60 using Jacobian = Eigen::Matrix<double, Dim, Dim>;
68 static_assert(IsManifold<M>::value,
69 "Template parameter M must be a GTSAM Manifold.");
72 if constexpr (
Dim == Eigen::Dynamic) {
75 throw std::invalid_argument(
76 "ManifoldEKF: Initial covariance P0 dimensions (" +
77 std::to_string(P0.rows()) +
"x" + std::to_string(P0.cols()) +
78 ") do not match state's tangent space dimension (" +
79 std::to_string(
n_) +
").");
81 I_ = Jacobian::Identity(
n_,
n_);
83 I_ = Jacobian::Identity();
115 if constexpr (
Dim == Eigen::Dynamic) {
117 throw std::invalid_argument(
118 "ManifoldEKF::predict: Dynamic F/Q dimensions must match state "
120 std::to_string(
n_) +
".");
125 P_ = F *
P_ * F.transpose() + Q;
129 template <
typename HMatrix,
typename RMatrix>
131 auto S = H *
P_ * H.transpose() + R;
132 return P_ * H.transpose() * S.inverse();
137 template <
typename GainMatrix,
typename HMatrix,
typename RMatrix>
138 void JosephUpdate(
const GainMatrix& K,
const HMatrix& H,
const RMatrix& R) {
140 P_ = I_KH *
P_ * I_KH.transpose() + K * R * K.transpose();
155 template <
typename Measurement>
157 const Measurement& prediction,
159 const Measurement& z,
162 bool performReset =
true) {
172 Eigen::Matrix<double, Dim, MeasDim> K =
KalmanGain(H, R);
199 template <
typename Measurement,
typename MeasurementFunction>
200 void update(MeasurementFunction&& h,
const Measurement& z,
203 bool performReset =
true) {
204 static_assert(IsManifold<Measurement>::value,
205 "Template parameter Measurement must be a GTSAM Manifold.");
209 Measurement prediction = h(
X_, H);
227 const gtsam::Vector& z,
const Matrix& R,
228 bool performReset =
true) {
242 if constexpr (HasRetractJacobian<M>::value) {
244 if constexpr (
Dim == Eigen::Dynamic) B.resize(
n_,
n_);
246 P_ = B *
P_ * B.transpose();
256 const gtsam::Vector& z,
const Matrix& R) {
257 const size_t m =
static_cast<size_t>(prediction.size());
258 if (
static_cast<size_t>(z.size()) != m) {
259 throw std::invalid_argument(
260 "ManifoldEKF::updateWithVector: prediction and z must have same "
264 throw std::invalid_argument(
265 "ManifoldEKF::updateWithVector: H must be m x n where m = "
266 "measurement size and n = state dimension.");
269 throw std::invalid_argument(
270 "ManifoldEKF::updateWithVector: R must be m x m where m = "
271 "measurement size.");
276 template <
typename MatrixType>
279 return static_cast<size_t>(matrix.rows()) == rows &&
280 static_cast<size_t>(matrix.cols()) == cols;
291 template <
typename T,
typename =
void>
292 struct HasRetractJacobian : std::false_type {};
293 template <
typename T>
294 struct HasRetractJacobian<
295 T,
std::void_t<decltype(traits<T>::Retract(
296 std::declval<const T&>(),
297 std::declval<const typename traits<T>::TangentVector&>(),
298 (Jacobian*)nullptr))>> : std::true_type {};
typedef and functions to augment Eigen's MatrixXd
Base class and basic functions for Manifold types.
typedef and functions to augment Eigen's VectorXd
Global functions in a separate testing namespace.
Definition chartTesting.h:28
A manifold defines a space in which there is a notion of a linear tangent space that can be centered ...
Definition Group.h:37
Extended Kalman Filter on a generic manifold M.
Definition ManifoldEKF.h:50
void update(const Measurement &prediction, const Eigen::Matrix< double, traits< Measurement >::dimension, Dim > &H, const Measurement &z, const Eigen::Matrix< double, traits< Measurement >::dimension, traits< Measurement >::dimension > &R, bool performReset=true)
Measurement update: Corrects the state and covariance using a pre-calculated predicted measurement an...
Definition ManifoldEKF.h:156
auto KalmanGain(const HMatrix &H, const RMatrix &R) const
Kalman gain K = P H^T S^-1.
Definition ManifoldEKF.h:130
Eigen::Matrix< double, Dim, Dim > Covariance
Definition ManifoldEKF.h:58
void validateInputs(const gtsam::Vector &prediction, const Matrix &H, const gtsam::Vector &z, const Matrix &R)
Validate inputs to update.
Definition ManifoldEKF.h:255
const M & state() const
Definition ManifoldEKF.h:92
Jacobian I_
Definition ManifoldEKF.h:286
void reset(const TangentVector &eta)
Reset step: retract the state by a tangent perturbation and, if available, transport the covariance f...
Definition ManifoldEKF.h:241
void update(MeasurementFunction &&h, const Measurement &z, const Eigen::Matrix< double, traits< Measurement >::dimension, traits< Measurement >::dimension > &R, bool performReset=true)
Measurement update: Corrects the state and covariance using a measurement model function.
Definition ManifoldEKF.h:200
static constexpr int Dim
Definition ManifoldEKF.h:53
G X_
Definition ManifoldEKF.h:284
Eigen::Matrix< double, Dim, Dim > Jacobian
Definition ManifoldEKF.h:60
size_t dimension() const
Definition ManifoldEKF.h:98
ManifoldEKF(const M &X0, const Covariance &P0)
Constructor: initialize with state and covariance.
Definition ManifoldEKF.h:67
static bool isMatrixOfSize(const MatrixType &matrix, size_t rows, size_t cols)
Check whether a matrix has the expected runtime dimensions.
Definition ManifoldEKF.h:277
void JosephUpdate(const GainMatrix &K, const HMatrix &H, const RMatrix &R)
Joseph-form covariance update in the current tangent space using a precomputed gain.
Definition ManifoldEKF.h:138
Covariance P_
Definition ManifoldEKF.h:285
const Covariance & covariance() const
Definition ManifoldEKF.h:95
typename traits< G >::TangentVector TangentVector
Definition ManifoldEKF.h:56
size_t n_
Definition ManifoldEKF.h:287
void predict(const M &X_next, const Jacobian &F, const Covariance &Q)
Basic predict step: Updates state and covariance given the predicted next state and the state transit...
Definition ManifoldEKF.h:114
void updateWithVector(const gtsam::Vector &prediction, const Matrix &H, const gtsam::Vector &z, const Matrix &R, bool performReset=true)
Convenience bridge for wrappers: vector measurement update calling update<Vector>.
Definition ManifoldEKF.h:226