Condition Propagation with Variant Subsystem

When you specify variant conditions in models containing Variant Subsystem blocks, Simulink® propagates these conditions to determine which components of the model are active during simulation. A variant condition can be a condition expression or a variant object.

The variant condition annotations help you visualize the propagated conditions. To view the variant condition annotations, on the Debug tab, select Information Overlays > Variant Legend.

Note

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

In the legend, the (default) keyword is displayed as negated condition.

Consider this model containing a Variant Subsystem block with variant choices. A specific variant condition activates each block.

In the Variant Subsystem (Controller), sensor1 and sensor3 are used both in the Linear Controller and Nonlinear Controllers but sensor2 is used only in the Linear Controller. Hence, the sensor2 block is executed only when the Linear Controller choice is active and is not executed for any other choice. To ensure that the components outside of the Variant Subsystem (Controller) are aware of the active or inactive state of blocks with the Variant Subsystem block, the block condition must propagate outside of the Variant Subsystem block.

Propagate Conditions Without Generate Preprocessor Conditionals

To propagate conditions outside of Variant Subsystems without generate preprocessor conditionals, select the Propagate conditions outside of variant subsystem check box in the Block Parameter dialog box of the Variant Subsystem block. By default, Propagate conditions outside of variant subsystem is not selected.

When you simulate the model with the active choice as Nonlinear Controller and the Propagate condition outside of variant subsystem selected, only the active choice is analyzed. Notice that the Variant activation time is set to update diagram.

The Variant Condition Legend displays the inactive conditions as false. Here, sensor2 is inactive with variant choice as Nonlinear Controller and is marked as false. The annotations are displayed on the sensor2 port and the inactive block that is connected to sensor2.

When you generate code for condition propagation without generate preprocessor conditionals, the inactive blocks are ignored. In this example, the input port In2 is not shown in the generated code.

Propagate Conditions with Generate Preprocessor Conditionals

To propagate conditions outside of Variant Subsystem with generate preprocessor conditionals, select the Propagate conditions outside of variant subsystem check box and set the Variant activation time to code compile in the Block Parameters dialog box of the Variant Subsystem.

Note

Variant activation time is available only when you specify Variant control mode as Expression.

When you simulate the model with active choice as Nonlinear Controller and Propagate conditions outside of variant subsystem check box and the Variant activation time set to code compile, all the variant choices are analyzed. The Variant Condition Legend displays the variant conditions associated with the model.

When you generate code for condition propagation with generate preprocessor conditionals, the model is analyzed for all the choices. In this example, the input port In2 is guarded with necessary conditions.

Note

To propagate variant conditions outside a Variant Subsystem block for zero or one active variant control specified, select Allow zero active variant controls.

Adaptive Interface for Variant Subsystems

When you select the Propagate conditions outside of variant subsystem check box in the Block Parameters dialog box, the Variant Subsystem adapts its interface to the connected blocks. Consider this model.

The Controller block is a Variant Subsystem that provides a Linear and a Nonlinear choice. The Linear choice is active when V = 1, and the Nonlinear choice is active when V = 2. Here, V is a variant control variable of the Simulink.Parameter type. Select the Controller block and, in Simulink click Diagram > Block Parameters (Subsystem). Verify that the Propagate condition outside of variant subsystem check box is selected.

To change the value of the variant control variable, in the MATLAB command window, type V.Value = 1 or V.Value = 2.

Double-click the Controller block to view its contents. The Linear choice is using sensor1 and sensor3 inputs of the Controller (Variant Subsystem block). It is not using sensor2 and, therefore, does not produce a saturate output.

When you simulate this model, the Variant Subsystem block adapts its interface such that the condition V = 2 (v:1 V=2) propagates the In2, the filter, and the saturation logger blocks.

Condition Propagation with Conditional Systems

When you propagate a condition to a conditional system, the same condition is set to all ports. For more information, see Propagate Variant Condition to Conditional Subsystem.

Consider this model. Here, when the condition is propagated to the Inport block (fcn), the same condition propagates to all the Inport and Outport blocks (as shown in the Variant Legend) and makes the Variant Subsystem block conditional.

Known Limitations

  • Propagated variant conditions from variant subsystems cannot be set on Simscape™ or Stateflow® blocks.

  • C++ code generation is not supported for models that contain propagated conditions outside of a Variant Subsystem block.

  • Variant condition propagation is not supported in models with root bus element ports.

Note

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

Propagate Conditions Programmatically

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

  • Propagate conditions without generate preprocessor conditionals:

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

    For example,

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

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

    For example,

    set_param('sldemo_variant_subsystems/Controller','PropagateVariantConditions','on',...
    'GeneratePreprocessorConditionals','on')

Code Generation with Conditional Systems

You can generate code for the model. To do so, on the Apps tab, click Embedded Coder, then on the C Code tab, click Build. For more information on configuring model to generate code, see Prepare Variant-Containing Model for Code Generation.

Consider a variant model containing a Variant Subsystem block for generating code.

In the generated code, the code inside fcn definition is guarded by C preprocessor conditionals #if and #endif.

void fcn(void)
{
  /* RootInportFunctionCallGenerator: '<Root>/RootFcnCall_InsertedFor_fcn_at_outport_1' */
#if VSSMODE == 0

    rtDWork.Linear.DiscreteFilter = rtU.In1 - 0.5 *
    rtDWork.Linear.DiscreteFilter_states;
 
  rtDWork.Linear.DiscreteFilter_states = rtDWork.Linear.DiscreteFilter;
  
#endif                                 /* VSSMODE == 0 */

#if VSSMODE == 1

    rtDWork.Nonlinear.DiscreteFilter = look1_binlxpw(rtU.In1,
    rtCP_LookupTable_bp01Data, rtCP_LookupTable_tableData, 4U) - 0.5 *
    rtDWork.Nonlinear.DiscreteFilter_states;
  
  rtDWork.Nonlinear.DiscreteFilter_states = rtDWork.Nonlinear.DiscreteFilter;
 
#endif                                 /* VSSMODE == 1 */
  
#if VSSMODE == 0
 
  rtY.Out1 = rtDWork.Linear.DiscreteFilter;

#endif                                 /* VSSMODE == 0 */
  
#if VSSMODE == 1
  
  rtY.Out1 = rtDWork.Nonlinear.DiscreteFilter;

#endif                                 /* VSSMODE == 1 */
 
}

Note

  • Configuring model as AUTOSAR component with runnable as Variant Subsystem choices is not supported.

Guarding the Function-Call Definition

To guard the whole definition of Function-Call (fcn), use a variant source as shown below.

In the generated code fcn() definition is guarded with A==1.

#if A == 1
void fcn(void)
{
…..
}
#endif

This function can be referred using a code snippet similar to as shown below.

…..
#if A==1
fcn()
#endif
……

Related Topics