wj_716_lidar_protocol.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. #ifndef WJ_716_LIDAR_PROTOCOL_H
  2. #define WJ_716_LIDAR_PROTOCOL_H
  3. #include <iostream>
  4. #include "string.h"
  5. #include <boost/shared_ptr.hpp>
  6. #include <boost/asio.hpp>
  7. #include <boost/asio/placeholders.hpp>
  8. #include <boost/system/error_code.hpp>
  9. #include <boost/bind/bind.hpp>
  10. #include <mutex>
  11. #include <chrono>
  12. #include <math.h>
  13. #include <pcl/point_types.h>
  14. #include <pcl/PCLPointCloud2.h>
  15. #include <pcl/conversions.h>
  16. #include <pcl/common/common.h>
  17. #include <google/protobuf/io/coded_stream.h>
  18. #include <google/protobuf/io/zero_copy_stream_impl.h>
  19. #include <google/protobuf/text_format.h>
  20. using google::protobuf::Message;
  21. using google::protobuf::io::CodedInputStream;
  22. using google::protobuf::io::CodedOutputStream;
  23. using google::protobuf::io::FileInputStream;
  24. using google::protobuf::io::FileOutputStream;
  25. using google::protobuf::io::ZeroCopyInputStream;
  26. using google::protobuf::io::ZeroCopyOutputStream;
  27. #include "glog/logging.h"
  28. #include "wj_lidar_conf.pb.h"
  29. #include "error_code/error_code.hpp"
  30. #include "tool/binary_buf.h"
  31. #include "tool/thread_safe_queue.hpp"
  32. #include "tool/thread_condition.h"
  33. #include "tool/point2D_tool.h"
  34. #include "tool/common_data.h"
  35. class Wj_716_lidar_protocol
  36. {
  37. public:
  38. //万集雷达解析协议状态
  39. enum Wanji_lidar_protocol_status
  40. {//default E_UNKNOWN = 0
  41. E_UNKNOWN = 0, //未知
  42. E_READY = 1, //正常待机
  43. E_FAULT = 10, //故障
  44. };
  45. //万集雷达扫描周期66ms, (频率15hz), 一般设置大一些
  46. #define WANJI_FRAME_SCAN_CYCLE_MS WANJI_716_SCAN_CYCLE_MS
  47. //万集716的通信数据长度, 每帧都是固定 898 byte
  48. #define WANJI_FRAME_LENGTH_716 898
  49. //万集716的数据头
  50. #define WANJI_FRAME_HEAD_716 0x02020202
  51. //万集716的点数, 一共811个点, 分开发送时, 前者405个点, 后者406个点
  52. #define WANJI_SCAN_POINT_NUMBER_TOTAL 811
  53. #define WANJI_SCAN_POINT_NUMBER_FORMER 405
  54. #define WANJI_SCAN_POINT_NUMBER_LATTER 406
  55. //万集716的角度范围, 角度-135~135, 弧度-2.35619449~2.35619449
  56. #define WANJI_SCAN_POINT_ANGLE_MIN -2.35619449
  57. #define WANJI_SCAN_POINT_ANGLE_MAX 2.35619449
  58. //万集716的角度分辨率, (每一度3个点), 135*2/(811-1)=0.333333333, 弧度0.005817764
  59. #define WANJI_SCAN_POINT_ANGLE_INCREMENT 0.005817764
  60. public:
  61. // 构造
  62. Wj_716_lidar_protocol();
  63. // 析构
  64. ~Wj_716_lidar_protocol();
  65. // 初始化
  66. Error_manager init(Thread_safe_queue<Binary_buf*>* p_communication_data_queue,
  67. Point2D_tool::Polar_coordinates_box polar_coordinates_box,
  68. Point2D_tool::Point2D_box point2D_box,
  69. Point2D_tool::Point2D_transform point2D_transform);
  70. //反初始化
  71. Error_manager uninit();
  72. //检查状态
  73. Error_manager check_status();
  74. //判断是否为待机,如果已经准备好,则可以执行任务。
  75. bool is_ready();
  76. public:
  77. //获取状态
  78. Wanji_lidar_protocol_status get_status();
  79. //获取扫描周期
  80. int get_scan_cycle();
  81. // 获取扫描点云
  82. Error_manager get_scan_points(pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud_out);
  83. //获取二次回波点云
  84. Error_manager get_two_echo_points(pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud_out);
  85. // 获取扫描点云更新时间点
  86. std::chrono::system_clock::time_point get_scan_time();
  87. std::chrono::system_clock::time_point get_two_echo_time();
  88. private:
  89. //解析线程函数
  90. void thread_analysis();
  91. //检查数据头和长度, 注:返回失败只是表示消息格式不对不是需要处理的消息, 忽略就好了
  92. bool check_head_and_length(Binary_buf* p_binary_buf);
  93. // 消息完整性检查, 检查末尾的校验码, 注:返回失败只是表示消息格式不对不是需要处理的消息, 忽略就好了
  94. bool check_xor(Binary_buf* p_binary_buf);
  95. // 万集通信协议, 解析数据, 转化为点云
  96. Error_manager data_protocol_analysis(Binary_buf* p_binary_buf);
  97. // 把点到雷达的距离, 转化为标准坐标下的点云
  98. Error_manager polar_coordinates_transform_cloud(float* p_point_distance, int number, pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud_out);
  99. protected:
  100. //状态
  101. std::atomic<Wanji_lidar_protocol_status> m_wanji_lidar_protocol_status; //万集雷达解析协议状态
  102. //数据
  103. Thread_safe_queue<Binary_buf*>* mp_communication_data_queue; //通信数据队列, 内存由上级管理
  104. //雷达扫描点的极坐标
  105. float m_scan_point_distance[WANJI_SCAN_POINT_NUMBER_TOTAL];//雷达扫描点的距离, 核心数据
  106. float m_scan_point_intensity[WANJI_SCAN_POINT_NUMBER_TOTAL];//雷达扫描点的光强,
  107. float m_two_echo_point_distance[WANJI_SCAN_POINT_NUMBER_TOTAL];//二次反射点的距离
  108. unsigned int m_current_frame_number; //当前数据的帧号
  109. //雷达扫描点平面坐标
  110. pcl::PointCloud<pcl::PointXYZ>::Ptr mp_scan_points; //扫描点的点云, 内存由本类管理
  111. pcl::PointCloud<pcl::PointXYZ>::Ptr mp_two_echo_points; //二次反射点的点云, 内存由本类管理
  112. // 点云获取互斥锁
  113. std::mutex m_scan_mutex; //扫描点的锁
  114. std::mutex m_two_echo_mutex; //二次反射点的锁
  115. // 扫描点云更新时间点
  116. std::chrono::system_clock::time_point m_scan_cloud_time; //扫描点的更新时间
  117. std::chrono::system_clock::time_point m_two_echo_cloud_time; //二次反射点的更新时间
  118. //控制参数
  119. Point2D_tool::Polar_coordinates_box m_polar_coordinates_box; //极坐标的限定范围
  120. Point2D_tool::Point2D_box m_point2D_box; //平面坐标的限定范围
  121. Point2D_tool::Point2D_transform m_point2D_transform; //平面坐标的转换矩阵
  122. //解析数据的线程, 自动从队列取出原始数据, 然后解析为点云
  123. std::thread * mp_thread_analysis; // 解析线程, 内存由本模块管理
  124. Thread_condition m_condition_analysis; //解析线程的条件变量
  125. };
  126. #endif // WJ_716_LIDAR_PROTOCOL_H