@@ -436,6 +436,13 @@ NavState NavState::update(const Vector3& b_acceleration, const Vector3& b_omega,
436436}
437437
438438// ------------------------------------------------------------------------------
439+
440+ // Because our navigation frames are placed on a spinning Earth, we experience two apparent forces on our inertials
441+ // Let Omega be the Earth's rotation rate in the navigation frame
442+ // Coriolis acceleration = -2 * (omega X n_v)
443+ // Centrifugal acceleration (secondOrder) = -omega X (omega X n_t)
444+ // We would also experience a rotation of (omega*dt) over time - so, counteract by compensating rotation by (-omega * dt)
445+ // Integrate centrifugal & coriolis accelerations to yield position, velocity perturbations
439446Vector9 NavState::coriolis (double dt, const Vector3& omega, bool secondOrder,
440447 OptionalJacobian<9 , 9 > H) const {
441448 Rot3 nRb = R_;
@@ -444,37 +451,42 @@ Vector9 NavState::coriolis(double dt, const Vector3& omega, bool secondOrder,
444451 const double dt2 = dt * dt;
445452 const Vector3 omega_cross_vel = omega.cross (n_v);
446453
447- // Get perturbations in nav frame
448- Vector9 n_xi, xi;
449- Matrix3 D_dR_R, D_dP_R, D_dV_R, D_body_nav;
454+ Vector9 n_xi;
455+ // Coriolis (first order) acceleration corrections
450456 dR (n_xi) << ((-dt) * omega);
451457 dP (n_xi) << ((-dt2) * omega_cross_vel); // NOTE(luca): we got rid of the 2 wrt INS paper
452458 dV (n_xi) << ((-2.0 * dt) * omega_cross_vel);
459+
460+ // Centrifugal (second order) acceleration corrections
461+ Matrix3 D_c2_nt; // To store Jacobian (if needed/desired)
453462 if (secondOrder) {
454- const Vector3 omega_cross2_t = omega. cross (omega. cross ( n_t ) );
463+ const Vector3 omega_cross2_t = doubleCross (omega, n_t , nullptr , H ? &D_c2_nt : nullptr );
455464 dP (n_xi) -= (0.5 * dt2) * omega_cross2_t ;
456465 dV (n_xi) -= dt * omega_cross2_t ;
457466 }
458467
459- // Transform n_xi into the body frame
460- xi << nRb.unrotate (dR (n_xi), H ? &D_dR_R : 0 , H ? &D_body_nav : 0 ),
461- nRb.unrotate (dP (n_xi), H ? &D_dP_R : 0 ),
462- nRb.unrotate (dV (n_xi), H ? &D_dV_R : 0 );
468+ // Transform correction from navigation frame -> body frame and get Jacobians
469+ Vector9 xi;
470+ Matrix3 D_dR_R, D_dP_R, D_dV_R;
471+ dR (xi) = nRb.unrotate (dR (n_xi), H ? &D_dR_R : 0 );
472+ dP (xi) = nRb.unrotate (dP (n_xi), H ? &D_dP_R : 0 );
473+ dV (xi) = nRb.unrotate (dV (n_xi), H ? &D_dV_R : 0 );
463474
475+ // Assemble Jacobians
464476 if (H) {
465477 H->setZero ();
466- const Matrix3 Omega = skewSymmetric (omega);
467- const Matrix3 D_cross_state = Omega * R ( );
478+ const Vector3 omega_b = nRb. unrotate (omega);
479+ const Matrix3 D_c1_b = skewSymmetric (omega_b );
468480 H->setZero ();
469481 D_R_R (H) << D_dR_R;
470- D_t_v (H) << D_body_nav * (-dt2) * D_cross_state ;
482+ D_t_v (H) << (-dt2) * D_c1_b ;
471483 D_t_R (H) << D_dP_R;
472- D_v_v (H) << D_body_nav * (-2.0 * dt) * D_cross_state ;
484+ D_v_v (H) << (-2.0 * dt) * D_c1_b ;
473485 D_v_R (H) << D_dV_R;
474486 if (secondOrder) {
475- const Matrix3 D_cross2_state = Omega * D_cross_state ;
476- D_t_t (H) -= D_body_nav * (0.5 * dt2) * D_cross2_state ;
477- D_v_t (H) -= D_body_nav * dt * D_cross2_state ;
487+ Matrix3 D_c2_b = D_c1_b * D_c1_b ;
488+ D_t_t (H) -= (0.5 * dt2) * D_c2_b ;
489+ D_v_t (H) -= dt * D_c2_b ;
478490 }
479491 }
480492 return xi;
0 commit comments