By default, nonlinear MPC controllers solve a nonlinear programming problem using the
fmincon
function with the SQP algorithm, which requires Optimization
Toolbox™ software. If you do not have Optimization
Toolbox software, you can specify your own custom nonlinear solver.
For nonlinear MPC controllers at time t_{k}, the nonlinear optimization problem uses the following decision variables:
Predicted state values from time t_{k+1} to
t_{k+p}. These values correspond to rows 2
through p+1 of the X
input argument of your cost,
and constraint functions, where p is the prediction horizon.
Predicted manipulated variables from time
t_{k} to
t_{k+p1}. These values correspond to the
manipulated variable columns in rows 1 through p of the
U
input argument of your cost, and constraint functions.
Therefore, the number of decision variables N_{Z} is equal to p(N_{x}+N_{mv}) + 1, N_{x} is the number of states, N_{mv} is the number of manipulated variables, and the +1 is for the global slack variable.
A properly configured standard linear MPC optimization problem has a unique solution. However, nonlinear MPC optimization problems often allow multiple solutions (local minima), and finding a solution can be difficult for the solver. In such cases, it is important to provide a good starting point near the global optimum.
During closedloop simulations, it is best practice to warm start your nonlinear solver. To do so, use the predicted state and manipulated variable trajectories from the previous control interval as the initial guesses for the current control interval. In Simulink^{®}, the Nonlinear MPC Controller block is configured to use these trajectories as initial guesses by default. To use these trajectories as initial guesses at the command line:
Return the opt
output argument when calling nlmpcmove
.
This nlmpcmoveopt
object contains any runtime options you specified in the previous call to
nlmpcmove
. It also includes the initial guesses for the state
(opt.X0
) and manipulated variable (opt.MV0
)
trajectories, and the global slack variable (opt.Slack0
).
Pass this object in as the options
input argument to
nlmpcmove
for the next control interval.
These commandline simulation steps are best practices, even if you do not specify any other runtime options.
fmincon
OptionsBy default, nonlinear MPC controllers optimize their control move using the
fmincon
function from the Optimization
Toolbox. When you first create your controller, the
Optimization.SolverOptions
property of the nlmpc
object contains the standard fmincon
options with the following
nondefault settings:
Use the SQP
algorithm (SolverOptions.Algorithm =
'sqp'
)
Use objective function gradients (SolverOptions.SpecifyObjectiveGradient =
'true'
)
Use constraint gradients (SolverOptions.SpecifyConstraintGradient =
'true'
)
Do not display optimization messages to the command window
(SolverOptions.Display = 'none'
)
These nondefault options typically improve the performance of the nonlinear MPC controller.
You can modify the solver options for your application. For example, to specify the
maximum number of solver iterations for your application, set
SolverOptions.MaxIter
. For more information on the available solver
options, see fmincon
.
In general, you should not modify the SpecifyObjectiveGradient
and
SpecifyConstraintGradient
solver options, since doing so can
significantly affect controller performance. For example, the constraint gradient matrices
are sparse, and setting SpecifyConstraintGradient
to false would cause
the solver to calculate gradients that are known to be zero.
If you do not have Optimization Toolbox software, you can specify your own custom nonlinear solver. To do so, create a custom wrapper function that converts the interface of your solver function to match the interface expected by the nonlinear MPC controller. Your custom function must be a MATLAB^{®} script or MATfile on the MATLAB path. For an example that shows a template custom solver wrapper function, see Optimizing Tuberculosis Treatment Using Nonlinear MPC with a Custom Solver.
To configure your nlmpc
object to use your custom solver wrapper
function, set its Optimization.CustomSolverFcn
property in one of the
following ways:
Name of a function in the current working folder or on the MATLAB path, specified as a string or character vector
Optimization.CustomSolverFcn = "myNLPSolver";
Handle to a function in the current working folder or on the MATLAB path
Optimization.CustomSolverFcn = @myNLPSolver;
Your custom solver wrapper function must have the signature:
function [zopt,cost,flag] = myNLPSolver(FUN,z0,A,B,Aeq,Beq,LB,UB,NLCON)
This table describes the inputs and outputs of this function, where:
N_{Z} is the number of decision variables.
M_{cineq} is the number of linear inequality constraints.
M_{ceq} is the number of linear equality constraints.
N_{cineq} is the number of nonlinear inequality constraints.
N_{ceq} is the number of nonlinear equality constraints.
Argument  Input/Output  Description 

FUN  Input  Nonlinear cost function to minimize, specified as a handle to a function with the signature: [F,G] = FUN(z) and arguments:

z0  Input  Initial guesses for decision variable values, specified as a vector of length N_{Z} 
A  Input  Linear inequality constraint array, specified as an
M_{cineq}byN_{Z}
array. Together, A and B define constraints of
the form $$\text{A}\cdot z\le \text{B}$$. 
B  Input  Linear inequality constraint vector, specified as a column vector of length
M_{cineq}. Together, A
and B define constraints of the form $$\text{A}\cdot z\le \text{B}$$. 
Aeq  Input  Linear equality constraint array, specified as an
M_{ceq}byN_{Z}
array. Together, Aeq and Beq define
constraints of the form $$\text{Aeq}\cdot z=\text{Beq}$$. 
Beq  Input  Linear equality constraint vector, specified as a column vector of length
M_{ceq}. Together, Aeq
and Beq define constraints of the form $$\text{Aeq}\cdot z=\text{Beq}$$. 
LB  Input  Lower bounds for decision variables, specified as a column vector of length N_{Z}, where $$\text{LB}\left(i\right)\le z\left(i\right)$$. 
UB  Input  Upper bounds for decision variables, specified as a column vector of length N_{Z}, where $$z\left(i\right)\le \text{UB}\left(i\right)$$. 
NLCON  Input  Nonlinear constraint function, specified as a handle to a function with the signature: [cineq,c,Gineq,Geq] = NLCON(z) and arguments:

zopt  Output  Optimal decision variable values, returned as a vector of length N_{Z}. 
cost  Output  Optimal cost, returned as a scalar. 
flag  Output  Exit flag, returned as one of the following:

When you implement your custom solver function, it is best practice to have your solver use the cost and constraint gradient information provided by the nonlinear MPC controller.
If you are unable to obtain a solution using your custom solver, try to identify a special condition for which you know the solution, and start the solver at this condition. If the solver diverges from this initial guess:
Check the validity of the state and output functions in your prediction model.
If you are using a custom cost function, make sure it is correct.
If you are using the standard MPC cost function, verify the controller tuning weights.
Make sure that all constraints are feasible at the initial guess.
If you are providing custom Jacobian functions, validate your Jacobians using
validateFcns
.