Skip to main content

Code Generation

To generate an embedded jMPC Controller, simply call embed on the jMPC controller object, and jSIM simulation object, as below:

embed(MPC1,simopts)

If you follow with the first example in Examples/Embedded_Examples.m supplied with the toolbox, this will result in:

------------------------------------------------
jMPC Auto Code Generator for Embedded MPC [v1.5]
Architecture: generic, Precision: double [%1.18g]
------------------------------------------------
1) Creating Embedded Header File "jMPC_embed.h" ... Done
2) Creating Embedded Constants File "jMPC_constants.c" ... Done
3) Creating jMATH Source File "jMPC_math.c" ... Done
4) Creating QP Source File "jMPC_qp.c" [Mehrotra] ... Done
4a) Creating MEX QP Testbench Source File "mexTestQP.c" ... Done
5) Creating MPC Source File "jMPC_engine.c" ... Done
6) Creating PIL MPC Source File "jMPC_pil.c" ... Done
------------------------------------------------

Each file generated is described below:

  • jMPC_embed.h

    The main header file for both the QP solver and MPC solver. It is created from a template and data types defined as per the configuration requested. Compiler defines are added to enable options specified in the controller such as unmeasured outputs, uncontrolled outputs, etc.

  • jMPC_constants.c

    Constants defined for both the QP and MPC algorithms based on the problem supplied.

  • jMPC_math.c

    The required linear algebra and mathematic routines are copied and defined in this file.

  • jMPC_qp.c

    The quadratic programming solver source file which is copied from a template (based on quad_wright or quad_mehrotra). Global variable definitions are added based on the problem size and user settings.

  • mexTestQP.c

    An autogenerated testbench file to ensure the QP solver was generated correctly (optional, default on). More information on this functionality here.

  • jMPC_engine.c

    The main MPC algorithm source file which is copied from a template. Global variable definitions are added based on the problem size, user settings, and initialization requirements.

  • jMPC_pil.c

    If the simulation options are supplied then a PIL implementation can be run, and the required communication routines are copied from the PIL template file. More information on this functionality here.

MPC Controller Interface

Within jMPC_embed.h is the declaration for the main MPC solver function:

intT EmbedMPCSolve(realT *yp, realT *setp, realT *v, realT *Ou, realT *Odel_u, realT *Oym, realT *Oxm, uintT *QPiter);

This single function call is all that is required to embed the jMPC controller designed in MATLAB! No initialization is required, as everything is statically defined by the autocoder. The arguments are as follows:

ypInputThe current plant output(s).
setpInputThe current setpoint(s).
vInputThe current measured disturbance(s), if any.
OuOutputThe computed control move(s) (plant input, controller output).
Odel_uOutputThe computed input increment(s), for diagnostics.
OymOutputThe internal model output(s), for diagnostics.
OxmOutputThe internal model state(s), for diagnostics.
QPiterOutputThe number of QP iterations taken, for diagnostics.
(Return Code)Output>=0 if solved correctly, negative if not.

Specifying Precision

Note the use of datatypes intT and realT in the function declaration. These are type defined in jMPC_embed.h as below:

typedef double realT;
typedef int intT;

In the above example the autocoder has generated a double precision (64bit floating point) embedded jMPC controller. For most modest embedded platforms, they will only support software double precision, which will substantially impact performance. To utilize the hardware Floating Point Unit (FPU), which is typically single precision (32bit), simply specify using jMPCeset and regenerate, as below:

embeddedopts = jMPCeset('precision','single');
embed(MPC1,simopts,embeddedopts)

which will generate a single precision floating point implementation of both the QP solver and the MPC algorithm, as well as define all real constants and variables as float.

Architecture Specific Code

Currently the toolbox has been configured for the following embedded architectures:

  • 'generic'

    No customizations, the same as a desktop PC.

  • 'c2000'

    Configures datatypes and initialization to suit the TI C2000 embedded devices.

  • 'arm'

    For a 64-bit ARM target running Linux (Beta)

Further customizations are easy to make within embedJMPC.m, which generally just requires definitions of the standard datatypes and their corresponding byte sizes.