坐标系与变换:世界坐标系、机体坐标系、传感器坐标系,欧拉角与四元数基础

做传感器融合,说白了就是跟坐标系打交道。我见过不少新手,算法公式背得滚瓜烂熟,结果一上手数据全乱套——十有八九是坐标系没搞明白。今天咱们就把这摊子事捋清楚。

1. 三个核心坐标系

先说说最常用的三个坐标系。你想想看,一个机器人身上挂着好几个传感器,每个传感器都有自己的小算盘,得有个统一的世界观才能把数据对齐。

世界坐标系(World Frame)

这是绝对参考系,通常用 W 表示。我习惯把机器人启动时的位置设为原点,X轴指向正东,Y轴指向正北,Z轴朝天。当然,你也可以用GPS经纬度作为基准,看具体场景。

关键点:世界坐标系是固定不动的。不管机器人怎么翻跟头,世界坐标系始终不变。

机体坐标系(Body Frame)

也叫载体坐标系,用 B 表示。原点在机器人质心,X轴朝前,Y轴朝左,Z轴朝上。注意,这里有个坑——不同行业定义不一样。无人机领域常用“前-左-上”,但汽车领域可能是“前-右-下”。

我在做AGV小车项目时,就吃过这个亏。供应商给的IMU数据按“前-右-下”定义,我按“前-左-上”解算,结果航向角差了180度。嗯,后来我学乖了,拿到传感器第一件事就是确认坐标系定义。

传感器坐标系(Sensor Frame)

每个传感器都有自己的坐标系。比如IMU的加速度计和陀螺仪,它们的敏感轴方向可能跟机体坐标系不完全重合。这就涉及到标定问题了。

坐标系 原点 典型用途
世界坐标系 W 固定点(如起点) 全局定位、路径规划
机体坐标系 B 机器人质心 控制指令、姿态描述
传感器坐标系 S 传感器中心 原始数据输出

2. 坐标系变换:旋转矩阵

坐标系之间怎么转换?核心就是旋转矩阵。一个点在世界坐标系下的坐标 PW,转换到机体坐标系下就是 PB = RWB · PW

旋转矩阵 R 是3x3的正交矩阵,行列式为1。说白了,它只改变方向,不改变长度。我刚开始学的时候,总觉得旋转矩阵太抽象,后来发现把它看成三个列向量就简单了——每一列就是目标坐标系的基向量在原坐标系下的投影。

// 绕Z轴旋转θ角的旋转矩阵
Rz(θ) = [
  cosθ, -sinθ, 0,
  sinθ,  cosθ, 0,
  0,      0,    1
]
我的小技巧:写代码时别手算旋转矩阵,直接用Eigen或ROS的tf库。我见过有人自己推导公式,结果符号搞反了,调了三天bug。

3. 欧拉角:直观但危险

欧拉角用三个角度描述姿态:横滚角(Roll)、俯仰角(Pitch)、偏航角(Yaw)。直观吧?但我要说,欧拉角是个美丽的陷阱。

为什么?因为万向锁(Gimbal Lock)。当俯仰角达到±90°时,横滚和偏航就分不清了。我在做四轴飞行器时遇到过这问题——飞机垂直爬升时,姿态解算突然跳变,差点炸机。

欧拉角的另一个问题是旋转顺序。ZYX顺序和XYZ顺序结果完全不同。我建议你统一用ZYX顺序(先偏航,再俯仰,最后横滚),这是航空领域的惯例。

避坑指南:我曾经在卡尔曼滤波里直接用欧拉角做状态量,结果协方差矩阵奇异了。后来换成四元数,问题迎刃而解。记住:欧拉角适合给人看,不适合给算法算。

4. 四元数:工程师的救星

四元数 q = w + xi + yj + zk,其中 w 是实部,x、y、z 是虚部。别被数学公式吓到,你只需要记住三点:

  • 四元数没有万向锁问题
  • 四元数插值平滑(SLERP)
  • 四元数乘法比旋转矩阵快

四元数表示绕单位向量 (x, y, z) 旋转 θ 角度:

q = [cos(θ/2), x*sin(θ/2), y*sin(θ/2), z*sin(θ/2)]

注意,四元数必须归一化。我见过有人忘了归一化,结果姿态越算越飘。嗯,这属于低级错误,但确实容易犯。

5. 欧拉角与四元数互转

实际项目中,我们经常需要在两者之间切换。比如从IMU读到的四元数,要转成欧拉角显示给用户看。

// 四元数转欧拉角(ZYX顺序)
roll  = atan2(2*(w*x + y*z), 1 - 2*(x² + y²))
pitch = asin(2*(w*y - z*x))
yaw   = atan2(2*(w*z + x*y), 1 - 2*(y² + z²))
注意: pitch 用 asin 计算,当接近±90°时数值不稳定。实际工程中我会加个阈值判断,防止溢出。

6. 知识体系总览

下面这张图是我自己整理的坐标系与变换知识结构,你可以照着这个思路去搭建自己的标定流程。

坐标系与变换知识体系 世界坐标系 W 绝对参考,固定不动 机体坐标系 B 随机器人运动 传感器坐标系 S 各传感器独立 变换方法 旋转矩阵 R | 欧拉角 (Roll, Pitch, Yaw) | 四元数 q 常见问题 万向锁 · 旋转顺序歧义 四元数归一化 · 坐标系定义不一致 工程实践 使用成熟库(Eigen/ROS tf) 统一坐标系定义 · 加阈值保护 核心原则:先标定传感器坐标系到机体坐标系,再解算机体坐标系到世界坐标系

7. 实战建议

最后,给你几条实在的建议:

  • 统一约定:项目一开始就定好坐标系定义和旋转顺序,写在文档里。我吃过亏,所以现在每个项目第一件事就是建个坐标系定义表。
  • 可视化验证:写个简单的3D可视化程序,把坐标系画出来。数据对不对,看一眼就知道。
  • 单元测试:写几个已知的旋转案例做测试。比如绕X轴转90°,看看结果对不对。
我的习惯:每次拿到新传感器,先用已知姿态做验证。比如把IMU平放,看Z轴加速度是不是9.8,四元数是不是(1,0,0,0)。这一步能筛掉80%的坐标系问题。

好了,坐标系这块就聊到这儿。记住一句话:坐标系定义清楚,融合就成功了一半。

专注资料整理