Main Content

Propagate Variant Conditions Outside Variant Subsystems

During simulation and code generation, Simulink® propagates the variant conditions to determine which components of the model remain active. By default, these conditions do not propagate outside the Variant Subsystem. To allow the conditions to propagate to the connecting blocks, you can use the Propagate conditions outside of variant subsystem parameter on the Variant Subsystem block. For more information about the Variant Subsystem block, see Variant Subsystem, Variant Model.

The propagation of variant conditions outside of the Variant Subsystem block ensures that the components outside of the block are aware of the active and inactive state of the underlying blocks in the Variant Subsystem.

Tip

Variant condition annotations on model components help you visualize the propagated conditions.

To view the annotations, on the Debug tab, select Information Overlays > Variant Legend.

If Variant Legend is not available, on the Debug tab, select Information Overlays > Variant Conditions.

Model showing propagation of variant conditions outside of a variant subsystem

Factors That Affect Propagation of Variant Conditions

The propagation of variant conditions outside of a Variant Subsystem depends on the variant activation time of the block and the interface of the underlying variant choices. The Variant activation time determines if Simulink must analyze only the active choice or both active and inactive choices of the block when simulating or generating code from the model. If the interface of the analyzed variant choices matches the interface of the Variant Subsystem block, the variant conditions do not propagate outside the Variant Subsystem. In other words, if the analyzed variant choices use all the input and the output signals of the Variant Subsystem block, the variant conditions do not propagate outside of the block. The variant conditions do propagate outside of the Variant Subsystem block only if the interfaces do not match.

Adaptive Interface for Variant Subsystems

This example shows how propagating variant conditions outside a Variant Subsystem block enables the block to adapt its interface according to the state of the underlying blocks for different activation times. Also, the code that is generated for different activation times are explained. For information on factors that affect the propagation, see Factors That Affect Propagation of Variant Conditions.

Consider the slexVariantSubsystemsAdaptiveInterface model containing a Variant Subsystem block named Controller with two variant choices, Linear and Nonlinear. The Linear controller is active when V = 1, and the Nonlinear controller is active when V = 2. V is a variant control variable and is defined in the PreLoadFcn callback of the model.

To change the value of the variant control variable, in the MATLAB™ Command Window, type V = 1 or V = 2.

Double-click the Controller block to view its contents. The Linear and Nonlinear controller blocks do not have the same interface. The inports sensor1 and sensor3 are used in Linear controller and Nonlinear controller blocks, but sensor2 is used only in Linear controller block. Hence, the sensor2 block is active only when Linear controller is active and is not executed for the other choice. To make the model components outside the Variant Subsystem (Controller) aware of the active or inactive state of blocks within the Variant Subsystem block, the block conditions must propagate outside the boundaries of the block. To propagate conditions outside of the Controller block, select Propagate conditions outside of variant subsystem in the Block Parameters dialog box of the block. By default, this parameter is set to off.

The propagation of variant conditions outside of Variant Subsystem depends on the Variant activation time of the block and the interface of its underlying variant choices. For more information, see Propagation with Different Activation Times.

Propagation with Different Activation Times

Next, simulate the model and generate code for Linear and Nonlinear controllers with different activation times.

Note

In the model, the saturate port is an unconnected output port and so it is not included in the generated code for any variant activation times.

Propagate Conditions for update diagram

  1. In the Block Parameters dialog box of the Controller block, set Variant activation time to update diagram.

  2. To activate the Linear controller and its connected blocks, change the value of V to 1 and simulate the model.

  3. Generate code from the model by using Embedded Coder® and observe the results. The generated code contains only the Linear controller. For information on how to generate code, see Generate Code Using Embedded Coder (Embedded Coder).

  4. Similarly, to activate the Nonlinear controller and its connected blocks, change the value of V to 2 and simulate the model. Generate code from the model and observe the results.

