MATLAB Answers

Run Simulink Model as a Function

7 views (last 30 days)
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?
%% 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

Sign in to comment.

Accepted Answer

Peter
Peter 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:
  1. If the Simulink model is fully algebraic, see if you can move it into MATLAB during the ode myfunc call.
  2. 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.
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

Sze Kwan Cheah
Sze Kwan Cheah on 3 Jun 2020
Hi Peter,
Thank you for the quick response. Yes, the plan is to run the simulink model within a call of ODE45.
Unfortunately your suggestion of including sim('simo') inside the ode function would not work as intended since it will solve the ODE for the entire timespan specified within the simulink model, not just at the instance in time required by your myfunc.
[y, t] = ode45(@myfunc, tspan, x0)
function dy = myfunc(t, x)
sim('simo') % default runs the entire 10 seconds, not computing at the instant of "t" of myfunc
% declaring computed output as "k" to workspace within "simo"
dy = k;
end
Perhaps there is a way to hack it by having simulink solution settings set from "t" to "t+delt" with fixed "Euler" time step of "delt" and the initial state "x0" where delt=1e-6; x0=x; defined within myfunc. I agree the overhead will be large and this method is not preferred. I assume MATLAB has a better/elegant way of doing it but can't find it in the help files.
To address your questions directly:
  1. No, it's not simply algebraic, it is a dynamic system.
  2. Yes, the code can be converted to blocks but this is a large effort. I find writing S-functions for use in Simulink not much fun.
Thank you, Sze Kwan
Peter
Peter 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.
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.
Sze Kwan Cheah
Sze Kwan Cheah on 3 Jun 2020
Hi Peter,
Thank you again for responding so quickly. I should provide more context to the problem which fortunately isn't very complicated. We have a SIMULINK model that simulates a mini-drone and, if I'm not mistaken, can also be controlled by MATLAB. I was hoping to encapsulate the mini-drone SIMULINK dynamic system with a function (thrust commands to dynamic response) and then code up a dynamic control law instead of using SIMULINK blocks.
Perhaps I am completely mistaken and have been overthinking it. I think I may implement #2 even with estimated feedforward in my control law.
Thank you, Sze Kwan

Sign in to comment.

More Answers (0)

Products


Release

R2019b

Translated by