Capture Simulation State, Fast Restart, and Step Through Model Containing FMU
This example shows how to use the internal states of a standalone cosimulation FMU to enhance the simulation capability of a model with fixed-step solver FMU in Simulink®. Internal states of an FMU enables you to stop and resume simulation using model operating points, perform iterative simulation using fast restart, and analyze your model using backward simulation stepping.
The first section of this example exports a Simulink® model to a standalone cosimulation FMU. The FMU is imported back into Simulink® model using the FMU Import block.
The second section shows how to pause the simulation at a desired time, capture the simulation state of the model using model operating point, change model parameters, and resume simulation from the saved operating point.
The third section shows how Fast Restart feature can be used for large number of quick iterative simulations that do not require recompiling the model between successive simulations.
The final section shows how FMU with states enable you to debug the model using backward simulation stepping.
Generate FMU with FMUState Capability and Import to Simulink
Open the massSpringDamperPISInternalVar
model. This model contains a PID controller that controls the position of a mass in a mass-spring-damper system.
basemodel = 'massSpringDamperPIDInternalVar';
open_system(basemodel);
Use the exportToFMU
function to export this model as an FMU with the FMUState
option enabled so that the generated FMU contains its state information.
exportToFMU(basemodel, "FMIVersion", "3.0", "FMUType", "CS", "EnableFMUState","on");
Setting System Target to FMU 'Co-Simulation' for model 'massSpringDamperPIDInternalVar'. Setting Hardware Implementation > Device Type to 'MATLAB Host' for model 'massSpringDamperPIDInternalVar'. ### 'GenerateComments' is disabled for 'Co-Simulation' FMU Export. Build Summary Top model targets: Model Build Reason Status Build Duration ================================================================================================================================= massSpringDamperPIDInternalVar Information cache folder or artifacts were missing. Code generated and compiled. 0h 0m 15.131s 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 15.91s ### Model was successfully exported to 'Co-Simulation' FMU: '/tmp/Bdoc24b_2725827_1537762/tp4c9e9c2a/simulinkcompiler-ex78526457/massSpringDamperPIDInternalVar.fmu'.
You can also use the FMU Export dialog to generate the FMU. In the Simulation tab on the Simulink® toolstrip, click drop-down button for Save. Select Standalone FMU..... This opens the FMU Export dialog. Open the Advanced tab within the dialog and select the Enable FMUState capability check box. Click Create to generate the FMU.
The generated FMU with FMUState
allows you to utilize the simulation features that enable enhanced simulation control. The canGetAndSetFMUState
and canSerializeFMUState
flags in the modelDescription.xml
are set to true for an FMU when it supports FMU states.
The massSpringDamperPID_modelFMU
Simulink® model imports the generated FMU into Simulink®. The referenceGenerator
function creates a reference signal for the controller to follow. The reference signal is initially a step input that sets the position of the mass to a non-zero steady state. After a specified time, the reference signal is an oscillating sine wave about this point.
Open the model and set the attributes for the sine wave and specify the PID controller parameters.
model_for_sim = 'massSpringDamperPID_modelFMU'; open_system(model_for_sim); sine_freq = 2; % Used to set the frequency of sine input generator sine_amp = 0.02; % Used to set the amplitude of sine input generator sine_time = 20; % Used to specify the time at whcich sine input starts set_param('massSpringDamperPID_modelFMU/FMU','Kp','100'); set_param('massSpringDamperPID_modelFMU/FMU','Kd','50'); set_param('massSpringDamperPID_modelFMU/FMU','Ki','100');
Use Model Operating Point to Pause and Resume Simulation
Model operating points help you to capture the simulation state of a model at a specified time. This enables you to perform faster iterative simulations for a simulation scenario with a common initialization phase and iterative simulations from the end of the initialization phase. For more information on using model operating point, see Use Model Operating Point for Faster Simulation Workflow.
To simulate iteratively with model operating point, first create a Simulink.SimulationInput
object for the model. Set the SaveFinalState
and SaveOperatingPoint
properties of this model to on
to save the model operating point. Specify a start time of 0 second and stop time of 20 second for the initialization phase for this model and simulate the model. Observe the simulation run till the end of the initialization phase. The operating point information is captured at the specified 20 second mark.
simInitial = Simulink.SimulationInput(model_for_sim); simInitial = setModelParameter(simInitial, 'SaveFinalState', 'on', 'SaveOperatingPoint', ... 'on','StartTime', '0', 'StopTime', int2str(sine_time)); initialSim = sim(simInitial); plotData = figure(1); plotData.Name = "System Response"; plot(initialSim.yout{2}.Values, 'r', 'LineWidth', 1.5); hold on; plot(initialSim.yout{1}.Values, 'g', 'LineWidth', 1.5); hold on; legend('Reference Signal', 'System Response','Location', 'northwest'); grid minor;
Create another Simulink.SimulationInput
object and set the saved model operating point as the initial state for the new simulation. Specify the final stop time as 50 second and resume the simulation to continue the simulation from the last saved operating point. Observe the simulation restart at 20 second and run till 50 second.
simOPResume = Simulink.SimulationInput(model_for_sim); simOPResume = setModelParameter(simOPResume, 'StopTime', '50'); simOPResume = setInitialState(simOPResume, initialSim.xFinal); resumeSim = sim(simOPResume); plot(resumeSim.yout{2}.Values, '--r', 'LineWidth', 1.5); hold on; plot(resumeSim.yout{1}.Values, '--g', 'LineWidth', 1.5); hold on; plot(initialSim.yout{1}.Values.Time(end), initialSim.yout{1}.Values.Data(end), '*k', 'LineWidth', 1.5); hold on; plot(initialSim.yout{2}.Values.Time(end), initialSim.yout{2}.Values.Data(end), '*k', 'LineWidth', 1.5); legend('Reference Signal', 'System Respose', 'Refernece Signal - resumed', 'System Response - resumed', 'Location','southeast');
You can now change the parameters of the model and resume the simulation from 20 second mark which is captured as the operating point.
For example, you can change the proportional coefficient Kp
of the controller for better transient tracking performance.
set_param('massSpringDamperPID_modelFMU/FMU','Kp','500'); simOPResume_1 = Simulink.SimulationInput(model_for_sim); simOPResume_1 = setModelParameter(simOPResume_1, 'StopTime', '50'); simOPResume_1 = setInitialState(simOPResume_1, initialSim.xFinal); resumeSim_1 = sim(simOPResume_1); plotDataNewParam = figure(2); plotDataNewParam.Name = "System Response"; plot(initialSim.yout{2}.Values, 'r', 'LineWidth', 1.5); hold on; plot(initialSim.yout{1}.Values, 'g', 'LineWidth', 1.5); hold on; plot(resumeSim.yout{2}.Values, '--r', 'LineWidth', 1.5); hold on; plot(resumeSim_1.yout{1}.Values, '--b', 'LineWidth', 1.5); hold on plot(initialSim.yout{1}.Values.Time(end), initialSim.yout{1}.Values.Data(end), '*k', 'LineWidth', 1.5); hold on; plot(initialSim.yout{2}.Values.Time(end), initialSim.yout{2}.Values.Data(end), '*k', 'LineWidth', 1.5); hold on grid minor; legend('Reference Signal', 'System Response', 'Refernece Signal - remused', 'System Response - resumed with new parameters', 'Location','southeast');
Use Fast Restart for Quicker Iterative Simulations
Fast Restart enables you effectively perform iterative simulations when you do not need to compile the model between successive simulations. For more information about using Fast Restart, see How Fast Restart Improves Iterative Simulations.
To perform iterative simulations using Fast Restart, first enable fast restart for the model.
set_param(model_for_sim,FastRestart="on");
This compiles the model and prepares it for simulation. You can now run quick iterative simulations without recompiling the model. For example, you can perform a parameter sweep to study the effect of increasing the proportional coefficient Kp
for the PID controller.
set_param('massSpringDamperPID_modelFMU/FMU','Kp','1'); set_param('massSpringDamperPID_modelFMU/FMU','Kd','50'); set_param('massSpringDamperPID_modelFMU/FMU','Ki','100'); set_param(model_for_sim, 'StartTime', '0', 'StopTime', '50'); plot_fastRestart = figure(3); grid minor; hold on; kp_array = 50:50:500; num_kp_array = length(kp_array); legendEntries = cell(num_kp_array+1,1); for i = 1:num_kp_array set_param('massSpringDamperPID_modelFMU/FMU', 'Kp', num2str(kp_array(i))); outFastRestart = sim(model_for_sim); plot(outFastRestart.yout{1}.Values, 'LineWidth', 1.2); legendEntries{i} = ['Kp = ', num2str(kp_array(i))]; hold on; end plot(outFastRestart.yout{2}.Values, '--k', 'LineWidth', 1.5); legendEntries{end} = 'Reference Signal'; legend(legendEntries, 'Location','southeast');
Step Forward and Backward Through Simulation
With FMUState enabled, you can also perform backward simulation stepping to step backward through major time steps of your simulation. Doing so helps you analyze and debug your model in Simulink®. To learn more about simulation stepping, see Step Through Simulations Using the Simulink Editor.
The Simulation tab of the Simulink® toolstrip contains Step Forward and Step Back buttons to enable you to perform simulation stepping.
To step back through the simulation, you must first enable stepping back. To enable stepping back, on the Simulation tab of the Simulink® toolstrip, click the Step Back drop down. Click Configure Simulation Stepping from the drop down options. Doing so opens the Simulation Stepping Options dialog box. Select the Enable stepping back check-box in the dialog.
Before you can step back, you must step forward. You cannot step back to a simulation time before the time you enabled stepping back. Click Step Forward twice. Then, click Step Back.
See Also
exportToFMU
| Simulink.SimulationInput