Skip to main content

Linear time-variant model predictive control in Python.

Project description

qpmpc

CI Documentation Coverage Conda version PyPI version

Model predictive control (MPC) in Python for optimal-control problems that are quadratic programs (QP). This includes linear time-invariant (LTI) and time-variant (LTV) systems with linear constraints. The corresponding QP has the form:

\begin{array}{rl}
\underset{x_k, u_k}{\min} \quad & w_{t} \|x_N - x_{\mathit{goal}}\|_2^2 + w_x \sum_{k=0}^{N-1} \| x_k - x^{\mathrm{ref}}_k \|_2^2  + w_u \sum_{k=0}^{N-1} \| u_k - u^{\mathrm{ref}}_k \|^2_2 \\
\mathrm{s.t.} \quad & x_{k+1} = A_k x_k + B_k u_k \\
& C_k x_k + D_k u_k \leq e_k \\
& x_0 = x_{\mathit{init}}
\end{array}

This module is designed for prototyping. If you need performance, check out the alternatives below.

Installation

pip install qpmpc

Usage

This module defines a one-stop shop function:

solve_mpc(problem: MPCProblem, solver: str) -> Plan

The MPCProblem defines the model predictive control problem (LTV system, LTV constraints, initial state and cost function to optimize) while the returned Plan holds the state and input trajectories that result from optimizing the problem (if a solution exists). The solver string is used to select the backend quadratic programming solver.

Example

Let us define a triple integrator:

    import numpy as np

    horizon_duration = 1.0  # [s]
    N = 16  # number of discretization steps
    T = horizon_duration / N
    A = np.array([[1.0, T, T ** 2 / 2.0], [0.0, 1.0, T], [0.0, 0.0, 1.0]])
    B = np.array([T ** 3 / 6.0, T ** 2 / 2.0, T]).reshape((3, 1))

Suppose for the sake of example that acceleration is the main constraint acting on our system. We thus define an acceleration constraint |acceleration| <= max_accel:

    max_accel = 3.0  # [m] / [s] / [s]
    accel_from_state = np.array([0.0, 0.0, 1.0])
    C = np.vstack([+accel_from_state, -accel_from_state])
    e = np.array([+max_accel, +max_accel])

This leads us to the following linear MPC problem:

    from qpmpc import MPCProblem

    x_init = np.array([0.0, 0.0, 0.0])
    x_goal = np.array([1.0, 0.0, 0.0])
    problem = MPCProblem(
        transition_state_matrix=A,
        transition_input_matrix=B,
        ineq_state_matrix=C,
        ineq_input_matrix=None,
        ineq_vector=e,
        initial_state=x_init,
        goal_state=x_goal,
        nb_timesteps=N,
        terminal_cost_weight=1.0,
        stage_state_cost_weight=None,
        stage_input_cost_weight=1e-6,
    )

We can solve it with:

    from qpmpc import solve_mpc

    solution = solve_mpc(problem, solver="proxqp")

The solution holds complete state and input trajectories as stacked vectors. For instance, we can plot positions, velocities and accelerations as follows:

    import matplotlib.pyplot as plt

    t = np.linspace(0.0, horizon_duration, N + 1)
    X = solution.states
    positions, velocities, accelerations = X[:, 0], X[:, 1], X[:, 2]
    plt.ion()
    plt.plot(t, positions)
    plt.plot(t, velocities)
    plt.plot(t, accelerations)
    plt.grid(True)
    plt.legend(("position", "velocity", "acceleration"))

This example produces the following trajectory:

2022-03-30-172206_1920x1080_scrot

The behavior is a weighted compromise between reaching the goal state (weight 1.0) and keeping reasonable finite jerk inputs (weight 1e-6). The latter mitigate bang-bang accelerations but prevent fully reaching the goal within the horizon. See the examples folder for more examples.

Areas of improvement

This module is incomplete with regards to the following points:

  • Cost functions: can be extended to general linear stage cost functions
  • Documentation: there are some undocumented functions
  • Test coverage: only one end-to-end test

Check out the contribution guidelines if you are interested in lending a hand.

Alternatives

You can also check out the following open-source libraries:

Linear model predictive control

Name Systems Languages License
Copra (LTV fork) Linear time-variant C++, Python BSD-2-Clause
Copra (original) Linear time-invariant C++, Python BSD-2-Clause
mpc-interface Linear time-variant C++, Python BSD-2-Clause
pyMPC Linear time-variant Python MIT

Nonlinear model predictive control

Name Systems Languages License
acados Nonlinear C++, Matlab, Python BSD-2-Clause
Aligator Nonlinear C++, Python BSD-2-Clause
Crocoddyl Nonlinear C++, Python BSD-3-Clause

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

qpmpc-3.2.0.tar.gz (170.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

qpmpc-3.2.0-py3-none-any.whl (20.8 kB view details)

Uploaded Python 3

File details

Details for the file qpmpc-3.2.0.tar.gz.

File metadata

  • Download URL: qpmpc-3.2.0.tar.gz
  • Upload date:
  • Size: 170.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-requests/2.32.4

File hashes

Hashes for qpmpc-3.2.0.tar.gz
Algorithm Hash digest
SHA256 9263eb0dba4a8cb8358c600e8550b7066bed7e3be71d21280b0627395bad3e98
MD5 7d658695dc4579086cb4b06c26a610e9
BLAKE2b-256 befef55b565113d4e8047aac6636b5dea3687d7c7ee34802cd52c4c7aa86768e

See more details on using hashes here.

File details

Details for the file qpmpc-3.2.0-py3-none-any.whl.

File metadata

  • Download URL: qpmpc-3.2.0-py3-none-any.whl
  • Upload date:
  • Size: 20.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-requests/2.32.4

File hashes

Hashes for qpmpc-3.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 55cc0161555ffe9c09450cbeca0be14be1a72135ce8e8c92adef1449f917b5e8
MD5 c6218866def68176ea45ec9a45c34aaf
BLAKE2b-256 d65653077db6069ec5ae3f73416926c6ea7ae1ff726c23e81bc207354638957e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page