Show Simulink simulation progess inside Matlab skript without too much performance loss.

Hello Community
I have a large Simulnk model which takes quite long to run (+/- 30min).
Now I would like to set parameters and start the simulation using a m-file. If I do so, Simulink no longer shows me the progress of the simulation on the bottom.
I searched for solutions and I programmed a custom progress bar using the Matlab function waitbar() and an "Embedded Matlab Function" block inside simulink.
The code looks like this:
function fcn(u1, u2)
% u1 = Current simulation time
% u2 = Total run-time of the simulation
coder.extrinsic('waitbar');
coder.extrinsic('evalin');
coder.extrinsic('sprintf');
h = evalin('base','h');
perc = u1/u2 * 100;
waitbar(u1/u2, h, sprintf('Completed: %.05fs of %.05fs (%.05f%%)', u1, u2, perc)
Inside my Matlab skript I execute the simulation as follows:
h = waitbar(0,'Please wait...');
out = sim(...);
close(h);
This solution works but seems to slow down my simulation a lot, probably because this embedded function block is called within every simulation step. Also print functions like sprintf() are known to be not so fast.
Now there are several questions that come with this solution.
  1. I have not managed to "pass" my waitbar handler into this function block. That's why I am using the evalin() function in order to get it from the workspace. Is there a better way to do this?
  2. Is it possible to tell Simulink that it should only execute this embedded function block once in a while, for example, every 0.1s?
  3. I know that I can implement this functionality inside my Matlab skribt by using the get_param() function in order to get the current simulation time. However, I have not figured out how to run the sim() command in the "background" so that my Matlab skript continues and then can enter a loop in which the progress bar is updated. How can I implement that?
  4. Is there a general, better solution for this that offers more performance?
Thanks for any answers!

Answers (3)

Add a Clock block to your root level model, or you can divide it by the totoal simulation time to get the percentage. You can use a Display block to just show the number or use a Scope block to show the curve. You can also set up sample time to mininize the efficiency impact. The value or curve will be updated when simulation is started by sim() command.

2 Comments

Hello Fangjun Jiang
Thank you for your answer.
I've already tried setting the sampling time much higher for this block, however, this does not seem to work.
The solution with the clock block seems to be quite good in terms of performance. Also, it is very easy to implement, so I am using this for now.
I meant setting the sample time for the extra Clock, Display or Scope block to reduce its impact on your simulation.

Sign in to comment.

model = 'your_model_name';
set_param(model, 'SimulationCommand', 'start');
while strcmp(get_param(model, 'SimulationStatus'), 'running')
% Get the current simulation time
currentTime = get_param(model, 'SimulationTime');
disp(['Current simulation time: ', num2str(currentTime)]);
pause(1); % Adjust the pause duration as needed
end
I use a simulation-monitor class for displaying progress utilizing a timer object (with option to stop simulation when it is stalled).
A basic implementation could look like:
classdef simMonitor < handle
properties
mdlName
actsimTime
lastsimTime
timerObj
minStep
end
methods
function obj = simMonitor(mdlName)
obj.mdlName = mdlName;
obj.timerObj = [];
end
function startTimer(obj, period, minStep)
obj.timerObj = timer('ExecutionMode', 'fixedRate', 'Period', period, 'TimerFcn', @(~,~)obj.timerFcn());
obj.actsimTime = 0;
obj.lastsimTime = -1;
obj.minStep = minStep;
start(obj.timerObj);
end
function stopTimer(obj)
if ~isempty(obj.timerObj)
stop(obj.timerObj);
delete(obj.timerObj);
obj.timerObj = [];
end
end
function delete(obj)
obj.stopTimer();
end
function timerFcn(obj)
if bdIsLoaded(obj.mdlName)
if strcmp(get_param(obj.mdlName,'SimulationStatus'),'compiling')
disp('Model compiles');
end
if strcmp(get_param(obj.mdlName,'SimulationStatus'),'running')
obj.actsimTime = get_param(obj.mdlName,'SimulationTime');
disp(['Current simulation time: ', num2str(obj.actsimTime)]);
if obj.actsimTime < obj.lastsimTime + obj.minStep
obj.stopTimer();
simulink.compiler.stopSimulation(obj.mdlName);
disp('Simulation did not advance enough: aborted.')
end
obj.lastsimTime = obj.actsimTime;
end
else
disp('Model not loaded (yet).');
end
end
end
end
Usage:
mdlName = 'myModel';
simMonitor = simMonitor(mdlName);
simMonitor.startTimer(0.5,1e-3);
load_system(mdlName)
sim(mdlName);
close_system(mdlName);
simMonitor.delete();

Categories

Products

Asked:

on 30 Mar 2020

Answered:

on 15 Jan 2026

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!