EXP-03 · 8 学时

定位与多点导航巡检

融合理论「SLAM / 定位 / 导航原理」:载入 EXP-02 地图,配置 AMCL 初始位姿与 Nav2 参数,编排多个巡检点让 Go2 依序自主到达并避障。验收标准:Go2 依序自主到达巡检点;关键技巧:每点需定位收敛后再出发。

实践/理论AMCLNav2waypoint_follower

00课程节奏:五星学习法 · 8 段微课(每段 ≤ 15 min)

本实验按五星学习法组织:先用一个真实故障聚焦问题,再激活旧知(EXP-02 地图 + 定位直觉 + 路径规划),接着示证新知(AMCL 粒子滤波 + Nav2 分层),然后动手应用新知完成载图给初值到依序巡检,最后借排障与拓展融会贯通。全程切成 8 段微课、每段不超过 15 分钟,段间停顿 1~2 分钟消化;纯讲授合计约 100 分钟,其余课时用于动手实操与个别辅导。

① 聚焦问题
课段 1 · 12 min
"狗到错位"故障现场,带着问题开课
② 激活旧知
课段 2 · 8 min
EXP-02 地图 · GPS 定位直觉 · 路径规划
③ 示证新知
课段 3~4 · 27 min
AMCL 粒子滤波 + Nav2 分层 + 巡检动画
④ 应用新知
课段 5~7 · 40 min
载图→给初值→等收敛→编排→依序执行
⑤ 融会贯通
课段 8 · 13 min
排障口诀 · 拓展阅读 · 思考题
课段五星阶段时长对应章节本段任务
课段 1聚焦问题12 min§01 + §02 前半抛出现场故障"狗到错位",明确本课要解决的目标
课段 2激活旧知8 min§02 后半用 EXP-02 地图、GPS 定位直觉、路径规划三条旧知解释故障成因
课段 3示证新知15 min§03认识 map.yaml/传感器/定位初值与巡检点编排
课段 4示证新知12 min§06看懂 AMCL 粒子收敛与多点巡检依序到达动画
课段 5应用新知15 min§04 S1~S3 + §05 ①②载入地图 + 给初值 + 等粒子收敛(边讲边演)
课段 6应用新知15 min§04 S4~S5 + §05 ③④编排巡检点 + 依序执行 follow_waypoints——课段 1 的故障就此根除
课段 7应用新知10 min§07巡检点编排与到达判定自测,全通方可进入下一实验
课段 8融会贯通13 min§08~§10排障口诀收口,挑战题与思考题拔高迁移

讲课提示:课段 1/2 以讲授 + 提问为主;课段 3~6 边讲边演(实物 / 动画 / 命令行);课段 7 学员独立完成;课段 8 答疑拔高。段与段之间停顿 1~2 分钟,确认学员跟上再进下一段。

01学习目标课段 1 · 聚焦问题 · 12 min

  • 用通俗语言讲清三层分工:SLAM 画地图、AMCL 猜我在哪、Nav2 决定怎么走。
  • 理解 AMCL 粒子滤波:一群「位置猜测」如何随激光观测淘汰收敛到真实位姿。
  • 读懂 Nav2 的规划—控制—避障流水线,以及全向(Omni)运动模型对四足的意义。
  • 完成初始位姿标定、Nav2 参数核对、多巡检点编排与依序送达。
  • 掌握「定位收敛后再出发」的操作节奏,判断何时可以放心切下一个点。
素材说明:本课无视频素材——官方仓库演示动图、自制 SVG 示意图与动画共同承担讲解,不虚构实拍录像。

02原理:SLAM / 定位 / 导航(理论 2 融合)课段 1 收尾 + 课段 2 · 激活旧知 · 8 min

❓ 聚焦问题(课段 1)学员现场最常遇到的怪事:巡检点明明标在表计前,狗却停在两米外拍照;/amcl_pose 协方差一直很大,粒子满图飞。问题出在哪?带着这个故障听完全课——到课段 6 你会亲手让狗精准到位。

三个角色一台戏:EXP-02 画好的地图是「城市地图」;AMCL 是「我在地图的哪」的猜谜游戏;Nav2 是「高德导航」——知道地图加知道位置,它负责规划绕障路线并把油门方向盘发给四足。缺任何一个,狗都不是巡检员,只是随机遛弯。

AMCL:一群猜测不断淘汰

