@@ -394,21 +394,34 @@ class EIGEN_ALIGN_MAX Kalman3D_Wave {
394
394
const Eigen::Matrix<T,3 ,1 >& r,
395
395
const Eigen::Matrix<T,3 ,3 >& R)
396
396
{
397
+ // Innovation covariance
397
398
Eigen::Matrix<T,3 ,3 > S = C * P * C.transpose () + R;
399
+
400
+ // Factorization (with fallback regularization)
398
401
Eigen::LDLT<Eigen::Matrix<T,3 ,3 >> ldlt (S);
402
+ bool used_reg = false ;
399
403
if (ldlt.info () != Eigen::Success) {
400
404
Eigen::Matrix<T,3 ,3 > S_reg = S + Eigen::Matrix<T,3 ,3 >::Identity () *
401
405
std::max (std::numeric_limits<T>::epsilon (), T (1e-6 ) * R.norm ());
402
406
ldlt.compute (S_reg);
403
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;
404
410
}
405
411
412
+ // Gain
406
413
Eigen::Matrix<T,NX,3 > K = P * C.transpose () * ldlt.solve (Eigen::Matrix<T,3 ,3 >::Identity ());
414
+
415
+ // State
407
416
x.noalias () += K * r;
408
417
409
- Eigen::Matrix<T,3 ,NX> CP = C * P;
410
- Eigen::Matrix<T,NX,NX> KC = K * CP;
411
- P.noalias () = P - KC - KC.transpose () + K * R * K.transpose ();
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 ();
423
+
424
+ // Symmetrize
412
425
P = T (0.5 ) * (P + P.transpose ());
413
426
}
414
427
};
0 commit comments