Use Variant Control Variables in Variant Parameters
These examples show you how to use different types of variant control variables in variant
parameters (Simulink.VariantVariable
objects).
You must use the Simulink.VariantControl
class to create variant control variables for variant
parameters. You use these variant control variables to specify the boolean variant condition
expression associated with each choice value of a variant parameter. During simulation, the
value associated with the variant condition that evaluates to true
becomes
the active value of that parameter. The Simulink.VariantControl
object allows
you to specify an ActivationTime
for the variant parameter.
The Value
property of the variant control variable (Simulink.VariantControl
), which determines the active value of a variant parameter,
must be one of these types:
Integer
Enumerated value
Simulink.Parameter
object with value of type integer, enumeration, or a mathematical expression specified using theslexpr
function.User-defined type that inherits from
Simulink.Parameter
Consider the slexVariantParameters
model.
The Gain parameter of the Gain blocks are variant
parameters that are specified as Simulink.VariantVariable
objects, K1
and K2
.
K1
and K2
have multiple values associated with variant
condition expressions V == 1
and V == 2
. Here, the
variant control variable V
that determines the active value of
K1
and K2
is a Simulink.VariantControl
object. You can change V
to any of
these types based on your requirement.
Note
Before you start with these examples, we recommend you complete Create a Simple Variant Parameter Model.
Numeric Variant Control Values for Rapid Prototyping of Variant Parameters
Numeric values allow you to rapidly prototype variant values when you are still building your model. Numeric values help you focus more on building your variant values than on developing the expressions that activate those choices.
You can define numeric control values in locations listed in Storage Locations for Variant Control Variables (Operands) in Variant Parameters.
Open the slexVariantParameters
model.
open_system('slexVariantParameters')
In the MATLAB® Editor, specify variant choices in their simplest form as numeric values in Simulink.VariantVariable
objects K1
and K2
.
K1 = Simulink.VariantVariable('Choices',{'V==1', 3.5, 'V==2', 8.5})
K1 = VariantVariable with 2 choices: Condition Value _________ _____ V == 1 3.5000 V == 2 8.5000 Specification: '' Bank: '' Use getChoice, setChoice, addChoice, removeChoice to access, modify, add or remove choices
K2 = Simulink.VariantVariable('Choices',{'V==1', 4.5, 'V==2', 9.5})
K2 = VariantVariable with 2 choices: Condition Value _________ _____ V == 1 4.5000 V == 2 9.5000 Specification: '' Bank: '' Use getChoice, setChoice, addChoice, removeChoice to access, modify, add or remove choices
Once you successfully create the Simulink.VariantVariable
objects, you can modify them by using the methods described in Public Methods or from the VariantVariable
dialog box.
Activate one of the variant values by defining a control variable, V
, and setting its value to 1
in a Simulink.VariantControl
object.
V = Simulink.VariantControl('Value', 1, 'ActivationTime', 'update diagram')
V = VariantControl with properties: Value: 1 ActivationTime: 'update diagram'
When you simulate the model, the condition V == 1
evaluates to true
. K1
is assigned a value of 3.5
and K2
is assigned a value of 8.5
.
sim ('slexVariantParameters')
If you change the value of V
to 2
, Simulink® sets the value of K1
and K2
to 4.5
and 9.5
during simulation. You can change the value of V
using this command or from Simulink.VariantControl
dialog box.
V.Value = 2;
sim ('slexVariantParameters')
Simulink.Parameter Type of Variant Control Variables for Code Generation of Variant Parameters
If you intend to generate code for a model containing variant parameters, specify variant control variables as Simulink.Parameter
objects. Simulink.Parameter
objects allow you to specify other attributes, such as data type and storage class, and control the appearance and placement of variant control variables in generated code.
You can define a variant control variable of type
Simulink.Parameter
only in the base workspace, model workspace, or in a data dictionary. For more information on storage locations for variant control variables, see Storage Locations for Variant Control Variables (Operands) in Variant Parameters.Simulink.Parameter
objects within structures and that have data types other thanSimulink.Bus
objects are not supported.
Open the slexVariantParameters
model.
open_system('slexVariantParameters');
In the MATLAB® Editor, define a Simulink.Parameter
object.
VSS_MODE = Simulink.Parameter; VSS_MODE.Value = 1; VSS_MODE.DataType = 'int32'; VSS_MODE.CoderInfo.StorageClass = 'Custom'; VSS_MODE.CoderInfo.CustomStorageClass = 'Define'; VSS_MODE.CoderInfo.CustomAttributes.HeaderFile ='demo_macros.h';
Variant control variables defined as Simulink.Parameter
objects can have any of the storage classes listed in Storage Classes for Different Variant Activation Times (Simulink Coder).
You can also convert a scalar variant control variable into a Simulink.Parameter
object. For more information, see Convert Variant Control Variables into Simulink.Parameter Objects.
Specify the object as a variant control in Simulink.VariantVariable
objects K1
and K2
.
K1 = Simulink.VariantVariable('Choices',{'V == 1',3.5,'V == 2',8.5}); K2 = Simulink.VariantVariable('Choices',{'V == 1',4.5,'V == 2',9.5});
Once you successfully create the Simulink.VariantVariable
objects, you can modify them by using the methods described in Public Methods or from the VariantVariable
dialog box.
Activate one of the variant values by defining a Simulink.VariantControl
object V
and setting its Value property to VSS_MODE
.
V = Simulink.VariantControl('Value',copy(VSS_MODE),'ActivationTime','code compile');
When you simulate the model, the condition V == 1
evaluates to true
. K1
is assigned a value of 3.5
, and K2
is assigned a value of 8.5
.
sim('slexVariantParameters');
If you change the value of V
to 2
, Simulink® sets the value of K1
and K2
to 4.5
and 9.5
during simulation. You can change the value of V
using this command or from the Simulink.VariantControl
dialog box.
V.Value.Value=2;
sim('slexVariantParameters');
Generate code from the model. For information on how to generate code, see Generate Code Using Embedded Coder (Embedded Coder)
The generated code contains both Linear
and Nonlinear
choices in preprocessor conditionals #if
and #elif
because of the code compile
activation time. The variant control variable V
is defined using a macro — #define
directive — in the header file demo_macros.h
. You can control the appearance and placement of V
in the generated code and prevent optimizations from eliminating storage for V
using the storage class property. For more information, see Storage Classes for Different Variant Activation Times (Simulink Coder).
% demo_macros.h % /* Exported data define */ % % /* Definition for custom storage class: Define */ % #define V 2 /* Referenced by: % * '<Root>/Gain' % * '<Root>/Gain1' % */ % #endif /* RTW_HEADER_demo_macros_h_ */ % % /*
Enumerated Types to Improve Code Readability of Variant Control Variables of Variant Parameters
Use enumerated types to give meaningful names to integers used as variant control values. For more information on enumerated type data, see Use Enumerated Data in Simulink Models.
In the MATLAB® Editor, define the classes that map enumerated values to meaningful names.
Open the slexVariantParameters
model.
open_system('slexVariantParameters')
Specify the variant condition expressions V == EngType.Small
and V == EngType.Big
in Simulink.VariantVariable
objects K1
and K2
.
K1 = Simulink.VariantVariable('Choices', {'V == EngType.Small',3.5,'V == EngType.Big',8.5})
K1 = VariantVariable with 2 choices: Condition Value __________________ _____ V == EngType.Big 8.5000 V == EngType.Small 3.5000 Specification: '' Bank: '' Use getChoice, setChoice, addChoice, removeChoice to access, modify, add or remove choices
K2 = Simulink.VariantVariable('Choices', {'V == EngType.Small',4.5,'V == EngType.Big',9.5})
K2 = VariantVariable with 2 choices: Condition Value __________________ _____ V == EngType.Big 9.5000 V == EngType.Small 4.5000 Specification: '' Bank: '' Use getChoice, setChoice, addChoice, removeChoice to access, modify, add or remove choices
Here, EngType
is an integer-based enumeration class that is derived from the built-in data type, int32
. The class has two enumeration values, Small
and Big
. These enumerated values have underlying integer values 1
and 2
. In this example, the enumeration class is defined in the base workspace. You can choose to define the class in other storage locations as listed in Storage Locations for Variant Control Variables (Operands) in Variant Blocks.
type EngType.m
classdef EngType < Simulink.IntEnumType enumeration Small (1) Big (2) end methods (Static) function retVal = addClassNameToEnumNames() % ADDCLASSNAMETOENUMNAMES Specifies whether to add the class name % as a prefix to enumeration member names in generated code. % Return true or false. % If you do not define this method, no prefix is added. retVal = true; end end end
Once you successfully create the Simulink.VariantVariable
objects, you can modify them by using the methods described in Public Methods or from the VariantVariable
dialog box.
Activate one of the variant values by defining the control variable V
and setting its value to EngType.Small
in Simulink.VariantControl
object V
.
V = Simulink.VariantControl('Value',EngType.Small,'ActivationTime','code compile')
V = VariantControl with properties: Value: Small ActivationTime: 'code compile'
When you simulate the model, the condition V == 1
evaluates to true
. K1
is assigned a value of 3.5
, and K2
is assigned a value of 8.5
.
sim('slexVariantParameters')
If you change the value of V
to 2
, Simulink® sets the value of K1
and K2
to 4.5
and 9.5
during simulation. You can change the value of V
using this command or from Simulink.VariantControl
dialog box.
V.Value = 2
V = VariantControl with properties: Value: 2 ActivationTime: 'code compile'
sim ('slexVariantParameters')
The code that you generate using enumerated types contains the names of the values rather than integers.
% slexVariantParameters_private.h % #if V == EngType_Big || V == EngType_Small % /* Variable: K1 Referenced by: '<Root>/Gain' */ % #if V == EngType_Big % #define rtCP_Gain_K1 (8.5) % #elif V == EngType_Small % #define rtCP_Gain_K1 (3.5) % #endif % #endif % % #if V == EngType_Big || V == EngType_Small % /* Variable: K2 Referenced by: '<Root>/Gain1' */ % #if V == EngType_Big % #define rtCP_Gain1_K2 (9.5) % #elif V == EngType_Small % #define rtCP_Gain1_K2 (4.5) % #endif % #endif % #endif /* RTW_HEADER_slexVariantParameters_private_h_ */
Note that for variant parameters with startup activation time, only enumerations that are defined using these techniques are supported:
Using the function
Simulink.defineIntEnumType
By subclassing built-in integer data types
int8
,int16
,int32
,uint8
, oruint16
, or by subclassingSimulink.IntEnumType
These enumerations are also supported when permanently stored in a Simulink® data dictionary. See Enumerations in Data Dictionary.
Simulink.VariantExpression Objects for Variant Condition Reuse of Variant Parameters
After identifying the variant values that your model requires, you can construct complex variant conditions to control the activation of your variant parameter values by defining variant conditions as Simulink.VariantExpression
objects. Simulink.VariantExpression
objects enable you to reuse common variant conditions across models and help you encapsulate complex variant condition expressions.
You can define a variant control variable of type
Simulink.VariantExpression
in the base workspace, model workspace, or in a data dictionary. For more information on storage locations for variant control variables, see Storage Locations for Variant Control Variables (Operands) in Variant Parameters.Simulink.VariantExpression
within structures are not supported.
Open the slexVariantParameters
model.
open_system('slexVariantParameters')
In the MATLAB® Editor, encapsulate variant control expressions as Simulink.VariantExpression
objects.
LinearController=Simulink.VariantExpression('V==1'); NonLinearController=Simulink.VariantExpression('V==2');
Specify the Simulink.VariantExpression
objects as the variant controls in a Simulink.VariantVariable
objects K1
and K2
.
K1 = Simulink.VariantVariable('Choices',{'LinearController',3.5,'NonLinearController',8.5})
K1 = VariantVariable with 2 choices: Condition Value ___________________ _____ LinearController 3.5000 NonLinearController 8.5000 Specification: '' Bank: '' Use getChoice, setChoice, addChoice, removeChoice to access, modify, add or remove choices
K2 = Simulink.VariantVariable('Choices',{'LinearController',4.5,'NonLinearController',9.5})
K2 = VariantVariable with 2 choices: Condition Value ___________________ _____ LinearController 4.5000 NonLinearController 9.5000 Specification: '' Bank: '' Use getChoice, setChoice, addChoice, removeChoice to access, modify, add or remove choices
Once you successfully create the Simulink.VariantVariable
objects, you can modify them by using the methods described in Public Methods or from the VariantVariable
dialog box.
Activate one of the variant values by defining a Simulink.VariantControl
object V
and setting its value to 1
.
V = Simulink.VariantControl('Value',1,'ActivationTime','update diagram')
V = VariantControl with properties: Value: 1 ActivationTime: 'update diagram'
When you simulate the model, the condition V == 1
evaluates to true
. K1
is assigned a value of 3.5
, and K2
is assigned a value of 8.5
.
sim('slexVariantParameters')
If you change the value of V
to 2
, Simulink® sets the value of K1
and K2
to 4.5
and 9.5
during simulation. You can change the value of V
using this command or from Simulink.VariantControl
dialog box.
V.Value = 2;
sim ('slexVariantParameters')
Using this approach, you can develop complex variant condition expressions that are reusable.
Custom Data Class Objects as Values of Simulink.VariantControl
Objects
Set the value of a Simulink.VariantControl
object to an object of a user-defined data class that derives from Simulink.Parameter
. The user-defined class package that contains the class definition must be available on the MATLAB® search path. Data objects that you create from your package can use the storage classes that the package defines. For an example that shows how to create a data class in a package, see Define Data Classes.
Explore the Model
In this example, the +myPackage
folder is a user-defined data class package folder that contains the class folder @myExParameter
. The class folder contains the class definition file myExParameter.m
and the class derives from Simulink.Parameter
. The csc_registration.m
file contains the custom storage class defined for this package using the Custom Storage Class Designer.
open_system("slexVariantParameters");
The
slexVariantParameters
model uses two variant parametersK1
andK2
, and aSimulink.VariantControl
objectV
, that are defined in the base workspace.Double-click the variant control object
V
in the base workspace to open theSimulink.VariantControl
dialog box.Select the custom class
myPackage.myExParameter
from the Value type list.In the Value box, enter
1
as the value of the variant control.From the Data type list, select
int32
and from the Activation time list, selectstartup
.In the Code Generation tab, select the custom storage class
myPackage_ExportedGlobal
defined in the package.
Generate code from the model. For information on how to generate code, see Generate Code Using Embedded Coder (Embedded Coder).
The generated header file myParams.h
contains the extern
declaration for the variable V
and the generated file myParams.c
contains the definition of the variable according to the settings in the custom storage class definition.
/* myParams.h */ /* Declaration for custom storage class: myPackage_ExportedGlobal */ extern int32_T V; /* myParams.c */ /* Exported data definition */ /* Definition for custom storage class: myPackage_ExportedGlobal */ int32_T V = 1;
Use Mathematical Expressions as Values of Simulink.VariantControl
Objects and Simulink.VariantVariable
Choices
Set the value of a Simulink.VariantControl
object and the value of a choice of a Simulink.VariantVariable
object to mathematical expressions involving literal numbers, MATLAB® variables, or Simulink.Parameter
objects. With expressions, you can:
Express a value as a relationship between known physical constants instead of as an unidentifiable literal number.
Explicitly model algebraic dependencies between parameter data. When you change the values of independent data, you do not need to remember to adjust the values of dependent data.
To specify a mathematical expression for the value of a Simulink.VariantControl
object or the value of a choice of a Simulink.VariantVariable
object:
Create a
Simulink.Parameter
object or an object of a class that inherits fromSimulink.Parameter
.Set the
Value
property of the object to the expression by using theslexpr
function.Use the object to set the value of the variant control or the values of the choices of a variant parameter.
You can generate C or C++ code that preserves the expressions using Embedded Coder® by applying compatible storage classes. For applicable code generation techniques and considerations, see Code Generation of Parameter Objects With Expression Values (Embedded Coder).
Explore Example
The example model uses a variant parameter object vp_tunable
that is used to set the Gain parameter of a Gain block. The model configuration parameter Default parameter behavior for code generation optimization is set to Tunable
.
vp_tunable
uses a Simulink.VariantControl
object vc_startup
that has activation time set to startup
and ExportedGlobal
storage class, which yields a global variable in the generated code. The choices of vp_tunable
are Simulink.Parameter
objects with values set to mathematical expressions. The values of the parameter objects a_vp
, b_vp
, a_vc
, and b_vc
that are used in the expressions are imported from an external file external_imp_defines.h
.
% These parameter objects have the CustomStorageClass property set to ImportedDefine and HeaderFile property set to 'external_imp_defines.h'
a_vc = Simulink.Parameter(int32(1));
b_vc = Simulink.Parameter(int32(2));
a_vp = Simulink.Parameter(int32(6));
b_vp = Simulink.Parameter(int32(5));
% This parameter object has the StorageClass property set to 'ExportedGlobal' vc_slprm = Simulink.Parameter(slexpr("a_vc+b_vc")); % Variant control for the vp_tunable parameter vc_startup = Simulink.VariantControl(Value=vc_slprm,ActivationTime="startup");
% These parameter objects have the CustomStorageClass property set to 'ExportToFile', HeaderFile property set to 'varparam.h', and DefinitionFile property set to 'varparam.c' slparam_1 = Simulink.Parameter(slexpr("a_vp+b_vp")); slparam_2 = Simulink.Parameter(slexpr("a_vp-b_vp")); slparam_3 = Simulink.Parameter(slexpr("a_vp*b_vp"));
vp_tunable = Simulink.VariantVariable('Choices', ... {'vc_startup==1','slparam_1','vc_startup==2','slparam_2','(default)','slparam_3'});
This code snippet shows the content of the external file external_imp_defines.h
.
#define a_vc 1 #define b_vc 2 #define a_vp 6 #define b_vp 5
With Embedded Coder, you can generate code that defines a global variable and initializes it by using an expression involving system constants.
/* varparam.c */ /* Definition for custom storage class: ExportToFile */ real_T slparam_1 = a_vp+b_vp; real_T slparam_2 = a_vp-b_vp; real_T slparam_3 = a_vp*b_vp;
/* <model>.c */ /* Exported block parameters */ int32_T vc_startup = a_vc+b_vc; /* Model initialize function */ if (vc_startup == 1) { mVarParamVCtrlSlexpr_P.vp_tunable = slparam_1; } else if (vc_startup == 2) { mVarParamVCtrlSlexpr_P.vp_tunable = slparam_2; } else { mVarParamVCtrlSlexpr_P.vp_tunable = slparam_3; }
Similarly, in this model, vp_macro
is a variant parameter that uses a Simulink.VariantControl
object vc_cc
with activation time set to code compile
. Both vc_cc
and the choices of vp_macro
have the Define
storage class that yields a macro in the generated code. The values of the parameter objects a_cc
, b_cc
, a_vp_cc
, and b_vp_cc
that are used in the expressions are imported from an external file external_imp_defines.h
.
% These parameter objects have the CustomStorageClass property set to 'ImportedDefine' and HeaderFile property set to 'external_imp_defines.h'
a_cc = Simulink.Parameter(int32(1));
b_cc = Simulink.Parameter(int32(2));
a_vp_cc = Simulink.Parameter(int32(7));
b_vp_cc = Simulink.Parameter(int32(4));
% This parameter object has the StorageClass property set to 'Define' and the HeaderFile property set to 'vcc_define.h' vc_slprm_cc = Simulink.Parameter(slexpr("a_cc+b_cc")); % Variant control for the vp_macro parameter vc_cc = Simulink.VariantControl(Value=vc_slprm_cc,ActivationTime="code compile");
% These parameter objects have the CustomStorageClass property set to 'Define' and the HeaderFile property set to 'varparam.h' slparam_1_cc = Simulink.Parameter(slexpr("a_vp_cc+b_vp_cc")); slparam_2_cc = Simulink.Parameter(slexpr("a_vp_cc-b_vp_cc")); slparam_3_cc = Simulink.Parameter(slexpr("a_vp_cc*b_vp_cc"));
vp_macro = Simulink.VariantVariable('Choices', ... {'vc_cc==1', 'slparam_1_cc', 'vc_cc==2', 'slparam_2_cc', '(default)', 'slparam_3_cc'});
This code snippet shows the content of the external file external_imp_defines.h
.
#define a_cc 1 #define b_cc 2 #define a_vp_cc 7 #define b_vp_cc 4
For this variant parameter, Embedded Coder generates code that defines a macro whose value is an expression involving other macros.
/* vcc_define.h */ /* Definition for custom storage class: Define */ #define vc_cc a_cc+b_cc /* Referenced by: '<Root>/Gain1' */ #endif
/* varparam.h */ /* Definition for custom storage class: Define */ #define slparam_1_cc a_vp_cc+b_vp_cc /* Referenced by: '<Root>/Gain1' */ #define slparam_2_cc a_vp_cc-b_vp_cc /* Referenced by: '<Root>/Gain1' */ #define slparam_3_cc a_vp_cc*b_vp_cc
/* <model>.c */ /* Model initialize function */ #if vc_cc == 1 mVarParamVCtrlSlexpr_P.vp_macro = slparam_1_cc; #elif vc_cc == 2 mVarParamVCtrlSlexpr_P.vp_macro = slparam_2_cc; #else mVarParamVCtrlSlexpr_P.vp_macro = slparam_3_cc; #endif