Group Variant Parameter Values and Conditionally Switch Active Value Sets in Generated Code
This example shows how to group variant parameters with the same variant conditions into a structure in the generated code. You will learn to:
Use variant parameter banks to group variant parameters with
startup
activation time in code generated by Simulink Coder®.Specify code generation properties for variant parameter banks.
Overview of Variant Parameters
Variant parameters enable you to conditionally vary the values of block parameters in a Simulink® model. Use the Simulink.VariantVariable
class to create a variant parameter object. A variant parameter object defines a set of values, referred to as choices, and variant condition expressions associated with each choice. During simulation, the choice associated with the variant condition that evaluates to true
becomes the active value of the variant parameter.
To specify the variant conditions for a variant parameter, use a variant control variable of type Simulink.VariantControl
. The Simulink.VariantControl
object allows you to specify a variant activation time for the variant parameter. For example, in this MATLAB® code, VCtrl
is a variant control with startup
activation time. The variant parameter TABLE_DIM_0
has two choices, 10
and 20
. For each choice, a variant condition is specified using VCtrl
.
VCtrl = Simulink.VariantControl('Value',1,'ActivationTime','startup'); TABLE_DIM_0 = Simulink.VariantVariable('Choices',{'VCtrl == 1',10,'VCtrl == 2',20});
The representation of variant parameters in the generated code depends on the ActivationTime
of Simulink.VariantControl
and the Specification
property of the Simulink.VariantVariable
object. Based on the variant activation time, Simulink determines whether to include only the active choice or both the active and inactive choices of the variant parameter in the code. The Specification
property allows you to specify properties such as data type, dimensions, and storage class applicable to all the choices.
For more information on variant activation times, see Activate Variant During Different Stages of Simulation and Code Generation Workflow. For information on variant parameter code generation, see Options to Represent Variant Parameters in Generated Code (Embedded Coder).
Overview of Variant Parameter Banks
When you generate code for variant parameters with startup
activation time, the values of variant parameters are enclosed in if
and else if
statements in the model_initialize
function. This involves reading and copying all parameter values into the program memory. Also, when you define a custom storage class to define the variant parameter values in a separate definition file, only the active values of the parameters are present in the definition file. To improve the efficiency and readability of the generated code for variant parameters with startup
activation time, you can use variant parameter banks.
Parameter banks help you to:
Group variant parameter values with the same variant conditions into a structure array.
Use a pointer switching mechanism to switch the set of active parameter values in the code based on variant conditions.
Customize code placement and specify the memory section to place the parameter values in the compiled code.
A variant parameter bank is an object of type Simulink.VariantBank
. To add a variant parameter to a variant parameter bank, set the Bank
property of the Simulink.VariantVariable
object to the name of the Simulink.VariantBank
object. When you generate code, Simulink.VariantVariable
objects that share the same Bank
property become part of the same structure in the code.
You must specify a list of variant conditions for a parameter bank. These conditions must match the variant conditions of the variant parameters in this parameter bank, except any default variant choice specified for the variant parameters using the (default)
keyword. For example, this MATLAB code creates a variant parameter bank.
LUTBank = Simulink.VariantBank(Name='LUTBpAndData',... Description='Lookup table breakpoint and data',... VariantConditions={'VCtrl == 1','VCtrl == 2'});
Note: Specifying storage class using the Specification
property is not supported if the Simulink.VariantVariable
object is part of a variant parameter bank.
Explore Example Model
1. Open the model slexVariantParameterBank
.
model = "slexVariantParameterBank";
open_system(model);
The slexVariantParameterBank
model contains blocks that use variant parameters. The variant parameters are defined as Simulink.VariantVariable
objects in the slexVariantParameterBankData.m
file.
The values of the Constant parameters of the two Constant blocks in the model are set to the variant parameter objects
SHIFT_VALUE
andTABLE_DIM_0
.
The Table data and Breakpoint sets of the n-D Lookup Table blocks are specified using the variant parameter objects
T1Break
,T1Data
,T2Break
, andT2Data
.
2. Open the file slexVariantParameterBankData.m
. Observe these settings in the file:
VCtrl
is defined as aSimulink.VariantControl
object. The value ofVCtrl
is set to1
, and its activation time is set tostartup
. This object is used as a variant control variable to define the variant conditions for all the variant parameter objects. During simulation, the choices associated with the conditionVCtrl==1
become active, and the choices associated withVCtrl==2
become inactive.
LUTBank
is defined as aSimulink.VariantBank
object. This variant parameter bank is used to group the variant parameter objectsT1Break
,T1Data
,T2Break
, andT2Data
. Hence,LUTBank
has the same set of variant conditions as these variant parameter objects. TheBankCoderInfo
property of this variant parameter bank object is set toLUTBankCoderInfo
.
LUTBankCoderInfo
is aSimulink.VariantBankCoderInfo
object. The object is used to specify code generation properties such as the header file, definition file, and#pragma
directives for the variant parameter bankLUTBank
.
The
Bank
property of the variant parameter objectsT1Break
,T1Data
,T2Break
, andT2Data
is set toLUTBank
.
Generate Code
To generate code that uses variant parameter bank switching, use Simulink Coder.
Before you generate code from the model, check whether you have write permission in your current folder. To generate code, in the Apps gallery of the model toolstrip, click Simulink Coder. On the C Code tab, click Build. For more information, see Generate Code Using Simulink Coder.
Review Generated Code
1. In the C Code tab, select Open Report. The header and definition files are named according to the properties of the object LUTBankCoderInfo
.
2. Select the header file slexVariantParameterBank_lut_params.h
from the Code section of the report. The file contains the type definition and data declarations of the variant parameter bank.
The variant parameters that are part of the parameter bank LUTBank
are grouped in the same structure. This structure is named LUTBpAndData
, according to the Name
property of the object LUTBank
.
typedef struct { real_T T1Break[11]; real_T T1Data[11]; real_T T2Break[3]; real_T T2Data[9]; } LUTBpAndData;
A structure array of type LUTBpAndData
is declared. The number of elements in the array depends on the number of variant conditions in the VariantConditions
property of the parameter bank object LUTBank
. A pointer LUTBpAndData_ptr
of structure type LUTBpAndData
is declared. These statements are guarded with the code specified in the PreStatement
and PostStatement
properties of the LUTBankCoderInfo
object.
#pragma data_seg(.mydata) extern LUTBpAndData LUTBpAndData_ptr_impl[2]; extern LUTBpAndData *LUTBpAndData_ptr; #pragma end
3. Select the definition file slexVariantParameterBank_lut_params.c
. The file contains the definition of the structure array and the pointer variable.
The LUTBpAndData_ptr_impl
array contains the choices of the variant parameters, grouped by the variant conditions specified for the parameter bank. The pointer variable LUTBpAndData_ptr
holds the reference to the active element of the structure array.
#pragma data_seg(.mydata) LUTBpAndData LUTBpAndData_ptr_impl[2] = { { /* Variable: T1Break * Referenced by: '<Root>/1D Lookup' */ { -5.0, -4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 },
/* Variable: T1Data * Referenced by: '<Root>/1D Lookup' */ { -0.99990920426259511, -0.999329299739067, -0.99505475368673046, -0.9640275800758169, -0.76159415595576485, 0.0, 0.76159415595576485, 0.9640275800758169, 0.99505475368673046, 0.999329299739067, 0.99990920426259511 },
/* Variable: T2Break * Referenced by: '<Root>/2D Lookup' */ { -10.0, 0.0, 10.0 },
/* Variable: T2Data * Referenced by: '<Root>/2D Lookup' */ { 4.0, 16.0, 10.0, 5.0, 19.0, 18.0, 6.0, 20.0, 23.0 } }, { /* Variable: T1Break * Referenced by: '<Root>/1D Lookup' */ { -10.0, -8.0, -6.0, -4.0, -2.0, 0.0, 2.0, 4.0, 6.0, 8.0, 10.0 },
/* Variable: T1Data * Referenced by: '<Root>/1D Lookup' */ { -74.203210577788752, -27.28991719712775, -10.017874927409903, -3.626860407847019, -1.1752011936438014, 0.0, 1.1752011936438014, 3.626860407847019, 10.017874927409903, 27.28991719712775, 74.203210577788752 },
/* Variable: T2Break * Referenced by: '<Root>/2D Lookup' */ { -20.0, 0.0, 20.0 },
/* Variable: T2Data * Referenced by: '<Root>/2D Lookup' */ { 6.0, 16.0, 12.0, 7.0, 19.0, 16.0, 8.0, 20.0, 20.0 } } };
LUTBpAndData *LUTBpAndData_ptr = &LUTBpAndData_ptr_impl[0]; #pragma end
4. Select the slexVariantParameterBank.c
file. The model_initialize
function contains the code to switch the active variant choice based on variant conditions. For variant parameters that are part of a parameter bank, the pointer variable is used to access the active value set from the structure array based on variant conditions.
if (VCtrl == 1) { LUTBpAndData_ptr = &LUTBpAndData_ptr_impl[0U]; } else if (VCtrl == 2) { LUTBpAndData_ptr = &LUTBpAndData_ptr_impl[1U]; }
See Also
Simulink.VariantVariable
| Simulink.VariantBank
| Simulink.VariantBankCoderInfo