Compute optimal control moves with code generation support

`[`

computes optimal MPC control moves and supports code generation for deployment to
real-time targets. The input data structures, generated using `mv`

,`newStateData`

]
= mpcmoveCodeGeneration(`configData`

,`stateData`

,`onlineData`

)`getCodeGenerationData`

, define the MPC controller to simulate.

`mpcmoveCodeGeneration`

does not check input arguments for
correct dimensions and data types.

`[___,`

returns additional information about the optimization result, including the number
of iterations and the objective function cost.`info`

] = mpcmoveCodeGeneration(___)

Create a proper plant model.

plant = rss(3,1,1); plant.D = 0;

Specify the controller sample time.

Ts = 0.1;

Create an MPC controller.

mpcObj = mpc(plant,Ts);

-->The "PredictionHorizon" property of "mpc" object is empty. Trying PredictionHorizon = 10. -->The "ControlHorizon" property of the "mpc" object is empty. Assuming 2. -->The "Weights.ManipulatedVariables" property of "mpc" object is empty. Assuming default 0.00000. -->The "Weights.ManipulatedVariablesRate" property of "mpc" object is empty. Assuming default 0.10000. -->The "Weights.OutputVariables" property of "mpc" object is empty. Assuming default 1.00000.

Create code generation data structures.

[configData,stateData,onlineData] = getCodeGenerationData(mpcObj);

-->Converting model to discrete time. -->Assuming output disturbance added to measured output channel #1 is integrated white noise. -->The "Model.Noise" property of the "mpc" object is empty. Assuming white noise on each measured output channel. -->Converting model to discrete time. -->Assuming output disturbance added to measured output channel #1 is integrated white noise. -->The "Model.Noise" property of the "mpc" object is empty. Assuming white noise on each measured output channel.

Initialize the plant states to zero to match the default states used by the MPC controller.

Run a closed-loop simulation. At each control interval, update the online data structure and call `mpcmoveCodeGeneration`

to compute the optimal control moves.

x = zeros(size(plant.B,1),1); % Initialize plant states to zero (|mpcObj| default). Tsim = 20; for i = 1:round(Tsim/Ts)+1 % Update plant output. y = plant.C*x; % Update measured output in online data. onlineData.signals.ym = y; % Update reference signal in online data. onlineData.signals.ref = 1; % Compute control actions. [u,statedata] = mpcmoveCodeGeneration(configData,stateData,onlineData); % Update plant state. x = plant.A*x + plant.B*u; end

Generate MEX function with MATLAB® Coder™, specifying `configData`

as a constant.

func = 'mpcmoveCodeGeneration'; funcOutput = 'mpcmoveMEX'; Cfg = coder.config('mex'); Cfg.DynamicMemoryAllocation = 'off'; codegen('-config',Cfg,func,'-o',funcOutput,'-args',... {coder.Constant(configData),stateData,onlineData});

`configData`

— MPC configuration parametersstructure

MPC configuration parameters that are constant at run time, specified as a
structure generated using `getCodeGenerationData`

.

**Note**

When using `codegen`

(MATLAB Coder),
`configData`

must be defined as `coder.Constant`

(MATLAB Coder).

`stateData`

— Controller statestructure

Controller state at run time, specified as a structure. Generate the
initial state structure using `getCodeGenerationData`

. For
subsequent control intervals, use the updated controller state from the
previous interval. In general, use the `newStateData`

structure directly.

If custom state estimation is enabled, you must manually update the
`stateData`

structure during each control interval.
For more information, see Custom State Estimation.

`stateData`

has the following fields:

`Plant`

— Plant model state estimates`MPCobj`

nominal plant
states (default) | column vector of length
Plant model state estimates, specified as a column vector of
length *N _{xp}*, where

**Note**

If custom state estimation is enabled, update
`Plant`

at each control interval.
Otherwise, do not change this field. Instead use the values
returned by either
`getCodeGenerationData`

or
`mpcmoveCodeGeneration`

.

`Disturbance`

— Unmeasured disturbance model state estimates`[]`

(default) | column vectorUnmeasured disturbance model state estimates, specified as a
column vector of length
*N _{xd}*, where

`Disturbance`

contains the input
disturbance model states followed by the output disturbance
model states.To view the input and output disturbance models, use `getindist`

