Resurgence (PY2022)
Codebase for the Husky Robotics 2021-2022 rover Resurgence
Loading...
Searching...
No Matches
KalmanFilter.h
1#pragma once
2
3#include "KalmanFilterBase.h"
4#include "StateSpaceUtil.h"
5
6#include <Eigen/Core>
7#include <Eigen/LU>
8
9namespace filters {
10
20template <int stateDim, int inputDim, int outputDim>
21class KalmanFilter : public KalmanFilterBase<stateDim, inputDim> {
22public:
39 static KalmanFilter
43 const Eigen::Matrix<double, stateDim, 1>& stateStdDevs,
44 const Eigen::Matrix<double, outputDim, 1>& measurementStdDevs,
45 double dt) {
48 Eigen::Matrix<double, outputDim, outputDim> measurementCovarianceCont =
49 statespace::createCovarianceMatrix(measurementStdDevs);
50
53 statespace::continuousToDiscrete(discA, discB, dt);
54
56 statespace::discretizeQ(systemMat, stateCovarianceCont, dt);
58 statespace::discretizeR(measurementCovarianceCont, dt);
59
60 // solve DARE for asymptotic state error covariance matrix
62 discA.transpose(), outputMat.transpose(), stateCovariance, measurementCovariance);
63
65 outputMat * P * outputMat.transpose() + measurementCovariance;
66 // from wikipedia: K = P * H^T * S^-1
67 // so:
68 // K * S = P * H^T
69 // (K * S)^T = (P * H^T)^T
70 // S^T * K^T = H * P^T
71 // K^T = solve(S^T, H * P^T)
72 // K = solve(S^T, H * P^T)^T
74 S.transpose().colPivHouseholderQr().solve(outputMat * P.transpose()).transpose();
75
76 return KalmanFilter(discA, discB, outputMat, stateCovariance, measurementCovariance,
77 gainMatrix);
78 }
79
96 static KalmanFilter
100 const Eigen::Matrix<double, stateDim, 1>& stateStdDevs,
101 const Eigen::Matrix<double, outputDim, 1>& measurementStdDevs, double dt) {
104 Eigen::Matrix<double, outputDim, outputDim> measurementCovarianceCont =
105 statespace::createCovarianceMatrix(measurementStdDevs);
106
109 statespace::discreteToContinuous(contA, contB, dt);
110
112 statespace::discretizeQ(contA, stateCovarianceCont, dt);
113 Eigen::Matrix<double, outputDim, outputDim> measurementCovariance =
114 statespace::discretizeR(measurementCovarianceCont, dt);
115
116 // solve DARE for asymptotic state error covariance matrix
118 statespace::DARE(systemMat.transpose().eval(), outputMat.transpose().eval(),
119 stateCovariance, measurementCovariance);
120
121 // The following math is derived from the asymptotic form:
122 // https://en.wikipedia.org/wiki/Kalman_filter#Asymptotic_form
124 outputMat * P * outputMat.transpose() + measurementCovariance;
125 // from wikipedia:
126 // K = P * H^T * S^-1
127 // K * S = P * H^T
128 // (K * S)^T = (P * H^T)^T
129 // S^T * K^T = H * P^T
130 // K^T = solve(S^T, H * P^T)
131 // K = solve(S^T, H * P^T)^T
133 S.transpose().colPivHouseholderQr().solve(outputMat * P.transpose()).transpose();
134
135 return KalmanFilter(systemMat, inputMat, outputMat, stateCovariance,
136 measurementCovariance, gainMatrix);
137 }
138
147 this->xHat = this->xHat + K * (measurement - C * this->xHat);
148 this->P = (Eigen::Matrix<double, stateDim, stateDim>::Identity() - K * C) * this->P;
149 }
150
151 void predict(const Eigen::Matrix<double, inputDim, 1>& input) override {
152 this->xHat = A * this->xHat + B * input;
153 this->P = A * this->P * A.transpose() + Q;
154 }
155
156private:
160 Eigen::Matrix<double, stateDim, stateDim> Q; // system noise covariance matrix
161 Eigen::Matrix<double, outputDim, outputDim> R; // output noise covariance matrix
162 Eigen::Matrix<double, stateDim, outputDim> K; // asymptotic kalman gain
163
164 // Assumes all discrete matrices
171 : A(A), B(B), C(C), Q(Q), R(R), K(K) {}
172};
173
174} // namespace filters
TransposeReturnType transpose()
static const IdentityReturnType Identity()
Implements a Kalman Filter.
Definition KalmanFilter.h:21
static KalmanFilter createDiscrete(const Eigen::Matrix< double, stateDim, stateDim > &systemMat, const Eigen::Matrix< double, stateDim, inputDim > &inputMat, const Eigen::Matrix< double, outputDim, stateDim > &outputMat, const Eigen::Matrix< double, stateDim, 1 > &stateStdDevs, const Eigen::Matrix< double, outputDim, 1 > &measurementStdDevs, double dt)
Create a new Kalman Filter from a discrete-time state space model.
Definition KalmanFilter.h:97
void correct(const Eigen::Matrix< double, outputDim, 1 > &measurement)
Correct the state estimate with measurement data.
Definition KalmanFilter.h:146
static KalmanFilter createContinuous(const Eigen::Matrix< double, stateDim, stateDim > &systemMat, const Eigen::Matrix< double, stateDim, inputDim > &inputMat, const Eigen::Matrix< double, outputDim, stateDim > &outputMat, const Eigen::Matrix< double, stateDim, 1 > &stateStdDevs, const Eigen::Matrix< double, outputDim, 1 > &measurementStdDevs, double dt)
Create a new Kalman Filter from a continuous-time state space model.
Definition KalmanFilter.h:40
void predict(const Eigen::Matrix< double, inputDim, 1 > &input) override
Use the model to predict the next system state, given the current inputs.
Definition KalmanFilter.h:151
Eigen::Matrix< double, numStates, numStates > discreteToContinuous(const Eigen::Matrix< double, numStates, numStates > &A, double dt)
Convert a discrete time system matrix to continuous time.
Definition StateSpaceUtil.h:39
Eigen::Matrix< double, numStates, numStates > discretizeQ(const Eigen::Matrix< double, numStates, numStates > &contA, const Eigen::Matrix< double, numStates, numStates > &contQ, double dt)
Discretizes a continuous time additive process noise covariance matrix.
Definition StateSpaceUtil.h:154
Eigen::Matrix< double, size, size > createCovarianceMatrix(const Eigen::Matrix< double, size, 1 > &stdDevs)
Create a covariance matrix modelling independent variables with the given standard deviations.
Definition StateSpaceUtil.h:23
void continuousToDiscrete(Eigen::Matrix< double, numStates, numStates > &A, Eigen::Matrix< double, numStates, numInputs > &B, double dt)
Convert continuous time system and input matrices to discrete time.
Definition StateSpaceUtil.h:75
Eigen::Matrix< double, numStates, numStates > discretizeR(const Eigen::Matrix< double, numStates, numStates > &contR, double dt)
Discretizes a continuous time additive output noise covariance matrix.
Definition StateSpaceUtil.h:172