decoder_test.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. #include <gtest/gtest.h>
  2. #include <rs_driver/driver/decoder/decoder_mech.hpp>
  3. #include <rs_driver/msg/point_cloud_msg.hpp>
  4. #include <rs_driver/utility/dbg.hpp>
  5. using namespace robosense::lidar;
  6. typedef PointXYZI PointT;
  7. typedef PointCloudT<PointT> PointCloud;
  8. #pragma pack(push, 1)
  9. struct MyMsopPkt
  10. {
  11. uint8_t id[8];
  12. };
  13. struct MyDifopPkt
  14. {
  15. uint8_t id[8];
  16. uint16_t rpm;
  17. RSFOV fov;
  18. RSCalibrationAngle vert_angle_cali[2];
  19. RSCalibrationAngle horiz_angle_cali[2];
  20. };
  21. #pragma pack(pop)
  22. class MyDecoder : public DecoderMech<PointCloud>
  23. {
  24. public:
  25. MyDecoder(const RSDecoderMechConstParam& const_param,
  26. const RSDecoderParam& param)
  27. : DecoderMech<PointCloud>(const_param, param)
  28. {
  29. }
  30. virtual void decodeDifopPkt(const uint8_t* packet, size_t size)
  31. {
  32. const MyDifopPkt& pkt = *(const MyDifopPkt*)(packet);
  33. this->template decodeDifopCommon<MyDifopPkt>(pkt);
  34. }
  35. virtual bool decodeMsopPkt(const uint8_t* pkt, size_t size)
  36. {
  37. return false;
  38. }
  39. };
  40. static ErrCode errCode = ERRCODE_SUCCESS;
  41. static void errCallback(const Error& err)
  42. {
  43. errCode = err.error_code;
  44. }
  45. TEST(TestDecoder, angles_from_file)
  46. {
  47. RSDecoderMechConstParam const_param;
  48. const_param.base.LASER_NUM = 4;
  49. RSDecoderParam param;
  50. param.config_from_file = true;
  51. param.angle_path = "../rs_driver/test/res/angle.csv";
  52. errCode = ERRCODE_SUCCESS;
  53. MyDecoder decoder(const_param, param);
  54. decoder.regCallback(errCallback, nullptr);
  55. ASSERT_EQ(errCode, ERRCODE_SUCCESS);
  56. ASSERT_TRUE(decoder.angles_ready_);
  57. }
  58. TEST(TestDecoder, angles_from_file_fail)
  59. {
  60. RSDecoderMechConstParam const_param;
  61. const_param.base.LASER_NUM = 4;
  62. RSDecoderParam param;
  63. param.config_from_file = true;
  64. param.angle_path = "../rs_driver/test/res/non_exist.csv";
  65. MyDecoder decoder(const_param, param);
  66. decoder.regCallback(errCallback, nullptr);
  67. ASSERT_FALSE(decoder.angles_ready_);
  68. }
  69. TEST(TestDecoder, processDifopPkt_fail)
  70. {
  71. RSDecoderMechConstParam const_param =
  72. {
  73. sizeof(MyMsopPkt) // msop len
  74. , sizeof(MyDifopPkt) // difop len
  75. , 8 // msop id len
  76. , 8 // difop id len
  77. , {0x55, 0xAA, 0x05, 0x0A, 0x5A, 0xA5, 0x50, 0xA0} // msop id
  78. , {0xA5, 0xFF, 0x00, 0x5A, 0x11, 0x11, 0x55, 0x55} // difop id
  79. };
  80. RSDecoderParam param;
  81. MyDecoder decoder(const_param, param);
  82. decoder.regCallback(errCallback, nullptr);
  83. // wrong difop length
  84. MyDifopPkt pkt = {0};
  85. errCode = ERRCODE_SUCCESS;
  86. decoder.processDifopPkt((const uint8_t*)&pkt, 10);
  87. ASSERT_EQ(errCode, ERRCODE_WRONGDIFOPLEN);
  88. // wrong difop id
  89. errCode = ERRCODE_SUCCESS;
  90. decoder.processDifopPkt((const uint8_t*)&pkt, sizeof(pkt));
  91. ASSERT_EQ(errCode, ERRCODE_WRONGDIFOPID);
  92. }
  93. TEST(TestDecoder, processDifopPkt)
  94. {
  95. RSDecoderMechConstParam const_param =
  96. {
  97. sizeof(MyMsopPkt) // msop len
  98. , sizeof(MyDifopPkt) // difop len
  99. , 8 // msop id len
  100. , 8 // difop id len
  101. , {0x55, 0xAA, 0x05, 0x0A, 0x5A, 0xA5, 0x50, 0xA0} // msop id
  102. , {0xA5, 0xFF, 0x00, 0x5A, 0x11, 0x11, 0x55, 0x55} // difop id
  103. , {0xFF, 0xEE} // block id
  104. , 2 // laser number
  105. , 1000 // blocks per packet
  106. , 2 // channels per block
  107. };
  108. const_param.BLOCK_DURATION = 55.52f / 1000000;
  109. RSDecoderParam param;
  110. param.config_from_file = false;
  111. MyDecoder decoder(const_param, param);
  112. decoder.regCallback(errCallback, nullptr);
  113. ASSERT_FALSE(decoder.angles_ready_);
  114. //
  115. // angles from difop. no angles in difop
  116. //
  117. uint8_t pkt_no_angles[] =
  118. {
  119. 0xA5, 0xFF, 0x00, 0x5A, 0x11, 0x11, 0x55, 0x55 // difop id
  120. , 0x02, 0x58 // rpm
  121. , 0x23, 0x28 // start angle = 9000
  122. , 0x46, 0x50 // end angle = 18000
  123. , 0xFF, 0xFF, 0xFF // vert angles
  124. , 0xFF, 0xFF, 0xFF
  125. , 0xFF, 0xFF, 0xFF // horiz angles
  126. , 0xFF, 0xFF, 0xFF
  127. };
  128. errCode = ERRCODE_SUCCESS;
  129. decoder.processDifopPkt(pkt_no_angles, sizeof(MyDifopPkt));
  130. errCode = ERRCODE_SUCCESS;
  131. ASSERT_EQ(decoder.rps_, 10);
  132. ASSERT_EQ(decoder.blks_per_frame_, 1801);
  133. ASSERT_EQ(decoder.block_az_diff_, 20);
  134. ASSERT_EQ(decoder.split_blks_per_frame_, 1801);
  135. ASSERT_EQ(decoder.fov_blind_ts_diff_, 0.075); // 0.1 * 3/4
  136. ASSERT_FALSE(decoder.angles_ready_);
  137. ASSERT_EQ(decoder.chan_angles_.vert_angles_.size(), 2);
  138. ASSERT_EQ(decoder.chan_angles_.vert_angles_[0], 0);
  139. ASSERT_EQ(decoder.chan_angles_.horiz_angles_.size(), 2);
  140. ASSERT_EQ(decoder.chan_angles_.horiz_angles_[0], 0);
  141. //
  142. // angles from difop. valid angels in difop.
  143. //
  144. uint8_t pkt[] =
  145. {
  146. 0xA5, 0xFF, 0x00, 0x5A, 0x11, 0x11, 0x55, 0x55 // difop id
  147. , 0x02, 0x58 // rpm
  148. , 0x00, 0x00 // start angle = 0
  149. , 0x8C, 0xA0 // end angle = 36000
  150. , 0x00, 0x00, 0x10 // vert angles
  151. , 0x01, 0x00, 0x20
  152. , 0x00, 0x00, 0x01 // horiz angles
  153. , 0x01, 0x00, 0x02
  154. };
  155. ASSERT_LT(decoder.getPacketDuration() - 55.52/1000, 0.00001);
  156. errCode = ERRCODE_SUCCESS;
  157. decoder.processDifopPkt(pkt, sizeof(MyDifopPkt));
  158. ASSERT_EQ(errCode, ERRCODE_SUCCESS);
  159. ASSERT_EQ(decoder.rps_, 10);
  160. ASSERT_EQ(decoder.fov_blind_ts_diff_, 0.0f); // 0.1 * 3/4
  161. ASSERT_TRUE(decoder.angles_ready_);
  162. ASSERT_EQ(decoder.chan_angles_.vert_angles_.size(), 2);
  163. ASSERT_EQ(decoder.chan_angles_.vert_angles_[0], 16);
  164. ASSERT_EQ(decoder.chan_angles_.horiz_angles_.size(), 2);
  165. ASSERT_EQ(decoder.chan_angles_.horiz_angles_[0], 1);
  166. }
  167. TEST(TestDecoder, processDifopPkt_invalid_rpm)
  168. {
  169. RSDecoderMechConstParam const_param =
  170. {
  171. sizeof(MyMsopPkt) // msop len
  172. , sizeof(MyDifopPkt) // difop len
  173. , 8 // msop id len
  174. , 8 // difop id len
  175. , {0x55, 0xAA, 0x05, 0x0A, 0x5A, 0xA5, 0x50, 0xA0} // msop id
  176. , {0xA5, 0xFF, 0x00, 0x5A, 0x11, 0x11, 0x55, 0x55} // difop id
  177. , {0xFF, 0xEE} // block id
  178. , 32 // laser number
  179. , 12 // blocks per packet
  180. , 32 // channels per block
  181. };
  182. RSDecoderParam param;
  183. MyDecoder decoder(const_param, param);
  184. decoder.regCallback(errCallback, nullptr);
  185. uint8_t pkt[] =
  186. {
  187. 0xA5, 0xFF, 0x00, 0x5A, 0x11, 0x11, 0x55, 0x55 // difop len
  188. , 0x00, 0x00 // rpm = 0
  189. };
  190. errCode = ERRCODE_SUCCESS;
  191. decoder.processDifopPkt(pkt, sizeof(MyDifopPkt));
  192. ASSERT_EQ(errCode, ERRCODE_SUCCESS);
  193. ASSERT_EQ(decoder.rps_, 10);
  194. }
  195. TEST(TestDecoder, processMsopPkt)
  196. {
  197. RSDecoderMechConstParam const_param =
  198. {
  199. sizeof(MyMsopPkt) // msop len
  200. , sizeof(MyDifopPkt) // difop len
  201. , 8 // msop id len
  202. , 8 // difop id len
  203. , {0x55, 0xAA, 0x05, 0x0A, 0x5A, 0xA5, 0x50, 0xA0} // msop id
  204. , {0xA5, 0xFF, 0x00, 0x5A, 0x11, 0x11, 0x55, 0x55} // difop id
  205. };
  206. MyMsopPkt pkt;
  207. RSDecoderParam param;
  208. MyDecoder decoder(const_param, param);
  209. decoder.regCallback(errCallback, nullptr);
  210. // wait_for_difop = true, angles not ready
  211. decoder.param_.wait_for_difop = true;
  212. decoder.angles_ready_ = false;
  213. errCode = ERRCODE_SUCCESS;
  214. decoder.processMsopPkt((const uint8_t*)&pkt, 2);
  215. ASSERT_EQ(errCode, ERRCODE_SUCCESS);
  216. #if 0
  217. sleep(2);
  218. errCode = ERRCODE_SUCCESS;
  219. decoder.processMsopPkt((const uint8_t*)&pkt, 2);
  220. ASSERT_EQ(errCode, ERRCODE_NODIFOPRECV);
  221. #endif
  222. decoder.param_.wait_for_difop = true;
  223. decoder.angles_ready_ = true;
  224. // wrong msop len
  225. errCode = ERRCODE_SUCCESS;
  226. decoder.processMsopPkt((const uint8_t*)&pkt, 2);
  227. ASSERT_EQ(errCode, ERRCODE_WRONGMSOPLEN);
  228. decoder.param_.wait_for_difop = false;
  229. // wrong msop header
  230. errCode = ERRCODE_SUCCESS;
  231. decoder.processMsopPkt((const uint8_t*)&pkt, sizeof(pkt));
  232. ASSERT_EQ(errCode, ERRCODE_WRONGMSOPID);
  233. // valid msop
  234. uint8_t id[] = {0x55, 0xAA, 0x05, 0x0A, 0x5A, 0xA5, 0x50, 0xA0};
  235. memcpy (pkt.id, id, 8);
  236. errCode = ERRCODE_SUCCESS;
  237. decoder.processMsopPkt((const uint8_t*)&pkt, sizeof(pkt));
  238. ASSERT_EQ(errCode, ERRCODE_SUCCESS);
  239. }