Get different optimization results in Simulink(S-Function) and MATLAB

Hi all,

I have a problem when using acados in Simulink.
Firstly, I use the Matlab interface to create an ocp object in Windows.
Then, I use the ocp.generate_c_code and make_sfun to create acados_solver_sfunction_ModelName.
However, when I use the same input, I get different optimization results from Matlab(I think the result in Simulink is wrong).
Futher more, I use the Python interface to generate S-Function in Linux, and this problem still exists.

Here are more details.
I want to use MPC in Quadrotor and creat the dynamics model by CasADi.
I set the current position to x=0, y=0, z=0 and set the reference position to x=0, y=0, z=1 to takeoff.
The optimization results u0 in both Matlab and Python are [1; 1; 1; 1].
That is, the input of the four motors is the maximum to takeoff.
However, the optimization result u0 in Simulink is [0.5309; 0.4347; 0.6110; 0.5285].

Here is a part of Matlab code:

%% cost
ocp_model.set('cost_type', 'linear_ls');
ocp_model.set('cost_type_e', 'linear_ls');

ocp_model.set('cost_W', blkdiag(model.W_x, model.W_u));
ocp_model.set('cost_W_e', model.W_x_e);
ocp_model.set('cost_Vx', Vx);
ocp_model.set('cost_Vx_e', Vx_e);
ocp_model.set('cost_Vu', Vu);

%% constraints
ocp_model.set('constr_type', 'bgh');
ocp_model.set('constr_lbu', repelem(min_input_val, nu));
ocp_model.set('constr_ubu', repelem(max_input_val, nu));
ocp_model.set('constr_Jbu', eye(nu));

%% ocp opts
ocp_opts.set('param_scheme_N', 20);
ocp_opts.set('qp_solver', 'full_condensing_hpipm');
ocp_opts.set('nlp_solver', 'sqp_rti');
ocp_opts.set('sim_method', 'erk');

%% call ocp solver
% set current state
ocp_model.set('constr_x0', x_current);

% set reference
y_reference = [x_reference; u_reference];
for k = 0: n_horizon - 1
    ocp.set('cost_y_ref', y_reference, k);
ocp.set('cost_y_ref_e', x_reference, n_horizon);

% solve

% get solution
u0 = ocp.get('u', 0);

And here is the Simulink:

Why do different optimization results occur? Did I do anything wrong?
I am a freshman in acados. If I do somethings wrong, thank you for your tolerance.

Thanks for your help!

1 Like

I may have found the reason for the problem.

When I don’t set y_ref in Simulink, I will get the correct solution.

So I think there is something wrong with my y_ref settings.

But I have another question: What is the correct setting method for y_ref?

Now, I have a x_ref in 13x1 and a u_ref in 4x1.

So the y_ref_0 is set to y_ref_0 = [x_ref; u_ref] in 17x1.

And the y_ref is set to y_ref = repelem(y_reference, N-1, 1) in (17*(N-1))x1.

What is the correct setting method for y_ref?

Thanks for your help!


I see, the S-Function expects y_ref to be the concatenation of y_ref values for all subsequent stages.
So, using this

repmat(y_ref_0, n_horizon-1, 1)

should make it work. Let me know if it does.
For reference:

Cheers :slight_smile:

Hi, Jonathan:

First of all, thank you for your replyThanks for your rely.

It really works. And I also realized that the repmat is different from the repelem.

I apologize for my carelessness.

Finally, thank you again for your help!

Best wishes to you! :wink:

Thank you for the reference link…That helped me.