and
`getoutdist`

respectively.

**Note**

If custom state estimation is enabled, update
`Disturbance`

at each control interval.
Otherwise, do not change this field. Instead use the values
returned by either
`getCodeGenerationData`

or
`mpcmoveCodeGeneration`

.

`Noise`

— Output measurement noise model state estimates`[]`

(default) | column vectorOutput measurement noise model state estimates, specified as a
column vector of length
*N _{xn}*, where

**Note**

If custom state estimation is enabled, update
`Noise`

at each control interval.
Otherwise, do not change this field. Instead use the values
returned by either
`getCodeGenerationData`

or
`mpcmoveCodeGeneration`

.

`LastMove`

— Manipulated variable control moves from previous control interval`MPCobj`

nominal MV
values (default) | column vectorManipulated variable control moves from previous control
interval, specified as a column vector of length
*N _{mv}*, where

**Note**

Do not change the value of `LastMove`

.
Always use the values returned by either
`getCodeGenerationData`

or
`mpcmoveCodeGeneration`

.

`Covariance`

— Covariance matrix for controller state estimatessymmetrical array

Covariance matrix for controller state estimates, specified as
a symmetrical *N*-by-*N*
array, where *N* is number of extended
controller states; that is, the sum of
*N _{xp}*,

If the controller uses custom state estimation,
`Covariance`

is empty.

**Note**

Do not change the value of `Covariance`

.
Always use the values returned by either
`getCodeGenerationData`

or
`mpcmoveCodeGeneration`

.

`iA`

— Active inequality constraintsfalse (default) | logical vector

Active inequality constraints, where the equal portion of the
inequality is `true`

, specified as a logical
vector of length *M*. If
`iA`

(*i*) is
`true`

, then the *i*th
inequality is active for the latest QP solver solution.

**Note**

Do not change the value of `iA`

. Always
use the values returned by either
`getCodeGenerationData`

or
`mpcmoveCodeGeneration`

.

`onlineData`

— Online controller datastructure

Online controller data that you must update at run time, specified as a
structure with the following fields. Generate the initial structure using
`getCodeGenerationData`

.

`signals`

— Updated input and output signalsstructure

Updated input and output signals, specified as a structure with the following fields:

`ym`

— Measured outputsvector

Measured outputs, specified as a vector of length
*N _{ym}*,
where

By default,
`getCodeGenerationData`

sets
`ym`

to the nominal measured
output values from the controller.

`ref`

— Output referencesrow vector | array

Output references, specified as one of the following:

Row vector of length

*N*, where_{y}*N*is the number of outputs._{y}If you are using reference signal previewing with implicit or adaptive MPC, specify a

*p*-by-*N*array, where_{y}*p*is the prediction horizon.

By
default,`getCodeGenerationData`

sets `ref`

to the nominal output
values from the controller.

`md`

— Measured disturbancesrow vector | array

Measured disturbances, specified as:

A row vector of length

*N*, where_{md}*N*is the number of measured disturbances._{md}If you are using signal previewing with implicit or adaptive MPC, specify a

*p*-by-*N*array._{md}

By default, if your controller has measured
disturbances,`getCodeGenerationData`

sets `md`

to the nominal measured
disturbance values from the controller. Otherwise,
this field is empty and ignored by
`mpcmoveCodeGeneration`

.

`mvTarget`

— Targets for manipulated variables`[]`

(default) | vectorTargets for manipulated variables, which replace
the targets defined in
`configData.uTarget`

, specified
as one of the following:

Vector of length

*N*, where_{mv}*N*is the number of manipulated variables_{mv}`[]`

to use the default targets defined in`configData.uTarget`

This field is ignored when using an explicit MPC controller.

`externalMV`

— Manipulated variables externally applied to the plant`[]`

(default) | vectorManipulated variables externally applied to the plant, specified as:

A vector of length

*N*._{mv}`[]`

to apply the optimal control moves to the plant.

`weights`

— Updated QP optimization weightsstructure

Updated QP optimization weights, specified as a structure. If
you do not expect tuning weights to change at run time, ignore
`weights`

. This field is ignored when using
an explicit MPC controller.

This structure contains the following fields:

`y`

