Main Content

Use Variant Control Variables in Variant Blocks

This topic explains how to use different types of variant control variables in variant blocks.

Consider the slexVariantSubsystems model.

Variant subsystem block with variant choices. Each variant choice is associated with a variant condition expression.

The Controller subsystem block dialog specifies two potential variants Linear Controller and Nonlinear Controller. Linear Controller and Nonlinear Controller blocks are associated with variant condition expressions V == 1 and V == 2. Here, V is the variant control variable that determines the active choice. You can change V to any of these types based on your requirement.

Scalar Variant Control Variables for Rapid Prototyping in Variant Blocks

Scalar MATLAB® variant control variables allow you to rapidly prototype variant choices when you are still building your model. Scalar MATLAB variant control variables help you focus more on building your variant choices than on developing the expressions that activate those choices.

You can define scalar control variables in storage locations as listed in Storage Locations for Variant Control Variables (Operands) in Variant Blocks.

Open the slexVariantSubsystems model.

open_system('slexVariantSubsystems')
VSS_MODE = 2

In the block parameters dialog box of the Controller block, specify variant controls in their simplest form as scalar variables, V == 1 and V == 2.

In the base workspace, define a variant control variable, V, set its value to 1, and then simulate the model.

V = 1;

During simulation, the Linear Controller block becomes active. Double-click the Controller block to see the active choice.

sim ('slexVariantSubsystems')
ans = 
  Simulink.SimulationOutput:

                   tout: [1000x1 double] 
                   yout: [1000x1 double] 

     SimulationMetadata: [1x1 Simulink.SimulationMetadata] 
           ErrorMessage: [0x0 char] 

Similarly, if you change the value of V to 2, the Nonlinear Controller block becomes active during simulation.

V = 2;
sim ('slexVariantSubsystems')
ans = 
  Simulink.SimulationOutput:

                   tout: [1000x1 double] 
                   yout: [1000x1 double] 

     SimulationMetadata: [1x1 Simulink.SimulationMetadata] 
           ErrorMessage: [0x0 char] 

Simulink.Parameter Type of Variant Control Variables for Code Generation in Variant Blocks

If you intend to generate code for a model containing variant blocks, 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 or in a data dictionary. Defining Simulink.Parameter type of variant control variables in the mask or model workspace is not supported. For more information on storage locations for variant control variables, see Storage Locations for Variant Control Variables (Operands) in Variant Blocks.

  • Simulink.Parameter objects within structures and that have data types other than Simulink.Bus objects are not supported.

Open the slexVariantSubsystems model.

open_system('slexVariantSubsystems')
VSS_MODE = 2

In the MATLAB Editor, define a Simulink.Parameter object, V.

V = Simulink.Parameter;
V.Value = 1;
V.DataType = 'int32';
V.CoderInfo.StorageClass = 'Custom';
V.CoderInfo.CustomStorageClass = 'ImportedDefine';
V.CoderInfo.CustomAttributes.HeaderFile ='rtwdemo_importedmacros.h';

Note:

Variant control variables defined as Simulink.Parameter objects can have any of the storage classes listed in Storage Classes for Different Variant Activation Times.

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 Simulink.Parameter object as the variant control variable in the block parameters dialog box of the Controller block. Also, change the Variant activation time to code compile.

During simulation, the Linear Controller block becomes active. Double-click the Controller block to see the active choice.

sim ('slexVariantSubsystems')
ans = 
  Simulink.SimulationOutput:

                   tout: [1000x1 double] 
                   yout: [1000x1 double] 

     SimulationMetadata: [1x1 Simulink.SimulationMetadata] 
           ErrorMessage: [0x0 char] 

Similarly, if you change the value of V to 2, the Nonlinear Controller block becomes active during simulation.

V .Value = 2;
sim ('slexVariantSubsystems')
ans = 
  Simulink.SimulationOutput:

                   tout: [1000x1 double] 
                   yout: [1000x1 double] 

     SimulationMetadata: [1x1 Simulink.SimulationMetadata] 
           ErrorMessage: [0x0 char] 

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 demos_macro.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.

% demos_macro.h
% /* Exported data define */
% 
% /* Definition for custom storage class: Define */
% #define V          1        /* Referenced by:
%                             * '<S1>/Linear Controller'
%                             * '<S1>/Nonlinear Controller'
%                             */
% #endif                      /* RTW_HEADER_demo_macros_h_ */

Enumerated Types To Improve Code Readability of Variant Control Variables of Variant Blocks

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 slexVariantSubsystems model.

open_system('slexVariantSubsystems')
VSS_MODE = 2

In the base workspace, define the classes that map enumerated values to meaningful names.

Here, EngType is an integer-based enumeration class that is derived from the built-in data type, int32. The class has two enumeration values, Linear and NonLinear. These enumerated values have underlying integer values 0 and 1.

type EngType
classdef EngType < Simulink.IntEnumType
        enumeration
        Small (1)
        Big (2)
        end
end

