Metadata-Version: 2.1
Name: ltv-mpc
Version: 0.6.0
Summary: Linear time-variant model predictive control in Python.
Keywords: rate,loop,frequency,regulator
Author-email: Stéphane Caron <stephane.caron@normalesup.org>
Maintainer-email: Stéphane Caron <stephane.caron@normalesup.org>
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Topic :: Scientific/Engineering :: Mathematics
Requires-Dist: qpsolvers >=1.8.0
Requires-Dist: sphinx ; extra == "doc"
Project-URL: Changelog, https://github.com/tasts-robots/ltv-mpc/blob/master/CHANGELOG.md
Project-URL: Documentation, https://tasts-robots.org/doc/ltv-mpc/
Project-URL: Source, https://github.com/tasts-robots/ltv-mpc
Project-URL: Tracker, https://github.com/tasts-robots/ltv-mpc/issues
Provides-Extra: doc

# ltv-mpc

[**Installation**](https://github.com/stephane-caron/pink#installation)
| [**Documentation**](https://tasts-robots.org/doc/ltv-mpc/)
| [**Usage**](https://github.com/stephane-caron/pink#usage)
| [**Contributing**](CONTRIBUTING.md)

[![build](https://img.shields.io/github/workflow/status/tasts-robots/ltv-mpc/CI)](https://github.com/tasts-robots/ltv-mpc/actions)
[![PyPI version](https://badge.fury.io/py/ltv-mpc.svg)](https://badge.fury.io/py/ltv-mpc)
![Status](https://img.shields.io/pypi/status/ltv-mpc)

Linear time-variant model predictive control in Python.

This module is designed for prototyping. If you need performance, check out one of the related libraries below.

## Installation

```sh
pip install ltv-mpc
```

## Usage

The module defines two types:

- ``Problem`` defines the model predictive control problem, that is:
    - Constrained linear time-variant system
    - Cost function to optimize
    - Initial (and goal) state
- ``Solution`` holds the solution to a given problem.

The ``solve_mpc`` function takes a ``Problem`` as input and outputs the corresponding ``Solution``.

## Example

Let us define a triple integrator:

```python
    import numpy as np

    horizon_duration = 1.0
    nb_timesteps = 16
    T = horizon_duration / nb_timesteps
    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])
    ineq_matrix = np.vstack([+accel_from_state, -accel_from_state])
    ineq_vector = np.array([+max_accel, +max_accel])
```

This leads us to the following linear MPC problem:

```python
    from ltv_mpc import Problem

    initial_pos = 0.0
    goal_pos = 1.0
    problem = ltv_mpc.Problem(
        transition_state_matrix=A,
        transition_input_matrix=B,
        ineq_state_matrix=ineq_matrix,
        ineq_input_matrix=None,
        ineq_vector=ineq_vector,
        initial_state=np.array([initial_pos, 0.0, 0.0]),
        goal_state=np.array([goal_pos, 0.0, 0.0]),
        nb_timesteps=nb_timesteps,
        terminal_cost_weight=1.0,
        stage_state_cost_weight=None,
        stage_input_cost_weight=1e-6,
    )
```

We can solve it with:

```python
    from ltv_mpc import solve_mpc

    solution = solve_mpc(problem, mpc)
```

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

```python
    import pylab

    t = np.linspace(0.0, horizon_duration, nb_timesteps + 1)
    X = solution.stacked_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)
```

## 🏗️ Work in progress

This module is still under development and its API might change. Future works may include:

- Complete documentation
- Complete test coverage
- General linear stage cost functions

## See also

| System                | Library                                                  | Language | License      |
|-----------------------|----------------------------------------------------------|----------|--------------|
| Linear time-invariant | [Copra (original)](https://github.com/jrl-umi3218/copra) | C++      | BSD-2-Clause |
| Linear time-variant   | [Copra (fork)](https://github.com/ANYbotics/copra)       | C++      | BSD-2-Clause |
| Nonlinear             | [Crocoddyl](https://github.com/loco-3d/crocoddyl)        | C++      | BSD-3-Clause |

