Model stop function callback cannot recognise variable when running with parsim

5 visualizzazioni (ultimi 30 giorni)
I have a function writeDataToPhobos, which I have added to my model's StopFcn callback. This function works fine when running without parsim. But with parsim, I get the error 'Unrecognized function or variable 'casenumber'.'
writeDataToPhobos(writeToPhobos, modelDirectory, writeToPhobosDebugMode, datenumNow, casenumber, CurveName, Experiment, Project, Database)
I have assigned all variables to the simIn objects as:
simIn(casenumber) = simIn(casenumber).setVariable('writeToPhobos',writeToPhobos);
simIn(casenumber) = simIn(casenumber).setVariable('modelDirectory',modelDirectory);
simIn(casenumber) = simIn(casenumber).setVariable('writeToPhobosDebugMode',writeToPhobosDebugMode);
simIn(casenumber) = simIn(casenumber).setVariable('datenumNow',datenumNow);
simIn(casenumber) = simIn(casenumber).setVariable('casenumber',casenumber);
simIn(casenumber) = simIn(casenumber).setVariable('CurveName',CurveName);
simIn(casenumber) = simIn(casenumber).setVariable('Experiment',Experiment);
simIn(casenumber) = simIn(casenumber).setVariable('Project',Project);
simIn(casenumber) = simIn(casenumber).setVariable('Database',Database);
and also set the post sim function as:
simIn(casenumber) = simIn(casenumber).setPostSimFcn(@(x) writeDataToPhobos(writeToPhobos, modelDirectory, writeToPhobosDebugMode, datenumNow, casenumber, CurveName, Experiment, Project, Database));
  2 Commenti
Paul
Paul il 21 Gen 2023
Hi Afzal,
Are you trying to use both the StopFcn and the postSimFcn after running a single simulation?
If I understand correctly, you want to call the function writeDataToPhobos after the simulation is complete. The variables writeToPhobos, modelDirectory, etc. are all used to run the simulation? Or are they only used after the simulation stops in the call to writeDataToPhobos?
How is the simulation executed and where are those variables defined when everything "works fine when running without parsim."? Using sim? Some other method?
I'm asking because the solution you've found seems more complicated than it should be; maybe there's an easier way to do this. If interested in potential for alternatives, can you post a code snippet that illustrates the code flow for setting up the simIn array and then running parsim?
Afzal
Afzal il 21 Gen 2023
Are you trying to use both the StopFcn and the postSimFcn after running a single simulation?
Originally, I wanted to just use the StopFcn. When that didn't work I started using postSimFcn. With the solution I've found below, I no longer require the postSimFcn.
If I understand correctly, you want to call the function writeDataToPhobos after the simulation is complete. The variables writeToPhobos, modelDirectory, etc. are all used to run the simulation? Or are they only used after the simulation stops in the call to writeDataToPhobos?
Only 'casenumber' is used by the simulation. The rest of the variables are used only by the function writeDataToPhobos
How is the simulation executed and where are those variables defined when everything "works fine when running without parsim."? Using sim? Some other method?
The variables are just set in the base workspace by a script, and the model is run using the command 'sim(Model)'.

Accedi per commentare.

Risposta accettata

Afzal
Afzal il 20 Gen 2023
Found the solution here. Had to modify it slighlty. My function:
function setParsimVars(in)
for iVar = 1:length(in.Variables)
assignin('base',in.Variables(iVar).Name,in.Variables(iVar).Value);
end
end
And then set model preSimFcn as:
simIn(casenumber) = simIn(casenumber).setPreSimFcn(@(x) setParsimVars(simIn(casenumber)));

Più risposte (1)

Paul
Paul il 21 Gen 2023
Modificato: Paul il 21 Gen 2023
Having all the variables in the base workspace, using sim('mymodel'), and using the StopFcn works fine because in that case StopFcn can access the base workspace. But things work differently with parsim.
The following code worked fine for me. At first I thought that parsim might require the simIn variables to set in the model workspace to get to the PostSimFcn, but that's not the case. I don't know if the workspace makes a difference as far as the how the simulation actually executes.
The problem can be solved in at least two ways as shown below.
The first option is to use setPostSimFcn to set up a function that simply takes all of the simIn variables and appends them to the original output of the parsim command. The function writeDataToPhobos could be called from inside simpostfunc using the values of the simIn variables, or it could be called after parsim command because all of the simIn variables are stored in y. The advantage of this approach is that it saves all of the simIn variables in the ouput y.
The second approach is commented out but worked fine for me. Just set the postSimFcn to directly call writeDataToPhobos. It seems like this is exactly what you tried; don't know why it works for me but doesn't work for you.
for ii = 1:2
casenumber = ii;
writeToPhobos = true;
simIn(ii) = Simulink.SimulationInput('MyModel');
% experiment to see if the Workspace matters for parsim
% simIn(ii) = setVariable(simIn(ii),'casenumber',casenumber,'Workspace','MyModel');
% simIn(ii) = setVariable(simIn(ii),'writeToPhobos',writeToPhobos,'Workspace','MyModel');
simIn(ii) = setVariable(simIn(ii),'casenumber',casenumber);
simIn(ii) = setVariable(simIn(ii),'writeToPhobos',writeToPhobos);
% both methods work
simIn(ii) = setPostSimFcn(simIn(ii),@(simout) simpostfunc(simIn(ii).Variables));
% simIn(ii) = setPostSimFcn(simIn(ii),@(simout) writeDataToPhobos(casenumber,writeToPhobos));
end
y = parsim(simIn);
function newout = simpostfunc(simvariables)
% simple function to echo the simIn variables to the the simulation output
% call writeDataToPhobos here if desired
newout.simvars = simvariables;
end
function writeDataToPhobos(casenumber,writeToPhobos)
if writeToPhobos
casenumber
end
end
After running the code, y(2) contains
>> y(2)
ans =
Simulink.SimulationOutput:
simvars: [1x2 Simulink.Simulation.Variable]
SimulationMetadata: [1x1 Simulink.SimulationMetadata]
ErrorMessage: [0x0 char]
>> y(2).simvars
ans =
1×2 Variable array with properties:
Name
Value
Workspace
Description
>> y(2).simvars(1)
ans =
Variable with properties:
Name: 'casenumber'
Value: 2
Workspace: 'global-workspace'
Description: ""
>> y(2).simvars(2)
ans =
Variable with properties:
Name: 'writeToPhobos'
Value: 1
Workspace: 'global-workspace'
Description: ""
  6 Commenti
Afzal
Afzal il 22 Gen 2023
Thanks, I think using the TransferBaseWorkspaceVariables name/value pair argument may be the best approach. The model is quite big, but based on what I've seen, the LoadFcn are just setting variables.

Accedi per commentare.

Categorie

Scopri di più su Programmatic Model Editing in Help Center e File Exchange

Tag

Prodotti


Release

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by