旋转矩阵转欧拉角(二自由度约束)

本文详细介绍了欧拉角与旋转矩阵之间的转换方法,包括由欧拉角构造旋转矩阵和由旋转矩阵推算欧拉角的过程。特别针对滚转角始终为0的应用场景进行了深入探讨,并给出了相应的C++实现代码。

在我的应用场景中有一个角度始终为0,添加这个约束后就不用考虑欧拉角奇异性问题。借此机会自己推导了一下公式,梳理一下欧拉角和旋转矩阵之间的变换关系。

1 关于欧拉角

参考文章:

  1. 欧拉角与旋转矩阵的转换关系
  2. 三维旋转:欧拉角、四元数、旋转矩阵、轴角之间的转换
  3. 欧拉角与旋转矩阵之间的转化公式及原理
  4. 无人机飞控算法-姿态估计-欧拉角-旋转矩阵-四元数

需要注意的是,由于欧拉角和旋转矩阵之间的转换关系跟很多因素有关,如各轴旋转角定义、欧拉角顺规、手性定义、参考坐标系等,因此讨论之前需要先明确定义。

本文讨论的内容约束如下:右手系、ZYX顺规(Z-Yaw,X-Roll,Y-Pitch)、内在旋转、主动旋转,也即参考文章【4】中的NED_Z-Y-X_Euler_Angles

2 转换公式推导

2.1 由欧拉角构造旋转矩阵

欧拉角构造旋转矩阵直接将三个基础旋转矩阵按顺序相乘即可:
R ( Z 1 Y 2 X 3 ) = [ c 1 − s 1 0 s 1 c 1 0 0 0 1 ] [ c 2 0 s 2 0 1 0 − s 2 0 c 2 ] [ 1 0 0 0 c 3 − s 3 0 s 3 c 3 ] = [ c 1 c 2 c 1 s 2 s 3 − c 3 s 1 s 1 s 3 + c 1 c 3 s 2 c 2 s 1 c 1 c 3 + s 1 s 2 s 3 c 3 s 1 s 2 − c 1 s 3 − s 2 c 2 s 3 c 2 c 3 ] R(Z_1Y_2X_3) =\begin{bmatrix} c_1 & -s_1 & 0 \\ s_1 & c_1 & 0\\ 0 & 0 &1 \end{bmatrix} \quad \begin{bmatrix} c_2 & 0 & s_2 \\ 0 &1 &0\\ -s_2 & 0 & c_2\end{bmatrix} \quad \begin{bmatrix}1 &0 &0\\ 0 &c_3 & -s_3 \\ 0 & s_3 & c_3\end{bmatrix} \quad\\ =\begin{bmatrix}c_1c_2 &c_1s_2s_3-c_3s_1 &s_1s_3+c_1c_3s_2 \\ c_2s_1 &c_1c_3+s_1s_2s_3 & c_3s_1s_2-c_1s_3 \\ -s_2 & c_2s_3 & c_2c_3\end{bmatrix} \quad RZ1Y2X3=c1s10s1c10001c20s2010s20c21000c3s30s3c3=

