Main Content


Compute optimal control using explicit MPC


Use this command to simulate an explicit MPC controller in closed-loop with a plant model. Call mpcmoveExplicit repeatedly in a for loop to calculate the manipulated variable and update the controller states at each time step.


mv = mpcmoveExplicit(empcobj,x,ym,r) returns the optimal move mv and updates the states xc of the controller empcobj.

The manipulated variable mv at the current time is calculated given:

  • the controller object, empcobj,

  • a pointer to the current estimated extended state, xc,

  • the measured plant outputs, ym,

  • the output references, r,

  • and the measured disturbance input, v.

If ym, r or v is specified as [], or if it is missing as a last input argument, mpcmove uses the appropriate mpcobj.Model.Nominal value instead.

When using default state estimation, mpcmoveExplicit also updates the controller state referenced by the handle object xc. Therefore, when using default state estimation, xc always points to the updated controller state. When using custom state estimation, you should update xc prior to each mpcmoveExplicit call.

[mv,info] = mpcmoveExplicit(empcobj,x,ym,r,v) returns additional details about the computation in a structure. To determine whether the optimal control calculation completed normally, check the data in info.

[mv,info] = mpcmoveExplicit(empcobj,x,ym,r,v,MVused) specifies the manipulated variable values used in the previous mpcmoveExplicit command, allowing a command-line simulation to mimic the Explicit MPC Controller Simulink® block with the optional external MV input signal.


collapse all

This example shows how to use mpcmoveExplicit to simulate a plant in closed loop with an explicit MPC controller.

First, define the sample time, the plant (for this example, a double integrator), and create a traditional MPC object.

Ts = 0.1;
plant = tf(1,[1 0 0]);
mpcobj = mpc(plant,0.1);
-->"PredictionHorizon" is empty. Assuming default 10.
-->"ControlHorizon" is empty. Assuming default 2.
-->"Weights.ManipulatedVariables" is empty. Assuming default 0.00000.
-->"Weights.ManipulatedVariablesRate" is empty. Assuming default 0.10000.
-->"Weights.OutputVariables" is empty. Assuming default 1.00000.

Define constraints on the manipulated variable.

mpcobj.MV = struct('Min',-1,'Max',1); 

The MPC controller states include states from the plant model, the disturbance model noise model, and the last values of the manipulated variables, in that order. To create a range structure where you can specify the range for each state, reference, and manipulated variable, use generateExplicitRange.

range = generateExplicitRange(mpcobj);
-->Converting the "Model.Plant" property to state-space.
-->Converting model to discrete time.
   Assuming no disturbance added to measured output #1.
-->"Model.Noise" is empty. Assuming white noise on each measured output.

If at run time any of these variables falls outside its range, the controller returns an error status and sets the manipulated variables to their last values. Therefore, it is important that you do not underestimate these ranges. For this example, use the following ranges.

range.State.Min(:) = [-10;-10];
range.State.Max(:) = [10;10];

range.Reference.Min = -2;
range.Reference.Max = 2;

range.ManipulatedVariable.Min = mpcobj.MV.Min -1;
range.ManipulatedVariable.Max = mpcobj.MV.Max +1;

Create an explicit MPC controller from the traditional MPC object and the range structure.

empcobj = generateExplicitMPC(mpcobj, range);
Regions found / unexplored:        9/       0

Set up the number of simulation steps and initialize arrays to store the plant input and output signals (so they can be plotted later).

N = round(5/Ts);
U = zeros(N,1);
Y = zeros(N,1);

Discretize the plant, and set up its initial condition.

dtplant = ss(c2d(plant,Ts));
x = [0 0]';

To obtain an handle (that is a pointer) to the controller state, use mpcstate.

xc = mpcstate(empcobj)
MPCSTATE object with fields
          Plant: [0 0]
    Disturbance: [1x0 double]
          Noise: [1x0 double]
       LastMove: 0
     Covariance: [2x2 double]

The controller has two states for the internal plant model, and one to hold the last value of the manipulated variable. All these states are initialized to zero.

Iteratively simulate the closed-loop response to a reference signal of 0.8. To calculate the explicit MPC controller move, use mpcmoveExplicit.

for k = 1:N

    % update plant measurement and store signal
    y = dtplant.C*x;

    % compute explicit MPC action and store signal
    u = mpcmoveExplicit(empcobj,xc,y,0.8);

    % update plant state
    x = dtplant.A*x + dtplant.B*u;

Plot the resulting plant input and output signals.

plot(1:N,[U Y])
title('Closed loop response')

Input Arguments

collapse all

Explicit MPC controller to simulate, specified as an Explicit MPC controller object. Use generateExplicitMPC to create an explicit MPC controller.

Current MPC controller state, specified as an mpcstate object.

Before you begin a simulation with mpcmoveExplicit, initialize the controller state using x = mpcstate(empcobj). Then, modify the default properties of x as appropriate.

If you are using default state estimation, mpcmoveExplicit expects x to represent x[n|n-1]. The mpcmoveExplicit command updates the state values in the previous control interval with that information. Therefore, you should not programmatically update x at all. The default state estimator employs a linear time-varying Kalman filter.

If you are using custom state estimation, mpcmoveExplicit expects x to represent x[n|n]. Therefore, prior to each mpcmoveExplicit command, you must set x.Plant, x.Disturbance, and x.Noise to the best estimates of these states (using the latest measurements) at the current control interval.

Current measured outputs, specified as a row vector of length Nym, where Nym is the number of measured outputs. If you are using custom state estimation, ym is ignored. If you set ym = [], then mpcmoveExplicit uses the appropriate nominal value.

Plant output reference values, specified as a vector of length Ny. mpcmoveExplicit uses a constant reference for the entire prediction horizon. In contrast to mpcmove and mpcmoveAdaptive, mpcmoveExplicit does not support reference previewing.

If you set r = [], then mpcmoveExplicit uses the appropriate nominal value.

Current and anticipated measured disturbances, specified as a vector of length Nmd, where Nmd is the number of measured disturbances. In contrast to mpcmove and mpcmoveAdaptive, mpcmoveExplicit does not support disturbance previewing. If your plant model does not include measured disturbances, use v = [].

Manipulated variable values applied to the plant during the previous control interval, specified as a vector of length Nmv, where Nmv is the number of manipulated variables. If this is the first mpcmoveExplicit command in a simulation sequence, omit this argument. Otherwise, if the MVs calculated by mpcmoveExplicit in the previous interval were overridden, set MVused to the correct values in order to improve the controller state estimation accuracy. If you omit MVused, mpcmoveExplicit assumes MVused = x.LastMove.

Output Arguments

collapse all

Optimal manipulated variable moves, returned as a column vector of length Nmv, where Nmv is the number of manipulated variables.

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, xc.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.

Explicit MPC solution status, returned as a structure having the following fields.

Solution status code, returned as one of the following values:

  • 1 — Successful solution.

  • 0 — Failure. One or more controller input parameters is out of range.

  • –1 — Undefined. Parameters are in range but an extrapolation must be used.

Region to which current controller input parameters belong, returned as either a positive integer or 0. The integer value is the index of the polyhedron (region) to which the current controller input parameters belong. If the solution failed, Region = 0.


Version History

Introduced in R2014b