While the existing interfaces for FORCES Pro for generation of fast optimization solvers are very powerful, the number of exposed options can be overwhelming especially for new users that just need a fast solver for a standard problem. To ease the way into the wonderful world of embedded optimization we will over time be adding simple interfaces for certain standard problem classes. Initially, these interface will only be available in the MATLAB® client, which is used by most FORCES Pro users.

**Simple, yet fast:** While these interfaces are easy to use and do not burden you with unnecessary flexibility, they will still generate the most efficient optimization algorithm for your problem. Internally, our other interfaces are used, so you are not paying in terms of computation speed and can still expect the highest performance. Naturally, all generated solvers are still embeddable everywhere.

**Adjustable and open**: If these simple interfaces do not quite match your requirements, do not fret. We ship the standard MPC interfaces as MATLAB® source code, so you can look how we generate the solver and what options we use. Then you can use that as a baseline to make the necessary changes to meet your needs. Also feel free to send us an e-mail to info@embotech.com and let us know what you think.

**Easily extensible:** Additionally, all simple interfaces have a debug parameter you can use to skip code-generation and instead obtain the FORCES Pro structures used to generate the solver in question. These you can modify to your heart's content and hand to the appropriate code-generation function (`generateCode` for the low-level interface or `FORCES_NLP` for the high-level interface) after implementing your changes.

The `SimpleRegulationMPC` interface for FORCES Pro generates a model predictive controller for probably the most fundamental control problem: regulating a linear time-invariant system to the origin. The corresponding optimization problem has the following form:

$$ \begin{align} \text{minimize} \quad \frac{1}{2} & x_N^T P x_N +\frac{1}{2} \sum_{i=0}^{N-1} \left( x_i^T Q x_i + u_i^T R u_i \right) & & \text{(standard regulation objective)}\\ \text{subject to} \quad x_0 & = \hat{x}_0 && \text{(initial state)} \\ x_{i+1} &= A_{i} x_{i} + B_{i} u_{i} && \text{(linear discrete-time dynamics)} \\ \underline{x} &\leq x_{i+1} \leq \bar{x} && \text{(state bounds)}\\ \underline{u} &\leq u_i \leq \bar{u} && \text{(input bounds)} \end{align}$$ for \(i=0,…,N-1\).

To obtain a solver for this control problem, the function `SimpleRegulationMPC` expects the following input parameters:

**System dynamics:** Store the system matrices \(A\) and \(B\) in a structure with the fields `A` and `B`, e.g. `system = struct('A', [1 1; 0 1], 'B', [0; 1])`. Note that this interface can only be used for discrete-time LTI systems. For time-varying dynamics you can use the powerful parametric capabilities of the low-level interface for FORCES Pro as outlined in our LTV example.

**Quadratic cost function:** The quadratic cost matrices \(Q\) and \(R\) are required and have to be symmetric positive semi-definite and symmetric positive definite, respectively. Store them in a structure with the fields `Q` and `R`, e.g. `objective = struct('Q', diag([10 1]), 'R', 1)`. You can use these matrices to tune the control performance by trading off control effort against control speed, e.g. larger values for \(R\) mean a less aggressive controller. You can also provide a dedicated terminal cost matrix \(P\) by populating a field `objective.P` with a symmetric positive semi-definite matrix. If that field is missing or empty, the value for \(Q\) is used instead. Finally, if you have access to the Control System Toolbox™ for MATLAB® you can set `objective.computeTerminalCost = true` to have a suitable terminal cost matrix be computed automatically.

**Bounds:** Simple lower and upper bounds on system states (\(\underline{x}\) and \(\bar{x}\)) and control inputs (\(\underline{u}\) and \(\bar{u}\)) can be provided in a structure with fields `xmin`, `xmax`, `umin`, and `umax`. If any of these fields is missing the corresponding variable is assumed to be unbounded. If a scalar value is provided it is used for all entries of the corresponding vector. Consider the following example that may not be realistic, but exemplifies all options for this parameter:

`bounds = struct('xmin', -5, 'xmax', [2; inf], 'umin', -2);`

This structure bounds all system states from below by -5, the first system state from above by 2, and the control input from below by -2. The second system state and the control input are unbounded from above.

**Prediction horizon:** The fourth input parameter is simply a positive integer scalar that specifies the prediction horizon \(N\).

**Solver name (optional):** You can specify a name to be used for the generated solver by passing a string as the fifth argument to `SimpleRegulationMPC`. Pass an empty array (`[]`) in case you do not want to specify a name but want to pass one of the input parameters below.

**User options (optional):** If you want to adjust the options used by FORCES Pro for code-generation of the solver, you can specify them in a structure as the sixth input parameter. You can use all options that are available in the low-level interface for FORCES Pro, e.g. to suppress all outputs of the solver generated by `SimpleRegulationMPC` just pass in `struct('printlevel', 0)`. Pass an empty array (`[]`) in case you want to use standard options but want to pass one of the input parameters below.

**Skip code-generation (optional):** If you do not want to generate a solver but use `SimpleRegulationMPC` to generate the structures necessary for code-generation, e.g. because you want to modify them to fit your application or investigate them for debugging purposes, you can pass in `true` as the seventh and final parameter.

`SimpleRegulationMPC` generates a solver for the problem you specified, the corresponding files will appear after code-generation in your working directory. Additionally, the function returns the following output parameters:

**Controller function:** To simplify use of the generated solver in MPC applications, the first return parameter is a MATLAB function handle that takes the current system state, calls the generated solver with that initial state value, and returns the corresponding optimal control input:

`controller = SimpleRegulationMPC(system, objective, bounds, N);`

`[ uopt, exitflag, info ] = controller(x0);`

Note the additional return values of `controller` which indicate whether solving the MPC optimization problem was successful (`exitflag` should be 1) and provide additional information about the result, e.g. `info.pobj` contains the objective function value at the solution. For details refer to the low-level interface documentation.

**Code-generation structures:** If you want to investigate what is passed to FORCES Pro to generate the solver you requested, you can investigate the return parameters two to five, modify them to match your needs, and call `generateCode` with these structures:

`[ controller, stages, params, codeopts, outputs ] = SimpleRegulationMPC(..., true);`
`generateCode(stages, params, codeopts, outputs);`

Note that in this case, the `controller` return parameter is empty.

**Stability**: Note that the presence of *just* a terminal cost does not guarantee stability of the closed-loop system, no matter how \(P\) is chosen. In general you will also need a suitable terminal constraint set which this interface does not expose, i.e. you have to compute it yourself and add it to the `stages` output parameter (see above). For details on stability of constrained MPC you can check out this classic reference:

D.Q. Mayne, J.B. Rawlings, C.V. Rao, P.O.M. Scokaert, Constrained model predictive control: Stability and optimality, *Automatica*, Volume 36, Issue 6, June 2000, Pages 789-814, DOI: 10.1016/S0005-1098(99)00214-9.

**Feasibility**: Because you are solving a constrained control problem it is not guaranteed that a solution can be found for all initial states. Hence, it is crucial that you always check the `exitflag` provided as the second return value of the generated controller.