4. 旋转表示法:欧拉角、旋转向量(轴角)、四元数的定义、相互转换及在机器人中的应用

在机器人视觉与点云配准中,三维旋转的表示方式直接影响标定精度、计算效率与算法稳定性。本章系统梳理三种最常用的旋转表示法——欧拉角、旋转向量(轴角)、四元数,涵盖其数学定义、核心特性、相互转换公式以及在 Eye-to-Hand 标定与点云配准中的典型应用场景。

核心认知:没有一种旋转表示法在所有场景中都是最优的。欧拉角直观但存在万向锁;旋转向量紧凑且适合插值;四元数无奇异性且计算高效。实际工程中常根据任务阶段切换使用。

4.1 欧拉角(Euler Angles)

4.1.1 定义与约定

欧拉角通过三个依次绕坐标轴旋转的角度来描述刚体姿态。最常见的约定是 ZYX 顺序(偏航-俯仰-横滚):

  • 偏航角(Yaw, ψ):绕 Z 轴旋转
  • 俯仰角(Pitch, θ):绕 Y 轴旋转
  • 横滚角(Roll, φ):绕 X 轴旋转

旋转矩阵 R 由三个基本旋转矩阵按顺序右乘得到:

R = R_z(ψ) · R_y(θ) · R_x(φ)

4.1.2 万向锁(Gimbal Lock)

当俯仰角 θ = ±90° 时,偏航与横滚的旋转轴重合,导致系统丢失一个自由度。这是欧拉角在机器人控制与标定中的主要缺陷。

工程警示:在 Eye-to-Hand 标定中,若机械臂末端姿态接近万向锁区域,欧拉角表示的微小变化可能导致旋转矩阵剧烈跳变,应优先使用四元数或旋转向量进行优化求解。

4.2 旋转向量(轴角,Axis-Angle)

4.2.1 定义

旋转向量用一个单位向量 k 表示旋转轴,用一个标量 θ 表示绕该轴的旋转角度。其数学形式为:

旋转向量 = θ · k = [θ·k_x, θ·k_y, θ·k_z]^T

其中 ||k|| = 1,θ ∈ [0, π]。

4.2.2 罗德里格斯公式(Rodrigues' Formula)

旋转向量到旋转矩阵的转换由罗德里格斯公式给出:

R = I + sin(θ) · K + (1 - cos(θ)) · K²

其中 K 为 k 的反对称矩阵:
K = [[0,   -k_z,  k_y],
     [k_z,  0,   -k_x],
     [-k_y, k_x,  0  ]]

4.3 四元数(Quaternion)

4.3.1 定义

四元数由一个实部和三个虚部构成,用于表示三维旋转:

q = w + x·i + y·j + z·k

其中 w² + x² + y² + z² = 1(单位四元数)

单位四元数与旋转向量之间存在直接对应关系:

q = [cos(θ/2), k_x·sin(θ/2), k_y·sin(θ/2), k_z·sin(θ/2)]^T

4.3.2 四元数的优势

  • 无奇异性:不存在万向锁问题
  • 紧凑:仅需 4 个参数,比旋转矩阵(9 个)更节省存储
  • 高效插值:球面线性插值(SLERP)可实现平滑旋转过渡
  • 复合运算:旋转复合通过四元数乘法实现,计算效率高

4.4 三种表示法的相互转换

转换方向 核心公式 / 方法 注意事项
欧拉角 → 旋转矩阵 R = R_z(ψ)·R_y(θ)·R_x(φ) 需明确旋转顺序(ZYX 最常用)
旋转矩阵 → 欧拉角 θ = asin(-R[2][0])
ψ = atan2(R[1][0], R[0][0])
φ = atan2(R[2][1], R[2][2])
θ = ±90° 时出现万向锁,需特殊处理
旋转向量 → 旋转矩阵 罗德里格斯公式 θ = 0 时需单独处理(R = I)
旋转矩阵 → 旋转向量 θ = arccos((tr(R)-1)/2)
k = (1/(2sinθ))·[R[2][1]-R[1][2], ...]
θ 接近 0 或 π 时数值不稳定
旋转向量 → 四元数 q = [cos(θ/2), k·sin(θ/2)] 直接对应,无奇异性
四元数 → 旋转矩阵 R = 2·[q_w²+q_x²-0.5, q_x·q_y-q_w·q_z, ...] 需确保四元数已归一化
四元数 → 欧拉角 先转旋转矩阵,再提取欧拉角 避免直接公式,防止万向锁传播
工程建议:在 Eye-to-Hand 标定代码中,建议统一使用四元数作为内部存储格式,仅在用户交互界面或调试输出时转换为欧拉角。这样既能避免万向锁,又能保持直观性。

4.5 在机器人中的应用对比

应用场景 推荐表示法 原因
机械臂示教与手动控制 欧拉角 直观,操作员容易理解偏航/俯仰/横滚
Eye-to-Hand 标定优化 四元数 无奇异性,适合非线性最小二乘优化
点云配准(ICP 变体) 旋转向量 参数少,适合流形优化(如 Lie 代数)
姿态插值与轨迹平滑 四元数 SLERP 插值平滑,无万向锁问题
旋转矩阵运算 旋转矩阵 点变换最直接,适合 GPU 并行计算

4.6 旋转表示法关系总览

旋转表示法关系总览 三维旋转 欧拉角 (ZYX) 旋转向量 (轴角) 四元数 直观易理解 存在万向锁 适合人机交互 紧凑 (3参数) 适合流形优化 θ=0/π 数值敏感 无奇异性 SLERP插值平滑 标定优化首选 Rodrigues 指数/对数 欧拉角 ↔ 四元数:通过旋转矩阵中转 典型应用场景 机械臂示教 欧拉角 Eye-to-Hand标定 四元数 点云配准 旋转向量 轨迹插值 四元数SLERP

4.7 代码示例:四元数与旋转向量互转(Python)

import numpy as np

def rotation_vector_to_quaternion(rot_vec):
    """旋转向量 → 四元数"""
    theta = np.linalg.norm(rot_vec)
    if theta < 1e-10:
        return np.array([1.0, 0.0, 0.0, 0.0])
    k = rot_vec / theta
    q = np.array([
        np.cos(theta / 2),
        k[0] * np.sin(theta / 2),
        k[1] * np.sin(theta / 2),
        k[2] * np.sin(theta / 2)
    ])
    return q

def quaternion_to_rotation_vector(q):
    """四元数 → 旋转向量"""
    q = q / np.linalg.norm(q)  # 归一化
    theta = 2 * np.arccos(np.clip(q[0], -1.0, 1.0))
    if theta < 1e-10:
        return np.array([0.0, 0.0, 0.0])
    k = q[1:] / np.sin(theta / 2)
    return theta * k

# 示例:绕 Z 轴旋转 90 度
rot_vec = np.array([0.0, 0.0, np.pi/2])
q = rotation_vector_to_quaternion(rot_vec)
print("四元数:", q)
# 输出: [0.7071, 0, 0, 0.7071]

rot_vec_back = quaternion_to_rotation_vector(q)
print("恢复旋转向量:", rot_vec_back)
# 输出: [0, 0, 1.5708]
关键提醒:在 Eye-to-Hand 标定中,旋转表示法的选择直接影响优化收敛速度。推荐使用四元数作为优化变量,并在每次迭代后归一化以保证单位约束。对于点云配准中的姿态初值估计,旋转向量配合 Lie 代数(so(3))的指数映射是当前主流方案。