mpc-control 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mpc_control-0.1.0/LICENSE +21 -0
- mpc_control-0.1.0/PKG-INFO +212 -0
- mpc_control-0.1.0/README.md +189 -0
- mpc_control-0.1.0/mpc_control/__init__.py +21 -0
- mpc_control-0.1.0/mpc_control/discrete.py +632 -0
- mpc_control-0.1.0/mpc_control/kalman.py +364 -0
- mpc_control-0.1.0/mpc_control/mpc.py +781 -0
- mpc_control-0.1.0/mpc_control/plant.py +141 -0
- mpc_control-0.1.0/mpc_control/rls.py +159 -0
- mpc_control-0.1.0/mpc_control.egg-info/PKG-INFO +212 -0
- mpc_control-0.1.0/mpc_control.egg-info/SOURCES.txt +18 -0
- mpc_control-0.1.0/mpc_control.egg-info/dependency_links.txt +1 -0
- mpc_control-0.1.0/mpc_control.egg-info/requires.txt +3 -0
- mpc_control-0.1.0/mpc_control.egg-info/top_level.txt +1 -0
- mpc_control-0.1.0/pyproject.toml +37 -0
- mpc_control-0.1.0/setup.cfg +4 -0
- mpc_control-0.1.0/test/test_kalman.py +371 -0
- mpc_control-0.1.0/test/test_mpc.py +460 -0
- mpc_control-0.1.0/test/test_plant.py +80 -0
- mpc_control-0.1.0/test/test_rls.py +211 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Zhen NI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mpc-control
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A Python library for Model Predictive Control (MPC)
|
|
5
|
+
Author-email: Zhen Ni <z.ni@hotmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Zhen-Ni/mpc-control
|
|
8
|
+
Project-URL: Issues, https://github.com/Zhen-Ni/mpc-control/issues
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering
|
|
16
|
+
Requires-Python: >=3.9
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
Requires-Dist: numpy>=2.0
|
|
20
|
+
Requires-Dist: osqp>=1.0.0
|
|
21
|
+
Requires-Dist: scipy>=1.0.0
|
|
22
|
+
Dynamic: license-file
|
|
23
|
+
|
|
24
|
+
# A Python library for model predictive control.
|
|
25
|
+
|
|
26
|
+
A Python library for Model Predictive Control (MPC), integrating system modeling, state estimation, parameter identification, and Quadratic Programming (QP) based MPC solvers.
|
|
27
|
+
|
|
28
|
+
## Requirements
|
|
29
|
+
|
|
30
|
+
- Python 3.9+ (Tested with Python 3.12)
|
|
31
|
+
- NumPy
|
|
32
|
+
- SciPy
|
|
33
|
+
- OSQP
|
|
34
|
+
|
|
35
|
+
## Model predictive control
|
|
36
|
+
|
|
37
|
+
### System Prediction Model
|
|
38
|
+
|
|
39
|
+
For discrete time-invariant systems:
|
|
40
|
+
|
|
41
|
+
$$
|
|
42
|
+
\begin{aligned}
|
|
43
|
+
x[n+1] &= A x[n] + B u[n] + w \\
|
|
44
|
+
y[n] &= C x[n] + v
|
|
45
|
+
\end{aligned}
|
|
46
|
+
$$
|
|
47
|
+
|
|
48
|
+
Prediction over horizon $N$:
|
|
49
|
+
|
|
50
|
+
$$
|
|
51
|
+
\begin{aligned}
|
|
52
|
+
X &= [x_1^T, x_2^T, \dots, x_N^T]^T \\
|
|
53
|
+
U &= [u_0^T, u_1^T, \dots, u_{N-1}^T]^T \\
|
|
54
|
+
Y &= [y_1^T, y_2^T, \dots, y_N^T]^T
|
|
55
|
+
\end{aligned}
|
|
56
|
+
$$
|
|
57
|
+
|
|
58
|
+
The predicted state and output sequences can be expressed as:
|
|
59
|
+
|
|
60
|
+
$$
|
|
61
|
+
\begin{aligned}
|
|
62
|
+
X &= M_x x_0 + M_u U + M_w w \\
|
|
63
|
+
Y &= \bar{C} X + V = \bar{C} M_x x_0 + \bar{C} M_u U + \bar{C} M_w w + V
|
|
64
|
+
\end{aligned}
|
|
65
|
+
$$
|
|
66
|
+
|
|
67
|
+
where $M_x$, $M_u$, and $M_w$ are block matrices defined as:
|
|
68
|
+
|
|
69
|
+
$$
|
|
70
|
+
M_x = \begin{bmatrix} A \\ A^2 \\ \cdots \\ A^N \end{bmatrix}
|
|
71
|
+
$$
|
|
72
|
+
$$
|
|
73
|
+
M_u = \begin{bmatrix}
|
|
74
|
+
B & 0 & \dots & 0 \\
|
|
75
|
+
AB & B & \dots & 0 \\
|
|
76
|
+
\vdots & \vdots & \ddots & \vdots \\
|
|
77
|
+
A^{N-1}B & A^{N-2}B & \dots & B
|
|
78
|
+
\end{bmatrix}
|
|
79
|
+
$$
|
|
80
|
+
$$
|
|
81
|
+
M_w = \begin{bmatrix}
|
|
82
|
+
I & 0 & \dots & 0 \\
|
|
83
|
+
A+I & I & \dots & 0 \\
|
|
84
|
+
\vdots & \vdots & \ddots & \vdots \\
|
|
85
|
+
\sum_{i=0}^{N-1} A^i & \sum_{i=0}^{N-2} A^i & \dots & I
|
|
86
|
+
\end{bmatrix}
|
|
87
|
+
$$
|
|
88
|
+
|
|
89
|
+
and $\bar{C}$ and $V$ are defined as:
|
|
90
|
+
|
|
91
|
+
$$
|
|
92
|
+
\bar{C} = \text{diag}(C, C, \dots, C), \quad
|
|
93
|
+
V = [v^T, v^T, \dots, v^T]^T
|
|
94
|
+
$$
|
|
95
|
+
|
|
96
|
+
### Cost Function
|
|
97
|
+
|
|
98
|
+
The optimization objective is to minimize the cost function:
|
|
99
|
+
|
|
100
|
+
$$
|
|
101
|
+
J = (Y - Y_{ref})^T \bar{Q} (Y - Y_{ref}) + U^T \bar{R} U + \Delta U^T \bar{R}_{\Delta} \Delta U
|
|
102
|
+
$$
|
|
103
|
+
|
|
104
|
+
where $\bar{Q}$, $\bar{R}$, and $\bar{R}_{\Delta}$ are block-diagonal weighting matrices for output, control, and control delta respectively. The control delta is defined as:
|
|
105
|
+
|
|
106
|
+
$$
|
|
107
|
+
\Delta U = \bar{D} U - U_{last}
|
|
108
|
+
$$
|
|
109
|
+
|
|
110
|
+
where $U_{last} = [u_{-1}^T, 0, \dots, 0]^T$ ($u_{-1}$ is the previous control input), and $\bar{D}$ is the control delta matrix defined as:
|
|
111
|
+
|
|
112
|
+
$$
|
|
113
|
+
\bar{D} = \begin{bmatrix}
|
|
114
|
+
I & 0 & \dots & 0 \\
|
|
115
|
+
-I & I & \dots & 0 \\
|
|
116
|
+
0 & -I & \dots & 0 \\
|
|
117
|
+
\vdots & \vdots & \ddots & \vdots \\
|
|
118
|
+
0 & 0 & \dots & I
|
|
119
|
+
\end{bmatrix}
|
|
120
|
+
$$
|
|
121
|
+
|
|
122
|
+
### QP Formulation
|
|
123
|
+
|
|
124
|
+
Let $E_y = \bar{C} M_x x_0 + \bar{C} M_w w + V - Y_{ref}$. Expanding the cost function and ignoring constant terms, we obtain:
|
|
125
|
+
|
|
126
|
+
$$
|
|
127
|
+
J = \frac{1}{2} U^T (2 M_u^T \bar{C}^T \bar{Q} \bar{C} M_u + 2 \bar{R} + 2 \bar{D}^T \bar{R}_{\Delta} \bar{D}) U + (2 M_u^T \bar{C}^T \bar{Q} E_y - 2 \bar{D}^T \bar{R}_{\Delta} U_{last})^T U
|
|
128
|
+
$$
|
|
129
|
+
|
|
130
|
+
This can be mapped to the standard OSQP form ($\min \frac{1}{2} U^T P U + q^T U$). The actual $P$ and $q$ computed in the code are (without the factor of 2):
|
|
131
|
+
|
|
132
|
+
$$
|
|
133
|
+
\begin{aligned}
|
|
134
|
+
P &= M_u^T \bar{C}^T \bar{Q} \bar{C} M_u + \bar{R} + \bar{D}^T \bar{R}_{\Delta} \bar{D} \\
|
|
135
|
+
q &= M_u^T \bar{C}^T \bar{Q} E_y - \bar{D}^T \bar{R}_{\Delta} U_{last}
|
|
136
|
+
\end{aligned}
|
|
137
|
+
$$
|
|
138
|
+
|
|
139
|
+
### Constraints
|
|
140
|
+
|
|
141
|
+
The problem is subject to the following constraints:
|
|
142
|
+
- **Output constraints**: $l_{y} \leq \bar{C} M_u U + \bar{C} M_x x_0 + \bar{C} M_w w + V \leq u_{y}$
|
|
143
|
+
- **Control constraints**: $l_{u} \leq U \leq u_{u}$
|
|
144
|
+
- **Control rate constraints**: $l_{\Delta u} \leq \bar{D} U - U_{last} \leq u_{\Delta u}$
|
|
145
|
+
|
|
146
|
+
These linear constraints are compiled into the standard form $l \leq A_c U \leq u$ for the OSQP solver.
|
|
147
|
+
|
|
148
|
+
### Nonlinear Systems
|
|
149
|
+
|
|
150
|
+
For nonlinear systems, the controller linearizes the system dynamics along a given reference trajectory. At each time step $i$ within the prediction horizon, the system is linearized around the reference state $x_{ref, i}$ and control $u_{ref, i}$ to obtain a linear time-varying (LTV) model:
|
|
151
|
+
|
|
152
|
+
$$
|
|
153
|
+
\begin{aligned}
|
|
154
|
+
x[i+1] &\approx A_i x[i] + B_i u[i] + w_i \\
|
|
155
|
+
y[i] &\approx C_i x[i] + v_i
|
|
156
|
+
\end{aligned}
|
|
157
|
+
$$
|
|
158
|
+
|
|
159
|
+
The QP problem is then formulated using these LTV matrices. The prediction matrices $M_x, M_u, M_w$ and the output mapping $\bar{C}$ become time-varying and are constructed iteratively over the horizon to reflect the changing linearization points. The reference trajectory for linearization can be provided to the solver via the `state_ref` and `control_ref` arguments.
|
|
160
|
+
|
|
161
|
+
## Features
|
|
162
|
+
|
|
163
|
+
- **System Models (`mpc.discrete`)**: Supports discrete-time system modeling, including Linear Time-Invariant (LTI), Affine Time-Invariant (ATI), Nonlinear, and Homogeneous systems.
|
|
164
|
+
- **Model Predictive Control (`mpc.mpc`)**: Formulates and solves QP problems using the OSQP solver. Supports output, control, and control delta weighting, as well as constraints on output, control, and control rate.
|
|
165
|
+
- **State Estimation (`mpc.kalman`)**: Implements Extended Kalman Filter (EKF) and Unscented Kalman Filter (UKF) for state estimation of nonlinear systems.
|
|
166
|
+
- **Parameter Identification (`mpc.rls`)**: Provides Recursive Least Squares (RLS) algorithms for online system parameter identification.
|
|
167
|
+
|
|
168
|
+
## Usage
|
|
169
|
+
|
|
170
|
+
Here is a basic example of how to define a system and solve an MPC problem:
|
|
171
|
+
|
|
172
|
+
```python
|
|
173
|
+
import numpy as np
|
|
174
|
+
immport mpc_control as mpc
|
|
175
|
+
|
|
176
|
+
# 1. Define a discrete LTI system
|
|
177
|
+
# x[n+1] = A x[n] + B u[n]
|
|
178
|
+
# y[n] = C x[n]
|
|
179
|
+
system = mpc.LtiSystem(
|
|
180
|
+
transition_matrix=np.array([[1.0, 1.0],
|
|
181
|
+
[0.0, 1.0]]),
|
|
182
|
+
control_matrix=np.array([[0.0],
|
|
183
|
+
[1.0]]),
|
|
184
|
+
output_matrix=np.array([[1.0, 0.0]])
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
# 2. Initialize the MPC controller
|
|
188
|
+
horizon = 10
|
|
189
|
+
n_output = system.n_output
|
|
190
|
+
n_control = system.n_control
|
|
191
|
+
|
|
192
|
+
Q = np.stack([np.eye(n_output)] * horizon) # Output weighting
|
|
193
|
+
R = np.stack([np.eye(n_control) * 0.1] * horizon) # Control weighting
|
|
194
|
+
|
|
195
|
+
controller = mpc.Mpc(
|
|
196
|
+
system=system,
|
|
197
|
+
horizon=horizon,
|
|
198
|
+
output_weighting=Q,
|
|
199
|
+
control_weighting=R
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
# 3. Set up the problem and solve
|
|
203
|
+
target_output = np.zeros([horizon, n_output])
|
|
204
|
+
initial_state = np.array([1.0, 0.0])
|
|
205
|
+
|
|
206
|
+
u_optimal = controller.solve(
|
|
207
|
+
target_output=target_output,
|
|
208
|
+
initial_state=initial_state
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
print("Optimal control sequence:\n", u_optimal)
|
|
212
|
+
```
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# A Python library for model predictive control.
|
|
2
|
+
|
|
3
|
+
A Python library for Model Predictive Control (MPC), integrating system modeling, state estimation, parameter identification, and Quadratic Programming (QP) based MPC solvers.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- Python 3.9+ (Tested with Python 3.12)
|
|
8
|
+
- NumPy
|
|
9
|
+
- SciPy
|
|
10
|
+
- OSQP
|
|
11
|
+
|
|
12
|
+
## Model predictive control
|
|
13
|
+
|
|
14
|
+
### System Prediction Model
|
|
15
|
+
|
|
16
|
+
For discrete time-invariant systems:
|
|
17
|
+
|
|
18
|
+
$$
|
|
19
|
+
\begin{aligned}
|
|
20
|
+
x[n+1] &= A x[n] + B u[n] + w \\
|
|
21
|
+
y[n] &= C x[n] + v
|
|
22
|
+
\end{aligned}
|
|
23
|
+
$$
|
|
24
|
+
|
|
25
|
+
Prediction over horizon $N$:
|
|
26
|
+
|
|
27
|
+
$$
|
|
28
|
+
\begin{aligned}
|
|
29
|
+
X &= [x_1^T, x_2^T, \dots, x_N^T]^T \\
|
|
30
|
+
U &= [u_0^T, u_1^T, \dots, u_{N-1}^T]^T \\
|
|
31
|
+
Y &= [y_1^T, y_2^T, \dots, y_N^T]^T
|
|
32
|
+
\end{aligned}
|
|
33
|
+
$$
|
|
34
|
+
|
|
35
|
+
The predicted state and output sequences can be expressed as:
|
|
36
|
+
|
|
37
|
+
$$
|
|
38
|
+
\begin{aligned}
|
|
39
|
+
X &= M_x x_0 + M_u U + M_w w \\
|
|
40
|
+
Y &= \bar{C} X + V = \bar{C} M_x x_0 + \bar{C} M_u U + \bar{C} M_w w + V
|
|
41
|
+
\end{aligned}
|
|
42
|
+
$$
|
|
43
|
+
|
|
44
|
+
where $M_x$, $M_u$, and $M_w$ are block matrices defined as:
|
|
45
|
+
|
|
46
|
+
$$
|
|
47
|
+
M_x = \begin{bmatrix} A \\ A^2 \\ \cdots \\ A^N \end{bmatrix}
|
|
48
|
+
$$
|
|
49
|
+
$$
|
|
50
|
+
M_u = \begin{bmatrix}
|
|
51
|
+
B & 0 & \dots & 0 \\
|
|
52
|
+
AB & B & \dots & 0 \\
|
|
53
|
+
\vdots & \vdots & \ddots & \vdots \\
|
|
54
|
+
A^{N-1}B & A^{N-2}B & \dots & B
|
|
55
|
+
\end{bmatrix}
|
|
56
|
+
$$
|
|
57
|
+
$$
|
|
58
|
+
M_w = \begin{bmatrix}
|
|
59
|
+
I & 0 & \dots & 0 \\
|
|
60
|
+
A+I & I & \dots & 0 \\
|
|
61
|
+
\vdots & \vdots & \ddots & \vdots \\
|
|
62
|
+
\sum_{i=0}^{N-1} A^i & \sum_{i=0}^{N-2} A^i & \dots & I
|
|
63
|
+
\end{bmatrix}
|
|
64
|
+
$$
|
|
65
|
+
|
|
66
|
+
and $\bar{C}$ and $V$ are defined as:
|
|
67
|
+
|
|
68
|
+
$$
|
|
69
|
+
\bar{C} = \text{diag}(C, C, \dots, C), \quad
|
|
70
|
+
V = [v^T, v^T, \dots, v^T]^T
|
|
71
|
+
$$
|
|
72
|
+
|
|
73
|
+
### Cost Function
|
|
74
|
+
|
|
75
|
+
The optimization objective is to minimize the cost function:
|
|
76
|
+
|
|
77
|
+
$$
|
|
78
|
+
J = (Y - Y_{ref})^T \bar{Q} (Y - Y_{ref}) + U^T \bar{R} U + \Delta U^T \bar{R}_{\Delta} \Delta U
|
|
79
|
+
$$
|
|
80
|
+
|
|
81
|
+
where $\bar{Q}$, $\bar{R}$, and $\bar{R}_{\Delta}$ are block-diagonal weighting matrices for output, control, and control delta respectively. The control delta is defined as:
|
|
82
|
+
|
|
83
|
+
$$
|
|
84
|
+
\Delta U = \bar{D} U - U_{last}
|
|
85
|
+
$$
|
|
86
|
+
|
|
87
|
+
where $U_{last} = [u_{-1}^T, 0, \dots, 0]^T$ ($u_{-1}$ is the previous control input), and $\bar{D}$ is the control delta matrix defined as:
|
|
88
|
+
|
|
89
|
+
$$
|
|
90
|
+
\bar{D} = \begin{bmatrix}
|
|
91
|
+
I & 0 & \dots & 0 \\
|
|
92
|
+
-I & I & \dots & 0 \\
|
|
93
|
+
0 & -I & \dots & 0 \\
|
|
94
|
+
\vdots & \vdots & \ddots & \vdots \\
|
|
95
|
+
0 & 0 & \dots & I
|
|
96
|
+
\end{bmatrix}
|
|
97
|
+
$$
|
|
98
|
+
|
|
99
|
+
### QP Formulation
|
|
100
|
+
|
|
101
|
+
Let $E_y = \bar{C} M_x x_0 + \bar{C} M_w w + V - Y_{ref}$. Expanding the cost function and ignoring constant terms, we obtain:
|
|
102
|
+
|
|
103
|
+
$$
|
|
104
|
+
J = \frac{1}{2} U^T (2 M_u^T \bar{C}^T \bar{Q} \bar{C} M_u + 2 \bar{R} + 2 \bar{D}^T \bar{R}_{\Delta} \bar{D}) U + (2 M_u^T \bar{C}^T \bar{Q} E_y - 2 \bar{D}^T \bar{R}_{\Delta} U_{last})^T U
|
|
105
|
+
$$
|
|
106
|
+
|
|
107
|
+
This can be mapped to the standard OSQP form ($\min \frac{1}{2} U^T P U + q^T U$). The actual $P$ and $q$ computed in the code are (without the factor of 2):
|
|
108
|
+
|
|
109
|
+
$$
|
|
110
|
+
\begin{aligned}
|
|
111
|
+
P &= M_u^T \bar{C}^T \bar{Q} \bar{C} M_u + \bar{R} + \bar{D}^T \bar{R}_{\Delta} \bar{D} \\
|
|
112
|
+
q &= M_u^T \bar{C}^T \bar{Q} E_y - \bar{D}^T \bar{R}_{\Delta} U_{last}
|
|
113
|
+
\end{aligned}
|
|
114
|
+
$$
|
|
115
|
+
|
|
116
|
+
### Constraints
|
|
117
|
+
|
|
118
|
+
The problem is subject to the following constraints:
|
|
119
|
+
- **Output constraints**: $l_{y} \leq \bar{C} M_u U + \bar{C} M_x x_0 + \bar{C} M_w w + V \leq u_{y}$
|
|
120
|
+
- **Control constraints**: $l_{u} \leq U \leq u_{u}$
|
|
121
|
+
- **Control rate constraints**: $l_{\Delta u} \leq \bar{D} U - U_{last} \leq u_{\Delta u}$
|
|
122
|
+
|
|
123
|
+
These linear constraints are compiled into the standard form $l \leq A_c U \leq u$ for the OSQP solver.
|
|
124
|
+
|
|
125
|
+
### Nonlinear Systems
|
|
126
|
+
|
|
127
|
+
For nonlinear systems, the controller linearizes the system dynamics along a given reference trajectory. At each time step $i$ within the prediction horizon, the system is linearized around the reference state $x_{ref, i}$ and control $u_{ref, i}$ to obtain a linear time-varying (LTV) model:
|
|
128
|
+
|
|
129
|
+
$$
|
|
130
|
+
\begin{aligned}
|
|
131
|
+
x[i+1] &\approx A_i x[i] + B_i u[i] + w_i \\
|
|
132
|
+
y[i] &\approx C_i x[i] + v_i
|
|
133
|
+
\end{aligned}
|
|
134
|
+
$$
|
|
135
|
+
|
|
136
|
+
The QP problem is then formulated using these LTV matrices. The prediction matrices $M_x, M_u, M_w$ and the output mapping $\bar{C}$ become time-varying and are constructed iteratively over the horizon to reflect the changing linearization points. The reference trajectory for linearization can be provided to the solver via the `state_ref` and `control_ref` arguments.
|
|
137
|
+
|
|
138
|
+
## Features
|
|
139
|
+
|
|
140
|
+
- **System Models (`mpc.discrete`)**: Supports discrete-time system modeling, including Linear Time-Invariant (LTI), Affine Time-Invariant (ATI), Nonlinear, and Homogeneous systems.
|
|
141
|
+
- **Model Predictive Control (`mpc.mpc`)**: Formulates and solves QP problems using the OSQP solver. Supports output, control, and control delta weighting, as well as constraints on output, control, and control rate.
|
|
142
|
+
- **State Estimation (`mpc.kalman`)**: Implements Extended Kalman Filter (EKF) and Unscented Kalman Filter (UKF) for state estimation of nonlinear systems.
|
|
143
|
+
- **Parameter Identification (`mpc.rls`)**: Provides Recursive Least Squares (RLS) algorithms for online system parameter identification.
|
|
144
|
+
|
|
145
|
+
## Usage
|
|
146
|
+
|
|
147
|
+
Here is a basic example of how to define a system and solve an MPC problem:
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
import numpy as np
|
|
151
|
+
immport mpc_control as mpc
|
|
152
|
+
|
|
153
|
+
# 1. Define a discrete LTI system
|
|
154
|
+
# x[n+1] = A x[n] + B u[n]
|
|
155
|
+
# y[n] = C x[n]
|
|
156
|
+
system = mpc.LtiSystem(
|
|
157
|
+
transition_matrix=np.array([[1.0, 1.0],
|
|
158
|
+
[0.0, 1.0]]),
|
|
159
|
+
control_matrix=np.array([[0.0],
|
|
160
|
+
[1.0]]),
|
|
161
|
+
output_matrix=np.array([[1.0, 0.0]])
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
# 2. Initialize the MPC controller
|
|
165
|
+
horizon = 10
|
|
166
|
+
n_output = system.n_output
|
|
167
|
+
n_control = system.n_control
|
|
168
|
+
|
|
169
|
+
Q = np.stack([np.eye(n_output)] * horizon) # Output weighting
|
|
170
|
+
R = np.stack([np.eye(n_control) * 0.1] * horizon) # Control weighting
|
|
171
|
+
|
|
172
|
+
controller = mpc.Mpc(
|
|
173
|
+
system=system,
|
|
174
|
+
horizon=horizon,
|
|
175
|
+
output_weighting=Q,
|
|
176
|
+
control_weighting=R
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
# 3. Set up the problem and solve
|
|
180
|
+
target_output = np.zeros([horizon, n_output])
|
|
181
|
+
initial_state = np.array([1.0, 0.0])
|
|
182
|
+
|
|
183
|
+
u_optimal = controller.solve(
|
|
184
|
+
target_output=target_output,
|
|
185
|
+
initial_state=initial_state
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
print("Optimal control sequence:\n", u_optimal)
|
|
189
|
+
```
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from .plant import Plant, LoggedPlant
|
|
2
|
+
from .kalman import Ekf, Ukf
|
|
3
|
+
from .rls import Rls
|
|
4
|
+
from .discrete import LtiSystem, AtiSystem, HomogeneousSystem, NonlinearSystem
|
|
5
|
+
from .mpc import Mpc
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def _get_version() -> str:
|
|
9
|
+
"""Try to get the installed package version.
|
|
10
|
+
|
|
11
|
+
If the package is not installed (e.g., running from source in
|
|
12
|
+
development mode), fall back to "dev".
|
|
13
|
+
"""
|
|
14
|
+
from importlib.metadata import version, PackageNotFoundError
|
|
15
|
+
try:
|
|
16
|
+
return version("mpc-control")
|
|
17
|
+
except PackageNotFoundError:
|
|
18
|
+
return "dev"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
__version__ = _get_version()
|