Pass Function Handles from MATLAB to Simulink
显示 更早的评论
I'm trying to implement control barrier functions in Simulink, and it's decided to make my life pretty difficult. I'm also a bit of a beginner in Simulink, though, so I'm hoping someone can help me with what I'm trying to do.
The problem:
I have a MATLAB script that sets up a large number of variables and then opens and runs a Simulink model with a control loop in it. Included in that control loop is a large quadratic program to be solved at every time step, where the constraints of that quadratic program are calculated using several control barrier functions and their first few time derivatives. The bottom line is that I need to make between 20 and 30 custom functions that each take in a vector input and return a scalar output.
First of all, my MATLAB script needs to have access to all of these functions because I need to check that hyperparameters defined in the script satisfy some requirements with the initial condition with the model. So, I need to write each of these functions in the MATLAB script regardless. And second of all, it's just so, so much easier to write these functions in MATLAB. As MATLAB functions, they're all one-liners. As Simulink functions, they all require several blocks.
What I'm currently doing:
Currently, I just have every one of the functions I need implemented in both MATLAB and Simulink. So, the bottom of my MATLAB script looks like
function h = h_x_lower(state, x_min)
h = state(1) - x_min;
end
function hdot = hdot_x_lower(state)
hdot = state(7);
end
% (I'm omitting a lot of the functions here for brevity)
function hddot = hddot_obs(state, a, b, g)
hddot = 2*(state(7)^2 + g*(state(1) - a)*state(4) + state(8)^2 - g*(state(2) - b)*state(5));
end
function hdddot = hdddot_obs(state, a, b, g)
hdddot = 2*g*(3*state(4)*state(7) + (state(1) - a)*state(10) - 3*state(5)*state(8) - (state(2) - b)*state(11));
end
and then I also have all of these Simulink functon blocks:

The issue is that this isn't a sustainable solution. I've just discovered that I want to significantly revise my design, which means that I have to remake all of these functions and add several more besides. I don't want to have to do all that work in two places every time I revise my design, and I'm really, really hoping there's a way around it.
Potential solution I've considered (1):
First, I'm aware of the existence of Interpreted MATLAB Function blocks, which seem to be exactly what I'm looking for. However, I've also read that they're extremely slow and will be removed in future versions of Simulink. So it sounds like I should avoid them if possible.
Potential solution I've considered (2):
The other solution I've considered is defining each of these MATLAB functions in the script (as I've already done) and then calling them in MATLAB Function blocks. The issue is that I'm not sure how to get the MATLAB Function block to acknowledge the existence of the functions as I've written them above. I do realize that Simulink can access parameters stored in the MATLAB workspace, so one thing I've tried is storing function handles in the MATLAB workspace - something like
a = 1; b = 1; g = 9.8;
hdddot_obs = @(state) hdddot_obs(state, a, b, g);
- and then defining a MATLAB Function block that takes the function handle as an argument and giving the block a mask so that I can put the function handle in as a parameter. The contents of the block look like
function hdddot = hdddot_obs(state, hdddot_obs_handle)
hdddot = hdddot_obs_handle(state);
I then added the following mask:

and I changed the argument hdddot_obs_handle to a parameter as below:

Finally, I passed the function handle to the block as below:

and connected it up to my model very simply as below:

However, when I try to run my model (which otherwise works fine) with this function block added in, I get the following error:
Expression 'hdddot_obs_handle' for initial value of data 'hdddot_obs_handle' must evaluate to logical or supported numeric type.
Conclusion:
Evidently, it's not possible to pass function handles as parameters to Simulink, at least not in the way I'm trying to do it. (Or perhaps I'm just doing something wrong.) I'm sure there should be a way to do generally what I'm trying to do. (I'm a bit frustrated that Interpreted MATLAB Function blocks are broken because they're exactly what I'm looking for.) As I said before, I'm kind of new to Simulink -- the whole masking thing took me several hours and multiple help docs to figure out. If anyone could give me some pointers for what I'm trying to do, I would greatly appreciate it.
采纳的回答
更多回答(1 个)
Fangjun Jiang
2023-11-20
编辑:Fangjun Jiang
2023-11-20
1 个投票
Design all those functions as Simulink Functions. A Simulink Function can be called in Simulink and/or inside a MATLAB Function block.
Put the "scripts to check that hyperparameters defined in the script satisfy some requirements with the initial condition with the model" inside a MATLAB Function block and put the MATLAB Function block inside the Initialize subsystem. This MATLAB Function block can call all those Simulink Functions. It is executed only once at the initialization of the simulation.
The way you put all the functions in one file makes the first function as the main function but the rest as "local functions". Local functions can only be called within the same file.
The other approach would require making one file for each function, which is not desirable.
5 个评论
Peter Fisher
2023-12-7
Gregor
2024-2-11
Hello Peter.
Did you manage to figure out how to pass function handles (generated in a m script) as parameters to Simulink (matlab function blocks) in the end?
I am trying to solve the same issue and would be curious if there is a solution
Many thanks
Walter Roberson
2024-2-11
There is no way to pass a function handle to Simulink. In order to pass such a thing, there would have to be a signal type that could hold function handles, but there is not: https://www.mathworks.com/help/simulink/ug/signal-types.html
Peter Fisher
2024-2-11
Peter Fisher
2024-2-11
类别
在 帮助中心 和 File Exchange 中查找有关 Programming 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!