LakiBeamUDP.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611
  1. #include "LakiBeamUDP.h"
  2. //初始化了一些UDP网络通信相关的资源
  3. //异步接收数据,并使用多线程处理接收到的数据
  4. void LakiBeamUDP::LakiBeamUDP(string local_ip, string local_port, string laser_ip, string laser_port)
  5. {
  6. //将本地设备的IP地址和端口号保存到对象的成员变量
  7. this->local_ip = local_ip;
  8. this->local_port = local_port;
  9. //远程(激光设备)
  10. this->laser_ip = laser_ip;
  11. this->laser_port = laser_port;
  12. //用于统计和控制某个资源
  13. dbmain = 0;
  14. dbmain_used = 0;
  15. urpmain = 0;
  16. urpmain_used = 0;
  17. char *temp = reinterpret_cast<char *>(udprepack);
  18. memset(temp, 0, CONFIG_MAX_REPACK * sizeof(repark_t));
  19. local_ep = new udp_endpoint_t(address_t::from_string("0.0.0.0"), atoi(local_port.c_str()));
  20. laser_ep = new udp_endpoint_t(address_t::from_string(laser_ip), atoi(laser_port.c_str()));
  21. socket = new udp_socket_t(io_servicess);
  22. socket->open(local_ep->protocol());
  23. socket->set_option(boost::asio::ip::udp::socket::reuse_address(true));
  24. socket->bind(*local_ep);
  25. socket->async_receive_from(boost::asio::buffer(buffff, CONFIG_FRAME), *laser_ep, boost::bind(&LakiBeamUDP::on_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
  26. //创建并启动一个线程udprepack_thd,执行udprepack_thread函数
  27. //数据包处理
  28. udprepack_thd.reset(new boost::thread(boost::bind(&LakiBeamUDP::udprepack_thread, this)));
  29. //创建并启动一个线程receive_thd,执行receive_thread函数
  30. //接收UDP数据
  31. receive_thd.reset(new boost::thread(boost::bind(&LakiBeamUDP::receive_thread, this)));
  32. }
  33. //运行在独立线程中的方法,用于持续处理网络事件并接收UDP数据
  34. void LakiBeamUDP::receive_thread()
  35. {
  36. //这个线程持续监听和处理网络事件
  37. while (1)
  38. {
  39. try {
  40. io_servicess.run();
  41. boost::this_thread::interruption_point();
  42. }
  43. //检查当前线程是否被请求中断
  44. //如果当前线程被请求中断就会抛出一个异常,并使得线程退出
  45. catch (boost::system::error_code& err)
  46. {
  47. break;
  48. }
  49. }
  50. }
  51. //析构函数,实现了资源的清理和线程的安全退出
  52. LakiBeamUDP::~LakiBeamUDP()
  53. {
  54. io_servicess.stop();
  55. receive_thd->interrupt();
  56. receive_thd->join();
  57. delete socket;
  58. delete local_ep;
  59. delete laser_ep;
  60. udprepack_thd->interrupt();
  61. udprepack_thd->join();
  62. }
  63. //从缓冲区中同步地获取重新打包的UDP数据包,并将其传递给pack变量(数据同步一)
  64. void LakiBeamUDP::sync_get_repackedpack(repark_t &pack)
  65. {
  66. while (urpmain < 2)
  67. {
  68. }
  69. while (urpmain <= (urpmain_used + 1))
  70. {
  71. }
  72. urpmain_used = urpmain - 1;
  73. pack = udprepack[(urpmain_used) % CONFIG_MAX_REPACK];
  74. }
  75. //该方法通过非阻塞的方式从缓冲区中获取UDP数据包(数据同步二)
  76. bool LakiBeamUDP::get_repackedpack(repark_t &pack)
  77. {
  78. bool result = true;
  79. //如果数据包太少,只有一个或没有,则无法进行获取。
  80. if ((urpmain < 2)||(urpmain <= (urpmain_used + 1)))
  81. {
  82. result = false;
  83. }
  84. else
  85. {
  86. //获取了最新的数据包
  87. urpmain_used = urpmain - 1;
  88. }
  89. if (result == true)
  90. {
  91. pack = udprepack[(urpmain_used) % CONFIG_MAX_REPACK];
  92. }
  93. return result;
  94. }
  95. //用于处理异步接收的UDP数据,将接收到的数据存入缓冲区
  96. void LakiBeamUDP::on_read(const boost::system::error_code& err, std::size_t read_bytes)
  97. {
  98. if (!err)
  99. {
  100. char* temp;
  101. if (read_bytes == CONFIG_FRAME)
  102. {
  103. temp = reinterpret_cast<char*>(&(doublebuffer[dbmain % CONFIG_FRAME_MAX]));
  104. memcpy(temp, buffff, CONFIG_FRAME);
  105. //dbmain:用于指示当前主缓冲区的位置或索引
  106. //dbmain_used:用于指示当前在双缓冲区的主索引或位置,可能用于跟踪已处理的数据数量或状态
  107. dbmain++;
  108. }
  109. }
  110. //重新启动异步接收。即使在本次接收完成后,系统会立即等待下一个数据包的到来。
  111. socket->async_receive_from(boost::asio::buffer(buffff, CONFIG_FRAME), *laser_ep, boost::bind(&LakiBeamUDP::on_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
  112. }
  113. //udprepack_thread线程定期检查缓冲区,获取数据包(根据数据包的特性去调用函数处理数据)
  114. //用于处理从UDP数据包双缓冲区中提取数据并进行封装的逻辑
  115. void LakiBeamUDP::udprepack_thread()
  116. {
  117. while (1)
  118. {
  119. try
  120. {
  121. //该标志位用于控制后续的数据处理是否继续
  122. bool goon = true;
  123. udp_pack_t doublebuffertemp[2]; //存储两个UDP数据包的数据
  124. {
  125. //检查当前的双缓冲区是否有足够的数据可以被封装处理。至少有两个数据帧待处理
  126. if ((dbmain - dbmain_used) >= 2)
  127. {
  128. char *source1 = reinterpret_cast<char *>(&doublebuffertemp[0]);
  129. char *source2 = reinterpret_cast<char *>(&doublebuffertemp[1]);
  130. char *from1 = reinterpret_cast<char *>(&(doublebuffer[dbmain_used % CONFIG_FRAME_MAX]));
  131. char *from2 = reinterpret_cast<char *>(&(doublebuffer[(dbmain_used + 1) % CONFIG_FRAME_MAX]));
  132. u32_t realindex = dbmain_used % CONFIG_FRAME_MAX;
  133. if (realindex == CONFIG_FRAME_INDEX_MAX)
  134. {
  135. memcpy(source1, from1, CONFIG_FRAME);
  136. memcpy(source2, from2, CONFIG_FRAME);
  137. }
  138. else
  139. {
  140. memcpy(source1, from1, CONFIG_FRAME * 2);
  141. }
  142. dbmain_used++;
  143. }
  144. //如果数据不足,
  145. else
  146. {
  147. goon = false;
  148. }
  149. }
  150. if (goon == true)
  151. {
  152. if ((doublebuffertemp[0].factory == 0x4037) && (doublebuffertemp[1].factory == 0x4037))
  153. {
  154. // 寻找0位包裹
  155. u32_t start_index = 0xFFFFFFFF;
  156. for (int i = 0; i < CONFIG_UDP_BLOCKS; i++)
  157. {
  158. //寻找起始数据包
  159. if (doublebuffertemp[0].depths[i].azimuth == 0)
  160. {
  161. start_index = i;
  162. }
  163. }
  164. // 0位数据包
  165. if (start_index != 0xFFFFFFFF)
  166. {
  167. fill_havestart(doublebuffertemp, start_index);
  168. }
  169. // 非0位数据包
  170. else
  171. {
  172. fill_nostart(doublebuffertemp);
  173. }
  174. }
  175. else
  176. {
  177. // DEBUG(doublebuffertemp[1].factory);
  178. // DEBUG(doublebuffertemp[0].factory);
  179. }
  180. }
  181. //检查当前线程是否被请求中断
  182. boost::this_thread::interruption_point();
  183. //如果剩余的数据包不足两个,则线程会休眠2毫秒
  184. if ((dbmain - dbmain_used) < 2)
  185. {
  186. boost::this_thread::sleep(boost::posix_time::milliseconds(2));
  187. }
  188. }
  189. catch (...)
  190. {
  191. break;
  192. }
  193. }
  194. }
  195. //用于处理非起始的UDP数据包,并将其转换为内部udprepack结构中的点云数据。
  196. //接收两个数据包,根据时间戳、角度和深度信息计算每个的点云的相关数据
  197. void LakiBeamUDP::fill_nostart(udp_pack_t pack[2])
  198. {
  199. (void)pack;
  200. u32_t start_time = pack[0].timestamp;
  201. u32_t end_time = pack[1].timestamp;
  202. u16_t tempdots = udprepack[urpmain % CONFIG_MAX_REPACK].maxdots;
  203. u32_t div_time = (end_time - start_time) / CONFIG_BLOCK_DEPTHS / CONFIG_UDP_BLOCKS;
  204. for (int i = 0; i < CONFIG_UDP_BLOCKS; i++)
  205. {
  206. if (pack[0].depths[i].head == 0xEEFF)
  207. {
  208. if (i < (CONFIG_UDP_BLOCKS - 1))
  209. {
  210. u16_t start_angle = pack[0].depths[i].azimuth;//当前block的起始角度
  211. u16_t end_angle = pack[0].depths[i + 1].azimuth;//下一个block的起始角度
  212. u16_t div_angle; //每个数据块中相邻两个测距数据的角度递增值
  213. if (end_angle >= start_angle)
  214. {
  215. div_angle = (end_angle - start_angle) / CONFIG_BLOCK_DEPTHS;
  216. }
  217. else
  218. {
  219. div_angle = (CONFIG_DEGREE_MAX - start_angle + end_angle) / CONFIG_BLOCK_DEPTHS;
  220. }
  221. for (int j = 0; j < CONFIG_BLOCK_DEPTHS; j++)
  222. {
  223. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].timestamp = start_time;
  224. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].angle = start_angle;
  225. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].distance = pack->depths[i].depth[j].distance0;
  226. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].rssi = pack->depths[i].depth[j].rssi0;
  227. udprepack[urpmain % CONFIG_MAX_REPACK].interval += div_time;
  228. tempdots++; //在每次插入后递增,用于跟踪当前已插入的点运输量
  229. if ((start_angle + div_angle) >= CONFIG_DEGREE_MAX)
  230. {
  231. start_angle = start_angle + div_angle - CONFIG_DEGREE_MAX;
  232. }
  233. else
  234. {
  235. start_angle += div_angle;
  236. }
  237. start_time += div_time;
  238. }
  239. }
  240. else
  241. {
  242. u16_t start_angle = pack[0].depths[i].azimuth;
  243. u16_t end_angle = pack[1].depths[0].azimuth;
  244. u16_t div_angle;
  245. if (end_angle >= start_angle)
  246. {
  247. div_angle = (end_angle - start_angle) / CONFIG_BLOCK_DEPTHS;
  248. }
  249. else
  250. {
  251. div_angle = (CONFIG_DEGREE_MAX - start_angle + end_angle) / CONFIG_BLOCK_DEPTHS;
  252. }
  253. for (int j = 0; j < CONFIG_BLOCK_DEPTHS; j++)
  254. {
  255. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].timestamp = start_time;
  256. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].angle = start_angle;
  257. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].distance = pack->depths[i].depth[j].distance0;
  258. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].rssi = pack->depths[i].depth[j].rssi0;
  259. udprepack[urpmain % CONFIG_MAX_REPACK].interval += div_time;
  260. tempdots++;
  261. if ((start_angle + div_angle) >= CONFIG_DEGREE_MAX)
  262. {
  263. start_angle = start_angle + div_angle - CONFIG_DEGREE_MAX;
  264. }
  265. else
  266. {
  267. start_angle += div_angle;
  268. }
  269. start_time += div_time;
  270. }
  271. }
  272. }
  273. }
  274. udprepack[urpmain % CONFIG_MAX_REPACK].maxdots = tempdots;
  275. }
  276. //处理一系列UDP数据包,将数据填充道dotcloud结构中
  277. //udp_pack_t pack[] 传入的UDP数据包数组 (包含来自传感器的数据)
  278. //u32_t start 表示当前数据包的索引,通常是数据流中的起始点
  279. void LakiBeamUDP::fill_havestart(udp_pack_t pack[], u32_t start)
  280. {
  281. // urpmain表示当前处理的urpmain数组索引
  282. //表示正在处理第一包数据
  283. if (urpmain == 0)
  284. {
  285. //指向当前正在处理的Udprepack数组中的位置,它可能会用于确定当前的处理状态或处理的帧
  286. urpmain++;
  287. //用于记录已使用的udprepack数组的数量(已处理的帧的数量)
  288. urpmain_used++;
  289. //udprepack存储结构体的数组,用于存放解析后的数据
  290. //urpmain % CONFIG_MAX_REPACK 会将Urpmain的值限制在0到CONFIG_MAX_REPACK-1范围内,这样可以保证访问udprepack数组时不会越界
  291. udprepack[urpmain % CONFIG_MAX_REPACK].maxdots = 0;
  292. udprepack[urpmain % CONFIG_MAX_REPACK].interval = 0;
  293. (void)pack;
  294. //计算时间间隔,从UDP数据包中提取开始和结束时间戳
  295. //第一个数据包的时间戳:表示数据采集开始的时间
  296. u32_t start_time = pack[0].timestamp;
  297. //第二个数据包的时间戳:表示数据采集结束的时间
  298. u32_t end_time = pack[1].timestamp;
  299. //获取当前udprepack数组中指定索引位置的maxdots值
  300. u16_t tempdots = udprepack[urpmain % CONFIG_MAX_REPACK].maxdots;
  301. //计算每个数据块之间的时间间隔
  302. u32_t div_time = (end_time - start_time) / CONFIG_BLOCK_DEPTHS / CONFIG_UDP_BLOCKS;
  303. //根据start的值遍历数据块,每个数据块有多少个深度(遍历数据包中多个“块”)
  304. for (int i = start; i < CONFIG_UDP_BLOCKS; i++)
  305. {
  306. //判断是否是最后一个块
  307. if (i < (CONFIG_UDP_BLOCKS - 1))
  308. {
  309. u16_t start_angle = pack[0].depths[i].azimuth;
  310. u16_t end_angle = pack[0].depths[i + 1].azimuth;
  311. u16_t div_angle;
  312. //通过计算起始和结束角度之间的差值,得出UDP包中每个小块所需的角度增量。
  313. if (end_angle >= start_angle)
  314. {
  315. div_angle = (end_angle - start_angle) / CONFIG_BLOCK_DEPTHS;
  316. }
  317. else
  318. {
  319. div_angle = (CONFIG_DEGREE_MAX - start_angle + end_angle) / CONFIG_BLOCK_DEPTHS;
  320. }
  321. //处理每个深度块中的深度数据,并将计算后的时间戳、角度、距离和信号强度存储到udprepack中
  322. //从输入的数据包中提取激光雷达的每个测量点,并将其数据存储到点云数据结构中
  323. //CONFIG_BLOCK_DEPTHS (16)
  324. for (int j = 0; j < CONFIG_BLOCK_DEPTHS; j++)
  325. {
  326. //时间戳
  327. //dotcloud是udprapack数组中每个元素的一个成员,,用于存储点云数据
  328. //start_time表示当前处理的数据点的时间戳,,将start_time存储到dotcloud的当前位置的timestamp字段中
  329. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].timestamp = start_time;
  330. //
  331. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].angle = start_angle;
  332. //pack是由udp_pack_t定义的结构体
  333. //depths[i].depth[j].distance0 表示从第i个数据块中的第j个深度数据点获取距离信息
  334. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].distance = pack->depths[i].depth[j].distance0;
  335. //将当前数据点的RSSI信息pack->depths[i].depth[j].rssi0存储到udprepack数组中的dotcloud数组的对应位置
  336. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].rssi = pack->depths[i].depth[j].rssi0;
  337. //将当前数据点的时间间隔div_time累加到udprepack数组中当前元素的interval字段
  338. udprepack[urpmain % CONFIG_MAX_REPACK].interval += div_time;
  339. //用于跟踪当前正在处理的dotcloud索引
  340. tempdots++; //增加点云数据的索引
  341. //可能会大360
  342. if ((start_angle + div_angle) >= CONFIG_DEGREE_MAX)
  343. {
  344. start_angle = start_angle + div_angle - CONFIG_DEGREE_MAX;
  345. }
  346. else
  347. {
  348. start_angle += div_angle;
  349. }
  350. //时间更新
  351. //start_time:当前数据点的时间戳
  352. //将start_time增加div_time的值,以反映下一个数据点的时间戳
  353. //div_time可能是每个数据点之前的时间间隔
  354. start_time += div_time;
  355. }
  356. }
  357. //最后一个块的处理逻辑
  358. //提取数据,并将其存储到udprepack结构中
  359. else
  360. {
  361. //假设pack是一个包含多个数据块的数组
  362. //从当前数据块的第i项中提取起始角度
  363. u16_t start_angle = pack[0].depths[i].azimuth;
  364. //从下一个数据块pack[1]的第一个深度点提取结束角度
  365. u16_t end_angle = pack[1].depths[0].azimuth;
  366. //用于存储每个深度点之间的角度增量
  367. u16_t div_angle;
  368. //如果结束角度大于起始角度,则可以直接计算差值
  369. if (end_angle >= start_angle)
  370. {
  371. div_angle = (end_angle - start_angle) / CONFIG_BLOCK_DEPTHS;
  372. }
  373. //如果结束角度小于起始角度,则意味着角度跨越了0度
  374. else
  375. {
  376. div_angle = (CONFIG_DEGREE_MAX - start_angle + end_angle) / CONFIG_BLOCK_DEPTHS;
  377. }
  378. //将start_angle更新为当前块中实际其实角度
  379. //(start + 1) * CONFIG_BLOCK_DEPTHS 表示当前数据块相对于第一块的偏移量,乘以div_angle可以得到当前数据块的起始角度
  380. //为了确保在处理多个数据块时,每个数据块的起始角度都是正确的
  381. start_angle = start_angle + div_angle * (start + 1) * CONFIG_BLOCK_DEPTHS;
  382. //处理当前数据块中的每个深度数据点
  383. for (int j = 0; j < CONFIG_BLOCK_DEPTHS; j++)
  384. {
  385. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].timestamp = start_time;
  386. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].angle = start_angle;
  387. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].distance = pack->depths[i].depth[j].distance0;
  388. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].rssi = pack->depths[i].depth[j].rssi0;
  389. udprepack[urpmain % CONFIG_MAX_REPACK].interval += div_time;
  390. tempdots++;
  391. if ((start_angle + div_angle) >= CONFIG_DEGREE_MAX)
  392. {
  393. start_angle = start_angle + div_angle - CONFIG_DEGREE_MAX;
  394. }
  395. else
  396. {
  397. start_angle += div_angle;
  398. }
  399. start_time += div_time;
  400. }
  401. }
  402. }
  403. //将当前数据包中有效存储的数据点数量temdots更新到maxdots字段中
  404. //这个信息可以在后续处理中使用,以确定当前数据包中的点云数据的数量
  405. udprepack[urpmain % CONFIG_MAX_REPACK].maxdots = tempdots;
  406. }
  407. // 其它0包
  408. else
  409. {
  410. {
  411. (void)pack;
  412. u32_t start_time = pack[0].timestamp;
  413. u32_t end_time = pack[1].timestamp;
  414. //tempdots用于跟踪当前处理的数据点数量
  415. u16_t tempdots = udprepack[urpmain % CONFIG_MAX_REPACK].maxdots;
  416. u32_t div_time = (end_time - start_time) / CONFIG_BLOCK_DEPTHS / CONFIG_UDP_BLOCKS;
  417. //累加时间间隔
  418. //将当前数据包中所有数据点的时间间隔累加到udprepack[urpmain % CONFIG_MAX_REPACK].interval
  419. udprepack[urpmain % CONFIG_MAX_REPACK].interval += div_time;
  420. //处理当前数据包中的深度数据
  421. for (u32_t i = 0; i < start; i++)
  422. {
  423. u16_t start_angle = pack[0].depths[i].azimuth;
  424. u16_t end_angle = pack[0].depths[i + 1].azimuth;
  425. u16_t div_angle;
  426. if (end_angle >= start_angle)
  427. {
  428. div_angle = (end_angle - start_angle) / CONFIG_BLOCK_DEPTHS;
  429. }
  430. else
  431. {
  432. div_angle = (CONFIG_DEGREE_MAX - start_angle + end_angle) / CONFIG_BLOCK_DEPTHS;
  433. }
  434. for (int j = 0; j < CONFIG_BLOCK_DEPTHS; j++)
  435. {
  436. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].timestamp = start_time;
  437. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].angle = start_angle;
  438. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].distance = pack->depths[i].depth[j].distance0;
  439. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].rssi = pack->depths[i].depth[j].rssi0;
  440. udprepack[urpmain % CONFIG_MAX_REPACK].interval += div_time;
  441. tempdots++;
  442. if ((start_angle + div_angle) >= CONFIG_DEGREE_MAX)
  443. {
  444. start_angle = start_angle + div_angle - CONFIG_DEGREE_MAX;
  445. }
  446. else
  447. {
  448. start_angle += div_angle;
  449. }
  450. start_time += div_time;
  451. }
  452. }
  453. //检查是否存在数据丢失
  454. //在点云数据数量为1440或3600的情况下
  455. if((tempdots==1440)||(tempdots==3600))
  456. {
  457. bool lost = false; //用于标识是否存在数据丢失
  458. if (tempdots == 1440)
  459. {
  460. for (int i = 180; i < (1440 - 17); i++)
  461. {
  462. if (udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[i+1].angle < udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[i].angle)
  463. {
  464. lost = true;
  465. }
  466. }
  467. }
  468. else
  469. {
  470. for (int i = 450; i < (3600 - 17); i++)
  471. {
  472. if (udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[i + 1].angle < udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[i].angle)
  473. {
  474. lost = true;
  475. }
  476. }
  477. }
  478. if (lost == false)
  479. {
  480. udprepack[urpmain % CONFIG_MAX_REPACK].interval /= tempdots;
  481. udprepack[urpmain % CONFIG_MAX_REPACK].maxdots = tempdots;
  482. urpmain++;
  483. }
  484. }
  485. }
  486. {
  487. //如果当前处理的不是最后一个数据块,则进入当前的数据块
  488. //将当前处理的点云数据包的最大点数maxdots初始化为0
  489. udprepack[urpmain % CONFIG_MAX_REPACK].maxdots = 0;
  490. (void)pack;
  491. u32_t start_time = pack[0].timestamp;
  492. u32_t end_time = pack[1].timestamp;
  493. u16_t tempdots = udprepack[urpmain % CONFIG_MAX_REPACK].maxdots;
  494. u32_t div_time = (end_time - start_time) / CONFIG_BLOCK_DEPTHS / CONFIG_UDP_BLOCKS;
  495. //循环处理数据包中的深度数据
  496. for (u32_t i = start; i < CONFIG_UDP_BLOCKS; i++)
  497. {
  498. //如果当前处理块不是最后一个块
  499. if (i < (CONFIG_UDP_BLOCKS - 1))
  500. {
  501. u16_t start_angle = pack[0].depths[i].azimuth;
  502. u16_t end_angle = pack[0].depths[i + 1].azimuth;
  503. u16_t div_angle;
  504. if (end_angle >= start_angle)
  505. {
  506. div_angle = (end_angle - start_angle) / CONFIG_BLOCK_DEPTHS;
  507. }
  508. else
  509. {
  510. div_angle = (CONFIG_DEGREE_MAX - start_angle + end_angle) / CONFIG_BLOCK_DEPTHS;
  511. }
  512. for (int j = 0; j < CONFIG_BLOCK_DEPTHS; j++)
  513. {
  514. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].timestamp = start_time;
  515. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].angle = start_angle;
  516. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].distance = pack->depths[i].depth[j].distance0;
  517. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].rssi = pack->depths[i].depth[j].rssi0;
  518. udprepack[urpmain % CONFIG_MAX_REPACK].interval += div_time;
  519. tempdots++;
  520. if ((start_angle + div_angle) >= CONFIG_DEGREE_MAX)
  521. {
  522. start_angle = start_angle + div_angle - CONFIG_DEGREE_MAX;
  523. }
  524. else
  525. {
  526. start_angle += div_angle;
  527. }
  528. start_time += div_time;
  529. }
  530. }
  531. else
  532. {
  533. u16_t start_angle = pack[0].depths[i].azimuth;
  534. u16_t end_angle = pack[1].depths[0].azimuth;
  535. u16_t div_angle;
  536. if (end_angle >= start_angle)
  537. {
  538. div_angle = (end_angle - start_angle) / CONFIG_BLOCK_DEPTHS;
  539. }
  540. else
  541. {
  542. div_angle = (CONFIG_DEGREE_MAX - start_angle + end_angle) / CONFIG_BLOCK_DEPTHS;
  543. }
  544. for (u32_t j = 0; j < CONFIG_BLOCK_DEPTHS; j++)
  545. {
  546. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].timestamp = start_time;
  547. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].angle = start_angle;
  548. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].distance = pack->depths[i].depth[j].distance0;
  549. udprepack[urpmain % CONFIG_MAX_REPACK].dotcloud[tempdots % CONFIG_CIRCLE_DOTS].rssi = pack->depths[i].depth[j].rssi0;
  550. udprepack[urpmain % CONFIG_MAX_REPACK].interval += div_time;
  551. tempdots++;
  552. if ((start_angle + div_angle) >= CONFIG_DEGREE_MAX)
  553. {
  554. start_angle = start_angle + div_angle - CONFIG_DEGREE_MAX;
  555. }
  556. else
  557. {
  558. start_angle += div_angle;
  559. }
  560. start_time += div_time;
  561. }
  562. }
  563. }
  564. //处理结束,将当前的点数tempdots更新为udprepack结构中的最大点数
  565. udprepack[urpmain % CONFIG_MAX_REPACK].maxdots = tempdots;
  566. }
  567. }
  568. }