运动建图调优实录 —— 从碎片图到导航级地图
日期:2026-10-09 晚 成果:碎片率 48% → 2.0%,产出项目首张物理正确(无镜像)的导航级地图。
一、修了三个问题
| # | 问题 | 根因 | 修复 |
|---|---|---|---|
| 1 | yaw 系统性偏差 ~30%,地图碎成渣 | 等效轮距 0.0704 是废标定(熄火拖转产物,差程低于物理下限 π×0.13≈0.41m) | 陀螺基准重标 → 0.333;距离尺度 3m 推车复核 ×1.124 → TICKS_PER_REV 788 |
| 2 | EKF 融合被轮式 yaw 拖偏 | 桥接用轮距重算 vyaw,弃掉了后端已融合的陀螺值 | odom_bridge raw 模式直接透传后端 w(陀螺优先、编码器兜底),轮距只留保底路径 |
| 3 | 所有地图是物理空间的镜像 | RPLIDAR 设备角(顺时针正)被直接当 ROS 角(逆时针正)下发 | lidar.py 下发前取反射角 (360−angle)%360 |
修复 1、2 的验证:陀螺 ±2000dps 定案(手转 360°→365.9°);轮距比值法 0.991; 距离两遍差 0.09%。修复 3 的验证:手性比值 +1.04 → −0.99,电梯归位真北。
二、最终生效参数(第三~五张图的配置)
# mapping.yaml(slam_toolbox)
minimum_travel_distance: 0.2
minimum_travel_heading: 0.25
minimum_time_interval: 0.3
max_laser_range: 8.0
resolution: 0.05
do_loop_closing: true
map_update_interval: 5.0
参数逐条含义:
| 参数 | 值 | 含义 | 为什么是这个值 |
|---|---|---|---|
minimum_travel_distance | 0.2 m | 建节点的平移门槛:车离上一节点走出 0.2m,才把当前帧扫描收进位姿图 | 默认 0.5 给 40Hz 雷达;我们 6.3Hz 下 0.5m = 14 帧才 1 节点,太稀。0.2 让节点密度 ×2.5 |
minimum_travel_heading | 0.25 rad | 建节点的旋转门槛:转超 ~14° 才建节点;与距离门槛”或”的关系 | 坦克掉头 180° 切成 ~12 个节点,转弯过程被充分记录 |
minimum_time_interval | 0.3 s | 时间下限:条件满足也要距上节点 ≥0.3s | 防原地抖动/慢速爬行时同位置狂建节点(6.3Hz 下 ≈2 帧一节点) |
max_laser_range | 8.0 m | 单点距离上限:超 8m 的回波丢弃 | A1M8 远端点又稀又飘,不丢会变成孤立散点(走廊第一把 12m 时的外圈碎片即此) |
resolution | 0.05 m | 地图分辨率:每格 5cm | 室内标准值;匹配用原始扫描点不用栅格,调细只费 CPU |
do_loop_closing | true | 回环开关:重访旧区域时做全图优化,掰回累积漂移 | 多圈”越跑越实”的机制前提。 |
map_update_interval | 5.0 s | 发 /map 的显示周期 | 纯刷新频率,不影响建图内部 |
# robot/backend/config.py
WHEEL_TRACK_M = 0.333 # 等效轮距
TICKS_PER_REV = 788 # 每圈tick数
# 雷达:duty 85% ≈ 6.3 Hz(点/帧 ~198,室内够用)
三、五张图的过程
① 走廊第一把(20:04)—— 调参 v1 首跑

- 场景:240cm 走廊 A→B 往返 6 腿 + 坦克掉头 ×5
- 参数:调参 v1(上表全部);雷达 85%;未含镜像修复
- 跑法:普通往返,端头常规掉头
- 成绩:碎片 8.9%,最大块 403px(20m)
- 暴露问题:两端 V 型收拢——走廊”沿轴盲区”误差攒到端头被回环集中修正
② 走廊第二把(20:49)—— 跑法改进,V 消失

- 参数:同 ①(唯一变量是跑法)
- 跑法改进:贴端墙 30~50cm 再掉头 + 掉头前停 1 秒 + 半速慢转——端墙正脸入镜,盲区误差在建图前被修正
- 成绩:碎片 7.7%,最大块 748px(37m),V 消失,电梯缺口边线笔直
- 仍存在的问题:手性比值 +1.04 → 发现整图镜像(见问题 3)
③ 走廊第三把(21:11)—— 镜像修复后首跑

- 参数:同 ① + lidar.py 反射角修复
- 验证:手性比值 −0.99 ✓;电梯缺口(3.1m)落真北墙 ✓(A→B=东→西,电梯在北)
- 成绩:碎片 4.8%,最大块 765px(38m)——修复未伤质量
④ 大厅(21:28)—— 场景泛化

- 场景:约 10×8m 大厅
- 参数:同 ③,一字未改(
max_laser_range 8.0对 10×8 房间恰好:任意点到墙 ≤6.4m,全在视窗内) - 跑法:沿墙根绕圈 ×3(离墙 0.5~1.5m,拐角减速,不做坦克掉头)
- 成绩:碎片 7.3%,最大块 787px;轨迹闭合差 0.7%(101m);地图外扩部分为 8m 视窗透过门口看到的真实外邻结构
⑤ 房间(21:54)—— 当晚最佳 ⭐

注:桌子B的中间是镂空的,只有几根桌子腿。
- 场景:约 9×9m 房间
- 参数:同 ③④
- 成绩:碎片 2.0%,最大块 2140px(107m,全屋一体),连通块仅 42,轨迹闭合差 0.5%(72m)
- 视觉:外墙完整闭合、家具轮廓可辨、直角锐利、无重影无畸变(9.5/10,仅一处覆盖小缺口)
碎片率曲线:48.2%(修复前)→ 8.9% → 7.7% → 4.8% → 7.3% → 2.0%