Hi,
I am glad you like the S-function.
Did you actually edit the template?
https://github.com/acados/acados/blob/master/interfaces/acados_template/acados_template/c_templates_tera/acados_solver_sfun.in.c#L1
Or the generated Code?
I think it is a trade-off what is added as input/output to the S-function.
If all possible inputs & outputs were added, I think that the block would get hard to use and probably it would slow down Simulink.
However, please feel encouraged to extent the S-function for your needs.
For example, you can enlarge the port with x_1 to contain the full state trajectory.
For that you would have to change the size of the port here (to size N*nx).:
ssSetInputPortVectorDimension(S, {{ i_input }}, {{ dims.nh }});
{%- set i_input = i_input + 1 %}
// uh
ssSetInputPortVectorDimension(S, {{ i_input }}, {{ dims.nh }});
{%- endif %}
// specify dimension information for the output ports
ssSetOutputPortVectorDimension(S, 0, {{ dims.nu }} ); // optimal input
ssSetOutputPortVectorDimension(S, 1, 1 ); // solver status
ssSetOutputPortVectorDimension(S, 2, 1 ); // KKT residuals
ssSetOutputPortVectorDimension(S, 3, {{ dims.nx }} ); // first state
ssSetOutputPortVectorDimension(S, 4, 1); // computation times
ssSetOutputPortVectorDimension(S, 5, 1 ); // sqp iter
// specify the direct feedthrough status
// should be set to 1 for all inputs used in mdlOutputs
{%- for i in range(end=n_inputs) %}
ssSetInputPortDirectFeedThrough(S, {{ i }}, 1);
{%- endfor %}
// one sample time
and add a loop that extracts x for stage 1 up to N here:
// get sqp iter
ocp_nlp_get(nlp_config, nlp_solver, "sqp_iter", (void *) &tmp_int);
*out_sqp_iter = (real_t) tmp_int;
// *out_sqp_iter = (real_t) nlp_out->sqp_iter;
// get solution
ocp_nlp_out_get(nlp_config, nlp_dims, nlp_out, 0, "u", (void *) out_u0);
// get next state
ocp_nlp_out_get(nlp_config, nlp_dims, nlp_out, 1, "x", (void *) out_x1);
}
static void mdlTerminate(SimStruct *S)
{
acados_free();
}
#ifdef MATLAB_MEX_FILE
Best,
Jonathan
1 Like