Main Content

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 becomes 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 propery 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 Simulink.VariantVariable objects 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/Bdoc21b_1757077_189922/tpe8ecdc23/ex18167195/slexVariantParametersStartup_ert_rtw
### Invoking Target Language Compiler on slexVariantParametersStartup.rtw
### Using System Target File: /mathworks/devel/bat/Bdoc21b/build/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 header file rtwtypes.h
### Writing header file builtin_typeid_types.h
### Writing header file multiword_types.h
.
### Writing source file slexVariantParametersStartup.c
### 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 header file rtGetInf.h
### Writing source file rtGetInf.c
### Writing header file rtGetNaN.h
### Writing source file rtGetNaN.c
### Writing source file ert_main.c
.
### TLC code generation complete.
.### Saving binary information cache.
### Using toolchain: GNU gcc/g++ | gmake (64-bit Linux)
### Creating '/tmp/Bdoc21b_1757077_189922/tpe8ecdc23/ex18167195/slexVariantParametersStartup_ert_rtw/slexVariantParametersStartup.mk' ...
### Building 'slexVariantParametersStartup': "/mathworks/devel/bat/Bdoc21b/build/matlab/bin/glnxa64/gmake"  -f slexVariantParametersStartup.mk all
gcc -c -fwrapv -fPIC -O0 -msse2 -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/Bdoc21b_1757077_189922/tpe8ecdc23/ex18167195 -I/tmp/Bdoc21b_1757077_189922/tpe8ecdc23/ex18167195/slexVariantParametersStartup_ert_rtw -I/mathworks/devel/bat/Bdoc21b/build/matlab/extern/include -I/mathworks/devel/bat/Bdoc21b/build/matlab/simulink/include -I/mathworks/devel/bat/Bdoc21b/build/matlab/rtw/c/src -I/mathworks/devel/bat/Bdoc21b/build/matlab/rtw/c/src/ext_mode/common -I/mathworks/devel/bat/Bdoc21b/build/matlab/rtw/c/ert -o "rt_logging.o" "/mathworks/devel/bat/Bdoc21b/build/matlab/rtw/c/src/rt_logging.c"
gcc -c -fwrapv -fPIC -O0 -msse2 -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/Bdoc21b_1757077_189922/tpe8ecdc23/ex18167195 -I/tmp/Bdoc21b_1757077_189922/tpe8ecdc23/ex18167195/slexVariantParametersStartup_ert_rtw -I/mathworks/devel/bat/Bdoc21b/build/matlab/extern/include -I/mathworks/devel/bat/Bdoc21b/build/matlab/simulink/include -I/mathworks/devel/bat/Bdoc21b/build/matlab/rtw/c/src -I/mathworks/devel/bat/Bdoc21b/build/matlab/rtw/c/src/ext_mode/common -I/mathworks/devel/bat/Bdoc21b/build/matlab/rtw/c/ert -o "rtGetInf.o" "/tmp/Bdoc21b_1757077_189922/tpe8ecdc23/ex18167195/slexVariantParametersStartup_ert_rtw/rtGetInf.c"
gcc -c -fwrapv -fPIC -O0 -msse2 -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/Bdoc21b_1757077_189922/tpe8ecdc23/ex18167195 -I/tmp/Bdoc21b_1757077_189922/tpe8ecdc23/ex18167195/slexVariantParametersStartup_ert_rtw -I/mathworks/devel/bat/Bdoc21b/build/matlab/extern/include -I/mathworks/devel/bat/Bdoc21b/build/matlab/simulink/include -I/mathworks/devel/bat/Bdoc21b/build/matlab/rtw/c/src -I/mathworks/devel/bat/Bdoc21b/build/matlab/rtw/c/src/ext_mode/common -I/mathworks/devel/bat/Bdoc21b/build/matlab/rtw/c/ert -o "rtGetNaN.o" "/tmp/Bdoc21b_1757077_189922/tpe8ecdc23/ex18167195/slexVariantParametersStartup_ert_rtw/rtGetNaN.c"
gcc -c -fwrapv -fPIC -O0 -msse2 -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/Bdoc21b_1757077_189922/tpe8ecdc23/ex18167195 -I/tmp/Bdoc21b_1757077_189922/tpe8ecdc23/ex18167195/slexVariantParametersStartup_ert_rtw -I/mathworks/devel/bat/Bdoc21b/build/matlab/extern/include -I/mathworks/devel/bat/Bdoc21b/build/matlab/simulink/include -I/mathworks/devel/bat/Bdoc21b/build/matlab/rtw/c/src -I/mathworks/devel/bat/Bdoc21b/build/matlab/rtw/c/src/ext_mode/common -I/mathworks/devel/bat/Bdoc21b/build/matlab/rtw/c/ert -o "rt_nonfinite.o" "/tmp/Bdoc21b_1757077_189922/tpe8ecdc23/ex18167195/slexVariantParametersStartup_ert_rtw/rt_nonfinite.c"
gcc -c -fwrapv -fPIC -O0 -msse2 -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/Bdoc21b_1757077_189922/tpe8ecdc23/ex18167195 -I/tmp/Bdoc21b_1757077_189922/tpe8ecdc23/ex18167195/slexVariantParametersStartup_ert_rtw -I/mathworks/devel/bat/Bdoc21b/build/matlab/extern/include -I/mathworks/devel/bat/Bdoc21b/build/matlab/simulink/include -I/mathworks/devel/bat/Bdoc21b/build/matlab/rtw/c/src -I/mathworks/devel/bat/Bdoc21b/build/matlab/rtw/c/src/ext_mode/common -I/mathworks/devel/bat/Bdoc21b/build/matlab/rtw/c/ert -o "slexVariantParametersStartup.o" "/tmp/Bdoc21b_1757077_189922/tpe8ecdc23/ex18167195/slexVariantParametersStartup_ert_rtw/slexVariantParametersStartup.c"
gcc -c -fwrapv -fPIC -O0 -msse2 -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/Bdoc21b_1757077_189922/tpe8ecdc23/ex18167195 -I/tmp/Bdoc21b_1757077_189922/tpe8ecdc23/ex18167195/slexVariantParametersStartup_ert_rtw -I/mathworks/devel/bat/Bdoc21b/build/matlab/extern/include -I/mathworks/devel/bat/Bdoc21b/build/matlab/simulink/include -I/mathworks/devel/bat/Bdoc21b/build/matlab/rtw/c/src -I/mathworks/devel/bat/Bdoc21b/build/matlab/rtw/c/src/ext_mode/common -I/mathworks/devel/bat/Bdoc21b/build/matlab/rtw/c/ert -o "slexVariantParametersStartup_VCtrl.o" "/tmp/Bdoc21b_1757077_189922/tpe8ecdc23/ex18167195/slexVariantParametersStartup_VCtrl.c"
gcc -c -fwrapv -fPIC -O0 -msse2 -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/Bdoc21b_1757077_189922/tpe8ecdc23/ex18167195 -I/tmp/Bdoc21b_1757077_189922/tpe8ecdc23/ex18167195/slexVariantParametersStartup_ert_rtw -I/mathworks/devel/bat/Bdoc21b/build/matlab/extern/include -I/mathworks/devel/bat/Bdoc21b/build/matlab/simulink/include -I/mathworks/devel/bat/Bdoc21b/build/matlab/rtw/c/src -I/mathworks/devel/bat/Bdoc21b/build/matlab/rtw/c/src/ext_mode/common -I/mathworks/devel/bat/Bdoc21b/build/matlab/rtw/c/ert -o "ert_main.o" "/tmp/Bdoc21b_1757077_189922/tpe8ecdc23/ex18167195/slexVariantParametersStartup_ert_rtw/ert_main.c"
### Creating standalone executable ../slexVariantParametersStartup ...
g++  -o ../slexVariantParametersStartup rt_logging.o rtGetInf.o rtGetNaN.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/Bdoc21b_1757077_189922/tpe8ecdc23/ex18167195/slexVariantParametersStartup.slxc'.

Build Summary

Top model targets built:

Model                         Action                       Rebuild Reason                                    
=============================================================================================================
slexVariantParametersStartup  Code generated and compiled  Code generation information file does not exist.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 25.973s

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;
}

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/Bdoc21b_1757077_189922/tpe8ecdc23/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/Bdoc21b_1757077_189922/tpe8ecdc23/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.9161s
** created slexVariantParametersStartup.mat **

** created slexVariantParametersStartup.mat **

** created slexVariantParametersStartup.mat **

** created slexVariantParametersStartup.mat **

See Also