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.hThe 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.cConstants defined for both the QP and MPC algorithms based on the problem supplied.
-
jMPC_math.cThe required linear algebra and mathematic routines are copied and defined in this file.
-
jMPC_qp.cThe quadratic programming solver source file which is copied from a template (based on
quad_wrightorquad_mehrotra). Global variable definitions are added based on the problem size and user settings. -
mexTestQP.cAn autogenerated testbench file to ensure the QP solver was generated correctly (optional, default on). More information on this functionality here.
-
jMPC_engine.cThe 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.cIf 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:
yp | Input | The current plant output(s). |
setp | Input | The current setpoint(s). |
v | Input | The current measured disturbance(s), if any. |
Ou | Output | The computed control move(s) (plant input, controller output). |
Odel_u | Output | The computed input increment(s), for diagnostics. |
Oym | Output | The internal model output(s), for diagnostics. |
Oxm | Output | The internal model state(s), for diagnostics. |
QPiter | Output | The 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.