Main Content

Compute optimal control action for nonlinear MPC controller

computes the optimal control action for the current time. To simulate closed-loop
nonlinear MPC control, call `mv`

= nlmpcmove(`nlmpcMSobj`

,`x`

,`lastmv`

)`nlmpcmove`

repeatedly.

specifies the additional `mv`

= nlmpcmove(`nlmpcobj`

,`x`

,`lastmv`

,`simdata`

)`simdata`

structure, which contains measured
disturbances, run-time bounds, parameters for the state and stage functions, and initial
guesses for state and manipulated variable trajectories. In general use the following
syntax to return a new `simdata`

(containing updated initial guesses)
as a second output argument.

Create nonlinear MPC controller with six states, six outputs, and four inputs.

nx = 6; ny = 6; nu = 4; nlobj = nlmpc(nx,ny,nu);

In standard cost function, zero weights are applied by default to one or more OVs because there are fewer MVs than OVs.

Specify the controller sample time and horizons.

Ts = 0.4; p = 30; c = 4; nlobj.Ts = Ts; nlobj.PredictionHorizon = p; nlobj.ControlHorizon = c;

Specify the prediction model state function and the Jacobian of the state function. For this example, use a model of a flying robot.

nlobj.Model.StateFcn = "FlyingRobotStateFcn"; nlobj.Jacobian.StateFcn = "FlyingRobotStateJacobianFcn";

Specify a custom cost function for the controller that replaces the standard cost function.

nlobj.Optimization.CustomCostFcn = @(X,U,e,data) Ts*sum(sum(U(1:p,:))); nlobj.Optimization.ReplaceStandardCost = true;

Specify a custom constraint function for the controller.

nlobj.Optimization.CustomEqConFcn = @(X,U,data) X(end,:)';

Specify linear constraints on the manipulated variables.

for ct = 1:nu nlobj.MV(ct).Min = 0; nlobj.MV(ct).Max = 1; end

Validate the prediction model and custom functions at the initial states (`x0`

) and initial inputs (`u0`

) of the robot.

x0 = [-10;-10;pi/2;0;0;0]; u0 = zeros(nu,1); validateFcns(nlobj,x0,u0);

Model.StateFcn is OK. Jacobian.StateFcn is OK. No output function specified. Assuming "y = x" in the prediction model. Optimization.CustomCostFcn is OK. Optimization.CustomEqConFcn is OK. Analysis of user-provided model, cost, and constraint functions complete.

Compute the optimal state and manipulated variable trajectories, which are returned in the `info`

.

[~,~,info] = nlmpcmove(nlobj,x0,u0);

Slack variable unused or zero-weighted in your custom cost function. All constraints will be hard.

Plot the optimal trajectories.

FlyingRobotPlotPlanning(info,Ts)

Optimal fuel consumption = 1.884953

Create a nonlinear MPC controller with four states, two outputs, and one input.

nlobj = nlmpc(4,2,1);

In standard cost function, zero weights are applied by default to one or more OVs because there are fewer MVs than OVs.

Specify the sample time and horizons of the controller.

Ts = 0.1; nlobj.Ts = Ts; nlobj.PredictionHorizon = 10; nlobj.ControlHorizon = 5;

Specify the state function for the controller, which is in the file `pendulumDT0.m`

. This discrete-time model integrates the continuous time model defined in `pendulumCT0.m`

using a multistep forward Euler method.

```
nlobj.Model.StateFcn = "pendulumDT0";
nlobj.Model.IsContinuousTime = false;
```

The prediction model uses an optional parameter, `Ts`

, to represent the sample time. Specify the number of parameters.

nlobj.Model.NumberOfParameters = 1;

Specify the output function of the model, passing the sample time parameter as an input argument.

nlobj.Model.OutputFcn = @(x,u,Ts) [x(1); x(3)];

Define standard constraints for the controller.

nlobj.Weights.OutputVariables = [3 3]; nlobj.Weights.ManipulatedVariablesRate = 0.1; nlobj.OV(1).Min = -10; nlobj.OV(1).Max = 10; nlobj.MV.Min = -100; nlobj.MV.Max = 100;

Validate the prediction model functions.

x0 = [0.1;0.2;-pi/2;0.3]; u0 = 0.4; validateFcns(nlobj, x0, u0, [], {Ts});

Model.StateFcn is OK. Model.OutputFcn is OK. Analysis of user-provided model, cost, and constraint functions complete.

Only two of the plant states are measurable. Therefore, create an extended Kalman filter for estimating the four plant states. Its state transition function is defined in `pendulumStateFcn.m`

