Todd Lupton and Salah Sukkarieh, “Visual-Inertial-Aided Navigation
for High-Dynamic Motion in Built Environments Without Initial
Conditions”, TRO, 28(1):61-76, 2012.
同时基于流形空间进行了优化,基于以下两篇论文
Luca Carlone, Zsolt Kira, Chris Beall, Vadim Indelman, and Frank
Dellaert, “Eliminating conditionally independent sets in factor graphs:
a unifying perspective based on smart factors”, Int. Conf. on Robotics
and Automation (ICRA), 2014.
Christian Forster, Luca Carlone, Frank Dellaert, and Davide
Scaramuzza, “IMU Preintegration on Manifold for Efficient
Visual-Inertial Maximum-a-Posteriori Estimation”, Robotics: Science and
Systems (RSS), 2015.
voidPreintegrationBase::integrateMeasurement(const Vector3& measuredAcc, const Vector3& measuredOmega, double dt){ // NOTE(frank): integrateMeasurement always needs to compute the derivatives, // even when not of interest to the caller. Provide scratch space here. Matrix9 A; Matrix93 B, C; update(measuredAcc, measuredOmega, dt, &A, &B, &C); }
voidTangentPreintegration::update(const Vector3& measuredAcc, const Vector3& measuredOmega, constdouble dt, Matrix9* A, Matrix93* B, Matrix93* C){ // Correct for bias in the sensor frame Vector3 acc = biasHat_.correctAccelerometer(measuredAcc); Vector3 omega = biasHat_.correctGyroscope(measuredOmega);
// Possibly correct for sensor pose Matrix3 D_correctedAcc_acc, D_correctedAcc_omega, D_correctedOmega_omega; if (p().body_P_sensor) boost::tie(acc, omega) = correctMeasurementsBySensorPose(acc, omega, D_correctedAcc_acc, D_correctedAcc_omega, D_correctedOmega_omega);
// Do update deltaTij_ += dt; preintegrated_ = UpdatePreintegrated(acc, omega, dt, preintegrated_, A, B, C);
if (p().body_P_sensor) { // More complicated derivatives in case of non-trivial sensor pose *C *= D_correctedOmega_omega; if (!p().body_P_sensor->translation().isZero()) *C += *B * D_correctedAcc_omega; *B *= D_correctedAcc_acc; // NOTE(frank): needs to be last }
// Compensate for sensor-body displacement if needed: we express the quantities // (originally in the IMU frame) into the body frame // Equations below assume the "body" frame is the CG
// Get sensor to body rotation matrix const Matrix3 bRs = p().body_P_sensor->rotation().matrix();
// Convert angular velocity and acceleration from sensor to body frame Vector3 correctedAcc = bRs * unbiasedAcc; const Vector3 correctedOmega = bRs * unbiasedOmega;
// Jacobians if (correctedAcc_H_unbiasedAcc) *correctedAcc_H_unbiasedAcc = bRs; if (correctedAcc_H_unbiasedOmega) *correctedAcc_H_unbiasedOmega = Z_3x3; if (correctedOmega_H_unbiasedOmega) *correctedOmega_H_unbiasedOmega = bRs;
// Centrifugal acceleration const Vector3 b_arm = p().body_P_sensor->translation(); if (!b_arm.isZero()) { // Subtract out the the centripetal acceleration from the unbiased one // to get linear acceleration vector in the body frame: const Matrix3 body_Omega_body = skewSymmetric(correctedOmega); const Vector3 b_velocity_bs = body_Omega_body * b_arm; // magnitude: omega * arm correctedAcc -= body_Omega_body * b_velocity_bs;
// This functor allows for saving computation when exponential map and its // derivatives are needed at the same location in so<3> so3::DexpFunctor local(theta);
// Calculate exact mean propagation Matrix3 w_tangent_H_theta, invH; const Vector3 w_tangent = // angular velocity mapped back to tangent space local.applyInvDexp(w_body, A ? &w_tangent_H_theta : 0, C ? &invH : 0); const SO3 R = local.expmap(); const Vector3 a_nav = R * a_body; constdouble dt22 = 0.5 * dt * dt;
本质就是以右扰动定义的雅克比,参见下文献中的公式10.86的\(J_r(x)\),此外注意这里的\(\omega\)是初始化local的时候传入的\(\theta\),不是测量的角速度\(\omega\) >Gregory S. Chirikjian.
“Stochastic Models, Information Theory, and Lie Groups, Volume 2”
(2012).