<think>首先,用户的问题是关于坐标系换的:原Z轴变为X轴负方向,原X轴变为Y轴负方向。需要计算对应的旋转矩阵欧拉角。 关键点: - 原坐标系:假设标准右手坐标系,X向右,Y向上,Z向外(或根据上下文)。 - 新坐标系:原Z轴变为新X轴的负方向,所以新X轴 = -旧Z轴。 - 原X轴变为新Y轴的负方向,所以新Y轴 = -旧X轴。 现在,我需要找到旋转矩阵,该矩阵将旧坐标系的点换到新坐标系。 定义旧坐标系基向量: - $\hat{\mathbf{x}}_o = [1, 0, 0]^T$ - $\hat{\mathbf{y}}_o = [0, 1, 0]^T$ - $\hat{\mathbf{z}}_o = [0, 0, 1]^T$ 新坐标系基向量: - 新X轴:原Z轴变为X轴负方向,所以 $\hat{\mathbf{x}}_n = -\hat{\mathbf{z}}_o = [0, 0, -1]^T$ - 新Y轴:原X轴变为Y轴负方向,所以 $\hat{\mathbf{y}}_n = -\hat{\mathbf{x}}_o = [-1, 0, 0]^T$ - 新Z轴:需要确定。由于是右手坐标系,新Z轴应该由新X和新Y的叉积得到:$\hat{\mathbf{z}}_n = \hat{\mathbf{x}}_n \times \hat{\mathbf{y}}_n$ 计算叉积: $\hat{\mathbf{x}}_n = [0, 0, -1]^T$ $\hat{\mathbf{y}}_n = [-1, 0, 0]^T$ $\hat{\mathbf{z}}_n = \hat{\mathbf{x}}_n \times \hat{\mathbf{y}}_n = \begin{vmatrix} \mathbf{i} & \mathbf{j} & \mathbf{k} \\ 0 & 0 & -1 \\ -1 & 0 & 0 \end{vmatrix} = \mathbf{i}(0 \cdot 0 - (-1) \cdot 0) - \mathbf{j}(0 \cdot 0 - (-1) \cdot (-1)) + \mathbf{k}(0 \cdot 0 - 0 \cdot (-1)) = \mathbf{i}(0) - \mathbf{j}(0 - 1) + \mathbf{k}(0) = [0, 1, 0]^T$ 所以 $\hat{\mathbf{z}}_n = [0, 1, 0]^T$,这正好是旧Y轴方向。 因此,新坐标系基向量在旧坐标系中的表示: - $\hat{\mathbf{x}}_n = [0, 0, -1]^T$ - $\hat{\mathbf{y}}_n = [-1, 0, 0]^T$ - $\hat{\mathbf{z}}_n = [0, 1, 0]^T$ 旋转矩阵 $R$ 将旧坐标系的点换到新坐标系。通常,旋转矩阵的列是新坐标系基向量在旧坐标系中的坐标。 所以,$R = \begin{bmatrix} \hat{\mathbf{x}}_n & \hat{\mathbf{y}}_n & \hat{\mathbf{z}}_n \end{bmatrix} = \begin{bmatrix} 0 & -1 & 0 \\ 0 & 0 & 1 \\ -1 & 0 & 0 \end{bmatrix}$ 验证:一个点在旧坐标系中的坐标 $\mathbf{p}_o = [p_x, p_y, p_z]^T$,在新坐标系中的坐标 $\mathbf{p}_n = R^T \mathbf{p}_o$,因为旋转矩阵是正交的,逆等于置。 标准定义:如果旋转矩阵 $R$ 的列是新轴在旧系中的方向,那么从旧系到新系的变换是 $\mathbf{p}_n = R^{-1} \mathbf{p}_o = R^T \mathbf{p}_o$。 所以这里 $R = \begin{bmatrix} 0 & -1 & 0 \\ 0 & 0 & 1 \\ -1 & 0 & 0 \end{bmatrix}$,那么 $R^T = \begin{bmatrix} 0 & 0 & -1 \\ -1 & 0 & 0 \\ 0 & 1 & 0 \end{bmatrix}$ 应用:旧点 $\mathbf{p}_o = [p_x, p_y, p_z]^T$,新点 $\mathbf{p}_n = R^T \mathbf{p}_o = \begin{bmatrix} 0 & 0 & -1 \\ -1 & 0 & 0 \\ 0 & 1 & 0 \end{bmatrix} \begin{bmatrix} p_x \\ p_y \\ p_z \end{bmatrix} = \begin{bmatrix} -p_z \\ -p_x \\ p_y \end{bmatrix}$ 检查: - 新X轴:原Z轴负方向,所以新X坐标应该与旧Z负相关,正确:$p_{n,x} = -p_z$ - 新Y轴:原X轴负方向,所以新Y坐标应该与旧X负相关,正确:$p_{n,y} = -p_x$ - 新Z轴:原Y轴方向,所以新Z坐标应该与旧Y相同,正确:$p_{n,z} = p_y$ 完美。 现在,旋转矩阵是 $R = \begin{bmatrix} 0 & -1 & 0 \\ 0 & 0 & 1 \\ -1 & 0 & 0 \end{bmatrix}$ 接下来,需要找到欧拉角。用户提到参考了万向锁的问题,所以需要指定旋转顺序。 用户说:“参考站内引用:引用[1]:旋转矩阵欧拉角。假设我们按照z-y-x的顺序对物体进行旋转...” 所以,可能使用z-y-x顺序,即先绕z轴,然后y轴,然后x轴旋转欧拉角通常有多个约定,这里指定z-y-x顺序,类似于Tait-Bryan角,常用在航空航天中。 设旋转顺序为:先绕Z轴旋转yaw角$\psi$,然后绕Y轴旋转pitch角$\theta$,然后绕X轴旋转roll角$\phi$。 那么,旋转矩阵可以表示为: $$R = R_z(\psi) R_y(\theta) R_x(\phi)$$ 其中: $$R_z(\psi) = \begin{bmatrix} \cos\psi & -\sin\psi & 0 \\ \sin\psi & \cos\psi & 0 \\ 0 & 0 & 1 \end{bmatrix}$$ $$R_y(\theta) = \begin{bmatrix} \cos\theta & 0 & \sin\theta \\ 0 & 1 & 0 \\ -\sin\theta & 0 & \cos\theta \end{bmatrix}$$ $$R_x(\phi) = \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos\phi & -\sin\phi \\ 0 & \sin\phi & \cos\phi \end{bmatrix}$$ 所以,乘积: $$R = R_z(\psi) R_y(\theta) R_x(\phi) = \begin{bmatrix} \cos\psi & -\sin\psi & 0 \\ \sin\psi & \cos\psi & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} \cos\theta & 0 & \sin\theta \\ 0 & 1 & 0 \\ -\sin\theta & 0 & \cos\theta \end{bmatrix} \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos\phi & -\sin\phi \\ 0 & \sin\phi & \cos\phi \end{bmatrix}$$ 先计算 $R_{yz} = R_y(\theta) R_x(\phi)$,然后 $R = R_z(\psi) R_{yz}$,但最好直接计算整个乘积。 计算: 首先,$R_{yz} = R_y(\theta) R_x(\phi) = \begin{bmatrix} \cos\theta & 0 & \sin\theta \\ 0 & 1 & 0 \\ -\sin\theta & 0 & \cos\theta \end{bmatrix} \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos\phi & -\sin\phi \\ 0 & \sin\phi & \cos\phi \end{bmatrix} = \begin{bmatrix} \cos\theta \cdot 1 + 0 \cdot 0 + \sin\theta \cdot 0 & \cos\theta \cdot 0 + 0 \cdot \cos\phi + \sin\theta \cdot \sin\phi & \cos\theta \cdot 0 + 0 \cdot (-\sin\phi) + \sin\theta \cdot \cos\phi \\ 0 \cdot 1 + 1 \cdot 0 + 0 \cdot 0 & 0 \cdot 0 + 1 \cdot \cos\phi + 0 \cdot \sin\phi & 0 \cdot 0 + 1 \cdot (-\sin\phi) + 0 \cdot \cos\phi \\ -\sin\theta \cdot 1 + 0 \cdot 0 + \cos\theta \cdot 0 & -\sin\theta \cdot 0 + 0 \cdot \cos\phi + \cos\theta \cdot \sin\phi & -\sin\theta \cdot 0 + 0 \cdot (-\sin\phi) + \cos\theta \cdot \cos\phi \end{bmatrix}$ 简化: $$R_{yz} = \begin{bmatrix} \cos\theta & \sin\theta \sin\phi & \sin\theta \cos\phi \\ 0 & \cos\phi & -\sin\phi \\ -\sin\theta & \cos\theta \sin\phi & \cos\theta \cos\phi \end{bmatrix}$$ 现在,$R = R_z(\psi) R_{yz} = \begin{bmatrix} \cos\psi & -\sin\psi & 0 \\ \sin\psi & \cos\psi & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} \cos\theta & \sin\theta \sin\phi & \sin\theta \cos\phi \\ 0 & \cos\phi & -\sin\phi \\ -\sin\theta & \cos\theta \sin\phi & \cos\theta \cos\phi \end{bmatrix}$ 计算每个元素: - (1,1): $\cos\psi \cdot \cos\theta + (-\sin\psi) \cdot 0 + 0 \cdot (-\sin\theta) = \cos\psi \cos\theta$ - (1,2): $\cos\psi \cdot (\sin\theta \sin\phi) + (-\sin\psi) \cdot \cos\phi + 0 \cdot (\cos\theta \sin\phi) = \cos\psi \sin\theta \sin\phi - \sin\psi \cos\phi$ - (1,3): $\cos\psi \cdot (\sin\theta \cos\phi) + (-\sin\psi) \cdot (-\sin\phi) + 0 \cdot (\cos\theta \cos\phi) = \cos\psi \sin\theta \cos\phi + \sin\psi \sin\phi$ - (2,1): $\sin\psi \cdot \cos\theta + \cos\psi \cdot 0 + 0 \cdot (-\sin\theta) = \sin\psi \cos\theta$ - (2,2): $\sin\psi \cdot (\sin\theta \sin\phi) + \cos\psi \cdot \cos\phi + 0 \cdot (\cos\theta \sin\phi) = \sin\psi \sin\theta \sin\phi + \cos\psi \cos\phi$ - (2,3): $\sin\psi \cdot (\sin\theta \cos\phi) + \cos\psi \cdot (-\sin\phi) + 0 \cdot (\cos\theta \cos\phi) = \sin\psi \sin\theta \cos\phi - \cos\psi \sin\phi$ - (3,1): $0 \cdot \cos\theta + 0 \cdot 0 + 1 \cdot (-\sin\theta) = -\sin\theta$ - (3,2): $0 \cdot (\sin\theta \sin\phi) + 0 \cdot \cos\phi + 1 \cdot (\cos\theta \sin\phi) = \cos\theta \sin\phi$ - (3,3): $0 \cdot (\sin\theta \cos\phi) + 0 \cdot (-\sin\phi) + 1 \cdot (\cos\theta \cos\phi) = \cos\theta \cos\phi$ 所以,整体旋转矩阵: $$R = \begin{bmatrix} \cos\psi \cos\theta & \cos\psi \sin\theta \sin\phi - \sin\psi \cos\phi & \cos\psi \sin\theta \cos\phi + \sin\psi \sin\phi \\ \sin\psi \cos\theta & \sin\psi \sin\theta \sin\phi + \cos\psi \cos\phi & \sin\psi \sin\theta \cos\phi - \cos\psi \sin\phi \\ -\sin\theta & \cos\theta \sin\phi & \cos\theta \cos\phi \end{bmatrix}$$ 现在,我们有给定的旋转矩阵: $$R = \begin{bmatrix} 0 & -1 & 0 \\ 0 & 0 & 1 \\ -1 & 0 & 0 \end{bmatrix}$$ 比较元素,找出 $\psi, \theta, \phi$。 看(3,1)元素:$-\sin\theta = -1$,因为给定矩阵(3,1)是-1。 所以 $-\sin\theta = -1 \Rightarrow \sin\theta = 1 \Rightarrow \theta = \frac{\pi}{2} + 2k\pi$,但通常欧拉角范围 $\theta \in [-\pi/2, \pi/2]$ 或类似,这里 $\sin\theta=1$,所以 $\theta = \frac{\pi}{2}$。 现在,看(1,1)元素:$\cos\psi \cos\theta = 0$ 由于 $\theta = \frac{\pi}{2}$,$\cos\theta = 0$,所以 $\cos\psi \cdot 0 = 0$,总是成立,不约束 $\psi$。 类似,(2,1)元素:$\sin\psi \cos\theta = \sin\psi \cdot 0 = 0$,给定是0,也总是成立。 现在,看(3,2)元素:$\cos\theta \sin\phi = 0 \cdot \sin\phi = 0$,给定是0,成立。 (3,3)元素:$\cos\theta \cos\phi = 0 \cdot \cos\phi = 0$,但给定矩阵(3,3)是0,成立。 现在,问题在(1,2)(1,3)等。 给定(1,2)是-1,(1,3)是0。 当 $\theta = \frac{\pi}{2}$,$\sin\theta =1$,$\cos\theta=0$。 代入公式: (1,2): $\cos\psi \sin\theta \sin\phi - \sin\psi \cos\phi = \cos\psi \cdot 1 \cdot \sin\phi - \sin\psi \cos\phi = \cos\psi \sin\phi - \sin\psi \cos\phi = \sin(\phi - \psi)$ 或类似。 标准三角恒等式:$a \sin\phi - b \cos\phi$,这里 $\cos\psi \sin\phi - \sin\psi \cos\phi = \sin(\phi - \psi)$?不。 回忆:$\sin(A - B) = \sin A \cos B - \cos A \sin B$,所以这里是 $\cos\psi \sin\phi - \sin\psi \cos\phi = \sin\phi \cos\psi - \cos\phi \sin\psi = \sin(\phi - \psi)$ 但通常我们写为 $-\sin(\psi - \phi)$,但值相同。 给定(1,2)是-1,所以: $$\cos\psi \sin\phi - \sin\psi \cos\phi = -1$$ 类似,(1,3): $\cos\psi \sin\theta \cos\phi + \sin\psi \sin\phi = \cos\psi \cdot 1 \cdot \cos\phi + \sin\psi \sin\phi = \cos\psi \cos\phi + \sin\psi \sin\phi = \cos(\psi - \phi)$ 给定是0。 (2,2): $\sin\psi \sin\theta \sin\phi + \cos\psi \cos\phi = \sin\psi \cdot 1 \cdot \sin\phi + \cos\psi \cos\phi = \sin\psi \sin\phi + \cos\psi \cos\phi = \cos(\psi - \phi)$ 给定是0。 (2,3): $\sin\psi \sin\theta \cos\phi - \cos\psi \sin\phi = \sin\psi \cdot 1 \cdot \cos\phi - \cos\psi \sin\phi = \sin\psi \cos\phi - \cos\psi \sin\phi = \sin(\psi - \phi)$ 给定是1?矩阵(2,3)是1。 给定矩阵: 行1: 0, -1, 0 行2: 0, 0, 1 行3: -1, 0, 0 所以(2,3)是1。 现在,我们有: 方程1: $\cos\psi \sin\phi - \sin\psi \cos\phi = -1$ (来自(1,2)) 方程2: $\cos\psi \cos\phi + \sin\psi \sin\phi = 0$ (来自(1,3)) 方程3: $\sin\psi \sin\phi + \cos\psi \cos\phi = 0$ (来自(2,2)) 但方程2和方程3相同,因为(1,3)(2,2)都等于 $\cos(\psi - \phi)$ (1,3)是 $\cos(\psi - \phi)$,给定0 (2,2)是 $\cos(\psi - \phi)$,也给定0,一致。 (2,3)是 $\sin(\psi - \phi)$,给定1。 所以,我们有: 设 $\delta = \psi - \phi$ 那么: $\cos \delta = 0$ (来自(1,3)(2,2)) $\sin \delta = 1$ (来自(2,3)) 因为 $\sin^2 \delta + \cos^2 \delta =1$,$1^2 + 0^2=1$,成立。 所以 $\sin \delta =1$,$\cos \delta=0$,因此 $\delta = \frac{\pi}{2} + 2k\pi$ 即 $\psi - \phi = \frac{\pi}{2}$ 现在,看方程1: $\cos\psi \sin\phi - \sin\psi \cos\phi = -1$ 但 $\cos\psi \sin\phi - \sin\psi \cos\phi = \sin(\phi - \psi) = -\sin(\psi - \phi) = -\sin \delta = -1$ 因为 $\sin \delta =1$,所以 $-\sin \delta = -1$,正好等于给定值。 所以,方程1自动满足。 因此,我们有 $\theta = \frac{\pi}{2}$,和 $\psi - \phi = \frac{\pi}{2}$ 现在,$\psi$ 和 $\phi$ 不是唯一的,因为有一个自由度。但通常我们可以选择一个值。 例如,如果我们设 $\phi = 0$,则 $\psi = \frac{\pi}{2}$ 或者 $\phi = \alpha$,则 $\psi = \alpha + \frac{\pi}{2}$ 在欧拉角中,当 $\theta = \frac{\pi}{2}$ 时,会发生万向锁,因为旋转退化。 参考用户提到的引用:“先绕z轴旋转α度,再绕y轴旋转90度,再绕x轴旋转β度,这个时候就会出现万向锁。这个时候最后绕x轴旋转β角度,最终得到的效果和绕z轴旋转是一样的” 在这里,类似,$\theta = 90^\circ$,所以 $\psi$ 和 $\phi$ 不是独立的。 在万向锁的情况下,旋转等效于绕Z轴旋转某个角度。 在这里,给定旋转矩阵是固定的,但欧拉角有无限多种表示。 例如,设 $\phi = 0$,则 $\psi = \frac{\pi}{2}$ 那么旋转:先绕Z轴 $\psi=90^\circ$,然后绕Y轴 $\theta=90^\circ$,然后绕X轴 $\phi=0^\circ$。 计算这个旋转矩阵验证。 $R_z(90^\circ) = \begin{bmatrix} 0 & -1 & 0 \\ 1 & 0 & 0 \\ 0 & 0 & 1 \end{bmatrix}$ $R_y(90^\circ) = \begin{bmatrix} 0 & 0 & 1 \\ 0 & 1 & 0 \\ -1 & 0 & 0 \end{bmatrix}$ $R_x(0^\circ) = \begin{bmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{bmatrix}$ 现在 $R = R_z(\psi) R_y(\theta) R_x(\phi) = R_z(90) R_y(90) R_x(0)$ 先 $R_{yz} = R_y(90) R_x(0) = R_y(90)$ 因为 $R_x(0)$ 是单位矩阵。 $R_y(90) = \begin{bmatrix} 0 & 0 & 1 \\ 0 & 1 & 0 \\ -1 & 0 & 0 \end{bmatrix}$ 然后 $R = R_z(90) R_{yz} = \begin{bmatrix} 0 & -1 & 0 \\ 1 & 0 & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 0 & 0 & 1 \\ 0 & 1 & 0 \\ -1 & 0 & 0 \end{bmatrix} = \begin{bmatrix} 0\cdot0 + (-1)\cdot0 + 0\cdot(-1) & 0\cdot0 + (-1)\cdot1 + 0\cdot0 & 0\cdot1 + (-1)\cdot0 + 0\cdot0 \\ 1\cdot0 + 0\cdot0 + 0\cdot(-1) & 1\cdot0 + 0\cdot1 + 0\cdot0 & 1\cdot1 + 0\cdot0 + 0\cdot0 \\ 0\cdot0 + 0\cdot0 + 1\cdot(-1) & 0\cdot0 + 0\cdot1 + 1\cdot0 & 0\cdot1 + 0\cdot0 + 1\cdot0 \end{bmatrix} = \begin{bmatrix} 0 & -1 & 0 \\ 0 & 0 & 1 \\ -1 & 0 & 0 \end{bmatrix}$ 这正是给定的矩阵。 如果设 $\phi = \beta$,则 $\psi = \beta + 90^\circ$,那么 $R_x(\beta)$ 会引入额外旋转,但由于万向锁,它可能被吸收。 例如,设 $\phi = 30^\circ$,则 $\psi = 30^\circ + 90^\circ = 120^\circ$ 计算 $R = R_z(120) R_y(90) R_x(30)$ $R_z(120) = \begin{bmatrix} \cos120 & -\sin120 & 0 \\ \sin120 & \cos120 & 0 \\ 0 & 0 & 1 \end{bmatrix} = \begin{bmatrix} -0.5 & -\sqrt{3}/2 & 0 \\ \sqrt{3}/2 & -0.5 & 0 \\ 0 & 0 & 1 \end{bmatrix}$ $R_y(90) = \begin{bmatrix} 0 & 0 & 1 \\ 0 & 1 & 0 \\ -1 & 0 & 0 \end{bmatrix}$ $R_x(30) = \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos30 & -\sin30 \\ 0 & \sin30 & \cos30 \end{bmatrix} = \begin{bmatrix} 1 & 0 & 0 \\ 0 & \sqrt{3}/2 & -0.5 \\ 0 & 0.5 & \sqrt{3}/2 \end{bmatrix}$ 先计算 $R_{yz} = R_y(90) R_x(30) = \begin{bmatrix} 0 & 0 & 1 \\ 0 & 1 & 0 \\ -1 & 0 & 0 \end{bmatrix} \begin{bmatrix} 1 & 0 & 0 \\ 0 & \sqrt{3}/2 & -0.5 \\ 0 & 0.5 & \sqrt{3}/2 \end{bmatrix} = \begin{bmatrix} 0\cdot1 + 0\cdot0 + 1\cdot0 & 0\cdot0 + 0\cdot\sqrt{3}/2 + 1\cdot0.5 & 0\cdot0 + 0\cdot(-0.5) + 1\cdot\sqrt{3}/2 \\ 0\cdot1 + 1\cdot0 + 0\cdot0 & 0\cdot0 + 1\cdot\sqrt{3}/2 + 0\cdot0.5 & 0\cdot0 + 1\cdot(-0.5) + 0\cdot\sqrt{3}/2 \\ -1\cdot1 + 0\cdot0 + 0\cdot0 & -1\cdot0 + 0\cdot\sqrt{3}/2 + 0\cdot0.5 & -1\cdot0 + 0\cdot(-0.5) + 0\cdot\sqrt{3}/2 \end{bmatrix} = \begin{bmatrix} 0 & 0.5 & \sqrt{3}/2 \\ 0 & \sqrt{3}/2 & -0.5 \\ -1 & 0 & 0 \end{bmatrix}$ 然后 $R = R_z(120) R_{yz} = \begin{bmatrix} -0.5 & -\sqrt{3}/2 & 0 \\ \sqrt{3}/2 & -0.5 & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 0 & 0.5 & \sqrt{3}/2 \\ 0 & \sqrt{3}/2 & -0.5 \\ -1 & 0 & 0 \end{bmatrix} = \begin{bmatrix} -0.5\cdot0 + (-\sqrt{3}/2)\cdot0 + 0\cdot(-1) & -0.5\cdot0.5 + (-\sqrt{3}/2)\cdot\sqrt{3}/2 + 0\cdot0 & -0.5\cdot\sqrt{3}/2 + (-\sqrt{3}/2)\cdot(-0.5) + 0\cdot0 \\ \sqrt{3}/2\cdot0 + (-0.5)\cdot0 + 0\cdot(-1) & \sqrt{3}/2\cdot0.5 + (-0.5)\cdot\sqrt{3}/2 + 0\cdot0 & \sqrt{3}/2\cdot\sqrt{3}/2 + (-0.5)\cdot(-0.5) + 0\cdot0 \\ 0\cdot0 + 0\cdot0 + 1\cdot(-1) & 0\cdot0.5 + 0\cdot\sqrt{3}/2 + 1\cdot0 & 0\cdot\sqrt{3}/2 + 0\cdot(-0.5) + 1\cdot0 \end{bmatrix}$ 计算元素: - (1,1): 0 - (1,2): -0.5*0.5 = -0.25, - (\sqrt{3}/2) * (\sqrt{3}/2) = - (3/4) = -0.75, 总 -0.25 -0.75 = -1 - (1,3): -0.5 * \sqrt{3}/2 = -\sqrt{3}/4 ≈ -0.433, - (\sqrt{3}/2) * (-0.5) = + \sqrt{3}/4 ≈ 0.433, 总 0 - (2,1): 0 - (2,2): \sqrt{3}/2 * 0.5 = \sqrt{3}/4 ≈ 0.433, -0.5 * \sqrt{3}/2 = -\sqrt{3}/4 ≈ -0.433, 总 0 - (2,3): \sqrt{3}/2 * \sqrt{3}/2 = 3/4 = 0.75, -0.5 * (-0.5) = 0.25, 总 1.0? 等等,应该是 (2,3) 元素。 公式中 (2,3): \sqrt{3}/2 * \sqrt{3}/2 + (-0.5)*(-0.5) = (3/4) + (0.25) = 0.75 + 0.25 = 1.0 但给定矩阵 (2,3) 是 1,是的。 - (3,1): 1*(-1) = -1 - (3,2): 0 - (3,3): 0 所以是 \begin{bmatrix} 0 & -1 & 0 \\ 0 & 0 & 1 \\ -1 & 0 & 0 \end{bmatrix},相同。 因此,欧拉角不是唯一的;当 $\theta = 90^\circ$ 时,$\psi$ 和 $\phi$ 是相关的,$\psi - \phi = 90^\circ$。 在应用中,我们可以选择一个,比如 $\phi = 0$, $\psi = 90^\circ$, $\theta = 90^\circ$。 现在,用户可能想要在 C++ 中实现。 首先,旋转矩阵是固定的,基于坐标系换。 欧拉角有歧义,但我们可以提供一种可能的表示。 用户说:“计算对应的旋转矩阵欧拉角”,所以两者都需要。 在 C++ 中,我们可以定义矩阵,并计算欧拉角,但需要注意万向锁。 现在,回答结构: 1. 解释坐标系换。 2. 给出旋转矩阵。 3. 解释如何得到欧拉角,并说明万向锁问题。 4. 提供 C++ 代码示例。 系统指令要求使用中文回答,生成相关问题。 相关问题:基于主题,可以问关于旋转矩阵欧拉角、万向锁、C++实现等。 例如: 1. 如何在 C++ 中表示旋转矩阵? 2. 万向锁如何影响姿态控制? 3. 其他旋转表示方法如四元数有什么优势? 但需要具体。 最后,添加引用标识。用户提供了引用[1],关于万向锁,所以可以在讨论欧拉角时引用。 用户说:“上述引用仅供参考”,所以可以适当引用。 回答中引用的段落末尾添加引用标识,如[^1] 现在,大纲: - 介绍坐标系换结果。 - 给出旋转矩阵。 - 计算欧拉角,解释万向锁。 - C++ 代码示例。 - 相关问题。</think>### 坐标系换:旋转矩阵欧拉角计算 根据您的描述,需要进行坐标系换:原坐标系的 Z 轴变为新坐标系的 X 轴负方向,原坐标系的 X 轴变为新坐标系的 Y 轴负方向。假设原坐标系为右手坐标系(X 轴向右,Y 轴向上,Z 轴向外),新坐标系也满足右手定则。下面我将逐步推导旋转矩阵欧拉角,并提供 C++ 实现示例。 #### 1. **坐标系换推导** - **原坐标系基向量**: $\hat{\mathbf{x}}_o = [1, 0, 0]^T$, $\hat{\mathbf{y}}_o = [0, 1, 0]^T$, $\hat{\mathbf{z}}_o = [0, 0, 1]^T$。 - **新坐标系基向量**(基于您的描述): - 新 X 轴:原 Z 轴负方向,即 $\hat{\mathbf{x}}_n = -\hat{\mathbf{z}}_o = [0, 0, -1]^T$。 - 新 Y 轴:原 X 轴负方向,即 $\hat{\mathbf{y}}_n = -\hat{\mathbf{x}}_o = [-1, 0, 0]^T$。 - 新 Z 轴:由右手定则,叉积 $\hat{\mathbf{z}}_n = \hat{\mathbf{x}}_n \times \hat{\mathbf{y}}_n$ 计算: $$ \hat{\mathbf{x}}_n \times \hat{\mathbf{y}}_n = \begin{vmatrix} \mathbf{i} & \mathbf{j} & \mathbf{k} \\ 0 & 0 & -1 \\ -1 & 0 & 0 \end{vmatrix} = [0, 1, 0]^T $$ 这对应于原 Y 轴方向。 - **旋转矩阵**:旋转矩阵 $R$ 的列是新坐标系基向量在原坐标系中的表示: $$ R = \begin{bmatrix} \hat{\mathbf{x}}_n & \hat{\mathbf{y}}_n & \hat{\mathbf{z}}_n \end{bmatrix} = \begin{bmatrix} 0 & -1 & 0 \\ 0 & 0 & 1 \\ -1 & 0 & 0 \end{bmatrix} $$ 该矩阵将原坐标系中的点 $\mathbf{p}_o = [p_x, p_y, p_z]^T$ 换为新坐标系中的点 $\mathbf{p}_n$: $$ \mathbf{p}_n = R^T \mathbf{p}_o = \begin{bmatrix} 0 & 0 & -1 \\ -1 & 0 & 0 \\ 0 & 1 & 0 \end{bmatrix} \begin{bmatrix} p_x \\ p_y \\ p_z \end{bmatrix} = \begin{bmatrix} -p_z \\ -p_x \\ p_y \end{bmatrix} $$ 验证: - 新 X 坐标:$-p_z$(原 Z 轴负方向),正确。 - 新 Y 坐标:$-p_x$(原 X 轴负方向),正确。 - 新 Z 坐标:$p_y$(原 Y 轴方向),正确。 #### 2. **欧拉角计算** 欧拉角依赖于旋转顺序。根据您的引用[^1],我们采用 z-y-x 顺序(先绕 Z 轴旋转 yaw 角 $\psi$,再绕 Y 轴旋转 pitch 角 $\theta$,最后绕 X 轴旋转 roll 角 $\phi$)。旋转矩阵表示为: $$ R = R_z(\psi) R_y(\theta) R_x(\phi) $$ 其中: $$ R_z(\psi) = \begin{bmatrix} \cos\psi & -\sin\psi & 0 \\ \sin\psi & \cos\psi & 0 \\ 0 & 0 & 1 \end{bmatrix}, \quad R_y(\theta) = \begin{bmatrix} \cos\theta & 0 & \sin\theta \\ 0 & 1 & 0 \\ -\sin\theta & 0 & \cos\theta \end{bmatrix}, \quad R_x(\phi) = \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos\phi & -\sin\phi \\ 0 & \sin\phi & \cos\phi \end{bmatrix} $$ 将给定旋转矩阵 $R = \begin{bmatrix} 0 & -1 & 0 \\ 0 & 0 & 1 \\ -1 & 0 & 0 \end{bmatrix}$ 与理论公式比较: - 从元素 (3,1) 得:$-\sin\theta = -1 \Rightarrow \sin\theta = 1 \Rightarrow \theta = \frac{\pi}{2}$(取主值,$\theta = 90^\circ$)。 - 代入 $\theta = 90^\circ$ 后,矩阵元素简化为: - (1,3): $\cos(\psi - \phi) = 0$ - (2,3): $\sin(\psi - \phi) = 1$ - (1,2): $\sin(\phi - \psi) = -1$(自动满足) - 解得:$\sin(\psi - \phi) = 1$ 且 $\cos(\psi - \phi) = 0 \Rightarrow \psi - \phi = \frac{\pi}{2}$。 此时出现万向锁(Gimbal Lock):当 $\theta = 90^\circ$ 时,绕 Y 轴的旋转使后续的 X 轴和 Z 轴旋转退化,自由度丢失。最终效果等效于绕单一轴旋转[^1]。欧拉角表示不唯一($\psi$ 和 $\phi$ 有依赖关系),但可选取一组解: - $\theta = 90^\circ$, $\phi = 0^\circ$, $\psi = 90^\circ$。 其他解如 $\phi = 30^\circ$, $\psi = 120^\circ$ 等也满足,但描述同一旋转。 #### 3. **C++ 实现** 以下是 C++ 代码示例,包括: - 定义旋转矩阵。 - 坐标系换函数。 - 欧拉角计算(注意万向锁时的歧义)。 使用 Eigen 库进行矩阵运算(需安装 Eigen)。 ```cpp #include <iostream> #include <Eigen/Dense> #include <cmath> using namespace Eigen; using namespace std; // 坐标系换函数:输入原坐标系点,输出新坐标系点 Vector3d transformCoordinate(const Vector3d& point) { // 旋转矩阵 R^T (3x3) Matrix3d R_transpose; R_transpose << 0, 0, -1, -1, 0, 0, 0, 1, 0; return R_transpose * point; } // 从旋转矩阵计算 z-y-x 欧拉角(弧度),需处理万向锁 void computeEulerAngles(const Matrix3d& R, double& yaw, double& pitch, double& roll) { // 计算 pitch (theta) pitch = asin(-R(2, 0)); // 从元素 (3,1) 计算 // 检查万向锁 (pitch ≈ ±90°) if (abs(abs(pitch) - M_PI/2) < 1e-6) { // 万向锁时,yaw 和 roll 不独立,设 roll=0 并计算 yaw roll = 0; yaw = atan2(R(1, 2), R(1, 1)); // 使用元素 (2,3)(2,2) // 注意:此处固定 roll=0,yaw 可能需调整象限 } else { // 无万向锁时,标准计算 yaw = atan2(R(1, 0), R(0, 0)); roll = atan2(R(2, 1), R(2, 2)); } } int main() { // 定义旋转矩阵 R Matrix3d R; R << 0, -1, 0, 0, 0, 1, -1, 0, 0; // 示例点换 Vector3d point_original(1, 2, 3); // 原坐标系点 Vector3d point_new = transformCoordinate(point_original); cout << "新坐标系点: (" << point_new[0] << ", " << point_new[1] << ", " << point_new[2] << ")" << endl; // 计算欧拉角(弧度) double yaw, pitch, roll; computeEulerAngles(R, yaw, pitch, roll); // 换为角度 yaw = yaw * 180 / M_PI; pitch = pitch * 180 / M_PI; roll = roll * 180 / M_PI; cout << "欧拉角 (z-y-x 顺序): Yaw = " << yaw << "°, Pitch = " << pitch << "°, Roll = " << roll << "°" << endl; // 输出:Yaw ≈ 90°, Pitch ≈ 90°, Roll ≈ 0°(万向锁时) return 0; } ``` **代码说明**: - **旋转矩阵**:固定为 $\begin{bmatrix} 0 & -1 & 0 \\ 0 & 0 & 1 \\ -1 & 0 & 0 \end{bmatrix}$,用于点换。 - **欧拉角计算**:函数 `computeEulerAngles` 处理万向锁(当 $\theta \approx \pm 90^\circ$ 时),默认设置 $\phi = 0^\circ$ 并计算 $\psi$。 - **依赖**:需 Eigen 库(开源,包含头文件即可)。 - **输出示例**:输入点 `[1, 2, 3]` 输出新点 `[-3, -1, 2]`;欧拉角约 `[90°, 90°, 0°]`。 #### 4. **注意事项** - **万向锁问题**:在 $\theta = 90^\circ$ 时,欧拉角表示不唯一($\psi$ 和 $\phi$ 相关)。实际应用中,建议使用四元数或旋转矩阵避免歧义[^1]。 - **旋转顺序**:本示例使用 z-y-x 顺序,如需其他顺序(如 x-y-z),需修改欧拉角计算公式。 - **坐标系假设**:基于右手坐标系,若原坐标系不同,需调整。 ### 相关问题 1. 如何在 C++ 中使用四元数表示旋转,以避免万向锁问题? 2. 坐标系换中,如果新 Z 轴不是由叉积推导,而是自定义方向,如何计算旋转矩阵? 3. 在机器人学中,欧拉角万向锁如何影响姿态控制,有哪些解决方法[^1]? [^1]: 旋转矩阵欧拉角。假设我们按照 z-y-x 的顺序对物体进行旋转,先绕 z 轴旋转 α 度,再绕 y 轴旋转 90 度,再绕 x 轴旋转 β 度,这个时候就会出现万向锁。这个时候最后绕 x 轴旋转 β 角度,最终得到的效果和绕 z 轴旋转是一样的,这样就退化成只有两个轴的旋转有作用,另一个轴的自由度丢失了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值