# 19 分帧策略 ## 19.1 概述 本文分别说明 MEMS 的分帧策略。 本文引用了如下一些文档的概念,请阅读。 - [如何解决丢包问题](./17_how_to_avoid_packet_loss_CN.md) - [点在点云中的布局](./18_about_point_layout_CN.md) ## 19.2 MEMS 雷达 MEMS 雷达的分帧,本质上在雷达端就确定了。 雷达有 5 个扫描区域,每轮扫秒同时扫描这 5 个区域,得到 10 个点,打包到一个 Block,写入 MSOP Packet。 在每个区域,按照 Z 字型进行扫描。这样一直继续,直到完成全部区域,得到一组 MSOP Packet。 这组 Packet 按扫描顺序从 1 开始编号。以 A0 雷达为例,编号为 1~1344。 最后 `ag_driver` 做的,是按照这些编号分割 MSOP Packet。 ### 19.2.1 丢包与乱序处理 MEMS 雷达可能同时发送多个 MSOP Packet,这样丢包和乱序的风险就变大了。 主机端的丢包,可以通过增大 Socket 接收缓存解决,但是从雷达到主机之间的丢包、乱序还是可能存在。 `ag_driver` 引入“安全区间”的做法,来处理可能的丢包和乱序。 先讨论没有安全区间时,如何处理丢包、乱序。 + 理想情况下,如果不丢包不乱序,MSOP Packet 编号从 1 到 1344,只需要检查 Packet 编号是不是 1。如果是就分帧。 + 那假如只有丢包呢?举个例子,如果编号为 1 的 Packet 丢了,则可以加入检查条件,就是当前 Packet 编号小于前一个 Packet 的编号 `prev_seq`,就分帧。 + 在乱序的情况下,这个检查条件会导致另一个困境。举个例子,如果编号为 300 和 301 的两个 Packet 乱序,那么这个位置分帧,会导致原本的一帧拆分成两帧。 使用安全区间的做法如下: + 以 `prev_seq` 为参考点,划定一个范围值 `RANGE`, ```cpp safe_seq_min = prev_seq_ - RANGE safe_seq_max = prev_seq_ + RANGE ``` + 如果 MSOP Packet 在范围 (`safe_seq_min_`, `safe_seq_max_`) 内,不算异常,不分帧。 ![safe range](./img/19_02_safe_range.png) 这样轻微的乱序不会触发分帧,也就解决了前面说的困境。