Model stop function callback cannot recognise variable when running with parsim
4 次查看(过去 30 天)
显示 更早的评论
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
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?
采纳的回答
更多回答(1 个)
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: ""
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Programmatic Model Editing 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!