— Output variable tuning weights`[]`

(default) | row vector | arrayOutput variable tuning weights that replace the original controller output weights at run time at run time, specified as a row vector or array of nonnegative values.

To use the same weights across the prediction horizon, specify a row vector of length
*N _{y}*, where

To vary the tuning weights over the prediction horizon from time *k*+1 to time *k*+*p*, specify an array with *N _{y}* columns and up to

If `y`

is empty,
`[]`

, the default weights defined
in the original MPC controller are used.

`u`

— Manipulated variable tuning weights`[]`

(default) | row vector | arrayManipulated variable tuning weights that replace the original controller manipulated variable weights at run time, specified as a row vector or array of nonnegative values.

To use the same weights across the prediction horizon, specify a row vector of length
*N _{mv}*, where

To vary the tuning weights over the prediction horizon from time *k* to time *k*+*p*-1, specify an array with *N _{mv}* columns and up to

If `u`

is empty,
`[]`

, the default weights defined
in the original MPC controller are used.

`du`

— Manipulated variable rate tuning weights`[]`

(default) | row vector | arrayManipulated variable rate tuning weights that replace the original controller manipulated variable rate weights at run time, specified as a row vector or array of nonnegative values.

To use the same weights across the prediction horizon, specify a row vector of length
*N _{mv}*, where

To vary the tuning weights over the prediction horizon from time *k* to time
*k*+*p*-1, specify
an array with *N _{mv}* columns
and up to

If `du`

is empty,
`[]`

, the default weights defined
in the original MPC controller are used.

`ecr`

— Weight on slack variable used for constraint softening`[]`

(default) | nonnegative scalarWeight on slack variable used for constraint softening, specified as a nonnegative scalar.

If `ecr`

is empty,
`[]`

, the default weight defined
in the original MPC controller are used.

`limits`

— Updated input and output constraintsstructure

Updated input and output constraints, specified as a
structure. If you do not expect constraints to change at run
time, ignore `limits`

. This field is ignored
when using an explicit MPC controller.

This structure contains the following fields:

`ymin`

— Output variable lower bounds`[]`

(default) | column vectorOutput variable lower bounds, specified as a
column vector of length
*N _{y}*.

`ymin(i)`

replaces the
`OutputVariables(i).Min`

constraint from the original controller. If the
`OutputVariables(i).Min`

property
of the controller is specified as a vector,
`ymin(i)`

replaces the first
finite entry in this vector, and the remaining
values shift to retain the same constraint
profile.If `ymin`

is empty,
`[]`

, the default bounds defined
in the original MPC controller are used.

`ymax`

— Output variable upper bounds`[]`

(default) | column vectorOutput variable upper bounds, specified as a
column vector of length
*N _{y}*.

`ymax(i)`

replaces the
`OutputVariables(i).Max`

constraint from the original controller. If the
`OutputVariables(i).Max`

property
of the controller is specified as a vector,
`ymax(i)`

replaces the first
finite entry in this vector, and the remaining
values shift to retain the same constraint
profile.If `ymax`

is empty,
`[]`

, the default bounds defined
in the original MPC controller are used.

`umin`

— Manipulated variable lower bounds`[]`

(default) | column vectorManipulated variable lower bounds, specified as a
column vector of length
*N _{mv}*.

`umin(i)`

replaces the
`ManipulatedVariables(i).Min`

constraint from the original controller. If the
`ManipulatedVariables(i).Min`

property of the controller is specified as a vector,
`umin(i)`

replaces the first
finite entry in this vector, and the remaining
values shift to retain the same constraint
profile.If `umin`

is empty,
`[]`

, the default bounds defined
in the original MPC controller are used.

`umax`

— Manipulated variable upper bounds`[]`

(default) | column vectorManipulated variable upper bounds, specified as a
column vector of length
*N _{mv}*.

`umax(i)`

replaces the
`ManipulatedVariables(i).Max`

constraint from the original controller. If the
`ManipulatedVariables(i).Max`

property of the controller is specified as a vector,
`umax(i)`

replaces the first
finite entry in this vector, and the remaining
values shift to retain the same constraint
profile.If `umax`

is empty,
`[]`

, the default bounds defined
in the original MPC controller are used.

`customconstraints`

