Name | qpmpc JSON |
Version |
3.0.1
JSON |
| download |
home_page | None |
Summary | Linear time-variant model predictive control in Python. |
upload_time | 2023-12-21 14:34:57 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.8 |
license | None |
keywords |
model
predictive
control
linear
time-varying
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# qpmpc
[![Build](https://img.shields.io/github/actions/workflow/status/stephane-caron/qpmpc/build.yml?branch=main)](https://github.com/stephane-caron/qpmpc/actions)
[![Coverage](https://coveralls.io/repos/github/stephane-caron/qpmpc/badge.svg?branch=main)](https://coveralls.io/github/stephane-caron/qpmpc?branch=main)
[![Documentation](https://img.shields.io/badge/docs-online-brightgreen?logo=read-the-docs&style=flat)](https://scaron.info/doc/qpmpc/)
[![PyPI version](https://img.shields.io/pypi/v/qpmpc)](https://pypi.org/project/qpmpc/0.6.0/)
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:
> ![qpmpc](https://raw.githubusercontent.com/stephane-caron/qpmpc/main/doc/src/images/qpmpc.svg)
This module is designed for prototyping. If you need performance, check out the [alternatives](#alternatives) below.
## Installation
```sh
pip install qpmpc
```
## Usage
This module defines a one-stop shop function:
```python
solve_mpc(problem: MPCProblem, solver: str) -> Plan
```
The [``MPCProblem``](https://scaron.info/doc/qpmpc/usage.html#qpmpc.mpc_problem.MPCProblem) defines the model predictive control problem (LTV system, LTV constraints, initial state and cost function to optimize) while the returned [``Plan``](https://tasts-robots.org/doc/qpmpc/usage.html#qpmpc.plan.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](https://github.com/stephane-caron/qpsolvers#solvers).
## Example
Let us define a triple integrator:
```python
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``:
```python
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:
```python
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:
```python
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:
```python
import pylab
t = np.linspace(0.0, horizon_duration, N + 1)
X = solution.states
positions, velocities, accelerations = X[:, 0], X[:, 1], X[:, 2]
pylab.ion()
pylab.plot(t, positions)
pylab.plot(t, velocities)
pylab.plot(t, accelerations)
pylab.grid(True)
pylab.legend(("position", "velocity", "acceleration"))
```
This example produces the following trajectory:
![2022-03-30-172206_1920x1080_scrot](https://user-images.githubusercontent.com/1189580/160871543-3734ec65-fe74-4a6f-8452-a877aa4050b1.png)
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](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](CONTRIBUTING.md) if you are interested in lending a hand.
## Alternatives
This module is designed for faster prototyping rather than performance. You can also check out the following open-source libraries:
| Name | Systems | Languages | License |
|------------------------------------------------------------|-----------------------|------------|--------------|
| [Copra (LTV fork)](https://github.com/ANYbotics/copra) | Linear time-variant | Python/C++ | BSD-2-Clause |
| [Copra (original)](https://github.com/jrl-umi3218/copra) | Linear time-invariant | Python/C++ | BSD-2-Clause |
| [Crocoddyl](https://github.com/loco-3d/crocoddyl) | Nonlinear | Python/C++ | BSD-3-Clause |
| [mpc-interface](https://github.com/Gepetto/mpc-interface) | Linear time-variant | Python/C++ | BSD-2-Clause |
| [pyMPC](https://github.com/forgi86/pyMPC) | Linear time-variant | Python | MIT |
Raw data
{
"_id": null,
"home_page": null,
"name": "qpmpc",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": "St\u00e9phane Caron <stephane.caron@normalesup.org>",
"keywords": "model,predictive,control,linear,time-varying",
"author": null,
"author_email": "St\u00e9phane Caron <stephane.caron@normalesup.org>",
"download_url": "https://files.pythonhosted.org/packages/98/c7/4199bca033e81d4548af37417f9ac40bc925eb93c6ca0383fa83480a868a/qpmpc-3.0.1.tar.gz",
"platform": null,
"description": "# qpmpc\n\n[![Build](https://img.shields.io/github/actions/workflow/status/stephane-caron/qpmpc/build.yml?branch=main)](https://github.com/stephane-caron/qpmpc/actions)\n[![Coverage](https://coveralls.io/repos/github/stephane-caron/qpmpc/badge.svg?branch=main)](https://coveralls.io/github/stephane-caron/qpmpc?branch=main)\n[![Documentation](https://img.shields.io/badge/docs-online-brightgreen?logo=read-the-docs&style=flat)](https://scaron.info/doc/qpmpc/)\n[![PyPI version](https://img.shields.io/pypi/v/qpmpc)](https://pypi.org/project/qpmpc/0.6.0/)\n\nModel 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:\n\n> ![qpmpc](https://raw.githubusercontent.com/stephane-caron/qpmpc/main/doc/src/images/qpmpc.svg)\n\nThis module is designed for prototyping. If you need performance, check out the [alternatives](#alternatives) below.\n\n## Installation\n\n```sh\npip install qpmpc\n```\n\n## Usage\n\nThis module defines a one-stop shop function:\n\n```python\nsolve_mpc(problem: MPCProblem, solver: str) -> Plan\n```\n\nThe [``MPCProblem``](https://scaron.info/doc/qpmpc/usage.html#qpmpc.mpc_problem.MPCProblem) defines the model predictive control problem (LTV system, LTV constraints, initial state and cost function to optimize) while the returned [``Plan``](https://tasts-robots.org/doc/qpmpc/usage.html#qpmpc.plan.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](https://github.com/stephane-caron/qpsolvers#solvers).\n\n## Example\n\nLet us define a triple integrator:\n\n```python\n import numpy as np\n\n horizon_duration = 1.0 # [s]\n N = 16 # number of discretization steps\n T = horizon_duration / N\n A = np.array([[1.0, T, T ** 2 / 2.0], [0.0, 1.0, T], [0.0, 0.0, 1.0]])\n B = np.array([T ** 3 / 6.0, T ** 2 / 2.0, T]).reshape((3, 1))\n```\n\nSuppose for the sake of example that acceleration is the main constraint acting on our system. We thus define an acceleration constraint ``|acceleration| <= max_accel``:\n\n```python\n max_accel = 3.0 # [m] / [s] / [s]\n accel_from_state = np.array([0.0, 0.0, 1.0])\n C = np.vstack([+accel_from_state, -accel_from_state])\n e = np.array([+max_accel, +max_accel])\n```\n\nThis leads us to the following linear MPC problem:\n\n```python\n from qpmpc import MPCProblem\n\n x_init = np.array([0.0, 0.0, 0.0])\n x_goal = np.array([1.0, 0.0, 0.0])\n problem = MPCProblem(\n transition_state_matrix=A,\n transition_input_matrix=B,\n ineq_state_matrix=C,\n ineq_input_matrix=None,\n ineq_vector=e,\n initial_state=x_init,\n goal_state=x_goal,\n nb_timesteps=N,\n terminal_cost_weight=1.0,\n stage_state_cost_weight=None,\n stage_input_cost_weight=1e-6,\n )\n```\n\nWe can solve it with:\n\n```python\n from qpmpc import solve_mpc\n\n solution = solve_mpc(problem, solver=\"proxqp\")\n```\n\nThe solution holds complete state and input trajectories as stacked vectors. For instance, we can plot positions, velocities and accelerations as follows:\n\n```python\n import pylab\n\n t = np.linspace(0.0, horizon_duration, N + 1)\n X = solution.states\n positions, velocities, accelerations = X[:, 0], X[:, 1], X[:, 2]\n pylab.ion()\n pylab.plot(t, positions)\n pylab.plot(t, velocities)\n pylab.plot(t, accelerations)\n pylab.grid(True)\n pylab.legend((\"position\", \"velocity\", \"acceleration\"))\n```\n\nThis example produces the following trajectory:\n\n![2022-03-30-172206_1920x1080_scrot](https://user-images.githubusercontent.com/1189580/160871543-3734ec65-fe74-4a6f-8452-a877aa4050b1.png)\n\nThe 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](examples/) folder for more examples.\n\n## Areas of improvement\n\nThis module is incomplete with regards to the following points:\n\n- Cost functions: can be extended to general linear stage cost functions\n- Documentation: there are some undocumented functions\n- Test coverage: only one end-to-end test\n\nCheck out the [contribution guidelines](CONTRIBUTING.md) if you are interested in lending a hand.\n\n## Alternatives\n\nThis module is designed for faster prototyping rather than performance. You can also check out the following open-source libraries:\n\n| Name | Systems | Languages | License |\n|------------------------------------------------------------|-----------------------|------------|--------------|\n| [Copra (LTV fork)](https://github.com/ANYbotics/copra) | Linear time-variant | Python/C++ | BSD-2-Clause |\n| [Copra (original)](https://github.com/jrl-umi3218/copra) | Linear time-invariant | Python/C++ | BSD-2-Clause |\n| [Crocoddyl](https://github.com/loco-3d/crocoddyl) | Nonlinear | Python/C++ | BSD-3-Clause |\n| [mpc-interface](https://github.com/Gepetto/mpc-interface) | Linear time-variant | Python/C++ | BSD-2-Clause |\n| [pyMPC](https://github.com/forgi86/pyMPC) | Linear time-variant | Python | MIT |\n",
"bugtrack_url": null,
"license": null,
"summary": "Linear time-variant model predictive control in Python.",
"version": "3.0.1",
"project_urls": {
"Changelog": "https://github.com/stephane-caron/qpmpc/blob/main/CHANGELOG.md",
"Documentation": "https://scaron.info/doc/qpmpc/",
"Source": "https://github.com/stephane-caron/qpmpc",
"Tracker": "https://github.com/stephane-caron/qpmpc/issues"
},
"split_keywords": [
"model",
"predictive",
"control",
"linear",
"time-varying"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "a98c45405fea297c567fc9f95cceb2f55668c53a247b7c79f3a3bf24944984ba",
"md5": "407d42ad7366be6b26d9fbbc3d590ac5",
"sha256": "044f0952ba95223c1fc3571bd7b013687a439f7a23d0d0c2ace6515b8afa4c80"
},
"downloads": -1,
"filename": "qpmpc-3.0.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "407d42ad7366be6b26d9fbbc3d590ac5",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 20038,
"upload_time": "2023-12-21T14:34:54",
"upload_time_iso_8601": "2023-12-21T14:34:54.336624Z",
"url": "https://files.pythonhosted.org/packages/a9/8c/45405fea297c567fc9f95cceb2f55668c53a247b7c79f3a3bf24944984ba/qpmpc-3.0.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "98c74199bca033e81d4548af37417f9ac40bc925eb93c6ca0383fa83480a868a",
"md5": "e8c7b7420d518ea08e1c07326f5afadc",
"sha256": "5394acc4969159c03af946a522b62d510617da090cb755805dc248b4e0ebe567"
},
"downloads": -1,
"filename": "qpmpc-3.0.1.tar.gz",
"has_sig": false,
"md5_digest": "e8c7b7420d518ea08e1c07326f5afadc",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 44594,
"upload_time": "2023-12-21T14:34:57",
"upload_time_iso_8601": "2023-12-21T14:34:57.370863Z",
"url": "https://files.pythonhosted.org/packages/98/c7/4199bca033e81d4548af37417f9ac40bc925eb93c6ca0383fa83480a868a/qpmpc-3.0.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-12-21 14:34:57",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "stephane-caron",
"github_project": "qpmpc",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"tox": true,
"lcname": "qpmpc"
}