Error on the s-function block

Hi, i have a problem when using the s-function generated in simulink.
Similar to the NLP problem example, i made a Constrained Sindy version using Acados, now i want to set up the simulink part.
When i create the s-function block and add the correct file it returns me that output 6 is wrong, the problem is that i have only 5 outputs.

This is the code in matlab:

clear all

clc

is_parametric = 1;

import casadi.*; % Import CasADi library

load(‘Theta.txt’)

load(‘dXdt.txt’)

Theta=Theta(1:100,:);

dXdt=dXdt(1:100);

% Step 2: Define problem variables

eps=casadi.SX.sym(‘eps’,7);

if is_parametric

dXdt = SX.sym(‘dXdt’,size(dXdt));

end

if is_parametric

Theta = SX.sym(‘Theta’,size(Theta));

end

% Cost function with regularization

lambda = 1e-3; % Regularization term

f = abs((Theta * eps - dXdt)’ * (Theta * eps - dXdt));

% Constraint bounds

g = [eps(1);eps(2);eps(3);eps(4);eps(5);eps(6);eps(7)];

glb = [0.001;50;-5000;70000;-700000;-0.05;-0.001];

gub = [0.002;100;-3000;100000;-500000;-0.01;0];

% Step 3: Model setup

model = AcadosModel();

model.name = ‘prova_sindy’;

model.x = eps;

model.f_expl_expr = casadi.SX.zeros(length(model.x),1);

if is_parametric

model.p = vertcat(Theta(:),dXdt(:));

end

% Cost and constraints

ocp = AcadosOcp();

ocp.name = ‘nlp_solver’;

ocp.model = model;

ocp.cost.cost_type_e = ‘EXTERNAL’;

ocp.model.cost_expr_ext_cost_e = f;

ocp.model.con_h_expr_e = g;

ocp.constraints.lh_e = glb;

ocp.constraints.uh_e = gub;

ocp.cost.cost_type_0 = ‘EXTERNAL’;

ocp.model.cost_expr_ext_cost_0 = 0;

ocp.cost.cost_type = ‘EXTERNAL’;

ocp.model.cost_expr_ext_cost = 0;

% Solver options

ocp.solver_options.tf = 1;

ocp.solver_options.N_horizon = 1;

ocp.solver_options.nlp_solver_type = ‘SQP_RTI’;

ocp.solver_options.nlp_solver_max_iter = 1000;

ocp.solver_options.nlp_solver_tol_stat = 1e-6;

ocp.solver_options.nlp_solver_tol_eq = 1e-6;

ocp.solver_options.nlp_solver_tol_comp = 1e-6;

simulink_opts = get_acados_simulink_opts;

ocp.simulink_opts = simulink_opts;

% Solver creation

ocp_solver = AcadosOcpSolver(ocp);

%% Compile Sfunctions

cd c_generated_code

make_sfun

This the output from the Command Window:

Successfully created sfunction:
acados_solver_sfunction_prova_sindy.mexw64

Note: Usage of Sfunction is as follows:
Inputs are:

  1. parameters - concatenated for all stages 0 to N, size [1600]
  2. lh_e, size [7]
  3. uh_e, size [7]

Outputs are:

  1. acados solver status (0 = SUCCESS)
  2. KKT residual
  3. x1, state at node 1
  4. CPU time
  5. SQP iterations

And this the error:

I also have another question, why is x_init in the input not present?

Hi,

if you check what happens when you call get_acados_simulink_opts you can see the default Simulink options. In there, x_init is not enabled by default so you need to set it before you do ocp.simulink_opts = simulink_opts;.

Additionally, since solving a generic NLP is kind of a degenerate case of an OCP formulation (which acados is designed for), the error you get might be related to the lack of control inputs (i.e., nu=0). The dimension check here is the reason why you see only 5 outputs instead of 6.

By turning off the output u0, i.e., setting simulink_opts.outputs.u0 = 0 you should be able to include the S-function properly.

Hope this helps,
Josip

Yes, now it works.
Thanks

