|     |  
Search
Register
Register
Login
Login
embotech
Menu
  • News
  • Automotive
  • Energy
  • Space
  • FORCES Pro
    • Request License
    • Installation
    • License Terms
    • User Manual
      • Y2F: Yalmip interface
      • High-level Interface
        • Integrators
        • Declaring Outputs
        • Solver Options
        • Solver Info
        • Simple MPC Example
      • Graphical Interface
        • Simple MPC Example
        • Simulink Block
      • Standard MPC interfaces
      • Low-level Interface
        • Parametric Problems
        • Declaring Outputs
        • Solver Options
        • Solver Info
        • Simple MPC Example
    • Code Deployment
    • Examples
    • FAQ
  • References
    • Vestas
    • Alstom
    • ABB Corporate Research
    • RWTH Aachen (IRT, VKA)
  • Jobs
    • SOFTWARE QUALITY ASSURANCE ENGINEER
    • MOTION PLANNING SOFTWARE ENGINEER
    • SOFTWARE DEVELOPMENT INTERNSHIP
  • Company
    • Contact
    • History

Low-level Interface

FORCES Pro  /  User Manual  /  Low-level Interface
  • News
  • Automotive
  • Energy
  • Space
  • FORCES Pro
    • Request License
    • Installation
    • License Terms
    • User Manual
      • Y2F: Yalmip interface
      • High-level Interface
        • Integrators
        • Declaring Outputs
        • Solver Options
        • Solver Info
        • Simple MPC Example
      • Graphical Interface
        • Simple MPC Example
        • Simulink Block
      • Standard MPC interfaces
      • Low-level Interface
        • Parametric Problems
        • Declaring Outputs
        • Solver Options
        • Solver Info
        • Simple MPC Example
    • Code Deployment
    • Examples
    • FAQ
  • References
    • Vestas
    • Alstom
    • ABB Corporate Research
    • RWTH Aachen (IRT, VKA)
  • Jobs
    • SOFTWARE QUALITY ASSURANCE ENGINEER
    • MOTION PLANNING SOFTWARE ENGINEER
    • SOFTWARE DEVELOPMENT INTERNSHIP
  • Company
    • Contact
    • History

Fast Convex Solvers and Predictive Controllers in MATLAB and Python

FORCES Pro supports designing solvers and controllers via MATLAB® and Python scripts. Regardless of the language used, a Simulink® block is always created such that you can plug your advanced formulation directly into your simulation models, or download it to a real-time target platform. Click here for further details on how to deploy the generated solver on an embedded target.

This low-level interface gives advanced optimization users the full flexibility when designing custom optimization solvers and MPC controllers based on non-standard formulations. For help in deciding which interface to use click here.

 

Supported Problem Class

The FORCES Pro low-level interface supports the class of convex multistage quadratically constrained programs (QCQPs) of the form

$$ \begin{align} \text{minimize} \ \ & \sum_{i=1}^N \frac{1}{2} z_i^T H_i z_i + f_i^T z_i & & \text{(separable objective)}\\
\text{subject to} \ \ & D_1 z_1 = c_1 && \text{(initial equality)} \\
& C_{i-1} z_{i-1} + D_{i} z_{i} = c_{i} && \text{(inter-stage equality)} \\
& \underline{z}_i \leq z_i && \text{(lower bounds)}\\
& z_i \leq \bar{z}_i && \text{(upper bounds)}\\
& A_i z_i \leq b_i && \text{(polytopic inequalities)}\\
& z_i^T Q_{i,k} z_i + L_{i,k}^T z_i \leq r_{i,k} && \text{(quadratic inequalities)}
\end{align}$$ for \(i=1,…,N\) and \(k=1,…,M\). To obtain a solver for this optimization problem using the FORCES Pro client, you need to define all data in the problem (the matrices \(H_i\), \(A_i\), \(Q_{i,j}\), \(D_i\), \(C_i\) and the vectors \( \underline{z}_i \),   \( \bar{z}_i \), \( b_i \), \( L_{i,k} \), \( r_{i,k} \), \( c_{i} \) ) in a MATLAB® struct or Python dictionary, along with the corresponding dimensions. The following steps will take you through this process. See also Simple MPC Example for a minimalistic example.