— Updated custom mixed input/output constraintsstructure

Updated custom mixed input/output constraints, specified as a structure. This field is ignored when using an explicit MPC controller.

This structure has the following fields:

`E`

— Manipulated variable constraint constant`[]`

(default) | Manipulated variable constraint constant,
specified as an
*N _{c}*-by-

If `E`

is empty,
`[]`

, the corresponding
constraint defined in the original MPC controller
are used.

`F`

— Controlled output constraint constant`[]`

(default) | Controlled output constraint constant, specified
as an
*N _{c}*-by-

`G`

— Mixed input/output constraint constant`[]`

(default) | column vector of length
Mixed input/output constraint constant, specified
as a column vector of length
*N _{c}*.

`S`

— Measured disturbance constraint constant`[]`

(default) | Measured disturbance constraint constant,
specified as an
*N _{c}*-by-

`horizons`

— Updated controller horizonsstructure

Updated controller horizons, specified as a structure. To vary
horizons at run time, first create your data structures using
`getCodeGenerationData`

setting the
`UseVariableHorizon`

name-value pair to
`true`

. When you vary the horizons, you
must specify both the prediction horizon and the control
horizon. For more information, see Adjust Horizons at Run Time.

This field is ignored when using an explicit MPC controller.

This structure has the following fields:

`p`

— Prediction horizon`[]`

(default) | positive integerPrediction horizon, which replaces the value of
`configData.p`

at run time,
specified as a positive integer.

Specifying `p`

changes
the:

Number of rows in the optimal sequences returned in

`info`

The maximum dimensions of the fields in

`model`

when`configData.IsLTV`

is`true`

`m`

— Control horizon`[]`

(default) | positive integer | vector of positive integersControl horizon, which replaces the value of
`configData.m`

at run time,
specified as one of the following:

Positive integer,

*m*, between`1`

and*p*, inclusive, where*p*is the prediction horizon (`horizons.p`

). In this case, the controller computes*m*free control moves occurring at times*k*through*k*+*m*-1, and holds the controller output constant for the remaining prediction horizon steps from*k*+*m*through*k*+*p*-1. Here,*k*is the current control interval. For optimal trajectory planning set*m*equal to*p*.Vector of positive integers, [

*m*_{1},*m*_{2}, …], where the sum of the integers equals the prediction horizon,*p*. In this case, the controller computes*M*blocks of free moves, where*M*is the length of the control horizon vector. The first free move applies to times*k*through*k*+*m*_{1}-1, the second free move applies from time*k*+*m*_{1}through*k*+*m*_{1}+*m*_{2}-1, and so on. Using block moves can improve the robustness of your controller compared to the default case.

`model`

— Updated plant and nominal valuesstructure

Updated plant and nominal values for adaptive MPC and
time-varying MPC, specified as a structure.
`model`

is only available if you specify
`isAdaptive`

or `isLTV`

as
`true`

when creating code generation data
structures.

This structure contains the following fields:

`A`

— State matrix of discrete-time state-space plant modelState matrix of discrete-time state-space plant model, specified as an:

*N*-by-_{x}*N*array when using adaptive MPC,_{x}*N*-by-_{x}*N*-by-(_{x}*p*+1) array when using time-varying MPC,

where *N _{x}*
is the number of plant states.

`B`

— Input-to-state matrix of discrete-time state-space plant modelInput-to-state matrix of discrete-time state-space plant model, specified as an:

*N*-by-_{x}*N*array when using adaptive MPC,_{u}*N*-by-_{x}*N*-by-(_{u}*p*+1) array when using time-varying MPC,

where *N _{u}*
is the number of plant inputs.

`C`

— State-to-output matrix of discrete-time state-space plant modelState-to-output matrix of discrete-time state-space plant model, specified as an:

*N*-by-_{y}*N*array when using adaptive MPC._{x}*N*-by-_{y}*N*-by-(_{x}*p*+1) array when using time-varying MPC.

`D`

— Feedthrough matrix of discrete-time state-space plant modelFeedthrough matrix of discrete-time state-space plant model, specified as an:

*N*-by-_{y}*N*array when using adaptive MPC._{u}*N*-by-_{y}*N*-by-(_{u}*p*+1) array when using time-varying MPC.

