odom.cpp 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #include "odom/odom.h"
  2. namespace hlzn_slam {
  3. namespace odom {
  4. void odom::addOdometry(const float x, const float y, const float yaw)
  5. {
  6. LOCK()
  7. odometry odom;
  8. odom.odom = common::Rigid2f(common::Rigid2f::Vector({x, y}), yaw);
  9. odom.time = std::chrono::system_clock::now();
  10. if (!odometry_.empty()) {
  11. std::chrono::duration<float> dur = odom.time - odometry_.front().time;
  12. if (dur.count() > 1.0) {
  13. odometry_.pop_front();
  14. }
  15. }
  16. odometry_.push_back(odom);
  17. }
  18. bool odom::extrapolaOdom(const common::Time& start_time,
  19. const common::Time& end_time,
  20. common::Rigid2f& T) {
  21. LOCK()
  22. if (odometry_.empty()) return false;
  23. odometry start_odom, end_odom;
  24. float start_close_minmal = 1e5, end_close_minmal = 1e5;
  25. // 在里程计序列中找到与时间戳最紧密的两帧数据
  26. for (const odometry& odom : odometry_) {
  27. std::chrono::duration<float> start_close = start_time - odom.time;
  28. std::chrono::duration<float> end_close = end_time - odom.time;
  29. if (start_close_minmal > fabs(start_close.count())) {
  30. start_odom = odom;
  31. start_close_minmal = fabs(start_close.count());
  32. }
  33. if (end_close_minmal > fabs(end_close.count())) {
  34. end_odom = odom;
  35. end_close_minmal = fabs(end_close.count());
  36. }
  37. }
  38. // 300 ms
  39. // std::cout<<" "<<end_close_minmal<<" "<<start_close_minmal<<std::endl;
  40. if (end_close_minmal > 3e-1 || start_close_minmal > 3e-1) {
  41. return false;
  42. }
  43. common::Rigid2f::Vector translation = start_odom.odom.rotation().inverse() * end_odom.odom.translation() -
  44. start_odom.odom.rotation().inverse() * start_odom.odom.translation();
  45. Eigen::Rotation2D<float> rotation = start_odom.odom.rotation().cast<float>().inverse() * end_odom.odom.rotation().cast<float>();
  46. T = common::Rigid2f(translation, rotation.cast<float>());
  47. return true;
  48. }
  49. bool odom::extrapolaOdom(const common::Rigid2f& start_odom, const common::Time& end_time,
  50. common::Rigid2f& T) {
  51. LOCK()
  52. if (odometry_.empty()) return false;
  53. odometry end_odom;
  54. float end_close_minmal = 1e5;
  55. // 在里程计序列中找到与时间戳最紧密的两帧数据
  56. for (const odometry& odom : odometry_) {
  57. std::chrono::duration<float> end_close = end_time - odom.time;
  58. if (end_close_minmal > fabs(end_close.count())) {
  59. end_odom = odom;
  60. end_close_minmal = fabs(end_close.count());
  61. }
  62. }
  63. // 300 ms
  64. // std::cout<<" "<<end_close_minmal<<" "<<close_start_elapsed_seconds<<std::endl;
  65. if (end_close_minmal > 3e-1) {
  66. return false;
  67. }
  68. common::Rigid2f::Vector translation = start_odom.rotation().inverse() * end_odom.odom.translation() -
  69. start_odom.rotation().inverse() * start_odom.translation();
  70. Eigen::Rotation2D<float> rotation = start_odom.rotation().cast<float>().inverse() * end_odom.odom.rotation().cast<float>();
  71. T = common::Rigid2f(translation, rotation.cast<float>());
  72. return true;
  73. }
  74. }
  75. }