and its measurement function is defined in `pendulumMeasurementFcn.m`

.

EKF = extendedKalmanFilter(@pendulumStateFcn,@pendulumMeasurementFcn);

Define initial conditions for the simulation, initialize the extended Kalman filter state, and specify a zero initial manipulated variable value.

x = [0;0;-pi;0]; y = [x(1);x(3)]; EKF.State = x; mv = 0;

Specify the output reference value.

yref = [0 0];

Create an `nlmpcmoveopt`

object, and specify the sample time parameter.

nloptions = nlmpcmoveopt; nloptions.Parameters = {Ts};

Run the simulation for `10`

seconds. During each control interval:

Correct the previous prediction using the current measurement.

Compute optimal control moves using

`nlmpcmove`

. This function returns the computed optimal sequences in`nloptions`

. Passing the updated options object to`nlmpcmove`

in the next control interval provides initial guesses for the optimal sequences.Predict the model states.

Apply the first computed optimal control move to the plant, updating the plant states.

Generate sensor data with white noise.

Save the plant states.

Duration = 10; xHistory = x; for ct = 1:(Duration/Ts) % Correct previous prediction xk = correct(EKF,y); % Compute optimal control moves [mv,nloptions] = nlmpcmove(nlobj,xk,mv,yref,[],nloptions); % Predict prediction model states for the next iteration predict(EKF,[mv; Ts]); % Implement first optimal control move x = pendulumDT0(x,mv,Ts); % Generate sensor data y = x([1 3]) + randn(2,1)*0.01; % Save plant states xHistory = [xHistory x]; end

Plot the resulting state trajectories.

figure subplot(2,2,1) plot(0:Ts:Duration,xHistory(1,:)) xlabel('time') ylabel('z') title('cart position') subplot(2,2,2) plot(0:Ts:Duration,xHistory(2,:)) xlabel('time') ylabel('zdot') title('cart velocity') subplot(2,2,3) plot(0:Ts:Duration,xHistory(3,:)) xlabel('time') ylabel('theta') title('pendulum angle') subplot(2,2,4) plot(0:Ts:Duration,xHistory(4,:)) xlabel('time') ylabel('thetadot') title('pendulum velocity')

This example shows how to create and simulate a simple multistage MPC controller in closed loop, without using initial guesses, with the MATLAB® function `nlmpcmove`

.

**Create Multistage MPC Controller**

Create a multistage nonlinear MPC object with a five-step horizon, one state, and one manipulated variable.

nlmsobj = nlmpcMultistage(5,1,1);

Specify the state transition function for the prediction model (`mystatefcn`

is defined at the end of this example).

nlmsobj.Model.StateFcn = @mystatefcn;

Specify the cost functions for last three stages (`mycostfcn`

is defined at the end of the file).

for i=3:6 nlmsobj.Stages(6).CostFcn = @mycostfcn; end

**Simulate Controller in Closed Loop**

Initialize the plant state and input.

x=3; mv=0;

Validate functions.

validateFcns(nlmsobj,x,mv);

Model.StateFcn is OK. "CostFcn" of the following stages 6 are OK. Analysis of user-provided model, cost, and constraint functions complete.

Simulate the control loop for 10 steps, without updating the initial guess.

for k=1:10 mv = nlmpcmove(nlmsobj, x, mv); % calculate move (without initial guess) x = x + (mv-sqrt(x))*1; % update x: x(t+1)=x(t)+xdot*Ts end

Note that, because initial guesses are not supplied as an input argument, `nlmpcmove`

needs to recalculate them at each time step, which negatively affects performance. Not supplying initial guesses can be an acceptable starting point, but in general is not suggested. As a best practice, use updated initial guesses at each time step, as shown in Simulate Multistage Nonlinear MPC Controller Using Initial Guesses, so that `nlmpcmove`

does not need to recalculate them at each time step.

Display the final values of the state and manipulated variables.

`disp(['Final value of x =' num2str(x)])`

Final value of x =0.57118

`disp(['Final value of mv =' num2str(mv)])`

Final value of mv =0.75571

**Support Functions**

State transition function.

function xdot = mystatefcn(x,u) xdot = u-sqrt(x); end

Stage cost functions.

function j = mycostfcn(s,x,u) j = abs(u)/s+s*x^2; end

This example shows how to create and simulate a simple multistage MPC controller in closed loop using initial guesses, with the MATLAB® function `nlmpcmove`

.

**Create Multistage MPC Controller**

Create a multistage MPC object with a seven-steps horizon, one state, and one manipulated variable.

