Vulcan
Aerospace Engineering Utilities Built on Janus
Loading...
Searching...
No Matches
EstimationUtils.hpp
Go to the documentation of this file.
1// Estimation Utilities - Helper functions for Kalman filtering
2// Part of Vulcan - Aerospace Engineering Utilities
3#pragma once
4
5#include <Eigen/Dense>
6#include <janus/janus.hpp>
7
8namespace vulcan::estimation {
9
10// =============================================================================
11// Innovation Statistics
12// =============================================================================
13
28template <typename Scalar, int M>
29Scalar
30normalized_innovation_squared(const Eigen::Matrix<Scalar, M, 1> &innovation,
31 const Eigen::Matrix<Scalar, M, M> &S) {
32 return (innovation.transpose() * S.inverse() * innovation)(0, 0);
33}
34
35// =============================================================================
36// Measurement Gating
37// =============================================================================
38
57template <typename Scalar, int M>
58bool passes_gate(const Eigen::Matrix<Scalar, M, 1> &innovation,
59 const Eigen::Matrix<Scalar, M, M> &S, double threshold) {
60 Scalar nis = normalized_innovation_squared<Scalar, M>(innovation, S);
61 return static_cast<double>(nis) <= threshold;
62}
63
78template <typename Scalar, int M>
79bool measurement_passes_gate(const Eigen::Matrix<Scalar, M, 1> &z,
80 const Eigen::Matrix<Scalar, M, 1> &z_pred,
81 const Eigen::Matrix<Scalar, M, M> &S,
82 double threshold) {
83 Eigen::Matrix<Scalar, M, 1> innovation = z - z_pred;
84 return passes_gate<Scalar, M>(innovation, S, threshold);
85}
86
87// =============================================================================
88// Joseph Form Covariance Update
89// =============================================================================
90
109template <int N, int M>
110Eigen::Matrix<double, N, N>
111joseph_update(const Eigen::Matrix<double, N, N> &P_prior,
112 const Eigen::Matrix<double, N, M> &K,
113 const Eigen::Matrix<double, M, N> &H,
114 const Eigen::Matrix<double, M, M> &R) {
115 Eigen::Matrix<double, N, N> I = Eigen::Matrix<double, N, N>::Identity();
116 Eigen::Matrix<double, N, N> IKH = I - K * H;
117
118 // Joseph form: P = (I-KH)*P*(I-KH)ᵀ + K*R*Kᵀ
119 return IKH * P_prior * IKH.transpose() + K * R * K.transpose();
120}
121
122// =============================================================================
123// Common Chi-Squared Thresholds
124// =============================================================================
125
136inline double chi_squared_threshold(int dof, double confidence = 0.95) {
137 // Pre-computed values for common cases
138 if (confidence >= 0.99) {
139 switch (dof) {
140 case 1:
141 return 6.635;
142 case 2:
143 return 9.210;
144 case 3:
145 return 11.345;
146 case 4:
147 return 13.277;
148 case 5:
149 return 15.086;
150 case 6:
151 return 16.812;
152 default:
153 // Approximation for larger dof at 99%
154 return dof + 2.33 * std::sqrt(2.0 * dof);
155 }
156 } else {
157 // 95% confidence
158 switch (dof) {
159 case 1:
160 return 3.841;
161 case 2:
162 return 5.991;
163 case 3:
164 return 7.815;
165 case 4:
166 return 9.488;
167 case 5:
168 return 11.070;
169 case 6:
170 return 12.592;
171 default:
172 // Approximation for larger dof at 95%
173 return dof + 1.645 * std::sqrt(2.0 * dof);
174 }
175 }
176}
177
178// =============================================================================
179// Covariance Symmetry Enforcement
180// =============================================================================
181
193template <int N>
194Eigen::Matrix<double, N, N> symmetrize(const Eigen::Matrix<double, N, N> &P) {
195 return 0.5 * (P + P.transpose());
196}
197
198} // namespace vulcan::estimation
Definition EstimationTypes.hpp:8
Scalar normalized_innovation_squared(const Eigen::Matrix< Scalar, M, 1 > &innovation, const Eigen::Matrix< Scalar, M, M > &S)
Compute normalized innovation squared (NIS).
Definition EstimationUtils.hpp:30
bool passes_gate(const Eigen::Matrix< Scalar, M, 1 > &innovation, const Eigen::Matrix< Scalar, M, M > &S, double threshold)
Chi-squared gating for outlier rejection.
Definition EstimationUtils.hpp:58
Eigen::Matrix< double, N, N > joseph_update(const Eigen::Matrix< double, N, N > &P_prior, const Eigen::Matrix< double, N, M > &K, const Eigen::Matrix< double, M, N > &H, const Eigen::Matrix< double, M, M > &R)
Joseph form covariance update.
Definition EstimationUtils.hpp:111
double chi_squared_threshold(int dof, double confidence=0.95)
Chi-squared threshold lookup.
Definition EstimationUtils.hpp:136
Eigen::Matrix< double, N, N > symmetrize(const Eigen::Matrix< double, N, N > &P)
Enforce covariance matrix symmetry.
Definition EstimationUtils.hpp:194
bool measurement_passes_gate(const Eigen::Matrix< Scalar, M, 1 > &z, const Eigen::Matrix< Scalar, M, 1 > &z_pred, const Eigen::Matrix< Scalar, M, M > &S, double threshold)
Compute innovation and check gate in one call.
Definition EstimationUtils.hpp:79