LakiBeamUDP.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. #ifndef LAKIBEAMUDP_H
  2. #define LAKIBEAMUDP_H
  3. #include <boost/thread.hpp>
  4. #include <boost/asio.hpp>
  5. #include <boost/scoped_ptr.hpp>
  6. #include <boost/smart_ptr.hpp>
  7. #include <boost/date_time/posix_time/posix_time.hpp>
  8. #include <boost/bimap.hpp>
  9. #include <sstream>
  10. #include <cstdlib>
  11. #include <iostream>
  12. #include <stdio.h>
  13. using namespace std;
  14. /// 已使用声明:用来消除未使用变量报警,没有功能上面的意义
  15. #ifndef USED
  16. #define USED(x) ((void)x)
  17. #endif
  18. /// 调试接口:快速打印调试信息
  19. #ifndef DEBUG
  20. #define DEBUG(x) (cout << x << endl)
  21. #endif
  22. /// 取消字节对齐:下面定义的数据结构体与雷达的协议结构相互映射,不可以进行自动对齐字节
  23. #define __autoalign__ __attribute__((packed))
  24. /**
  25. * 为了统一代码风格,对部分数据类型进行了重新定义
  26. */
  27. #ifndef i32_t
  28. typedef signed int i32_t;
  29. #endif
  30. #ifndef u32_t
  31. typedef unsigned int u32_t;
  32. #endif
  33. #ifndef u16_t
  34. typedef unsigned short u16_t;
  35. #endif
  36. #ifndef u16_t
  37. typedef unsigned short i16_t;
  38. #endif
  39. #ifndef u8_t
  40. typedef unsigned char u8_t;
  41. #endif
  42. #ifndef c8_t
  43. typedef char i8_t;
  44. #endif
  45. #ifndef udp_socket_t
  46. typedef boost::asio::ip::udp::socket udp_socket_t;
  47. #endif
  48. #ifndef address_t
  49. typedef boost::asio::ip::address address_t;
  50. #endif
  51. #ifndef service_t
  52. typedef boost::asio::io_service service_t;
  53. #endif
  54. typedef boost::scoped_ptr<boost::thread> thread_t;
  55. #ifndef service_work_t
  56. typedef boost::scoped_ptr<service_t::work> service_work_t;
  57. #endif
  58. #ifndef endpoint_t
  59. typedef boost::asio::ip::udp::endpoint udp_endpoint_t;
  60. #endif
  61. #ifndef mutex_t
  62. typedef boost::mutex mutex_t;
  63. #endif
  64. /// UDP数据报的数据帧大小——42字节UDP数据头不用于数据解码 1206 = 1248-42
  65. #define CONFIG_FRAME (1206)
  66. /// UDP数据包数据帧深度——必须为2的倍数
  67. #define CONFIG_FRAME_MAX (256)
  68. /// UDP数据缓存二位数组的第1个索引下标最大值
  69. #define CONFIG_FRAME_INDEX_MAX (CONFIG_FRAME_MAX - 1)
  70. /// 最大角度值
  71. #define CONFIG_DEGREE_MAX (36000)
  72. /// UDP数据报一帧数据中数据块个数
  73. #define CONFIG_UDP_BLOCKS (12)
  74. /// 数据块中数据池的深度
  75. #define CONFIG_BLOCK_DEPTHS (16)
  76. /// 转换缓存数据块深度
  77. #define CONFIG_CIRCLE_DOTS (3600)
  78. /// 雷达超时时间设置——2s
  79. #define CONFIG_LASER_DISCONNECT (5)
  80. #define CONFIG_LASER_TIMER_HEART (100)
  81. /// 重组数据包大小
  82. #define CONFIG_MAX_REPACK (32)
  83. /// 16位数据大小端转换
  84. #define T16_H8(x) ((u16_t)((((u16_t)x) & ((u16_t)(0xFF00))) >> 8))
  85. #define T16_L8(x) ((u16_t)((((u16_t)x) & ((u16_t)(0x00FF))) << 8))
  86. #define BIG_TO_LITTLE_16(x) ((u16_t)(T16_H8(x) | T16_L8(x)))
  87. /// 32位数据大小端转换
  88. #define T32_HH8(x) ((u32_t)((((u32_t)x) & ((u32_t)(0xFF000000))) >> 24))
  89. #define T32_HL8(x) ((u32_t)((((u32_t)x) & ((u32_t)(0x00FF0000))) >> 8))
  90. #define T32_LH8(x) ((u32_t)((((u32_t)x) & ((u32_t)(0x0000FF00))) << 8))
  91. #define T32_LL8(x) ((u32_t)((((u32_t)x) & ((u32_t)(0x000000FF))) << 24))
  92. #define BIG_TO_LITTLE_32(x) ((u32_t)(T32_HH8(x) | T32_HL8(x) | T32_LH8(x) | T32_LL8(x)))
  93. /** @struct depth_t 雷达元数据包——最小数据包单元
  94. * @brief 雷达深度数据的最小包裹
  95. */
  96. #pragma pack(push)
  97. #pragma pack(1)
  98. struct depth_t
  99. {
  100. u16_t distance0; ///< 深度数据
  101. u8_t rssi0; ///< 回波强度
  102. u16_t distance1;
  103. u8_t rssi1;
  104. };
  105. /** @struct little_pack_t UDP数据包封装最小结构单元
  106. * @brief 一帧雷达深度数据的数据结构的最小单元
  107. */
  108. struct little_pack_t
  109. {
  110. u16_t head; ///< 数据头
  111. u16_t azimuth; ///< 测距数据的角度值
  112. depth_t depth[CONFIG_BLOCK_DEPTHS]; ///< 深度数据点位包 16
  113. };
  114. /** @struct udp_pack_t UDP数据报一帧数据结构
  115. * @brief 一帧UDP数据包的数据结构
  116. */
  117. struct udp_pack_t
  118. {
  119. little_pack_t depths[CONFIG_UDP_BLOCKS]; ///< 深度数据单元 12
  120. u32_t timestamp; ///< 时间戳
  121. u16_t factory; ///< 工厂信息
  122. };
  123. /** @struct cicle_pack_t UDP成品数据结构
  124. * @brief 重新封装的深度数据包最小单元
  125. */
  126. struct cicle_pack_t
  127. {
  128. u32_t timestamp; ///< 时间戳
  129. u16_t angle; ///< 角度值
  130. u16_t distance; ///< 深度数据
  131. u8_t rssi; ///< 回波强度
  132. };
  133. /** @struct repark_t 深度数据块,一块包含雷达一周的深度数据
  134. * @brief 一帧代表一块深度数据
  135. */
  136. struct repark_t
  137. {
  138. u32_t interval; ///< 间隔时间
  139. u16_t maxdots; ///< 点位个数
  140. cicle_pack_t dotcloud[CONFIG_CIRCLE_DOTS]; ///< 深度数据点云
  141. };
  142. #pragma pack(pop)
  143. class LakiBeamUDP
  144. {
  145. public:
  146. /*!
  147. 构造函数
  148. \param local_ip 本地ip
  149. \param local_port 本地端口号
  150. \param laser_ip 雷达ip
  151. \param laser_port 雷达端口号
  152. */
  153. LakiBeamUDP(string local_ip, string local_port, string laser_ip, string laser_port);
  154. /*!
  155. 析构函数
  156. */
  157. ~LakiBeamUDP();
  158. /*!
  159. 同步重新组包功能
  160. \param pack 用户包裹出口
  161. */
  162. void sync_get_repackedpack(repark_t &pack);
  163. /*!
  164. 取出数据包裹 返回true那么立即返回数据
  165. \param pack 用户包裹出口
  166. */
  167. bool get_repackedpack(repark_t &pack);
  168. private:
  169. string local_ip;
  170. string local_port;
  171. string laser_ip;
  172. string laser_port;
  173. thread_t receive_thd;
  174. thread_t udprepack_thd;
  175. mutex_t thd_mutex;
  176. bool everyThingOK;
  177. volatile u32_t dbmain;
  178. volatile u32_t dbmain_used;
  179. udp_pack_t doublebuffer[CONFIG_FRAME_MAX];
  180. volatile u32_t urpmain;
  181. volatile u32_t urpmain_used;
  182. repark_t udprepack[CONFIG_MAX_REPACK];
  183. char buffff[CONFIG_FRAME];
  184. udp_socket_t* socket;
  185. boost::asio::io_service io_servicess;
  186. udp_endpoint_t *local_ep;
  187. udp_endpoint_t *laser_ep;
  188. private:
  189. /*!
  190. 接受UDP数据包线程
  191. */
  192. void receive_thread(void);
  193. /*!
  194. UDP拆包组包线程
  195. */
  196. void udprepack_thread(void);
  197. /*!
  198. 填充没有起始包的包裹(一次需要2包)
  199. \param pack 包裹入口数组
  200. */
  201. void fill_nostart(udp_pack_t pack[2]);
  202. /*!
  203. 填充有起始包的包裹(一次需要2包)
  204. \param pack 包裹入口数组
  205. */
  206. void fill_havestart(udp_pack_t pack[2], u32_t start);
  207. void on_read(const boost::system::error_code& err, std::size_t read_bytes);
  208. };
  209. #endif // LAKIBEAMUDP_H