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 旋转表示法关系总览
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))的指数映射是当前主流方案。