This table compares the propagation of variant conditions and the generated code for the Linear and Nonlinear controller choices for update diagram activation time.

When V = 1 Linear controller is activeWhen V = 2 Nonlinear controller is active
  • Only the Linear controller is analyzed.

  • The Linear controller uses only sensor1, sensor3 and u ports, so these ports and its connected blocks are active. The Linear controller does not use sensor2 and saturate ports, so these ports and its connected blocks are inactive. Since the interface of the Linear controller is different than the Controller subsystem, the variant conditions are propagated outside of the subsystem. The condition is propagated only to the ports that are not used by at least one of the variant choices. In this example, the variant annotation v:2 with condition set to false is displayed on sensor2, saturate, and all the connected blocks. In the variant conditions legend, a condition is set to false if the blocks associated with that condition are never active.

    Propagation of variant conditions outside of Controller subsystem when V = 1 for update diagram activation time

  • The code that you generate contains only the active ports. In this example, the input port In2 is inactive, so it is not part of the generated code.

    //slexVariantSubsystemsAdaptiveInterface.h
    /* External inputs (root inport signals with default storage) */
    typedef struct {
      real_T In1;                          /* '<Root>/In1' */
      real_T In3;                          /* '<Root>/In3' */
    } ExternalInputs;
    
    /* External outputs (root outports with default storage) */
    typedef struct {
      real_T u;                          /* '<Root>/u' */
    } ExternalOutputs;
    

    The active choice is unconditional. The unconditional statements are not enclosed in any conditional statements and are compiled or executed irrespective of the state of the variant choices.

    //slexVariantSubsystemsAdaptiveInterface.c
    /* Model step function */
    void step(void)
    {
    // Logic for Linear choice
    }
    /* Model initialize function */
    void initialize(void)
    {
      /* (no initialization code required) */
    

  • Only the Nonlinear controller is analyzed.

  • The Nonlinear controller uses all the input and output ports of the Controller subsystem, so all the input ports sensor1, sensor2, sensor3, and all its connected blocks are active. Also, all the output ports u, saturate, and all its connected blocks are active. Because of the matching interfaces, the variant conditions are not propagated outside of the Controller subsystem.

    Propagation of variant condition outside of Controller subsystem when V = 2 for update diagram activation time

  • The code that you generate contains only the active ports. In this example, all the input and the output ports are active and so they are part of the generated code.

    //slexVariantSubsystemsAdaptiveInterface.h
    /* External inputs (root inport signals with default storage) */
    typedef struct {
      real_T In1;                          /* '<Root>/In1' */
      real_T In2;                          /* '<Root>/In2' */
      real_T In3;                          /* '<Root>/In3' */
    } ExternalInputs;
    
    /* External outputs (root outports with default storage) */
    typedef struct {
      real_T u;                          /* '<Root>/u' */
    } ExternalOutputs; 
    

    The active choice is unconditional. The unconditional statements are not enclosed in any conditional statements and are compiled or executed irrespective of the state of the variant choices.

    /* Model step function */
    void step(void) 
    {
    // Logic for Nonlinear choice
    }
    /* Model initialize function */
    void initialize(void)
    {
      /* (no initialization code required) */
    

Note

When propagating variant conditions outside of a Variant Subsystem with update diagram activation time:

  • If you set Allow zero active variant controls to on, the variant condition is displayed on all other active ports and its connected blocks to distinguish between the active blocks that belong to the variant region and the blocks that belong to the fixed region during simulation.

  • The code that you generate with and without Allow zero active variant controls is the same.

Propagate Conditions for update diagram analyze all choices

  1. In the Block Parameters dialog box of the Controller block, set Variant activation time to update diagram analyze all choices.

  2. To activate the Linear controller and its connected blocks, change the value of V to 1 and simulate the model.

  3. Generate code from the model by using Embedded Coder and observe the results. The generated code contains only the Linear controller. For information on how to generate code, see Generate Code Using Embedded Coder (Embedded Coder).

  4. Similarly, to activate Nonlinear controller and its connected blocks, change the value of V to 2 and simulate the model. Generate code from the model and observe the results.

This table compares the propagation of variant conditions for the Linear and Nonlinear controller choices with update diagram analyze all choices activation time. The generated code is the same as update diagram.

When V = 1 Linear controller is activeWhen V = 2 Nonlinear controller is active
  • Linear controller and Nonlinear controller choices are analyzed.

  • The Linear controller uses only sensor1, sensor3 and u ports, so these ports and its connected blocks are active. The Linear controller does not use sensor2 and saturate ports and so, these ports and its connected blocks are inactive.

  • Since only the interface of the Nonlinear controller matches that of the Controller subsystem, and the interface of Linear controller does not match the interface of the Controller subsystem, the variant conditions are propagated outside of the Controller subsystem. The condition is propagated only to the ports that are not used by at least one of the variant choices. In this example, the variant annotation v:1 with condition set to V == 2 is displayed on the sensor2, saturate, and its connected blocks.

Propagation of variant conditions outside of Controller subsystem when V = 1 for update diagram analyze all choices activation time

  • Linear controller and Nonlinear controller choices are analyzed.

  • The Nonlinear controller uses all the input and output ports of the Controller subsystem, so all the input ports sensor1, sensor2, sensor3, and all its connected blocks are active. Also, all the output ports u, saturate, and all its connected blocks are active.

  • Since only the interface of the Nonlinear controller matches that of the Controller subsystem, and the interface of the Linear controller does not match the interface of the Controller subsystem, the variant conditions are propagated outside of the Controller subsystem. The condition is propagated only to the ports that are not used by at least one of the variant choices. In this example, the variant annotation v:1 with condition set to V == 2 is displayed on the sensor2, saturate, and its connected blocks.

Propagation of variant conditions outside of Controller subsystem when V = 2 for update diagram analyze all choices activation time

Note

When propagating variant conditions outside of a Variant Subsystem with update diagram analyze all choices activation time:

  • If you set Allow zero active variant controls to on, the variant condition is displayed on all other active ports and its connected blocks to distinguish between the active blocks that belong to the variant region and the blocks that belong to the fixed region during simulation.

  • The code that you generate with and without Allow zero active variant controls is the same.

Propagate Conditions for code compile

  1. In the Block Parameters dialog box of the Controller block, set the Variant activation time to code compile.

  2. To activate the Linear controller and its connected blocks, change the value of V to 1 and simulate the model.

  3. Generate code from the model by using Embedded Coder and observe the results. The generated code contains only the Linear controller. For information on how to generate code, see Generate Code Using Embedded Coder (Embedded Coder).

  4. Similarly, to activate the Nonlinear controller and its connected blocks, change the value of V to 2 and simulate the model. Generate code from the model and observe the results.

The propagation of variant conditions for Linear and Nonlinear controller choices is the same as update diagram analyze all choices. The code that is generated for the Linear and Nonlinear controllers is as shown.

The code contains active and inactive ports. The ports that are not used by at least any of the variant choices are enclosed in necessary preprocessor conditionals #if and #elif. In this example, the input port sensor2 is enclosed in condition V == 2.

//slexVariantSubsystemsAdaptiveInterface.h
External inputs (root inport signals with default storage)*/
typedef struct {
  real_T In1;                /* '<Root>/In1' */
	
#if V == 2
  real_T In2;                /* '<Root>/In2' */

#define EXTERNALINPUTS_VARIANT_EXISTS
#endif

  real_T In3;                /* '<Root>/In3' */
} ExternalInputs;
// External outputs (root outports fed by 
// signals with default storage)
typedef struct {
  real_T u;                            

The active and inactive choices are enclosed in preprocessor conditionals #if and #elif.

//slexVariantSubsystemsAdaptiveInterface.c
/* Model step function */
void step(void)
{
#if V == 1 
  // Logic for Linear choice
#elif V == 2  
 // Logic for Nonlinear choice
}
/* Model initialize function */
void initialize(void)
{
  /* (no initialization code required) */
}

Note

When propagating variant conditions outside of a Variant Subsystem with code compile activation time, if you set Allow zero active variant controls to on, the choices are enclosed in an additional conditional statement #if V == 1 || V == 2. This skips the compilation of both the choices if none of the choice evaluates to true.

Propagate Conditions for startup

  1. In the Block Parameters dialog box of the Controller block, set Variant activation time to startup.

  2. To activate the Linear controller and its connected blocks, change the value of V to 1 and simulate the model.

  3. Generate code from the model by using Embedded Coder and observe the results. The generated code contains only the Linear controller. For information on how to generate code, see Generate Code Using Embedded Coder (Embedded Coder).

  4. Similarly, to activate Nonlinear controller and its connected blocks, change the value of V to 2 and simulate the model. Generate code from the model and observe the results.

The propagation of variant conditions for the Linear and Nonlinear controller choices is the same as update diagram analyze all choices.

The code that is generated for the Linear and Nonlinear controllers is as shown.

The code contains active and inactive ports.

//slexVariantSubsystemsAdaptiveInterface.h
/* External inputs (root inport signals with default storage) */
typedef struct {
  real_T In1;                          /* '<Root>/In1' */
  real_T In2;                          /* '<Root>/In2' */
  real_T In3;                          /* '<Root>/In3' */
} ExternalInputs;

// External outputs (root outports fed by signals
// with default storage) */
typedef struct {
  real_T u;                            /* '<Root>/u' */
} ExternalOutputs;

The active and inactive choices are enclosed in regular if and else if conditions.

//slexVariantSubsystemsAdaptiveInterface.c
/* Model step function */
void step(void)
{
if (V == 1) 
  // Logic for Linear choice
else if (V == 2)  
 // Logic for Nonlinear choice
}
/* Model initialize function */
void initialize(void)
{
  startupVariantChecker();
}
static void startupVariantChecker(void)
{
  /* startup variant condition checks */
  utAssert((rtP.V == 1.0) + (rtP.V == 2.0) == 1);
}

Note

When propagating variant conditions outside of a Variant Subsystem with startup activation time, if you set Allow zero active variant controls to on, the choices are enclosed in an additional conditional statement if V == 1 || V == 2. This skips the compilation of both the choices if none of the choice evaluates to true.

Propagation Without Inport and Outport Blocks

Consider this model with a Variant Subsystem block that has two variant choices. There are no inports or outports on the block. The two variant choices have the conditions Var==1 and Var==2, respectively. When the Propagate conditions outside of variant subsystem parameter of the Variant Subsystem block is set to off, a logical OR of the variant conditions, Var==1 || Var==2, is set on the Variant Subsystem block. When the parameter is set to on, no conditions are applied on the Variant Subsystem block.

Variant Subsystem with no inports and outports

Propagate Conditions Programmatically

To propagate conditions outside of a Variant Subsystem block programmatically, use one of these syntaxes:

  • Propagate conditions:

    set_param(VariantSubsystemName, 'PropagateVariantConditions','on')

    For example,

    set_param('sldemo_variant_subsystems/Controller','PropagateVariantConditions','on')
  • Propagate conditions and generate preprocessor conditionals in code:

    set_param(VariantSubsystemName,'PropagateVariantConditions',...
    'on','VariantActivationTime','code compile')

    For example,

    set_param('slexVariantSubsystems/Controller','PropagateVariantConditions', ...
    'on','VariantActivationTime','code compile')

Limitations

Propagated variant conditions from variant subsystems can be set on Simscape™ or Stateflow® blocks only for the update diagram variant activation time.

Note

All elements of a Mux, Demux, or a Vector Concatenate block signal must have the same variant condition.

Related Topics