练习与里程碑¶
本章目标:把前面各章的"看懂"变成"能做"。每个核心章节配有分级练习(🟢 入门 / 🟡 进阶 / 🔴 挑战)和明确的验收标准——做不出来就回去重读对应章节,做出来了才算真正过关。
先读这段
看懂 EKF 推导和自己写出一个能收敛的 EKF 是两种能力,中间差着几十小时的调试。本章的练习不是可选的补充,而是成长的主体——前面所有章节只是为这里的练习提供地图。原则上:
- 不看原码写:入门和进阶练习都要求先自己写,卡死了再对照仓库代码,对照后删掉重写一遍。
- 验收标准是硬性的:达不到数字就没通过,不要自我感动。
- 每个练习都留下产物:代码入 Git、结果截图入笔记。三个月后你会感谢这些记录。
成长里程碑总览¶
四个里程碑对应四个能力阶段,每个里程碑由若干练习组成。完成一个里程碑,你就有资格承担对应的团队角色。
| 里程碑 | 能力定义 | 对应角色 | 预计耗时 |
|---|---|---|---|
| M1 跑起来 | 能搭建环境、编译运行两个仓库、用录像回放调试 | 新队员 | 1-2 周 |
| M2 拆开看 | 能独立复现检测和 PnP 模块,能解释每个参数的作用 | 视觉组正式成员 | 3-5 周 |
| M3 改得动 | 能复现 EKF 和弹道解算,能定位并修复真实 bug | 模块负责人 | 4-8 周 |
| M4 设计者 | 能横向对比多个方案,能对架构提出并验证改进 | 视觉组核心/组长 | 长期 |
环境+回放"] --> M2["M2 拆开看
检测+PnP复现"] M2 --> M3["M3 改得动
EKF+弹道+修bug"] M3 --> M4["M4 设计者
对比+改进+验证"]
M1 跑起来(对应 ch01-ch05、end-to-end)¶
练习 1.1 🟢 环境搭建验收¶
按 ch01 完成环境搭建,然后不看文档从零编译 RM_Vision_2027 和 sp_vision_25。
验收标准:
-
colcon build一次通过(RM_Vision_2027) -
cmake .. && make一次通过(sp_vision_25) - 能说出两个仓库分别依赖哪些第三方库(OpenCV / Eigen / yaml-cpp / fmt / ROS2 …),以及各自是怎么被找到的(
find_package在哪个文件里)
练习 1.2 🟢 录像回放跑通全链路¶
用 ros2 bag 或 sp 的录像回放模式,让自瞄程序在没有相机和电控的情况下跑起来。
验收标准:
- 能在 rviz2 / 调试窗口中看到检测框和跟踪结果
- 能用
ros2 topic hz报出检测节点的实际帧率 - 断开一个节点(如 tracker),能说出下游会观察到什么现象
练习 1.3 🟡 数据流手绘¶
合上电脑,在白纸上画出 end-to-end 章节的完整数据流:从相机触发到串口发包,标出每一步的数据类型(cv::Mat / Armors msg / Eigen 向量 / 字节包)和大致耗时。
验收标准:画完后对照 end-to-end 章节,遗漏或错误的环节 ≤ 2 个。
练习 1.4 🟡 OpenCV 灯条检测热身¶
完成 ch05 末尾的两个 TODO 练习(灰度→二值化→轮廓检测),并额外:
- 把
binary_thres做成滑动条(cv::createTrackbar)实时调节 - 用 sp 的演示视频
assets/demo/demo.avi逐帧处理
验收标准:在演示视频上,你的二值化图中灯条完整、背景干净,且能口头解释为什么阈值取这个值。
M2 拆开看(对应 ch06、ch07、ch09)¶
练习 2.1 🟡 从零复现传统灯条检测¶
不看 detector.cpp,只依据 ch07 的算法描述,自己写一个完整的检测器:预处理 → 找灯条(isLight)→ 配对(isArmor)→ 输出装甲板四角点。
验收标准:
- 在演示视频上,与仓库原版检测器逐帧对比,检出的装甲板数量一致的帧数 ≥ 90%
- 你的
isLight/isArmor里每一个阈值都能说出物理含义("为什么宽高比上限是 0.4 而不是 0.8") - 写完后 diff 你的实现与原版,列出 3 处原版考虑到而你没考虑到的细节
练习 2.2 🟡 PnP 手算与验证¶
取一帧检测结果,手动(用 Python + NumPy,不用 cv2.solvePnP)实现 DLT 或用 scipy.optimize 最小化重投影误差求解位姿,与 cv::solvePnP(SOLVEPNP_IPPE) 的输出对比。
验收标准:平移分量与 OpenCV 结果偏差 < 5%;能解释偏差来源。
练习 2.3 🔴 亲手撞一次 IPPE 二义性¶
设计实验复现 9.3.4 节描述的位姿二义性:
- 用已知位姿合成(或实拍)一组装甲板图像,装甲板 yaw 从 -30° 扫到 +30°
- 对每帧跑
solvePnP,画出"真实 yaw vs 解算 yaw"曲线 - 找到 yaw 发生镜像跳变的区间
验收标准:拿到跳变曲线图,并复现 sp 的 optimize_yaw 枚举法,证明它能消除跳变。这个实验做完,你对 ch09 的理解会超过绝大多数队员。
练习 2.4 🟡 串口协议解析器¶
不连电控,写一个 Python 脚本:按 ch06 的 SendPacket 定义手工构造一个字节包(含 CRC16 计算),再写解析函数还原字段,用 struct.pack/unpack 验证与 C++ 端 __attribute__((packed)) 的内存布局一致。
验收标准:Python 打包的字节序列与 C++ toVector() 输出逐字节一致(可以在 C++ 端打印 hex 对拍)。
M3 改得动(对应 ch08、ch10、debugging)¶
练习 3.1 🟡 2D 玩具 EKF¶
在碰 11 维 EKF 之前,先用 Python 写一个 4 维 EKF(状态 [x, vx, y, vy],观测为带噪声的极坐标 [yaw, dist]——注意观测是非线性的):
- 仿真一个做匀速圆周运动的目标,加观测噪声
- 实现 predict / update,画出真值、观测、估计三条轨迹
- 把 Q 调大 100 倍、调小 100 倍,各画一张图,解释现象
验收标准:估计轨迹明显优于原始观测;能用自己的话说清 Q 和 R 分别"信任谁"。
练习 3.2 🔴 复现 11 维整车 EKF¶
把 ch08 的 11 维模型在 Python 中完整复现(状态转移、h_armor_xyz、雅可比、角度感知加减法),用仿真的小陀螺目标验证:
- 仿真一个
ω = 6 rad/s、四装甲板、长短轴不同的旋转目标 - 每帧只"观测"到面向相机的那块装甲板(含噪声)
- 验证滤波器能收敛出正确的
r、r_diff、ω
验收标准:收敛后 ω 估计误差 < 5%,r 误差 < 2cm;关掉角度感知加法(x_add 用普通加法),能复现出 yaw 跨 ±π 时的发散现象并截图。
练习 3.3 🟡 弹道仿真对拍¶
用 Python 实现 ch10 的两个模型(抛物线解析解 + 单方向空气阻力迭代),画出同一目标(距离 3m/5m/8m,弹速 15/18/30 m/s)下两个模型给出的 pitch 差值表。
验收标准:能回答"在什么距离和弹速下,忽略空气阻力的误差开始超过半块装甲板高度(约 3cm 落点偏差)",并给出数据支撑。
练习 3.4 🔴 修复 x[8] bug 并实测¶
ch10 警告框指出了 sp_vision_25 choose_aim_point() 的疑似索引 bug(ekf_x()[8] 应为 [7])。完成完整的修复闭环:
- 写一个最小复现:构造一个
ω = 5 rad/s的仿真 Target,证明修复前代码走的是"不考虑小陀螺"分支 - 修复后重跑,确认 coming/leaving 逻辑被正确触发
- 在录像回放上对比修复前后的瞄准点选择行为
验收标准:产出一份 200 字以内的 bug 报告(现象/根因/修复/验证),格式参照开源项目 issue。做完可以真的去给上游仓库提 issue——这就是你的第一个开源贡献。
练习 3.5 🟡 故障注入排查¶
请队友(或自己写脚本)在你的工作环境里随机注入一个故障——改错一个 yaml 参数、注释掉一行 TF 发布、把相机图像 topic 重映射到错误名字——然后限时 30 分钟排查。debugging 章节是你的工具箱。
验收标准:三轮注入,至少两轮在 30 分钟内定位到根因。这个练习最接近比赛现场的真实压力。
M4 设计者(对应 ch11、ch12 及上游)¶
M4 没有标准答案,练习以"产出可讨论的技术文档"为验收形式。
练习 4.1 🟡 完整标定实操¶
用真实相机(或手机)走完 ch11 的完整标定流程:采集 → 标定 → 验证重投影误差 → 用标定结果跑 PnP 测距,与卷尺实测对比。
验收标准:重投影误差 < 0.5 px;1-5m 范围内 PnP 测距误差 < 3%。
练习 4.2 🔴 方案横评¶
选一个模块(推荐:反陀螺预测或装甲板检测),横向调研至少三个开源方案(本手册两个仓库 + 至少一个其他强队开源,如华南虎/狼牙/TUP/rv 上游),产出一份对比文档:架构差异、关键参数、各自的适用场景与失效模式。
验收标准:文档能让一个 M2 水平的队员读懂,且包含至少一个"手册里没写、你自己发现的"差异点。
练习 4.3 🔴 提出并验证一个改进¶
基于前面所有练习的积累,对现有系统提出一个可量化验证的改进(例:自适应 R 的公式改进、优化 optimize_yaw 的搜索策略、给 EKF 加 NIS 驱动的自适应 Q),并用录像回放或仿真给出前后对比数据。
验收标准:有假设、有实验、有数据、有结论——哪怕结论是"改进无效"。能独立完成这个闭环,你就是设计者了。
使用建议¶
给不同起点的读者
- 纯新人:严格按 M1 → M4 顺序,不要跳。M1 阶段感觉"太简单"是错觉——1.3 的手绘练习会暴露你以为懂了但没懂的地方。
- 有工程经验的读者(会写代码、做过项目):M1 可压缩到 3 天,然后直接从 2.1 和 3.1 双线并行——检测线(2.1→2.3)和估计线(3.1→3.2)互不依赖。
- 备赛压力大的团队:优先做 1.2、2.1、3.4、3.5 四个练习,它们的性价比最高。
关于验收
最好的验收方式是讲给队友听:每完成一个 🔴 练习,做一次 15 分钟的组内分享。讲不清楚的地方就是你没真正掌握的地方——这同时也在为团队沉淀第二代知识库。