Documentation

## QP Solver

The model predictive controller QP solver converts an MPC optimization problem to the general form QP problem

`$\underset{x}{Min}\left(\frac{1}{2}{x}^{⊺}Hx+{f}^{⊺}x\right)$`

subject to the linear inequality constraints

`$Ax\ge b$`

where

• x is the solution vector.

• H is the Hessian matrix. This matrix is constant when using implicit MPC without online weight changes.

• A is a matrix of linear constraint coefficients. This matrix is constant when using implicit MPC.

• b and f are vectors.

At the beginning of each control interval, the controller computes H, f, A, and b or, if they are constant, retrieves their precomputed values.

The toolbox uses the KWIK algorithm [1] to solve the QP problem, which requires the Hessian to be positive definite. In the first control step, KWIK uses a cold start, in which the initial guess is the unconstrained solution described in Unconstrained Model Predictive Control. If x satisfies the constraints, it is the optimal QP solution, x*, and the algorithm terminates. Otherwise, at least one of the linear inequality constraints must be satisfied as an equality. In this case, KWIK uses an efficient, numerically robust strategy to determine the active constraint set satisfying the standard optimization conditions. In the following control steps, KWIK uses a warm start. In this case, the active constraint set determined at the previous control step becomes the initial guess for the next.

Although KWIK is robust, consider the following:

• One or more linear constraints can be violated slightly due to numerical round-off errors. The toolbox employs a nonadjustable relative tolerance. This tolerance allows constraint violations of 10-6 times the magnitude of each term. Such violations are considered normal and do not generate warning messages.

• The toolbox also uses a nonadjustable tolerance when testing for an optimal solution.

• The search for the active constraint set is an iterative process. If the iterations reach a problem-dependent maximum, the algorithm terminates. For some controller configurations, the default maximum iterations can be very large, which can make the QP solver appear to stop responding (see Optimizer).

• If your problem includes hard constraints, these constraints can be infeasible (impossible to satisfy). If the algorithm detects infeasibility, it terminates immediately.

In the last two situations, with an abnormal outcome to the search, the controller retains the last successful control output. For more information, see, the `mpcmove` command. You can detect an abnormal outcome and override the default behavior as you see fit.

### Suboptimal QP Solution

For a given MPC application with constraints, there is no way to predict how many QP solver iterations are required to find an optimal solution. Also, in real-time applications the number of iterations can change dramatically from one control interval to the next. In such cases, the worst-case execution time can exceed the limit that is allowed on the hardware platform and determined by controller sample time.

You can guarantee the worst-case execution time for your MPC controller by applying a suboptimal solution after the number of optimization iterations exceeds a specified maximum value. To set the worst-case execution time, first determine the time needed for a single optimization iteration by experimenting with your controller under nominal conditions. Then, set an upper bound on the number of iterations per control interval. For example, if it takes around 1 ms to compute each iteration on the hardware and the controller sample time is 10 ms, set the maximum number of iterations to be no greater than `10`.

`MPCobj.Optimizer.MaxIter = 10;`

By default, an MPC controller object has a lower bound of `120` on the maximum number of iterations.

By default, when the solver reaches the maximum number of solver iterations without an optimal solution, the controller holds the manipulated variables at their previous values. To use the suboptimal solution reached after the final iteration, set the `UseSuboptimalSolution` option to `true`.

`MPCobj.Optimizer.UseSuboptimalSolution = true;`

While the solution is not optimal, when applied, it satisfies all your specified constraints.

There is no guarantee that the suboptimal solution performs better than holding the controller output constant. You can simulate your system using both approaches, and select the configuration that provides better controller performance.

For an example, see Use Suboptimal Solution in Fast MPC Applications.

### Custom QP Application

To access the built-in KWIK solver for applications that require solving online QP problems, use the `mpcqpsolver` command. This option is useful for:

• Advanced MPC applications that are beyond the scope of Model Predictive Control Toolbox™ software.

• Custom QP applications, including applications that require code generation.

### Custom QP Solver

Model Predictive Control Toolbox software lets you specify a custom QP solver for your MPC controller. This solver is called in place of the built-in `qpkwik` solver at each control interval. This option is useful for:

• Validating your simulation results or generating code with a third-party solver.

• Large MPC problems where the built-in KWIK solver runs slowly or fails to find a feasible solution.

You can define a custom solver for simulation or for code generation. In either instance, you define the custom solver using a custom function and configure your controller to use this custom function.

Custom Solver FunctionAffected MATLAB® FunctionsAffected Simulink® Blocks

Simulation

Set `Optimizer.CustomSolver` to `true`.

`Optimizer.CustomSolverCodeGen` is ignored.

`mpcCustomSolver.m`

Supports:

• MATLAB code

• MEX files

• `sim`

• `mpcmove`

• `mpcmoveAdaptive`

• `mpcmoveMultiple`

• `mpcmoveCodeGeneration`

• MPC Controller

• Multiple MPC Controllers

Code Generation

Set `Optimizer.CustomSolverCodeGen` to `true`.

