LivoxLaser.puml 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. @startuml
  2. skinparam classAttributeIconSize 0
  3. <<<<<<< HEAD
  4. title CLivoxLaser 大疆livox雷达
  5. =======
  6. title CLivoxLaser
  7. >>>>>>> origin/hl
  8. class CLivoxLaser
  9. {
  10. //大疆livox雷达,从Laser_base继承。
  11. ==protected:==
  12. //雷达设备状态,livox管理底层sdk,后台线程的工作状态
  13. typedef enum
  14. {
  15. kDeviceStateDisconnect = 0, //雷达设备状态 断开连接
  16. kDeviceStateConnect = 1, //雷达设备状态 连接正常
  17. kDeviceStateSampling = 2, //雷达设备状态 正在扫描
  18. } DeviceState;
  19. ..
  20. //雷达设备信息,
  21. typedef struct
  22. {
  23. uint8_t handle; //雷达控制句柄
  24. DeviceState device_state; //雷达设备状态
  25. DeviceInfo info; //雷达基本信息
  26. } DeviceItem;
  27. ==public:==
  28. CLivoxLaser() = delete;
  29. CLivoxLaser(const CLivoxLaser& other) = delete;
  30. //唯一的构造函数,按照设备名称和雷达参数来创建实例。
  31. CLivoxLaser(int id, Laser_proto::laser_parameter laser_param);
  32. ~CLivoxLaser();
  33. ..
  34. //雷达链接设备,为3个线程添加线程执行函数。
  35. virtual Error_manager connect_laser();
  36. //雷达断开链接,释放3个线程
  37. virtual Error_manager disconnect_laser();
  38. //对外的接口函数,负责接受并处理任务单,
  39. virtual Error_manager execute_task(Task_Base* p_laser_task);
  40. //检查雷达状态,是否正常运行
  41. virtual Error_manager check_laser();
  42. //雷达的启动接口函数, 让雷达进行扫描,一般需要子类重载,不同的雷达开始方式不同。
  43. virtual Error_manager start_scan();
  44. //雷达的停止接口函数, 让雷达停止扫描,一般需要子类重载,不同的雷达结束方式不同。
  45. virtual Error_manager stop_scan();
  46. //结束任务单,stop之后,要检查线程状态和数据结果,然后才能 end_task
  47. virtual Error_manager end_task();
  48. ..
  49. //判断雷达状态是否为待机,如果已经准备好,则可以执行任务。
  50. //子类重载 is_ready(),里面增加livox sdk后台线程状态的判断。
  51. virtual bool is_ready();
  52. ==protected:==
  53. //接受二进制消息的功能函数,每次只接受一个CBinaryData
  54. virtual bool receive_buf_to_queue(Binary_buf& binary_buf);
  55. //将二进制消息转化为三维点云的功能函数,每次只转化一个CBinaryData,
  56. virtual Buf_type transform_buf_to_points(Binary_buf* p_binary_buf, std::vector<CPoint3D>& point3D_cloud);
  57. ==protected:==
  58. static void InitLivox();
  59. virtual bool IsScanComplete();
  60. virtual void UpdataHandle();
  61. static void LidarDataCallback(uint8_t handle, LivoxEthPacket *data, uint32_t data_num, void *laser);
  62. static void OnDeviceChange(const DeviceInfo *info, DeviceEvent type);
  63. static void OnDeviceBroadcast(const BroadcastDeviceInfo *info);
  64. static void OnSampleCallback(uint8_t status, uint8_t handle, uint8_t response, void *data);
  65. ==protected:==
  66. uint8_t m_handle;
  67. unsigned int m_frame_maxnum;
  68. Thread_safe_queue<Binary_buf*> m_queue_livox_data;
  69. static DeviceItem g_devices[kMaxLidarCount];
  70. static std::map<uint8_t,std::string> g_handle_sn;
  71. static std::map<std::string, uint8_t> g_sn_handle;
  72. static std::map<std::string, CLivoxLaser*> g_sn_laser;
  73. static CLivoxLaser* g_all_laser[kMaxLidarCount];
  74. static unsigned int g_count[kMaxLidarCount];
  75. }
  76. class Laser_base
  77. {
  78. //雷达的基类,不能直接使用,必须子类继承
  79. ==public:==
  80. Laser_base() = delete;
  81. Laser_base(const Laser_base& other) = delete;
  82. ..
  83. //唯一的构造函数,按照设备名称和雷达参数来创建实例。
  84. //input:id: 雷达设备的id,(唯一索引)
  85. //input:laser_param:雷达的参数,
  86. //注:利用protobuf创建 laser_parameter 类,然后从文件读取参数
  87. Laser_base(int laser_id,Laser_proto::laser_parameter laser_param);
  88. //析构函数
  89. ~Laser_base();
  90. ..
  91. //雷达链接设备,为3个线程添加线程执行函数。
  92. virtual Error_manager connect_laser();
  93. //雷达断开链接,释放3个线程
  94. virtual Error_manager disconnect_laser();
  95. //对外的接口函数,负责接受并处理任务单,
  96. //input:p_laser_task 雷达任务单,基类的指针,指向子类的实例,(多态)
  97. //注:这个函数为虚函数,实际的处理任务的代码由子类重载并实现。
  98. virtual Error_manager execute_task(Task_Base* p_laser_task);
  99. //检查雷达状态,是否正常运行
  100. virtual Error_manager check_laser();
  101. //雷达的启动接口函数, 让雷达进行扫描,一般需要子类重载,不同的雷达开始方式不同。
  102. virtual Error_manager start_scan();
  103. //雷达的停止接口函数, 让雷达停止扫描,一般需要子类重载,不同的雷达结束方式不同。
  104. virtual Error_manager stop_scan();
  105. //结束任务单,stop之后,要检查线程状态和数据结果,然后才能 end_task
  106. virtual Error_manager end_task();
  107. ==public:==
  108. //设置保存文件的路径,并打开文件,
  109. Error_manager set_open_save_path(std::string save_path,bool is_save=true);
  110. //关闭保存文件,推出前一定要执行
  111. Error_manager close_save_path();
  112. //判断雷达状态是否为待机,如果已经准备好,则可以执行任务。
  113. //子类重载 is_ready(),里面增加livox sdk后台线程状态的判断。
  114. virtual bool is_ready();
  115. //获取雷达id
  116. int get_laser_id();
  117. ==protected:==
  118. //接受二进制消息的功能函数,每次只接受一个CBinaryData
  119. // 纯虚函数,必须由子类重载,
  120. virtual bool receive_buf_to_queue(Binary_buf& binary_buf) = 0;
  121. //线程执行函数,将二进制消息存入队列缓存,
  122. void thread_receive();
  123. ..
  124. //将二进制消息转化为三维点云的功能函数,每次只转化一个CBinaryData,
  125. // 纯虚函数,必须由子类重载,
  126. virtual Buf_type transform_buf_to_points(Binary_buf* p_binary_buf, std::vector<CPoint3D>& point3D_cloud)=0;
  127. //线程执行函数,转化并处理三维点云。
  128. void thread_transform();
  129. ..
  130. //公开发布雷达信息的功能函数,
  131. Error_manager publish_laser_to_message();
  132. //线程执行函数,公开发布雷达的相关信息,用作上位机的监视。
  133. static void thread_publish(Laser_base* p_laser);
  134. ..
  135. //获取雷达状态
  136. Laser_statu get_laser_statu();
  137. ==protected:==
  138. //初始化变换矩阵,设置默认值
  139. Error_manager init_laser_matrix();
  140. //设置变换矩阵,用作三维点的坐标变换,
  141. Error_manager set_laser_matrix(double* p_matrix, int size);
  142. ..
  143. //三维点的坐标变换的功能函数,从雷达自己的坐标系,转化到公共坐标系,(目前以plc为公共坐标系)
  144. virtual CPoint3D transform_by_matrix(CPoint3D point);
  145. ==protected:==
  146. //为了保证多线程的数据安全,修改共享数据必须加锁。 atomic 和 安全队列 可以不加锁进行读写
  147. //建议:判断标志位使用 atomic, 容器要封装并使用 安全容器,
  148. std::mutex m_laser_lock; //雷达数据锁
  149. ..
  150. std::atomic<int> m_laser_id; //雷达设备id
  151. Laser_proto::laser_parameter m_laser_param; //雷达的配置参数
  152. //雷达变换矩阵,三维点的坐标变换的矩阵,从雷达自己的坐标系,转化到公共坐标系,(目前以plc为公共坐标系)
  153. //必须在set_laser_matrix之后,才能使用。(connect时,从雷达的配置参数导入)
  154. double mp_laser_matrix[LASER_MATRIX_ARRAY_SIZE]; //雷达变换矩阵
  155. //雷达扫描事件的标志位,受start和stop控制,然后其他线程判断m_scan_flag标准位,来进行启停。
  156. std::atomic<bool> m_laser_scan_flag; //雷达扫描的使能标志位
  157. //雷达状态和任务状态同步,m_scan_flag停止之后,还要等任务执行完成,才会切回 ready。
  158. std::atomic<Laser_statu> m_laser_statu; //雷达工作状态,基类三线程的状态
  159. //注:m_laser_statu是基类的三线程的状态,和livox sdk后台线程状态没有任何关系。
  160. //子类重载 is_ready(),里面增加livox sdk后台线程状态的判断。
  161. ..
  162. std::atomic<int> m_points_count; //雷达采集点的计数
  163. Thread_safe_queue<Binary_buf*> m_queue_laser_data; //二进制缓存的队列容器
  164. Binary_buf m_last_data; //上一个二进制缓存,用作数据拼接
  165. ..
  166. std::atomic<bool> m_save_flag; //雷达保存文件的使能标志位
  167. std::string m_save_path; //雷达保存文件的保存路径
  168. CLogFile m_binary_log_tool; //二进制缓存的日志工具
  169. CLogFile m_points_log_tool; //三维点云的日志工具
  170. ..
  171. //线程指针的内存管理,由Connect和Disconnect进行分配和释放。
  172. std::thread* mp_thread_receive; //接受缓存的线程指针
  173. Thread_condition m_condition_receive; //接受缓存的条件变量
  174. std::thread* mp_thread_transform; //转化数据的线程指针
  175. Thread_condition m_condition_transform; //转化数据的条件变量
  176. std::thread* mp_thread_publish; //发布信息的线程指针
  177. Thread_condition m_condition_publish; //发布信息的条件变量
  178. ..
  179. //任务单的指针,实际内存由应用层管理,
  180. //接受任务后,指向新的任务单
  181. Laser_task * mp_laser_task; //任务单的指针
  182. }
  183. class CLivoxMid100Laser
  184. {
  185. ==public:==
  186. CLivoxMid100Laser(int id, Laser_proto::laser_parameter laser_param);
  187. ~CLivoxMid100Laser();
  188. ..
  189. //雷达链接设备,为3个线程添加线程执行函数。
  190. virtual Error_manager connect_laser();
  191. //雷达断开链接,释放3个线程
  192. virtual Error_manager disconnect_laser();
  193. //对外的接口函数,负责接受并处理任务单,
  194. //input:p_laser_task 雷达任务单,基类的指针,指向子类的实例,(多态)
  195. //注:这个函数为虚函数,实际的处理任务的代码由子类重载并实现。
  196. virtual Error_manager execute_task(Task_Base* p_laser_task);
  197. //检查雷达状态,是否正常运行
  198. virtual Error_manager check_laser();
  199. //雷达的启动接口函数, 让雷达进行扫描,一般需要子类重载,不同的雷达开始方式不同。
  200. virtual Error_manager start_scan();
  201. //雷达的停止接口函数, 让雷达停止扫描,一般需要子类重载,不同的雷达结束方式不同。
  202. virtual Error_manager stop_scan();
  203. //结束任务单,stop之后,要检查线程状态和数据结果,然后才能 end_task
  204. virtual Error_manager end_task();
  205. ..
  206. //判断雷达状态是否为待机,如果已经准备好,则可以执行任务。
  207. //子类重载 is_ready(),里面增加livox sdk后台线程状态的判断。
  208. virtual bool is_ready();
  209. ==protected:==
  210. virtual bool IsScanComplete();
  211. virtual void UpdataHandle();
  212. ==protected:==
  213. uint8_t m_handle1;
  214. uint8_t m_handle2;
  215. uint8_t m_handle3;
  216. }
  217. Laser_base -> CLivoxLaser : inherit
  218. CLivoxLaser -> CLivoxMid100Laser : inherit
  219. @enduml