wanji_716N_device.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. #include "wanji_716N_device.h"
  2. // 万集雷达封装类构造函数
  3. Wanji_716N_lidar_device::Wanji_716N_lidar_device()
  4. {
  5. m_wanji_lidar_device_status = E_UNKNOWN;
  6. }
  7. // 万集雷达封装类析构函数
  8. Wanji_716N_lidar_device::~Wanji_716N_lidar_device()
  9. {
  10. uninit();
  11. }
  12. // 初始化
  13. Error_manager Wanji_716N_lidar_device::init(wj::wjLidarParams params)
  14. {
  15. Error_manager t_error;
  16. LOG(INFO) << " Wanji_716N_lidar_device::init "<< this;
  17. //唤醒队列
  18. m_communication_data_queue.wake_queue();
  19. m_lidar_id = params.lidar_id();
  20. //控制参数
  21. Point2D_tool::Polar_coordinates_box t_polar_coordinates_box; //极坐标的限定范围
  22. Point2D_tool::Point2D_box t_point2D_box; //平面坐标的限定范围
  23. Point2D_tool::Point2D_transform t_point2D_transform; //平面坐标的转换矩阵
  24. t_polar_coordinates_box.angle_min = params.angle_min();
  25. t_polar_coordinates_box.angle_max = params.angle_max();
  26. t_polar_coordinates_box.distance_min = params.range_min();
  27. t_polar_coordinates_box.distance_max = params.range_max();
  28. t_point2D_box.x_min = params.scan_limit().minx();
  29. t_point2D_box.x_max = params.scan_limit().maxx();
  30. t_point2D_box.y_min = params.scan_limit().miny();
  31. t_point2D_box.y_max = params.scan_limit().maxy();
  32. t_point2D_transform.m00 = params.transform().m00();
  33. t_point2D_transform.m01 = params.transform().m01();
  34. t_point2D_transform.m02 = params.transform().m02();
  35. t_point2D_transform.m10 = params.transform().m10();
  36. t_point2D_transform.m11 = params.transform().m11();
  37. t_point2D_transform.m12 = params.transform().m12();
  38. //初始化通信协议
  39. t_error = m_protocol.init(&m_communication_data_queue, t_polar_coordinates_box, t_point2D_box, t_point2D_transform);
  40. if (t_error != SUCCESS)
  41. {
  42. return t_error;
  43. }
  44. //初始化雷达通信模块
  45. std::string t_ip = params.net_config().ip_address();
  46. int t_port = params.net_config().port();
  47. t_error = m_async_client.init(t_ip, t_port, &m_communication_data_queue);
  48. if ( t_error != SUCCESS )
  49. {
  50. return t_error;
  51. }
  52. //启动 内部线程。默认wait。
  53. m_execute_condition.reset(false, false, false);
  54. // mp_execute_thread = new std::thread(&Wanji_716N_lidar_device::execute_thread_fun, this);
  55. m_wanji_lidar_device_status = E_READY;
  56. return t_error;
  57. }
  58. //反初始化
  59. Error_manager Wanji_716N_lidar_device::uninit()
  60. {
  61. //终止队列,防止 wait_and_pop 阻塞线程。
  62. m_communication_data_queue.termination_queue();
  63. //关闭线程
  64. if (mp_execute_thread)
  65. {
  66. m_execute_condition.kill_all();
  67. }
  68. //回收线程的资源
  69. if (mp_execute_thread)
  70. {
  71. mp_execute_thread->join();
  72. delete mp_execute_thread;
  73. mp_execute_thread = NULL;
  74. }
  75. m_async_client.uninit();
  76. m_protocol.uninit();
  77. //清空队列
  78. m_communication_data_queue.clear_and_delete();
  79. if ( m_wanji_lidar_device_status != E_FAULT )
  80. {
  81. m_wanji_lidar_device_status = E_UNKNOWN;
  82. }
  83. return Error_code::SUCCESS;
  84. }
  85. //检查雷达状态,是否正常运行
  86. Error_manager Wanji_716N_lidar_device::check_status()
  87. {
  88. updata_status();
  89. if ( m_wanji_lidar_device_status == E_READY )
  90. {
  91. return Error_code::SUCCESS;
  92. }
  93. else if(m_wanji_lidar_device_status == E_BUSY)
  94. {
  95. return Error_manager(Error_code::WANJI_LIDAR_DEVICE_STATUS_BUSY, Error_level::NEGLIGIBLE_ERROR,
  96. " Wanji_716N_lidar_device::check_status() error ");
  97. }
  98. else
  99. {
  100. return Error_manager(Error_code::WANJI_LIDAR_DEVICE_STATUS_ERROR, Error_level::MINOR_ERROR,
  101. " Wanji_716N_lidar_device::check_status() error ");
  102. }
  103. return Error_code::SUCCESS;
  104. }
  105. //判断是否为待机,如果已经准备好,则可以执行任务。
  106. bool Wanji_716N_lidar_device::is_ready()
  107. {
  108. updata_status();
  109. return m_wanji_lidar_device_status == E_READY;
  110. }
  111. //外部调用获取新的点云, 获取指令时间之后的点云, 如果没有就会等待点云刷新, 直到超时, (内置while)
  112. Error_manager Wanji_716N_lidar_device::get_new_cloud_and_wait(std::mutex* p_mutex, pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud,
  113. std::chrono::system_clock::time_point command_time, int timeout_ms)
  114. {
  115. if ( p_mutex == NULL || p_cloud.get() == NULL )
  116. {
  117. return Error_manager(Error_code::POINTER_IS_NULL, Error_level::MINOR_ERROR,
  118. " POINTER IS NULL ");
  119. }
  120. //判断是否超时
  121. while (std::chrono::system_clock::now() - command_time < std::chrono::milliseconds(timeout_ms))
  122. {
  123. //获取指令时间之后的点云, 如果没有就会循环
  124. if( m_protocol.get_scan_time() > command_time )
  125. {
  126. std::unique_lock<std::mutex> lck(*p_mutex);
  127. Error_manager code = m_protocol.get_scan_points(p_cloud);
  128. return code;
  129. }
  130. //else 等待下一次数据更新
  131. //等1ms
  132. std::this_thread::sleep_for(std::chrono::milliseconds(1));
  133. }
  134. //超时退出就报错
  135. return Error_manager(Error_code::WJ_LIDAR_GET_CLOUD_TIMEOUT, Error_level::MINOR_ERROR,
  136. " Wanji_716N_lidar_device::get_new_cloud_and_wait error ");
  137. }
  138. //外部调用获取当前点云, 获取指令时间之后的点云, 如果没有就会报错, 不会等待
  139. Error_manager Wanji_716N_lidar_device::get_current_cloud(std::mutex* p_mutex, pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud,
  140. std::chrono::system_clock::time_point command_time)
  141. {
  142. if ( p_mutex == NULL || p_cloud.get() == NULL )
  143. {
  144. return Error_manager(Error_code::POINTER_IS_NULL, Error_level::MINOR_ERROR,
  145. " POINTER IS NULL ");
  146. }
  147. //获取指令时间之后的点云, 如果没有就会报错, 不会等待
  148. if( m_protocol.get_scan_time() > command_time )
  149. {
  150. std::unique_lock<std::mutex> lck(*p_mutex);
  151. Error_manager code = m_protocol.get_scan_points(p_cloud);
  152. return code;
  153. }
  154. else
  155. {
  156. return Error_manager(Error_code::WANJI_LIDAR_DEVICE_NO_CLOUD, Error_level::MINOR_ERROR,
  157. " Wanji_716N_lidar_device::get_current_cloud error ");
  158. }
  159. }
  160. //外部调用获取最新的点云, 获取指令时间往前一个周期内的点云, 如果没有就会报错, 不会等待
  161. Error_manager Wanji_716N_lidar_device::get_last_cloud(std::mutex* p_mutex, pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud,
  162. std::chrono::system_clock::time_point command_time)
  163. {
  164. if ( p_mutex == NULL || p_cloud.get() == NULL )
  165. {
  166. return Error_manager(Error_code::POINTER_IS_NULL, Error_level::MINOR_ERROR,
  167. " POINTER IS NULL ");
  168. }
  169. int t_scan_cycle_ms = m_protocol.get_scan_cycle();
  170. //将指令时间提前一个扫描周期, 然后获取这个时间后面的点云.
  171. //就是说, 在收到指令的时候, 可以使用一个周期以前的数据, 不用获取最新的点云.
  172. if( m_protocol.get_scan_time() > command_time - std::chrono::milliseconds(t_scan_cycle_ms) )
  173. {
  174. std::unique_lock<std::mutex> lck(*p_mutex);
  175. Error_manager code = m_protocol.get_scan_points(p_cloud);
  176. return code;
  177. }
  178. else
  179. {
  180. return Error_manager(Error_code::WANJI_LIDAR_DEVICE_NO_CLOUD, Error_level::MINOR_ERROR,
  181. " Wanji_716N_lidar_device::get_last_cloud error ");
  182. }
  183. }
  184. //外部调用获取最新的点云, 获取指令时间往前一个周期内的点云, 如果没有就会报错, 不会等待
  185. //注:函数内部不加锁, 由外部统一加锁.
  186. Error_manager Wanji_716N_lidar_device::get_last_cloud(pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud,
  187. std::chrono::system_clock::time_point command_time)
  188. {
  189. if ( p_cloud.get() == NULL )
  190. {
  191. return Error_manager(Error_code::POINTER_IS_NULL, Error_level::MINOR_ERROR,
  192. " POINTER IS NULL ");
  193. }
  194. int t_scan_cycle_ms = m_protocol.get_scan_cycle();
  195. //将指令时间提前一个扫描周期, 然后获取这个时间后面的点云.
  196. //就是说, 在收到指令的时候, 可以使用一个周期以前的数据, 不用获取最新的点云.
  197. if( m_protocol.get_scan_time() > command_time - std::chrono::milliseconds(t_scan_cycle_ms*2) )
  198. {
  199. Error_manager code = m_protocol.get_scan_points(p_cloud);
  200. // LOG(WARNING) << " !!!!!!!!!!!!! wj scan cloud: "<<p_cloud->size();
  201. return code;
  202. }
  203. else
  204. {
  205. // LOG(WARNING) << "get cloud failed..... "<<m_protocol.get_scan_time().time_since_epoch().count()<<", "<<command_time.time_since_epoch().count();
  206. return Error_manager(Error_code::WANJI_LIDAR_DEVICE_NO_CLOUD, Error_level::MINOR_ERROR,
  207. " Wanji_716N_lidar_device::get_last_cloud error ");
  208. }
  209. }
  210. Wanji_716N_lidar_device::Wanji_716N_device_status Wanji_716N_lidar_device::get_status()
  211. {
  212. updata_status();
  213. return m_wanji_lidar_device_status;
  214. }
  215. void Wanji_716N_lidar_device::updata_status()
  216. {
  217. Async_Client::Communication_status communication_status = m_async_client.get_status();
  218. // Wj_716N_lidar_protocol::Wanji_716N_device_status wanji_lidar_protocol_status = m_protocol.get_status();
  219. if ( communication_status == Async_Client::Communication_status::E_FAULT)// ||
  220. // wanji_lidar_protocol_status == Wj_716N_lidar_protocol::Wanji_716N_device_status::E_FAULT)
  221. {
  222. m_wanji_lidar_device_status = E_FAULT;
  223. }
  224. if ( communication_status == Async_Client::Communication_status::E_DISCONNECT )
  225. {
  226. m_wanji_lidar_device_status = E_DISCONNECT;
  227. }
  228. else if ( communication_status == Async_Client::Communication_status::E_READY)// &&
  229. // wanji_lidar_protocol_status == Wj_716N_lidar_protocol::Wanji_716N_device_status::E_READY )
  230. {
  231. if ( m_execute_condition.get_pass_ever() )
  232. {
  233. m_wanji_lidar_device_status = E_BUSY;
  234. }
  235. else
  236. {
  237. m_wanji_lidar_device_status = E_READY;
  238. }
  239. }
  240. else
  241. {
  242. m_wanji_lidar_device_status = E_UNKNOWN;
  243. }
  244. }