Laser.h 7.7 KB

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