`Optimizer.CustomSolver` is ignored.

`mpcCustomSolverCodeGen.m`

Supports:

• MATLAB code suitable for code generation

• C/C++ code

• `mpcMoveCodeGeneration`

#### Implement Custom Solver for Simulation

To simulate an MPC controller with a custom QP solver:

1. Copy the solver template file to your working folder or anywhere on the MATLAB path, and rename it `mpcCustomSolver.m`. To copy the solver template to your current working folder, type the following at the MATLAB command line.

```src = which('mpcCustomSolver.txt'); dest = fullfile(pwd,'mpcCustomSolver.m'); copyfile(src,dest,'f');```
2. Modify `mpcCustomSolver.m` by adding your own custom solver. Your solver must be able to run in MATLAB and be implemented in a MATLAB script or MEX-file.

3. Configure your MPC controller `MPCobj` to use the custom solver.

`MPCobj.Optimizer.CustomSolver = true;`

The software now uses your custom solver for simulation in place of the built-in QP KWIK solver.

For an example, see Simulate MPC Controller with a Custom QP Solver.

#### Implement Custom Solver for Code Generation

You can generate code for MPC controllers that use a custom QP solver written in either C/C++ code or MATLAB code suitable for code generation. Doing so:

• At the command line requires MATLAB Coder™ software.

To generate code for MPC controllers that use a custom QP solver:

1. Copy the solver template file to your working folder or anywhere on the MATLAB path, and rename it `mpcCustomSolverCodeGen.m`. To copy the MATLAB code template to your current working folder, type the following at the MATLAB command line.

```src = which('mpcCustomSolverCodeGen_TemplateEML.txt'); dest = fullfile(pwd,'mpcCustomSolverCodeGen.m'); copyfile(src,dest,'f');```

Alternatively, you can use the C template.

```src = which('mpcCustomSolverCodeGen_TemplateC.txt'); dest = fullfile(pwd,'mpcCustomSolverCodeGen.m'); copyfile(src,dest,'f');```
2. Modify `mpcCustomSolverCodeGen.m` by adding your own custom solver.

3. Configure your MPC controller `MPCobj` to use the custom solver.

`MPCobj.Optimizer.CustomSolverCodeGen = true;`

The software now uses your custom solver for code generation in place of the built-in QP KWIK solver.

4. Generate code for the controller. For more information, see Generate Code and Deploy Controller to Real-Time Targets.

For an example, see Simulate and Generate Code for MPC Controller with Custom QP Solver.

#### Implement Custom Solver for Simulation and Code Generation

You can implement the same custom QP solver for both simulation and code generation. To do so, you must:

• Set both `Optimizer.CustomSolver` and `Optimizer.CustomSolverCodeGen` to `true`.

• Create both `mpcCustomSolver.m` and `mpcCustomSolverCodeGen.m`.

During simulation, your controller uses the `mpcCustomSolver.m` custom function. For code generation, your controller uses the `mpcCustomSolverCodeGen.m` custom function.

You can specify the same MATLAB code in both custom solver functions, provided the code is suitable for code generation.

If you implement `mpcCustomSolverCodeGen.m` using C/C++ code, create a MEX file using the code. You can then call this MEX file from `mpcCustomSolver.m`. For more information on creating and using MEX files, see C MEX File Applications (MATLAB).

#### Custom Solver Argument Descriptions

When you implement a custom QP solver, your custom function must have one of the following signatures:

• When using a custom solver for simulation:

`function [x,status] = mpcCustomSolver(H,f,A,b,x0)`
• When using a custom solver for code generation:

`function [x,status] = mpcCustomSolverCodeGen(H,f,A,b,x0)`

In both cases, your custom solver has the following input and output arguments:

• `H` is a Hessian matrix, specified as an n-by-n symmetric positive definite matrix, where n is the number of optimization variables.

• `f` is the multiplier of objective function linear term, specified as a column vector of length n.

• `A` is a matrix of linear inequality constraint coefficients, specified as an m-by-n matrix, where m is the number of constraints.

• `b` is the right side of inequality constraint equation, specified as a column vector of length m.

• `x0` is an initial guess for the solution, specified as a column vector of length n.

• `x` is the optimal solution, returned as a column vector of length n.

• `status` is a solution validity indicator, returned as an integer according to the following:

ValueDescription
`> 0``x` is optimal. `status` represents the number of iterations performed during optimization.
`0`

The maximum number of iterations was reached without finding an optimal solution. The solution, `x`, may be suboptimal or infeasible.

If the `Optimizer.UseSuboptimalSolution` property of your controller is `true`, the controller uses the suboptimal solution in `x` when `status` is `0`.

`-1`The problem appears to be infeasible, that is, the constraint $Ax\ge b$ cannot be satisfied.
`-2`An unrecoverable numerical error occurred.

## References

[1] Schmid, C. and L.T. Biegler, "Quadratic programming methods for reduced Hessian SQP," Computers & Chemical Engineering, Vol. 18, Number 9, 1994, pp. 817–832.