Model stop function callback cannot recognise variable when running with parsim

3 ビュー (過去 30 日間)
Afzal
Afzal 2023 年 1 月 20 日
コメント済み: Paul 2023 年 1 月 22 日
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 件のコメント
Paul
Paul 2023 年 1 月 21 日
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 2023 年 1 月 21 日
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)'.

サインインしてコメントする。

採用された回答

Afzal
Afzal 2023 年 1 月 20 日
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)));

その他の回答 (1 件)

Paul
Paul 2023 年 1 月 21 日
編集済み: Paul 2023 年 1 月 21 日
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 件のコメント
Afzal
Afzal 2023 年 1 月 22 日
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.
Paul
Paul 2023 年 1 月 22 日
You're welcome. Also, I posted an Answer to the question you linked to that might be of interest.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeProgrammatic Model Editing についてさらに検索

タグ

製品


リリース

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by