This repository implements a Moving-Horizon Simultaneous Input-and-State Estimation (MH-SISE) problem in Python. The MH-SISE algorithm estimates both inputs and states of a dynamic system over a moving horizon.
A DPP-complient optimization problem is defined using CVXPY. For real-time applications, the package can generate a high-speed C-solver using CVXPYGEN.
We consider a discrete-time linear time-invariant (LTI) system of the form:
Where:
-
$x_k \in \mathbb{R}^n$ represents the system state at time step$k$ , -
$u_k \in \mathbb{R}^m$ is the control input at time step$k$ , -
$y_k \in \mathbb{R}^p$ is a vector of measured outputs at time step$k$ , -
$w_k \in \mathbb{R}^n$ and$v_k \in \mathbb{R}^p$ are process and measurement noise, respectively, -
$A \in \mathbb{R}^{n \times n}$ ,$B \in \mathbb{R}^{n \times m}$ , and$C \in \mathbb{R}^{p \times n}$ are system matrices describing the dynamics and observation model.
To estimate both the states
where:
-
$Q_v \in \mathbb{R}^{p \times p}$ ,$Q_w \in \mathbb{R}^{n \times n}$ are covariande matrices of measurement noise$v_n$ , process noise$w_n$ , respectively. -
$L(u)$ is a regularization term designed by the user. -
$\mathcal{C}$ is a convex set defined by the user. -
$\hat{x}_{k-N-1}$ is an estimatie of the initial state.
This formulation leads to a convex optimization problem, which is solved using the cvxpy optimization framework, and code generation for real-time applications is handled by cvxpygen.
This project is developed Python 3.12.4 and has not been tested for other versions.
Clone repository and install mh_sise in editable mode using:
pip install -e .This will install the package and allow you to modify the code without needing to reinstall it. Now you can import mh_sise in your Python projects:
from mh_sise.problem import ProblemTo run the code in this project, you'll need to install the following Python packages:
numpyfor numerical operations.cvxpyfor convex optimization.cvxpygenfor code ceneration.scipyfor linear algebra and control-related oprations.matplotlibfor plotting and visualization.
Install the dependencies with:
pip install -r requirements.txtThis example outlines the process of creatign and solving an MH-SISE problem. The following example steps through the process of defining an MH-SISE problem for a system with
The complete example is provided in:
- MH-SISE Example, example.ipynb
The class Problem in the mh-sise package creates a DPP-complient optimization problem of the form
The regularization term
from mh_sise.problem import Problem
p = n_outputs
m = n_inputs
n = n_states
problem = Problem(n, m, p, N)This is how you add additional parameters beyond the ones defined in the "mother" problem above. Here parameters
problem.add_parameter(shape=(m,m), name='Q_u_inv_sqrt')
problem.add_parameter(shape=1, name='b')Here the regularization term
import cvxpy as cp
# create the regularization term
expression = cp.sum_squares(problem.Q_u_inv_sqrt @ problem.U)
problem.add_regularization(expression)This is how you add additional constraints not defined in the mother problem. Here the constraint
# create a constraint
new_constraint = cp.abs(problem.U) <= problem.b
# add constraint to problem
problem.add_constraints(new_constraint)It is sometimes necessary to add additional variables beyond those included in the mother problem. Variables are added as follows:
problem.add_variable(shape, name)Parameter values are assigned as follows. It is also possible to assign values to a subset of all parameters.
problem.assign_parameter_values(
Q_v_inv_sqrt = Q_v_inv_sqrt,
Q_w_inv_sqrt = Q_w_inv_sqrt,
Q_u_inv_sqrt = Q_u_inv_sqrt,
A = A,
B = B,
C = C,
x0 = x0,
y = y,
b = b
)Solve the problem with cvxpy with the following command:
problem.solve()Here we will step through how to generate C code using CVXPYGEN for the problem above above.
problem.generate_code(pth, name)where pth is the path to where the solved is to be saved, and name is the name you want to give the solver.
from mh_sise.problem import CProblem
from codegen.<<pth_to_solver>>.cpg_solver import cpg_solve
cproblem = CProblem(pth=pth_to_solver)Parameter values are assigned to the C solver as follows. It is also possible to assign values to a selection of the parameters.
cproblem.assign_parameter_values(
Q_v_inv_sqrt = Q_v_inv_sqrt,
Q_w_inv_sqrt = Q_w_inv_sqrt,
Q_u_inv_sqrt = Q_u_inv_sqrt,
A = A,
B = B,
C = C,
x0 = x0,
y = y,
b = b
)cproblem.solve(cpg_solve)If you use this package in your research, please cite it using the following BibTeX entry:
@misc{mh-sise-py,
author = {Manngård, Mikael and Bouzoulas, Dimitrios and Hakonen, Urho and Kronqvist, Jan},
title = {{MH-SISE-PY}: A Python Package for Moving-Horizon Simultaneous Input-and-State Estimation},
year = {2024},
howpublished = {\url{https://github.com/Novia-RDI-Seafaring/mh-sise-py}},
}- Mikael Manngård, (Novia UAS). Contributed with the MH-SISE formulation.
- CRediT: Conceptualization, Methodology, Software, Formal analysis, Supervision.
- Dimitrios Bouzoulas (Novia UAS). Contributed with the code-generation work with
cvxpygen.- CRediT: Software, Validation.
- Urho Hakonen (Aalto University). This work is a continuation and implementation of (Hakonen, 2023).
- CRediT: Methodology, Validation.
- Jan Kronqvist (KTH).
- CRediT: Supervision.
This work was done in the Business Finland funded project Virtual Sea Trial.