Error while compiling simulink model for dSpace Scalexio

It was a problem regarding the compiler / simulink. I isolated the S-Function, now I get loads of “undefined reference to nlp_in” errors.

#define S_FUNCTION_NAME   acados_solver_sfunction_ocp_model
#define S_FUNCTION_LEVEL  2

#define MDL_START

// acados
#include "print.h"
#include "math.h"
#include "sim_interface.h"
#include "external_function_interface.h"

// example specific
#include "ocp_model_model.h"
#include "acados_solver_ocp_model.h"

#include "simstruc.h"

//#define SAMPLINGTIME -1
#define SAMPLINGTIME 0.25

static void mdlInitializeSizes (SimStruct *S)
{
    // specify the number of continuous and discrete states
    ssSetNumContStates(S, 0);
    ssSetNumDiscStates(S, 0);

                  

    // specify the number of input ports
    if ( !ssSetNumInputPorts(S, 10) )
        return;

    // specify the number of output ports
    if ( !ssSetNumOutputPorts(S, 6) )
        return;

    // specify dimension information for the input ports
    // x0
    ssSetInputPortVectorDimension(S, 0, 3);
    // y_ref
    ssSetInputPortVectorDimension(S, 1, 30 * 6);
    // y_ref_e
    ssSetInputPortVectorDimension(S, 2, 3);
    // parameters
    ssSetInputPortVectorDimension(S, 3, (30+1) * 1);
    // lbx
    ssSetInputPortVectorDimension(S, 4, 3);
    // ubx
    ssSetInputPortVectorDimension(S, 5, 3);
    // lbu
    ssSetInputPortVectorDimension(S, 6, 3);
    // ubu
    ssSetInputPortVectorDimension(S, 7, 3);
    // lh
    ssSetInputPortVectorDimension(S, 8, 2);
    // uh
    ssSetInputPortVectorDimension(S, 9, 2);

    // specify dimension information for the output ports
    ssSetOutputPortVectorDimension(S, 0, 3 ); // optimal input
    ssSetOutputPortVectorDimension(S, 1, 1 ); // solver status
    ssSetOutputPortVectorDimension(S, 2, 1 ); // KKT residuals
    ssSetOutputPortVectorDimension(S, 3, 3 ); // 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
    ssSetInputPortDirectFeedThrough(S, 0, 1);
    ssSetInputPortDirectFeedThrough(S, 1, 1);
    ssSetInputPortDirectFeedThrough(S, 2, 1);
    ssSetInputPortDirectFeedThrough(S, 3, 1);
    ssSetInputPortDirectFeedThrough(S, 4, 1);
    ssSetInputPortDirectFeedThrough(S, 5, 1);
    ssSetInputPortDirectFeedThrough(S, 6, 1);
    ssSetInputPortDirectFeedThrough(S, 7, 1);
    ssSetInputPortDirectFeedThrough(S, 8, 1);
    ssSetInputPortDirectFeedThrough(S, 9, 1);

    // one sample time
    ssSetNumSampleTimes(S, 1);
}


#if defined(MATLAB_MEX_FILE)

#define MDL_SET_INPUT_PORT_DIMENSION_INFO
#define MDL_SET_OUTPUT_PORT_DIMENSION_INFO

static void mdlSetInputPortDimensionInfo(SimStruct *S, int_T port, const DimsInfo_T *dimsInfo)
{
    if ( !ssSetInputPortDimensionInfo(S, port, dimsInfo) )
         return;
}

static void mdlSetOutputPortDimensionInfo(SimStruct *S, int_T port, const DimsInfo_T *dimsInfo)
{
    if ( !ssSetOutputPortDimensionInfo(S, port, dimsInfo) )
         return;
}

#endif /* MATLAB_MEX_FILE */


static void mdlInitializeSampleTimes(SimStruct *S)
{
    ssSetSampleTime(S, 0, SAMPLINGTIME);
    ssSetOffsetTime(S, 0, 0.0);
}


static void mdlStart(SimStruct *S)
{
    acados_create();
}

