detect_manager.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. //
  2. // Created by zx on 2023/11/24.
  3. //
  4. #include "detect_manager.h"
  5. Error_manager DetectManager::Init(const google::protobuf::RepeatedPtrField<tof3dVzenseEtc> &tof_devices) {
  6. for (int device_index = 0; device_index < DeviceAzimuth::DEVICE_AZIMUTH_MAX; device_index++) {
  7. TofTransformationManager::iter()->set((DeviceAzimuth)device_index, tof_devices[device_index].trans());
  8. updateTrans((DeviceAzimuth) device_index, tof_devices[device_index].trans());
  9. }
  10. m_thread = new std::thread(&DetectManager::run, this);
  11. m_condit.notify_all(true);
  12. return {};
  13. }
  14. Error_manager DetectManager::Release() {
  15. stop();
  16. return {};
  17. }
  18. Error_manager DetectManager::updateTrans(const DeviceAzimuth &azimuth, const CoordinateTransformation3D &trans) {
  19. Eigen::Matrix4f rotaition = Eigen::Matrix4f::Identity();
  20. Eigen::Matrix3f rotation_matrix3 = Eigen::Matrix3f::Identity();
  21. rotation_matrix3 =
  22. Eigen::AngleAxisf(trans.yaw() * M_PI / 180.f, Eigen::Vector3f::UnitZ()) *
  23. Eigen::AngleAxisf(trans.pitch() * M_PI / 180.f, Eigen::Vector3f::UnitY()) *
  24. Eigen::AngleAxisf(trans.roll() * M_PI / 180.f, Eigen::Vector3f::UnitX());
  25. Eigen::Vector3f move;
  26. move << trans.x(), trans.y(), trans.z();
  27. rotaition.block<3, 3>(0, 0) = rotation_matrix3;
  28. rotaition.col(3) << move;
  29. rotation_matrix4[azimuth] = rotaition;
  30. return {};
  31. }
  32. #include "tool/time.hpp"
  33. bool boxIsValid(const JetStream::SegBox& box, int min ,bool reverse=false){
  34. if(box.confidence()<0.8){
  35. return false;
  36. }
  37. int left_side = box.x();
  38. if(reverse){
  39. left_side=640-(box.x()+box.width());
  40. }
  41. return left_side > min;
  42. }
  43. int IsInImageValidRegion(const JetStream::LabelYolo &labels) {
  44. if(labels.boxes_size()!=4){
  45. return -1; //没有识别框
  46. }
  47. for (int device_index = 0; device_index < 4; device_index++) {
  48. // LOG(INFO) << device_index << ": "<< labels.boxes(device_index).confidence() << " " << labels.boxes(device_index).x();
  49. }
  50. JetStream::SegBox box2=labels.boxes(1);
  51. JetStream::SegBox box4=labels.boxes(3);
  52. bool frontExsit = labels.boxes(0).confidence() > 0.8 || labels.boxes(1).confidence() > 0.8;
  53. bool backExist = labels.boxes(2).confidence() > 0.8 || labels.boxes(3).confidence() > 0.8;
  54. if(!frontExsit){
  55. if(backExist){ //后有前没有
  56. return 1; //往前
  57. }else{ //前后都没有
  58. return -1;
  59. }
  60. }else{
  61. if(backExist){
  62. bool front_OK = boxIsValid(labels.boxes(1), 20) || boxIsValid(labels.boxes(0), 20,true);
  63. bool back_OK = boxIsValid(labels.boxes(2), 20,true) || boxIsValid(labels.boxes(3), 20);
  64. if(front_OK && back_OK){
  65. return 0;
  66. }else{
  67. return 1;
  68. }
  69. }else{ // 前有后没有
  70. bool front_OK=boxIsValid(labels.boxes(1),320) || boxIsValid(labels.boxes(0),320,true);
  71. if(!front_OK){
  72. return 1;
  73. }else{
  74. return -1;
  75. }
  76. }
  77. }
  78. }
  79. void DetectManager::run() {
  80. LOG(INFO) << "detect thread running in " << std::this_thread::get_id();
  81. DetectResult m_detect_result_record;
  82. std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> vct_wheel_cloud;
  83. for (int i = 0; i < DeviceAzimuth::DEVICE_AZIMUTH_MAX; i++) {
  84. vct_wheel_cloud.emplace_back(new pcl::PointCloud<pcl::PointXYZ>);
  85. }
  86. auto t_start_time = std::chrono::steady_clock::now();
  87. std::chrono::duration<double> cost = std::chrono::steady_clock::now() - t_start_time;
  88. while (m_condit.is_alive()) {
  89. m_condit.wait();
  90. // 参数初始化
  91. cost = std::chrono::steady_clock::now() - t_start_time;
  92. std::this_thread::sleep_for(std::chrono::milliseconds(50 - std::min<int>(49, cost.count() * 1000)));
  93. t_start_time = std::chrono::steady_clock::now();
  94. if (m_condit.is_alive()) {
  95. std::vector<int> have_cloud;
  96. DetectResult detect_result;
  97. JetStream::LabelYolo seg_results;
  98. for (int i = 0; i < DeviceAzimuth::DEVICE_AZIMUTH_MAX; i++) {
  99. vct_wheel_cloud[i]->clear();
  100. }
  101. if (!LabelYoloDataBuffer::iter()->lock_exe(&LabelYoloDataBuffer::get, seg_results, 10)) {
  102. continue;
  103. }
  104. // 判断识别结果数量以及是否存图
  105. int seg_num = 0;
  106. for (int device_index = 0; device_index < DeviceAzimuth::DEVICE_AZIMUTH_MAX; device_index++) {
  107. // LOG(INFO) << device_index << ": " << seg_results.boxes(device_index).confidence();
  108. if (seg_results.boxes(device_index).confidence() > 0.7) {
  109. seg_num++;
  110. }
  111. }
  112. if (seg_num == 0) {
  113. detect_statu = MeasureStatu::Measure_Empty_Clouds;
  114. m_detect_result_record.reset();
  115. continue;
  116. }
  117. // 取高置信度识别结果
  118. for (int device_index = 0; device_index < DeviceAzimuth::DEVICE_AZIMUTH_MAX; device_index++) {
  119. if (seg_results.boxes(device_index).confidence() < 0.9) {
  120. DLOG(INFO) << device_index << " empty";
  121. continue;
  122. }
  123. cv::Mat pointMat;
  124. //LOG(INFO) << "b get data" << " empty";
  125. if (MatDataBuffer::iter()->lock_exe(&MatDataBuffer::get, device_index, seg_results.label(), pointMat,
  126. 10)) {
  127. have_cloud.push_back(device_index);
  128. std::vector<cv::Point> seg_points;
  129. for (int row = 0; row < 480; row++) {
  130. for (int col = seg_results.boxes(device_index).lines(row).begin();
  131. col < seg_results.boxes(device_index).lines(row).end(); col++) {
  132. seg_points.emplace_back(col, row);
  133. vct_wheel_cloud[device_index]->emplace_back(pointMat.at<cv::Vec3f>(row, col)[0] * 0.001,
  134. pointMat.at<cv::Vec3f>(row, col)[1] * 0.001,
  135. pointMat.at<cv::Vec3f>(row, col)[2] * 0.001);
  136. }
  137. }
  138. TransitData::get_instance_pointer()->setMask(seg_points, device_index);
  139. CoordinateTransformation3D device_trans;
  140. // 更新旋转坐标
  141. if (TofTransformationManager::iter()->get((DeviceAzimuth)device_index, device_trans)) {
  142. updateTrans((DeviceAzimuth)device_index, device_trans);
  143. }
  144. pcl::transformPointCloud(*vct_wheel_cloud[device_index], *vct_wheel_cloud[device_index],
  145. rotation_matrix4[device_index]());
  146. // Point3D_tool::WriteTxtCloud(ETC_PATH PROJECT_NAME "/data/cloud_" + std::to_string(device_index) + ".txt", vct_wheel_cloud[device_index]);
  147. }
  148. }
  149. int flag = IsInImageValidRegion(seg_results);
  150. if (flag == 1) {
  151. LOG(INFO) << "向前";
  152. detect_statu = MeasureStatu::Measure_Border;
  153. continue;
  154. } else if (flag == -1){
  155. LOG(WARNING) << "缺少轮子";
  156. continue;
  157. }
  158. // 点云处理
  159. if (!have_cloud.empty()) {
  160. WheelCloudOptimize(vct_wheel_cloud, detect_result);
  161. cost = std::chrono::steady_clock::now() - t_start_time;
  162. DLOG(INFO) << "cost time is " << cost.count() * 1000 << " ms";
  163. bool ceres_detect_ret = false;
  164. auto wheel_detect = detect_wheel_ceres::iter();
  165. // 采用上次测量结果的数据
  166. if (!m_detect_result_time_lock_data.timeout(0.5)) {
  167. detect_result = m_detect_result_time_lock_data();
  168. detect_result.car.wheel_width = MIN(detect_result.car.wheel_width + 0.4, 2.5);
  169. } else {
  170. detect_result.car.wheel_width = 3;
  171. detect_result.car.wheel_base = 2.7;
  172. }
  173. // 根据车轮数采用不同的优化方式
  174. if (m_detect_result_record.car.wheel_width < 1.0 || m_detect_result_record.car.wheel_base < 2.0 ||
  175. have_cloud.size() > 2) {
  176. ceres_detect_ret = wheel_detect->detect_2Step(vct_wheel_cloud[DeviceAzimuth::DEVICE_AZIMUTH_LF],
  177. vct_wheel_cloud[DeviceAzimuth::DEVICE_AZIMUTH_RF],
  178. vct_wheel_cloud[DeviceAzimuth::DEVICE_AZIMUTH_LR],
  179. vct_wheel_cloud[DeviceAzimuth::DEVICE_AZIMUTH_RR],
  180. detect_result.car.wheels_center_x,
  181. detect_result.car.wheels_center_y,
  182. detect_result.car.theta, detect_result.car.wheel_base,
  183. detect_result.car.wheel_width,
  184. detect_result.car.front_wheels_theta,
  185. detect_result.car.loss);
  186. if ((m_detect_result_record.car.wheel_width < 1.0 && m_detect_result_record.car.wheel_base < 1.0 &&
  187. have_cloud.size() == 2) || have_cloud.size() < 2) {
  188. detect_result.car.wheel_width = m_detect_result_record.car.wheel_width;
  189. detect_result.car.wheel_base = m_detect_result_record.car.wheel_base;
  190. } else if (have_cloud.size() == 2) {
  191. for (int device_index = 0; device_index < DeviceAzimuth::DEVICE_AZIMUTH_MAX; device_index++) {
  192. if (!vct_wheel_cloud[device_index]->empty()) {
  193. have_cloud.push_back(device_index);
  194. }
  195. }
  196. if (have_cloud[0] % 2 == have_cloud[1] % 2) {
  197. detect_result.car.wheel_width = m_detect_result_record.car.wheel_width;
  198. } else {
  199. detect_result.car.wheel_base = m_detect_result_record.car.wheel_base;
  200. }
  201. }
  202. } else {
  203. ceres_detect_ret = wheel_detect->detect_dynP(vct_wheel_cloud[DeviceAzimuth::DEVICE_AZIMUTH_LF],
  204. vct_wheel_cloud[DeviceAzimuth::DEVICE_AZIMUTH_RF],
  205. vct_wheel_cloud[DeviceAzimuth::DEVICE_AZIMUTH_LR],
  206. vct_wheel_cloud[DeviceAzimuth::DEVICE_AZIMUTH_RR],
  207. detect_result.car.wheels_center_x,
  208. detect_result.car.wheels_center_y,
  209. detect_result.car.theta,
  210. m_detect_result_record.car.wheel_base,
  211. m_detect_result_record.car.wheel_width,
  212. detect_result.car.front_wheels_theta,
  213. detect_result.car.loss);
  214. detect_result.car.wheel_base = m_detect_result_record.car.wheel_base;
  215. detect_result.car.wheel_width = m_detect_result_record.car.wheel_width;
  216. }
  217. // 如果车辆运动,不断刷新运动时间,如果由运动转为静止则刷新运动状态到静止
  218. float move_distance = detect_result.car.wheels_center_y - m_detect_result_record.car.wheels_center_y;
  219. if (fabs(move_distance) > 0.1) {
  220. move_statu = true;
  221. } else if (move_statu()) {
  222. move_statu = false;
  223. }
  224. if (ceres_detect_ret) {
  225. // 记录下测量结果
  226. m_detect_result_record = detect_result;
  227. detect_statu = Measure_OK;
  228. m_detect_result_time_lock_data = m_detect_result_record;
  229. } else {
  230. detect_statu = Measure_Failture;
  231. }
  232. }
  233. cost = std::chrono::steady_clock::now() - t_start_time;
  234. DLOG(INFO) << "cost time is " << cost.count() * 1000 << " ms";
  235. } else {
  236. cv::destroyAllWindows();
  237. }
  238. }
  239. LOG(INFO) << "detect thread " << std::this_thread::get_id() << " closed.";
  240. }
  241. void DetectManager::stop() {
  242. //杀死线程,
  243. m_condit.kill_all();
  244. //在线程join结束之后, 就可以可以回收线程内存资源
  245. m_thread->join();
  246. delete m_thread;
  247. m_thread = nullptr;
  248. }
  249. Error_manager DetectManager::WheelCloudOptimize(std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> &vct_wheel_cloud,
  250. DetectResult &result) {
  251. //下采样
  252. pcl::VoxelGrid<pcl::PointXYZ> vox; //创建滤波对象
  253. vox.setLeafSize(0.03f, 0.03f, 0.03f); //设置滤波时创建的体素体积为1cm的立方体
  254. pcl::PointCloud<pcl::PointXYZ>::Ptr filtered_cloud(new pcl::PointCloud<pcl::PointXYZ>);
  255. for (int device_index = 0; device_index < DeviceAzimuth::DEVICE_AZIMUTH_MAX; device_index++) {
  256. if (vct_wheel_cloud[device_index]->empty()) { continue; }
  257. vox.setInputCloud(vct_wheel_cloud[device_index]); //设置需要过滤的点云给滤波对象
  258. vox.filter(*vct_wheel_cloud[device_index]); //执行滤波处理,存储输出
  259. }
  260. return {};
  261. }
  262. MeasureStatu DetectManager::getMeasureResult(DetectManager::DetectResult &result) {
  263. if (detect_statu() != MeasureStatu::Measure_OK) {
  264. return detect_statu();
  265. }
  266. if (m_detect_result_time_lock_data.timeout()) {
  267. return MeasureStatu::Measure_Failture;
  268. }
  269. result = m_detect_result_time_lock_data();
  270. return MeasureStatu::Measure_OK;
  271. }
  272. Error_manager DetectManager::carMoveStatus() {
  273. if (move_statu.timeout(3) && !move_statu()) {
  274. return {FAILED, NORMAL};
  275. }
  276. return {};
  277. }
  278. Error_manager DetectManager::Stop() {
  279. m_condit.kill_all();
  280. m_thread->join();
  281. delete m_thread;
  282. m_thread = nullptr;
  283. return {};
  284. }
  285. Error_manager DetectManager::Continue() {
  286. m_condit.reset();
  287. m_thread = new std::thread(&DetectManager::run, this);
  288. m_condit.notify_all(true);
  289. return {};
  290. }