detect_wheel_ceres.cpp 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122
  1. //
  2. // Created by zx on 2020/7/1.
  3. //
  4. #include "detect_wheel_ceres.h"
  5. #include <ceres/cubic_interpolation.h>
  6. #include <pcl/common/transforms.h>
  7. #include <pcl/sample_consensus/ransac.h>
  8. #include <pcl/sample_consensus/sac_model_line.h> // 拟合直线
  9. #include <pcl/ModelCoefficients.h> //导入ModelCoefficients(模型系数)结构
  10. #include <pcl/filters/project_inliers.h> //导入ProjectInliers滤波器
  11. class CostDynFunc {
  12. std::vector<double> line_l_;
  13. std::vector<double> line_r_;
  14. std::vector<double> line_y_;
  15. double length_;
  16. double width_;
  17. pcl::PointCloud<pcl::PointXYZ>::Ptr m_left_front_cloud; //左前点云
  18. pcl::PointCloud<pcl::PointXYZ>::Ptr m_right_front_cloud; //右前点云
  19. pcl::PointCloud<pcl::PointXYZ>::Ptr m_left_rear_cloud; //左后点云
  20. pcl::PointCloud<pcl::PointXYZ>::Ptr m_right_rear_cloud; //右后点云
  21. public:
  22. CostDynFunc(pcl::PointCloud<pcl::PointXYZ>::Ptr left_front, pcl::PointCloud<pcl::PointXYZ>::Ptr right_front,
  23. pcl::PointCloud<pcl::PointXYZ>::Ptr left_rear, pcl::PointCloud<pcl::PointXYZ>::Ptr right_rear,
  24. std::vector<double> linel, std::vector<double> liner, std::vector<double> liney, double width,
  25. double length) {
  26. line_l_ = linel;
  27. line_r_ = liner;
  28. line_y_ = liney;
  29. width_ = width;
  30. length_ = length;
  31. m_left_front_cloud = left_front;
  32. m_right_front_cloud = right_front;
  33. m_left_rear_cloud = left_rear;
  34. m_right_rear_cloud = right_rear;
  35. }
  36. template<typename T>
  37. bool operator()(const T *const variable, T *residual) const {
  38. T cx = variable[0];
  39. T cy = variable[1];
  40. T theta = variable[2];
  41. T theta_front = variable[3];
  42. //整车旋转
  43. Eigen::Rotation2D<T> rotation(theta);
  44. Eigen::Matrix<T, 2, 2> rotation_matrix = rotation.toRotationMatrix();
  45. //左前偏移
  46. Eigen::Matrix<T, 2, 1> wheel_center_normal_left_front(T(-width_ / 2.0), T(length_ / 2.0));
  47. //右前偏移
  48. Eigen::Matrix<T, 2, 1> wheel_center_normal_right_front(T(width_ / 2.0), T(length_ / 2.0));
  49. //左后偏移
  50. Eigen::Matrix<T, 2, 1> wheel_center_normal_left_rear(T(-width_ / 2.0), T(-length_ / 2.0));
  51. //右后偏移
  52. Eigen::Matrix<T, 2, 1> wheel_center_normal_right_rear(T(width_ / 2.0), T(-length_ / 2.0));
  53. //前轮旋转
  54. Eigen::Rotation2D<T> rotation_front(theta_front);
  55. Eigen::Matrix<T, 2, 2> rotation_matrix_front = rotation_front.toRotationMatrix();
  56. ceres::Grid1D<double> grid_l(line_l_.data(), 0, line_l_.size());
  57. ceres::CubicInterpolator<ceres::Grid1D<double>> interpolator_l(grid_l);
  58. ceres::Grid1D<double> grid_r(line_r_.data(), 0, line_r_.size());
  59. ceres::CubicInterpolator<ceres::Grid1D<double>> interpolator_r(grid_r);
  60. ceres::Grid1D<double> grid_y(line_y_.data(), 0, line_y_.size());
  61. ceres::CubicInterpolator<ceres::Grid1D<double>> interpolator_y(grid_y);
  62. //左前轮
  63. int left_front_num = m_left_front_cloud->size();
  64. for (int i = 0; i < m_left_front_cloud->size(); ++i) {
  65. const Eigen::Matrix<T, 2, 1> point((T(m_left_front_cloud->points[i].x) + cx),
  66. (T(m_left_front_cloud->points[i].y) + cy));
  67. //减去经过车辆旋转计算的左前中心
  68. const Eigen::Matrix<T, 2, 1> tanslate_point = rotation_matrix * point - wheel_center_normal_left_front;
  69. //旋转
  70. const Eigen::Matrix<T, 2, 1> point_rotation = rotation_matrix_front * tanslate_point;
  71. interpolator_l.Evaluate(point_rotation[0] * T(1000.) + T(200.), &residual[2 * i]);
  72. interpolator_y.Evaluate(point_rotation[1] * T(1000.) + T(1000.), &residual[2 * i + 1]);
  73. }
  74. //右前轮
  75. int right_front_num = m_right_front_cloud->size();
  76. for (int i = 0; i < m_right_front_cloud->size(); ++i) {
  77. const Eigen::Matrix<T, 2, 1> point((T(m_right_front_cloud->points[i].x) + cx),
  78. (T(m_right_front_cloud->points[i].y) + cy));
  79. //减去经过车辆旋转计算的左前中心
  80. const Eigen::Matrix<T, 2, 1> tanslate_point = rotation_matrix * point - wheel_center_normal_right_front;
  81. //旋转
  82. const Eigen::Matrix<T, 2, 1> point_rotation = rotation_matrix_front * tanslate_point;
  83. interpolator_r.Evaluate(point_rotation[0] * T(1000.) + T(1000.), &residual[2 * left_front_num + 2 * i]);
  84. interpolator_y.Evaluate(point_rotation[1] * T(1000.) + T(1000.), &residual[2 * left_front_num + 2 * i + 1]);
  85. }
  86. //左后轮
  87. int left_rear_num = m_left_rear_cloud->size();
  88. for (int i = 0; i < m_left_rear_cloud->size(); ++i) {
  89. const Eigen::Matrix<T, 2, 1> point((T(m_left_rear_cloud->points[i].x) + cx),
  90. (T(m_left_rear_cloud->points[i].y) + cy));
  91. //减去经过车辆旋转计算的左前中心
  92. const Eigen::Matrix<T, 2, 1> tanslate_point = rotation_matrix * point - wheel_center_normal_left_rear;
  93. interpolator_l.Evaluate(tanslate_point[0] * T(1000.) + T(200.),
  94. &residual[2 * (left_front_num + right_front_num + i)]);
  95. interpolator_y.Evaluate(tanslate_point[1] * T(1000.) + T(1000.),
  96. &residual[2 * (left_front_num + right_front_num) + 2 * i + 1]);
  97. }
  98. //右后轮
  99. for (int i = 0; i < m_right_rear_cloud->size(); ++i) {
  100. const Eigen::Matrix<T, 2, 1> point((T(m_right_rear_cloud->points[i].x) + cx),
  101. (T(m_right_rear_cloud->points[i].y) + cy));
  102. //减去经过车辆旋转计算的左前中心
  103. const Eigen::Matrix<T, 2, 1> tanslate_point = rotation_matrix * point - wheel_center_normal_right_rear;
  104. interpolator_r.Evaluate(tanslate_point[0] * T(1000.) + T(1000.),
  105. &residual[2 * (left_front_num + right_front_num + left_rear_num + i)]);
  106. interpolator_y.Evaluate(tanslate_point[1] * T(1000.) + T(1000.),
  107. &residual[2 * (left_front_num + right_front_num + left_rear_num) + 2 * i + 1]);
  108. }
  109. return true;
  110. }
  111. };
  112. class CostRYFunc {
  113. private:
  114. std::vector<double> line_y_;
  115. pcl::PointCloud<pcl::PointXYZ>::Ptr m_left_front_cloud; //左前点云
  116. pcl::PointCloud<pcl::PointXYZ>::Ptr m_right_front_cloud; //右前点云
  117. pcl::PointCloud<pcl::PointXYZ>::Ptr m_left_rear_cloud; //左后点云
  118. pcl::PointCloud<pcl::PointXYZ>::Ptr m_right_rear_cloud; //右后点云
  119. public:
  120. CostRYFunc(pcl::PointCloud<pcl::PointXYZ>::Ptr left_front, pcl::PointCloud<pcl::PointXYZ>::Ptr right_front,
  121. pcl::PointCloud<pcl::PointXYZ>::Ptr left_rear, pcl::PointCloud<pcl::PointXYZ>::Ptr right_rear,
  122. std::vector<double> liney) {
  123. line_y_ = liney;
  124. m_left_front_cloud = left_front;
  125. m_right_front_cloud = right_front;
  126. m_left_rear_cloud = left_rear;
  127. m_right_rear_cloud = right_rear;
  128. }
  129. template<typename T>
  130. bool operator()(const T *const variable, T *residual) const {
  131. T cy = variable[0];
  132. T theta = variable[1];
  133. T length = variable[2];
  134. //整车旋转
  135. Eigen::Rotation2D<T> rotation(theta);
  136. Eigen::Matrix<T, 2, 2> rotation_matrix = rotation.toRotationMatrix();
  137. //左前偏移
  138. Eigen::Matrix<T, 2, 1> wheel_center_normal_left_front(-0 / 2.0, length / 2.0);
  139. //右前偏移
  140. Eigen::Matrix<T, 2, 1> wheel_center_normal_right_front(0 / 2.0, length / 2.0);
  141. //左后偏移
  142. Eigen::Matrix<T, 2, 1> wheel_center_normal_left_rear(-0 / 2.0, -length / 2.0);
  143. //右后偏移
  144. Eigen::Matrix<T, 2, 1> wheel_center_normal_right_rear(0 / 2.0, -length / 2.0);
  145. ceres::Grid1D<double> grid_y(line_y_.data(), 0, line_y_.size());
  146. ceres::CubicInterpolator<ceres::Grid1D<double>> interpolator_y(grid_y);
  147. T weight = T(0.3);
  148. //左前轮
  149. int left_front_num = m_left_front_cloud->size();
  150. for (int i = 0; i < m_left_front_cloud->size(); ++i) {
  151. const Eigen::Matrix<T, 2, 1> point((T(m_left_front_cloud->points[i].x)),
  152. (T(m_left_front_cloud->points[i].y)));
  153. const Eigen::Matrix<T, 2, 1> tp(T(0), -cy);
  154. //减去经过车辆旋转计算的左前中心
  155. const Eigen::Matrix<T, 2, 1> point_rotation = rotation_matrix * point + tp - wheel_center_normal_left_front;
  156. interpolator_y.Evaluate(point_rotation[1] * T(1000.) + T(1000.), &residual[i]);
  157. residual[i] = residual[i] * weight;
  158. }
  159. //右前轮
  160. int right_front_num = m_right_front_cloud->size();
  161. for (int i = 0; i < m_right_front_cloud->size(); ++i) {
  162. const Eigen::Matrix<T, 2, 1> point((T(m_right_front_cloud->points[i].x)),
  163. (T(m_right_front_cloud->points[i].y)));
  164. const Eigen::Matrix<T, 2, 1> tp(T(0), -cy);
  165. //减去经过车辆旋转计算的左前中心
  166. const Eigen::Matrix<T, 2, 1> point_rotation =
  167. rotation_matrix * point + tp - wheel_center_normal_right_front;
  168. interpolator_y.Evaluate(point_rotation[1] * T(1000.) + T(1000.), &residual[left_front_num + i]);
  169. residual[left_front_num + i] = residual[left_front_num + i] * weight;
  170. }
  171. //左后轮
  172. int left_rear_num = m_left_rear_cloud->size();
  173. for (int i = 0; i < m_left_rear_cloud->size(); ++i) {
  174. const Eigen::Matrix<T, 2, 1> point((T(m_left_rear_cloud->points[i].x)),
  175. (T(m_left_rear_cloud->points[i].y)));
  176. const Eigen::Matrix<T, 2, 1> tp(T(0), -cy);
  177. //减去经过车辆旋转计算的左前中心
  178. const Eigen::Matrix<T, 2, 1> tanslate_point = rotation_matrix * point + tp - wheel_center_normal_left_rear;
  179. interpolator_y.Evaluate(tanslate_point[1] * T(1000.) + T(1000.),
  180. &residual[(left_front_num + right_front_num) + i]);
  181. }
  182. //右后轮
  183. for (int i = 0; i < m_right_rear_cloud->size(); ++i) {
  184. const Eigen::Matrix<T, 2, 1> point((T(m_right_rear_cloud->points[i].x)),
  185. (T(m_right_rear_cloud->points[i].y)));
  186. const Eigen::Matrix<T, 2, 1> tp(T(0), -cy);
  187. //减去经过车辆旋转计算的左前中心
  188. const Eigen::Matrix<T, 2, 1> tanslate_point = rotation_matrix * point + tp - wheel_center_normal_right_rear;
  189. interpolator_y.Evaluate(tanslate_point[1] * T(1000.) + T(1000.),
  190. &residual[left_front_num + right_front_num + left_rear_num + i]);
  191. }
  192. return true;
  193. }
  194. private:
  195. };
  196. class CostRXFunc {
  197. private:
  198. std::vector<double> line_x_;
  199. pcl::PointCloud<pcl::PointXYZ>::Ptr m_left_front_cloud; //左前点云
  200. pcl::PointCloud<pcl::PointXYZ>::Ptr m_right_front_cloud; //右前点云
  201. pcl::PointCloud<pcl::PointXYZ>::Ptr m_left_rear_cloud; //左后点云
  202. pcl::PointCloud<pcl::PointXYZ>::Ptr m_right_rear_cloud; //右后点云
  203. public:
  204. CostRXFunc(pcl::PointCloud<pcl::PointXYZ>::Ptr left_front, pcl::PointCloud<pcl::PointXYZ>::Ptr right_front,
  205. pcl::PointCloud<pcl::PointXYZ>::Ptr left_rear, pcl::PointCloud<pcl::PointXYZ>::Ptr right_rear,
  206. std::vector<double> linex) {
  207. line_x_ = linex;
  208. m_left_front_cloud = left_front;
  209. m_right_front_cloud = right_front;
  210. m_left_rear_cloud = left_rear;
  211. m_right_rear_cloud = right_rear;
  212. }
  213. template<typename T>
  214. bool operator()(const T *const variable, T *residual) const {
  215. T cx = variable[0];
  216. T theta = variable[1];
  217. //整车旋转
  218. Eigen::Rotation2D<T> rotation(theta);
  219. Eigen::Matrix<T, 2, 2> rotation_matrix = rotation.toRotationMatrix();
  220. ceres::Grid1D<double> grid_x(line_x_.data(), 0, line_x_.size());
  221. ceres::CubicInterpolator<ceres::Grid1D<double>> interpolator_x(grid_x);
  222. T weight = T(1.0);
  223. //左前轮
  224. int left_front_num = m_left_front_cloud->size();
  225. for (int i = 0; i < m_left_front_cloud->size(); ++i) {
  226. const Eigen::Matrix<T, 2, 1> point((T(m_left_front_cloud->points[i].x)),
  227. (T(m_left_front_cloud->points[i].y)));
  228. const Eigen::Matrix<T, 2, 1> tp(cx, T(0));
  229. //减去经过车辆旋转计算的左前中心
  230. const Eigen::Matrix<T, 2, 1> point_rotation = rotation_matrix * point + tp;
  231. interpolator_x.Evaluate(point_rotation[0] * T(1000.) + T(1000.), &residual[i]);
  232. residual[i] = residual[i] * weight;
  233. }
  234. //右前轮
  235. int right_front_num = m_right_front_cloud->size();
  236. for (int i = 0; i < m_right_front_cloud->size(); ++i) {
  237. const Eigen::Matrix<T, 2, 1> point((T(m_right_front_cloud->points[i].x)),
  238. (T(m_right_front_cloud->points[i].y)));
  239. const Eigen::Matrix<T, 2, 1> tp(cx, T(0));
  240. //减去经过车辆旋转计算的左前中心
  241. const Eigen::Matrix<T, 2, 1> point_rotation = rotation_matrix * point + tp;
  242. interpolator_x.Evaluate(point_rotation[0] * T(1000.) + T(1000.), &residual[left_front_num + i]);
  243. residual[left_front_num + i] = residual[left_front_num + i] * weight;
  244. }
  245. //左后轮
  246. int left_rear_num = m_left_rear_cloud->size();
  247. for (int i = 0; i < m_left_rear_cloud->size(); ++i) {
  248. const Eigen::Matrix<T, 2, 1> point((T(m_left_rear_cloud->points[i].x)),
  249. (T(m_left_rear_cloud->points[i].y)));
  250. const Eigen::Matrix<T, 2, 1> tp(cx, T(0));
  251. //减去经过车辆旋转计算的左前中心
  252. const Eigen::Matrix<T, 2, 1> tanslate_point = rotation_matrix * point + tp;
  253. interpolator_x.Evaluate(tanslate_point[0] * T(1000.) + T(1000.),
  254. &residual[(left_front_num + right_front_num) + i]);
  255. }
  256. //右后轮
  257. for (int i = 0; i < m_right_rear_cloud->size(); ++i) {
  258. const Eigen::Matrix<T, 2, 1> point((T(m_right_rear_cloud->points[i].x)),
  259. (T(m_right_rear_cloud->points[i].y)));
  260. const Eigen::Matrix<T, 2, 1> tp(cx, T(0));
  261. //减去经过车辆旋转计算的左前中心
  262. const Eigen::Matrix<T, 2, 1> tanslate_point = rotation_matrix * point + tp;
  263. interpolator_x.Evaluate(tanslate_point[0] * T(1000.) + T(1000.),
  264. &residual[left_front_num + right_front_num + left_rear_num + i]);
  265. }
  266. return true;
  267. }
  268. private:
  269. };
  270. class CostXYWFFunc {
  271. std::vector<double> line_l_;
  272. std::vector<double> line_r_;
  273. std::vector<double> line_y_;
  274. double length_;
  275. double theta_;
  276. pcl::PointCloud<pcl::PointXYZ>::Ptr m_left_front_cloud; //左前点云
  277. pcl::PointCloud<pcl::PointXYZ>::Ptr m_right_front_cloud; //右前点云
  278. pcl::PointCloud<pcl::PointXYZ>::Ptr m_left_rear_cloud; //左后点云
  279. pcl::PointCloud<pcl::PointXYZ>::Ptr m_right_rear_cloud; //右后点云
  280. public:
  281. CostXYWFFunc(pcl::PointCloud<pcl::PointXYZ>::Ptr left_front, pcl::PointCloud<pcl::PointXYZ>::Ptr right_front,
  282. pcl::PointCloud<pcl::PointXYZ>::Ptr left_rear, pcl::PointCloud<pcl::PointXYZ>::Ptr right_rear,
  283. std::vector<double> linel, std::vector<double> liner, std::vector<double> liney,
  284. double theta, double length) {
  285. line_l_ = linel;
  286. line_r_ = liner;
  287. line_y_ = liney;
  288. length_ = length;
  289. theta_ = theta;
  290. m_left_front_cloud = left_front;
  291. m_right_front_cloud = right_front;
  292. m_left_rear_cloud = left_rear;
  293. m_right_rear_cloud = right_rear;
  294. }
  295. template<typename T>
  296. bool operator()(const T *const variable, T *residual) const {
  297. T cx = variable[0];
  298. T cy = variable[1];
  299. T width = variable[2];
  300. T theta_front = variable[3];
  301. T theta = T(theta_);
  302. //整车旋转
  303. Eigen::Rotation2D<T> rotation(theta);
  304. Eigen::Matrix<T, 2, 2> rotation_matrix = rotation.toRotationMatrix();
  305. //左前偏移
  306. Eigen::Matrix<T, 2, 1> wheel_center_normal_left_front(-width / 2.0, T(length_) / 2.0);
  307. //右前偏移
  308. Eigen::Matrix<T, 2, 1> wheel_center_normal_right_front(width / 2.0, T(length_) / 2.0);
  309. //左后偏移
  310. Eigen::Matrix<T, 2, 1> wheel_center_normal_left_rear(-width / 2.0, -T(length_) / 2.0);
  311. //右后偏移
  312. Eigen::Matrix<T, 2, 1> wheel_center_normal_right_rear(width / 2.0, -T(length_) / 2.0);
  313. //前轮旋转
  314. Eigen::Rotation2D<T> rotation_front(theta_front);
  315. Eigen::Matrix<T, 2, 2> rotation_matrix_front = rotation_front.toRotationMatrix();
  316. T weight = T(0.5);
  317. ceres::Grid1D<double> grid_l(line_l_.data(), 0, line_l_.size());
  318. ceres::CubicInterpolator<ceres::Grid1D<double>> interpolator_l(grid_l);
  319. ceres::Grid1D<double> grid_r(line_r_.data(), 0, line_r_.size());
  320. ceres::CubicInterpolator<ceres::Grid1D<double>> interpolator_r(grid_r);
  321. ceres::Grid1D<double> grid_y(line_y_.data(), 0, line_y_.size());
  322. ceres::CubicInterpolator<ceres::Grid1D<double>> interpolator_y(grid_y);
  323. //左前轮
  324. int left_front_num = m_left_front_cloud->size();
  325. for (int i = 0; i < m_left_front_cloud->size(); ++i) {
  326. const Eigen::Matrix<T, 2, 1> point((T(m_left_front_cloud->points[i].x) - cx),
  327. (T(m_left_front_cloud->points[i].y) - cy));
  328. //减去经过车辆旋转计算的左前中心
  329. const Eigen::Matrix<T, 2, 1> tanslate_point = rotation_matrix * point - wheel_center_normal_left_front;
  330. //旋转
  331. const Eigen::Matrix<T, 2, 1> point_rotation = rotation_matrix_front * tanslate_point;
  332. interpolator_l.Evaluate(point_rotation[0] * T(1000.) + T(200.), &residual[2 * i]);
  333. interpolator_y.Evaluate(point_rotation[1] * T(1000.) + T(1000.), &residual[2 * i + 1]);
  334. residual[2 * i] = residual[2 * i] * weight;
  335. }
  336. //右前轮
  337. int right_front_num = m_right_front_cloud->size();
  338. for (int i = 0; i < m_right_front_cloud->size(); ++i) {
  339. const Eigen::Matrix<T, 2, 1> point((T(m_right_front_cloud->points[i].x) - cx),
  340. (T(m_right_front_cloud->points[i].y) - cy));
  341. //减去经过车辆旋转计算的左前中心
  342. const Eigen::Matrix<T, 2, 1> tanslate_point = rotation_matrix * point - wheel_center_normal_right_front;
  343. //旋转
  344. const Eigen::Matrix<T, 2, 1> point_rotation = rotation_matrix_front * tanslate_point;
  345. interpolator_r.Evaluate(point_rotation[0] * T(1000.) + T(1000.), &residual[2 * left_front_num + 2 * i]);
  346. interpolator_y.Evaluate(point_rotation[1] * T(1000.) + T(1000.), &residual[2 * left_front_num + 2 * i + 1]);
  347. residual[2 * left_front_num + 2 * i] = residual[2 * left_front_num + 2 * i] * weight;
  348. }
  349. //左后轮
  350. int left_rear_num = m_left_rear_cloud->size();
  351. for (int i = 0; i < m_left_rear_cloud->size(); ++i) {
  352. const Eigen::Matrix<T, 2, 1> point((T(m_left_rear_cloud->points[i].x) - cx),
  353. (T(m_left_rear_cloud->points[i].y) - cy));
  354. //减去经过车辆旋转计算的左前中心
  355. const Eigen::Matrix<T, 2, 1> tanslate_point = rotation_matrix * point - wheel_center_normal_left_rear;
  356. interpolator_l.Evaluate(tanslate_point[0] * T(1000.) + T(200.),
  357. &residual[2 * (left_front_num + right_front_num + i)]);
  358. interpolator_y.Evaluate(tanslate_point[1] * T(1000.) + T(1000.),
  359. &residual[2 * (left_front_num + right_front_num) + 2 * i + 1]);
  360. }
  361. //右后轮
  362. for (int i = 0; i < m_right_rear_cloud->size(); ++i) {
  363. const Eigen::Matrix<T, 2, 1> point((T(m_right_rear_cloud->points[i].x) - cx),
  364. (T(m_right_rear_cloud->points[i].y) - cy));
  365. //减去经过车辆旋转计算的左前中心
  366. const Eigen::Matrix<T, 2, 1> tanslate_point = rotation_matrix * point - wheel_center_normal_right_rear;
  367. interpolator_r.Evaluate(tanslate_point[0] * T(1000.) + T(1000.),
  368. &residual[2 * (left_front_num + right_front_num + left_rear_num + i)]);
  369. interpolator_y.Evaluate(tanslate_point[1] * T(1000.) + T(1000.),
  370. &residual[2 * (left_front_num + right_front_num + left_rear_num) + 2 * i + 1]);
  371. }
  372. return true;
  373. }
  374. };
  375. detect_wheel_ceres::detect_wheel_ceres() {
  376. FILE *filel = fopen("./cuve_l.txt", "w");
  377. for (int i = 0; i < 1200; i++) {
  378. double x = double(i - 200) * 0.001;
  379. double y = std::max(1.0 / (1. + exp(-400. * (-x - 0.02))), 1. - exp(-x * x));
  380. m_line_l.push_back(y);
  381. fprintf(filel, "%f %f 0\n", x, y);
  382. }
  383. fclose(filel);
  384. FILE *filer = fopen("./cuve_r.txt", "w");
  385. for (int i = 0; i < 1200; i++) {
  386. double x = double(i - 1000) * 0.001;
  387. double y = std::max(1.0 / (1. + exp(-400. * (x - 0.02))), 1. - exp(-x * x));
  388. m_line_r.push_back(y);
  389. fprintf(filer, "%f %f 0\n", x, y);
  390. }
  391. fclose(filer);
  392. FILE *filey = fopen("./cuve_y.txt", "w");
  393. for (int i = 0; i < 2000; i++) {
  394. double x = double(i - 1000) * 0.001;
  395. m_line_y.push_back(1. - exp(-0.5 * x * x));
  396. m_line_y_2stp.push_back(1. - exp(-2 * x * x));
  397. fprintf(filey, "%f %f 0\n", x, 1. - exp(-0.5 * x * x));
  398. fprintf(filey, "%f %f 0\n", x, 1. - exp(-2 * x * x));
  399. }
  400. fclose(filey);
  401. FILE *filex = fopen("./cuve_x.txt", "w");
  402. for (int i = 0; i < 2000; i++) {
  403. double x = double(i - 1000) * 0.001;
  404. double y = 1.0 + 1.0 / (1.0 + exp(-49. * (x - 0.9))) - 1 / (1 + exp(-49. * (x + 0.9)));
  405. m_line_x.push_back(y);
  406. fprintf(filex, "%f %f 0\n", x, y);
  407. }
  408. fclose(filex);
  409. }
  410. detect_wheel_ceres::~detect_wheel_ceres() {}
  411. bool detect_wheel_ceres::detect_dynP(pcl::PointCloud<pcl::PointXYZ>::Ptr cl1, pcl::PointCloud<pcl::PointXYZ>::Ptr cl2,
  412. pcl::PointCloud<pcl::PointXYZ>::Ptr cl3, pcl::PointCloud<pcl::PointXYZ>::Ptr cl4,
  413. float &cx, float &cy, float &theta, float &wheel_base, float &width,
  414. float &front_theta, float &loss) {
  415. m_left_front_cloud = filter(cl1, 1.5);
  416. m_right_front_cloud = filter(cl2, 1.5);
  417. m_left_rear_cloud = filter(cl3, 1.5);
  418. m_right_rear_cloud = filter(cl4, 1.5);
  419. double variable[] = {cx, cy, theta, front_theta};
  420. auto t1 = std::chrono::steady_clock::now();
  421. // 第二部分:构建寻优问题
  422. ceres::Problem problem;
  423. ceres::CostFunction *cost_function = new
  424. ceres::AutoDiffCostFunction<CostDynFunc, ceres::DYNAMIC, 4>(
  425. new CostDynFunc(m_left_front_cloud, m_right_front_cloud, m_left_rear_cloud, m_right_rear_cloud,
  426. m_line_l, m_line_r, m_line_y, width, wheel_base),
  427. 2 * (m_left_front_cloud->size() + m_right_front_cloud->size() + m_left_rear_cloud->size() +
  428. m_right_rear_cloud->size()));
  429. problem.AddResidualBlock(cost_function, NULL, variable); //向问题中添加误差项,本问题比较简单,添加一个就行。
  430. //第三部分: 配置并运行求解器
  431. ceres::Solver::Options options;
  432. options.use_nonmonotonic_steps = false;
  433. options.linear_solver_type = ceres::DENSE_QR; //配置增量方程的解法
  434. options.max_num_iterations = 1000;
  435. options.num_threads = 2;
  436. options.minimizer_progress_to_stdout = false;//输出到cout
  437. ceres::Solver::Summary summary;//优化信息
  438. ceres::Solve(options, &problem, &summary);//求解!!!
  439. auto t2 = std::chrono::steady_clock::now();
  440. auto duration = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1);
  441. double time =
  442. double(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den;
  443. loss = summary.final_cost / (m_left_front_cloud->size() + m_right_front_cloud->size() + m_left_rear_cloud->size() +
  444. m_right_rear_cloud->size());
  445. cx = variable[0];
  446. cy = variable[1];
  447. theta = variable[2];
  448. front_theta = variable[3];
  449. if (loss > 0.05) {
  450. return false;
  451. }
  452. //save(*m_left_front_cloud,*m_right_front_cloud,*m_left_rear_cloud,*m_right_rear_cloud,cx,cy,theta,wheel_base,width,front_theta);
  453. return true;
  454. }
  455. float cost(pcl::PointCloud<pcl::PointXYZ>::Ptr cl1, pcl::PointCloud<pcl::PointXYZ>::Ptr cl2,
  456. pcl::PointCloud<pcl::PointXYZ>::Ptr cl3, pcl::PointCloud<pcl::PointXYZ>::Ptr cl4,
  457. std::vector<double> line_y_,
  458. float cy, float wheelbase, float theta) {
  459. //整车旋转
  460. Eigen::Rotation2D<float> rotation(-theta);
  461. Eigen::Matrix<float, 2, 2> rotation_matrix = rotation.toRotationMatrix();
  462. //左前偏移
  463. Eigen::Matrix<float, 2, 1> wheel_center_normal_left_front(-0 / 2.0, wheelbase / 2.0);
  464. //右前偏移
  465. Eigen::Matrix<float, 2, 1> wheel_center_normal_right_front(0 / 2.0, wheelbase / 2.0);
  466. //左后偏移
  467. Eigen::Matrix<float, 2, 1> wheel_center_normal_left_rear(-0 / 2.0, -wheelbase / 2.0);
  468. //右后偏移
  469. Eigen::Matrix<float, 2, 1> wheel_center_normal_right_rear(0 / 2.0, -wheelbase / 2.0);
  470. ceres::Grid1D<double> grid_y(line_y_.data(), 0, line_y_.size());
  471. ceres::CubicInterpolator<ceres::Grid1D<double>> interpolator_y(grid_y);
  472. float weight = 1;
  473. //左前轮
  474. float loss = 0.;
  475. int left_front_num = cl1->size();
  476. FILE *lf = fopen("./lf.txt", "w");
  477. FILE *rf = fopen("./rf.txt", "w");
  478. FILE *lb = fopen("./lb.txt", "w");
  479. FILE *rb = fopen("./rb.txt", "w");
  480. for (int i = 0; i < cl1->size(); ++i) {
  481. const Eigen::Matrix<float, 2, 1> point(cl1->points[i].x, cl1->points[i].y);
  482. const Eigen::Matrix<float, 2, 1> tp((0), -cy);
  483. //减去经过车辆旋转计算的左前中心
  484. const Eigen::Matrix<float, 2, 1> point_rotation = rotation_matrix * point + tp - wheel_center_normal_left_front;
  485. double cost = 0.0;
  486. interpolator_y.Evaluate(point_rotation[1] * float(1000.) + float(1000.), &cost);
  487. cost = cost * weight;
  488. loss += cost * cost;
  489. fprintf(lf, "%f %f %f\n", point_rotation[1], cl1->points[i].z, point_rotation[0]);
  490. }
  491. //右前轮
  492. int right_front_num = cl2->size();
  493. for (int i = 0; i < cl2->size(); ++i) {
  494. const Eigen::Matrix<float, 2, 1> point(cl2->points[i].x, cl2->points[i].y);
  495. const Eigen::Matrix<float, 2, 1> tp(float(0), -cy);
  496. //减去经过车辆旋转计算的左前中心
  497. const Eigen::Matrix<float, 2, 1> point_rotation =
  498. rotation_matrix * point + tp - wheel_center_normal_right_front;
  499. double cost = 0.0;
  500. interpolator_y.Evaluate(point_rotation[1] * float(1000.) + float(1000.), &cost);
  501. cost = cost * weight;
  502. loss += cost * cost;
  503. fprintf(rf, "%f %f %f\n", point_rotation[1], cl2->points[i].z, point_rotation[0]);
  504. }
  505. //左后轮
  506. int left_rear_num = cl3->size();
  507. for (int i = 0; i < cl3->size(); ++i) {
  508. const Eigen::Matrix<float, 2, 1> point(cl3->points[i].x, cl3->points[i].y);
  509. const Eigen::Matrix<float, 2, 1> tp(0, -cy);
  510. //减去经过车辆旋转计算的左前中心
  511. const Eigen::Matrix<float, 2, 1> tanslate_point = rotation_matrix * point + tp - wheel_center_normal_left_rear;
  512. double cost = 0.0;
  513. interpolator_y.Evaluate(tanslate_point[1] * float(1000.) + float(1000.), &cost);
  514. cost = cost * weight;
  515. loss += cost * cost;
  516. fprintf(lb, "%f %f %f\n", tanslate_point[1], cl3->points[i].z, tanslate_point[0]);
  517. }
  518. //右后轮
  519. for (int i = 0; i < cl4->size(); ++i) {
  520. const Eigen::Matrix<float, 2, 1> point(cl4->points[i].x, cl4->points[i].y);
  521. const Eigen::Matrix<float, 2, 1> tp(0, -cy);
  522. //减去经过车辆旋转计算的左前中心
  523. const Eigen::Matrix<float, 2, 1> tanslate_point = rotation_matrix * point + tp - wheel_center_normal_right_rear;
  524. double cost = 0.0;
  525. interpolator_y.Evaluate(tanslate_point[1] * float(1000.) + float(1000.), &cost);
  526. cost = cost * weight;
  527. loss += cost * cost;
  528. fprintf(rb, "%f %f %f\n", tanslate_point[1], cl4->points[i].z, tanslate_point[0]);
  529. }
  530. fclose(lf);
  531. fclose(rf);
  532. fclose(lb);
  533. fclose(rb);
  534. return loss;
  535. }
  536. bool detect_wheel_ceres::ransicLine(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,
  537. pcl::PointXYZ &center, double &theta) {
  538. if (cloud->size() < 10)
  539. return false;
  540. for (int i = 0; i < cloud->size(); ++i) {
  541. cloud->points[i].z = 0;
  542. }
  543. pcl::SampleConsensusModelLine<pcl::PointXYZ>::Ptr model_line(
  544. new pcl::SampleConsensusModelLine<pcl::PointXYZ>(cloud));
  545. pcl::RandomSampleConsensus<pcl::PointXYZ> ransac(model_line);
  546. ransac.setDistanceThreshold(0.02); //内点到模型的最大距离
  547. ransac.setMaxIterations(1000); //最大迭代次数
  548. ransac.computeModel(); //直线拟合
  549. //-------------------------根据索引提取内点--------------------------
  550. pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_line(new pcl::PointCloud<pcl::PointXYZ>);
  551. std::vector<int> inliers; //存储内点索引的容器
  552. ransac.getInliers(inliers); //提取内点索引
  553. pcl::copyPointCloud<pcl::PointXYZ>(*cloud, inliers, *cloud_line);
  554. //----------------------------输出模型参数---------------------------
  555. Eigen::VectorXf coefficient;
  556. ransac.getModelCoefficients(coefficient);
  557. theta = atan(coefficient[3] / coefficient[4]);
  558. pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients());
  559. coefficients->values.resize(6);
  560. for (int i = 0; i < 6; ++i) {
  561. coefficients->values[i] = coefficient[i];
  562. }
  563. // ------------------------------投影到平面---------------------------------------
  564. pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_projected(new pcl::PointCloud<pcl::PointXYZ>);
  565. pcl::ProjectInliers<pcl::PointXYZ> proj;
  566. proj.setModelType(pcl::SACMODEL_LINE); //创建投影类型,投影到直线上
  567. proj.setInputCloud(cloud_line);
  568. proj.setModelCoefficients(coefficients);
  569. proj.filter(*cloud_projected);
  570. Eigen::Vector4f centroid; //质心
  571. pcl::compute3DCentroid(*cloud_projected, centroid); // 计算质心
  572. center = pcl::PointXYZ(centroid[0], centroid[1], 0);
  573. return true;
  574. }
  575. bool detect_wheel_ceres::detect_ransic(pcl::PointCloud<pcl::PointXYZ>::Ptr cl1, pcl::PointCloud<pcl::PointXYZ>::Ptr cl2,
  576. pcl::PointCloud<pcl::PointXYZ>::Ptr cl3, pcl::PointCloud<pcl::PointXYZ>::Ptr cl4,
  577. float &cx, float &cy, float &theta, float &wheel_base, float &width,
  578. float &front_theta, float &loss) {
  579. // cl4->clear();
  580. pcl::PointXYZ center1, center2, center3, center4;
  581. double theta1, theta2, theta3, theta4;
  582. pcl::PointXYZ vertexs[4];
  583. std::vector<pcl::PointXYZ> correct_vertexs;
  584. for (int i = 0; i < 4; ++i) vertexs[i] = pcl::PointXYZ(0, 0, 0);
  585. if (ransicLine(cl1, center1, theta1)) {
  586. vertexs[0] = (center1);
  587. correct_vertexs.push_back(center1);
  588. }
  589. if (ransicLine(cl2, center2, theta2)) {
  590. vertexs[1] = (center2);
  591. correct_vertexs.push_back(center2);
  592. }
  593. if (ransicLine(cl3, center3, theta3)) {
  594. vertexs[2] = (center3);
  595. correct_vertexs.push_back(center3);
  596. }
  597. if (ransicLine(cl4, center4, theta4)) {
  598. vertexs[3] = (center4);
  599. correct_vertexs.push_back(center4);
  600. }
  601. std::vector<pcl::PointXYZ> rect_points = correct_vertexs;
  602. if (!isRect(rect_points))
  603. return false;
  604. if (correct_vertexs.size() == 4) {
  605. pcl::PointXYZ fcenter = pcl::PointXYZ((center1.x + center2.x) * 0.5, (center1.y + center2.y) * 0.5, 0);
  606. pcl::PointXYZ bcenter = pcl::PointXYZ((center3.x + center4.x) * 0.5, (center3.y + center4.y) * 0.5, 0);
  607. cx = (fcenter.x + bcenter.x) * 0.5;
  608. cy = (fcenter.y + bcenter.y) * 0.5;
  609. double thetal = atan((center1.x - center3.x) / (center1.y - center3.y));
  610. double thetar = atan((center2.x - center4.x) / (center2.y - center4.y));
  611. theta = (thetal + thetar) * 0.5;
  612. width = 0.5 * sqrt(pow(center1.x - center2.x, 2) + pow(center1.y - center2.y, 2)) +
  613. 0.5 * sqrt(pow(center3.x - center4.x, 2) + pow(center3.y - center4.y, 2));
  614. wheel_base = sqrt(pow(fcenter.x - bcenter.x, 2) + pow(fcenter.y - bcenter.y, 2));
  615. } else if (correct_vertexs.size() == 3) {
  616. int errorId = 0;
  617. for (int i = 0; i < 4; ++i) {
  618. if (fabs(vertexs[i].y) < 1e-5) {
  619. errorId = i;
  620. break;
  621. }
  622. }
  623. if (errorId == 0) {
  624. cx = (center2.x + center3.x) * 0.5;
  625. cy = (center2.y + center3.y) * 0.5;
  626. theta = atan((center2.x - center4.x) / (center2.y - center4.y));
  627. wheel_base = sqrt(pow(center2.x - center4.x, 2) + pow(center2.y - center4.y, 2));
  628. width = sqrt(pow(center3.x - center4.x, 2) + pow(center3.y - center4.y, 2));
  629. front_theta = theta2;
  630. } else if (errorId == 1) {
  631. cx = (center1.x + center4.x) * 0.5;
  632. cy = (center1.y + center4.y) * 0.5;
  633. theta = atan((center1.x - center3.x) / (center1.y - center3.y));
  634. wheel_base = sqrt(pow(center1.x - center3.x, 2) + pow(center1.y - center3.y, 2));
  635. width = sqrt(pow(center3.x - center4.x, 2) + pow(center3.y - center4.y, 2));
  636. front_theta = theta1;
  637. } else if (errorId == 2) {
  638. cx = (center1.x + center4.x) * 0.5;
  639. cy = (center1.y + center4.y) * 0.5;
  640. theta = atan((center2.x - center4.x) / (center2.y - center4.y));
  641. wheel_base = sqrt(pow(center2.x - center4.x, 2) + pow(center2.y - center4.y, 2));
  642. width = sqrt(pow(center1.x - center2.x, 2) + pow(center1.y - center2.y, 2));
  643. front_theta = (theta1 + theta2) * 0.5;
  644. } else if (errorId == 3) {
  645. cx = (center2.x + center3.x) * 0.5;
  646. cy = (center2.y + center3.y) * 0.5;
  647. theta = atan((center1.x - center3.x) / (center1.y - center3.y));
  648. wheel_base = sqrt(pow(center1.x - center3.x, 2) + pow(center1.y - center3.y, 2));
  649. width = sqrt(pow(center1.x - center2.x, 2) + pow(center1.y - center2.y, 2));
  650. front_theta = (theta1 + theta2) * 0.5;
  651. }
  652. front_theta -= theta;
  653. return recorrect_width(cl3, cl4, theta, width);
  654. } else {
  655. return false;
  656. }
  657. front_theta = (theta1 + theta2) * 0.5 - theta;
  658. return recorrect_width(cl3, cl4, theta, width);
  659. }
  660. bool detect_wheel_ceres::recorrect_width(pcl::PointCloud<pcl::PointXYZ>::Ptr left_cl,
  661. pcl::PointCloud<pcl::PointXYZ>::Ptr right_cl,
  662. float theta, float &width) {
  663. int NUMS[] = {100, 200, 400, 800, 1600};
  664. float COVS[] = {0.04 * 0.04, 0.02 * 0.02, 0.01 * 0.01, 0.005 * 0.005, 0.01 * 0.01};
  665. float widthCov[2] = {0, 100.0};
  666. int correct_count = 0;
  667. for (int i = 0; i < 5; ++i) {
  668. float w = 0;
  669. if (compute_width(left_cl, right_cl, NUMS[i], theta, w)) {
  670. float K = widthCov[1] / (widthCov[1] + COVS[i]);
  671. widthCov[0] = widthCov[0] + K * (w - widthCov[0]);
  672. widthCov[1] = widthCov[1] * (1.0 - K);
  673. correct_count++;
  674. }
  675. }
  676. if (correct_count > 0) {
  677. width = widthCov[0];
  678. return true;
  679. }
  680. return false;
  681. }
  682. bool detect_wheel_ceres::compute_width(pcl::PointCloud<pcl::PointXYZ>::Ptr cl3, pcl::PointCloud<pcl::PointXYZ>::Ptr cl4,
  683. int NUM, float &theta, float &width) {
  684. auto t1 = std::chrono::steady_clock::now();
  685. if (cl3->size() == 0 && cl4->size() == 0) {
  686. return false;
  687. }
  688. double vx = cos(theta);
  689. double vy = sin(theta);
  690. double per = 4.0 / NUM;
  691. int *counts = new int[NUM];
  692. memset(counts, 0, NUM * sizeof(int));
  693. for (int i = 0; i < cl3->size(); ++i) {
  694. float dot = cl3->points[i].x * vx + cl3->points[i].y * vy;
  695. int id = int(dot / per + 0.5) + NUM / 2;
  696. if (id >= 0 && id < NUM) {
  697. counts[id] += 1;
  698. }
  699. }
  700. for (int i = 0; i < cl4->size(); ++i) {
  701. float dot = cl4->points[i].x * vx + cl4->points[i].y * vy;
  702. int id = int(dot / per + 0.5) + NUM / 2;
  703. if (id >= 0 && id < NUM)
  704. counts[id] += 1;
  705. }
  706. double *grade = new double[NUM];
  707. memset(grade, 0, NUM * sizeof(double));
  708. double ming = 0, maxg = 0;
  709. for (int i = 1; i < NUM; ++i) {
  710. grade[i - 1] = counts[i] - counts[i - 1];
  711. if (grade[i - 1] < ming && i > NUM / 2) ming = grade[i - 1];
  712. if (grade[i - 1] > maxg && i < NUM / 2) maxg = grade[i - 1];
  713. }
  714. int l = -1, r = -1;
  715. double weight = 0.3;
  716. for (int i = 0; i < NUM - 1; ++i) {
  717. if (grade[i] > maxg * weight) {
  718. l = i;
  719. break;
  720. }
  721. }
  722. for (int i = NUM - 1; i > 0; --i) {
  723. if (grade[i] < ming * weight) {
  724. r = i;
  725. break;
  726. }
  727. }
  728. delete[] counts;
  729. delete[] grade;
  730. auto t2 = std::chrono::steady_clock::now();
  731. auto duration = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1);
  732. double time =
  733. double(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den;
  734. if (l >= 0 && r >= 0) {
  735. width = (r - l) * per;
  736. return true;
  737. }
  738. return false;
  739. }
  740. bool detect_wheel_ceres::detect_2Step(pcl::PointCloud<pcl::PointXYZ>::Ptr cl1, pcl::PointCloud<pcl::PointXYZ>::Ptr cl2,
  741. pcl::PointCloud<pcl::PointXYZ>::Ptr cl3, pcl::PointCloud<pcl::PointXYZ>::Ptr cl4,
  742. float &cx, float &cy, float &theta, float &wheel_base, float &width,
  743. float &front_theta, float &loss) {
  744. //cl3->clear();
  745. m_left_front_cloud = filter(cl1, 1);
  746. m_right_front_cloud = filter(cl2, 1);
  747. m_left_rear_cloud = filter(cl3, 1);
  748. m_right_rear_cloud = filter(cl4, 1);
  749. bool ryl = detect_RYL(m_left_front_cloud, m_right_front_cloud, m_left_rear_cloud, m_right_rear_cloud,
  750. cx, cy, theta, wheel_base, width, front_theta, loss);
  751. if (ryl == false) return ryl;
  752. bool xwf = detect_XWF(m_left_front_cloud, m_right_front_cloud, m_left_rear_cloud, m_right_rear_cloud,
  753. cx, cy, theta, wheel_base, width, front_theta, loss);
  754. return xwf;
  755. }
  756. bool detect_wheel_ceres::detect_RX(pcl::PointCloud<pcl::PointXYZ>::Ptr cl1, pcl::PointCloud<pcl::PointXYZ>::Ptr cl2,
  757. pcl::PointCloud<pcl::PointXYZ>::Ptr cl3, pcl::PointCloud<pcl::PointXYZ>::Ptr cl4,
  758. float &cx, float &cy, float &theta, float &wheel_base, float &width,
  759. float &front_theta, float &loss) {
  760. m_left_front_cloud = filter(cl1, 1);
  761. m_right_front_cloud = filter(cl2, 1);
  762. m_left_rear_cloud = filter(cl3, 1);
  763. m_right_rear_cloud = filter(cl4, 1);
  764. double variable[] = {cx, theta};
  765. auto t1 = std::chrono::steady_clock::now();
  766. // 第二部分:构建寻优问题
  767. ceres::Problem problem;
  768. ceres::CostFunction *cost_function = new
  769. ceres::AutoDiffCostFunction<CostRXFunc, ceres::DYNAMIC, 2>(
  770. new CostRXFunc(m_left_front_cloud, m_right_front_cloud, m_left_rear_cloud, m_right_rear_cloud, m_line_x),
  771. (m_left_front_cloud->size() + m_right_front_cloud->size() + m_left_rear_cloud->size() +
  772. m_right_rear_cloud->size()));
  773. problem.AddResidualBlock(cost_function, NULL, variable); //向问题中添加误差项,本问题比较简单,添加一个就行。
  774. //第三部分: 配置并运行求解器
  775. ceres::Solver::Options options;
  776. options.use_nonmonotonic_steps = false;
  777. options.linear_solver_type = ceres::DENSE_QR; //配置增量方程的解法
  778. options.max_num_iterations = 100;
  779. options.function_tolerance = 1e-10;
  780. options.num_threads = 2;
  781. options.minimizer_progress_to_stdout = false;//输出到cout
  782. ceres::Solver::Summary summary;//优化信息
  783. ceres::Solve(options, &problem, &summary);//求解!!!
  784. auto t2 = std::chrono::steady_clock::now();
  785. auto duration = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1);
  786. double time =
  787. double(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den;
  788. loss = summary.final_cost / (m_left_front_cloud->size() + m_right_front_cloud->size() + m_left_rear_cloud->size() +
  789. m_right_rear_cloud->size());
  790. cx = variable[0];
  791. theta = variable[1];
  792. if (loss > 0.05) {
  793. return false;
  794. }
  795. return true;
  796. }
  797. bool detect_wheel_ceres::detect_RYL(pcl::PointCloud<pcl::PointXYZ>::Ptr cl1, pcl::PointCloud<pcl::PointXYZ>::Ptr cl2,
  798. pcl::PointCloud<pcl::PointXYZ>::Ptr cl3, pcl::PointCloud<pcl::PointXYZ>::Ptr cl4,
  799. float &cx, float &cy, float &theta, float &wheel_base, float &width,
  800. float &front_theta, float &loss) {
  801. double variable[] = {cy, theta, wheel_base};
  802. auto t1 = std::chrono::steady_clock::now();
  803. // 第二部分:构建寻优问题
  804. ceres::Problem problem;
  805. ceres::CostFunction *cost_function = new
  806. ceres::AutoDiffCostFunction<CostRYFunc, ceres::DYNAMIC, 3>(
  807. new CostRYFunc(m_left_front_cloud, m_right_front_cloud, m_left_rear_cloud, m_right_rear_cloud,
  808. m_line_y_2stp),
  809. (m_left_front_cloud->size() + m_right_front_cloud->size() + m_left_rear_cloud->size() +
  810. m_right_rear_cloud->size()));
  811. problem.AddResidualBlock(cost_function, NULL, variable); //向问题中添加误差项,本问题比较简单,添加一个就行。
  812. //第三部分: 配置并运行求解器
  813. ceres::Solver::Options options;
  814. options.use_nonmonotonic_steps = false;
  815. options.linear_solver_type = ceres::DENSE_QR; //配置增量方程的解法
  816. options.max_num_iterations = 100;
  817. options.function_tolerance = 1e-10;
  818. options.num_threads = 2;
  819. options.minimizer_progress_to_stdout = false;//输出到cout
  820. ceres::Solver::Summary summary;//优化信息
  821. ceres::Solve(options, &problem, &summary);//求解!!!
  822. auto t2 = std::chrono::steady_clock::now();
  823. auto duration = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1);
  824. double time =
  825. double(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den;
  826. loss = summary.final_cost / (m_left_front_cloud->size() + m_right_front_cloud->size() + m_left_rear_cloud->size() +
  827. m_right_rear_cloud->size());
  828. cy = variable[0];
  829. theta = variable[1];
  830. wheel_base = variable[2];
  831. if (loss > 0.05) {
  832. return false;
  833. }
  834. return true;
  835. }
  836. bool detect_wheel_ceres::detect_XWF(pcl::PointCloud<pcl::PointXYZ>::Ptr cl1, pcl::PointCloud<pcl::PointXYZ>::Ptr cl2,
  837. pcl::PointCloud<pcl::PointXYZ>::Ptr cl3, pcl::PointCloud<pcl::PointXYZ>::Ptr cl4,
  838. float &cx, float &cy, float &theta, float &wheel_base, float &width,
  839. float &front_theta, float &loss) {
  840. double variable[] = {cx, cy, width, front_theta};
  841. auto t1 = std::chrono::steady_clock::now();
  842. // 第二部分:构建寻优问题
  843. ceres::Problem problem;
  844. CostXYWFFunc *costFuc = new CostXYWFFunc(m_left_front_cloud, m_right_front_cloud, m_left_rear_cloud,
  845. m_right_rear_cloud,
  846. m_line_l, m_line_r, m_line_y, theta, wheel_base);
  847. ceres::CostFunction *cost_function = new
  848. ceres::AutoDiffCostFunction<CostXYWFFunc, ceres::DYNAMIC, 4>(costFuc,
  849. 2 * (m_left_front_cloud->size() +
  850. m_right_front_cloud->size() +
  851. m_left_rear_cloud->size() +
  852. m_right_rear_cloud->size()));
  853. problem.AddResidualBlock(cost_function, NULL, variable); //向问题中添加误差项,本问题比较简单,添加一个就行。
  854. //第三部分: 配置并运行求解器
  855. ceres::Solver::Options options;
  856. options.use_nonmonotonic_steps = false;
  857. options.linear_solver_type = ceres::DENSE_QR; //配置增量方程的解法
  858. options.max_num_iterations = 100;
  859. options.num_threads = 2;
  860. options.minimizer_progress_to_stdout = false;//输出到cout
  861. ceres::Solver::Summary summary;//优化信息
  862. ceres::Solve(options, &problem, &summary);//求解!!!
  863. auto t2 = std::chrono::steady_clock::now();
  864. auto duration = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1);
  865. double time =
  866. double(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den;
  867. loss = summary.final_cost / (m_left_front_cloud->size() + m_right_front_cloud->size() + m_left_rear_cloud->size() +
  868. m_right_rear_cloud->size());
  869. cx = variable[0];
  870. cy = variable[1];
  871. width = variable[2];
  872. front_theta = variable[3];
  873. if (loss > 0.05) {
  874. return false;
  875. }
  876. return true;
  877. }
  878. pcl::PointCloud<pcl::PointXYZ>::Ptr detect_wheel_ceres::transformRY(
  879. pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, float theta, float y) {
  880. //整车旋转
  881. Eigen::Rotation2D<float> rotation(theta);
  882. Eigen::Matrix<float, 2, 2> rotation_matrix = rotation.toRotationMatrix();
  883. pcl::PointCloud<pcl::PointXYZ>::Ptr out(new pcl::PointCloud<pcl::PointXYZ>);
  884. for (int i = 0; i < cloud->size(); ++i) {
  885. const Eigen::Matrix<float, 2, 1> point(cloud->points[i].x, cloud->points[i].y);
  886. const Eigen::Matrix<float, 2, 1> tp(0.0, y);
  887. //减去经过车辆旋转计算的左前中心
  888. const Eigen::Matrix<float, 2, 1> point_transform = rotation_matrix * point + tp;
  889. out->push_back(pcl::PointXYZ(point_transform[0], point_transform[1], cloud->points[i].z));
  890. }
  891. return out;
  892. }
  893. pcl::PointCloud<pcl::PointXYZ>::Ptr detect_wheel_ceres::filter(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, float r) {
  894. if (cloud->size() == 0)
  895. return cloud;
  896. float sumx = 0;
  897. for (int i = 0; i < cloud->size(); ++i) {
  898. sumx += cloud->points[i].x;
  899. }
  900. float avg = sumx / float(cloud->size());
  901. float stdd = 0.0;
  902. for (int i = 0; i < cloud->size(); ++i) {
  903. stdd += pow(cloud->points[i].x - avg, 2);
  904. }
  905. stdd = sqrt(stdd / (float(cloud->size())));
  906. if (stdd < 0.15)
  907. return cloud;
  908. pcl::PointCloud<pcl::PointXYZ>::Ptr out(new pcl::PointCloud<pcl::PointXYZ>);
  909. for (int i = 0; i < cloud->size(); ++i) {
  910. if (fabs(cloud->points[i].x - avg) < r * stdd)
  911. out->push_back(cloud->points[i]);
  912. }
  913. return out;
  914. }
  915. /*
  916. bool detect_wheel_ceres::detect_fall(pcl::PointCloud<pcl::PointXYZ>::Ptr cl1,pcl::PointCloud<pcl::PointXYZ>::Ptr cl2,
  917. pcl::PointCloud<pcl::PointXYZ>::Ptr cl3,pcl::PointCloud<pcl::PointXYZ>::Ptr cl4,
  918. float& cx,float& cy,float& theta,float& wheel_base,
  919. float& width,float& front_theta,float& loss){
  920. pcl::PointXYZ tp1,tp2,tp3,tp4;
  921. float yaw1=0.0;
  922. float yaw2=0.0;
  923. float yaw3=0.0;
  924. float yaw4=0.0;
  925. pcl::PointCloud<pcl::PointXYZ>::Ptr out1,out2,out3,out4;
  926. FallModel::fall(cl1,out1,tp1,yaw1,eNagtive);
  927. FallModel::fall(cl2,out2,tp2,yaw2,ePositive);
  928. FallModel::fall(cl3,out3,tp3,yaw3,eNagtive);
  929. FallModel::fall(cl4,out4,tp4,yaw4,ePositive);
  930. save_cloud_txt(out1,"./src1.txt");
  931. save_cloud_txt(out2,"./src2.txt");
  932. save_cloud_txt(out3,"./src3.txt");
  933. save_cloud_txt(out4,"./src4.txt");
  934. printf("yaw: %f %f %f %f\n",yaw1*180.0/M_PI,yaw2*180.0/M_PI,yaw3*180.0/M_PI,yaw4*180.0/M_PI);
  935. return true;
  936. }*/