AMCL(自适应蒙特卡洛定位)的玩法:撒一把纸屑——在地图各处随机撒 2000 个「我可能在这」的粒子;每个粒子都拿当前激光扫描与地图比对,「如果我真在这,看到的景象对得上吗」,对得上的留下并繁殖,对不上的直接淘汰;几轮之后,所有粒子挤成一团,那团中心就是你的位置。初始一无所知时粒子满图乱飞,一旦你说「我其实在充电桩旁边」(2D Pose Estimate 给初值),粒子团会唰地收敛——这就是「定位收敛」的直观含义,也是「每点需收敛后再出发」的科学依据:粒子还没抱团就发车,狗会拿着错误位置自信地撞墙。

Nav2:高德地图导航的机器人版

Nav2 收到目标点后干三件事:①全局规划(在栅格地图上画出理论最优路线)→ ②局部控制(controller 按周期算每一步往哪迈,go2_ros2_sdk 参数里 controller_frequency 为 3.0Hz,匹配四足步态节奏)→ ③实时避障(代价地图里突然出现人/纸箱,局部规划当场绕开)。四足 Go2 可横移平移,所以用 nav2_amcl::OmniMotionModel(全向运动模型)比差速小车模型更贴合;多点巡检则交给 nav2_waypoint_follower——「把这串点按顺序走完,每到一个可以停一停」。

一句话版本:SLAM=画地图;AMCL=地图上自拍定位(一群猜测不断淘汰);Nav2=高德地图导航(规划+避障+踩油门);waypoint_follower=批量下单「一口气巡完 N 个点」。
↺ 激活旧知(课段 2)回忆三条旧知:① EXP-02 产出的 map.yaml(栅格地图是定位的底图);② GPS 定位直觉(知道大致位置才能精确定位);③ 路径规划(两点间走最优路线)。三条合起来,正好解释课段 1 那个故障。
go2_ros2_sdk 在 RViz 中的建图与导航地图
图 3-1|go2_ros2_sdk 在 RViz 中呈现的场地地图与机器人位姿(abizovnuralem/go2_ros2_sdk 仓库 README 官方截图):AMCL 正是把「机器人小箭头」钉在这张图的正确位置上。
① 初始:粒子满图乱撒 ② 观测淘汰 → ③ 收敛抱团 max_particles=2000,激光对不上的快速淘汰 ✗ 淘汰 ✗ 淘汰 真值 绿团抱团=定位收敛;黄圈=真实位姿
图 3-2|AMCL 粒子滤波三个阶段(自制示意图):左=随机撒粒子猜位置;右红点=被激光观测淘汰的猜测,绿点=存活并繁殖的猜测,抱团中心趋近真实位姿(黄圈)。
Nav2 分层:从「一张路线图」到「每一步落脚」(示意图) waypoint_follower 巡检点队列:P1→P2→P3… Planner(全局规划) 地图上画最优路线 Controller + 避障 3Hz 循环:走这步+绕障 桩123 障 绿弧=局部避障绕行 黄虚线=全局路线 · 桩=充电桩(巡检起终点)
图 3-3|Nav2 三层职责与多点巡检路线(自制示意图):上层按队列发目标,中层画全局路线,底层 3Hz 循环控步并绕开突发障碍(红点)。

03硬件与材料课段 3 · 示证新知 · 15 min

地图文件
EXP-02 产出的 map.yaml + map.pgm 放进导航工作空间;分辨率与 origin 必须完整。
传感器在线
3D 激光 utlidar/cloud 稳定输出(AMCL 的观测源);里程计/IMU 随运动服务发布。
定位初值
RViz「2D Pose Estimate」手动给初始位姿;充电桩是天然的原点参照。
场地巡检点
3~5 个:表计位、转角、货架端头、门禁点;预先在地图上目测好编号。
关键参数本课示例值(go2_ros2_sdk nav2_params)含义
robot_model_typenav2_amcl::OmniMotionModel四足可横移,全向模型比差速模型更准
max_particles / min_particles2000(官方默认量级)猜测数量:太少跟不上、太多耗算力
laser modellikelihood_field用「离墙面远近」打分,比波束法抗噪声
controller_frequency3.0 Hz控制循环 3 次/秒,匹配四足步态节奏

04操作步骤课段 5~6 · 应用新知 · 2×15 min

