1

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!

Enrico Anderlini
  • 447
  • 6
  • 21
  • From your description it sounds as if you are using a `MATLAB Function` block, not an m-code S-Function. `MATLAB Function` blocks get converted to C and compiled during model initialization and only support a subset of the MATLAB language. You need to write an m-code S-Function. They do not convert the m-code to C but rather run it (as interpreted code) in the standard MATLAB computational engine, and hence support the full MATLAB language. – Phil Goddard Feb 05 '17 at 17:38
  • What you can also do is only use the `MATLAB Function` block as a wrapper around another m-code function. In the `MATLAB Function` you define your other function as extrinsic and just pass appropriate inputs to it, and get output from it back into the Simulink model. Then in the other function define the optimization that needs to be performed. – Phil Goddard Feb 06 '17 at 02:34
  • Thanks! You are right, to save time in the programming, I went for the Matlab function block. I will now try again and express it as an S-function instead. – Enrico Anderlini Feb 06 '17 at 07:24
  • I tried the second approach and it works as well. However, I think the S-function approach is neater. If you post an answer summarizing your two points, I will vote for it. – Enrico Anderlini Feb 06 '17 at 07:28
  • @PhilGoddard Correct me if I am wrong, but from Mathworks' documentation ([S-Func](https://www.mathworks.com/help/simulink/sfg/what-is-an-s-function.html); [MATLAB Func](https://www.mathworks.com/help/simulink/ug/what-is-a-matlab-function-block.html)) it would seems that both are compiled to C MEX. Also, from the second link: "Extrinsic functions execute in the workspace during model simulation", so they are interpreted in MATLAB. Not sure where the error OP mentioned with `fmincon` comes from. – Filip Cvejic Oct 11 '20 at 09:34
  • I think there is some info about the `Function handles cannot be passed to extrinsic functions` error [here](https://www.mathworks.com/matlabcentral/answers/16798-coder-and-error-passing-handles-to-extrinsic-functions#answer_22663). – Filip Cvejic Oct 11 '20 at 09:41
  • I did solve the problem, but thanks for that! The MATLAB function is indeed compiled to C MEX, but S-functions are typically more customisable. – Enrico Anderlini Oct 12 '20 at 11:26

1 Answers1

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:

enter image description here

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).

Matteo Ragni
  • 2,837
  • 1
  • 20
  • 34