第4章 旋转矩阵与欧拉角

码枢沄社 · 嵌入式体系化教程平台
入门 👤 刚接触机器人运动学的开发者 🔧 描述和计算机器人的旋转姿态
本章你将学到
  • 旋转矩阵的构成与物理意义
  • 欧拉角的三种常见定义与旋转顺序
  • 两种表示法的优缺点与适用场景
核心概念旋转矩阵欧拉角

想象一下,你手里拿着一个魔方,想描述它从初始状态旋转到了什么样子。你可以说“先向右转90度,再向上翻90度”——这就是欧拉角的思路。而旋转矩阵则像一张精确的“方向说明书”,告诉你魔方上每一个面的新朝向。在机器人导航中,我们需要用数学语言精确描述这种旋转。

4.1 旋转矩阵:三维空间的“方向说明书”

旋转矩阵是一个3x3的矩阵,它的核心思想是:一个坐标系相对于另一个坐标系的旋转,可以通过一个矩阵乘法来表示。这个矩阵的每一列,都代表了新坐标系的一个轴(X, Y, Z)在原坐标系下的方向余弦。

假设我们有一个世界坐标系 {W},一个机器人坐标系 {R}。{R}相对于{W}的旋转矩阵 R 满足一个关键性质:它将一个在{R}中表示的向量,变换到在{W}中表示。

关键点:旋转矩阵的每一列,就是旋转后新坐标系的X轴、Y轴、Z轴在原坐标系下的单位向量。因此,这个矩阵是正交矩阵,它的逆等于它的转置(R-1 = RT),且行列式为1。

4.2 旋转矩阵的构成与示例

让我们用一个具体的例子来构建旋转矩阵。考虑机器人绕世界坐标系的Z轴旋转了角度θ。旋转后,机器人自身的X轴和Y轴方向改变了,但Z轴方向不变。

世界坐标系 {W}
绕Z轴旋转θ
机器人坐标系 {R}
XW, YW, ZW
XR, YR, ZR

根据几何关系,我们可以写出旋转后{R}的各个轴在{W}下的坐标:

将这三个列向量组合起来,就得到了绕Z轴旋转的旋转矩阵:

// 绕Z轴旋转θ角的旋转矩阵 R_z(θ)
R_z(θ) = [ cosθ, -sinθ, 0;
           sinθ,  cosθ, 0;
           0,     0,    1 ]

同理,我们可以推导出绕X轴和Y轴旋转的基本旋转矩阵。这三个矩阵是构建所有复杂旋转的基础。

基本旋转矩阵(右手坐标系)
旋转轴旋转矩阵示意图(想象从轴正方向看向原点)
绕X轴旋转 αR_x(α) = [1, 0, 0; 0, cosα, -sinα; 0, sinα, cosα]Y轴转向Z轴
绕Y轴旋转 βR_y(β) = [cosβ, 0, sinβ; 0, 1, 0; -sinβ, 0, cosβ]Z轴转向X轴
绕Z轴旋转 γR_z(γ) = [cosγ, -sinγ, 0; sinγ, cosγ, 0; 0, 0, 1]X轴转向Y轴

常见误区

  • 混淆旋转方向:绕轴旋转的正方向遵循右手定则(右手握住旋转轴,拇指指向轴正方向,四指弯曲方向为正)。许多图形库(如OpenGL)使用左手坐标系,其旋转方向定义可能相反,实际开发中务必确认。
  • 矩阵乘法顺序不可交换:连续旋转时,矩阵乘法顺序至关重要。R = R_z * R_y * R_x 表示绕X轴,绕Y轴,最后绕Z轴旋转。顺序不同,结果完全不同。
  • 将旋转矩阵用于平移:旋转矩阵只能改变方向,不能改变位置。描述完整的位姿(位置+方向)需要用到齐次变换矩阵,这是另一个重要的概念。

4.3 欧拉角:直观的“转几下”描述法

如果说旋转矩阵是精确的“说明书”,那么欧拉角就是通俗的“口头指令”。它用三个连续的绕自身坐标轴的旋转角度来描述姿态,非常符合人类的直观想象。

欧拉角的核心在于旋转顺序。你不能只说“绕X、Y、Z轴分别转α、β、γ度”,必须明确先转哪个轴,再转哪个轴。最常见的顺序是ZYX(也常被称为“偏航-俯仰-滚转”,即yaw-pitch-roll)。

初始姿态
绕Z轴转 (偏航角)
Y轴转 (俯仰角)
最新X轴转 (滚转角)
最终姿态

在航空航天和移动机器人中,ZYX顺序被广泛使用:

无人机控制

  • 偏航:改变机头水平指向
  • 俯仰:控制前进/后退
  • 滚转:控制左右平移

地面机器人

  • 偏航:最重要的姿态角
  • 俯仰/滚转:通常很小,由路面不平引起