S1载入地图
map.yaml 进导航工作空间
→
S2给初值
RViz 2D Pose Estimate 对准桩位
→
S3等收敛
粒子抱团 + 激光贴合墙体
→
S4编排巡检点
Waypoint 工具逐点投放 P1~Pn
→
S5依序执行
follow_waypoints + 每点收敛判定
  1. 载图:把 map.yaml / map.pgm 放到导航参数指定路径,启动 ros2 launch go2_robot_sdk robot.launch.py(内置 slam_toolbox、Nav2、RViz),并停掉建图节点——建图与定位不要同时发 map,静态地图由 map_server 独家供图。
  2. 给初值:RViz 点 2D Pose Estimate,在地图上从充电桩位置拖出方向箭头——箭头起点放狗的真实站位、朝向拖准;AMCL 粒子应从满图散点唰地抱团。
  3. 判定收敛(技巧):让狗小幅前后挪 0.2m——激光轮廓与地图墙体贴合不重影、粒子团紧致,才算收敛;没收敛就再给一次初值。
  4. 编排路线:用 RViz Waypoint / Nav Through Points 工具在地图上依次落点 P1~Pn;或直接调用 follow_waypoints 服务把姿态数组一次下发。
  5. 依序执行:狗自主逐点到达;每到一点等待定位收敛(粒子不发散、朝向稳定)再执行下一点;途中人为放纸箱,验证局部避障绕行。
  6. 留痕:记录每个点的到达时刻与偏差,任何一点「冲过头/到错位」都回查 AMCL 粒子状态与 /amcl_pose 协方差。
验收闸门:全部巡检点按投放顺序到达且无撞障;抽查任意一点停稳后激光与墙体贴合——顺序错、到点偏、粒子发散三者出现其一即不通过。

05关键命令随课段 5 / 6 对照使用

AMCL 参数与 waypoint_follower 来自 Nav2 官方文档;launch 与参数路径沿用 go2_ros2_sdk。

# ① 启动(内置 map + AMCL + Nav2 + RViz;建图节点需按步骤停掉)
export ROBOT_IP=192.168.123.161
export CONN_TYPE=cyclonedds
ros2 launch go2_robot_sdk robot.launch.py

# ② RViz 操作(鼠标):2D Pose Estimate 给初值 → 等粒子抱团
#    nav2_params.yaml 关键片段(沿 Nav2 官方结构):
#    amcl: robot_model_type: "nav2_amcl::OmniMotionModel"  # 四足全向
#          max_particles: 2000   laser_model_type: "likelihood_field"
#    controller_server: controller_frequency: 3.0           # 3Hz 控制循环

# ③ 多点巡检:一次下发巡检点队列(nav2_waypoint_follower 服务)
ros2 service call /follow_waypoints nav2_msgs/srv/FollowWaypoints \
  "{poses: [{header: {frame_id: map}, pose: {position: {x: 2.1, y: 0.6}, orientation: {w: 1.0}}},
            {header: {frame_id: map}, pose: {position: {x: 4.0, y: 2.5}, orientation: {w: 1.0}}}]}"
#    也可以不用命令行:RViz 顶部 Waypoint 工具逐点投放,效果相同

# ④ 监控定位质量(收敛判据看这两个)
ros2 topic echo /amcl_pose --once      # 协方差椭圆应越缩越小
ros2 topic echo /particle_cloud --once # 粒子云:抱团=收敛,满图飞=未收敛
观察每到一个巡检点,/amcl_pose 的协方差会先涨(起步扰动)再降;看到协方差回落、粒子抱团再发车,就是「定位收敛后再出发」在数据上的样子。
规划谁说了算
PlannerServer 全局画线;ControllerServer 局部 3Hz 跟线;两层解耦,绕障不推翻全局路线。
代价地图两层
static 层放 EXP-02 地图,obstacle 层实时吃激光——人走过来会被实时标记为膨胀障碍。
为啥用 Omni 模型
四足可原地横移,差速模型会把横向漂移当误差猛纠,Omni 则视为正常运动。
到点判定
goal checker 按位置/朝向容差判定「到达」;容差太紧反复踱步,太松拍照对不准。

06动画:粒子收敛与多点巡检课段 4 · 示证新知 · 12 min