Since MPC controllers do not support plants with
direct feedthrough, specify `D`

as
an array of zeros.

`X`

— Nominal plant statescolumn vector of length

Nominal plant states, specified as:

A column vector of length

*N*when using adaptive MPC._{x}An

*N*-by-1-by-(_{x}*p*+1) array when using time-varying MPC.

`U`

— Nominal plant inputscolumn vector of length

Nominal plant inputs, specified as:

A column vector of length

*N*when using adaptive MPC._{u}An

*N*-by-1-by-(_{u}*p*+1) array when using time-varying MPC.

`Y`

— Nominal plant outputscolumn vector of length

Nominal plant outputs, specified as:

A column vector of length

*N*when using adaptive MPC._{y}An

*N*-by-1-by-(_{y}*p*+1) array when using time-varying MPC.

`DX`

— Nominal plant state derivativescolumn vector of length

Nominal plant state derivatives, specified as:

A column vector of length

*N*when using adaptive MPC._{x}An

*N*-by-1-by-(_{x}*p*+1) array when using time-varying MPC.

`mv`

— Optimal manipulated variable movescolumn vector

Optimal manipulated variable moves, returned as a column vector of length
*N _{mv}*, where

If the controller detects an infeasible optimization problem or encounters numerical
difficulties in solving an ill-conditioned optimization problem, `mv`

remains at its most recent successful solution, `x.LastMove`

.

Otherwise, if the optimization problem is feasible and the solver reaches the
specified maximum number of iterations without finding an optimal solution,
`mv`

:

Remains at its most recent successful solution if the

`Optimizer.UseSuboptimalSolution`

property of the controller is`false`

.Is the suboptimal solution reached after the final iteration if the

`Optimizer.UseSuboptimalSolution`

property of the controller is`true`

. For more information, see Suboptimal QP Solution.

`newStateData`

— Updated controller statestructure

Updated controller state, returned as a structure. For subsequent control
intervals, pass `newStateData`

to
`mpcmoveCodeGeneration`

as
`stateData`

.

If custom state estimation is enabled, use
`newStateData`

to manually update the state structure
before the next control interval. For more information, see Custom State Estimation.

`info`

— Controller optimization informationstructure

Controller optimization information, returned as a structure.

If you are using implicit or adaptive MPC, `info`

contains the following fields:

Field | Description |
---|---|

`Iterations` | Number of QP solver iterations |

`QPCode` | QP solver status code |

`Cost` | Objective function cost |

`Uopt` | Optimal manipulated variable adjustments |

`Yopt` | Optimal predicted output variable sequence |

`Xopt` | Optimal predicted state variable sequence |

`Topt` | Time horizon intervals |

`Slack` | Slack variable used in constraint softening |

If `configData.OnlyComputeCost`

is
`true`

, the optimal sequence information,
`Uopt`

, `Yopt`

,
`Xopt`

, `Topt`

, and
`Slack`

, is not available:

For more information, see `mpcmove`

and `mpcmoveAdaptive`

.

If you are using explicit MPC, `info`

contains the
following fields:

Field | Description |
---|---|

`Region` | Region in which the optimal solution was found |

`ExitCode` | Solution status code |

For more information, see `mpcmoveExplicit`

.

Generate C and C++ code using MATLAB® Coder™.

Usage notes and limitations:

You can generate code for both implicit and explicit MPC controllers.

To generate code for computing optimal MPC control moves:

Generate data structures from an MPC controller or explicit MPC controller using

`getCodeGenerationData`

.To verify that your controller produces the expected closed-loop results, simulate it using

`mpcmoveCodeGeneration`

in place of`mpcmove`

.Generate code for

`mpcmoveCodeGeneration`

using`codegen`

(MATLAB Coder). This step requires MATLAB^{®}Coder™ software.

`getCodeGenerationData`

| `mpcmove`

| `mpcmoveAdaptive`

| `mpcmoveExplicit`

| `codegen`

(MATLAB Coder)

A modified version of this example exists on your system. Do you want to open this version instead?

You clicked a link that corresponds to this MATLAB command:

Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.

Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .

Select web siteYou can also select a web site from the following list:

Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.

- América Latina (Español)
- Canada (English)
- United States (English)

- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)

- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)