I need to periodically interrupt a SIMULINK model, and restart it with the the state it was in at some previous time (with some changes to model parameters using environmental variables).
The concise questions is: how do i take 'XXX = sim(gcs)' and define a restart state from a timeslice of 'XXX'?
The gist of what i'm trying to do is as follows:
%% LOAD SYSTEM
if ~isempty(gcs); close_system(gcs,0); endSIMSYS = load_system(systemname) ; setActiveConfigSet( SIMSYS, 'Configuration1' );cset = getConfigSet( gcs, 'Configuration1' ); set_param(cset,'SaveFormat', 'StructureWithTime' );set_param(cset,'StateSaveName', 'state_history'); % SIMULATE over intervals
for kk = 1:5; %length(tstarts); %1
tstart = tstarts(kk); tend = tends(kk); set_param(cset,'StartTime', string(tstart) ); set_param(cset,'StopTime', string(tend) ); set_param(cset,'SaveState', 'on'); if kk==1; % set initial details and paramter values
set_param(cset,'Solver','VariableStepAuto') set_param(cset,'SolverName','VariableStepAuto') set_param(cset, 'LoadInitialState','off'); set_param(cset, 'LoggingToFile','off'); B.R = 3; B.C = 0.12; B.P = 17.0; end try simOUT = sim( gcs, cset ); catch ME rethrow(ME) end % modify things for next iteration
set_param(cset, 'LoadInitialState','on'); % MAKE a variable 'rststate' from the
rststate = simOUT.state_history; % get record time closest to next
[~,rst_kt] = min( abs(rststate.time - tstart) ); %***
for rstkk = 1:length(rststate.signals); rststate.signals(rstkk).values = rststate.signals(rstkk).values( rst_kt ); end rststate.time = rststate.time(rst_kt); % SET intial state as restart state
set_param(cset, 'InitialState', 'rststate' ); %[B.R, B.C, B.P] = parameter_update(some system monitors)
end system_close(gcs,0)
Unfortunately, this fails at the SECOND call to 'sim' with the error
Size mismatch in the initial state for model 'your_model'. The signals(136).values field in the initial state structure has1 element(s), where as the corresponding state 'Discrete' in block 'your_model/Solver Configuration' has 2 element(s)
What I've done before is manually remove these blocks from the restart state at line *** a la:
rststate.signals(136)=[] % or similar
but this works inconsistently and is model specific. Namely, when i do remove entry 136, which corresponds to the Solver Configuration, I get the following error which is absolutely perplexing:
Unable to load the specified initial state for model 'your_model'. Cannot find a matching block statecorresponding to element 135 of signals structure array
To me , it seems like the indexing ouf the output state and the initial state are different. THat's not a typo; removing element 136 from the initial signal gives a model that element 135 is not provided. The following don't work either, in the sense that they remove the 136th signal element, and produces and undefined element 135.
%rmblk = find( ismember( {rststate.signals(1:end).label}, 'Discrete') )rmblk = find( contains( {rststate.signals(1:end).blockName },'Solver'));rststate.signals(rmblk) = [];
Best Answer