Control Active Choice of Variant Subsystem During Simulation or Code Generation
You can change the active variant of a Variant
Subsystem block during simulation or code generation by using a Parameter Writer
block to model the variant change. To enable run-time activation of variants, in the Block
Parameters dialog box of the Variant Subsystem block, set Variant
activation time to runtime
. To set the block parameter
programmatically, enter this command in the MATLAB® Command
Window:
set_param("Variant Subsystem",'VariantActivationTime','runtime')
Variant Subsystem
" is the name or handle of
the subsystem.Place a Parameter Writer block inside a conditionally executed subsystem or in an event function. Use the Parameter Writer block to write to a variable that you use in a condition expression for variant control. Set the Destination parameter of the Parameter Writer block based on the location of your variant control variable.
Block parameter
— Control variable is a mask parameter in a subsystem.Model workspace variable
— Control variable is located in the model workspace.Base workspace variable
— Control variable is located in the base workspace or a data dictionary.
Modeling Considerations
When configuring your model to use run-time variants, consider these modeling guidelines:
To avoid having multiple variants active at the same time or no variants active, use a single Parameter Writer block to write to the variant control expression of a run-time variant block.
To avoid conflict, the variant control expression must be written such that at any point in simulation, only one variant is active. For example,
vc==1
,vc==2
, orvc~=1
.To use a Parameter Writer block from the top model to write to a run-time variant block, create a control variable in the model workspace and configure the variable as a model argument by selecting the Argument checkbox. You can tune the control variable from the top model or create a system mask from the referenced model, then use the mask dialog from the top model to tune the control variable.
For more information, see Configure Instance-Specific Values for Block Parameters in a Referenced Model.
Switch Active Variants at Run Time Using a Parameter Writer Block Inside a Conditional Subsystem
This example shows how to change the traffic signal lights for a traffic control system by using run-time variants.
Explore the Harness Model
Open the model slexVariantRunTimeTraffic_Harness
.
open_system('slexVariantRunTimeTraffic_Harness')
This harness model uses a Variant Source block with the Variant control mode parameter set to sim codegen switching
to automatically switch the input signals between simulation and code generation.
For simulation, signals from a pulse wave generator control the signal. For code generation, you can replace the ReadFromHardware
subystem with production logic that provides the signal inputs.
Explore the Controller Model
Open the traffic control system model slexVariantRunTimeTraffic_Controller
.
open_system('slexVariantRunTimeTraffic_Controller')
The controller model contains a Stateflow chart and a variant subsystem configured for run-time activation.
The Stateflow chart determines which light is turned on by using the input signal as a trigger. Depending on the current state of the signal, Stateflow invokes the corresponding Simulink Function block, TrafficMove
or TrafficStop
, to set the variant control variable stTrafficLight
using a Parameter Writer block. This variant control variable activates the corresponding variant choice, go
or stop
, within the variant subsystem.
Mask icons are promoted to the run-time variant subsystem to change the icon based on the active variant choice.
An additional variant subsystem in the controller model uses the same variant control variable stTrafficLight
(with opposite logic) to control a pedestrian crossing light.
Switch Active Variants at Run Time Using a Parameter Writer Block Inside an Event Function
This example shows how to use startup and run-time variant activation times to calculate the torque demand for a vehicle capable of operating in both two-wheel and four-wheel drive modes.
Upon startup, the system assesses whether the vehicle is equipped for a two-wheel drive system or switchable four-wheel drive system. If the vehicle is a switchable four-wheel drive vehicle, the system can alternate between two-wheel and four-wheel drive during run time, depending on the external conditions and driver overrides. Otherwise, the system will use the two-wheel drive system. A startup variant determines whether to use the two-wheel drive system or the switchable four-wheel drive system. A run-time variant controls the system that alternates between two-wheel drive and four-wheel drive in the switchable four-wheel drive system.
Explore the Harness Model
Open the harness model slexVariantRunTimeTruck_Harness
.
open_system('slexVariantRunTimeTruck_Harness')
In the top model, you can select whether to run the model as a two-wheel drive or a switchable four-wheel drive vehicle by double-clicking the 2WD
or 2WD_4WD
block. The block callbacks set the value of the variant control variable that corresponds with the selected vehicle design. The reset ports of the referenced model trigger the run-time variant switching in a switchable four-wheel drive vehicle.
The referenced model can be used for simulation as well as code generation.
Explore the Controller Model
Open the referenced controller model slexVariantRunTimeTruck_Controller
.
open_system('slexVariantRunTimeTruck_Controller')
The controller model uses startup variant activation time to select the vehicle drive type.
If the vehicle is a switchable four-wheel drive vehicle, the model uses run-time variant activation time to switch between drive types based on external inputs.
During run-time switching, state transfer between drive modes is done using State Reader and State Writer blocks. State transfer ensures a smooth transition of output during run-time variant switching.
The Initialize Function block sets the vehicle type based on the argument received from the top model. If the vehicle type is set to a switchable four-wheel drive, the system is initialized to four-wheel drive mode.
Note that within the Initialize Function block, there is a Variant Source block with the condition expression VehTransType==VehTrans.TwoandFourWheelDrive
. The VehTransType
value is assigned by the first Parameter Writer block. Without block priority, Simulink sorts blocks based on their names.
Analysis of Simulation Output
When the vehicle is set to the two-wheel drive configuration at startup, the torque for the rear wheels remains at zero throughout the simulation, and the torque demand is met entirely by the front wheels.
When the vehicle is set to the switchable four-wheel drive configuration at startup, the rear wheel torque is calculated only when the four-wheel drive is active.
Analysis of the Generated Code
Generate code for the controller model.
evalc('slbuild("slexVariantRunTimeTruck_Controller")');
All states within the system are unconditionally initialized within the slexVariantRunTimeTruck_Controller_initialize()
function. This helps the initialization of states with initial condition values when explicit state initialization is not done during run-time variant switching. In this example, the run-time variant control variable TransRequestType
is explicitly initialized within the Initialize Function block using a Parameter Writer block.
The state handoff happens inside the functions slexVariantRunTimeTruck_Controller_SwitchTo4WD()
and slexVariantRunTimeTruck_Controller_Switch_To_2WD()
. The top model invokes these functions to switch the run-time variant.
coder.example.extractLines('slexVariantRunTimeTruck_Controller_ert_rtw/slexVariantRunTimeTruck_Controller.c',... 'void slexVariantRunTimeTruck_Controller_SwitchTo4WD(void)',... 'if (slexVariantRunTimeTruck_Cont_DW.Delay_DSTATE > 0.0)')
void slexVariantRunTimeTruck_Controller_SwitchTo4WD(void) { if (slexVariantRunTimeTruck_C_InstP.VehTransType == TwoandFourWheelDrive) { slexVariantRunTimeTruck_Contr_P.TransRequestType = slexVariantRunTimeTruck_Contr_P.TransRequest_FourWheel; }
Code Generation with Run-time Variants
To use run-time variants with code generation, set the model configuration parameter
Default parameter behavior to Tunable
. The
code generator generates conditional code as part of an if-else statement similar to
this:
void mParamWrWithOutIRTAndbaseW_codegen_step(void)
{
mParamWrWithOutIRTAndbaseW_co_B.Compare =
(mParamWrWithOutIRTAndbaseW_c_DW.Output_DSTATE ==
mParamWrWithOutIRTAndbaseW__co_P.CompareToConstant_const);
if (mParamWrWithOutIRTAndbaseW_co_B.Compare) {
V = mParamWrWithOutIRTAndbaseW_co_P.Constant1_Value_c;
}
if (V == 1) {
mParamWrWithOutIRTAndbaseW_co_Y.Out1 =
mParamWrWithOutIRTAndbaseW_co_P.Gain_Gain *
mParamWrWithOutIRTAndbaseW_co_P.Contant1_Value;
} else if (V == 2) {
mParamWrWithOutIRTAndbaseW_co_Y.Out1 =
mParamWrWithOutIRTAndbaseW_co_P.Gain_Gain_a *
mParamWrWithOutIRTAndbaseW_co_P.Contant1_Value;
}
mParamWrWithOutIRTAndbaseW_c_DW.Output_DSTATE +=
mParamWrWithOutIRTAndbaseW_co_P.FixPtConstant_Value;
if (mParamWrWithOutIRTAndbaseW_c_DW.Output_DSTATE >
mParamWrWithOutIRTAndbaseW_co_P.WrapToZero_Threshold) {
mParamWrWithOutIRTAndbaseW_c_DW.Output_DSTATE =
mParamWrWithOutIRTAndbaseW_co_P.Constant_Value;
}
}
void mParamWrWithOutIRTAndbaseW_codegen_initialize(void)
{
mParamWrWithOutIRTAndbaseW_c_DW.Output_DSTATE =
mParamWrWithOutIRTAndbaseW_co_P.Output_InitialCondition;
}
void mParamWrWithOutIRTAndbaseW_codegen_terminate(void)
{
}
Limitations
Limitations for run-time variants include:
Run-time variants are supported only for Variant Subsystem blocks and not inline variant blocks such as Variant Source or Variant Sink.
Simulink® Real-Time™ workflows with Model blocks containing IRT ports are not supported.
HDL Coder™ does not support run-time variants.
Blocks with continuous time signals are not compatible with run-time variants.
The variant activation time setting
Inherit from Simulink.VariantControl
is not supported because theSimulink.VariantControl
object does not support run-time activation.
See Also
Variant Subsystem | Parameter Writer