SLAM 原理与 URDF 模型
这节课不写一行复杂代码,目标就两件事——① 用"蒙眼逛新家"的比喻听懂 SLAM 到底在干什么;② 用 URDF + RViz 把 car1 机器人"搬"到电脑屏幕上,看看它长什么样、坐标怎么连。
01问题引入:没地图的"鸡生蛋"困局
你要让扫地机器人打扫房间,它得先知道自己"在房间哪一格";可要判断自己在哪,它又得先有一张地图。定位需要地图,建图又需要知道自己的位置——这就是 SLAM 面对的经典鸡生蛋问题。再看另一个现实:
02原理通俗讲解:SLAM 与 URDF 是什么
COIN-D6 每秒 10 圈、量程 0.05~12 m,把周围墙壁变成一圈"距离点",相当于蒙眼人的手。
轮速与 IMU 经 EKF 融合推算走了多远(仍会漂),再拿新一圈扫描与上一圈对齐修正——相当于步感 + 摸墙校正。
世界切成 0.05 m 的小格子:100 = 占据、0 = 空闲、-1 = 没扫到的未知区。手电筒照到哪,哪格就"亮"。
URDF(Unified Robot Description Format,统一机器人描述格式)则是机器人的"身份证 + 骨架说明书":用 XML 写清每个连杆(link)的外观尺寸与惯性、每个关节(joint)怎么连、能怎么动。TF 坐标树再把 base_link、雷达、机械臂这些坐标系串成一棵树——没有这棵树,雷达数据不知道该画在车体哪一侧,后面建图全是乱的。
| 概念 | 生活比喻 | 本课程对应 |
|---|---|---|
| SLAM | 蒙眼逛新家:边摸边画图,边画图边记自己站哪 | EXP-02 用 SLAM Toolbox 真正跑起来 |
| 占据栅格 | 户型图的方格纸:每格标"墙 / 空 / 未勘探" | 话题里是 100/0/-1,存成 .pgm 后变成 0/254/205 灰度 |
| URDF | 机器人的乐高拼装说明书 | car1.urdf:底盘 + arm_link1~6 + 夹爪 |
| joint | 骨头之间的关节:有的焊死、有的能转 | fixed / continuous / revolute 三类 |
| TF 树 | 全家福站位图:谁站在谁旁边、朝向哪 | 根是 base_footprint,树断一则全乱 |
03关联知识点
定位要地图、建图要定位,SLAM 把两者联合求解,是移动机器人自主性的起点。
感知(雷达)→ 定位(里程计+匹配)→ 构图(栅格),缺一则地图不可用。
visual 看的、collision 撞的、inertial 算动力学的——三者可以引用不同精度的几何模型。
fixed 焊死(底盘→雷达)、continuous 无界旋转(4 个麦轮)、revolute 有界旋转(臂与夹爪,必须带 limit)。
根是 base_footprint(车体在地面的投影点),base_joint 以 fixed 抬升 0.029 m 接 base_link,保证 2D 导航的"地面基准"。
夹爪 5 个指节里只有 r_joint 是主动的,其余用 <mimic> 跟随它——滑条只拖一根,五根指节一起动。
04实验目标
- 能用一句生活比喻向他人讲清 SLAM = 边走边画地图 + 同时定位
- 能指认 car1 URDF 中 底盘 / 机械臂 / 夹爪 三部分及各自 joint 类型
- 跑通 display.launch.py 可视化三件套,在 rviz2 中看到模型并拖动关节滑条
- 用 view_frames 导出 TF 树,说清 base_footprint → base_link → laser_link 链路
- 解释栅格地图三值 -1 / 0 / 100 与分辨率 0.05 m 的含义
05实验环境与准备
本实验纯软件即可完成(有实物更佳):只需 Ubuntu 22.04 + ROS2 Humble 与已编译的 car1_description 功能包。
| 项目 | 要求 |
|---|---|
| 系统 | Ubuntu 22.04 + ROS2 Humble,source 工作空间并编译通过 |
| 软件包 | car1_description(含 urdf/car1.urdf、launch/display.launch.py、rviz/car1.rviz)、joint_state_publisher_gui、robot_state_publisher、rviz2 |
| 源码位置 | ros2_ws/src/xflz_eai_car1/simulations/car1_description/ |
| 可选硬件 | 小车 C1:COIN-D6 雷达(设备节点 /dev/lidar、话题 /scan、10 Hz、Best Effort QoS) |
| 验证命令 | ros2 topic hz /scan 约 10 Hz(接实物时) |
06动画讲解:激光扫描与栅格地图
左:雷达扇形束一圈圈扫过,量出到墙面的距离;右:扫到的格子被逐格"点亮"——100(墙)、0(空闲)、-1(灰色未知)。小车走到哪,亮的格子就铺到哪,这就是建图的最小过程。
07互动讲解:joint 类型 × TF 树拼装台
点击按钮给两个 link 选一种 joint,看 TF 父子关系与车体行为如何变化:
<limit>(机械臂与夹爪)选 revolute。类型选错,rviz 里要么拖不动、要么转飞了。08实操步骤:display 三件套看模型
# ① 启动模型可视化(本实验核心命令,一条命令拉起三个节点) ros2 launch car1_description display.launch.py # ② 导出 TF 坐标树:生成 frames_<时间戳>.pdf 与 frames.gv(在命令执行的当前目录) ros2 run tf2_tools view_frames # ③ 数一数 URDF 里有多少连杆与关节(真实值:17 link / 21 joint) grep -c "<link name=" car1.urdf grep -c "<joint name=" car1.urdf # ④(接实物)确认雷达数据在发 ros2 topic hz /scan # 约 10.0 Hz # car1.urdf 关键片段:根节点贴地,fixed 抬升 0.029 m 接车体 <link name="base_footprint" /> <joint name="base_joint" type="fixed"> <origin xyz="0 0 0.029" rpy="0 0 0" /> <parent link="base_footprint" /> <child link="base_link" /> </joint>
| car1 三部分 | 构成 | joint 类型 |
|---|---|---|
| 底盘主体 | base_link + 4 个麦轮(wheel_lf/rf/lb/rb)+ 雷达 / IMU 支架 | base_joint、laser_joint、imu_joint 全为 fixed;4 个轮子为 continuous |
| 机械臂 | arm_base_link + arm_link1~6(臂体 6 段,其中 arm_link6 用 fixed 与 link5 固定) | arm_joint1~5 为 revolute(各带 ±3.14 rad limit)→ 5 自由度 |
| 夹爪 | r_link / l_link / r_in_link / r_out_link / l_in_link / l_out_link 共 6 段指节 | 全部 revolute;仅 r_joint 主动,其余 5 个用 <mimic> 跟随开合 |
<link> 数 = 17、<joint> 数 = 21,而自由度只有 4(轮子)+ 5(臂)+ 1(夹爪)= 10:因为 fixed 关节、mimic 从动关节都不贡献自由度。分清"节点数"与"自由度",后面算正逆运动学才不会乱。09重点与易错点
| ⚠️ 常见坑 | 现象 → 解法 |
|---|---|
| rviz 里没有模型 | 画面空白 → 检查左侧 Displays 里 RobotModel 是否 Enabled、Description Topic 是否为 /robot_description |
| joint 滑条拖不动 | 该关节是 fixed / mimic 从动关节(本来就拖不动)→ 改拖 arm_joint1~5 或 r_joint |
| 找不到功能包 | Package 'car1_description' not found → 忘了 source 工作空间的 install/setup.bash,或未编译该包 |
| 模型扭曲/位置错 | origin 的 xyz/rpy 写错单位(米/弧度)→ 对照实物量一遍 |
| TF 树断裂 | view_frames 里缺 laser_link → robot_state_publisher 没起,或 URDF parent/child 写反 |
- display.launch.py 一键拉起 三件套,rviz2 能看到完整车体与机械臂
- frames.pdf 中 root = base_footprint,laser_link 与 imu_link 挂在 base_link 之下
- 能说出 -1 / 0 / 100 与 0.05 m 分辨率的含义
- 能指出 car1 三部分及 fixed / continuous / revolute 各用在哪里,并说出自由度为何是 10
10总结与思考
display 三件套跑通,rviz2 见车、view_frames 见树、grep 数出 17 link / 21 joint。
感知 → 定位 → 构图闭环;蒙眼逛新家比喻讲清同时定位与建图。
link/joint/origin 三件套语法,三种 joint 类型辨识,mimic 联动关系。
source 了吗 → RobotModel 加了吗 → Fixed Frame 对吗 → parent/child 反了吗。