@@ -387,43 +387,42 @@ class EIGEN_ALIGN_MAX Kalman3D_Wave {
387
387
static void PhiAxis4x1_analytic (T tau, T h, Eigen::Matrix<T,4 ,4 >& Phi_axis);
388
388
static void QdAxis4x1_analytic (T tau, T h, T sigma2, Eigen::Matrix<T,4 ,4 >& Qd_axis);
389
389
390
- static inline void joseph_update_rank3 (
391
- Eigen::Matrix<T,NX,1 >& x,
392
- Eigen::Matrix<T,NX,NX>& P,
393
- const Eigen::Matrix<T,3 ,NX>& C,
394
- const Eigen::Matrix<T,3 ,1 >& r,
395
- const Eigen::Matrix<T,3 ,3 >& R)
396
- {
397
- // Innovation covariance
398
- Eigen::Matrix<T,3 ,3 > S = C * P * C.transpose () + R;
399
-
400
- // Factorization (with fallback regularization)
401
- Eigen::LDLT<Eigen::Matrix<T,3 ,3 >> ldlt (S);
402
- bool used_reg = false ;
403
- if (ldlt.info () != Eigen::Success) {
404
- Eigen::Matrix<T,3 ,3 > S_reg = S + Eigen::Matrix<T,3 ,3 >::Identity () *
405
- std::max (std::numeric_limits<T>::epsilon (), T (1e-6 ) * R.norm ());
406
- ldlt.compute (S_reg);
407
- if (ldlt.info () != Eigen::Success) return ;
408
- S = S_reg; // <- make sure Joseph uses the SAME S that produced K
409
- used_reg = true ; (void )used_reg;
410
- }
390
+ template <typename T, bool with_gyro_bias, bool with_accel_bias>
391
+ inline void Kalman3D_Wave<T, with_gyro_bias, with_accel_bias>::joseph_update_rank3(
392
+ Eigen::Matrix<T,NX,1 >& x,
393
+ Eigen::Matrix<T,NX,NX>& P,
394
+ const Eigen::Matrix<T,3 ,NX>& C,
395
+ const Eigen::Matrix<T,3 ,1 >& r,
396
+ const Eigen::Matrix<T,3 ,3 >& R)
397
+ {
398
+ // Innovation covariance
399
+ Eigen::Matrix<T,3 ,3 > S = C * P * C.transpose () + R;
400
+
401
+ // Factorization (with fallback regularization)
402
+ Eigen::LDLT<Eigen::Matrix<T,3 ,3 >> ldlt (S);
403
+ if (ldlt.info () != Eigen::Success) {
404
+ Eigen::Matrix<T,3 ,3 > S_reg = S + Eigen::Matrix<T,3 ,3 >::Identity () *
405
+ std::max (std::numeric_limits<T>::epsilon (), T (1e-6 ) * R.norm ());
406
+ ldlt.compute (S_reg);
407
+ if (ldlt.info () != Eigen::Success) return ;
408
+ }
411
409
412
- // Gain
413
- Eigen::Matrix<T,NX,3 > K = P * C.transpose () * ldlt.solve (Eigen::Matrix<T,3 ,3 >::Identity ());
410
+ // Gain
411
+ Eigen::Matrix<T,NX,3 > K = P * C.transpose () * ldlt.solve (Eigen::Matrix<T,3 ,3 >::Identity ());
414
412
415
- // State
416
- x.noalias () += K * r;
413
+ // State update
414
+ x.noalias () += K * r;
417
415
418
- // Rank-3 Joseph covariance update:
419
- // P' = P - KCP - (KCP)ᵀ + K S Kᵀ with K = P Cᵀ S⁻¹
420
- Eigen::Matrix<T,3 ,NX> CP = C * P; // 3×NX
421
- Eigen::Matrix<T,NX,NX> KC = K * CP; // NX×NX (rank ≤ 3)
422
- P.noalias () = P - KC - KC.transpose () + K * S * K.transpose ();
416
+ // Correct Joseph covariance update (rank-3)
417
+ // P' = P - KCP - (KCP)ᵀ + K R Kᵀ
418
+ Eigen::Matrix<T,3 ,NX> CP = C * P; // 3×NX
419
+ Eigen::Matrix<T,NX,NX> KC = K * CP; // NX×NX (rank ≤ 3)
420
+ P.noalias () = P - KC - KC.transpose () + K * R * K.transpose ();
423
421
424
- // Symmetrize
425
- P = T (0.5 ) * (P + P.transpose ());
426
- }
422
+ // Symmetrize
423
+ P = T (0.5 ) * (P + P.transpose ());
424
+ }
425
+
427
426
};
428
427
429
428
// Implementation
0 commit comments