Preintegration.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. #ifndef INTEGRATIONBASE_H_
  2. #define INTEGRATIONBASE_H_
  3. #include <Eigen/Eigen>
  4. #include "utils/math_tools.h"
  5. #include "utils/common.h"
  6. using Eigen::Vector3d;
  7. using Eigen::Matrix;
  8. using Eigen::Matrix3d;
  9. using Eigen::MatrixXd;
  10. using Eigen::Quaterniond;
  11. enum StateOrder {
  12. O_P = 0,
  13. O_R = 3,
  14. O_V = 6,
  15. O_BA = 9,
  16. O_BG = 12,
  17. };
  18. class Preintegration {
  19. public:
  20. EIGEN_MAKE_ALIGNED_OPERATOR_NEW
  21. Preintegration() = delete;
  22. Preintegration(const Vector3d &acc0, const Vector3d &gyr0,
  23. const Vector3d &linearized_ba, const Vector3d &linearized_bg)
  24. : acc0_{acc0},
  25. gyr0_{gyr0},
  26. linearized_acc_{acc0},
  27. linearized_gyr_{gyr0},
  28. linearized_ba_{linearized_ba},
  29. linearized_bg_{linearized_bg},
  30. jacobian_{Matrix<double, 15, 15>::Identity()},
  31. sum_dt_{0.0},
  32. delta_p_{Vector3d::Zero()},
  33. delta_q_{Quaterniond::Identity()},
  34. delta_v_{Vector3d::Zero()} {
  35. // acc_n = 0.00059;
  36. // gyr_n = 0.000061;
  37. // acc_w = 0.000011;
  38. // gyr_w = 0.000001;
  39. nh.param<double>("/IMU/acc_n", acc_n, 0.00059);
  40. nh.param<double>("/IMU/gyr_n", gyr_n, 0.000061);
  41. nh.param<double>("/IMU/acc_w", acc_w, 0.000011);
  42. nh.param<double>("/IMU/gyr_w", gyr_w, 0.000001);
  43. covariance_ = 0.001 * Matrix<double, 15, 15>::Identity();
  44. g_vec_ = -Eigen::Vector3d(0, 0, 9.805);
  45. noise_ = Matrix<double, 18, 18>::Zero();
  46. noise_.block<3, 3>(0, 0) = (acc_n * acc_n) * Matrix3d::Identity();
  47. noise_.block<3, 3>(3, 3) = (gyr_n * gyr_n) * Matrix3d::Identity();
  48. noise_.block<3, 3>(6, 6) = (acc_n * acc_n) * Matrix3d::Identity();
  49. noise_.block<3, 3>(9, 9) = (gyr_n * gyr_n) * Matrix3d::Identity();
  50. noise_.block<3, 3>(12, 12) = (acc_w * acc_w) * Matrix3d::Identity();
  51. noise_.block<3, 3>(15, 15) = (gyr_w * gyr_w) * Matrix3d::Identity();
  52. }
  53. void push_back(double dt, const Vector3d &acc, const Vector3d &gyr) {
  54. dt_buf_.push_back(dt);
  55. acc_buf_.push_back(acc);
  56. gyr_buf_.push_back(gyr);
  57. Propagate(dt, acc, gyr);
  58. }
  59. void Repropagate(const Vector3d &linearized_ba, const Vector3d &linearized_bg) {
  60. sum_dt_ = 0.0;
  61. acc0_ = linearized_acc_;
  62. gyr0_ = linearized_gyr_;
  63. delta_p_.setZero();
  64. delta_q_.setIdentity();
  65. delta_v_.setZero();
  66. linearized_ba_ = linearized_ba;
  67. linearized_bg_ = linearized_bg;
  68. jacobian_.setIdentity();
  69. covariance_.setZero();
  70. for (size_t i = 0; i < dt_buf_.size(); ++i) {
  71. Propagate(dt_buf_[i], acc_buf_[i], gyr_buf_[i]);
  72. }
  73. }
  74. void MidPointIntegration(double dt,
  75. const Vector3d &acc0, const Vector3d &gyr0,
  76. const Vector3d &acc1, const Vector3d &gyr1,
  77. const Vector3d &delta_p, const Quaterniond &delta_q,
  78. const Vector3d &delta_v, const Vector3d &linearized_ba,
  79. const Vector3d &linearized_bg, Vector3d &result_delta_p,
  80. Quaterniond &result_delta_q, Vector3d &result_delta_v,
  81. Vector3d &result_linearized_ba, Vector3d &result_linearized_bg,
  82. bool update_jacobian) {
  83. Vector3d un_acc_0 = delta_q * (acc0 - linearized_ba);
  84. Vector3d un_gyr = 0.5 * (gyr0 + gyr1) - linearized_bg;
  85. result_delta_q = delta_q * Quaterniond(1, un_gyr(0) * dt / 2, un_gyr(1) * dt / 2, un_gyr(2) * dt / 2);
  86. Vector3d un_acc_1 = result_delta_q * (acc1 - linearized_ba);
  87. Vector3d un_acc = 0.5 * (un_acc_0 + un_acc_1);
  88. result_delta_p = delta_p + delta_v * dt + 0.5 * un_acc * dt * dt;
  89. result_delta_v = delta_v + un_acc * dt;
  90. result_linearized_ba = linearized_ba;
  91. result_linearized_bg = linearized_bg;
  92. if (update_jacobian) {
  93. Vector3d w_x = 0.5 * (gyr0 + gyr1) - linearized_bg;
  94. Vector3d a_0_x = acc0 - linearized_ba;
  95. Vector3d a_1_x = acc1 - linearized_ba;
  96. Matrix3d R_w_x, R_a_0_x, R_a_1_x;
  97. R_w_x << 0, -w_x(2), w_x(1),
  98. w_x(2), 0, -w_x(0),
  99. -w_x(1), w_x(0), 0;
  100. R_a_0_x << 0, -a_0_x(2), a_0_x(1),
  101. a_0_x(2), 0, -a_0_x(0),
  102. -a_0_x(1), a_0_x(0), 0;
  103. R_a_1_x << 0, -a_1_x(2), a_1_x(1),
  104. a_1_x(2), 0, -a_1_x(0),
  105. -a_1_x(1), a_1_x(0), 0;
  106. MatrixXd F = MatrixXd::Zero(15, 15);
  107. F.block<3, 3>(0, 0) = Matrix3d::Identity();
  108. F.block<3, 3>(0, 3) = -0.25*delta_q.toRotationMatrix() * R_a_0_x * dt * dt +
  109. -0.25 * result_delta_q.toRotationMatrix() * R_a_1_x * (Matrix3d::Identity() - R_w_x * dt) * dt * dt;
  110. F.block<3, 3>(0, 6) = MatrixXd::Identity(3, 3) * dt;
  111. F.block<3, 3>(0, 9) = -0.25*(delta_q.toRotationMatrix() + result_delta_q.toRotationMatrix()) * dt * dt;
  112. F.block<3, 3>(0, 12) = -0.1667*result_delta_q.toRotationMatrix() * R_a_1_x * dt * dt * -dt;
  113. F.block<3, 3>(3, 3) = Matrix3d::Identity() - R_w_x * dt;
  114. F.block<3, 3>(3, 12) = -MatrixXd::Identity(3, 3) * dt;
  115. F.block<3, 3>(6, 3) = -0.5*delta_q.toRotationMatrix() * R_a_0_x * dt +
  116. -0.5 * result_delta_q.toRotationMatrix() * R_a_1_x * (Matrix3d::Identity() - R_w_x * dt) * dt;
  117. F.block<3, 3>(6, 6) = Matrix3d::Identity();
  118. F.block<3, 3>(6, 9) = -0.5*(delta_q.toRotationMatrix() + result_delta_q.toRotationMatrix()) * dt;
  119. F.block<3, 3>(6, 12) = -0.5*result_delta_q.toRotationMatrix() * R_a_1_x * dt * -dt;
  120. F.block<3, 3>(9, 9) = Matrix3d::Identity();
  121. F.block<3, 3>(12, 12) = Matrix3d::Identity();
  122. // NOTE: V = Fd * G_c
  123. // FIXME: verify if it is right, the 0.25 part
  124. MatrixXd V = MatrixXd::Zero(15, 18);
  125. V.block<3, 3>(0, 0) = 0.5 * delta_q.toRotationMatrix() * dt * dt;
  126. V.block<3, 3>(0, 3) = -0.25*result_delta_q.toRotationMatrix() * R_a_1_x * dt * dt * 0.5 * dt;
  127. V.block<3, 3>(0, 6) = 0.5 * result_delta_q.toRotationMatrix() * dt * dt;
  128. V.block<3, 3>(0, 9) = V.block<3, 3>(0, 3);
  129. V.block<3, 3>(3, 3) = 0.5*MatrixXd::Identity(3, 3) * dt;
  130. V.block<3, 3>(3, 9) = 0.5*MatrixXd::Identity(3, 3) * dt;
  131. V.block<3, 3>(6, 0) = 0.5*delta_q.toRotationMatrix() * dt;
  132. V.block<3, 3>(6, 3) = 0.5*-result_delta_q.toRotationMatrix() * R_a_1_x * dt * 0.5 * dt;
  133. V.block<3, 3>(6, 6) = 0.5*result_delta_q.toRotationMatrix() * dt;
  134. V.block<3, 3>(6, 9) = V.block<3, 3>(6, 3);
  135. V.block<3, 3>(9, 12) = MatrixXd::Identity(3, 3) * dt;
  136. V.block<3, 3>(12, 15) = MatrixXd::Identity(3, 3) * dt;
  137. jacobian_ = F * jacobian_;
  138. covariance_ = F * covariance_ * F.transpose() + V * noise_ * V.transpose();
  139. }
  140. }
  141. void Propagate(double dt, const Vector3d &acc1, const Vector3d &gyr1) {
  142. dt_ = dt;
  143. acc1_ = acc1;
  144. gyr1_ = gyr1;
  145. Vector3d result_delta_p;
  146. Quaterniond result_delta_q;
  147. Vector3d result_delta_v;
  148. Vector3d result_linearized_ba;
  149. Vector3d result_linearized_bg;
  150. MidPointIntegration(dt, acc0_, gyr0_, acc1, gyr1, delta_p_, delta_q_, delta_v_,
  151. linearized_ba_, linearized_bg_,
  152. result_delta_p, result_delta_q, result_delta_v,
  153. result_linearized_ba, result_linearized_bg, true);
  154. delta_p_ = result_delta_p;
  155. delta_q_ = result_delta_q;
  156. delta_v_ = result_delta_v;
  157. linearized_ba_ = result_linearized_ba;
  158. linearized_bg_ = result_linearized_bg;
  159. delta_q_.normalize();
  160. sum_dt_ += dt_;
  161. acc0_ = acc1_;
  162. gyr0_ = gyr1_;
  163. }
  164. Matrix<double, 15, 1> evaluate(const Vector3d &Pi,
  165. const Quaterniond &Qi,
  166. const Vector3d &Vi,
  167. const Vector3d &Bai,
  168. const Vector3d &Bgi,
  169. const Vector3d &Pj,
  170. const Quaterniond &Qj,
  171. const Vector3d &Vj,
  172. const Vector3d &Baj,
  173. const Vector3d &Bgj) {
  174. // NOTE: low cost update jacobian here
  175. Matrix<double, 15, 1> residuals;
  176. residuals.setZero();
  177. Matrix3d dp_dba = jacobian_.block<3, 3>(O_P, O_BA);
  178. Matrix3d dp_dbg = jacobian_.block<3, 3>(O_P, O_BG);
  179. Matrix3d dq_dbg = jacobian_.block<3, 3>(O_R, O_BG);
  180. Matrix3d dv_dba = jacobian_.block<3, 3>(O_V, O_BA);
  181. Matrix3d dv_dbg = jacobian_.block<3, 3>(O_V, O_BG);
  182. Vector3d dba = Bai - linearized_ba_;
  183. Vector3d dbg = Bgi - linearized_bg_; // NOTE: optimized one minus the linearized one
  184. Quaterniond corrected_delta_q = delta_q_ * deltaQ(dq_dbg * dbg);
  185. Vector3d corrected_delta_v = delta_v_ + dv_dba * dba + dv_dbg * dbg;
  186. Vector3d corrected_delta_p = delta_p_ + dp_dba * dba + dp_dbg * dbg;
  187. residuals.block<3, 1>(O_P, 0) =
  188. Qi.inverse() * (-0.5 * g_vec_ * sum_dt_ * sum_dt_ + Pj - Pi - Vi * sum_dt_) - corrected_delta_p;
  189. residuals.block<3, 1>(O_R, 0) = 2.0 * (corrected_delta_q.inverse() * (Qi.inverse() * Qj)).normalized().vec();
  190. residuals.block<3, 1>(O_V, 0) = Qi.inverse() * (-g_vec_ * sum_dt_ + Vj - Vi) - corrected_delta_v;
  191. residuals.block<3, 1>(O_BA, 0) = Baj - Bai;
  192. residuals.block<3, 1>(O_BG, 0) = Bgj - Bgi;
  193. return residuals;
  194. }
  195. double dt_;
  196. Vector3d acc0_, gyr0_;
  197. Vector3d acc1_, gyr1_;
  198. const Vector3d linearized_acc_, linearized_gyr_;
  199. Vector3d linearized_ba_, linearized_bg_;
  200. Matrix<double, 15, 15> jacobian_, covariance_;
  201. Matrix<double, 18, 18> noise_;
  202. double sum_dt_;
  203. Vector3d delta_p_;
  204. Quaterniond delta_q_;
  205. Vector3d delta_v_;
  206. std::vector<double> dt_buf_;
  207. std::vector<Vector3d> acc_buf_;
  208. std::vector<Vector3d> gyr_buf_;
  209. Eigen::Vector3d g_vec_;
  210. double nf, cf;
  211. double acc_n;
  212. double gyr_n;
  213. double acc_w;
  214. double gyr_w;
  215. ros::NodeHandle nh;
  216. };
  217. #endif //INTEGRATIONBASE_H_