- If the Simulink model is fully algebraic, see if you can move it into MATLAB during the ode myfunc call.
- Wrap at least the ODE solve of your code within simulink. Then you incur the Simulink setup and solving only once. There's a single sim() call.
Run Simulink Model as a Function
11 views (last 30 days)
Show older comments
Greetings,
I'm inheriting a complicated simulink model. My goal is to encapsulate said simulink model for use by my matlab functions.
To illustrate my problem, below is a simple simo.slx with input at Port 1 and output at Port 2. Is there a way to encapsulate this such that I could do the following in Matlab Command line?
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/308801/image.png)
%% Desired Function created from simulink slx model
output = simo(3); % returns output = 6
With the capability above, my plan is to do use the function generated by Simulink inside a ODE45 function. Unfortunately sim function does not achieve what I need as it runs the entire standalone simulink model.
Thank you in advance.
0 Comments
Accepted Answer
Peter O
on 3 Jun 2020
Hi Sze,
To clarify, you're hoping to run a simulink model from within a call to ODE45? While possible, I'm afraid this is going to run painfully slow from overhead. If this is really what you need, then replace the Input and Output ports with From Workspace and To Workspace blocks. You specify the variable names on either side. Then, call sim() within ode45's function, something like
[y,t] = ode45(@myfunc, tspan, x0, etc)
function dy = myfunc()
sim('simo') % spits out variable 'k' to workspace. Since you're wrapped, you may need to specify that Simulink interfaces with the caller workspace and not the global one.
dy = 2*k
end
Two thoughts instead:
For #2, I'm assuming that Simulink is used to compute dy in some form and that's why you need to call it from within ODE45. If that's the case, then make the model (which has ports) into a subsystem. Port 2 about will feed into an upper level model in which you compute the rest of the things needed for dy (you can even use a MATLAB function block within Simulink, so you don't have to convert your code into blocks). Then connect dy to an Integrator block, and you're off to the races!
Hopefully this helps give you some direction. If you have further questions about specifics I'd be happy to answer them.
3 Comments
Peter O
on 3 Jun 2020
Sze,
Agreed, S-functions take the fun out of function.
From #1, it sounds like the Simulink model's dynamics are necessary to calculate dy within the ODE45 call. It also makes it sound like you've got slow and fast dynamics, like an inner and outer loop.
Simulink's bread and butter is ODEs. If you don't mind sharing a few more specifics about the model and what it calculates for your function, it might help me understand if there's a way to make things play more nicely. From what you've described, my gut feeling says that the cleanest and most maintainable way is let Simulink do your integration and to structure it like the image below.
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/308885/image.png)
I know you want to use ode45, but since you're handing off the function integration to ode45, you're already outsourcing the control flow for the integration. Is there a reason you can't use the User-Defined-Functions/MATLAB Function to call the remaining existing bits? This technique avoids S-functions. You can make that block a wrapper that does nothing but call your external MATLAB code and looks like:
function dy = fcn(u)
dy = my_external_func(u)
end
If it needs extra parameters, those can be defined and supplied by declaring parameters to fcn through the simulation explorer. You would have to break the function into two blocks if you have code that needs to compute before simo.slx can run and code that has to run after simo but prior to integrating, but that's light work. If the outer loop solver has to be ODE45, and simo.slx is stiff or needs a different solver for another reason, you can use a model reference block instead of a subsystem to isolate the solvers.
If the above approach wouldn't work, what am I missing? Does the derivative computation function interface somewhere else in the system? Is something getting parallelized? Does simo.slx affect only ten states out of a thousand you're computing at each time step?
I have done what you're considering -- setting the initial state manually to a Simulink model and altering the StartTime and StopTime parameters as you go. It's very handy when searching for a steady-state condition: run, check, push out a little longer if not there yet. I think it could work for this case too. Save the FinalStates output and assign the output of sim() to a variable so you get an easier to work with structure, and set that to the Initial State for the next bit. It's just that this method is usually five or ten calls max. My concern is that if you reset on every ODE45 timestep, you're going to be waiting forever.
More Answers (0)
See Also
Categories
Find more on Simulink Functions in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!