Run Executable for Different Variant Parameter Values Without Recompiling Code
This example shows how to generate an executable that runs for different set of variant parameter values without needing to recompile the code for each set of values.
In this example, you build an executable that represents the step response of a linear system with PID controller. In the executable, the PID parameters, proportional gain and integral gain, are specified as variant parameters that have multiple values to cater to multiple requirements. Each value is associated with a variant control expression. When you run the executable, Simulink® evaluates the condition expressions. Based on the condition expression that evaluates to true
, all the gain parameter values associated with that condition expression become active and the executable runs only for that set of gain values. You can then change the value of the variant control variable to run the executable for different set of gain parameter values. You are not required to recompile the code to build the executable for a different set of gain parameter values.
Overview of Variant Parameters
Variant parameters can have multiple values. Each value of the variant parameter is associated with a variant condition expression. During simulation, the value of the variant parameter associated with the condition that evaluates to true
is the active value of that parameter. The value associated with the condition that evaluates to false
is the inactive value of that variant parameter. For more information, see Use Variant Parameters to Reuse Block Parameters with Different Values.
The variability and the representation of variant parameters in the generated code depends on the ActivationTime and the Specification property you specify. The activation time determines whether to include only active choice or both active and inactive choices in the code. The storage class determines whether to represent the parameters as inline or tunable variables. For more information, see Options to Represent Variant Parameters in Generated Code (Embedded Coder).
If you specify the activation time as startup
, the generated code includes both active and inactive values of variant parameters. The values are enclosed in regular if
conditions of the model initialize function of the code. When you run an executable that is built from the code, the if
conditions are conditionally executed at the start of the execution. Based on the condition that evaluates to true
, the executable determines the active values of the variant parameters. If you include all the values in the executable, then you do not need to recompile the code every time you change the value of the variant control variable. You build the executable only once. You can then change the value of the variant control variable and then run the executable for a different set of active values.
Prerequisite
Before you start this example, we recommend you complete Options to Represent Variant Parameters in Generated Code (Embedded Coder).
Explore the Model
Open the model.
mdl = 'slexVariantParametersStartup';
open_system(mdl)
The PID Controller block has two variant parameters, Proportional(P) and Integral(I). The parameters are specified as
objects Simulink.VariantVariable
Kp
and Ki
. Kp
and Ki
have multiple values and are associated with a Simulink.VariantControl
object VCtrl
, as specified in the slexVariantParameterGain.m
file. In this file, the activation time of VCtrl
is specified as startup
. So, the executable that you build from this model determines the active value of Kp
and Ki
at the start of its execution by reading the value of VCtrl
from the slexVariantParametersStartup_VCtrl.txt
file. Since, the value of VCtrl
is specified as 1
, the executable calculates the step response for the values associated with VCtrl == 1
. To calculate the step response for a different value of VCtrl
, change the value of VCtrl
in the slexVariantParametersStartup_VCtrl.txt
file and run the executable again.
Build and Review the Generated Code with Regular if
Conditions and utAssert
Function
Before you generate code and build executable from the model, you first check that you have write permission in your current folder.
1. On the Simulink toolstrip, on the Apps tab, click Embedded Coder. On the C Code tab, click Build. For more information, see Generate Code Using Embedded Coder (Embedded Coder).
The code generator builds the executable, generates the Code Generation Report, and places the executable in the working folder. On Windows®, the executable is slexVariantParametersStartup.exe
. On Linux®, the executable is slexVariantParameterStartup
. Alternatively, enter this command in the MATLAB® Command Window to build the executable file.
slbuild(mdl);
### Starting build procedure for: slexVariantParametersStartup ### Generating code and artifacts to 'Model specific' folder structure ### Generating code into build folder: /tmp/Bdoc24b_2679053_907440/tpe5f5767d/simulink_variants-ex18167195/slexVariantParametersStartup_ert_rtw ### Invoking Target Language Compiler on slexVariantParametersStartup.rtw ### Using System Target File: /mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/rtw/c/ert/ert.tlc ### Loading TLC function libraries ........ ### Generating TLC interface API for custom data . ### Initial pass through model to cache user defined code ### Caching model source code ............................................... ### Writing header file slexVariantParametersStartup_types.h ### Writing header file slexVariantParametersStartup.h ### Writing source file slexVariantParametersStartup.c . ### Writing header file rtwtypes.h ### Writing header file builtin_typeid_types.h ### Writing header file multiword_types.h ### Writing header file slexVariantParametersStartup_private.h ### Writing header file rt_assert.h . ### Writing header file rt_nonfinite.h ### Writing source file rt_nonfinite.c ### Writing source file ert_main.c ### TLC code generation complete (took 5.236s). .### Saving binary information cache. ### Using toolchain: GNU gcc/g++ | gmake (64-bit Linux) ### Creating '/tmp/Bdoc24b_2679053_907440/tpe5f5767d/simulink_variants-ex18167195/slexVariantParametersStartup_ert_rtw/slexVariantParametersStartup.mk' ... ### Building 'slexVariantParametersStartup': "/mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/bin/glnxa64/gmake" -j 4 -l 4 -f slexVariantParametersStartup.mk all gcc -c -fwrapv -fPIC -O0 -msse2 -fno-predictive-commoning -DCLASSIC_INTERFACE=0 -DALLOCATIONFCN=0 -DTERMFCN=1 -DONESTEPFCN=1 -DMAT_FILE=1 -DMULTI_INSTANCE_CODE=0 -DINTEGER_CODE=0 -DMT=0 -DTID01EQ=1 -DMODEL=slexVariantParametersStartup -DNUMST=2 -DNCSTATES=0 -DHAVESTDIO -DMODEL_HAS_DYNAMICALLY_LOADED_SFCNS=0 -I/tmp/Bdoc24b_2679053_907440/tpe5f5767d/simulink_variants-ex18167195 -I/tmp/Bdoc24b_2679053_907440/tpe5f5767d/simulink_variants-ex18167195/slexVariantParametersStartup_ert_rtw -I/mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/extern/include -I/mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/simulink/include -I/mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/rtw/c/src -I/mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/rtw/c/src/ext_mode/common -I/mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/rtw/c/ert -o "rt_logging.o" "/mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/rtw/c/src/rt_logging.c" gcc -c -fwrapv -fPIC -O0 -msse2 -fno-predictive-commoning -DCLASSIC_INTERFACE=0 -DALLOCATIONFCN=0 -DTERMFCN=1 -DONESTEPFCN=1 -DMAT_FILE=1 -DMULTI_INSTANCE_CODE=0 -DINTEGER_CODE=0 -DMT=0 -DTID01EQ=1 -DMODEL=slexVariantParametersStartup -DNUMST=2 -DNCSTATES=0 -DHAVESTDIO -DMODEL_HAS_DYNAMICALLY_LOADED_SFCNS=0 -I/tmp/Bdoc24b_2679053_907440/tpe5f5767d/simulink_variants-ex18167195 -I/tmp/Bdoc24b_2679053_907440/tpe5f5767d/simulink_variants-ex18167195/slexVariantParametersStartup_ert_rtw -I/mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/extern/include -I/mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/simulink/include -I/mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/rtw/c/src -I/mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/rtw/c/src/ext_mode/common -I/mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/rtw/c/ert -o "rt_nonfinite.o" "/tmp/Bdoc24b_2679053_907440/tpe5f5767d/simulink_variants-ex18167195/slexVariantParametersStartup_ert_rtw/rt_nonfinite.c" gcc -c -fwrapv -fPIC -O0 -msse2 -fno-predictive-commoning -DCLASSIC_INTERFACE=0 -DALLOCATIONFCN=0 -DTERMFCN=1 -DONESTEPFCN=1 -DMAT_FILE=1 -DMULTI_INSTANCE_CODE=0 -DINTEGER_CODE=0 -DMT=0 -DTID01EQ=1 -DMODEL=slexVariantParametersStartup -DNUMST=2 -DNCSTATES=0 -DHAVESTDIO -DMODEL_HAS_DYNAMICALLY_LOADED_SFCNS=0 -I/tmp/Bdoc24b_2679053_907440/tpe5f5767d/simulink_variants-ex18167195 -I/tmp/Bdoc24b_2679053_907440/tpe5f5767d/simulink_variants-ex18167195/slexVariantParametersStartup_ert_rtw -I/mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/extern/include -I/mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/simulink/include -I/mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/rtw/c/src -I/mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/rtw/c/src/ext_mode/common -I/mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/rtw/c/ert -o "slexVariantParametersStartup.o" "/tmp/Bdoc24b_2679053_907440/tpe5f5767d/simulink_variants-ex18167195/slexVariantParametersStartup_ert_rtw/slexVariantParametersStartup.c" gcc -c -fwrapv -fPIC -O0 -msse2 -fno-predictive-commoning -DCLASSIC_INTERFACE=0 -DALLOCATIONFCN=0 -DTERMFCN=1 -DONESTEPFCN=1 -DMAT_FILE=1 -DMULTI_INSTANCE_CODE=0 -DINTEGER_CODE=0 -DMT=0 -DTID01EQ=1 -DMODEL=slexVariantParametersStartup -DNUMST=2 -DNCSTATES=0 -DHAVESTDIO -DMODEL_HAS_DYNAMICALLY_LOADED_SFCNS=0 -I/tmp/Bdoc24b_2679053_907440/tpe5f5767d/simulink_variants-ex18167195 -I/tmp/Bdoc24b_2679053_907440/tpe5f5767d/simulink_variants-ex18167195/slexVariantParametersStartup_ert_rtw -I/mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/extern/include -I/mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/simulink/include -I/mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/rtw/c/src -I/mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/rtw/c/src/ext_mode/common -I/mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/rtw/c/ert -o "slexVariantParametersStartup_VCtrl.o" "/tmp/Bdoc24b_2679053_907440/tpe5f5767d/simulink_variants-ex18167195/slexVariantParametersStartup_VCtrl.c" gcc -c -fwrapv -fPIC -O0 -msse2 -fno-predictive-commoning -DCLASSIC_INTERFACE=0 -DALLOCATIONFCN=0 -DTERMFCN=1 -DONESTEPFCN=1 -DMAT_FILE=1 -DMULTI_INSTANCE_CODE=0 -DINTEGER_CODE=0 -DMT=0 -DTID01EQ=1 -DMODEL=slexVariantParametersStartup -DNUMST=2 -DNCSTATES=0 -DHAVESTDIO -DMODEL_HAS_DYNAMICALLY_LOADED_SFCNS=0 -I/tmp/Bdoc24b_2679053_907440/tpe5f5767d/simulink_variants-ex18167195 -I/tmp/Bdoc24b_2679053_907440/tpe5f5767d/simulink_variants-ex18167195/slexVariantParametersStartup_ert_rtw -I/mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/extern/include -I/mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/simulink/include -I/mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/rtw/c/src -I/mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/rtw/c/src/ext_mode/common -I/mathworks/devel/bat/filer/batfs2561-0/Bdoc24b.2679053/build/runnable/matlab/rtw/c/ert -o "ert_main.o" "/tmp/Bdoc24b_2679053_907440/tpe5f5767d/simulink_variants-ex18167195/slexVariantParametersStartup_ert_rtw/ert_main.c" ### Creating standalone executable ../slexVariantParametersStartup ... g++ -o ../slexVariantParametersStartup rt_logging.o rt_nonfinite.o slexVariantParametersStartup.o slexVariantParametersStartup_VCtrl.o ert_main.o ### Created: ../slexVariantParametersStartup ### Successfully generated all binary outputs. gmake: Nothing to be done for `all'. ### Successful completion of build procedure for: slexVariantParametersStartup ### Simulink cache artifacts for 'slexVariantParametersStartup' were created in '/tmp/Bdoc24b_2679053_907440/tpe5f5767d/simulink_variants-ex18167195/slexVariantParametersStartup.slxc'. Build Summary Top model targets: Model Build Reason Status Build Duration =============================================================================================================================== slexVariantParametersStartup Information cache folder or artifacts were missing. Code generated and compiled. 0h 0m 18.583s 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 20.701s
2. On the C Code tab, select Open Report.
3. Select the slexVariantParametersStartup.c
file. In this file, the model initialize function includes:
a. Symbolic names for all the values of Kp
and Ki
enclosed in regular if
conditions. These if
conditions are evaluated when you run the executable.
if (get_VCtrl() == 1) { Ki = 4.5; Kp = 0.15; } else if (get_VCtrl() == 2) { Ki = 4.0; Kp = 0.5; } else if (get_VCtrl() == 3) { Ki = 3.5; Kp = 0.75; } else if (get_VCtrl() == 4) { Ki = 3.0; Kp = 1.0; }
Note: If the variant parameter has a default value specified using the (default)
variant condition, the value is assigned in the else
condition in the code.
b. The utAssert
function to ensure that at least one variant condition evaluates to true
when running the executable.
utAssert((get_VCtrl() == 1) || (get_VCtrl() == 2) || (get_VCtrl() == 3) || (get_VCtrl() == 4));
4. In the model_step
function, the symbol names of Kp
and Ki
are used to form the equation.
void slexVariantParameters_step(void) { ... slexVariantParametersStartup_Y.Out1 = 0.5 * slexVariantParametersStartup_DW.DiscreteTransferFcn_states[1];
Add = (real_T)!(slexVariantParametersStartup_M->Timing.t[0] < 1.0) -slexVariantParametersStartup_Y.Out1;
rtb_FilterCoefficient = (0.0 * Add - slexVariantParametersStartup_DW.Filter_DSTATE) * 100.0;
slexVariantParametersStartup_B.Sum = (Kp * Add + slexVariantParametersStartup_DW.Integrator_DSTATE) + rtb_FilterCoefficient;
rtb_IntegralGain = Ki * Add;
...
}
Set Active Values of Variant Parameters at Model Startup Stage
Identify the version of MATLAB® software on your machine. ispc
returns logical 1
(true
) if the version of MATLAB® software is for the Microsoft® Windows® platform. Otherwise, it returns logical 0
(false
). On Windows®, the executable is slexVariantParametersStartup.exe
. On Linux®, the executable is slexVariantParameterStartup
. To run the generated executable, enter this command in the MATLAB Command Window.
if ispc exeName = [mdl, '.exe']; else exeName = ['./', mdl]; end system(exeName);
** created slexVariantParametersStartup.mat **
At the start of the execution, the executable invokes the model initialize function. The executable reads the value of VCtrl
from the slexVariantParametersStartup_VCtrl.txt
file to evaluate the if
conditions in the function. Since the value of VCtrl
is set to 1
in the slexVariantParametersStartup_VCtrl.txt
file, the if
condition for VCtrl == 1
evaluates to true
. The generated executable is conditionally run for the PID gain parameter values that are associated with VCtrl == 1
and creates a slexVariantParametersStartup.mat
MAT-file as an output. The MAT-file contains values for the variables rt_tout
and rt_yout
, where rt_yout
represents the linear step response at the outport block Out1
for each time step rt_tout
.
You can load the variables from the MAT-file by typing this command:
load slexVariantParametersStartup.mat;
To plot the linear step response, use this function:
plot(rt_tout, rt_yout.signals.values, 'x-');
Now, change the value of VCtrl
in the slexVariantParametersStartup_VCtrl.txt
file to 2
. Run the executable again to observe the change in the step response.
Set Different Active Values for Variant Parameters Without Recompiling Code
The slexVariantStartup_script.m
script implements the logic to plot the linear step response for different values of proportional gain and integral gain parameters by changing the value of the VCtrl
using a for
loop.
When you run the script:
In the first iteration, the executable runs and the model initialize function is invoked. The executable reads the value of VCtrl
as 1
from the slexVariantParametersStartup_VCtrl.txt
file to evaluate the if
conditions in the model initialize function. The condition VCtrl == 1
evaluates to true
, the proportional and integral gain values that are associated with VCtrl == 1
becomes active. The executable calculates the step response for those values and creates a slexVariantParametersStartup.mat
MAT-file that contains the step response calculated for each time step.
In the next iteration, the value of VCtrl
is increased to 2
. The executable calculates the step response for the associated values and appends the newly calculated step response to the MAT-file.
Similarly, the executable calculates the step response for values associated with conditions VCtrl == 3
and VCtrl == 4
.
The script plots the linear step response as shown.
run slexVariantParameters_script.m;
### Starting build procedure for: slexVariantParametersStartup ### Generating code and artifacts to 'Model specific' folder structure ### Generating code into build folder: /tmp/Bdoc24b_2679053_907440/tpe5f5767d/simulink_variants-ex18167195/slexVariantParametersStartup_ert_rtw ### Generated code for 'slexVariantParametersStartup' is up to date because no structural, parameter or code replacement library changes were found. ### Skipping makefile generation and compilation because /tmp/Bdoc24b_2679053_907440/tpe5f5767d/simulink_variants-ex18167195/slexVariantParametersStartup is up to date ### Successful completion of build procedure for: slexVariantParametersStartup Build Summary 0 of 1 models built (1 models already up to date) Build duration: 0h 0m 2.3253s ** created slexVariantParametersStartup.mat ** ** created slexVariantParametersStartup.mat ** ** created slexVariantParametersStartup.mat ** ** created slexVariantParametersStartup.mat **