Note: FORCES Pro supports all problem data to be parametric, i.e. to be unknown at code generation time. Read Parametric Problems to learn how to use parameters correctly.

Expressing the Optimization Problem in MATLAB or Python

In the following, we describe how to model a problem of the above form with FORCES Pro. First make sure that the FORCES Pro client is on the MATLAB/Python path. Click here for more details. 

Python users first have to import the FORCES Pro module. 

from forcespro import *

Multistage struct

First, an empty struct/class has to be initialized, which contains all fields needed and initialises matrices and vectors to empty matrices. The command

  • Matlab
  • Python
stages = MultistageProblem(N);
stages = MultistageProblem(N)

creates such an empty structure/class of length \(N\). Once this structure/class has been created, the corresponding matrices, vectors and dimensions can be set for each element of stages.

Dimensions

In order to define the dimensions of the stage variables \(z_i\), the number of lower and upper bounds, the number of polytopic inequality constraints and the number of quadratic constraints use the following fields:

  • Matlab
  • Python
stages(i).dims.n = ...; % length of stage variable zi
stages(i).dims.r = ...; % number of equality constraints
stages(i).dims.l = ...; % number of lower bounds
stages(i).dims.u = ...; % number of upper bounds
stages(i).dims.p = ...; % number of polytopic constraints
stages(i).dims.q = ...; % number of quadratic constraints
stages.dims[ i ]['n'] = ... # length of stage variable zi
stages.dims[ i ]['r'] = ... # number of equality constraints
stages.dims[ i ]['l'] = ... # number of lower bounds
stages.dims[ i ]['u'] = ... # number of upper bounds
stages.dims[ i ]['p'] = ... # number of polytopic constraints
stages.dims[ i ]['q'] = ... # number of quadratic constraints

Cost function

The cost function is, for each stage, defined by the matrix \(H_i\) and the vector \(f_i\). These can be set by

  • Matlab
  • Python
stages(i).cost.H = ...; % Hessian
stages(i).cost.f = ...; % linear term
stages.cost[i]['H'] = ... # Hessian
stages.cost[i]['f'] = ... # linear term

Note: whenever one of these terms is zero, you have to set them to zero (otherwise the default of an empty matrix is assumed, which is different from a zero matrix).

Equality Constraints

The equality constraints for each stage, which are given by the matrices \(C_i\), \(D_i\) and the vector \(c_i\), have to be provided in the following form:

  • Matlab
  • Python
stages(i).eq.C = ...;
stages(i).eq.c = ...;
stages(i).eq.D = ...;
stages.eq[ i ]['C'] = ...
stages.eq[ i ]['c'] = ...
stages.eq[ i ]['D'] = ...

Lower and upper bounds

Lower and upper bounds have to be set in sparse format, i.e. an index vector lbIdx/ubIdx that defines the elements of the stage variable \(z_i\) has to be provided, along with the corresponding upper/lower bound lb/ub:

  • Matlab
  • Python
stages(i).ineq.b.lbidx = ...; % index vector for lower bounds
stages(i).ineq.b.lb = ...;    % lower bounds
stages(i).ineq.b.ubidx = ...; % index vector for upper bounds
stages(i).ineq.b.ub = ...;    % upper bounds
stages.ineq[ i ]['b']['lbidx'] = ... # index vector for lower bounds
stages.ineq[ i ]['b']['lb'] = ...    # lower bounds
stages.ineq[ i ]['b']['ubidx'] = ... # index vector for upper bounds
stages.ineq[ i ]['b']['ub'] = ...    # upper bounds

Both lb and lbIdx must have length stages(i).dims.l / stages.dims[ i ]['l'], and both ub and ubIdx must have length stages(i).dims.u / stages.dims[ i ]['u'].

Polytopic constraints

In order to define the inequality \(A_i z_i \leq b_i \), use

  • Matlab
  • Python
stages(i).ineq.p.A = ...; % Jacobian of linear inequality
stages(i).ineq.p.b = ...; % RHS of linear inequality
stages.ineq[ i ]['A'] = ... # Jacobian of linear inequality
stages.ineq[ i ]['b'] = ... # RHS of linear inequality

