## QP Solvers

The model predictive controller QP solver converts a linear 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\le b$`

where

• x is the solution vector.

• H is the Hessian matrix. This matrix is constant when your prediction model and tuning weights do not change at run time.

• A is a matrix of linear constraint coefficients. This matrix is constant when your prediction model does not change at run time.

• b and f are vectors.

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

### Built-In QP Solvers

Model Predictive Control Toolbox™ software supports two built-in algorithms for solving the QP problem. Both solvers require the Hessian matrix to be positive definite.

• Active-set solver — This solver can provide fast and robust performance for small-scale and medium-scale optimization problems in both single and double precision. The active-set solver uses the KWIK algorithm from [1]. To use the active-set solver, set the `Optimizer.Algorithm` property of your MPC controller to `'active-set'`. To configure the algorithm settings, use the `Optimizer.ActiveSetOptions` property of your controller.

• Interior-point solver — This solver can provide superior performance for large-scale optimization problems, such as MPC applications that enforce constraints over large prediction and control horizons. This interior-point solver uses a primal-dual algorithm with a Mehrotra predictor-corrector. To use the interior-point solver, set the `Optimizer.Algorithm` property of your MPC controller to `'interior-point'`. To configure the algorithm settings, use the `Optimizer.InteriorPointOptions` property of your controller.

#### Solver Configuration

When selecting and configuring the QP solver for your application, consider the following:

• The size and configuration of the MPC problem affects the performance of the built-in QP solvers. To determine which solver is best for your application, consider simulating your controller across multiple simulation scenarios using both QP solvers.

• The interior-point solver is more sensitive to solver parameters than the active-set solver. Therefore, it can require more adjustment to find an optimal balance between performance and robustness.

• The active-set solver also uses a nonadjustable tolerance when testing for an optimal solution. You can adjust the optimality tolerances for the interior-point solver.

• One or more linear constraints can be violated slightly due to numerical round-off errors. Such violations are normal and do not generate warning messages. To adjust the tolerance for acceptable constraint violations, use the `ConstraintTolerance` setting for either the active-set or interior-point solver.

• The search for a QP solution is an iterative process. For either solver, you can specify the maximum number of iterations using the corresponding `MaxIterations` setting. If the number of iterations reaches the maximum, the algorithm terminates.

• The default maximum number of iterations for the active-set solver is $4\left({n}_{c}+{n}_{v}\right)$, where nc and nv are the number of constraints and optimization variables across the prediction horizon, respectively. For some controller configurations, this value can be very large, which can make the QP solver appear to stop responding. This value has a lower bound of `120`.

• The default maximum number of iterations for the interior-point solver is `50`.

• If your MPC problem includes hard constraints after conversion to a QP problem, the QP inequality constraints can be infeasible (impossible to satisfy). If the QP solver detects infeasibility, it terminates immediately.

When the solver detects an infeasible problem or reaches the maximum number of iterations without finding an optimal solution, the controller retains the last successful control output. For more information, see `mpcmove`. You can detect an abnormal outcome and override the default behavior as you see fit.

In the first control step, the QP solvers use 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 and the algorithm terminates. Otherwise, at least one of the linear inequality constraints must be satisfied as an equality, and the solver computes the optimal solution. For subsequent control steps:

• The active-set solver uses a warm start where the active constraint set determined in the previous control step becomes the initial guess.

• The interior-point solver continues to use a cold start.

#### 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 set a guaranteed 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 no greater than `10`.

`mpcobj.Optimizer.ActiveSetOptions.MaxIterations = 10;`

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

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, the MPC controller adjusts the solution such that it satisfies all your specified constraints.

There is no guarantee that the suboptimal solution performs better than if you hold 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 Applications

To access the QP solvers for applications that require solving online QP problems, use the `mpcActiveSetSolver` and `mpcInteriorPointSolver` functions, which are 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 solvers at each control interval. This option is useful for:

• Validating your simulation results or generating code with an in-house third-party solver that you trust.

• Applications where the built-in solvers do not provide satisfactory performance for your specific problem.

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.

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`

#### Custom Solver for Simulation

To simulate an MPC controller with a custom QP solver, perform the following steps.

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.

#### 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.

• To do so at the command line, you must have MATLAB Coder™ software.

To generate code for MPC controllers that use a custom QP solver, perform the following steps.

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.

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

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

• 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 Write C Functions Callable from MATLAB (MEX Files).

#### Custom Solver Function Implementation

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

• Custom solver for simulation:

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

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

For both simulation and code generation, 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 the 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 the 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 as shown in the following table.

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` might 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 constraints cannot be satisfied.
`-2`An unrecoverable numerical error occurred.

Note

The MPC controller expects the custom solver functions to solve the QP problem subject to the linear inequality constraints $Ax\ge b$. If your custom solver uses $Ax\le b$, you must change the sign of both `A` and `b` before passing them to your custom solver code.

### Use `quadprog` as Custom QP Solver

You can configure an MPC object to use the active-set solver available with the `quadprog` (Optimization Toolbox) function as a custom QP solver.

To automatically configure the MPC object `mpcobj` to use `quadprog` as custom QP solver for both simulation and code generation, you can use the `setCustomSolver` function. Specifically at the MATLAB command prompt, enter the following.

`setCustomSolver(mpcobj,'quadprog')`
This command generates, in the current folder, the files `mpcCustomSolver.m` and `mpcCustomSolverCodeGen.m`, which internally call `quadprog` (Optimization Toolbox). It then sets `mpcobj.Optimizer.CustomSolver` and `mpcobj.Optimizer.CustomSolverCodeGen` to `true`.

You can also further customize these functions, for example by adjusting the solver options, provided that you use the active-set solver (since other `quadprog` solvers are not supported for MPC problems).

To revert `mpcobj` back to use the built-in algorithm specified in `mpcobj.Optimizer.Algorithm` for both simulation and code generation, call `setCustomSolver` as follows.

`setCustomSolver(mpcobj,'quadprog')`
This command sets `mpcobj.Optimizer.CustomSolver` and `mpcobj.Optimizer.CustomSolverCodeGen` to `false`.

### Integration with FORCESPRO Solver

You can use FORCESPRO, a real-time embedded optimization software tool developed by Embotech AG, to simulate and generate code for an MPC controller designed using Model Predictive Control Toolbox software. Starting with FORCESPRO 2.0, Embotech provides a plugin that leverages the design capabilities of Model Predictive Control Toolbox software and the computational performance of FORCESPRO. Using the plugin, you can generate a custom QP solver that allows deployment on real-time hardware and is highly optimized based on your specific MPC problem to achieve satisfactory real-time performance. Especially long-horizon MPC problems can be solved very efficiently.

For information on using the FORCESPRO solver together with Model Predictive Control Toolbox software, see Implement MPC Controllers Using Embotech FORCESPRO Solvers.

## References

[1] Schmid, C., and L.T. Biegler. "Quadratic Programming Methods for Reduced Hessian SQP." Computers & Chemical Engineering 18, no. 9 (September 1994): 817–32. https://doi.org/10.1016/0098-1354(94)E0001-4.