nlmsobj = nlmpcMultistage(7,1,1);

Specify the state transition function for the prediction model (`mystatefcn`

is defined at the end of this example).

nlmsobj.Model.StateFcn = @mystatefcn;

As a best practice, use Jacobians whenever they are available, otherwise the solver must compute it numerically.

Specify the Jacobian of the state transition function (`mystatejacobian`

is defined at the end of the file).

nlmsobj.Model.StateJacFcn = @mystatejac;

Specify the cost functions for all stages except the first two (`mycostfcn`

is defined at the end of the file).

for i=3:8 nlmsobj.Stages(6).CostFcn = @mycostfcn; end

**Define Initial Conditions, Create Data Structure, and Validate Functions**

Initialize the plant state and input.

x=3; mv=0;

Create the initial simulation data structure.

simdata = getSimulationData(nlmsobj)

`simdata = `*struct with fields:*
InitialGuess: []

Validate functions and the data structure.

validateFcns(nlmsobj,x,mv,simdata);

Model.StateFcn is OK. Model.StateJacFcn is OK. "CostFcn" of the following stages 6 are OK. Analysis of user-provided model, cost, and constraint functions complete.

**Simulate Controller in Closed Loop**

Simulate the control loop for 10 steps.

for k=1:10 [mv,simdata] = nlmpcmove(nlmsobj, x, mv, simdata); % calculate move x = x + (mv-sqrt(x))*1; % update x: x(t+1)=x(t)+xdot*Ts end

Since updated initial guesses are supplied as an input argument within the `simdata`

structure, `nlmpcmove`

does not need to recalculate them at each time step, which saves computation time and improves performance. Updating initial guesses at every time step is a best practice.

Display the last values of the state and manipulated variables.

`disp(['Final value of x =' num2str(x)])`

Final value of x =1.6556

`disp(['Final value of mv =' num2str(mv)])`

Final value of mv =1.2816

**Support Functions**

State transition function.

function xdot = mystatefcn(x,u) xdot = u-sqrt(x); end

Jacobian of the state transition function.

function [A,B] = mystatejac(x,~) A = -1/(2*x^(1/2)); B = 1; end

Stage cost functions.

function j = mycostfcn(s,x,u) j = abs(u)/s+s*x^2; end

`nlmpcobj`

— Nonlinear MPC controller`nlmpc`

objectNonlinear MPC controller, specified as an `nlmpc`

object.

`x`

— Current prediction model statesvector

Current prediction model states, specified as a vector of
length*N _{x}*, where

`lastmv`

— Control signals used in plant at previous control intervalvector

Control signals used in plant at previous control interval, specified as a vector of
length*N _{mv}*, where

**Note**

Specify `lastmv`

as the manipulated variable signals applied to
the plant in the previous control interval. Typically, these signals are the values
generated by the controller, though this is not always the case. For example, if your
controller is offline and running in tracking mode; that is, the controller output is
not driving the plant, then feeding the actual control signal to
`last_mv`

can help achieve bumpless transfer when the controller
is switched back online.

`ref`

— Plant output reference values`[]`

(default) | row vector | arrayPlant output reference values, specified as a row vector of length
*N _{y}* or an array with

`ref`

, the default reference values are
zero.To use the same reference values across the prediction horizon, specify a row vector.

To vary the reference values over the prediction horizon from time
*k*+1 to time *k*+*p*, specify an
array with up to *p* rows. Here, *k* is the current
time and *p* is the prediction horizon. Each row contains the reference
values for one prediction horizon step. If you specify fewer than *p*
rows, the values in the final row are used for the remaining steps of the prediction
horizon.

`md`

— Measured disturbance values`[]`

(default) | row vector | arrayMeasured disturbance values, specified as a row vector of length
*N _{md}* or an array with

`md`

. If your controller has no measured disturbances, specify
`md`

as `[]`

.To use the same disturbance values across the prediction horizon, specify a row vector.

To vary the disturbance values over the prediction horizon from time
*k* to time *k*+*p*, specify an
array with up to *p*+1 rows. Here, *k* is the current
time and *p* is the prediction horizon. Each row contains the
disturbance values for one prediction horizon step. If you specify fewer than
*p* rows, the values in the final row are used for the remaining
steps of the prediction horizon.

`options`

— Run-time options`nlmpcmoveopt`

objectRun-time options, specified as an `nlmpcmoveopt`

object. Using these options, you can:

Tune controller weights

Update linear constraints

Set manipulated variable targets

Specify prediction model parameters

Provide initial guesses for state and manipulated variable trajectories

These options apply to only the current `nlmpcmove`

