Real-Time Interface between App in AppDesigner and Simulink using parsim - Error: not enough input arguments @(x)addlistener

More questions to the topic.
Error using nhf>@(x)addlistener(x,'SimulationOutput','PostSimFcn',listener) (line 233)
Not enough input arguments.
in my simulink-modell i do the following. Is something wrong here?
Should i write listener = @nhf (Class)?
This function run in nhf (Class)
function Simulate(obj)
for simNr = numel(obj.Data):-1:1
in(simNr) = Simulink.SimulationInput(obj.simModel);
for prop = fieldnames(obj.Data(simNr))'
in(simNr) = in(simNr).setVariable(char(prop), obj.Data(simNr).(char(prop)));
% tbd: assign to baseworkspace
% assignin('base',char(prop), obj.Data(simNr).(char(prop)));
end
if isdeployed
in(simNr) = simulink.compiler.configureForDeployment(in(simNr));
end
end
% - Disable the automatic opening of the visualization viewer
% - Should be done for all models before compiling
% -------------------------------------------------------------
%open_system(obj.simModel);
%set_param(obj.simModel, 'SimMechanicsOpenEditorOnUpdate', 'off');
% Set up the listener for progress updates
listener = @(src,event) updateProgress(app,event);
% Save results internally
obj.simOut = parsim(in, ...
'ShowProgress','on',...
'TransferBaseWorkspaceVariables','on',...
'SetupFcn',@(x) addlistener(x, 'SimulationOutput', 'PostSimFcn', listener));
What is wrong in the function ('SetupFcn', @(x) addlistener(x, 'SimulationOutput', 'PostSimFcn', listener) ?
Is the function in simulink wrong?

 Risposta accettata

The error you are encountering is because the arguments given to the "addlistener" function is not correct. The function required an "event" as input and the "postSimFcn" will not be considered as an event here.
Please make sure that "SimulationOutput" is defined as an event in the class definition as follows.
events
Simulationoutput % Define a custom event
end
Also, make sure to add the "setPostSimFcn" as shown below.
for simNr = numel(obj.Data):-1:1
in(simNr) = Simulink.SimulationInput(obj.simModel);
for prop = fieldnames(obj.Data(simNr))'
in(simNr) = in(simNr).setVariable(char(prop), obj.Data(simNr).(char(prop)));
% tbd: assign to baseworkspace
% assignin('base',char(prop), obj.Data(simNr).(char(prop)));
in(simNr) = in(simNr).setPostSimFcn(@(simOut) obj.postSimFunction(simOut, simNr));
end
if isdeployed
in(simNr) = simulink.compiler.configureForDeployment(in(simNr));
end
end
Please modify the "parsim" command as follows to correct the arguments of the "addlistener" function.
obj.simOut = parsim(in, ...
'ShowProgress', 'on', ...
'TransferBaseWorkspaceVariables','on',...
'SetupFcn', @(x) addlistener(obj, 'Simulationoutput', @updateProgress));
Now, you can modify the post simulation function to notify the listener once the event is completed. You can decide on when to call the "notify" function. But below is an example on how you can use the function in your implementation.
function simOut = postSimFunction(obj, simOut, simNr)
try
% Example: Save each simulation output to a file
save(sprintf('output_%03d.mat', simNr), 'simOut');
% Notify listeners that the simulation output is ready
notify(obj, 'Simulationoutput', SimulationCompletedData(simNr, simOut));
catch ME
disp(['Error in PostSimFcn: ', ME.message]);
end
end
classdef SimulationCompletedData < event.EventData
properties
SimulationNumber
SimulationOutput
end
methods
function data = SimulationCompletedData(simNr, simOut)
data.SimulationNumber = simNr;
data.SimulationOutput = simOut;
end
end
end
Here, I have provided the normal workflow and syntaxes, you can modify the code as required for "AppDesigner".
For more information on "addlistener" and "notify" function, please refer to the below documentation links.
Hope you find this information helpful!

9 Commenti

Hello Gayathri
i have problems to implement these in my appdesigner.
My App handle already with a script and so it is not possible to do a second classdef.
How can i solve this issue?
Next to this, i got the Error 'PostSimFcn'
How can i handle this?
Hello if i try something else:
new .m function for classdef
classdef SimulationCompletedData < event.EventData
properties
SimulationNumber
SimulationOutput
end
methods
function data = SimulationCompletedData(simNr, simOut)
data.SimulationNumber = simNr;
data.SimulationOutput = simOut;
end
end
end
Then i got this error:
Why?
Kind regards
Fabian
@Fabian, can you provide your complete code including the class definitions, so that I can look into the issue in detail?
%Hello here ist the Code: nhf_weiterentV01 handle with the mlapp-File
classdef nhf_weiterentV01 < handle
events
Simulationoutput %Define a custom event
end
function Simulate(obj)
for simNr = numel(obj.Data):-1:1
in(simNr) = Simulink.SimulationInput(obj.simModel);
for prop = fieldnames(obj.Data(simNr))'
in(simNr) = in(simNr).setVariable(char(prop), obj.Data(simNr).(char(prop)));
% tbd: assign to baseworkspace
% assignin('base',char(prop), obj.Data(simNr).(char(prop)));
in(simNr) = in(simNr).setPostSimFcn(@(simOut) obj.postSimFunction(simOut, simNr));
end
if isdeployed
in(simNr) = simulink.compiler.configureForDeployment(in(simNr));
end
end
obj.simOut = parsim(in, 'ShowProgress','on',...
'TransferBaseWorkspaceVariables','on',...
'SetupFcn', @(x) addlistener(obj, 'Simulationoutput', 'PostSimFcn', @updateProgress));
function simOut = postSimFunction(obj, simOut, simNr)
try
% Example: Save each simulation output to a file
save(sprintf('output_%03d.mat', simNr), 'simOut');
% Notify listeners that the simulation output is ready
notify(obj, 'Simulationoutput', SimulationCompletedData(simNr, simOut));
catch ME
disp(['Error in PostSimFcn: ', ME.message]);
end
end
end
% in a second .m-File (SimulationCompletedData.m)
classdef SimulationCompletedData < event.EventData
properties
SimulationNumber
SimulationOutput
end
methods
function data = SimulationCompletedData(simNr, simOut)
data.SimulationNumber = simNr;
data.SimulationOutput = simOut;
end
end
end
% in the mlapp-Code:
function updateGUI(app, varargin)
progress = event.Progress;
app.PercentageOfSim.Value = progress;
end
% in the model for StartFcn:
%The GUI handles are by
set(0,'ShowHiddenHandles','on');
app = evalin('base', 'app');
%Set up the arguments that will go out from Outport to event callback listener
blk='D2002_PTD1000/TimeOut';
event = 'PostOutputs';
listener = @(h,e) updateGUI(app);
%Create the listener
h = add_exec_event_listener(blk,event, listener);
@Fabian, I am not really sure of how you have designed your "app". I had inserted a "button" to start the simulation once the button is pressed. Please look into the code below of the ".mlapp" file which I had used to verify the code you provided.
classdef app < matlab.apps.AppBase
% Properties that correspond to app components
properties (Access = public)
UIFigure matlab.ui.Figure
Button matlab.ui.control.Button
EditField matlab.ui.control.NumericEditField
EditFieldLabel matlab.ui.control.Label
end
properties (Access = private)
SimulationObject % Description
end
methods (Access = public)
function updateGUI(app, varargin)
progress = event.Progress;
app.PercentageOfSim.Value = progress;
end
end
% Callbacks that handle component events
methods (Access = private)
% Button pushed function: Button
function startFcn(app, event)
exampleData=struct();
exampleData(1).var1 = 1;
exampleData(2).var1 = 2;
app.SimulationObject = nhf_weiterentV01(exampleData);
% Set up data for the simulation, e.g., app.SimulationObject.Data
app.SimulationObject.Simulate();
end
end
And I had created "nhf_weiterentV01.m" and "SimulationCompletedData.m" files in the same folder as that of the ".mlapp" file with the class definitions.
Please modify your "nhf_weiterentV01.m" file as per the code shown below. As I could see a function defined within another function in the code you provided. This might be due to the wrong placement of "end" function.
classdef nhf_weiterentV01 < handle
properties
simModel = 'simple'; % Name of your Simulink model
Data; % Data for simulations
simOut; % Simulation output storage
end
events
Simulationoutput % Define a custom event
end
methods
function obj = SimulationExample(data)
obj.Data = data;
end
function Simulate(obj, app)
% Prepare the SimulationInput objects
for simNr = numel(obj.Data):-1:1
in(simNr) = Simulink.SimulationInput(obj.simModel);
in(simNr) = in(simNr).setVariable('gainValue', simNr); % Example variable setup
for prop = fieldnames(obj.Data(simNr))'
in(simNr) = in(simNr).setVariable(char(prop), obj.Data(simNr).(char(prop)));
end
in(simNr) = in(simNr).setPostSimFcn(@(simOut) obj.postSimFunction(simOut, simNr));
end
% Set up the listener for progress updates
%addlistener(obj, 'Simulationoutput', @(src, event) app.updateProgress(event));
% Run simulations using parsim
obj.simOut = sim(in, ...
'ShowProgress', 'on', ...
'SetupFcn', @(x) addlistener(obj, 'Simulationoutput', @updateProgress));
end
function simOut = postSimFunction(obj, simOut, simNr)
try
% Example: Save each simulation output to a file
save(sprintf('output_%03d.mat', simNr), 'simOut');
% Notify listeners that the simulation output is ready
notify(obj, 'Simulationoutput', SimulationCompletedData(simNr, simOut));
catch ME
disp(['Error in PostSimFcn: ', ME.message]);
end
end
end
end
% Define a mock updateProgress function in your app
function updateProgress(~, ~)
fprintf('Simulation completed.\n');
% Additional processing can be done using event.SimulationOutput
end
With these changes, I was able to run the ".mlapp" file without any errors. Please find the screenshot below which shows the same.
@Gayathri now you use only sim in your function.
We want to use parsim. And we want to get the process of each simulation in parsim. Is that possible?
@Fabian, it will work even if you change "sim" to "parsim" in the code.
Here is the output after modifying the code to use "parsim" function.
Unfortunately, it's not exactly what I'm looking for.
I am looking for a way to read out a variable that I change in the Simulink model during the simulation during the parsim simulation and display it in the app. Quasi as a live variable from the Simulink model during parsim

Accedi per commentare.

Più risposte (0)

Richiesto:

il 3 Feb 2025

Commentato:

il 7 Feb 2025

Community Treasure Hunt

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

Start Hunting!

Translated by