I have other questions:

  • Is it possible to define the sample time of the generated s-function?
    I manage to run however the s-function by modifing the output ports for the previous error and by modifing the code for the sampling time directly on its c code generated.
    I modify : #define SAMPLINGTIME 1
    with: #define SAMPLINGTIME -1
    because i need to run the s-function on a enabled subsystem
  • Till now i can set around 6000 parameters, if i try to give bigger matricies it fails the script with this error message:
    Error using acados_template_mex.compile_ocp_shared_lib
    Building templated code as shared library failed.
    Got status 2, result: [ 6%] Building C object
    CMakeFiles/model_Constr_SINDy_7.dir/Constr_SINDy_7_model/Constr_SINDy_7_expl_ode_fun.c.obj
    [ 12%] Building C object CMakeFiles/model_Constr_SINDy_7.dir/Constr_SINDy_7_model/Constr_SINDy_7_expl_vde_forw.c.obj
    [ 18%] Building C object CMakeFiles/model_Constr_SINDy_7.dir/Constr_SINDy_7_model/Constr_SINDy_7_expl_vde_adj.c.obj
    [ 18%] Built target model_Constr_SINDy_7
    [ 25%] Building C object CMakeFiles/ocp_Constr_SINDy_7.dir/Constr_SINDy_7_cost/Constr_SINDy_7_cost_ext_cost_0_fun.c.obj
    [ 31%] Building C object CMakeFiles/ocp_Constr_SINDy_7.dir/Constr_SINDy_7_cost/Constr_SINDy_7_cost_ext_cost_0_fun_jac.c.obj
    [ 37%] Building C object CMakeFiles/ocp_Constr_SINDy_7.dir/Constr_SINDy_7_cost/Constr_SINDy_7_cost_ext_cost_0_fun_jac_hess.c.obj
    [ 43%] Building C object CMakeFiles/ocp_Constr_SINDy_7.dir/Constr_SINDy_7_cost/Constr_SINDy_7_cost_ext_cost_fun.c.obj
    [ 50%] Building C object CMakeFiles/ocp_Constr_SINDy_7.dir/Constr_SINDy_7_cost/Constr_SINDy_7_cost_ext_cost_fun_jac.c.obj
    [ 56%] Building C object CMakeFiles/ocp_Constr_SINDy_7.dir/Constr_SINDy_7_cost/Constr_SINDy_7_cost_ext_cost_fun_jac_hess.c.obj
    [ 62%] Building C object CMakeFiles/ocp_Constr_SINDy_7.dir/Constr_SINDy_7_cost/Constr_SINDy_7_cost_ext_cost_e_fun.c.obj
    mingw32-make.exe[2]: *** [CMakeFiles\ocp_Constr_SINDy_7.dir\build.make:166:
    CMakeFiles/ocp_Constr_SINDy_7.dir/Constr_SINDy_7_cost/Constr_SINDy_7_cost_ext_cost_e_fun.c.obj] Error 1
    mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:112: CMakeFiles/ocp_Constr_SINDy_7.dir/all] Error 2
    mingw32-make.exe: *** [Makefile:135: all] Error 2

Error in AcadosOcpSolver (line 64)
acados_template_mex.compile_ocp_shared_lib(ocp.code_export_directory)

Error in CSINDy_7 (line 107)
ocp_solver = AcadosOcpSolver(ocp);

Yes, you can set the sampling time with the samplingtime option.

Unfortunately, I’m not sure why it fails with larger matrices. Have you considered using CasADi for this part (sysid)? It might be able to handle it more efficiently, especially when you lower the execution rate.
The opti stack should allow for an easy transition from your current formulation.

Thanks for the reply, using CasADI is also possible to generate a s-function of the problem to be runned in simulink?

Yes, there are a few posts on their blog. I would suggest to first try the approach described here, it could be fast enough for your application.

Thanks again.

Thanks @josipkh for suggesting the workaround with turning u0 off explictly.
After merging this PR 1422 it should not be needed anymore.

@casto regarding your other question:

Till now i can set around 6000 parameters, if i try to give bigger matricies it fails the script with this

The error of make is not clear at all. Is there any additional output. Parameter sizes much bigger than 6000 should be possible.
If this issue persists, please describe it clearly, ideally with an example to reproduce in a new thread.

1 Like

Hi @FreyJo i have created another thread for the problem.