time
instant.

To improve solver efficiency, it is best practice to specify initial guesses for the state and manipulated variable trajectories.

`nlmpcMSobj`

— Nonlinear Multistage MPC controller`nlmpcMultistage`

objectMultistage nonlinear MPC controller, specified as an `nlmpcMultistage`

object.

`simdata`

— Run-time simulation datastructure

Run-time simulation data, specified as structure. It must be initially created by
`getSimulationData`

, and then populated (if needed) before being passed to
`nlmpcmove`

as an input argument. An updated version is then always
returned as a second output argument of `nlmpcmove`

. Note that the
`MVMin`

, `MVMax`

, `StateMin`

,
`StateMax`

, `MVRateMin`

,
`MVRateMax`

fields are needed only if you want to change these
bounds at run time. These fields exist in the structure returned by
`getSimulationData`

only if you enable them explicitly when calling
`getSimulationData`

. The `simdata`

structure has
the following fields.

`MeasuredDisturbance`

— Measured disturbance values`[]`

(default) | row vector | arrayMeasured disturbance values, specified as a row vector of length
*N _{md}* or an array with

`MeasuredDisturbance`

. If your
controller has no measured disturbances, this field does not exist in the
structure generated by `getSimulationData`

.To use the same disturbance values across the prediction horizon, specify a row vector.

To vary the disturbance values over the prediction horizon from time
*k* to time *k*+*p*, specify
an array with up to *p*+1 rows. Here, *k* is the
current time and *p* is the prediction horizon. Each row contains
the disturbance values for one prediction horizon step. If you specify fewer than
*p* rows, the values in the final row are used for the
remaining steps of the prediction horizon.

`MVMin`

— Manipulated variable lower bounds`[]`

(default) | row vector | matrixManipulated variable lower bounds, specified as a row vector of length
*N _{mv}* or a matrix with

`MVMin(:,i)`

replaces the
`ManipulatedVariables(i).Min`

property of the controller at run
time.To use the same bounds across the prediction horizon, specify a row vector.

To vary the bounds over the prediction horizon from time *k*
to time *k*+*p*-1, specify a matrix with up to
*p* rows. Here, *k* is the current time and
*p* is the prediction horizon. Each row contains the bounds for
one prediction horizon step. If you specify fewer than *p* rows,
the final bounds are used for the remaining steps of the prediction
horizon.

`MVMax`

— Manipulated variable upper bounds`[]`

(default) | row vector | matrixManipulated variable upper bounds, specified as a row vector of length
*N _{mv}* or a matrix with

`MVMax(:,i)`

replaces the
`ManipulatedVariables(i).Max`

property of the controller at run
time.To use the same bounds across the prediction horizon, specify a row vector.

To vary the bounds over the prediction horizon from time *k*
to time *k*+*p*-1, specify a matrix with up to
*p* rows. Here, *k* is the current time and
*p* is the prediction horizon. Each row contains the bounds for
one prediction horizon step. If you specify fewer than *p* rows,
the final bounds are used for the remaining steps of the prediction
horizon.

`MVRateMin`

— Manipulated variable rate lower bounds`[]`

(default) | row vector | matrixManipulated variable rate lower bounds, specified as a row vector of length
*N _{mv}* or a matrix with

`MVRateMin(:,i)`

replaces the
`ManipulatedVariables(i).RateMin`

property of the controller at
run time. `MVRateMin`

bounds must be nonpositive.To use the same bounds across the prediction horizon, specify a row vector.

To vary the bounds over the prediction horizon from time *k*
to time *k*+*p*-1, specify a matrix with up to
*p* rows. Here, *k* is the current time and
*p* is the prediction horizon. Each row contains the bounds for
one prediction horizon step. If you specify fewer than *p* rows,
the final bounds are used for the remaining steps of the prediction
horizon.

`MVRateMax`

— Manipulated variable rate upper bounds`[]`

(default) | row vector | matrixManipulated variable rate upper bounds, specified as a row vector of length
*N _{mv}* or a matrix with

`MVRateMax(:,i)`

replaces the
`ManipulatedVariables(i).RateMax`

property of the controller at
run time. `MVRateMax`

bounds must be nonnegative.To use the same bounds across the prediction horizon, specify a row vector.

*k*
to time *k*+*p*-1, specify a matrix with up to
*p* rows. Here, *k* is the current time and
*p* is the prediction horizon. Each row contains the bounds for
one prediction horizon step. If you specify fewer than *p* rows,
the final bounds are used for the remaining steps of the prediction
horizon.

`StateMin`

