2. 坐标系与刚体运动基础

做多传感器融合,说白了就是跟坐标系打交道。我刚开始接触这个领域时,觉得坐标系不就是个参考系嘛,有什么好讲的?结果第一次做激光雷达和相机的联合标定,就被坐标系变换搞得晕头转向。嗯,今天咱们就把这块硬骨头啃下来。

2.1 为什么坐标系这么重要?

你想想看,一个机器人身上可能同时装着激光雷达、IMU、相机、GPS。每个传感器都有自己的"小世界"——自己的坐标系。激光雷达说"前方3米有障碍物",相机说"图像中心偏右100像素有特征点",IMU说"当前加速度是0.5m/s²"。这些数据如果不统一到一个坐标系下,根本没法用。

我在项目中遇到过最典型的例子:一个AGV小车,激光雷达检测到前方1米有障碍物,但实际障碍物在车体左前方。为什么?因为激光雷达装在车头右侧,它的"前方"和车体的"前方"差了30度。这就是坐标系没对齐的后果。

核心思想:多传感器融合的第一步,就是把所有传感器的数据都变换到同一个参考坐标系下。

2.2 常用坐标系

做SLAM,你至少得搞明白下面这几个坐标系:

坐标系 符号 说明
世界坐标系 W 固定在地面上的全局参考系,通常以机器人起始位置为原点
机器人本体坐标系 B 固定在机器人质心,x轴朝前,y轴朝左,z轴朝上
传感器坐标系 S 每个传感器自己的坐标系,比如相机坐标系、激光雷达坐标系

我个人习惯把世界坐标系叫做"地图坐标系",因为最终建图的结果就是在这个坐标系下表达的。机器人本体坐标系嘛,说白了就是"我当前在哪儿、朝哪个方向看"。

2.3 刚体运动与变换矩阵

刚体运动,就是物体在空间中移动和旋转,但形状大小不变。一个刚体在三维空间中的位姿,可以用6个自由度来描述:3个平移 + 3个旋转。

怎么表示这个变换呢?最常用的就是齐次变换矩阵:

// 齐次变换矩阵 T 的形式
// T = [R  t]
//     [0  1]

// 其中 R 是 3x3 旋转矩阵
// t 是 3x1 平移向量

// 举个例子:将点 p 从传感器坐标系变换到机器人坐标系
p_robot = T_sensor_to_robot * p_sensor

这里有个坑,我曾经踩过:旋转矩阵必须是正交矩阵,行列式为+1。如果你标定出来的旋转矩阵不满足这个条件,那肯定是算错了。嗯,别问我怎么知道的。

避坑指南:我曾经在写代码时直接把旋转矩阵的9个元素当参数优化,结果优化出来的矩阵根本不是合法的旋转矩阵。后来改用四元数或者李代数表示旋转,才解决了这个问题。

2.4 旋转的多种表示方式

旋转矩阵、欧拉角、四元数、轴角……初学者看到这些肯定头大。我建议你这样理解:

  • 旋转矩阵:最直观,但9个参数有6个约束,不适合优化
  • 欧拉角:3个参数,但有万向锁问题
  • 四元数:4个参数,无奇异性,适合插值和优化
  • 轴角:3个参数,但表达不唯一

做SLAM,我个人强烈推荐用四元数。为什么?因为它在优化时不会遇到奇异性,而且插值平滑。我在做视觉惯性里程计(VIO)时,所有旋转都用四元数表示,省了不少麻烦。

// 四元数表示旋转
// q = [w, x, y, z],其中 w 是实部

// 用四元数旋转一个三维向量 v
// 先把 v 写成纯四元数 [0, vx, vy, vz]
// 然后计算 q * v * q_conjugate

Eigen::Quaterniond q(0.707, 0.707, 0, 0);  // 绕z轴旋转90度
Eigen::Vector3d v(1, 0, 0);
Eigen::Vector3d v_rotated = q * v;  // 结果是 (0, 1, 0)

2.5 坐标系变换链

实际系统中,坐标系变换往往是链式的。比如:

// 从激光雷达点变换到世界坐标系
p_world = T_world_to_robot * T_robot_to_lidar * p_lidar

// 或者写成
p_world = T_world_to_robot * (T_robot_to_lidar * p_lidar)

这里要注意变换的顺序。矩阵乘法不满足交换律,先旋转后平移和先平移后旋转结果完全不同。我见过有人把这两个搞反了,结果点云全部飞到天上去。

小技巧:写代码时,我习惯把变换矩阵的命名写成"T_目标坐标系_源坐标系"。比如 T_world_robot 表示从机器人坐标系到世界坐标系的变换。这样一眼就能看出变换方向。

2.6 知识体系总览

下面这张图总结了本章的核心内容,我建议你保存下来,做项目时对照着看:

坐标系与刚体运动知识体系 多传感器融合SLAM 坐标系定义 世界坐标系 W 机器人坐标系 B 传感器坐标系 S 刚体运动表示 旋转矩阵 R 四元数 q 欧拉角 (RPY) 齐次变换矩阵 T T = [R t; 0 1] 变换链组合 逆变换 T⁻¹ 核心:统一坐标系 → 数据对齐 → 融合计算

2.7 实践中的坐标系管理

在ROS中,坐标系管理有现成的工具——tf库。你不需要手动维护变换矩阵,tf会帮你搞定一切。但理解背后的原理仍然很重要,因为:

  • 标定传感器外参时,你需要自己推导变换关系
  • 调试时,你需要能看懂tf树,快速定位问题
  • 优化算法时,你可能需要自己实现变换,而不是依赖tf

我记得有一次,一个学生在做激光雷达和IMU融合时,发现定位结果总是飘。查了两天,最后发现是IMU的坐标系定义和激光雷达差了90度。这种问题,如果你不懂坐标系变换,根本无从下手。

总结一下:坐标系和刚体运动是SLAM的"语法"。语法都搞不明白,写出来的代码肯定跑不通。我建议你花时间把旋转矩阵、四元数、齐次变换矩阵的互相转换写一遍代码,亲手验证一下。纸上得来终觉浅,绝知此事要躬行。

公众号:蓝海资料掘金营,微信deep3321