detect_wheel_ceres3d.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671
  1. //
  2. // Created by zx on 2020/7/1.
  3. //
  4. #include "detect_wheel_ceres3d.h"
  5. #include "interpolated_grid.hpp"
  6. #include <pcl/common/transforms.h>
  7. #include "point_tool.h"
  8. class CostFunctor3d
  9. {
  10. private:
  11. const InterpolatedProbabilityGrid m_left_interpolated_grid;
  12. const InterpolatedProbabilityGrid m_right_interpolated_grid;
  13. mutable double m_costs_lf, m_costs_rf, m_costs_lr, m_costs_rr;
  14. pcl::PointCloud<pcl::PointXYZ> m_left_front_cloud; //左前点云
  15. pcl::PointCloud<pcl::PointXYZ> m_right_front_cloud; //右前点云
  16. pcl::PointCloud<pcl::PointXYZ> m_left_rear_cloud; //左后点云
  17. pcl::PointCloud<pcl::PointXYZ> m_right_rear_cloud; //右后点云
  18. public:
  19. CostFunctor3d(pcl::PointCloud<pcl::PointXYZ> left_front, pcl::PointCloud<pcl::PointXYZ> right_front,
  20. pcl::PointCloud<pcl::PointXYZ> left_rear, pcl::PointCloud<pcl::PointXYZ> right_rear,
  21. const HybridGrid& left_interpolated_grid,
  22. const HybridGrid& right_interpolated_grid)
  23. :m_left_interpolated_grid(left_interpolated_grid),m_right_interpolated_grid(right_interpolated_grid)
  24. {
  25. m_left_front_cloud = left_front;
  26. m_right_front_cloud = right_front;
  27. m_left_rear_cloud = left_rear;
  28. m_right_rear_cloud = right_rear;
  29. m_costs_lf = 0.0;
  30. m_costs_rf = 0.0;
  31. m_costs_lr = 0.0;
  32. m_costs_rr = 0.0;
  33. }
  34. template<typename T>
  35. bool operator()(const T *const variable, T *residual) const
  36. {
  37. T cx = variable[0];
  38. T cy = variable[1];
  39. T theta = variable[2];
  40. T length = variable[3];
  41. T width = variable[4];
  42. T theta_front = variable[5];
  43. //整车旋转
  44. Eigen::Rotation2D<T> rotation(theta);
  45. Eigen::Matrix<T, 2, 2> rotation_matrix = rotation.toRotationMatrix();
  46. //左前偏移
  47. Eigen::Matrix<T, 2, 1> wheel_center_normal_left_front(length / 2.0, width / 2.0);
  48. //右前偏移
  49. Eigen::Matrix<T, 2, 1> wheel_center_normal_right_front(length / 2.0, -width / 2.0);
  50. //左后偏移
  51. Eigen::Matrix<T, 2, 1> wheel_center_normal_left_rear(-length / 2.0, width / 2.0);
  52. //右后偏移
  53. Eigen::Matrix<T, 2, 1> wheel_center_normal_right_rear(-length / 2.0, -width / 2.0);
  54. //前轮旋转
  55. Eigen::Rotation2D<T> rotation_front(theta_front);
  56. Eigen::Matrix<T, 2, 2> rotation_matrix_front = rotation_front.toRotationMatrix();
  57. //左前轮
  58. int left_front_num = m_left_front_cloud.size();
  59. for (int i = 0; i < m_left_front_cloud.size(); ++i)
  60. {
  61. const Eigen::Matrix<T, 2, 1> point((T(m_left_front_cloud[i].x) - cx),
  62. (T(m_left_front_cloud[i].y) - cy));
  63. //减去经过车辆旋转计算的左前中心
  64. const Eigen::Matrix<T, 2, 1> tanslate_point = rotation_matrix * point - wheel_center_normal_left_front;
  65. //旋转
  66. const Eigen::Matrix<T, 2, 1> point_rotation = rotation_matrix_front * tanslate_point;
  67. residual[i] = T(1.0) - m_left_interpolated_grid.GetInterpolatedValue(point_rotation[0],point_rotation[1],
  68. T(m_left_front_cloud[i].z));
  69. }
  70. //右前轮
  71. int right_front_num = m_right_front_cloud.size();
  72. for (int i = 0; i < m_right_front_cloud.size(); ++i)
  73. {
  74. const Eigen::Matrix<T, 2, 1> point((T(m_right_front_cloud[i].x) - cx),
  75. (T(m_right_front_cloud[i].y) - cy));
  76. //减去经过车辆旋转计算的左前中心
  77. const Eigen::Matrix<T, 2, 1> tanslate_point = rotation_matrix * point - wheel_center_normal_right_front;
  78. //旋转
  79. const Eigen::Matrix<T, 2, 1> point_rotation = rotation_matrix_front * tanslate_point;
  80. residual[left_front_num + i] = T(1.0) - m_right_interpolated_grid.GetInterpolatedValue(point_rotation[0],point_rotation[1],
  81. T(m_right_front_cloud[i].z));
  82. }
  83. //左后轮
  84. int left_rear_num = m_left_rear_cloud.size();
  85. for (int i = 0; i < m_left_rear_cloud.size(); ++i)
  86. {
  87. const Eigen::Matrix<T, 2, 1> point((T(m_left_rear_cloud[i].x) - cx),
  88. (T(m_left_rear_cloud[i].y) - cy));
  89. //减去经过车辆旋转计算的左前中心
  90. const Eigen::Matrix<T, 2, 1> tanslate_point = rotation_matrix * point - wheel_center_normal_left_rear;
  91. residual[left_front_num + right_front_num + i] = T(1.0) -
  92. m_left_interpolated_grid.GetInterpolatedValue(tanslate_point[0],tanslate_point[1],
  93. T(m_left_rear_cloud[i].z));
  94. }
  95. //右后轮
  96. int right_rear_num = m_right_rear_cloud.size();
  97. for (int i = 0; i < m_right_rear_cloud.size(); ++i)
  98. {
  99. const Eigen::Matrix<T, 2, 1> point((T(m_right_rear_cloud[i].x) - cx),
  100. (T(m_right_rear_cloud[i].y) - cy));
  101. //减去经过车辆旋转计算的左前中心
  102. const Eigen::Matrix<T, 2, 1> tanslate_point = rotation_matrix * point - wheel_center_normal_right_rear;
  103. residual[left_front_num + right_front_num + left_rear_num+i] = T(1.0) -
  104. m_right_interpolated_grid.GetInterpolatedValue(tanslate_point[0],tanslate_point[1],
  105. T(m_right_rear_cloud[i].z));
  106. }
  107. return true;
  108. }
  109. };
  110. detect_wheel_ceres3d::detect_wheel_ceres3d(pcl::PointCloud<pcl::PointXYZ>::Ptr left_grid_cloud,
  111. pcl::PointCloud<pcl::PointXYZ>::Ptr right_grid_cloud)
  112. {
  113. float del_x=0.05;
  114. float del_y=0.03;
  115. float del_z=0.05;
  116. Eigen::Matrix3f delta=Eigen::MatrixXf::Identity(3,3);
  117. delta(0,0)=del_x*del_x;
  118. delta(1,1)=del_y*del_y;
  119. delta(2,2)=del_z*del_z;
  120. Eigen::Matrix3f delta_inv=delta.inverse();
  121. Eigen::Vector3f d(0,0,0.02);
  122. Eigen::MatrixXf ce=-0.5*((d).transpose()*delta_inv*(d));
  123. float cut_p=exp(ce(0,0));
  124. // std::cout << "1111" << std::endl;
  125. float resolution=0.01;
  126. mp_left_grid=new HybridGrid(resolution);
  127. mp_right_grid=new HybridGrid(resolution);
  128. for(int i=0;i<left_grid_cloud->size();++i)
  129. {
  130. // std::cout << "2222 "<< i << std::endl;
  131. pcl::PointXYZ pt=left_grid_cloud->points[i];
  132. Eigen::Vector3f u(pt.x,pt.y,pt.z);
  133. for(float x=pt.x-0.1;x<pt.x+0.1;x+=mp_left_grid->resolution())
  134. {
  135. // std::cout << "aa" << std::endl;
  136. for(float y=pt.y-0.1;y<pt.y+0.1;y+=mp_left_grid->resolution())
  137. {
  138. // std::cout << "bb" << std::endl;
  139. for(float z=pt.z-0.1;z<pt.z+0.1;z+=mp_left_grid->resolution())
  140. {
  141. // std::cout << "cc" << std::endl;
  142. Eigen::Vector3f p(x,y,z);
  143. Eigen::MatrixXf B=-0.5*((p-u).transpose()*delta_inv*(p-u));
  144. float prob=exp(B(0,0));
  145. if(prob>cut_p)
  146. prob=cut_p;
  147. Eigen::Array3i index=mp_left_grid->GetCellIndex(p);
  148. // std::cout << "dd "<< index << std::endl;
  149. if(mp_left_grid->GetProbability(index)<prob){
  150. // std::cout << "e1 "<<index << std::endl;
  151. mp_left_grid->SetProbability(index,prob);
  152. // std::cout << "e2 "<<index << std::endl;
  153. }
  154. // std::cout << "ee "<<index << std::endl;
  155. }
  156. }
  157. }
  158. }
  159. // std::cout << "3333" << std::endl;
  160. for(int i=0;i<right_grid_cloud->size();++i)
  161. {
  162. pcl::PointXYZ pt=right_grid_cloud->points[i];
  163. Eigen::Vector3f u(pt.x,pt.y,pt.z);
  164. for(float x=pt.x-0.1;x<pt.x+0.1;x+=mp_right_grid->resolution())
  165. {
  166. for(float y=pt.y-0.1;y<pt.y+0.1;y+=mp_right_grid->resolution())
  167. {
  168. for(float z=pt.z-0.1;z<pt.z+0.1;z+=mp_right_grid->resolution())
  169. {
  170. Eigen::Vector3f p(x,y,z);
  171. Eigen::MatrixXf B=-0.5*((p-u).transpose()*delta_inv*(p-u));
  172. float prob=exp(B(0,0));
  173. if(prob>cut_p)
  174. prob=cut_p;
  175. Eigen::Array3i index=mp_right_grid->GetCellIndex(p);
  176. if(mp_right_grid->GetProbability(index)<prob)
  177. mp_right_grid->SetProbability(index,prob);
  178. }
  179. }
  180. }
  181. }
  182. // std::cout << "4444" << std::endl;
  183. // save_model("/home/zx/zzw/catkin_ws/src/feature_extra");
  184. }
  185. void detect_wheel_ceres3d::save_model(std::string dir)
  186. {
  187. InterpolatedProbabilityGrid inter_grid(*mp_left_grid);
  188. pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_grid(new pcl::PointCloud<pcl::PointXYZRGB>);
  189. for(int x=0;x<mp_left_grid->grid_size();++x)
  190. {
  191. for(int y=0;y<mp_left_grid->grid_size();++y)
  192. {
  193. for(int z=0;z<mp_left_grid->grid_size();++z)
  194. {
  195. Eigen::Array3i index(x-mp_left_grid->grid_size()/2,
  196. y-mp_left_grid->grid_size()/2,z-mp_left_grid->grid_size()/2);
  197. Eigen::Vector3f pt=mp_left_grid->GetCenterOfCell(index);
  198. float prob=inter_grid.GetInterpolatedValue(double(pt[0]),double(pt[1]),double(pt[2]));
  199. if(prob>0.01)
  200. {
  201. Eigen::Vector3f pt=mp_left_grid->GetCenterOfCell(index);
  202. int rgb=int((prob-0.01)*255);
  203. pcl::PointXYZRGB point;
  204. point.x=pt[0];
  205. point.y=pt[1];
  206. point.z=pt[2];
  207. point.r=rgb;
  208. point.g=0;
  209. point.b=255-rgb;
  210. cloud_grid->push_back(point);
  211. }
  212. }
  213. }
  214. }
  215. InterpolatedProbabilityGrid right_grid(*mp_right_grid);
  216. pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_right_grid(new pcl::PointCloud<pcl::PointXYZRGB>);
  217. for(int x=0;x<mp_right_grid->grid_size();++x)
  218. {
  219. for(int y=0;y<mp_right_grid->grid_size();++y)
  220. {
  221. for(int z=0;z<mp_right_grid->grid_size();++z)
  222. {
  223. Eigen::Array3i index(x-mp_right_grid->grid_size()/2,
  224. y-mp_right_grid->grid_size()/2,z-mp_right_grid->grid_size()/2);
  225. Eigen::Vector3f pt=mp_right_grid->GetCenterOfCell(index);
  226. float prob=right_grid.GetInterpolatedValue(double(pt[0]),double(pt[1]),double(pt[2]));
  227. if(prob>0.01)
  228. {
  229. Eigen::Vector3f pt=mp_right_grid->GetCenterOfCell(index);
  230. int rgb=int((prob-0.01)*255);
  231. pcl::PointXYZRGB point;
  232. point.x=pt[0];
  233. point.y=pt[1];
  234. point.z=pt[2];
  235. point.r=rgb;
  236. point.g=0;
  237. point.b=255-rgb;
  238. cloud_right_grid->push_back(point);
  239. }
  240. }
  241. }
  242. }
  243. //std::cout<<" save model :"<<dir<<std::endl;
  244. //save_cloud_txt(cloud_grid,dir+"/left_model.txt");
  245. //save_cloud_txt(cloud_right_grid,dir+"/right_model.txt");
  246. }
  247. detect_wheel_ceres3d::~detect_wheel_ceres3d(){
  248. delete mp_left_grid;
  249. delete mp_right_grid;
  250. mp_left_grid= nullptr;
  251. mp_right_grid= nullptr;
  252. }
  253. bool detect_wheel_ceres3d::detect(std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> cloud_vec,
  254. Detect_result &detect_result, std::string &error_info)
  255. {
  256. error_info = "";
  257. //清理点云
  258. m_left_front_cloud.clear();
  259. m_right_front_cloud.clear();
  260. m_left_rear_cloud.clear();
  261. m_right_rear_cloud.clear();
  262. //重新计算点云,按方位分割
  263. //第一步,计算整体中心,主轴方向
  264. pcl::PointCloud<pcl::PointXYZ> cloud_all;
  265. for (int i = 0; i < cloud_vec.size(); ++i)
  266. {
  267. cloud_all += (*cloud_vec[i]);
  268. }
  269. // std::cout<<"cloud size: "<<cloud_all.size()<<std::endl;
  270. if (cloud_all.size() < 20)
  271. return false;
  272. Eigen::Vector4f centroid;
  273. pcl::compute3DCentroid(cloud_all, centroid);
  274. double center_x = centroid[0];
  275. double center_y = centroid[1];
  276. // printf("3dwheel x,y:%.3f, %.3f\n", center_x, center_y);
  277. // save_cloud_txt(cloud_all.makeShared(), "total_wheel.txt");
  278. //计算外接旋转矩形
  279. std::vector<cv::Point2f> points_cv;
  280. for (int i = 0; i < cloud_all.size(); ++i)
  281. {
  282. points_cv.push_back(cv::Point2f(cloud_all[i].x, cloud_all[i].y));
  283. }
  284. cv::RotatedRect rotate_rect = cv::minAreaRect(points_cv);
  285. //计算旋转矩形与X轴的夹角
  286. cv::Point2f vec;
  287. cv::Point2f vertice[4];
  288. rotate_rect.points(vertice);
  289. float len1 = pow(vertice[0].x - vertice[1].x, 2.0) + pow(vertice[0].y - vertice[1].y, 2.0);
  290. float len2 = pow(vertice[1].x - vertice[2].x, 2.0) + pow(vertice[1].y - vertice[2].y, 2.0);
  291. // 寻找长边,倾角为长边与x轴夹角
  292. if (len1 > len2)
  293. {
  294. vec.x = vertice[0].x - vertice[1].x;
  295. vec.y = vertice[0].y - vertice[1].y;
  296. }
  297. else
  298. {
  299. vec.x = vertice[1].x - vertice[2].x;
  300. vec.y = vertice[1].y - vertice[2].y;
  301. }
  302. float angle_x = 180.0 / M_PI * acos(vec.x / sqrt(vec.x * vec.x + vec.y * vec.y));
  303. // printf("rect theta: %.3f\n",angle_x);
  304. //第二步, 将每份点云旋转回去,计算点云重心所在象限
  305. for (int i = 0; i < cloud_vec.size(); ++i)
  306. {
  307. pcl::PointCloud<pcl::PointXYZ> cloud = (*cloud_vec[i]);
  308. Eigen::Affine3f traslation = Eigen::Affine3f::Identity();//初始化变换矩阵为单位矩阵
  309. // 平移
  310. traslation.translation() << -center_x, -center_y, 0.0;
  311. pcl::PointCloud<pcl::PointXYZ> translate_cloud;
  312. pcl::transformPointCloud(cloud, translate_cloud, traslation);
  313. // 旋转; Z 轴上旋转angle_x 弧度,Y轴上旋转0弧度
  314. Eigen::Affine3f rotation = Eigen::Affine3f::Identity();
  315. rotation.rotate(Eigen::AngleAxisf(-angle_x * M_PI / 180.0, Eigen::Vector3f::UnitZ()));
  316. pcl::PointCloud<pcl::PointXYZ> transformed_cloud;
  317. pcl::transformPointCloud(translate_cloud, transformed_cloud, rotation);
  318. //计算重心
  319. Eigen::Vector4f centroid;
  320. pcl::compute3DCentroid(transformed_cloud, centroid);
  321. double x = centroid[0];
  322. double y = centroid[1];
  323. //计算象限
  324. if (x > 0 && y > 0)
  325. {
  326. //第一象限
  327. m_left_front_cloud = cloud;
  328. }
  329. if (x > 0 && y < 0)
  330. {
  331. //第四象限
  332. m_right_front_cloud = cloud;
  333. }
  334. if (x < 0 && y > 0)
  335. {
  336. //第二象限
  337. m_left_rear_cloud = cloud;
  338. }
  339. if (x < 0 && y < 0)
  340. {
  341. //第三象限
  342. m_right_rear_cloud = cloud;
  343. }
  344. }
  345. // 多次优化,获取最佳优化结果
  346. detect_result.cx = center_x;
  347. detect_result.cy = center_y;
  348. detect_result.wheel_base=std::max(len1,len2);
  349. // 已计算次数,初始传入值正常,之后solve函数会修改初始值,需要恢复角度单位为弧度
  350. int calc_count = 0;
  351. // double final_theta = 0;
  352. // 误差结构体,保存左前、右前、左后、右后、整体平均误差
  353. Loss_result loss_result;
  354. // 平均误差值,用于获取最小整体平均误差
  355. double avg_loss = 100;
  356. // 定义图像列数,控制图像大小
  357. int map_cols = 800;
  358. // 优化后图像行数,用于保存优化后结果图像
  359. int optimized_map_rows = 200;
  360. // 优化结果
  361. bool solve_result = false;
  362. double total_solve_time = 0;
  363. bool stop_sign = false;
  364. Detect_result t_detect_result = detect_result;
  365. // 寻找最小loss值对应的初始旋转角
  366. t_detect_result.theta = (-angle_x ) * M_PI / 180.0;
  367. Loss_result t_loss_result;
  368. t_loss_result.total_avg_loss = 1000;
  369. //输出角度已变化,需恢复成弧度
  370. if (calc_count > 0)
  371. {
  372. t_detect_result.front_theta *= (-M_PI) / 180.0;
  373. }
  374. std::string t_error_info;
  375. bool current_result = Solve(t_detect_result, t_loss_result, t_error_info);
  376. error_info = t_error_info;
  377. // std::cout<<"current_result: "<<current_result<<std::endl;
  378. if (current_result)
  379. {
  380. avg_loss = t_loss_result.total_avg_loss;
  381. // final_theta = -input_vars[2] * M_PI / 180.0;
  382. detect_result = t_detect_result;
  383. detect_result.loss = t_loss_result;
  384. solve_result = current_result;
  385. loss_result = t_loss_result;
  386. }
  387. return solve_result;
  388. }
  389. void detect_wheel_ceres3d::get_costs(double* variable,double &lf, double &rf, double &lr, double &rr)
  390. {
  391. double losses[4]={0};
  392. double cx = variable[0];
  393. double cy = variable[1];
  394. double theta = variable[2];
  395. double length = variable[3];
  396. double width = variable[4];
  397. double theta_front = variable[5];
  398. //整车旋转
  399. Eigen::Rotation2D<double> rotation(theta);
  400. Eigen::Matrix<double, 2, 2> rotation_matrix = rotation.toRotationMatrix();
  401. //左前偏移
  402. Eigen::Matrix<double, 2, 1> wheel_center_normal_left_front(length / 2.0, width / 2.0);
  403. //右前偏移
  404. Eigen::Matrix<double, 2, 1> wheel_center_normal_right_front(length / 2.0, -width / 2.0);
  405. //左后偏移
  406. Eigen::Matrix<double, 2, 1> wheel_center_normal_left_rear(-length / 2.0, width / 2.0);
  407. //右后偏移
  408. Eigen::Matrix<double, 2, 1> wheel_center_normal_right_rear(-length / 2.0, -width / 2.0);
  409. //前轮旋转
  410. Eigen::Rotation2D<double> rotation_front(theta_front);
  411. Eigen::Matrix<double, 2, 2> rotation_matrix_front = rotation_front.toRotationMatrix();
  412. InterpolatedProbabilityGrid left_interpolated_grid(*mp_left_grid);
  413. InterpolatedProbabilityGrid right_interpolated_grid(*mp_right_grid);
  414. //左前轮
  415. int left_front_num = m_left_front_cloud.size();
  416. m_left_front_transformed_cloud.clear();
  417. for (int i = 0; i < m_left_front_cloud.size(); ++i)
  418. {
  419. const Eigen::Matrix<double, 2, 1> point((double(m_left_front_cloud[i].x) - cx),
  420. (double(m_left_front_cloud[i].y) - cy));
  421. //减去经过车辆旋转计算的左前中心
  422. const Eigen::Matrix<double, 2, 1> tanslate_point = rotation_matrix * point - wheel_center_normal_left_front;
  423. //旋转
  424. const Eigen::Matrix<double, 2, 1> point_rotation = rotation_matrix_front * tanslate_point;
  425. losses[0] += 1.0 - left_interpolated_grid.GetInterpolatedValue(point_rotation[0],point_rotation[1],
  426. double(m_left_front_cloud[i].z));
  427. m_left_front_transformed_cloud.push_back(pcl::PointXYZ(point_rotation[0],point_rotation[1],m_left_front_cloud[i].z));
  428. }
  429. //右前轮
  430. int right_front_num = m_right_front_cloud.size();
  431. m_right_front_transformed_cloud.clear();
  432. for (int i = 0; i < m_right_front_cloud.size(); ++i)
  433. {
  434. const Eigen::Matrix<double, 2, 1> point((double(m_right_front_cloud[i].x) - cx),
  435. (double(m_right_front_cloud[i].y) - cy));
  436. //减去经过车辆旋转计算的左前中心
  437. const Eigen::Matrix<double, 2, 1> tanslate_point = rotation_matrix * point - wheel_center_normal_right_front;
  438. //旋转
  439. const Eigen::Matrix<double, 2, 1> point_rotation = rotation_matrix_front * tanslate_point;
  440. losses[1]+= 1.0 - right_interpolated_grid.GetInterpolatedValue(point_rotation[0],point_rotation[1],
  441. double(m_right_front_cloud[i].z));
  442. m_right_front_transformed_cloud.push_back(pcl::PointXYZ(point_rotation[0],point_rotation[1],
  443. double(m_right_front_cloud[i].z)));
  444. }
  445. //左后轮
  446. int left_rear_num = m_left_rear_cloud.size();
  447. m_left_rear_transformed_cloud.clear();
  448. for (int i = 0; i < m_left_rear_cloud.size(); ++i)
  449. {
  450. const Eigen::Matrix<double, 2, 1> point((double(m_left_rear_cloud[i].x) - cx),
  451. (double(m_left_rear_cloud[i].y) - cy));
  452. //减去经过车辆旋转计算的左前中心
  453. const Eigen::Matrix<double, 2, 1> tanslate_point = rotation_matrix * point - wheel_center_normal_left_rear;
  454. losses[2] += 1.0 -
  455. left_interpolated_grid.GetInterpolatedValue(tanslate_point[0],tanslate_point[1],
  456. double(m_left_rear_cloud[i].z));
  457. m_left_rear_transformed_cloud.push_back(pcl::PointXYZ(tanslate_point[0],tanslate_point[1],
  458. double(m_left_rear_cloud[i].z)));
  459. }
  460. //右后轮
  461. int right_rear_num = m_right_rear_cloud.size();
  462. m_right_rear_transformed_cloud.clear();
  463. for (int i = 0; i < m_right_rear_cloud.size(); ++i)
  464. {
  465. const Eigen::Matrix<double, 2, 1> point((double(m_right_rear_cloud[i].x) - cx),
  466. (double(m_right_rear_cloud[i].y) - cy));
  467. //减去经过车辆旋转计算的左前中心
  468. const Eigen::Matrix<double, 2, 1> tanslate_point = rotation_matrix * point - wheel_center_normal_right_rear;
  469. losses[3]+= 1.0 -
  470. right_interpolated_grid.GetInterpolatedValue(tanslate_point[0],tanslate_point[1],
  471. double(m_right_rear_cloud[i].z));
  472. m_right_rear_transformed_cloud.push_back(pcl::PointXYZ(tanslate_point[0],tanslate_point[1],
  473. double(m_right_rear_cloud[i].z)));
  474. }
  475. lf=losses[0];
  476. rf=losses[1];
  477. lr =losses[2];
  478. rr =losses[3];
  479. }
  480. void detect_wheel_ceres3d::save_debug_data(std::string dir )
  481. {
  482. ::save_cloud_txt(m_left_front_transformed_cloud.makeShared(),dir+"/left_front_tranformed.txt");
  483. ::save_cloud_txt(m_right_front_transformed_cloud.makeShared(),dir+"/right_front_tranformed.txt");
  484. ::save_cloud_txt(m_left_rear_transformed_cloud.makeShared(),dir+"/left_rear_tranformed.txt");
  485. ::save_cloud_txt(m_right_rear_transformed_cloud.makeShared(),dir+"/right_rear_tranformed.txt");
  486. }
  487. bool detect_wheel_ceres3d::Solve(Detect_result &detect_result, Loss_result &loss_result, std::string &error_info)
  488. {
  489. double cx=detect_result.cx;
  490. double cy=detect_result.cy;
  491. double init_theta=detect_result.theta;
  492. double init_wheel_base=2.7;
  493. if(detect_result.wheel_base>2.55 && detect_result.wheel_base<3.2)
  494. init_wheel_base=detect_result.wheel_base;
  495. double init_width=1.85;
  496. double init_theta_front=0*M_PI/180.0;
  497. double variable[] = {cx, cy, init_theta, init_wheel_base, init_width, init_theta_front};
  498. // printf("init solve x:%.3f y: %.3f wheel:%.3f width:%.3f theta : %.3f front theta: %.3f\n",
  499. // variable[0], variable[1], variable[3], variable[4], variable[2], variable[5]);
  500. // 第二部分:构建寻优问题
  501. ceres::Problem problem;
  502. CostFunctor3d *cost_func = new CostFunctor3d(m_left_front_cloud,m_right_front_cloud,m_left_rear_cloud,m_right_rear_cloud,
  503. *mp_left_grid,*mp_right_grid);
  504. //使用自动求导,将之前的代价函数结构体传入,第一个1是输出维度,即残差的维度,第二个1是输入维度,即待寻优参数x的维度。
  505. ceres::CostFunction* cost_function =new
  506. ceres::AutoDiffCostFunction<CostFunctor3d, ceres::DYNAMIC, 6>(
  507. cost_func,
  508. m_left_front_cloud.size()+m_right_front_cloud.size()+m_left_rear_cloud.size()+m_right_rear_cloud.size());
  509. problem.AddResidualBlock(cost_function, NULL, variable); //向问题中添加误差项,本问题比较简单,添加一个就行。
  510. //第三部分: 配置并运行求解器
  511. ceres::Solver::Options options;
  512. // options.use_nonmonotonic_steps=false;
  513. options.linear_solver_type = ceres::DENSE_QR; //配置增量方程的解法
  514. //options.logging_type = ceres::LoggingType::SILENT;
  515. options.max_num_iterations=500;
  516. options.num_threads=1;
  517. options.minimizer_progress_to_stdout = false;//输出到cout
  518. ceres::Solver::Summary summary;//优化信息
  519. ceres::Solve(options, &problem, &summary);//求解!!!
  520. // printf("after solve x:%.3f y: %.3f wheel:%.3f width:%.3f theta : %.3f front theta: %.3f\n",
  521. // variable[0], variable[1], variable[3], variable[4], variable[2], variable[5]);
  522. double loss=summary.final_cost/(m_left_front_cloud.size()+m_right_front_cloud.size()+m_left_rear_cloud.size()+m_right_rear_cloud.size());
  523. detect_result.cx=variable[0];
  524. detect_result.cy=variable[1];
  525. detect_result.theta=(-variable[2])*180.0/M_PI;
  526. detect_result.wheel_base=variable[3];
  527. detect_result.width=variable[4];
  528. detect_result.front_theta=-(variable[5]*180.0/M_PI);
  529. if(detect_result.theta>180.0)
  530. detect_result.theta=detect_result.theta-180.0;
  531. if(detect_result.theta<0)
  532. detect_result.theta+=180.0;
  533. if(summary.iterations.size()<=1){
  534. error_info.append(std::string("仅迭代一轮,优化异常"));
  535. return false;
  536. }
  537. if(summary.iterations[summary.iterations.size()-1].iteration<=1){
  538. error_info.append(std::string("最终仅迭代一轮,优化异常"));
  539. return false;
  540. }
  541. /*printf("it : %d ,summary loss: %.5f \n",
  542. summary.iterations.size(),loss);*/
  543. if (detect_result.width < 1.25 || detect_result.width > 2.000 || detect_result.wheel_base > 3.15 || detect_result.wheel_base < 2.200)
  544. {
  545. error_info.append(std::string("宽度(1.25, 2.00) 轴距(2.20, 3.15): ").append(
  546. std::to_string(detect_result.width).append(", ").append(
  547. std::to_string(detect_result.wheel_base)).append("\t")));
  548. return false;
  549. }
  550. if(detect_result.theta > 120 || detect_result.theta < 60)
  551. {
  552. error_info.append("车身角度错误 ").append(std::to_string(detect_result.theta)).append("\t");
  553. // LOG(WARNING) <<"总角度错误 "<<detect_result.theta;
  554. return false;
  555. }
  556. if(fabs(detect_result.front_theta)>35)
  557. {
  558. error_info.append("前轮角度错误 ").append(std::to_string(detect_result.front_theta)).append("\t");
  559. return false;
  560. }
  561. // 将loss传出
  562. if(cost_func!=nullptr)
  563. {
  564. double costs_lf, costs_rf, costs_lr, costs_rr;
  565. get_costs(variable,costs_lf, costs_rf, costs_lr, costs_rr);
  566. loss_result.lf_loss = costs_lf/float(m_left_front_cloud.size()+1e-6);
  567. loss_result.rf_loss = costs_rf/float(m_right_front_cloud.size()+1e-6);
  568. loss_result.lb_loss = costs_lr/float(m_left_rear_cloud.size()+1e-6);
  569. loss_result.rb_loss = costs_rr/float(m_right_rear_cloud.size()+1e-6);
  570. loss_result.total_avg_loss = loss;
  571. detect_result.loss=loss_result;
  572. if(loss_result.lf_loss>0.4 || loss_result.rf_loss>0.4
  573. ||loss_result.lb_loss>0.4||loss_result.rb_loss>0.4)
  574. {
  575. error_info.append("loss过大 lf").append(std::to_string(loss_result.lf_loss)).append(",rf").append(std::to_string(loss_result.rf_loss)).append(", lr").
  576. append(std::to_string(loss_result.lb_loss)).append(",rb").append(std::to_string(loss_result.rb_loss));
  577. return false;
  578. }
  579. }
  580. else
  581. {
  582. return false;
  583. }
  584. return true;
  585. }