— State lower bounds`[]`

(default) | row vector | matrixState lower bounds, specified as a row vector of length
*N _{x}* or a matrix with

`StateMin(:,i)`

replaces the `States(i).Min`

property of the controller at run time.To use the same bounds across the prediction horizon, specify a row vector.

To vary the bounds over the prediction horizon from time
*k*+1 to time *k*+*p*, specify
a matrix with up to *p* rows. Here, *k* is the
current time and *p* is the prediction horizon. Each row contains
the bounds for one prediction horizon step. If you specify fewer than
*p* rows, the final bounds are used for the remaining steps of
the prediction horizon.

`StateMax`

— State upper bounds`[]`

(default) | row vector | matrixState upper bounds, specified as a row vector of length
*N _{x}* or a matrix with

`StateMax(:,i)`

replaces the `States(i).Max`

property of the controller at run time.To use the same bounds across the prediction horizon, specify a row vector.

To vary the bounds over the prediction horizon from time
*k*+1 to time *k*+*p*, specify
a matrix with up to *p* rows. Here, *k* is the
current time and *p* is the prediction horizon. Each row contains
the bounds for one prediction horizon step. If you specify fewer than
*p* rows, the final bounds are used for the remaining steps of
the prediction horizon.

`StateFcnParameters`

— State function parameter values`[]`

(default) | vectorState function parameter values, specified as a vector with length equal to
the value of the `Model.ParameterLength`

property of the
multistage controller object. If `Model.StateFcn`

needs a
parameter vector, you must provide its value at runtime using this field. If
`Model.ParameterLength`

is `0`

this field does
not exist in the structure returned by
`getSimulationData`

.

`StageFcnParameters`

— Stage function parameter values`[]`

(default) | vectorStage functions parameter values, specified as a vector with length equal to
the sum of all the values in the `Stages(i).ParameterLength`

properties of the multistage controller object. If any cost or constraint function
defined in the `Stages`

property needs a parameter vector, you
must provide all the parameter vectors at runtime (stacked in a single column)
using this field. If none of your stage functions have parameters, this field does
not exist in the structure returned by
`getSimulationData`

.

You must stack the parameter vectors for all stages in the column vector
`StateFcnParameters`

as
follows.

[parameter vector for stage 1; parameter vector for stage 2; ... parameter vector for stage p+1; ]

`TerminalState`

— Terminal state`[]`

(default) | vectorTerminal state, specified as a column vector with as many elements as the
number of states. The terminal state is the desired state at the last prediction
step. To specify desired terminal states at run-time via this field, you must
specify finite values in the `TerminalState`

field of the
`Model`

property of `nlmpcMSobj`

. Specify
`inf`

for the states that do not need to be constrained to a
terminal value. At run time, `nlmpcmove`

ignores any values in the
`TerminalState`

field of `simdata`

that
correspond to `inf`

values in `nlmpcMSobj`

. If
you do not specify any terminal value condition in
`nlmpcMSobj`

, this field is not created in
`simdata`

.

If there is no `TerminalState`

in
`simdata`

then the terminal state constraint (if present)
does not change at run time.

`InitialGuess`

— Initial guesses for the decision variables`[]`

(default) | vectorInitial guesses for the decision variables, specified as a column vector of
length equal to the sum of the lengths of all the decision variable vectors for
each stage. Good initial guesses are important since they help the solver to
converge to a solution faster. Therefore, when simulating a control loop by
calling `nlmpcmove`

repeatedly in a loop, pass
`simdata`

as an input argument (so initial guesses can be
used), and at the same time return an updated version of
`simdata`

(with new initial guesses for the next control
interval) as an output argument.

You must be stack the initial guesses for all stages in the column vector
`InitialGuess`

as
follows.

[state vector guess for stage 1; manipulated variable vector guess for stage 1; manipulated variable vector rate guess for stage 1; % if used slack variable vector guess for stage 1; % if used state vector guess for stage 2; manipulated variable vector guess for stage 2; manipulated variable vector rate guess for stage 2; % if used slack variable vector guess for stage 2; % if used ... state vector guess for stage p; manipulated variable vector guess for stage p; manipulated variable vector rate guess for stage p; % if used slack variable vector guess for stage p; % if used state vector guess for stage p+1; slack variable vector guess for stage p+1; % if used ]

If `InitialGuess`

is `[]`

, the default
initial guesses are calculated from the `x`

and
`lastmv`

arguments passed to
`nlmpcmove`

.

In general, during closed-loop simulation, you do not specify
`InitialGuess`

yourself. Instead, when calling `nlmpcmove`