Specify the enumeration names as variant control variables in the block parameters dialog box of the Controller block. Also, change the Variant activation time to code compile.

Define the variant control variable, V in the base workspace, specify its value as EngType.Small and then simulate the model.

V = EngType.Small;

During simulation, the Linear Controller block becomes active. Double-click the Controller block to see the active choice.

sim ('slexVariantSubsystems')
ans = 
  Simulink.SimulationOutput:

                   tout: [1000x1 double] 
                   yout: [1000x1 double] 

     SimulationMetadata: [1x1 Simulink.SimulationMetadata] 
           ErrorMessage: [0x0 char] 

The code that you generate using enumerated types contains the names of the values rather than integers. Here, values 1 and 2 are represented as EngType_Small and EngType_Big.

% slexVariantSubsystems_types.h
%  #ifndef V
%  #define V                              EngType_Small
%  #endif
% 
%  #ifndef DEFINED_TYPEDEF_FOR_EngType_
%  #define DEFINED_TYPEDEF_FOR_EngType_
% 
%  typedef int32_T EngType;
% 
%  /* enum EngType */
%  #define EngType_Small                  (1)      /* Default value */
%  #define EngType_Big                    (2)
%  #endif


% slexVariantSubsystems.c
%  void slexVariantSubsystems_step(void)
%  {
%     #if V == EngType_Small
%       logic of Linear Controller
%     #elif V == EngType_Big
%       logic of Nonlinear Controller
%     #endif
%  } 

Note that for variant blocks 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, or uint16, or by subclassing Simulink.IntEnumType

These enumerations are also supported when permanently stored in a Simulink® data dictionary. See Enumerations in Data Dictionary.

Simulink.Variant Objects for Variant Condition Reuse of Variant Blocks

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.Variant objects. Simulink.Variant objects enable you to reuse common variant conditions across models and help you encapsulate complex variant condition expressions.

You can specify the whole of a variant condition expression or only the variant control variable inside the condition expression of type Simulink.Variant.

Note:

  • You can define a variant control variable of type Simulink.Variant only in the base workspace or in a data dictionary. Defining Simulink.Variant type of variant control variables in the mask or model workspace is not supported. For more information on storage locations for variant control variables, see Storage Locations for Variant Control Variables (Operands) in Variant Blocks.

  • Simulink.Variant within structures are not supported.

Open the slexVariantSubsystems model.

open_system('slexVariantSubsystems');
VSS_MODE = 2

In the MATLAB® Editor, encapsulate variant control expressions as Simulink.Variant objects.

V_LinearController=Simulink.Variant('V==1');
V_NonLinearController=Simulink.Variant('V==2');

Specify the Simulink.Variant objects as the variant control variables in the block parameters dialog box of the Controller block.

Define the variant control variable, V, specify its value as 1 and then simulate the model.

V = 1;

During simulation, the Linear Controller block becomes active. Double-click the Controller block to see the active choice.

sim ('slexVariantSubsystems')
ans = 
  Simulink.SimulationOutput:

                   tout: [1000x1 double] 
                   yout: [1000x1 double] 

     SimulationMetadata: [1x1 Simulink.SimulationMetadata] 
           ErrorMessage: [0x0 char] 

Using this approach, you can develop complex variant condition expressions that are reusable.

Associate Activation Time with Control Variables of Variant Blocks

Simulink.VariantControl object enables you to associate variant activation time with a variant control variable.

You can define Simulink.VariantControl type of control variables in storage locations as listed in Storage Locations for Variant Control Variables (Operands) in Variant Blocks.

Open the slexVariantParameters model.

open_system('slexVariantSubsystems')
VSS_MODE = 2

In the block parameters dialog box of the Controller block, specify variant controls, V == 1 and V == 2.

In the base workspace, define a Simulink.VariantControl object, V, set its value to 1, and then simulate the model.

V = Simulink.VariantControl('Value', 1, 'ActivationTime', 'update diagram analyze all choices')
V = 
  VariantControl with properties:

             Value: 1
    ActivationTime: 'update diagram analyze all choices'

Note that the Variant activation time that you specify in the block parameter dialog box overrides the ActivationTime that you specify in the Simulink.VariantControl object.

During simulation, the Linear Controller block becomes active. Double-click the Controller block to see the active choice.

sim ('slexVariantSubsystems')
ans = 
  Simulink.SimulationOutput:

                   tout: [1000x1 double] 
                   yout: [1000x1 double] 

     SimulationMetadata: [1x1 Simulink.SimulationMetadata] 
           ErrorMessage: [0x0 char] 

Similarly, if you change the value of V to 2, the Nonlinear Controller block becomes active during simulation. You can change the value of V using this command or from Simulink.VariantControl dialog box.

V.Value = 2;
sim ('slexVariantSubsystems')
ans = 
  Simulink.SimulationOutput:

                   tout: [1000x1 double] 
                   yout: [1000x1 double] 

     SimulationMetadata: [1x1 Simulink.SimulationMetadata] 
           ErrorMessage: [0x0 char] 

Related Topics