EXP-01 · 8 学时(2 理论 + 6 实践)

沙盘环境认知与建图导航

先认识沙盘上的每一条交通语义,再让小车 C1 用激光 SLAM 遍历全场、闭环保存 slam_map,用 Nav2 完成点到点巡路,最后回到地图上给路口、灯口、车位打语义标注——验收标准:地图闭环无重影 + 点到点 3 次到位 + 语义标注 ≥6 处。

理论2+实践6slam_toolboxcar1_slam / slam_mapNav2 + AMCL安全边界

01本节目标

  • 说出沙盘典型元素及其交通语义:车道线(约 40cm 宽)、直角弯、T 形/十字路口、红绿灯模型、斑马线、平行车位/侧方车位、四类交通标志牌、行人模型、高对比识别线。
  • 讲清激光 SLAM 三件事:怎么扫(/scan 扫描匹配)、怎么闭(回环校正)、怎么存(slam_map 栅格地图)。
  • 独立跑通 car1_slam/slam.launch.py 遍历建图并保存 slam_map,在 RViz2 检查路口无重影。
  • 用 car1_navigation/navigation.launch.py 完成 Nav2 点到点巡路,会设 2D Pose Estimate 初始位姿。
  • 在地图上完成 ≥6 处沙盘语义标注(路口/灯口/车位/斑马线),形成后续实验的点位底座。
  • 牢记安全铁律:沙盘边缘 0.5m 内视为安全边界,小车低速起步(≤0.15m/s),先空场后巡路。
素材说明:本实验无实拍素材,示意图与交互动画为准;两幅沙盘参照图抓取自 Hiwonder 官方产品页(公开图),仅作同类规格参考,元素与尺寸以现场沙盘实际为准。

02核心原理:沙盘即结构化城市,SLAM 把它变成栅格地图

把沙盘想像成一座"微缩城市"的施工图纸:车道线是道路中轴,路口是节点,红绿灯与标志牌是规则牌,车位是终点站。小车要在这座城市里活下来,先得把"图纸"装进脑子里——这幅图纸就是 slam_map 栅格地图。激光雷达每转一圈吐出一帧 /scan,slam_toolbox 做扫描匹配:拿当前帧与已有地图对齐,能对上就推出自身位姿、顺手把新墙面刷进地图;走过回头路时触发回环校正——发现"这面墙我来过",把累计漂移一把拉回,路口才不会画成两个路口。

沙盘元素 → 地图语义 → 课程用途(典型规格,以现场沙盘实际元素为准)

沙盘元素典型规格在本课程中的用途
车道线 / 高对比识别线车道宽约 40cm,黑黄高对比EXP-03 视觉巡线的检测对象,建图时贴地特征对激光反射弱、靠边界墙定图
直角弯 ×4、T 形/十字路口路口为规则几何,墙沿笔直建图回环的关键路标;EXP-03 路口状态机的执行场所
红绿灯模型立式三色灯,高约 24cmEXP-02 三态识别 → EXP-03 红灯停绿灯行
斑马线人行横道白条纹横跨车道EXP-03 礼让行人触发区;EXP-04 综合路测扣分项
平行车位 / 侧方车位标线框约 45×35cmEXP-04 车位检测与轨迹泊车目标
交通标志牌(直行/转向/停车/注意行人)牌面约 8×8cm、杆高约 16cmEXP-02 四类标志检测 → EXP-04 按标志改道
行人模型立牌式,置于斑马线端EXP-03 斑马线礼让判据
中心十字路口(灯口) 直角弯 平行车位 红绿灯模型 巡图回环路线(闭环) 沙盘路网拓扑(俯视简化)
图 1-1|自制示意图:沙盘路网拓扑——外环主路 + 中轴支路构成回环,中心为灯口十字路口,四角为直角弯,右下为平行车位;蓝紫虚线示意建图时应走的闭环巡图路线。

地图有了,Nav2 负责"怎么走":AMCL 粒子滤波拿实时 /scan 与 slam_map 匹配求出小车在图上的坐标(map→base_link),全局规划器(A*/DWA 层级)在代价地图上铺出路线,局部控制器沿路纠偏,把结果化成 /cmd_vel 速度流给麦克纳姆轮底盘——于是"走到那个路口"就成了一次点击。语义标注则是往这张图上贴标签:把 map 坐标系里的路口、灯口、车位写进一个 yaml 点位表,EXP-02~04 全部按名取点,不再传裸坐标。

03硬件与场景