, return the `simdata`

output argument,
which contains the calculated initial guesses for the next control interval. You
can then pass `simdata`

as an input argument to
`nlmpcmove`

for the next control interval. These steps are a
best practice, even if you do not specify any other run-time options.

`mv`

— Optimal manipulated variable control actioncolumn vector

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

If the solver converges to a local optimum solution
(`info.ExitFlag`

is positive), then `mv`

contains
the optimal solution.

If the solver reaches the maximum number of iterations without finding an optimal
solution (`info.ExitFlag = 0`

) and:

`nlmpcobj.Optimization.UseSuboptimalSolution`

is`true`

, then`mv`

contains the suboptimal solution`nlmpcobj.Optimization.UseSuboptimalSolution`

is`false`

, then`mv`

contains`lastmv`

If the solver fails (`info.ExitFlag`

is negative), then
`mv`

contains `lastmv`

.

`opt`

— Run-time options with initial guesses`nlmpcmoveopt`

objectRun-time options with initial guesses for the state and manipulated variable
trajectories to be used in the next control interval, returned as an `nlmpcmoveopt`

object. Any run-time options that you specified using `options`

, such
as weights, constraints, or parameters, are copied to `opt`

.

The initial guesses for the states (`opt.X0`

) and manipulated
variables (`opt.MV0`

) are the optimal trajectories computed by
`nlmpcmove`

and correspond to the last *p*-1 rows
of `info.Xopt`

and `info.MVopt`

, respectively.

To use these initial guesses in the next control interval, specify
`opt`

as the `options`

input argument to
`nlmpcmove`

.

`info`

— Solution detailsstructure

Solution details, returned as a structure with the following fields.

`MVopt`

— Optimal manipulated variable sequencearray

Optimal manipulated variable sequence, returned as a
(*p*+1)-by-*N _{mv}*
array, where

`MVopt(i,:)`

contains the calculated optimal manipulated
variable values at time `k+i-1`

, for ```
i =
1,...,p
```

, where `k`

is the current time.
`MVopt(1,:)`

contains the same manipulated variable values as
output argument `mv`

. Since the controller does not calculate
optimal control moves at time `k+p`

,
`MVopt(p+1,:)`

is equal to
`MVopt(p,:)`

.

`Xopt`

— Optimal prediction model state sequencearray

Optimal prediction model state sequence, returned as a
(*p*+1)-by-*N _{x}*
array, where

`Xopt(i,:)`

contains the calculated state values at time
`k+i-1`

, for `i = 2,...,p+1`

, where
`k`

is the current time. `Xopt(1,:)`

is the
same as the current states in `x`

.

`Yopt`

— Optimal output variable sequencearray

Optimal output variable sequence, returned as a
(*p*+1)-by-*N _{y}*
array, where

`Yopt(i,:)`

contains the calculated output values at time
`k+i-1`

, for `i = 2,...,p+1`

, where
`k`

is the current time. `Yopt(1,:)`

is
computed based on the current states in `x`

and the current
measured disturbances in `md`

, if any.

`Topt`

— Prediction horizon time sequencecolumn vector

Prediction horizon time sequence, returned as a column vector of length
*p*+1, where *p* is the prediction horizon.
`Topt`

contains the time sequence from time
*k* to time *k*+*p*, where
*k* is the current time.

`Topt(1)`

= 0 represents the current time. Subsequent time
steps `Topt(i)`

are `Ts*(i-1)`

, where
`Ts`

is the controller sample time.

Use `Topt`

when plotting the `MVopt`

,
`Xopt`

, or `Yopt`

sequences.

`Slack`

— Stacked slack variables vectornonnegative vector

Stacked slack variables vector, used in constraint softening. If all elements are zero, then all soft constraints are satisfied over the entire prediction horizon. If any element is greater than zero, then at least one soft constraint is violated.

The slack variable vector for all stages are stacked as:

[slack variable vector for stage 1; % if used slack variable vector for stage 2; % if used ... slack variable vector for stage p+1; % if used ]

`ExitFlag`

— Optimization exit codeinteger

Optimization exit code, returned as one of the following:

Positive Integer — Optimal solution found

`0`

— Feasible suboptimal solution found after the maximum number of iterationsNegative integer — No feasible solution found

`Iterations`

— Number of iterationspositive integer

Number of iterations used by the nonlinear programming solver, returned as a positive integer.

`Cost`

— Objective function costnonnegative scalar

Objective function cost, returned as a nonnegative scalar value. The cost quantifies the degree to which the controller has achieved its objectives.

The cost value is only meaningful when `ExitFlag`

