Menu

MATLAB crash when using the code generation tool with a model described in a C++ file

2015-08-24
2015-11-03
  • Jonathan Nadeau

    Jonathan Nadeau - 2015-08-24

    Hi,

    I am using the last stable branch of the acado toolkit with the MATLAB interface and the following setup:

    MATLAB R2011b
    compiler: Windows SDK 7.1

    I want to compile a S-function usable with Simulink in order to control a system in real-time.

    For a simplified model,

    I successfully compiled and run a S-Function generated by the code generation tool. With a model of the system described with the function "f.add()".

    But, when I describe the system in a c++ file like the following example supplied with the toolkit:

    ACADOtoolkit\interfaces\matlab\examples\simulationenv\periodic_tracking_c

    MATLAB crash while using acado.OCPexport().

    I get a Segmentation violation error.

    Here is the code:

    BEGIN_ACADO
    EXPORT = 1;
    N = 10;
    ts = 0.001;

    acadoSet('problemname', 'DC_motor_ctrl_cpp');

    DifferentialState omega pos;
    Control al_m;

    n_XD = length(diffStates);
    n_U = length(controls);

    f = acado.DiscretizedDifferentialEquation(0.001);
    f.linkCFunction('DC_motor_mdl.cpp', 'myAcadoDifferentialEquation1');

    ocp = acado.OCP(0.0, N*ts, N);

    h = {pos};
    hN = {pos};

    W_mat = eye(length(h));
    WN_mat = eye(length(hN));
    W = acado.BMatrix(W_mat);
    WN = acado.BMatrix(WN_mat);

    ocp.minimizeLSQ(W, h);
    ocp.minimizeLSQEndTerm( WN, hN);

    ocp.subjectTo( f);
    ocp.subjectTo( 0 <= omega <= 200 );
    ocp.subjectTo( -1 <= al_m <= 1 );

    mpc = acado.OCPexport( ocp );
    mpc.set( 'HESSIAN_APPROXIMATION', 'GAUSS_NEWTON' );
    mpc.set( 'INTEGRATOR_TYPE', 'INT_EX_EULER' );
    mpc.set( 'NUM_INTEGRATOR_STEPS', N );
    mpc.set( 'QP_SOLVER', 'QP_QPOASES' );
    mpc.set( 'HOTSTART_QP', 'NO' );
    mpc.set( 'LEVENBERG_MARQUARDT', 1e-6 );
    mpc.set( 'GENERATE_SIMULINK_INTERFACE', 'YES' );

    if EXPORT
    mpc.exportCode( 'export_MPC' );
    copyfile('../../../external_packages/qpoases', 'export_MPC/qpoases')

    mpc.printDimensionsQP( );
    cd export_MPC
    make_acado_solver('../acado_MPCstep')
    cd ..
    

    end
    END_ACADO


    and the c++ file "DC_motor_mdl.cpp":

    void myAcadoDifferentialEquation1( double x, double f, void *user_data ){

    double t = x[0];
    double omega = x[1];
    double pos = x[2];
    double al_m = x[3];

    double tau_m = 0.02;
    double Km = 150;
    double dm = 0.005;

    f[0] = 1/tau_m(Kmal_m-omega);
    f[1] = omega;
    }


    I got the follwing error:

    [ACADO] Error: An assertion has been violated
    Code: (RET_ASSERTION)
    File: ....\ACADO\FUNCTION\c_operator.cpp
    Line: 255

    Segmentation violation detected

    Configuration:
    Crash Decoding : Disabled
    Default Encoding: windows-1252
    MATLAB Root : C:\Program Files\MATLAB\R2011b
    MATLAB Version : 7.13.0.564 (R2011b)
    Operating System: Microsoft Windows XP
    Processor ID : x86 Family 6 Model 15 Stepping 11, GenuineIntel
    Virtual Machine : Java 1.6.0_17-b04 with Sun Microsystems Inc. Java HotSpot(TM) Client VM mixed mode
    Window System : Version 5.1 (Build 2600: Service Pack 3)

    Fault Count: 2

    Abnormal termination:
    Segmentation violation

    And a Stack trace containing:

    Stack Trace (from fault):
    [ 0] 0x1e93be1f C:\Jonathan\ACADOtoolkit\interfaces\matlab\DC_motor_control_cpp\DC_motor_ctrl_cpp_RUN.mexw32+01228319 ???+000000

    ....

    [ 8] 0x01eb6cf4 C:\Program Files\MATLAB\R2011b\bin\win32\libmex.dll+00027892 ( mexRunMexFile+000132 )

    When I run the same code but with the following MPC formulation instead of a C++ file :

    f = acado.DiscretizedDifferentialEquation(0.001);
    f.add(next(omega) == 1/tau_m(Kmal_m-omega));
    f.add(next(pos) == omega);

    the s-function is successfully generated and I am able to run it in simulink ...

    If someone have an idea why this is happening, I really need a help for that.

    Best regards,

     
  • Rien Quirynen

    Rien Quirynen - 2015-08-24

    Hi there,

    The reason is simple: models in the form of C++ functions are not supported by ACADO code generation because they cannot be parsed to export them in the right format..

    So you should either define your model in the ACADO symbolics, or you can have a look at the code generation examples. A few of these examples show how to use the code generation tool together with an external model defined directly in C code. However, the latter interface is quite restrictive as you would have to provide the C function in the right format etc.

    examples/code_generation/simulation/extern_model.cpp
    interfaces/matlab/examples/code_generation/simulation/pendulum.m
    (the same interface works for OCPexport)

     
  • Thomas Stastny

    Thomas Stastny - 2015-10-09

    Sorry to piggy-back here, but am I correct to understand that there is currently no way to export code for black box models (i.e. using OCPexport)? I checked the examples you cited, and they all use acado.OptimizationAlgorithm, which has no ".exportCode" member. I also found the "simplerocket_c" example which uses the linkCFunction (actually exactly how Jonathan has it implemented in his code above), but here again the example uses OptimizationAlgorithm, not OCPexport.

    Sorry if I am misunderstanding anything, let me know please! If there is a way to link a black box model and actually export the code for use somewhere else, this would help a lot...basically a hack to allow discrete models (not time discretized, but things like atan2 functions and switching guidance logic within the horizon) in OCP problems until the functionality becomes supported.

    Your insight would be greatly appreciated! Thanks!

     
  • Rien Quirynen

    Rien Quirynen - 2015-10-09

    Hey Thomas,

    The examples I mentioned in my previous post are in the code generation folder.
    For the C++ examples, you can for example have a look at:
    'ACADO_DIR/examples/code_generation/simulation/extern_model.cpp'
    For the MATLAB examples, you can have a look at:
    'ACADO_DIR/interfaces/matlab/examples/code_generation/simulation/pendulum.m'

    I hope this helps. Best,
    Rien

     
  • Rien Quirynen

    Rien Quirynen - 2015-10-09

    Hey Thomas,

    The examples I mentioned in my previous post are in the code generation folder.
    For the C++ examples, you can for example have a look at:
    'ACADO_DIR/examples/code_generation/simulation/extern_model.cpp'
    For the MATLAB examples, you can have a look at:
    'ACADO_DIR/interfaces/matlab/examples/code_generation/simulation/pendulum.m'

    I hope this helps. Best,
    Rien

     
  • Thomas Stastny

    Thomas Stastny - 2015-10-10

    Hi Rien,

    Thanks for the quick reply! I did see the code generation examples you mentioned previously. And they do not have optimal control problems. They are exporting simulations. Which is actually somewhat different in process than OCPs.

    I am having trouble with exactly what Jonathan mentioned above. The use of OCPexport with a black box model. This is what seems not to work. However, you mentioned in your post above that if the c-file is set up properly, this functionality should even be possible for OCPexport.

    For example, this is the process I'm refering to.

    ocp = acado.OCP()

    This OCP needs a model, which I would like to be a black box model, so I tried two methods:

    1)
    Similar to the pendulum example:

    ocp.setModel('cfilename','cfunctionname')

    This results in "ERROR: Invalid setModel". The same error also occurs if you include cfilename.c in the string.

    2)
    The method Jonathan tried, and what is described in the user-manual.

    f = acadoDifferentialEquation;
    f.linkCFunction('cfilename.c','cfunctionname');
    ocp.subjectTo( f );

    Using this approach (as instructed in the manual and simplerocket example), the problem occurs after making an OCPexport, i.e.

    nmpc = acado.OCPexport( ocp );

    and then trying to export the code:

    nmpc.exportCode( 'exportfolder' );

    At this point, the same error Jonathan received occurs (An assertion has been violated).

    In both examples, I've set up the c file model exactly as prescribed within either the manual or in the pendulum example. But I believe (from what I've seen) that OCPexport does not have the same functionality as simExport in the examples you cited.

    So my original question was whether I am missing something, if the manual is not correct, or if there simply is no way to export an OCP with a black box model.

    Again, any help would be wonderful! And I apologize if I am still missing something obvious!

    Best,

    Thomas

     
  • Rien Quirynen

    Rien Quirynen - 2015-10-10

    Hey Thomas,

    The problem is that ACADO always needs derivatives, which it cannot compute if you only provide a black box C function. So instead of doing numerical differentiation, we require the user to provide these derivatives whenever you employ a black box C model. This is also what you can see in the two examples I referred to: there are always 2 C function names provided of which one evaluates the right hand side of the model and the other one the Jacobian.

    By the way, the API for SIMexport and OCPexport regarding external C functions is exactly the same. You can find it in this "abstract" class:
    http://acado.sourceforge.net/doc/html/d5/d5d/classModelContainer.html

    Best,
    Rien

     
  • Thomas Stastny

    Thomas Stastny - 2015-10-11

    Hi Rien,

    Thanks for clarifying! I assumed before that ACADO would automatically fall back to numeric differentiation if I did not supply a jacobian. I was able to compile now; however, I had to manually insert the rhs and rhs_jac functions into the auto-generated acado_integrator.c file before calling make_acado_solver.

    The make_acado_solver.m file auto-generated from an ocp.exportCode call does not contain the second "extern" input argument like the simexport does. I attempted, again, manually adding this functionality, but the acado_integrator.c will not notice the functions (rhs and rhs_jac) included within model.c even when I added it to the CGSources. I imagine there is some simple issue somewhere with declarations and/or definitions not going to the right places, but I stopped looking into it after I found I could simply paste the rhs and rhs_jac directly into the integrator c file. After this, compilation finishes.

    Should I make an issue for including the same autogenerated functionality with an external model for ocp.exportcode? I imagine it would not be a very difficult fix to the code. But I will let you be the judge! ;)

    Thanks again for the help.

    Best,

    Thomas

     
  • Rien Quirynen

    Rien Quirynen - 2015-10-11

    Hey Thomas,

    I'm glad I could help. Regarding the compilation error, I can currently not see a reason why you would have this problem only with OCPexport and not with SIMexport at the moment. But if you would indeed make an issue with your exact compilation error including the compiler, example code etc, then I will try to have a look at it as soon as I have a bit more time.

    Cheers,
    Rien

     
  • Thomas Stastny

    Thomas Stastny - 2015-11-03

    Hi Rien,

    Sorry for the delay on this, I was away for two weeks on a project. I've created a git issue on the master. Thanks again for your support.

    Cheers,

    Thomas

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.