AMCL 粒子收敛:随机猜测 → 淘汰 → 抱团锁定真实位姿 真实位姿 t0:给初值前——蓝色粒子满图 t3s:激光观测打分后——蓝聚红灭 蓝=存活猜测(向真值聚拢) 红=观测对不上被秒淘汰 黄=真实位姿(收敛后与粒子团中心重合)
动画 3-1:给完初始位姿后,蓝粒子从满图各处涌向真值,红粒子在观测比对中闪烁出局——抱团完成即「定位收敛」,此时才允许发车去下一个巡检点。
多点巡检:桩 → P1 → P2 → P3 依序到达,遇障绕行 桩P1P2P3 障 局部代价地图膨胀 → 绿弧绕行 黄虚线=全局规划路线 黄脉冲=到达某点,停稳等定位收敛再出发 绿弧段=controller 局部绕障
动画 3-2:Go2 从充电桩出发按 P1→P2→P3 顺序执行;到点黄圈脉冲代表「停稳—等粒子收敛」的间歇,途中红障碍被局部规划以绿弧绕开——全局顺序不变,局部灵活应变。
观察动画 3-2 中机器人在每个点都会顿一下——那不是卡顿,是验收技巧「每点需定位收敛后再出发」的具象:停稳让粒子重新抱团,下一段路才不会带着漂移狂奔。

07互动:巡检点编排与到达判定课段 7 · 应用新知 · 10 min

按你想要的顺序投放巡检点,系统计算路线总长并判定编排质量

试试「P2 → P1」和「P1 → P2」两种顺序:路线总长会明显不同——巡检编排不是随手点,顺序决定里程、里程决定电量与耗时;判定区的黄色警告对应本实验技巧:出发顺序再好,到点不等收敛照样到错位。

08常见问题课段 8 · 融会贯通 · 13 min

Q 初始位姿给了还是飞?
箭头方向拖反、或给位姿时狗其实在别处:把箭头起点放在狗真实站位、朝向拖准;仍散则小幅挪动让观测刷新。
Q 走着走着定位漂了?
长直走廊特征少(对称墙迷惑观测):补桌面/柱子等非对称特征,或在该段降速多留观测帧。
Q 到点总差半米?
goal checker 容差与地图分辨率不匹配:先核对 map.yaml 的 resolution/origin,再微调 xy 容差。
Q follow_waypoints 报 404?
waypoint_follower 节点没起:确认 launch 拉起了 navigation_launch 全套,ros2 node list 里能看到它。
Q 遇人就停不绕?
obstacle 层没吃到激光或膨胀半径过大:检查 pointcloud_to_laserscan 输出与 obstacle 层 topic,膨胀调回合理值。
Q 电机哼哼/原地踱步?
定位抖动导致 controller 反复纠偏:等收敛、减小目标抖动;确认用 Omni 模型而非差速模型。
Q 建图节点要关吗?
要:建图与 AMCL 同时发 map 会互相覆盖,静态地图必须由 map_server 独家供图。
Q 能中途加点吗?
可以向队列继续发 follow_waypoints 请求;但每批点都遵守「到点—收敛—再出发」节奏,别连珠炮。

09拓展阅读课段 8 · 融会贯通

  • nav2_waypoint_follower 官方能力:「依序导航到一组 waypoints」,每点可插回调(拍照等动作)——EXP-04 的「到点拍照」就挂在这里。
  • Nav2 AMCL 官方配置:robot_model_type、max_particles、likelihood_field、initialpose 的完整语义——https://docs.nav2.org/configuration/packages/configuring-amcl.html
  • nav2_simple_commander(Basic Navigator):Python API 按「goToPose → wait → followWaypoints」编排流程,比手点 RViz 更适合做全自动巡检脚本。
  • 粒子云可视化:RViz 订阅 particle_cloud,把「抱团过程」录屏,是理解粒子滤波最直观的一手素材。
  • 回充对接(预告):Nav2 Docking Framework(opennav_docking,插件如 opennav_docking::SimpleChargingDock)负责巡检结束自主回桩——EXP-04 展开。

10思考题 · 自测课段 8 · 融会贯通

✅ 完成成果
Go2 按投放顺序自主到达全部巡检点,避障绕行一次成功并留痕。
🧠 原理收获
用「一群猜测不断淘汰」「高德导航」讲透 AMCL 与 Nav2 的分工与协作。
🛠 技能收获
独立完成初始位姿标定、收敛判定、多点编排下发与 /amcl_pose 质量监控。
📐 评分速览
依序到达 40% + 避障表现 20% + 原理口述 20% + 动画互动 20%。
思考 1为什么「每点需定位收敛后再出发」?用粒子滤波语言解释:未收敛就出发,误差会怎样被 Nav2 的反馈循环放大?
思考 2如果把 robot_model_type 换回差速模型(DiffMotionModel),四足横移时会出什么现象?说明 Omni 与差速模型的假设差异。