WheelFactor.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. //
  2. // Created by zx on 23-9-20.
  3. //
  4. #include "WheelFactor.h"
  5. #include <pcl/io/pcd_io.h>
  6. WheelsPredictor::WheelsPredictor() {
  7. valid_ = false;
  8. length_ = 0;
  9. wheelBase_ = 0;
  10. width_ = 0;
  11. diff_ = 0;
  12. }
  13. WheelsPredictor::~WheelsPredictor() = default;
  14. void WheelsPredictor::reset() {
  15. valid_ = false;
  16. }
  17. bool WheelsPredictor::update(pcl::PointCloud<pcl::PointXYZ>::Ptr src, double cx, double cy, double theta,
  18. double width, double wheelbase) {
  19. if (src->empty()) {
  20. LOG(WARNING) << "cloud is empty,cloud size:" + std::to_string(src->size());
  21. return false;
  22. }
  23. LOG(INFO) << "input params -----> cx: " << cx << ", cy: " << cy << ", theta: "
  24. << theta << ", width: " << width << ", wheelbase: " << wheelbase;
  25. pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
  26. pcl::copyPointCloud(*src, *cloud);
  27. //绕原点摆正
  28. float minx = 1e8, maxx = -1e8, miny = 1e8, maxy = -1e8;
  29. float t_minx = 1e8, t_maxx = -1e8;
  30. for (auto &point: cloud->points) {
  31. pcl::PointXYZ pt(point);
  32. t_minx = MIN(t_minx, point.x);
  33. t_maxx = MAX(t_maxx, point.x);
  34. point.x = pt.x * cos(-theta) - pt.y * sin(-theta);
  35. point.y = pt.x * sin(-theta) + pt.y * cos(-theta);
  36. minx = MIN(minx, point.x);
  37. maxx = MAX(maxx, point.x);
  38. miny = MIN(miny, point.y);
  39. maxy = MAX(maxy, point.y);
  40. }
  41. float car_y = (miny + maxy) / 2.f;
  42. LOG(INFO) << "befor trans -----> t_minx: " << t_minx << ", t_maxx: " << t_maxx;
  43. LOG(INFO) << "minx: " << minx << ", maxx: " << maxx << ", miny: " << miny << ", maxy: " << maxy;
  44. minx = 1e8, maxx = -1e8;
  45. for (auto &point:cloud->points) {
  46. if (point.y < car_y - 0.5 || point.y > car_y + 0.5) {
  47. continue;
  48. }
  49. minx = MIN(minx, point.x);
  50. maxx = MAX(maxx, point.x);
  51. }
  52. float car_x = (minx + maxx) / 2.;
  53. LOG(INFO) << "after only use body-----> minx: " << minx << ", maxx: " << maxx;
  54. length_ = maxy - miny;
  55. float x = cx * cos(-theta) - cy * sin(-theta);
  56. float y = cx * sin(-theta) + cy * cos(-theta);
  57. LOG(INFO) << "carx - wheel x = (" << car_x << " - " << x << ") = " << car_x - x;
  58. if (fabs(car_x - x) < 0.03) {
  59. diff_ = y - car_y;
  60. width_ = width;
  61. wheelBase_ = wheelbase;
  62. LOG(INFO) << "update diff: " << diff_ << ", width: " << width_ << ", wheelbase: " << wheelBase_;
  63. valid_ = true;
  64. } else {
  65. valid_ = false;
  66. }
  67. return valid_;
  68. }
  69. bool WheelsPredictor::predict(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, double theta, PreResult &res) {
  70. if (!valid_) {
  71. return false;
  72. }
  73. float minx = 1e8, maxx = -1e8, miny = 1e8, maxy = -1e8;
  74. for (int i = 0; i < cloud->size(); ++i) {
  75. pcl::PointXYZ pt = cloud->points[i];
  76. float x = pt.x * cos(-theta) - pt.y * sin(-theta);
  77. float y = pt.x * sin(-theta) + pt.y * cos(-theta);
  78. cloud->points[i].x = x;
  79. cloud->points[i].y = y;
  80. if (x < minx) minx = x;
  81. if (x > maxx) maxx = x;
  82. if (y < miny) miny = y;
  83. if (y > maxy) maxy = y;
  84. }
  85. float car_x = (minx + maxx) / 2.;
  86. float car_y = (miny + maxy) / 2.;
  87. minx = 1e8, maxx = -1e8;
  88. for (int i = 0; i < cloud->size(); ++i) {
  89. pcl::PointXYZ pt = cloud->points[i];
  90. if (pt.y < car_y + 0.5 && pt.y > car_y - 0.5) {
  91. if (pt.x < minx) minx = pt.x;
  92. if (pt.x > maxx) maxx = pt.x;
  93. }
  94. }
  95. car_x = (minx + maxx) / 2.;
  96. float length = fabs(maxy - miny);
  97. if (fabs(length_ - length) < 0.1) {
  98. float x = car_x;
  99. float y = car_y + diff_;
  100. res.x = x * cos(theta) - y * sin(theta);
  101. res.y = x * sin(theta) + y * cos(theta);
  102. res.theta = theta;
  103. res.w = width_;
  104. res.wheelBase = wheelBase_;
  105. res.frontTheta = 0;
  106. return true;
  107. }
  108. return false;
  109. }