is
nonnegative.

`simdata`

— Run-time simulation data structurestructure

Updated run-time simulation data, returned as a structure, containing new initial guesses for the state and manipulated trajectories to be used in the next control interval. It is a structure with the following fields.

`MeasuredDisturbance`

— Measured disturbance values`[]`

(default) | row vector | arrayMeasured disturbance values, specified as a row vector of length
*N _{md}* or an array with

`MeasuredDisturbance`

. If your
controller has no measured disturbances, this field does not exist in the
structure generated by `getSimulationData`

.To use the same disturbance values across the prediction horizon, specify a row vector.

To vary the disturbance values over the prediction horizon from time
*k* to time *k*+*p*, specify
an array with up to *p*+1 rows. Here, *k* is the
current time and *p* is the prediction horizon. Each row contains
the disturbance values for one prediction horizon step. If you specify fewer than
*p* rows, the values in the final row are used for the
remaining steps of the prediction horizon.

`MVMin`

— Manipulated variable lower bounds`[]`

(default) | row vector | matrixManipulated variable lower bounds, specified as a row vector of length
*N _{mv}* or a matrix with

`MVMin(:,i)`

replaces the
`ManipulatedVariables(i).Min`

property of the controller at run
time.To use the same bounds across the prediction horizon, specify a row vector.

*k*
to time *k*+*p*-1, specify a matrix with up to
*p* rows. Here, *k* is the current time and
*p* is the prediction horizon. Each row contains the bounds for
one prediction horizon step. If you specify fewer than *p* rows,
the final bounds are used for the remaining steps of the prediction
horizon.

`MVMax`

— Manipulated variable upper bounds`[]`

(default) | row vector | matrixManipulated variable upper bounds, specified as a row vector of length
*N _{mv}* or a matrix with

`MVMax(:,i)`

replaces the
`ManipulatedVariables(i).Max`

property of the controller at run
time.To use the same bounds across the prediction horizon, specify a row vector.

*k*
to time *k*+*p*-1, specify a matrix with up to
*p* rows. Here, *k* is the current time and
*p* is the prediction horizon. Each row contains the bounds for
one prediction horizon step. If you specify fewer than *p* rows,
the final bounds are used for the remaining steps of the prediction
horizon.

`MVRateMin`

— Manipulated variable rate lower bounds`[]`

(default) | row vector | matrixManipulated variable rate lower bounds, specified as a row vector of length
*N _{mv}* or a matrix with

`MVRateMin(:,i)`

replaces the
`ManipulatedVariables(i).RateMin`

property of the controller at
run time. `MVRateMin`

bounds must be nonpositive.To use the same bounds across the prediction horizon, specify a row vector.

*k*
to time *k*+*p*-1, specify a matrix with up to
*p* rows. Here, *k* is the current time and
*p* is the prediction horizon. Each row contains the bounds for
one prediction horizon step. If you specify fewer than *p* rows,
the final bounds are used for the remaining steps of the prediction
horizon.

`MVRateMax`

— Manipulated variable rate upper bounds`[]`

(default) | row vector | matrixManipulated variable rate upper bounds, specified as a row vector of length
*N _{mv}* or a matrix with

`MVRateMax(:,i)`

replaces the
`ManipulatedVariables(i).RateMax`

property of the controller at
run time. `MVRateMax`

bounds must be nonnegative.To use the same bounds across the prediction horizon, specify a row vector.

*k*
to time *k*+*p*-1, specify a matrix with up to
*p* rows. Here, *k* is the current time and
*p* is the prediction horizon. Each row contains the bounds for
one prediction horizon step. If you specify fewer than *p* rows,
the final bounds are used for the remaining steps of the prediction
horizon.

`StateMin`

— State lower bounds`[]`

(default) | row vector | matrixState lower bounds, specified as a row vector of length
*N _{x}* or a matrix with

`StateMin(:,i)`

replaces the `States(i).Min`

property of the controller at run time.To use the same bounds across the prediction horizon, specify a row vector.

To vary the bounds over the prediction horizon from time
*k*+1 to time *k*+*p*, specify
a matrix with up to *p* rows. Here, *k* is the
current time and *p* is the prediction horizon. Each row contains
the bounds for one prediction horizon step. If you specify fewer than
*p* rows, the final bounds are used for the remaining steps of
the prediction horizon.

`StateMax`

— State upper bounds`[]`

(default) | row vector | matrixState upper bounds, specified as a row vector of length
*N _{x}* or a matrix with

`StateMax(:,i)`

replaces the `States(i).Max`

