@@ -395,7 +395,6 @@ class EIGEN_ALIGN_MAX Kalman3D_Wave {
395
395
const Eigen::Matrix<T,3 ,1 >& r,
396
396
const Eigen::Matrix<T,3 ,3 >& R)
397
397
{
398
- // Innovation covariance
399
398
Eigen::Matrix<T,3 ,3 > S = C * P * C.transpose () + R;
400
399
401
400
Eigen::LDLT<Eigen::Matrix<T,3 ,3 >> ldlt (S);
@@ -406,22 +405,17 @@ class EIGEN_ALIGN_MAX Kalman3D_Wave {
406
405
if (ldlt.info () != Eigen::Success) return ;
407
406
}
408
407
409
- // Kalman gain
410
408
Eigen::Matrix<T,NX,3 > K = P * C.transpose () *
411
409
ldlt.solve (Eigen::Matrix<T,3 ,3 >::Identity ());
412
410
413
- // State update
411
+ // state update
414
412
x.noalias () += K * r;
415
413
416
- // Covariance update (Joseph form, numerically stable)
417
- const Eigen::Matrix<T,3 ,NX> CP = C * P;
418
- const Eigen::Matrix<T,NX,NX> KCP = K * CP;
419
- const Eigen::Matrix<T,NX,NX> KSKt = K * R * K.transpose ();
420
-
421
- P.noalias () -= KCP;
422
- P.noalias () -= KCP.transpose ();
423
- P.noalias () += KSKt;
414
+ // covariance update (safe Joseph form)
415
+ Eigen::Matrix<T,NX,NX> I_KC = MatrixNX::Identity () - K * C;
416
+ P.noalias () = I_KC * P * I_KC.transpose () + K * R * K.transpose ();
424
417
418
+ // enforce symmetry
425
419
P = T (0.5 ) * (P + P.transpose ());
426
420
}
427
421
@@ -433,13 +427,11 @@ class EIGEN_ALIGN_MAX Kalman3D_Wave {
433
427
const Eigen::Matrix<T,3 ,1 >& inno,
434
428
const Eigen::Matrix<T,3 ,3 >& R_S)
435
429
{
436
- // Pull out S-block only
437
- Eigen::Matrix<T,NX,3 > P_Scols = P.template block <NX,3 >(0 , off_S);
438
- Eigen::Matrix<T,3 ,NX> P_Srows = P.template block <3 ,NX>(off_S, 0 );
439
- Eigen::Matrix<T,3 ,3 > P_SS = P.template block <3 ,3 >(off_S, off_S);
430
+ // Measurement matrix for pseudo: H selects the S block
431
+ Eigen::Matrix<T,3 ,NX> H = Eigen::Matrix<T,3 ,NX>::Zero ();
432
+ H.template block <3 ,3 >(0 , off_S) = Matrix3::Identity ();
440
433
441
- // Innovation covariance
442
- Eigen::Matrix<T,3 ,3 > S_mat = P_SS + R_S;
434
+ Eigen::Matrix<T,3 ,3 > S_mat = H * P * H.transpose () + R_S;
443
435
Eigen::LDLT<Eigen::Matrix<T,3 ,3 >> ldlt (S_mat);
444
436
if (ldlt.info () != Eigen::Success) {
445
437
S_mat += Eigen::Matrix<T,3 ,3 >::Identity () *
@@ -448,21 +440,17 @@ class EIGEN_ALIGN_MAX Kalman3D_Wave {
448
440
if (ldlt.info () != Eigen::Success) return ;
449
441
}
450
442
451
- // Kalman gain
452
- Eigen::Matrix<T,NX,3 > K = P_Scols *
443
+ Eigen::Matrix<T,NX,3 > K = P * H.transpose () *
453
444
ldlt.solve (Eigen::Matrix<T,3 ,3 >::Identity ());
454
445
455
- // State update
446
+ // state update
456
447
x.noalias () += K * inno;
457
448
458
- // Covariance update (Joseph form, consistent with accel/mag)
459
- const Eigen::Matrix<T,NX,NX> KCP = K * P_Srows;
460
- const Eigen::Matrix<T,NX,NX> KSKt = K * R_S * K.transpose ();
461
-
462
- P.noalias () -= KCP;
463
- P.noalias () -= KCP.transpose ();
464
- P.noalias () += KSKt;
449
+ // covariance update (safe Joseph form)
450
+ Eigen::Matrix<T,NX,NX> I_KH = MatrixNX::Identity () - K * H;
451
+ P.noalias () = I_KH * P * I_KH.transpose () + K * R_S * K.transpose ();
465
452
453
+ // enforce symmetry
466
454
P = T (0.5 ) * (P + P.transpose ());
467
455
}
468
456
};
0 commit comments