Laser.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. #ifndef __LASER__HH__
  2. #define __LASER__HH__
  3. #include "Point2D.h"
  4. #include "Point3D.h"
  5. #include "LogFiles.h"
  6. #include <glog/logging.h>
  7. #include "../tool/StdCondition.h"
  8. #include "laser_parameter.pb.h"
  9. #include "laser_message.pb.h"
  10. #include "../error_code/error_code.h"
  11. #include "laser_task_command.h"
  12. //雷达消息的类型
  13. //在通信消息的前面一部分字符串,表示这条消息的类型。
  14. //在解析消息的时候,先解析前面的消息类型,来判断这条消息的功用
  15. enum DATA_type
  16. {
  17. eStart =0,
  18. eReady =1,
  19. eData =2,
  20. eStop =3,
  21. eHerror =4,
  22. eUnknow =5,
  23. };
  24. //通信消息的二进制数据,
  25. //这里用字符串,来存储雷达的通信消息的原始数据
  26. //CBinaryData的内容格式:消息类型 + 消息数据
  27. class CBinaryData
  28. {
  29. public:
  30. CBinaryData();
  31. CBinaryData(const CBinaryData& data);
  32. ~CBinaryData();
  33. CBinaryData(const char* buf, int len, DATA_type type= eUnknow);
  34. CBinaryData& operator=(const CBinaryData& data);
  35. bool operator==(const char* str);
  36. const char* operator+(int n);
  37. CBinaryData& operator+(CBinaryData& data);
  38. char& operator[](int n);
  39. char* Data()const;
  40. int Length()const;
  41. protected:
  42. char* m_buf;
  43. int m_length;
  44. };
  45. #include <queue>
  46. #include <memory>
  47. #include <mutex>
  48. #include <condition_variable>
  49. //通信消息的安全队列,用来存储通信消息的二进制数据的容器
  50. template<typename T>
  51. class threadsafe_queue
  52. {
  53. private:
  54. mutable std::mutex mut;
  55. std::queue<T> data_queue;
  56. std::condition_variable data_cond;
  57. public:
  58. threadsafe_queue() {}
  59. threadsafe_queue(threadsafe_queue const& other)
  60. {
  61. std::lock_guard<std::mutex> lk(other.mut);
  62. data_queue = other.data_queue;
  63. }
  64. ~threadsafe_queue()
  65. {
  66. while (!empty())
  67. {
  68. try_pop();
  69. }
  70. }
  71. size_t size()
  72. {
  73. return data_queue.size();
  74. }
  75. void push(T new_value)//��Ӳ���
  76. {
  77. std::lock_guard<std::mutex> lk(mut);
  78. data_queue.push(new_value);
  79. data_cond.notify_one();
  80. }
  81. void wait_and_pop(T& value)//ֱ����Ԫ�ؿ���ɾ��Ϊֹ
  82. {
  83. std::unique_lock<std::mutex> lk(mut);
  84. data_cond.wait(lk, [this] {return !data_queue.empty(); });
  85. value = data_queue.front();
  86. data_queue.pop();
  87. }
  88. std::shared_ptr<T> wait_and_pop()
  89. {
  90. std::unique_lock<std::mutex> lk(mut);
  91. data_cond.wait(lk, [this] {return !data_queue.empty(); });
  92. std::shared_ptr<T> res(std::make_shared<T>(data_queue.front()));
  93. data_queue.pop();
  94. return res;
  95. }
  96. //ֻ���� �� pop
  97. bool front(T& value)
  98. {
  99. std::lock_guard<std::mutex> lk(mut);
  100. if (data_queue.empty())
  101. return false;
  102. value = data_queue.front();
  103. return true;
  104. }
  105. bool try_pop(T& value)//������û�ж���Ԫ��ֱ�ӷ���
  106. {
  107. if (data_queue.empty())
  108. return false;
  109. std::lock_guard<std::mutex> lk(mut);
  110. value = data_queue.front();
  111. data_queue.pop();
  112. return true;
  113. }
  114. std::shared_ptr<T> try_pop()
  115. {
  116. std::lock_guard<std::mutex> lk(mut);
  117. if (data_queue.empty())
  118. return std::shared_ptr<T>();
  119. std::shared_ptr<T> res(std::make_shared<T>(data_queue.front()));
  120. data_queue.pop();
  121. return res;
  122. }
  123. bool empty() const
  124. {
  125. std::lock_guard<std::mutex> lk(mut);
  126. return data_queue.empty();
  127. }
  128. void clear()
  129. {
  130. while (!empty()) {
  131. try_pop();
  132. }
  133. }
  134. };
  135. ///////////////////////////////////////////////
  136. //雷达的工作状态,
  137. //在start和stop中要切换状态
  138. enum eLaserStatu
  139. {
  140. eLaser_ready =0, //雷达正常待机,空闲
  141. eLaser_busy =1, //雷达正在工作,正忙
  142. eLaser_disconnect =2, //雷达断连
  143. eLaser_error =3, //雷达错误
  144. };
  145. //回调函数,当有事件触发是,便会自动调用回调函数,
  146. //typedef从定义,将其简化为PointCallBack,方便后面多次使用
  147. typedef void (*PointCallBack)(CPoint3D , void* );
  148. //雷达的基类,不能直接使用,必须子类继承
  149. class Laser_base
  150. {
  151. public:
  152. //唯一的构造函数,按照设备名称和雷达参数来创建实例。
  153. //input:id: 雷达设备的id,(唯一索引)
  154. //input:laser_param:雷达的参数,
  155. //注:利用protobuf创建stLaserCalibParam类,然后从文件读取参数
  156. Laser_base(int id,Laser_proto::laser_parameter laser_param);
  157. virtual ~Laser_base();
  158. ///��������Դ
  159. virtual bool Connect();
  160. virtual void Disconnect();
  161. //对外的接口函数,负责接受并处理任务单,
  162. //input:p_laser_task 雷达任务单,必须是子类,并且任务正确。
  163. virtual Error_manager execute_task(Task_Base* p_laser_task);
  164. //检查雷达状态,是否正常运行
  165. Error_manager check_error();
  166. ///��ʼ��ֹͣ�ɼ�
  167. virtual bool Start();
  168. virtual bool Stop();
  169. ///���õ��Ʊ任���󣨱궨������
  170. void SetMetrix(double* data);
  171. ///���û�ȡ��ά��ص�����
  172. void SetPointCallBack(PointCallBack fnc,void* pointer);
  173. public:
  174. ///�������ݴ洢·��
  175. void SetSaveDir(std::string strDir,bool bSave=true);
  176. ///��ѯ�״��Ƿ����
  177. bool IsReady() { return (GetStatu() == eLaser_ready && m_queue_laser_data.size()==0); }
  178. virtual eLaserStatu GetStatu(){return m_statu;}
  179. int ID() { return m_id; }
  180. protected:
  181. ////��ȡԭʼ���ݰ�
  182. virtual bool RecvData(CBinaryData& data) = 0;
  183. ////����ԭʼ���ݰ��ɵ���
  184. virtual DATA_type Data2PointXYZ(CBinaryData* pData, std::vector<CPoint3D>& points)=0;
  185. void thread_recv();
  186. void thread_toXYZ();
  187. ////���Ʊ任
  188. virtual CPoint3D transfor(CPoint3D point);
  189. protected:
  190. static void threadPublish(Laser_base* laser);
  191. void PublishMsg();
  192. protected:
  193. std::thread* m_ThreadRcv;
  194. std::thread* m_ThreadPro;
  195. std::thread* m_ThreadPub;
  196. StdCondition m_bThreadRcvRun;
  197. StdCondition m_bThreadProRun;
  198. int m_id;
  199. int m_points_count;
  200. std::mutex m_scan_lock;
  201. bool m_bscan_start;
  202. eLaserStatu m_statu;
  203. bool m_bSave_file;
  204. Laser_proto::laser_parameter m_laser_param;////����
  205. //���ݴ������
  206. threadsafe_queue<CBinaryData*> m_queue_laser_data; // ���ݶ���
  207. CBinaryData m_last_data; //��һ��������δ�������
  208. double* m_dMatrix;
  209. PointCallBack m_point_callback_fnc;
  210. void* m_point_callback_pointer;
  211. //���ݴ洢
  212. CLogFile m_binary_log_tool; //�洢������
  213. CLogFile m_pts_log_tool; //�洢����
  214. std::string m_pts_save_path;
  215. StdCondition m_bStart_capture;
  216. //任务单的指针,实际内存由应用层管理,
  217. //接受任务后,指向新的任务单
  218. Laser_task * mp_laser_task;
  219. };
  220. class LaserRegistory
  221. {
  222. typedef Laser_base* (*CreateLaserFunc)(int id, Laser_proto::laser_parameter laser_param);
  223. public:
  224. LaserRegistory(std::string name, CreateLaserFunc pFun) {
  225. AddCreator(name, pFun);
  226. }
  227. static Laser_base* CreateLaser(std::string name, int id,Laser_proto::laser_parameter laser_param) {
  228. if (GetFuncMap().count(name) == 0)
  229. return 0;
  230. return GetFuncMap()[name](id,laser_param);
  231. }
  232. private:
  233. static std::map<std::string, CreateLaserFunc>& GetFuncMap() {
  234. static std::map<std::string, CreateLaserFunc>* g_map = new std::map<std::string, CreateLaserFunc>;
  235. return *g_map;
  236. }
  237. void AddCreator(std::string name, CreateLaserFunc pFun) {
  238. GetFuncMap()[name] = pFun;
  239. }
  240. };
  241. #define RegisterLaser(NAME) \
  242. static Laser_base* Create_##NAME##_Laser(int id, Laser_proto::laser_parameter param) \
  243. { \
  244. return new C##NAME##Laser(id,param); \
  245. } \
  246. LaserRegistory g_##NAME##_Laser(#NAME,Create_##NAME##_Laser);
  247. #endif