ImuFactor.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #pragma once
  2. #include <ros/assert.h>
  3. #include <iostream>
  4. #include <eigen3/Eigen/Dense>
  5. #include "utils/math_tools.h"
  6. #include "Preintegration.h"
  7. #include <ceres/ceres.h>
  8. class ImuFactor : public ceres::SizedCostFunction<15, 3, 4, 9, 3, 4, 9> {
  9. public:
  10. EIGEN_MAKE_ALIGNED_OPERATOR_NEW
  11. ImuFactor() = delete;
  12. ImuFactor(Preintegration *pre_integration) : pre_integration_{
  13. pre_integration} {
  14. g_vec_ = pre_integration_->g_vec_;
  15. }
  16. virtual bool Evaluate(double const *const *parameters, double *residuals, double **jacobians) const {
  17. Eigen::Vector3d Pi(parameters[0][0], parameters[0][1], parameters[0][2]);
  18. Eigen::Quaterniond Qi(parameters[1][0], parameters[1][1], parameters[1][2], parameters[1][3]);
  19. Qi.normalize();
  20. Eigen::Vector3d Vi(parameters[2][0], parameters[2][1], parameters[2][2]);
  21. Eigen::Vector3d Bai(parameters[2][3], parameters[2][4], parameters[2][5]);
  22. Eigen::Vector3d Bgi(parameters[2][6], parameters[2][7], parameters[2][8]);
  23. Eigen::Vector3d Pj(parameters[3][0], parameters[3][1], parameters[3][2]);
  24. Eigen::Quaterniond Qj(parameters[4][0], parameters[4][1], parameters[4][2], parameters[4][3]);
  25. Qj.normalize();
  26. Eigen::Vector3d Vj(parameters[5][0], parameters[5][1], parameters[5][2]);
  27. Eigen::Vector3d Baj(parameters[5][3], parameters[5][4], parameters[5][5]);
  28. Eigen::Vector3d Bgj(parameters[5][6], parameters[5][7], parameters[5][8]);
  29. Eigen::Map<Eigen::Matrix<double, 15, 1>> residual(residuals);
  30. residual = pre_integration_->evaluate(Pi, Qi, Vi, Bai, Bgi,
  31. Pj, Qj, Vj, Baj, Bgj);
  32. Eigen::Matrix<double, 15, 15> sqrt_info =
  33. Eigen::LLT<Eigen::Matrix<double, 15, 15>>(pre_integration_->covariance_.inverse()).matrixL().transpose();
  34. residual = sqrt_info * residual;
  35. if (jacobians) {
  36. double sum_dt = pre_integration_->sum_dt_;
  37. Eigen::Matrix3d dp_dba = pre_integration_->jacobian_.template block<3, 3>(O_P, O_BA);
  38. Eigen::Matrix3d dp_dbg = pre_integration_->jacobian_.template block<3, 3>(O_P, O_BG);
  39. Eigen::Matrix3d dq_dbg = pre_integration_->jacobian_.template block<3, 3>(O_R, O_BG);
  40. Eigen::Matrix3d dv_dba = pre_integration_->jacobian_.template block<3, 3>(O_V, O_BA);
  41. Eigen::Matrix3d dv_dbg = pre_integration_->jacobian_.template block<3, 3>(O_V, O_BG);
  42. if (pre_integration_->jacobian_.maxCoeff() > 1e8 || pre_integration_->jacobian_.minCoeff() < -1e8) {
  43. ROS_WARN("numerical unstable in preintegration");
  44. }
  45. if (jacobians[0]) {
  46. Eigen::Map<Eigen::Matrix<double, 15, 3, Eigen::RowMajor>> jacobian_pose_i(jacobians[0]);
  47. jacobian_pose_i.setZero();
  48. jacobian_pose_i.block<3, 3>(O_P, O_P) = -Qi.inverse().toRotationMatrix();
  49. jacobian_pose_i = sqrt_info * jacobian_pose_i;
  50. if (jacobian_pose_i.maxCoeff() > 1e8 || jacobian_pose_i.minCoeff() < -1e8) {
  51. ROS_WARN("numerical unstable in preintegration");
  52. }
  53. }
  54. if (jacobians[1]) {
  55. Eigen::Map<Eigen::Matrix<double, 15, 4, Eigen::RowMajor>> jacobian_pose_qi(jacobians[1]);
  56. jacobian_pose_qi.setZero();
  57. Eigen::Vector3d tmp = -0.5 * g_vec_ * sum_dt * sum_dt + Pj - Pi - Vi * sum_dt;
  58. jacobian_pose_qi.block<3, 1>(O_P, 0) = 2 * (Qi.w() * tmp + skewSymmetric(Qi.vec()) * tmp);
  59. jacobian_pose_qi.block<3, 3>(O_P, 1) = 2 * (Qi.vec().dot(tmp) * Eigen::Matrix3d::Identity() + Qi.vec() * tmp.transpose() - tmp * Qi.vec().transpose() - Qi.w() * skewSymmetric(tmp));
  60. Eigen::Quaterniond corrected_delta_q =
  61. pre_integration_->delta_q_ * deltaQ(dq_dbg * (Bgi - pre_integration_->linearized_bg_));
  62. jacobian_pose_qi.block<3, 4>(O_R, 0) =
  63. -2 * (Qleft(Qj.inverse()) * Qright(corrected_delta_q)).bottomRightCorner<3, 4>();
  64. Eigen::Vector3d tmp1 = -g_vec_ * sum_dt + Vj - Vi;
  65. jacobian_pose_qi.block<3, 1>(O_V, 0) = 2 * (Qi.w() * tmp1 + skewSymmetric(Qi.vec()) * tmp1);
  66. jacobian_pose_qi.block<3, 3>(O_V, 1) = 2 * (Qi.vec().dot(tmp1) * Eigen::Matrix3d::Identity() + Qi.vec() * tmp1.transpose() - tmp1 * Qi.vec().transpose() - Qi.w() * skewSymmetric(tmp1));
  67. jacobian_pose_qi = sqrt_info * jacobian_pose_qi;
  68. }
  69. if (jacobians[2]) {
  70. Eigen::Map<Eigen::Matrix<double, 15, 9, Eigen::RowMajor>> jacobian_speedbias_i(jacobians[2]);
  71. jacobian_speedbias_i.setZero();
  72. jacobian_speedbias_i.block<3, 3>(O_P, O_V - O_V) = -Qi.inverse().toRotationMatrix() * sum_dt;
  73. jacobian_speedbias_i.block<3, 3>(O_P, O_BA - O_V) = -dp_dba;
  74. jacobian_speedbias_i.block<3, 3>(O_P, O_BG - O_V) = -dp_dbg;
  75. Eigen::Quaterniond corrected_delta_q =
  76. pre_integration_->delta_q_ * deltaQ(dq_dbg * (Bgi - pre_integration_->linearized_bg_));
  77. jacobian_speedbias_i.block<3, 3>(O_R, O_BG - O_V) =
  78. -LeftQuatMatrix(Qj.inverse() * Qi * corrected_delta_q).topLeftCorner<3, 3>() * dq_dbg;
  79. jacobian_speedbias_i.block<3, 3>(O_V, O_V - O_V) = -Qi.inverse().toRotationMatrix();
  80. jacobian_speedbias_i.block<3, 3>(O_V, O_BA - O_V) = -dv_dba;
  81. jacobian_speedbias_i.block<3, 3>(O_V, O_BG - O_V) = -dv_dbg;
  82. jacobian_speedbias_i.block<3, 3>(O_BA, O_BA - O_V) = -Eigen::Matrix3d::Identity();
  83. jacobian_speedbias_i.block<3, 3>(O_BG, O_BG - O_V) = -Eigen::Matrix3d::Identity();
  84. jacobian_speedbias_i = sqrt_info * jacobian_speedbias_i;
  85. }
  86. if (jacobians[3]) {
  87. Eigen::Map<Eigen::Matrix<double, 15, 3, Eigen::RowMajor>> jacobian_pose_j(jacobians[3]);
  88. jacobian_pose_j.setZero();
  89. jacobian_pose_j.block<3, 3>(O_P, O_P) = Qi.inverse().toRotationMatrix();
  90. jacobian_pose_j = sqrt_info * jacobian_pose_j;
  91. }
  92. if (jacobians[4]) {
  93. Eigen::Map<Eigen::Matrix<double, 15, 4, Eigen::RowMajor>> jacobian_pose_qj(jacobians[4]);
  94. jacobian_pose_qj.setZero();
  95. Eigen::Quaterniond corrected_delta_q =
  96. pre_integration_->delta_q_ * deltaQ(dq_dbg * (Bgi - pre_integration_->linearized_bg_));
  97. jacobian_pose_qj.block<3, 4>(O_R, 0) =
  98. 2 * Qleft(corrected_delta_q.inverse() * Qi.inverse()).bottomRightCorner<3, 4>();
  99. jacobian_pose_qj = sqrt_info * jacobian_pose_qj;
  100. }
  101. if (jacobians[5]) {
  102. Eigen::Map<Eigen::Matrix<double, 15, 9, Eigen::RowMajor>> jacobian_speedbias_j(jacobians[5]);
  103. jacobian_speedbias_j.setZero();
  104. jacobian_speedbias_j.block<3, 3>(O_V, O_V - O_V) = Qi.inverse().toRotationMatrix();
  105. jacobian_speedbias_j.block<3, 3>(O_BA, O_BA - O_V) = Eigen::Matrix3d::Identity();
  106. jacobian_speedbias_j.block<3, 3>(O_BG, O_BG - O_V) = Eigen::Matrix3d::Identity();
  107. jacobian_speedbias_j = sqrt_info * jacobian_speedbias_j;
  108. }
  109. }
  110. return true;
  111. }
  112. Preintegration *pre_integration_;
  113. Eigen::Vector3d g_vec_;
  114. };