I would like to write a matlab function that wraps around a simulink block. The function should load data into the simulink model, run it, then return the data back from the function.
The only way I can think of doing this is by using the 'To Workspace' and 'From Workspace' blocks in simulink. The problem is that the 'From Workspace' block doesn't pick up variables from the function scope, only from the workspace scope.
Below is the only solution I could come up with, which basically converts the incoming vector to a string, and then creates a function which gets called when the model starts (effectively this is just as bad as eval).
Here is the code:
function [ dataOut ] = run_simulink( dataIn )
% Convert data to a string (this is the part I would like to avoid)
variableInitString = sprintf('simin = %s;', mat2str(dataIn));
% we need both the name and the filename
modelName = 'programatic_simulink';
modelFileName = strcat(modelName,'.slx');
% load model (without displaying window)
load_system(modelFileName);
% Set the InitFcn to the god awful string
% this is how the dataIn actually gets into the model
set_param(modelName, 'InitFcn', variableInitString);
% run it
sim(modelName);
% explicity close without saving (0) because changing InitFcn
% counts as changing the model. Note that set_param also
% creates a .autosave file (which is deleted after close_system)
close_system(modelName, 0);
% return data from simOut that is created by simulink
dataOut = simout;
end
And you run it like this: run_simulink([0 0.25 0.5 0.75; 1 2 3 4]')
where the first part of the matrix is the time vector.
Finally here is the underlying simulink file with the workspace block properties open for completeness.
(If the image is fuzzy, click to enlarge)
Is there a more clean way to do this without the mat2str()
and sprintf()
? The sprint
line takes forever to run, even with vectors of size 50k.