### 旋转矩阵与欧拉角的数学关系及转换方法
#### 数学关系概述
旋转矩阵是一种用于描述三维空间中物体姿态的工具,它是一个正交矩阵 \( R \in SO(3) \),满足 \( R^T R = I \) 和 \( \det(R) = 1 \)[^1]。而欧拉角则通过三个角度 (roll, pitch, yaw 或者 rpy 角) 来表示这种旋转。
对于给定的旋转顺序 XYZ(即 roll-pitch-yaw),对应的旋转矩阵可以通过基元旋转矩阵相乘得到:
\[
R_{xyz}(\phi,\theta,\psi) = R_x(\phi) R_y(\theta) R_z(\psi)
\]
其中,
- \( R_x(\phi) \) 是围绕 X 轴旋转的角度为 \( \phi \) 的基元旋转矩阵;
- \( R_y(\theta) \) 是围绕 Y 轴旋转的角度为 \( \theta \) 的基元旋转矩阵;
- \( R_z(\psi) \) 是围绕 Z 轴旋转的角度为 \( \psi \) 的基元旋转矩阵[^2]。
具体形式如下:
\[
R_x(\phi) =
\begin{bmatrix}
1 & 0 & 0 \\
0 & \cos\phi & -\sin\phi \\
0 & \sin\phi & \cos\phi
\end{bmatrix},
R_y(\theta) =
\begin{bmatrix}
\cos\theta & 0 & \sin\theta \\
0 & 1 & 0 \\
-\sin\theta & 0 & \cos\theta
\end{bmatrix},
R_z(\psi) =
\begin{bmatrix}
\cos\psi & -\sin\psi & 0 \\
\sin\psi & \cos\psi & 0 \\
0 & 0 & 1
\end{bmatrix}.
\]
因此,完整的旋转矩阵可写成:
\[
R_{xyz}(\phi,\theta,\psi) =
\begin{bmatrix}
c_\theta c_\psi & c_\theta s_\psi & -s_\theta \\
-s_\phi s_\theta c_\psi - c_\phi s_\psi & -s_\phi s_\theta s_\psi + c_\phi c_\psi & s_\phi c_\theta \\
c_\phi s_\theta c_\psi - s_\phi s_\psi & c_\phi s_\theta s_\psi + s_\phi c_\psi & c_\phi c_\theta
\end{bmatrix},
\]
这里使用了缩写 \( c_\alpha = \cos\alpha \), \( s_\alpha = \sin\alpha \).
#### 欧拉角到旋转矩阵的转换公式
已知欧拉角 \( [\phi, \theta, \psi]^T \),可以直接代入上述公式计算旋转矩阵 \( R \)。需要注意的是,不同的旋转顺序会导致不同的旋转矩阵表达式[^3]。
#### 旋转矩阵到欧拉角的反求解
如果给出一个旋转矩阵 \( R \),要提取出相应的欧拉角,则需逆向操作。假设采用 XYZ 序列,有以下解析公式:
当 \( |R_{31}| \neq 1 \) (避免奇异性)时:
\[
\theta = -\arcsin(R_{31}),
\quad \phi = \arctan2(R_{32}/\cos\theta, R_{33}/\cos\theta),
\quad \psi = \arctan2(R_{21}/\cos\theta, R_{11}/\cos\theta).
\]
特殊情况处理:当 \( R_{31} = \pm 1 \) 表明发生了 **万向锁** 现象,在此情况下某些自由度丢失,通常需要额外设定约束条件来解决歧义。
#### 工程中的应用实例
在机器人控制领域,利用欧拉角简化复杂的空间变换过程;而在计算机图形学里,借助旋转矩阵实现对象的姿态调整。两者互换频繁发生于实际项目开发阶段。
```python
import numpy as np
def euler_to_rotation_matrix(phi, theta, psi):
"""
Convert Euler angles to rotation matrix.
Parameters:
phi : float
Roll angle in radians around the x-axis.
theta : float
Pitch angle in radians around the y-axis.
psi : float
Yaw angle in radians around the z-axis.
Returns:
R_xyz : ndarray
Rotation matrix corresponding to given Euler angles.
"""
cx, sx = np.cos(phi), np.sin(phi)
cy, sy = np.cos(theta), np.sin(theta)
cz, sz = np.cos(psi), np.sin(psi)
Rx = np.array([[1, 0, 0], [0, cx, -sx], [0, sx, cx]])
Ry = np.array([[cy, 0, sy], [0, 1, 0], [-sy, 0, cy]])
Rz = np.array([[cz, -sz, 0], [sz, cz, 0], [0, 0, 1]])
return Rz @ Ry @ Rx
def rotation_matrix_to_euler(R):
"""
Extract Euler angles from a rotation matrix assuming xyz order.
Parameters:
R : array-like shape=(3,3)
The input rotation matrix.
Returns:
phi, theta, psi : floats
Corresponding Euler angles in radians.
"""
if abs(R[2, 0]) != 1:
theta = -np.arcsin(R[2, 0])
cos_theta = np.cos(theta)
phi = np.arctan2(R[2, 1]/cos_theta, R[2, 2]/cos_theta)
psi = np.arctan2(R[1, 0]/cos_theta, R[0, 0]/cos_theta)
else:
raise ValueError("Gimbal lock detected.")
return phi, theta, psi
```