问题
I am trying to implement a particular type of model predictive control in the Simulink-Matlab framework. To do so, my plan was to have the dynamic model in Simulink call an external Matlab S-function which in turns runs an optimization that calls a different Simulink file. Hence, the program flow would be as follows:
Simulink -> Matlab (fmincon
or quadprog
) -> Simulink.
As you can see, the Matlab S-function would call either fmincon
or quadprog
, but I would like to use fmincon for my particular control type. Please, ignore any issues related to computational efficiency so far.
I tried this approach, but there are two very clear problems: * Firstly, in order to compile the code without errors (basically obtaining a .mex file, I do not need to program in C yet), I added the command
coder.extrinsic('fmincon');
This was required because otherwise Simulink is unable to compile the mex file. However, if you do this, then you get the following error:
Function handles cannot be passed to extrinsic functions.
I tried to change my cost function calling Simulink to another, simpler cost function (x.^2
), but I still get the error.
Looking for a solution to the problem, I found the same question (i.e. how to call fmincon
from a Matlab function within Simulink) on the Mathworks blog, but with no answer (https://uk.mathworks.com/matlabcentral/answers/65202-optimization-calling-fmincon-in-simulink-embedded-block).
Could anyone give me a hand? Thanks in advance!
回答1:
Instead of using coder.extrinsic
on the fmincon
function, I usually write a wrapper for the optimization problem that I have to solve as a .m
file function for Matlab (namely opt_problem
) and declare coder.extrinsic('opt_problem')
in the simulink Matlab function. I'll give you a simple example:
Consider this Simulink "model", in which at each integration step I want to solve a linear regression problem on some generated data. The optimization problem is something in the form:
minimize (y - m x - q)²
subject to 0 ≤ m ≤ 1
0 ≤ q ≤ 1
The scheme is really simple, bet the regressor calls fmincon
:
Let's see inside the regressor:
function [m, q] = regressor(xs, ys, mic, qic)
coder.extrinsic('opt_problem'); % <- Informing the Coder
m = 0;
q = 0;
[m, q] = opt_problem(xs, ys, mic, qic); % <- Optimal problem wrapper call
end
this function is only a wrapper for an external function opt_problem
. Let'see it (it has two functions inside):
function [m, q] = opt_problem(xs, ys, mic, qic)
fmincon_target = @(mq)(target(mq, xs, ys));
mq = fmincon(fmincon_target, [mic; qic], [], [], [], [], [0; 0], [1; 1]);
m = mq(1);
q = mq(2);
end
function r = target(mq, xs, ys)
r = norm(ys - xs.*mq(1) - mq(2));
end
and that's all. As you can see in the picture, the scheme runs and the solution are the m, q
parameters (in the two displays) that minimize the target function while respecting the constraints (m = 1.2 → m_opt = 1
).
来源:https://stackoverflow.com/questions/42054642/calling-fmincon-from-simulink