detect_manager.cpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. //
  2. // Created by zx on 2023/11/24.
  3. //
  4. #include "detect_manager.h"
  5. Error_manager DetectManager::Init() {
  6. m_thread = new std::thread(&DetectManager::run, this);
  7. m_condit.notify_all(true);
  8. return {};
  9. }
  10. Error_manager DetectManager::Release() {
  11. stop();
  12. return {};
  13. }
  14. void DetectManager::run() {
  15. LOG(INFO) << "detect thread running in " << std::this_thread::get_id();
  16. DetectResult m_detect_result_record;
  17. std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> vct_wheel_cloud;
  18. for (int i = 0; i < DeviceAzimuth::DEVICE_AZIMUTH_MAX; i++) {
  19. vct_wheel_cloud.emplace_back(new pcl::PointCloud<pcl::PointXYZ>);
  20. }
  21. auto t_start_time = std::chrono::steady_clock::now();
  22. std::chrono::duration<double> cost = std::chrono::steady_clock::now() - t_start_time;
  23. while (m_condit.is_alive()) {
  24. m_condit.wait();
  25. // 参数初始化
  26. cost = std::chrono::steady_clock::now() - t_start_time;
  27. std::this_thread::sleep_for(std::chrono::milliseconds(100 - std::min<int>(99, cost.count() * 1000)));
  28. t_start_time = std::chrono::steady_clock::now();
  29. if (m_condit.is_alive()) {
  30. std::vector<int> have_cloud;
  31. DetectResult detect_result;
  32. JetStream::LabelYolo seg_results;
  33. if (!LabelYoloDataBuffer::iter()->lock_exe(&LabelYoloDataBuffer::get, seg_results, 10)) {
  34. continue;
  35. }
  36. LOG(INFO) << seg_results.label() << " " << seg_results.boxes(0).lines_size();
  37. for (int device_index = 0; device_index < DeviceAzimuth::DEVICE_AZIMUTH_MAX; device_index++) {
  38. if (seg_results.boxes(device_index).lines().empty()) {
  39. LOG(INFO) << device_index << " empty";
  40. continue;
  41. }
  42. cv::Mat pointMat;
  43. LOG(INFO) << "b get data" << " empty";
  44. if (MatDataBuffer::iter()->lock_exe(&MatDataBuffer::get, device_index, seg_results.label(), pointMat, 10)) {
  45. cv::imshow(std::to_string(device_index), pointMat);
  46. cv::waitKey(1);
  47. }
  48. LOG(INFO) << "e get data" << " empty";
  49. continue;
  50. have_cloud.push_back(device_index);
  51. for (int row = 0; row < 480; row++) {
  52. for (int col = seg_results.boxes(device_index).lines(row).begin(); col < seg_results.boxes(device_index).lines(row).end(); col++) {
  53. vct_wheel_cloud[device_index]->emplace_back(pointMat.at<cv::Vec3f>(row, col)[0],
  54. pointMat.at<cv::Vec3f>(row, col)[1],
  55. pointMat.at<cv::Vec3f>(row, col)[2]);
  56. }
  57. }
  58. }
  59. continue;
  60. // 点云处理
  61. if (!have_cloud.empty()) {
  62. WheelCloudOptimize(vct_wheel_cloud, detect_result);
  63. cost = std::chrono::steady_clock::now() - t_start_time;
  64. DLOG(INFO) << "cost time is " << cost.count() * 1000 << " ms";
  65. bool ceres_detect_ret = false;
  66. auto wheel_detect = detect_wheel_ceres::iter();
  67. // 采用上次测量结果的数据
  68. if (!m_detect_result_time_lock_data.timeout(0.5)) {
  69. detect_result = m_detect_result_time_lock_data();
  70. detect_result.car.wheel_width = MIN(detect_result.car.wheel_width + 0.4, 2.5);
  71. } else {
  72. detect_result.car.wheel_width = 3;
  73. detect_result.car.wheel_base = 2.7;
  74. }
  75. // TODO:测试功能
  76. wheel_detect->detect_fall(vct_wheel_cloud[DeviceAzimuth::DEVICE_AZIMUTH_LF], vct_wheel_cloud[DeviceAzimuth::DEVICE_AZIMUTH_RF],
  77. vct_wheel_cloud[DeviceAzimuth::DEVICE_AZIMUTH_LR], vct_wheel_cloud[DeviceAzimuth::DEVICE_AZIMUTH_RR],
  78. detect_result.car.wheels_center_x, detect_result.car.wheels_center_y,
  79. detect_result.car.theta, detect_result.car.wheel_base,
  80. detect_result.car.wheel_width,detect_result.car.front_wheels_theta, detect_result.car.loss);
  81. // 根据车轮数采用不同的优化方式
  82. if (m_detect_result_record.car.wheel_width < 1.0 || m_detect_result_record.car.wheel_base < 2.0 ||
  83. have_cloud.size() > 2) {
  84. ceres_detect_ret = wheel_detect->detect_2Step(vct_wheel_cloud[DeviceAzimuth::DEVICE_AZIMUTH_LF], vct_wheel_cloud[DeviceAzimuth::DEVICE_AZIMUTH_RF],
  85. vct_wheel_cloud[DeviceAzimuth::DEVICE_AZIMUTH_LR], vct_wheel_cloud[DeviceAzimuth::DEVICE_AZIMUTH_RR],
  86. detect_result.car.wheels_center_x, detect_result.car.wheels_center_y,
  87. detect_result.car.theta, detect_result.car.wheel_base,
  88. detect_result.car.wheel_width,detect_result.car.front_wheels_theta, detect_result.car.loss);
  89. if ((m_detect_result_record.car.wheel_width < 1.0 && m_detect_result_record.car.wheel_base < 1.0 && have_cloud.size() == 2) || have_cloud.size() < 2) {
  90. detect_result.car.wheel_width = m_detect_result_record.car.wheel_width;
  91. detect_result.car.wheel_base = m_detect_result_record.car.wheel_base;
  92. } else if (have_cloud.size() == 2) {
  93. for (int device_index = 0; device_index < DeviceAzimuth::DEVICE_AZIMUTH_MAX; device_index++) {
  94. if (!vct_wheel_cloud[device_index]->empty()) {
  95. have_cloud.push_back(device_index);
  96. }
  97. }
  98. if (have_cloud[0] % 2 == have_cloud[1] %2 ) {
  99. detect_result.car.wheel_width = m_detect_result_record.car.wheel_width;
  100. } else {
  101. detect_result.car.wheel_base = m_detect_result_record.car.wheel_base;
  102. }
  103. }
  104. } else {
  105. ceres_detect_ret = wheel_detect->detect_dynP(vct_wheel_cloud[DeviceAzimuth::DEVICE_AZIMUTH_LF], vct_wheel_cloud[DeviceAzimuth::DEVICE_AZIMUTH_RF],
  106. vct_wheel_cloud[DeviceAzimuth::DEVICE_AZIMUTH_LR], vct_wheel_cloud[DeviceAzimuth::DEVICE_AZIMUTH_RR],
  107. detect_result.car.wheels_center_x, detect_result.car.wheels_center_y,
  108. detect_result.car.theta, m_detect_result_record.car.wheel_base,
  109. m_detect_result_record.car.wheel_width,detect_result.car.front_wheels_theta, detect_result.car.loss);
  110. detect_result.car.wheel_base = m_detect_result_record.car.wheel_base;
  111. detect_result.car.wheel_width = m_detect_result_record.car.wheel_width;
  112. }
  113. // 如果车辆运动,不断刷新运动时间,如果由运动转为静止则刷新运动状态到静止
  114. float move_distance = detect_result.car.wheels_center_y - m_detect_result_record.car.wheels_center_y;
  115. if (fabs(move_distance) > 0.1) {
  116. move_statu = true;
  117. } else if (move_statu()) {
  118. move_statu = false;
  119. }
  120. if (ceres_detect_ret) {
  121. // 记录下测量结果
  122. m_detect_result_record = detect_result;
  123. detect_statu = Measure_OK;
  124. m_detect_result_time_lock_data = m_detect_result_record;
  125. } else {
  126. detect_statu = Measure_Failture;
  127. }
  128. }
  129. cost = std::chrono::steady_clock::now() - t_start_time;
  130. DLOG(INFO) << "cost time is " << cost.count() * 1000 << " ms";
  131. } else {
  132. cv::destroyAllWindows();
  133. }
  134. }
  135. LOG(INFO) << "detect thread " << std::this_thread::get_id() << " closed.";
  136. }
  137. void DetectManager::stop() {
  138. //杀死线程,
  139. m_condit.kill_all();
  140. //在线程join结束之后, 就可以可以回收线程内存资源
  141. m_thread->join();
  142. delete m_thread;
  143. m_thread = nullptr;
  144. }
  145. Error_manager DetectManager::WheelCloudOptimize(std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> &vct_wheel_cloud, DetectResult &result) {
  146. //下采样
  147. pcl::VoxelGrid<pcl::PointXYZ> vox; //创建滤波对象
  148. vox.setLeafSize(0.03f, 0.03f, 0.03f); //设置滤波时创建的体素体积为1cm的立方体
  149. pcl::PointCloud<pcl::PointXYZ>::Ptr filtered_cloud(new pcl::PointCloud<pcl::PointXYZ>);
  150. for (int device_index = 0; device_index < DeviceAzimuth::DEVICE_AZIMUTH_MAX; device_index++) {
  151. if (vct_wheel_cloud[device_index]->empty()) { continue;}
  152. vox.setInputCloud(vct_wheel_cloud[device_index]); //设置需要过滤的点云给滤波对象
  153. vox.filter(*vct_wheel_cloud[device_index]); //执行滤波处理,存储输出
  154. }
  155. return {};
  156. }
  157. MeasureStatu DetectManager::getMeasureResult(DetectManager::DetectResult &result) {
  158. if (detect_statu() != MeasureStatu::Measure_OK) {
  159. return detect_statu();
  160. }
  161. if (m_detect_result_time_lock_data.timeout()) {
  162. return MeasureStatu::Measure_Failture;
  163. }
  164. result = m_detect_result_time_lock_data();
  165. return MeasureStatu::Measure_OK;
  166. }
  167. Error_manager DetectManager::carMoveStatus() {
  168. if (move_statu.timeout(3) && !move_statu()) {
  169. return {FAILED, NORMAL};
  170. }
  171. return {};
  172. }