property of the controller at run time.To use the same bounds across the prediction horizon, specify a row vector.

*k*+1 to time *k*+*p*, specify
a matrix with up to *p* rows. Here, *k* is the
current time and *p* is the prediction horizon. Each row contains
the bounds for one prediction horizon step. If you specify fewer than
*p* rows, the final bounds are used for the remaining steps of
the prediction horizon.

`StateFcnParameters`

— State function parameter values`[]`

(default) | vector`Model.ParameterLength`

property of the
multistage controller object. If `Model.StateFcn`

needs a
parameter vector, you must provide its value at runtime using this field. If
`Model.ParameterLength`

is `0`

this field does
not exist in the structure returned by
`getSimulationData`

.

`StageFcnParameters`

— Stage function parameter values`[]`

(default) | vectorStage functions parameter values, specified as a vector with length equal to
the sum of all the values in the `Stages(i).ParameterLength`

properties of the multistage controller object. If any cost or constraint function
defined in the `Stages`

property needs a parameter vector, you
must provide all the parameter vectors at runtime (stacked in a single column)
using this field. If none of your stage functions have parameters, this field does
not exist in the structure returned by
`getSimulationData`

.

You must stack the parameter vectors for all stages in the column vector
`StateFcnParameters`

as
follows.

[parameter vector for stage 1; parameter vector for stage 2; ... parameter vector for stage p+1; ]

`TerminalState`

— Terminal state`[]`

(default) | vectorTerminal state, specified as a column vector with as many elements as the
number of states. The terminal state is the desired state at the last prediction
step. To specify desired terminal states at run-time via this field, you must
specify finite values in the `TerminalState`

field of the
`Model`

property of `nlmpcMSobj`

. Specify
`inf`

for the states that do not need to be constrained to a
terminal value. At run time, `nlmpcmove`

ignores any values in the
`TerminalState`

field of `simdata`

that
correspond to `inf`

values in `nlmpcMSobj`

. If
you do not specify any terminal value condition in
`nlmpcMSobj`

, this field is not created in
`simdata`

.

If there is no `TerminalState`

in
`simdata`

then the terminal state constraint (if present)
does not change at run time.

`InitialGuess`

— Initial guesses for the decision variables`[]`

(default) | vectorInitial guesses for the decision variables, specified as a column vector of
length equal to the sum of the lengths of all the decision variable vectors for
each stage. Good initial guesses are important since they help the solver to
converge to a solution faster. Therefore, when simulating a control loop by
calling `nlmpcmove`

repeatedly in a loop, pass
`simdata`

as an input argument (so initial guesses can be
used), and at the same time return an updated version of
`simdata`

(with new initial guesses for the next control
interval) as an output argument.

You must be stack the initial guesses for all stages in the column vector
`InitialGuess`

as
follows.

[state vector guess for stage 1; manipulated variable vector guess for stage 1; manipulated variable vector rate guess for stage 1; % if used slack variable vector guess for stage 1; % if used state vector guess for stage 2; manipulated variable vector guess for stage 2; manipulated variable vector rate guess for stage 2; % if used slack variable vector guess for stage 2; % if used ... state vector guess for stage p; manipulated variable vector guess for stage p; manipulated variable vector rate guess for stage p; % if used slack variable vector guess for stage p; % if used state vector guess for stage p+1; slack variable vector guess for stage p+1; % if used ]

If `InitialGuess`

is `[]`

, the default
initial guesses are calculated from the `x`

and
`lastmv`

arguments passed to
`nlmpcmove`

.

In general, during closed-loop simulation, you do not specify
`InitialGuess`

yourself. Instead, when calling `nlmpcmove`

, return the `simdata`

output argument,
which contains the calculated initial guesses for the next control interval. You
can then pass `simdata`

as an input argument to
`nlmpcmove`

for the next control interval. These steps are a
best practice, even if you do not specify any other run-time options.

During closed-loop simulations, it is best practice to *warm start* the
nonlinear solver by using the predicted state and manipulated variable trajectories from the
previous control interval as the initial guesses for the current control interval. To use
these trajectories as initial guesses:

Return the

`opt`

output argument when calling`nlmpcmove`

. This`nlmpcmoveopt`

object contains any run-time options you specified in the previous call to`nlmpcmove`

, along with the initial guesses for the state (`opt.X0`

) and manipulated variable (`opt.MV0`

) trajectories.Pass this object in as the

`options`

input argument to`nlmpcmove`

for the next control interval.

These steps are a best practice, even if you do not specify any other run-time options.

You have a modified version of this example. Do you want to open this example with your edits?

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)