This model illustrates Simulink® variant subsystems. Variant subsystems let you provide multiple implementations for a subsystem where only one implementation is active during simulation. You can programmatically swap out the active implementation and replace it with one of the other implementations without modifying the model.
A Variant Subsystem block contains two or more child subsystems where one child is active during model execution. The active child subsystem is referred to as the active variant. You can programmatically switch the active variant of the Variant Subsystem block by changing values of variables in the global workspace, or by manually overriding variant selection using the Variant Subsystem block dialog. The active variant is programmatically wired to the Inport and Outport blocks of the Variant Subsystem by Simulink during model compilation.
To programmatically control variant selection, a Simulink.Variant
object is associated with each child subsystem in the Variant Subsystem block dialog. Simulink.Variant
objects are created in the MATLAB® global workspace. These objects have a property named Condition
, which is an expression, that evaluates to a boolean value and is used to determine the active variant child subsystem.
Note: You can specify variant controls in the MATLAB® global workspace, model workspace, mask workspace, or a data dictionary.
For example, defining VSS_LINEAR_CONTROLLER=Simulink.Variant('VSS_MODE==1');
in the global workspace creates a Simulink.Variant
object where the constructor argument ('VSS_MODE==1')
defines when the variant is active. Using the Variant Subsystem dialog, you then associate VSS_LINEAR_CONTROLLER
with one of the child subsystems within the Variant Subsystem. Defining
VSS_MODE=1
in the global workspace, activates the VSS_LINEAR_CONTROLLER
variant. The condition argument can be a simple expression consisting of scalar variables, enumerations, equality, inequality, &&, , and ~. Parenthesis () can be used for precedence grouping.
The model in this example uses the following variant objects and variant control variable, which are defined in the MATLAB global workspace:
VSS_LINEAR_CONTROLLER=Simulink.Variant('VSS_MODE==1');
VSS_NONLINEAR_CONTROLLER=Simulink.Variant('VSS_MODE==2');
VSS_MODE=2;
Opening the example model sldemo_variant_subsystems
runs the PreLoadFcn defined in File -> ModelProperties -> Callbacks
. This populates the global workspace with the variables for the Variant Subsystem block named Controller:
open_system('sldemo_variant_subsystems')
Figure 1: The example model, sldemo_variant_subsystems
To specify the Simulink.Variant
objects association for the Controller subsystem, right-click on the Controller subsystem and select Subsystem Parameters
, which will open the Controller subsystem block dialog.
The Controller subsystem block dialog specifies two potential variants. The two variants are in turn associated with the two Simulink.Variant
objects VSS_LINEAR_CONTROLLER
and VSS_NONLINEAR_CONTROLLER
, which exist in the global workspace. These objects have a property named Condition, an expression that evaluates to a boolean and that determines which variant is active. The condition is also shown in the Variant Subsystem block dialog. In this example, the Condition properties of VSS_LINEAR_CONTROLLER
and VSS_NONLINEAR_CONTROLLER
are VSS_MODE == 1
and VSS_MODE == 2
, respectively. The variable VSS_MODE
resides in the global workspace, and can be a standard MATLAB variable or a Simulink.Parameter
.
If there is no associated variant object or a '%' (comment) character prefixes the variant object in the Variant Subsystem parameters dialog box, then the child subsystem is considered commented out and is not used during model execution.
open_system('sldemo_variant_subsystems/Controller');
Figure 2: Contents of the Controller subsystem block
Within a Variant Subsystem block, you can place Inport, Outport, and Subsystem blocks. In this example, the Linear Controller
Subsystem block is associated with the variant object, VSS_LINEAR_CONTROLLER
, and the Nonlinear Controller
Subsystem block is associated with the variant object, VSS_NONLINEAR_CONTROLLER
.
Signal connections are not allowed in the Variant Subsystem. Simulink programmatically wires up the Inport and Outport blocks to the active variant when simulating the model.
To simulate using the Linear Controller
variant, define:
VSS_MODE=1
in the global workspace and then simulate the model.
open_system('sldemo_variant_subsystems/Controller','parameter'); close_system('sldemo_variant_subsystems/Controller') VSS_MODE=1; %#ok (used by sldemo_variant_subsystems) sim sldemo_variant_subsystems;
Figure 3: Simulation using the Linear Controller
variant
To simulate using the Nonlinear Controller
, define
VSS_MODE=2
in the global workspace and then simulate the model.
VSS_MODE=2; % (used by sldemo_variant_subsystems) sim sldemo_variant_subsystems;
Figure 4: Simulation using the Nonlinear Controller
variant
The sldemo_variant_subsystems_enum
model illustrates the following Simulink.Variant
capabilities:
1. Enumerations: MATLAB enumeration classes can be used to improve readability in the conditions of the variant object.
2. Reuse: Simulink.Variant
objects can be reused in different Variant Subsystem blocks.
This example uses following variables which are defined in the MATLAB global workspace:
VSSE_LINEAR_CONTROLLER=Simulink.Variant( ... 'VSSE_MODE==sldemo_vss_CONTROLLER_TYPE.LINEAR')
VSSE_NONLINEAR_CONTROLLER=Simulink.Variant( ... 'VSSE_MODE==sldemo_vss_CONTROLLER_TYPE.NONLINEAR')
VSSE_MODE=sldemo_vss_CONTROLLER_TYPE.LINEAR
VSSE_PROTOTYPE=Simulink.Variant( ... 'VSSE_MODE_BUILD==sldemo_vss_BUILD_TYPE.PROTOTYPE')
VSSE_PRODUCTION=Simulink.Variant( ... 'VSSE_MODE_BUILD==sldemo_vss_BUILD_TYPE.PRODUCTION')
VSSE_MODE_BUILD=sldemo_vss_BUILD_TYPE.PRODUCTION
In these Simulink.Variant
objects, we use the enumeration classes, sldemo_vss_BUILD_TYPE.m, and sldemo_vss_CONTROLLER_TYPE.m to define the Simulink.Variant
Condition parameters which improves readability.
The three filter Variant Subsystems blocks, Filter1, Filter2, and Filter3 all use the VSSE_PROTOTYPE
and VSSE_PRODUCTION
Simulink.Variant
objects.
Note: The name of the enumeration class must be unique among data type names and global workspace variable names, and is case-sensitive.
Opening the example model sldemo_variant_subsystems_enum
runs the PreLoadFcn defined in File -> ModelProperties -> Callbacks
. This populates the global workspace with variables for the Variant Subsystem blocks:
open_system('sldemo_variant_subsystems_enum')
Figure 5: The example model, sldemo_variant_subsystems_enum
You can use enumerated types to give meaningful names to integers used as variant control values.
Consider the model rtwdemo_preprocessor_subsys
.
In the MATLAB Editor, define the classes that map enumerated values to meaningful names.
If the enumerated types are not defined correctly, an error will be displayed. Here are a couple of scenarios which results in error.
Invalid definition1: In this case, the Simulink.IntEnumType
is not defined.
Invalid definition2: In this case, the variables are not initialized.
Enter the variant control expression as shown in the next example:
Figure 6: Block Parameters
Define the value of V in the global workspace. For example, V=2;. The value can be a normal MATLAB variable or a Simulink.Parameter
object. However, the value cannot be an enumerated type.
Now generate code with Variant activation time set to code compile
. Sample code is as shown below.
Figure 7: Generated Code
For information on using Simulink.Variant
or Simulink.Parameter
object or MATLAB variables as a variant control variable, see the Approaches for Specifying Variant Controls section in Introduction to Variant Controls.
See the Embedded Coder documentation for more information on code generation for variant subsystems.