运动学基础(一):刚体运动描述、旋转矩阵、欧拉角与四元数

各位同学,欢迎来到《人形机器人动态轨迹平衡术》的第二讲。

今天我们要聊的,是运动学里最基础、也最绕不开的一块硬骨头——刚体运动描述。说白了,就是怎么用数学语言告诉机器人:「你的脑袋现在朝哪边歪?你的手臂转了多少度?」

我个人习惯把这一讲称为「坐标系的语言课」。你想想看,人形机器人全身几十个关节,每个关节都有自己的小脾气(坐标系)。如果连怎么描述它们之间的相对关系都搞不清楚,后面谈轨迹规划、动态平衡,那都是空中楼阁。

核心认知:刚体在三维空间中的运动 = 平移 + 旋转。平移很简单,就是三个坐标值。真正让人头疼的,是旋转。

1. 旋转矩阵:最直观,但最啰嗦

旋转矩阵,我刚开始学的时候觉得它很友好。3x3的矩阵,每一列代表一个坐标轴在参考系里的投影。你用它左乘一个向量,就能把向量转到新的坐标系里。

举个例子,绕Z轴转θ角,旋转矩阵长这样:

R_z(θ) = [cosθ  -sinθ  0]
         [sinθ   cosθ  0]
         [0      0     1]

嗯,看起来挺规整的。但我在项目中遇到过一个问题:旋转矩阵有9个元素,但自由度只有3个。这意味着什么?意味着你每次更新矩阵,都得小心翼翼地保证它满足正交性(R^T R = I)和行列式为+1。否则,你的机器人模型会「扭曲」,仿真直接崩掉。

我的小技巧:在实际代码里,我很少直接操作旋转矩阵的9个元素。要么用库函数(比如Eigen、numpy的scipy.spatial.transform),要么用其他参数化方式。手动维护9个数的正交性,太容易出bug了。

2. 欧拉角:直观,但小心「万向锁」

欧拉角就亲民多了。三个角度:偏航(Yaw)、俯仰(Pitch)、滚转(Roll)。你想想看,描述一架飞机的姿态,说「机头偏左30度,抬头15度,机身倾斜10度」,多直观。

但这里有个大坑——万向锁。

为什么会这样?因为欧拉角的旋转顺序是固定的(比如ZYX顺序)。当中间的那个角度(俯仰)达到±90度时,第一个和第三个旋转轴会重合,导致丢失一个自由度。这时候,你无论怎么调偏航和滚转,效果都一样。

我曾经在一个机械臂的逆解项目里踩过这个坑。当时用欧拉角做插值,结果在某个奇异点附近,机械臂突然「抽搐」了一下,差点撞到旁边的设备。从那以后,我只要涉及连续旋转的插值,一律不用欧拉角。

避坑指南:欧拉角适合做人机交互的输入(比如操作员说「偏航5度」),也适合做姿态的直观显示。但千万别用它做内部连续旋转的计算,尤其是插值和微分。

3. 四元数:低调的王者

四元数,说实话我第一次看到它时觉得挺玄乎的。一个标量加上三个虚部,q = w + xi + yj + zk,这玩意儿能描述旋转?

但用久了你会发现,它简直是工程界的福音。

  • 无万向锁:这是最大的优势。随便你怎么转,不会丢自由度。
  • 插值平滑:用球面线性插值(SLERP),可以生成非常平滑的旋转过渡。人形机器人走路时,髋关节和踝关节的姿态变化,用四元数插值效果远好于欧拉角。
  • 计算高效:组合两个旋转,四元数乘法只需要4个分量运算,比旋转矩阵的9个分量快不少。

我记得有一次做双足机器人的步态规划,需要在两个关键帧之间插值出20个中间姿态。用欧拉角插出来,脚掌的轨迹歪歪扭扭的;换成四元数SLERP,轨迹平滑得像丝绸一样。嗯,从那以后我就成了四元数的忠实用户。

四元数旋转的公式也很简洁:

v' = q * v * q_conj

其中v是三维向量(写成纯四元数形式),q是单位四元数,q_conj是它的共轭。就这么简单。

重要提醒:四元数一定要归一化!数值误差会让它慢慢偏离单位长度,导致旋转变形。我习惯在每个控制周期末尾都做一次归一化,养成习惯。

4. 三种表示方法的对比

特性 旋转矩阵 欧拉角 四元数
参数数量 9 3 4
直观性 低 高 低
万向锁 无 有 无
插值平滑性 一般 差 好
计算效率 低 高 高
工程常用场景 坐标变换、雅可比矩阵 人机交互、姿态显示 姿态控制、插值、滤波

5. 知识体系结构图

下面这张图,是我自己梳理的本章知识脉络。你可以把它当作一张地图,随时回来对照。

刚体运动描述 平移 (x, y, z) 旋转 (3自由度) 旋转矩阵 (9参数) 欧拉角 (3参数) 四元数 (4参数) 关键特性 • 刚体 = 形状不变 • 运动 = 平移 + 旋转 • 坐标系是根本 工程选择:四元数 > 旋转矩阵 > 欧拉角(内部计算)

6. 工程中的选择建议

说了这么多,到底该用哪个?我个人的经验是:

  • 做底层控制、状态估计、滤波:用四元数。IMU的数据出来就是四元数,卡尔曼滤波里也用四元数做状态量。别折腾,直接上。
  • 做运动学正解、雅可比矩阵:用旋转矩阵。因为矩阵形式方便求导,链式法则用起来顺手。
  • 做人机交互界面、调试显示:用欧拉角。给操作员看三个角度,比看四个数或者9个数直观得多。

我的习惯:在代码内部,所有旋转计算都用四元数。只在输入输出接口处,转换成欧拉角或旋转矩阵。这样既保证了计算的鲁棒性,又兼顾了可读性。

好了,这一讲的内容就到这里。刚体运动的描述是后续所有运动学、动力学分析的基础。你想想看,如果连「机器人脚底相对于地面的姿态」都描述不清楚,那平衡控制根本无从谈起。嗯,把这些基础打牢,后面我们会越来越有意思。

可可精品资料库