第三章 四元数基础:从困惑到通透
说实话,我第一次接触四元数的时候,脑袋是懵的。
什么 i² = j² = k² = ijk = -1?这玩意儿跟控制算法有什么关系?我当时在做一个无人机项目,导师丢给我一句「用四元数代替欧拉角,避免万向锁」。我硬着头皮啃了三天,才勉强搞明白。
今天我就用最直白的方式,把四元数给你讲透。
3.1 四元数的定义
四元数,说白了就是一个四维的复数扩展。你想想看,复数有一个实部和一个虚部(a + bi),四元数则是一个实部和三个虚部:
q = w + xi + yj + zk
其中 w、x、y、z 是实数,i、j、k 是三个虚数单位。它们的关系是:
- i² = j² = k² = -1
- ij = k, ji = -k
- jk = i, kj = -i
- ki = j, ik = -j
嗯,这里要注意,乘法不满足交换律。也就是说 ij ≠ ji。这在后面的旋转计算中非常关键。
我习惯把四元数写成向量形式:
q = [w, x, y, z]ᵀ
或者拆成标量部分和向量部分:
q = (w, v) 其中 v = (x, y, z)
单位四元数(模长为1)是描述旋转的利器。它的模长定义为:
||q|| = √(w² + x² + y² + z²) = 1
核心要点:只有单位四元数才能表示纯旋转。如果你的四元数模长不是1,记得先归一化。
3.2 四元数与欧拉角的转换
我在项目中遇到过最头疼的事,就是调试时发现姿态数据跳变。查了半天,原来是欧拉角到四元数的转换写错了。
先说说欧拉角转四元数。假设我们用的是 ZYX 顺序(偏航-俯仰-横滚):
// 欧拉角:yaw(ψ), pitch(θ), roll(φ)
// 转换为四元数
double cy = cos(yaw * 0.5);
double sy = sin(yaw * 0.5);
double cp = cos(pitch * 0.5);
double sp = sin(pitch * 0.5);
double cr = cos(roll * 0.5);
double sr = sin(roll * 0.5);
double w = cr * cp * cy + sr * sp * sy;
double x = sr * cp * cy - cr * sp * sy;
double y = cr * sp * cy + sr * cp * sy;
double z = cr * cp * sy - sr * sp * cy;
反过来,四元数转欧拉角:
// 四元数 q = (w, x, y, z)
// 转换为欧拉角
double roll = atan2(2*(w*x + y*z), 1 - 2*(x*x + y*y));
double pitch = asin(2*(w*y - z*x));
double yaw = atan2(2*(w*z + x*y), 1 - 2*(y*y + z*z));
避坑指南:我曾经因为 pitch 接近 ±90° 时,asin 的参数超出 [-1,1] 范围,导致程序直接崩溃。建议加一个 clamp 操作:
double sinp = 2*(w*y - z*x);
if (sinp > 1.0) sinp = 1.0;
if (sinp < -1.0) sinp = -1.0;
double pitch = asin(sinp);
3.3 四元数的优势
为什么我们要用四元数?说白了,欧拉角有三个硬伤:
| 特性 | 欧拉角 | 四元数 |
|---|---|---|
| 万向锁 | 有(pitch=±90°时丢失自由度) | 无 |
| 插值平滑性 | 差(非线性,容易跳变) | 好(球面线性插值SLERP) |
| 计算效率 | 涉及大量三角函数 | 仅需乘法和加法 |
| 存储空间 | 3个角度 | 4个分量 |
我个人觉得,四元数最大的优势是避免了万向锁。你想想看,在无人机控制中,如果飞机做特技动作时姿态突然锁死,那后果不堪设想。
另外,四元数的旋转组合非常优雅。两个旋转 q₁ 和 q₂ 的复合,直接就是四元数乘法:
q_total = q₂ ⊗ q₁
注意顺序:先应用 q₁,再应用 q₂。乘法公式如下:
q₁ = (w₁, x₁, y₁, z₁)
q₂ = (w₂, x₂, y₂, z₂)
q₁ ⊗ q₂ = (
w₁w₂ - x₁x₂ - y₁y₂ - z₁z₂,
w₁x₂ + x₁w₂ + y₁z₂ - z₁y₂,
w₁y₂ - x₁z₂ + y₁w₂ + z₁x₂,
w₁z₂ + x₁y₂ - y₁x₂ + z₁w₂
)
我的小技巧:在代码里实现四元数乘法时,我习惯用临时变量存中间结果,避免覆盖原始数据。特别是嵌入式环境,一个不小心就把寄存器搞乱了。
3.4 知识体系总览
下面这张图是我自己总结的四元数知识脉络,你看一眼就能明白整个章节在讲什么:
这张图把四元数的三个核心模块串起来了。定义是基础,转换是工具,优势是为什么选它。你顺着这个脉络学,就不会迷路。
好了,四元数的基础就讲到这里。记住:多写代码,多调试,遇到问题别慌。我当年也是从一脸懵逼到逐渐通透的。
公众号:蓝海资料掘金营,微信deep3321