static void mdlOutputs(SimStruct *S, int_T tid)
{
    InputRealPtrsType in_sign;
    

    // local buffer
    real_t buffer[6];


    /* go through inputs */
    // initial condition
    in_sign = ssGetInputPortRealSignalPtrs(S, 0);
    for (int i = 0; i < 3; i++)
        buffer[i] = (double)(*in_sign[i]);
    ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, 0, "lbx", buffer);
    ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, 0, "ubx", buffer);


    // y_ref - stage-variant !!!
    in_sign = ssGetInputPortRealSignalPtrs(S, 1);

    for (int ii = 0; ii < 30; ii++)
    {
        for (int jj = 0; jj < 6; jj++)
            buffer[jj] = (double)(*in_sign[ii*6+jj]);
        ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, ii, "yref", (void *) buffer);
    }



    // y_ref_e
    in_sign = ssGetInputPortRealSignalPtrs(S, 2);

    for (int i = 0; i < 3; i++)
        buffer[i] = (double)(*in_sign[i]);

    ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, 30, "yref", (void *) buffer);


    // parameters - stage-variant !!!
    in_sign = ssGetInputPortRealSignalPtrs(S, 3);

    // update value of parameters
    for (int ii = 0; ii <= 30; ii++) 
    {
        for (int jj = 0; jj < 1; jj++)
            buffer[jj] = (double)(*in_sign[ii*1+jj]);
        acados_update_params(ii, buffer, 1);
    }



    // lbx
    in_sign = ssGetInputPortRealSignalPtrs(S, 4);

    for (int i = 0; i < 3; i++)
        buffer[i] = (double)(*in_sign[i]);

    for (int ii = 1; ii < 30; ii++)
        ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, ii, "lbx", buffer);

    // ubx
    in_sign = ssGetInputPortRealSignalPtrs(S, 5);

    for (int i = 0; i < 3; i++)
        buffer[i] = (double)(*in_sign[i]);

    for (int ii = 1; ii < 30; ii++)
        ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, ii, "ubx", buffer);


    // lbu
    in_sign = ssGetInputPortRealSignalPtrs(S, 6);

    for (int i = 0; i < 3; i++)
        buffer[i] = (double)(*in_sign[i]);

    for (int ii = 0; ii < 30; ii++)
        ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, ii, "lbu", buffer);

    // ubu
    in_sign = ssGetInputPortRealSignalPtrs(S, 7);

    for (int i = 0; i < 3; i++)
        buffer[i] = (double)(*in_sign[i]);

    for (int ii = 0; ii < 30; ii++)
        ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, ii, "ubu", buffer);




    // lh
    in_sign = ssGetInputPortRealSignalPtrs(S, 8);

    for (int i = 0; i < 2; i++)
        buffer[i] = (double)(*in_sign[i]);

    for (int ii = 0; ii < 30; ii++)
        ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, ii, "lh", buffer);

    // uh
    in_sign = ssGetInputPortRealSignalPtrs(S, 9);

    for (int i = 0; i < 2; i++)
        buffer[i] = (double)(*in_sign[i]);

    for (int ii = 0; ii < 30; ii++)
        ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, ii, "uh", buffer);

    /* call solver */
    int rti_phase = 0;
    ocp_nlp_solver_opts_set(nlp_config, nlp_opts, "rti_phase", &rti_phase);
    int acados_status = acados_solve();


    /* set outputs */
    // assign pointers to output signals
    real_t *out_u0, *out_status, *out_sqp_iter, *out_KKT_res, *out_x1, *out_cpu_time;
    int tmp_int;

    out_u0          = ssGetOutputPortRealSignal(S, 0);
    out_status      = ssGetOutputPortRealSignal(S, 1);
    out_KKT_res     = ssGetOutputPortRealSignal(S, 2);
    out_x1          = ssGetOutputPortRealSignal(S, 3);
    out_cpu_time    = ssGetOutputPortRealSignal(S, 4);
    out_sqp_iter    = ssGetOutputPortRealSignal(S, 5);

    // extract solver info
    *out_status = (real_t) acados_status;
    *out_KKT_res = (real_t) nlp_out->inf_norm_res;
//    *out_cpu_time = (real_t) nlp_out->total_time;
    
    // get solution time
    ocp_nlp_get(nlp_config, nlp_solver, "time_tot", (void *) out_cpu_time);

    // 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
#include "simulink.c"
#else
#include "cg_sfun.h"
#endif

Looks like a header is missing after acados code generation. Will keep you updated