The matrix A must have stages(i).dims.p / stages.dims[ i ]['p'] rows and stages(i).dims.n / stages.dims[ i ]['n'] columns. The vector b must have stages(i).dims.p / stages.dims[ i ]['p'] rows.

Quadratic constraints

Similar to lower and upper bounds, quadratic constraints are given in sparse form by means of an index vector, which determines on which variables the corresponding quadratic constraint acts. 

  • Matlab
  • Python
stages(i).ineq.q.idx = { idx1, idx2, …}; % index vectors
stages(i).ineq.q.Q = { Q1, Q2, …}; % Hessians
stages(i).ineq.q.l = { L1, L2, …}; % linear terms
stages(i).ineq.q.r = [ r1; r2; … ]; % RHSs
stages.ineq[ i ]['q']['idx'] = ... # index vectors
stages.ineq[ i ]['q']['Q'] = ... # Hessians
stages.ineq[ i ]['q']['l'] = ... # linear terms
stages.ineq[ i ]['q']['r'] = ... # RHSs

If the index vector idx1 has length \(m_1\), then the matrix Q must be square and of size \(m_1 \times m_1\), the column vector l1 must be of size \(m_1\) and r1 is a scalar. Of course this dimension rules apply to all further quadratic constraints that might be present. Note that \(L1\), \(L2\) etc. are column vectors in MATLAB!

Since multiple quadratic constraints can be present per stage, in MATLAB we make use of the cell notation for the Hessian, linear terms, and index vectors. In Python we make use of Python object arrays for the Hessians, linear terms, and index vectors.
 
Example

To express the two quadratic constraints $$ \begin{align} z_{3,3}^2 + 2z_{3,5}^2 - z_{3,5} &\leq 3 \\ 5z_{3,1}^2 &\leq 1 \end{align} $$ on the third stage variable, use the code

  • Matlab
  • Python
stages(3).ineq.q.idx = { [3 5], [1] } % index vectors
stages(3).ineq.q.Q = { [1 0; 0 2], [5] }; % Hessians
stages(3).ineq.q.l = { [0; -1], [0] }; % linear terms
stages(3).ineq.q.r = [ 3; 1 ]; % RHSs

stages.ineq[3-1]['q']['idx'] = np.zeros((2,), dtype=object) % index vectors
stages.ineq[3-1]['q']['idx'][0] = np.array([3,5])
stages.ineq[3-1]['q']['idx'][1] = np.array([1])
stages.ineq[3-1][
'q']['Q'] = np.zeros((2,), dtype=object) % Hessians
stages.ineq[3-1][
'q']['Q'][0] = np.array([1.0 0],[0 2.0])
stages.ineq[3-1][
'q']['Q'][1] = np.array([5])
stages.ineq[3-1][
'q']['l'] = np.zeros((2,), dtype=object) % linear terms
stages.ineq[3-1][
'q']['l'][0] = np.array([0], [-1])
stages.ineq[3-1][
'q']['l'][1] = np.array([0])
stages.ineq[3-1][
'q']['r'] = np.array([3],[1]) % RHSs 

Binary Constraints

To declare binary variables, you can use the bidx field of the stages struct or object. For example, the following code declares variables 3 and 7 of stage 1 to be binary:

  • Matlab
  • Python
stages(1).bidx = [3 7]
stages.bidx[1] = np.array([3, 7])

 

That's it! You can now generate a solver that will take into account the binary constraints on these variables. If binary variables are declared, FORCES Pro will add a branch-and-bound procedure to the standard convex solver it generates. 

About Us

embotech, short for embedded optimization technologies, was founded in September 2013. We strive to lead the market for numerical optimization solutions that will be integral part of tomorrow's decision making systems. The company is a spin-off of the Automatic Control Laboratory from ETH Zurich.

Contact Us

We are located at Technopark Zurich, 10 minutes from Zurich main station and 20 minutes from Zurich International Airport.

  Technoparkstrasse 1
CH-8005 Zurich

  info@embotech.com
  CHE-195.606.420

Email Us

Supported by

News Automotive Energy Space FORCES Pro References Jobs Company
Copyright 2013-2018 by embotech AG | Privacy Statement | Terms Of Use