region_worker.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. //
  2. // Created by zx on 2019/12/9.
  3. //
  4. #ifndef REGION_WORKER_H
  5. #define REGION_WORKER_H
  6. #include "region_detect.h"
  7. //#include "../tool/StdCondition.h"
  8. #include <thread>
  9. #include <mutex>
  10. #include <iostream>
  11. #include <atomic>
  12. #include <chrono>
  13. #include "error_code/error_code.hpp"
  14. #include "verify/Verify_result.h"
  15. #include "tool/thread_condition.h"
  16. #include "tool/common_data.h"
  17. /**
  18. * 区域功能类,负责自动检测区域状态并更新到plc
  19. * */
  20. class Region_worker
  21. {
  22. public:
  23. #define REGION_WORKER_RESULT_DEFAULT 0x0000
  24. //#define REGION_WORKER_VERIFY_OK 0x0001
  25. //#define REGION_WORKER_EMPTY_SPACE 0x0020
  26. //#define REGION_WORKER_CLUSTER_SIZE_ERROR 0x0040
  27. //#define REGION_WORKER_OTHER_ERROR 0x0080
  28. //#define REGION_WORKER_NULL_POINTER 0x0100
  29. #define REGION_WORKER_EMPTY_SPACE 1
  30. #define REGION_WORKER_HAS_CAR 2
  31. #define REGION_WORKER_DETECT_ERROR 3
  32. //区域功能类 的预测算法的时间周期, 一般为100ms, 我们这里设一个较大值200ms
  33. #define REGION_WORKER_DETECT_CYCLE_MS 200
  34. //万集区域功能的状态
  35. enum Region_worker_status
  36. {
  37. E_UNKNOWN = 0, //未知
  38. E_READY = 1, //准备,待机
  39. E_BUSY = 2, //工作正忙
  40. E_FAULT = 10, //故障
  41. };
  42. // 超界情况
  43. enum Range_status_wj
  44. {
  45. Range_correct = 0x0000, // 未超界
  46. Range_front = 0x0001, //前超界
  47. Range_back = 0x0002, //后超界
  48. Range_left = 0x0004, // 左超界
  49. Range_right = 0x0008, // 右超界
  50. Range_bottom = 0x0010, //底盘超界
  51. Range_top = 0x0020, // 车顶超界
  52. Range_car_width = 0x0040, // 车宽超界
  53. Range_car_wheelbase = 0x0080, // 轴距超界
  54. Range_angle_anti_clock = 0x0100, // 左(逆时针)旋转超界
  55. Range_angle_clock = 0x0200, // 右(顺时针)旋转超界
  56. Range_steering_wheel_nozero = 0x0400, // 方向盘未回正
  57. Range_car_moving = 0x0800, // 车辆移动为1,静止为0
  58. };
  59. public:
  60. Region_worker();
  61. ~Region_worker();
  62. Error_manager init(wj::Region region);
  63. // // 初始化传入编号,仅普爱使用
  64. // Error_manager init(wj::Region region, std::mutex* p_cloud_collection_mutex,
  65. // pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud_collection, int index);
  66. // 公有点云更新函数,传入最新点云获得结果
  67. Error_manager update_cloud(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud);
  68. //开始自动预测的算法线程
  69. Error_manager start_auto_detect();
  70. //关闭自动预测的算法线程
  71. Error_manager stop_auto_detect();
  72. // 获得中心点、角度等测量数据
  73. Error_manager detect_wheel_result(std::mutex* p_cloud_mutex, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in,
  74. Common_data::Car_wheel_information& car_wheel_information);
  75. // 获得中心点、角度等测量数据, 新算法, 可以测量前轮旋转
  76. Error_manager detect_wheel_result_ex(std::mutex* p_cloud_mutex, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in,
  77. Common_data::Car_wheel_information& car_wheel_information);
  78. //外部调用获取新的车轮定位信息, 获取指令时间之后的车轮定位信息, 如果没有就会等待车轮定位信息刷新, 直到超时, (内置while)
  79. Error_manager get_new_wheel_information_and_wait(Common_data::Car_wheel_information* p_car_wheel_information,
  80. std::chrono::system_clock::time_point command_time, int timeout_ms=1500);
  81. //外部调用获取当前车轮定位信息, 获取指令时间之后的车轮定位信息, 如果没有就会报错, 不会等待
  82. Error_manager get_current_wheel_information(Common_data::Car_wheel_information* p_car_wheel_information,
  83. std::chrono::system_clock::time_point command_time);
  84. //外部调用获取最新的车轮定位信息, 获取指令时间往前一个周期内的车轮定位信息, 如果没有就会报错, 不会等待
  85. Error_manager get_last_wheel_information(Common_data::Car_wheel_information* p_car_wheel_information,
  86. std::chrono::system_clock::time_point command_time);
  87. void get_region_cloud(pcl::PointCloud<pcl::PointXYZ>::Ptr &out_cloud)
  88. {
  89. out_cloud->clear();
  90. if(mp_cloud_collection_mutex == nullptr)
  91. {
  92. return;
  93. }
  94. mp_cloud_collection_mutex->lock();
  95. out_cloud->operator+=(*mp_cloud_collection);
  96. mp_cloud_collection_mutex->unlock();
  97. }
  98. // 获取区域终端号, 注意!未初始化调用将返回-1
  99. int get_terminal_id()
  100. {
  101. if(m_region_worker_status == E_UNKNOWN)
  102. return -1;
  103. else
  104. return m_region_param.region_id();
  105. }
  106. // 获取区域状态
  107. Region_worker_status get_status() { return m_region_worker_status; }
  108. // 获取更新时间
  109. std::chrono::system_clock::time_point get_detect_update_time() { return m_detect_update_time; }
  110. // 获取配置参数
  111. wj::Region get_param() { return m_region_param; }
  112. // 检查激光是否在区域中
  113. bool check_lidar_inside(int lidar_id)
  114. {
  115. for (size_t i = 0; i < m_region_param.lidar_exts_size(); i++)
  116. {
  117. if(m_region_param.lidar_exts(i).lidar_id() == lidar_id)
  118. return true;
  119. }
  120. return false;
  121. }
  122. public:
  123. std::chrono::system_clock::time_point get_detect_updata_time();
  124. protected:
  125. static cv::RotatedRect create_rotate_rect(float length,float width,float angle,float x,float y);
  126. //自动预测的线程函数
  127. void auto_detect_thread_fun();
  128. // 超界判断,旋转单位(deg),默认无旋转
  129. // 主要判断左右超界
  130. int outOfRangeDetection(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, double plate_cx=0.0, double plate_cy=0.0, double theta=0.0);
  131. // 超界判断,增加对后轮的判断,对轴距、车宽、角度超界的判断
  132. int outOfRangeDetection(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, Common_data::Car_wheel_information measure_result, double plate_cx=0.0, double plate_cy=0.0, double theta=0.0);
  133. protected:
  134. // int m_index;// 区域编号,仅普爱使用
  135. wj::Region m_region_param;
  136. //状态
  137. Region_worker_status m_region_worker_status; //万集区域功能的状态
  138. Region_detector* mp_detector; // 区域检测算法实例
  139. //万集雷达的自动功能, 定时收集所有点云, 然后通知detect去计算车轮信息.
  140. std::mutex* mp_cloud_collection_mutex; // 点云更新互斥锁, 内存由上级管理
  141. pcl::PointCloud<pcl::PointXYZ>::Ptr mp_cloud_collection; //扫描点的点云集合, 内存由上级管理
  142. Common_data::Car_wheel_information m_car_wheel_information; //车轮的定位结果,
  143. std::chrono::system_clock::time_point m_detect_update_time; //定位结果的更新时间.
  144. std::thread* mp_auto_detect_thread; //自动预测的线程指针,内存由本类管理
  145. Thread_condition m_auto_detect_condition; //自动预测的条件变量
  146. // pcl::PointCloud<pcl::PointXYZ>::Ptr m_cloud; // 自动区域检测用点云
  147. // std::atomic<bool> mb_cloud_updated; // 点云更新指标
  148. ////
  149. //// std::chrono::system_clock::time_point m_update_plc_time; // 更新plc状态时刻
  150. //// int m_last_sent_code; // 上次写入plc的状态值
  151. //// int m_last_read_code; // 上次检查获得的状态值
  152. //// int m_last_border_status; // 上次超界提示
  153. //// std::atomic<int> m_read_code_count; // 检查后重复获取相同状态值次数
  154. //
  155. // Thread_condition m_cond_exit; // 系统退出标志
  156. // std::thread *m_detect_thread; // 实时检测线程
  157. // std::mutex m_mutex; // 点云互斥锁
  158. //
  159. // Verify_result* mp_verify_handle; // 边缘检测
  160. };
  161. #endif //REGION_WORKER_H