机械臂末端

  • 用欧拉角定义工具方向
  • 需与运动学模型定义的顺序一致

4.4 旋转矩阵与欧拉角的相互转换

在实际的机器人系统中,我们经常需要在旋转矩阵和欧拉角之间进行转换。传感器(如IMU)可能输出欧拉角,而运动学计算则需要使用旋转矩阵。

从欧拉角到旋转矩阵:根据指定的旋转顺序,将对应的基本旋转矩阵按顺序相乘。对于ZYX顺序(偏航ψ,俯仰θ,滚转φ):

R = R_z(ψ) * R_y(θ) * R_x(φ)
// 将三个基本矩阵代入并相乘,得到最终的3x3矩阵

从旋转矩阵到欧拉角:这个过程称为“提取”欧拉角,需要根据旋转矩阵的元素反解出角度。对于ZYX顺序,公式如下(假设cosθ ≠ 0):

θ = arcsin(-R[2,0]) // 俯仰角
ψ = atan2(R[1,0]/cosθ, R[0,0]/cosθ) // 偏航角
φ = atan2(R[2,1]/cosθ, R[2,2]/cosθ) // 滚转角

编者提示:在从旋转矩阵提取欧拉角时,要特别注意万向节死锁问题。当俯仰角θ为±90度时,cosθ=0,上述公式中的分母为零,偏航角ψ和滚转角φ失去唯一解(它们的变化效果相同)。这是欧拉角表示法的固有缺陷。在实际编程中,调用数学库函数(如scipy.spatial.transform.Rotation或Eigen库的转换函数)时,这些库通常会处理死锁情况,返回一个合理的解,但你需要意识到此时姿态信息有损失。

4.5 如何选择:旋转矩阵 vs. 欧拉角

两种表示法各有优劣,没有绝对的好坏,只有适合的场景。

旋转矩阵与欧拉角对比
特性旋转矩阵欧拉角
直观性差,难以直接理解姿态极好,三个角度一目了然
唯一性唯一(特殊正交矩阵)不唯一(存在多解和万向节死锁)
计算矩阵乘法,计算量稍大(9个数)角度计算,简单快速(3个数)
插值不能直接对矩阵元素插值可直接对角插值,但路径可能不自然
适用场景连续变换、复合旋转、理论推导姿态显示、简单控制指令、传感器原始数据

我在一个机械臂项目中踩过坑:上位机界面用欧拉角让用户设置末端姿态,而下位机运动学求解器使用旋转矩阵。由于没有统一约定旋转顺序(是ZYX还是XYZ?),导致设置的角度和实际运动方向对不上。最后我们强制规定整个项目全部使用ZYX顺序,并在所有接口文档中明确标注,问题才得以解决。

动手试一试

假设一个机器人初始朝向与世界坐标系一致。现在它执行了以下动作:先绕自身Z轴(偏航)旋转30度,再绕新的Y轴(俯仰)旋转45度,最后绕最新的X轴(滚转)旋转60度(ZYX顺序)。

  1. 手动计算或编写一小段程序(可使用Python的NumPy或任何数学库),计算这个复合旋转的最终旋转矩阵。
  2. 从你得到的旋转矩阵中,尝试用公式反解出三个欧拉角,看看是否与你输入的30°, 45°, 60°一致。
  3. (进阶)修改旋转顺序为XYZ,重复步骤1,观察得到的旋转矩阵是否与ZYX顺序相同。思考为什么。

这个练习能让你深刻理解旋转顺序的重要性以及矩阵乘法的不可交换性。

检验你的理解

  1. 判断题:一个旋转矩阵的行列式值总是等于1。
  2. 判断题:欧拉角的三次旋转都是绕固定不动的世界坐标轴进行的。
  3. 选择题:在ZYX欧拉角顺序中,当俯仰角为90度时,会出现什么问题?
    • A. 旋转矩阵无法计算
    • B. 偏航角和滚转角无法被唯一确定(万向节死锁)
    • C. 欧拉角表示失效,必须改用旋转矩阵

本章小结

  • 旋转矩阵是一个3x3的正交矩阵,其列向量是旋转后坐标轴在原坐标系下的方向。它描述旋转精确且唯一,适合连续计算和复合变换。
  • 欧拉角用三个绕特定顺序的坐标轴旋转的角度直观描述姿态,最常用的是ZYX(偏航-俯仰-滚转)顺序。
  • 两者可以相互转换,但从旋转矩阵提取欧拉角时需注意万向节死锁问题,即当中间旋转角为±90度时,解不唯一。
  • 选择依据:欧拉角用于人机交互和直观显示旋转矩阵用于内部精确计算和变换合成。实际开发中必须明确并统一旋转顺序。
  • 基本旋转矩阵(绕X、Y、Z轴)是构建更复杂旋转的基石。
← 上一章 返回目录 下一章 →