| 坐标系名 | 谁在用这个名字 | 如果你改了会怎样 |
|---|---|---|
| map | SLAM(Cartographer、Gmapping)、Nav2 全局代价地图、rviz 固定坐标系 | SLAM 发布到错误的 frame,Nav2 找不到全局地图,rviz 里什么都看不到 |
| odom | Nav2 局部代价地图、AMCL、EKF 里程计融合 | 导航规划器无法计算局部路径 |
| base_link | MoveIt2、Nav2 底盘控制、所有 TF 查询的默认目标 | 机械臂不知道自己在哪,导航不知道往哪走 |
| laser / camera_link | 激光雷达驱动、相机驱动、代价地图层 | 传感器数据无法被其他节点消费 |
所以实际上,这 4 个名字是"事实上的标准",改了等于自找麻烦。
二、真正"固定"的是什么?
不是名字,而是它们在 TF 树中的层级关系和语义角色:
map (全局参考系,固定不动)
│
odom (里程计参考系,短期精确,长期漂移)
│
base_link (机器人本体参考系,跟着机器人动)
│
sensor (传感器,相对于机器人本体有固定安装位置)
这个结构是固定的。ROS 生态里所有导航、定位、规划工具都依赖这个结构。但名字本身,你可以改------只要你同时改所有相关配置。
三、实际项目中你会怎么配置?
1. 在 URDF 里定义(静态部分)
xml
<!-- base_link 是机器人本体的根 -->
<link name="base_link"/>
<!-- 激光雷达相对于 base_link 的位置 -->
<joint name="laser_joint" type="fixed">
<parent link="base_link"/>
<child link="laser_link"/> <!-- 你也可以叫 lidar_link -->
<origin xyz="0.2 0 0.15" rpy="0 0 0"/>
</joint>
2. 在 SLAM 配置里指定(动态部分)
yaml
# Cartographer 或 Nav2 的配置
map_frame: "map" # 全局坐标系名
odom_frame: "odom" # 里程计坐标系名
base_frame: "base_link" # 机器人基坐标系名
如果你把 base_frame 改成了 robot_base,那所有引用这个参数的地方都要改------Nav2、MoveIt2、EKF、rviz 配置......牵一发动全身。
四、常见的"变体"命名
虽然标准是 map/odom/base_link,但你会看到一些项目用不同的名字:
| 项目 | 实际命名 | 说明 |
|---|---|---|
| TurtleBot3 | map / odom / base_link / base_scan |
激光雷达叫 base_scan 而不是 laser |
| Husky | map / odom / base_link / front_laser_link |
激光雷达带位置前缀 |
| UR5 + 移动底盘 | map / odom / base_link / tool0 |
机械臂末端叫 tool0(不是 gripper) |
| 你的超市机器人 | map / odom / base_link / ... |
建议严格遵循标准 |
规律 :map/odom/base_link 这三个几乎没人改(因为代价太大),但传感器坐标系的名字 经常带前缀或后缀(front_laser、camera_shelf、realsense_d455)。
五、一句话总结
map / odom / base_link这三个名字在 ROS 生态里是"准强制"的------你可以改,但所有工具都要跟着改,得不偿失。传感器坐标系的名字相对自由,但通常也遵循{位置}_{类型}_{编号}的命名习惯(如front_laser、camera_shelf_1)。
所以你记住:用标准名字,别折腾。 把精力花在 TF 树的结构和坐标变换的正确性上,而不是纠结名字。