Variant Subsystems

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.

Overview of Variant Subsystems

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

Using Variant Subsystems

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.

Switching Active Variants

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

Enumerations and Reuse

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 the 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

Code Generation Using Enumerated types as Variant Control Variables

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 Analyze all choices during update diagram and generate preprocessor conditionals option selected. 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 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.