小车 C1 · 底盘
麦克纳姆轮四轮底盘,执行 /cmd_vel;全向平移让直角弯出弯更从容,但 横移会带来雷达视差,建图时优先前向行驶。
小车 C1 · 眼睛
2D 激光雷达(建图主力)+ HP60C 深度相机(/ascamera_hp60c/**,存在 0.5m 近盲区,贴墙作业时不可依赖)。
小车 C1 · 大脑
6 TOPS NPU 端侧算力,本实验主要跑 slam_toolbox 与 Nav2;语音 car1_speech 在 EXP-04 播报成绩时启用。
智慧交通教学沙盘
约 3.26m×2.98m 级别铺装 + 挡边围栏,元素见第 02 节表;以现场沙盘实际元素为准。
上电前检查标准不达标后果
电量>50%,低于 30% 立即回充建图半途掉电,slam_map 损坏重跑
雷达话题ros2 topic echo /scan --once 有数据slam_toolbox 无输入,map 全黑
沙盘清场移走散落物,行人模型归位动态障碍被刷进地图成"鬼墙"
安全边界沙盘四周 0.5m 无人踩踏区小车冲沿、人员绊倒
交通教学沙盘场景参照图
图 1-2|交通教学沙盘场景参照(网抓自 Hiwonder 官方产品页 的同类产品公开图,非本教室实拍):环形车道、路口、标志牌、行道树分区与红绿灯立柱的典型布局——本课沙盘元素以现场实际为准。

04操作步骤

S1认知与清场
对照第 02 节表逐个认元素 → 划安全边界 → 上电自检
→
S2启动建图
slam.launch.py + RViz2,遥控低速遍历沙盘闭环一圈
→
S3保存与检查
保存 slam_map,检查路口无重影、车位框完整
→
S4Nav2 巡路
navigation.launch.py 加载地图 → 设初始位姿 → 3 个目标点
→
S5语义标注
RViz2 Pick Point 记录路口/灯口/车位 → 写入点位 yaml
  1. 遍历策略:先沿外环顺时针走一圈,再穿中轴支路,最后回到出发点触发回环——直角弯外侧 90° 缓转,速度 ≤0.15m/s,起步前让轮子转半圈再落,避免麦克纳姆轮原地打滑刷歪地图。
  2. 闭环检查:RViz2 中回到起点时,起始墙面与返场墙面应重合成一条线;出现"双墙"说明漂移大,重新建图并放慢过弯速度。
  3. 保存地图:执行第 05 节命令保存 slam_map.yaml + slam_map.pgm,先在 RViz2 反复加载确认再往下走。
  4. 点到点巡路:加载地图启动导航后必设 2D Pose Estimate,依次下发 3 个目标点(A 角直角弯、B 点灯口前、C 点车位前),每个点连续 3 次到位算通过。
  5. 语义标注:用 RViz2 的 Publish Point 读坐标,按 name: {x, y, yaw} 格式写入点位 yaml,至少标注 4 路口 + 1 灯口 + 1 车位。
  6. 留痕:保存地图截图、3 次到位截屏与点位 yaml,构成本实验验收证据。

05关键命令

命令风格与《培训方案》xlsx 一致;包名、地图名沿用 car1_slam / slam_map / car1_navigation 约定。

# ① 预检:雷达与底盘话题在线
ros2 topic echo /scan --once
ros2 topic list | grep -E "scan|cmd_vel"

# ② 启动激光 SLAM 建图(终端1)+ RViz2 观察(终端2)
ros2 launch car1_slam slam.launch.py
rviz2 -d ~/car1_ws/src/car1_slam/rviz/slam.rviz

# ③ 遥控遍历沙盘闭环(低速起步!)+ 查看 TF 树确认 frame 完整
ros2 run teleop_twist_keyboard teleop_twist_keyboard
ros2 run tf2_tools view_frames

# ④ 保存地图为 slam_map(遍历闭环并回到起点后执行)
ros2 run nav2_map_server map_saver_cli -f slam_map

# ⑤ 加载 slam_map 启动 Nav2 + AMCL 定位
ros2 launch car1_navigation navigation.launch.py map:=slam_map

# ⑥ RViz2 设初始位姿(2D Pose Estimate)后再下发目标点
ros2 action send_goal /navigate_to_pose nav2_msgs/action/NavigateToPose \
  "{pose: {header: {frame_id: map}, pose: {position: {x: 1.2, y: 0.8}}}}"

# ⑦ 监控定位质量:粒子云应收敛成一撮,TF 持续刷新
ros2 topic echo /amcl_pose --once
ros2 run tf2_ros tf2_echo map base_link
验收标准(写入 s4 打卡):① slam_map 覆盖全场、路口无重影;② 3 个目标点各连续 3 次到位(横向偏差 < 半个车道);③ 点位 yaml ≥6 条且名称可读。易错点:初始位姿必设、低速起步、闭环回原点、目标点别压在车道线上(footprint 会顶掉)。
数据流
/scan → slam_toolbox → /map → AMCL(+初始位姿)→ /cmd_vel → 底盘,一条链断了先查话题。
为什么保留 slam_map
EXP-04 综合路测在同一张图上跑,点位、路线全部复用,禁止随意挪动沙盘元素。
回环的意义
闭环把"走到路口时车以为自己在直道"的累计误差拉回,否则语义标注全是错位的。
语义标注格式
waypoints.yaml:name/x/y/yaw 四字段,EXP-03~04 按名取点,杜绝裸坐标硬编码。

06原理动画:遍历建图与 Nav2 点到点

实时建图:/scan 扫描匹配 + 回环校正 黄点=小车沿闭环巡图 · 绿线=激光扫掠 · 末段脉冲=回到起点触发回环校正 回环前后对比 ❌ 漂移:路口出现"双墙"重影 ✅ 校正:墙面重合、坐标拉回
动画 1-1:小车沿沙盘外环闭环巡图,激光扫掠不断刷进新墙面;回到起点脉冲扩散——回环校正把累计漂移拉回,右下"双墙"复位为单墙。
slam_map + 目标点 map 帧坐标 AMCL 定位 粒子滤波 /amcl_pose 全局规划 A* 代价地图避障 /cmd_vel 速度指令 小车 C1 里程计 + 激光匹配反馈:位姿实时回灌 AMCL,规划闭环(只发不收=盲开) goal
动画 1-2:点到点管线——目标点进入后,AMCL 先把"我在哪"算准,A* 铺路,/cmd_vel 驱动底盘,位姿反馈不断回灌;下方进度条演示目标点从下发到到位的全过程。
观察动画 1-1 里为什么回环发生在"回到起点"那一刻?SLAM 的误差是越走越攒的:只在识别出旧场景时才有机会把攒下的误差一次性摊销——这就是巡图必须闭环、不能只走单程的原因。

07互动实验:红绿灯配时模拟器

沙盘灯口配时推演:拖时间轴看南北/东西向灯态与通行决策
南北向 停止线 C1 东西向 灯口平面见第 06 节动画

配时公式(本模拟器采用):南北向 红 3s → 绿 25s → 黄 5s,东西向 绿 13s → 黄 2s,周期 48s。把滑杆推到黄灯切换前 2 秒再看车辆位置——"能否在停止线前停下"决定黄灯该走还是该停,这正是 EXP-03 路口状态机的判据原型。

08常见问题

Q map 一片黑?
先查 /scan 是否在滚;再看 slam.launch.py 是否指到雷达话题;最后确认沙盘挡边在雷达量程内且反射正常。
Q 路口出现双墙重影?
回环没触发或触发失败:放慢过弯、让起点与终点重叠 0.5m 以上;仍不行则清图重建,禁用横移。
Q 启动导航后小车原地打转/找不着北?
没设 2D Pose Estimate!AMCL 初始粒子弥散,必须先在 RViz 给初值对准起始朝向。
Q goal 发出即被拒?
多半是 transform 超时或目标点落在代价地图内:检查 view_frames 的 map→odom→base_link 链,把点挪到车道内。
Q 小车起步就画歪?
起步过猛导致轮子打滑(低速起步铁律):teleop 先点动半圈观察 RViz 再连续行进。
Q 相机能帮忙建图吗?
本实验只用 2D 雷达;HP60C 有 0.5m 近盲区,靠墙场景不可依赖,留给 EXP-02 做视觉。
Q 地图存哪了?
工作目录下 slam_map.yaml/.pgm;提交时连同点位 yaml 一起归档,EXP-04 复用。
Q 巡路时撞行人模型?
语义上行人模型是"可绕障",先从地图删掉误刷的模型再导航,或在 costmap 中膨胀半径调大。

09拓展阅读

  • slam_toolbox 官方文档(ROS 2 Wiki):mapping / localization 两种模式的参数表——对照本课 slam.launch.py 看 resolution、max_laser_range 怎么影响 40cm 车道的建图精度。
  • Nav2 概念页:global planner 与 controller 的分工、代价地图膨胀层——理解"目标点为什么不能压线放"。
  • tf2_tools view_frames:每次导航会话开始先导一次 TF 树,map→odom→base_link 断链是 80% 导航怪病的根源。
  • 教学沙盘选型:淘宝「ROS机器人无人驾驶沙盘」(id=696594369848,¥899,塔克创新品牌店);同类规格可参考 Hiwonder 自动驾驶地图产品页(本课抓图来源)。
  • 本课程索引:CASE-05 课程目录,下一实验将把灯口与标志牌变成话题数据。

10思考题 · 自测

✅ 完成成果
slam_map 全场无重影 + 3 目标点 ×3 次到位 + 语义点位 yaml ≥6 条。
🧠 原理收获
能讲清扫描匹配、回环校正、AMCL 粒子滤波三者在"画图→认路"链条中的分工。
🛠 技能收获
独立完成建图、存图、加载导航、设初始位姿、下发目标点与语义标注全流程。
📐 评分速览
地图质量 40% + 巡路到位 30% + 标注完整性 20% + 安全规范 10%。
思考 1为什么巡图必须回到起点闭环?如果不闭环,语义标注里的"灯口"坐标会怎样随巡图时长漂移?请用"误差累积"解释。
思考 2假设把初始位姿故意偏 30° 再导航,小车会有什么表现?这与"低速起步"各自防的是哪类事故?