#ifndef WJ_716_LIDAR_PROTOCOL_H #define WJ_716_LIDAR_PROTOCOL_H #include #include "string.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using google::protobuf::Message; using google::protobuf::io::CodedInputStream; using google::protobuf::io::CodedOutputStream; using google::protobuf::io::FileInputStream; using google::protobuf::io::FileOutputStream; using google::protobuf::io::ZeroCopyInputStream; using google::protobuf::io::ZeroCopyOutputStream; #include "glog/logging.h" #include "wj_lidar_conf.pb.h" #include "../error_code/error_code.h" #include "../tool/binary_buf.h" #include "../tool/thread_safe_queue.h" #include "../tool/thread_condition.h" #include "../tool/point2D_tool.h" #include "../tool/common_data.h" class Wj_716_lidar_protocol { public: //万集雷达解析协议状态 enum Wanji_lidar_protocol_status {//default E_UNKNOWN = 0 E_UNKNOWN = 0, //未知 E_READY = 1, //正常待机 E_FAULT = 10, //故障 }; //万集雷达扫描周期66ms, (频率15hz), 一般设置大一些 #define WANJI_FRAME_SCAN_CYCLE_MS WANJI_716_SCAN_CYCLE_MS //万集716的通信数据长度, 每帧都是固定 898 byte #define WANJI_FRAME_LENGTH_716 898 //万集716的数据头 #define WANJI_FRAME_HEAD_716 0x02020202 //万集716的点数, 一共811个点, 分开发送时, 前者405个点, 后者406个点 #define WANJI_SCAN_POINT_NUMBER_TOTAL 811 #define WANJI_SCAN_POINT_NUMBER_FORMER 405 #define WANJI_SCAN_POINT_NUMBER_LATTER 406 //万集716的角度范围, 角度-135~135, 弧度-2.35619449~2.35619449 #define WANJI_SCAN_POINT_ANGLE_MIN -2.35619449 #define WANJI_SCAN_POINT_ANGLE_MAX 2.35619449 //万集716的角度分辨率, (每一度3个点), 135*2/(811-1)=0.333333333, 弧度0.005817764 #define WANJI_SCAN_POINT_ANGLE_INCREMENT 0.005817764 public: // 构造 Wj_716_lidar_protocol(); // 析构 ~Wj_716_lidar_protocol(); // 初始化 Error_manager init(Thread_safe_queue* p_communication_data_queue, Point2D_tool::Polar_coordinates_box polar_coordinates_box, Point2D_tool::Point2D_box point2D_box, Point2D_tool::Point2D_transform point2D_transform); //反初始化 Error_manager uninit(); //检查状态 Error_manager check_status(); //判断是否为待机,如果已经准备好,则可以执行任务。 bool is_ready(); public: //获取状态 Wanji_lidar_protocol_status get_status(); //获取扫描周期 int get_scan_cycle(); // 获取扫描点云 Error_manager get_scan_points(pcl::PointCloud::Ptr p_cloud_out); //获取二次回波点云 Error_manager get_two_echo_points(pcl::PointCloud::Ptr p_cloud_out); // 获取扫描点云更新时间点 std::chrono::system_clock::time_point get_scan_time(); std::chrono::system_clock::time_point get_two_echo_time(); private: //解析线程函数 void thread_analysis(); //检查数据头和长度, 注:返回失败只是表示消息格式不对不是需要处理的消息, 忽略就好了 bool check_head_and_length(Binary_buf* p_binary_buf); // 消息完整性检查, 检查末尾的校验码, 注:返回失败只是表示消息格式不对不是需要处理的消息, 忽略就好了 bool check_xor(Binary_buf* p_binary_buf); // 万集通信协议, 解析数据, 转化为点云 Error_manager data_protocol_analysis(Binary_buf* p_binary_buf); // 把点到雷达的距离, 转化为标准坐标下的点云 Error_manager polar_coordinates_transform_cloud(float* p_point_distance, int number, pcl::PointCloud::Ptr p_cloud_out); protected: //状态 std::atomic m_wanji_lidar_protocol_status; //万集雷达解析协议状态 //数据 Thread_safe_queue* mp_communication_data_queue; //通信数据队列, 内存由上级管理 //雷达扫描点的极坐标 float m_scan_point_distance[WANJI_SCAN_POINT_NUMBER_TOTAL];//雷达扫描点的距离, 核心数据 float m_scan_point_intensity[WANJI_SCAN_POINT_NUMBER_TOTAL];//雷达扫描点的光强, float m_two_echo_point_distance[WANJI_SCAN_POINT_NUMBER_TOTAL];//二次反射点的距离 unsigned int m_current_frame_number; //当前数据的帧号 //雷达扫描点平面坐标 pcl::PointCloud::Ptr mp_scan_points; //扫描点的点云, 内存由本类管理 pcl::PointCloud::Ptr mp_two_echo_points; //二次反射点的点云, 内存由本类管理 // 点云获取互斥锁 std::mutex m_scan_mutex; //扫描点的锁 std::mutex m_two_echo_mutex; //二次反射点的锁 // 扫描点云更新时间点 std::chrono::system_clock::time_point m_scan_cloud_time; //扫描点的更新时间 std::chrono::system_clock::time_point m_two_echo_cloud_time; //二次反射点的更新时间 //控制参数 Point2D_tool::Polar_coordinates_box m_polar_coordinates_box; //极坐标的限定范围 Point2D_tool::Point2D_box m_point2D_box; //平面坐标的限定范围 Point2D_tool::Point2D_transform m_point2D_transform; //平面坐标的转换矩阵 //解析数据的线程, 自动从队列取出原始数据, 然后解析为点云 std::thread * mp_thread_analysis; // 解析线程, 内存由本模块管理 Thread_condition m_condition_analysis; //解析线程的条件变量 }; #endif // WJ_716_LIDAR_PROTOCOL_H