193 lines
6.2 KiB
Markdown
193 lines
6.2 KiB
Markdown
# 导航代码审查报告
|
||
|
||
日期: 2026-04-03
|
||
|
||
范围:
|
||
- `App/nav/global_nav.c`
|
||
- `App/nav/track_map.c`
|
||
- `App/nav/track_map.h`
|
||
- `App/robot_params.h`
|
||
- `App/app_tasks.c`
|
||
- `App/preproc/corridor_preproc.c`
|
||
|
||
## 结论
|
||
|
||
当前版本的 S 型拓扑和左右转向表整体上与地图理解一致,没有再发现明显的左右方向写反问题。
|
||
|
||
主要风险集中在以下几类:
|
||
- 时间基准过度依赖 IMU 时间戳
|
||
- 连续确认逻辑复用了同一帧 VL53 数据
|
||
- 入场段过度依赖固定起始摆放位置
|
||
- 阶段切换存在 1 个控制周期的旧命令残留
|
||
- 连接段提前转向策略较激进
|
||
|
||
## Findings
|
||
|
||
### 1. 高: IMU 时间戳卡住时,超时与里程都会冻结
|
||
|
||
位置:
|
||
- `App/nav/global_nav.c:430-445`
|
||
- `App/nav/global_nav.c:471`
|
||
- `App/nav/global_nav.c:628-630`
|
||
- `App/nav/global_nav.c:657-659`
|
||
|
||
现象:
|
||
- `GlobalNav_Update()` 用 `board->imu_wz.timestamp_ms` 作为内部时间基准
|
||
- `odom_distance_accum` 的积分和 `elapsed_ms` 的推进都依赖这个时间戳
|
||
|
||
风险:
|
||
- 如果 IMU 仍被判定为在线,但时间戳停更,导航状态机会继续输出控制命令
|
||
- 同时阶段超时保护不会推进
|
||
- 里程积分也不会推进
|
||
|
||
可能后果:
|
||
- `ENTRY_STRAIGHT`、`LINK_STRAIGHT`、`EXIT_STRAIGHT` 长时间不退出
|
||
- 转向超时失效,机器人可能持续原地转
|
||
|
||
说明:
|
||
- 这是行为级问题,不是单纯的调参问题
|
||
- 文档中也提到了该项仍是 TODO,但当前实现里确实已经构成运行风险
|
||
|
||
### 2. 高: “连续 N 拍确认”实际在重复消费同一帧 VL53 数据
|
||
|
||
位置:
|
||
- `App/app_tasks.c:285-286`
|
||
- `App/app_tasks.c:299-347`
|
||
- `App/nav/global_nav.c:516-523`
|
||
- `App/nav/global_nav.c:615-620`
|
||
- `App/robot_params.h:398-399`
|
||
|
||
现象:
|
||
- 导航循环周期约为 `20ms`
|
||
- VL53 任务推送周期约为 `100ms`
|
||
- `REACQUIRE` 的连续 `5` 拍确认和 `LINK_STRAIGHT` 的连续 `2` 拍确认,都是按导航循环计数
|
||
|
||
风险:
|
||
- 同一帧 VL53 观测会被导航层重复读取多次
|
||
- 于是“连续确认”并不等于“连续多个独立观测确认”
|
||
|
||
可能后果:
|
||
- `REACQUIRE` 可能只靠 1 帧侧向数据就进入 `CORRIDOR_TRACK`
|
||
- 沟口检测的 2 拍确认也可能只是一帧瞬时失效被重复消费
|
||
|
||
说明:
|
||
- 这会削弱你现在新设计的联合判定可靠性
|
||
- 当前问题核心不是阈值,而是采样独立性不足
|
||
|
||
### 3. 中: 入场段强依赖起始摆放位置,缺少几何确认
|
||
|
||
位置:
|
||
- `App/nav/global_nav.c:484-495`
|
||
- `App/robot_params.h:382-385`
|
||
- `App/app_tasks.c:302-306`
|
||
- `Doc/map.md:9`
|
||
- `Doc/map.md:53-59`
|
||
|
||
现象:
|
||
- `ENTRY_STRAIGHT` 现在只用 `里程 >= 0.30m 或 超时` 进入第一次右转
|
||
- 启动后直接 `GlobalNav_Start()`,没有专门的“出启动区口再开始计段”动作
|
||
|
||
风险:
|
||
- 这要求机器人初始位置必须比较稳定,且接近你假设的起跑点
|
||
|
||
可能后果:
|
||
- 如果车放在 100cm 深启动区内更靠后位置,可能在到达 `C1` 入口前就右转
|
||
- 如果车放得更靠前,也可能转得偏晚
|
||
|
||
说明:
|
||
- 当前实现修掉了“侧墙始终有效导致误触发”的问题
|
||
- 但引入了“对起点一致性要求很高”的新假设
|
||
|
||
### 4. 中: 阶段切换发生后,本周期仍可能执行旧阶段指令
|
||
|
||
位置:
|
||
- `App/nav/global_nav.c:242-266`
|
||
- `App/nav/global_nav.c:491-495`
|
||
- `App/nav/global_nav.c:623-625`
|
||
- `App/nav/global_nav.c:706-710`
|
||
|
||
现象:
|
||
- 若本周期内先生成了旧阶段控制命令,再满足切段条件并 `transition_to()`
|
||
- `out->stage` 在函数末尾会更新成新阶段
|
||
- 但本周期发出去的速度命令可能还是旧阶段的
|
||
|
||
风险:
|
||
- 状态显示与实际执行在一个周期内不完全一致
|
||
|
||
可能后果:
|
||
- 转向完成后多转一个控制周期
|
||
- 直行段满足切换条件后,当拍仍会继续向前推进一小段
|
||
|
||
说明:
|
||
- 这通常是 20ms 量级的小偏差
|
||
- 但在靠近入口边缘、转向容差较紧时会放大几何误差
|
||
|
||
### 5. 中: 连接段允许仅凭前激光位移提前触发下一次转向
|
||
|
||
位置:
|
||
- `App/nav/global_nav.c:590-625`
|
||
- `App/robot_params.h:406-409`
|
||
- `App/nav/track_map.h:36-37`
|
||
|
||
现象:
|
||
- `LINK_STRAIGHT` 的逻辑是 `B || (A && C)`
|
||
- 其中 `A` 和 `B` 都采用 `0.70m * 0.85 = 0.595m` 作为触发阈值
|
||
- 也就是前激光变化量到达约 `59.5cm` 就可直接触发转向
|
||
|
||
风险:
|
||
- 机器人可能在标称 `70cm` 沟间距之前约 `10.5cm` 就开始转向
|
||
|
||
可能后果:
|
||
- 若前激光初值记录稍晚、转出后航向略偏、或前激光看到的并非理想正对围栏面,可能提前转向
|
||
- 提前量叠加转向半径误差后,可能更接近垄背边缘而非下一条沟中心
|
||
|
||
说明:
|
||
- 这不是硬 bug,更像策略上偏激进
|
||
- 若实车转向余量很大,可能仍可工作;若几何余量小,则风险会明显上升
|
||
|
||
## 正向观察
|
||
|
||
### 1. 转向拓扑表当前与地图理解一致
|
||
|
||
位置:
|
||
- `App/nav/track_map.c:34-47`
|
||
|
||
说明:
|
||
- `C1` 右转入、左转出
|
||
- `C2` 左转入、右转出
|
||
- 奇偶沟交替
|
||
- `C6` 左转出场
|
||
|
||
这一版没有再看到此前那种第一条沟转向方向写反的问题。
|
||
|
||
### 2. 连接段已经避免把“贴围栏侧 VL53 常亮”当作入口触发
|
||
|
||
位置:
|
||
- `App/nav/global_nav.c:108-144`
|
||
- `App/nav/global_nav.c:557-625`
|
||
|
||
说明:
|
||
- 你已经把“非围栏侧 VL53 沟口检测”显式建模出来
|
||
- 同时结合前激光和里程计做联合判定
|
||
|
||
这比此前的 `side_walls_detected()` 直接触发要合理得多。
|
||
|
||
## 开放问题
|
||
|
||
1. 比赛摆车是否保证机器人车头在启动区出口附近,而不是启动区任意位置?
|
||
2. 传感器黑板中的 `is_valid` 是否有基于时间戳的失效机制,还是生产者停更后仍可能保持有效?
|
||
3. 连接段的目标是“到下一沟中心线再转”,还是“进入下一沟开口就允许转”?当前 0.85 容差会显著影响这个定义。
|
||
|
||
## 总体评价
|
||
|
||
当前版本比前一版明显更接近真实场地几何,尤其是:
|
||
- 地图方向理解正确
|
||
- S 型左右转表正确
|
||
- 连接段不再依赖错误的侧墙常亮判据
|
||
|
||
但如果从比赛稳定性角度看,当前还存在两个最值得优先处理的问题:
|
||
- 时间基准不能完全绑死在 IMU 时间戳上
|
||
- 连续确认不能重复消费同一帧侧向观测
|
||
|
||
如果这两点不处理,现场表现会比较依赖传感器健康状态与偶然时序,稳定性风险较高。
|