欧拉角与旋转矩阵(EIgen与书中公式的区别)

本文详细介绍了欧拉角的概念及其在不同坐标系中的应用,对比了主动旋转与被动旋转的区别,并通过实例验证了四元数左乘的特性。

1. 欧拉角简介

1.1 定义欧拉角的关键项

  定义一个欧拉角需要确认以下几条:

1、旋转坐标系是右手坐标系还是左手坐标系。
 右手坐标系中的欧拉角逆时针旋转为正,左手系中顺时针旋转为正。
2、旋转组合方式,欧拉角共有322共计12种。
 欧拉角根据旋转方式可分为Tait-Bryan angle(也称作:Cardan angles; nautical angles; heading、elevation、bank; yaw、pitch、roll)和 Proper/classic Euler angle两种。
 Tait-Bryan angle包括:

z-y-x//即为zyx欧拉角,先绕z轴旋转,再绕y轴旋转,再绕x轴旋转,zyx欧拉角是导航和slam技术中常用的欧拉角,
此外,Tait-Bryan angle还包括以下欧拉角:
z-x-y, y-x-z, y-z-x, x-y-z, x-z-y

 Proper/classic Euler angle包括:

z-x-z,x-y-x,y-z-y,z-y-z, x-z-x,y-x-y

3、点或向量旋转(主动旋转)还是坐标系旋转(被动旋转);二者对应的旋转矩阵也有所不同。
 主动旋转是指将向量逆时针围绕旋转轴旋转,被动旋转是对坐标轴进行的逆时针旋转,相当于主动旋转的逆操作
4、定轴旋转与动轴旋转
 动轴旋转又称为内在旋转,内在旋转每次旋转围绕的轴是上次旋转之后坐标系的某个轴,定轴旋转又称为外在旋转,外在旋转每次旋转的轴是固定坐标系中的轴。内在旋转与外在旋转的转换关系:互换第一次和第三次旋转的位置则两者结果相同

2 正常坐标旋转

正常的旋转如上图所示,在世界坐标系中有一个点P_w1(1,1,0)T, θ \theta θ表示的是从世界坐标系w1到世界坐标系w2旋转的角度,则可以得到,旋转后的P_w2为 ( 2 , 0 , 0 ) T (\sqrt2,0,0)^T (2 ,0,0)

<think>我们已知:用户想将欧拉角换为旋转矩阵Eigen::Matrix4f类型),使用Eigen库。 根据引用[2]和引用[3]中的内容,我们可以通过以下步骤实现: 1. 将欧拉角换为3x3的旋转矩阵Eigen::Matrix3d或Eigen::Matrix3f) 2. 将3x3旋转矩阵换为4x4齐次变换矩阵Eigen::Matrix4f) 注意:欧拉角换时需要注意旋转顺序(例如ZXY、XYZ等)。假设用户使用常见的ZXY顺序(即先绕Z轴,再绕X轴,最后绕Y轴),但实际顺序需根据用户需求确定。 步骤详解: 步骤1:使用Eigen::AngleAxis(旋转向量)按顺序相乘得到3x3旋转矩阵。 步骤2:创建一个4x4的单位矩阵,将3x3旋转矩阵放在左上角,其余位置补0,右下角补1。 示例代码(使用Eigen库): 注意:欧拉角单位是弧度。 假设用户有欧拉角(yaw, pitch, roll)分别对应绕Z、Y、X轴的旋转(注意顺序可能不同,这里以ZYX为例,但用户问题中引用[3]使用了ZXY顺序,所以需要明确顺序。根据用户需求,我们假设顺序为ZYX(即yaw, pitch, roll)?但用户引用[3]中使用了ZXY顺序。因此,我们需要用户明确顺序。如果没有明确,我们按照引用[3]的ZXY顺序示例。 根据用户引用[3]的示例代码,他们使用的是ZXY顺序(先Z,再X,后Y)。因此我们按照这个顺序。 但是,用户要求的是Eigen::Matrix4f(单精度浮点数),而引用[3]中使用了双精度(double)。我们可以根据需要选择单精度或双精度。 下面给出一个示例,将欧拉角(theta_z, theta_x, theta_y)换为Eigen::Matrix4f: 步骤: 1. 使用Eigen::AngleAxisf(因为要单精度)分别创建绕Z轴、X轴、Y轴的旋转。 2. 按照ZXY顺序相乘(注意:Eigen旋转相乘的顺序是从右向左,即先旋转的放在右边)。 3. 将得到的3x3旋转矩阵换为4x4齐次变换矩阵(左上角3x3为旋转矩阵,其余位置:最后一列和最后一行除了右下角为1,其余为0)。 代码示例: ```cpp #include <Eigen/Dense> #include <Eigen/Geometry> // 假设欧拉角(弧度)分别为:theta_z(绕Z轴旋转角),theta_x(绕X轴旋转角),theta_y(绕Y轴旋转角) Eigen::Matrix4f eulerToMatrix4f(float theta_z, float theta_x, float theta_y) { // 步骤1:使用AngleAxisf(单精度)创建绕各轴的旋转,并按照ZXY顺序相乘(注意:从右向左乘) // 即:先绕Z轴,再绕X轴,最后绕Y轴。所以表达式为:Y * X * Z Eigen::Matrix3f rotation_matrix; rotation_matrix = Eigen::AngleAxisf(theta_y, Eigen::Vector3f::UnitY()) * Eigen::AngleAxisf(theta_x, Eigen::Vector3f::UnitX()) * Eigen::AngleAxisf(theta_z, Eigen::Vector3f::UnitZ()); // 步骤2:创建4x4单位矩阵,将3x3旋转矩阵放入左上角 Eigen::Matrix4f matrix_4f = Eigen::Matrix4f::Identity(); matrix_4f.block<3,3>(0,0) = rotation_matrix; return matrix_4f; } ``` 注意:上述代码中旋转顺序是ZXY(因为相乘顺序是Y*X*Z,即最后乘的是Z,所以最先旋转的是Z)。这符合引用[3]中的顺序。 如果用户使用其他顺序(如XYZ、ZYX等),则需要调整相乘的顺序。 例如,如果用户想要ZYX顺序(即先绕Z轴,再绕Y轴,最后绕X轴),则应该: rotation_matrix = Eigen::AngleAxisf(theta_x, Eigen::Vector3f::UnitX()) * Eigen::AngleAxisf(theta_y, Eigen::Vector3f::UnitY()) * Eigen::AngleAxisf(theta_z, Eigen::Vector3f::UnitZ()); 因此,请根据用户的实际旋转顺序调整。 总结: 1. 使用Eigen::AngleAxisf创建绕各轴的旋转(注意轴和角度)。 2. 按照旋转顺序(从右向左)相乘得到3x3旋转矩阵。 3. 将3x3旋转矩阵放入4x4单位矩阵的左上角。 这样,我们就得到了一个4x4的旋转矩阵(没有平移部分,只有旋转)。如果还需要平移,可以另外设置。 引用[2]中提到了Eigen::Affine3f和Eigen::Matrix4f的换,这里我们直接构造了Eigen::Matrix4f。也可以使用Eigen::Affine3f,但用户要求的是Eigen::Matrix4f。 如果用户需要包含平移,那么可以构建一个4x4的变换矩阵,将旋转部分放在左上角3x3,平移向量放在第4列的前3个元素。 但用户问题中只要求旋转矩阵(没有提到平移),所以我们只处理旋转部分。 相关引用: [^2] 中提供了旋转向量、旋转矩阵欧拉角、四元数之间的换,以及Eigen::Affine3f和Eigen::Matrix4f的换。 [^3] 提供了欧拉角旋转矩阵的示例(3x3)。 因此,我们按照上述方法实现。 如果用户需要其他顺序的欧拉角,请自行调整相乘顺序。 注意:欧拉角存在万向锁问题,因此在使用时需注意角度范围。 以上代码示例即可满足用户需求。</think># 使用Eigen库将欧拉角换为Eigen::Matrix4f旋转矩阵Eigen库中,将欧拉角换为`Eigen::Matrix4f`类型的旋转矩阵需要两个关键步骤:首先将欧拉角换为3×3旋转矩阵,然后将其嵌入到4×4齐次变换矩阵中。以下是完整的实现方法: ```cpp #include <Eigen/Dense> #include <Eigen/Geometry> // 将欧拉角换为Eigen::Matrix4f旋转矩阵 // 参数:yaw (绕Z轴), pitch (绕Y轴), roll (绕X轴) - 单位为弧度 Eigen::Matrix4f eulerToMatrix4f(float yaw, float pitch, float roll) { // 1. 创建3×3旋转矩阵(使用单精度float) Eigen::Matrix3f rotation_matrix; // 2. 使用AngleAxis按顺序构建旋转(Z-Y-X顺序) rotation_matrix = Eigen::AngleAxisf(yaw, Eigen::Vector3f::UnitZ()) * // 绕Z轴旋转(yaw) Eigen::AngleAxisf(pitch, Eigen::Vector3f::UnitY()) * // 绕Y轴旋转(pitch) Eigen::AngleAxisf(roll, Eigen::Vector3f::UnitX()); // 绕X轴旋转(roll) // 3. 创建4×4齐次变换矩阵并设置为单位矩阵 Eigen::Matrix4f matrix_4f = Eigen::Matrix4f::Identity(); // 4. 将3×3旋转矩阵放入4×4矩阵的左上角 matrix_4f.block<3, 3>(0, 0) = rotation_matrix; return matrix_4f; } ``` ## 使用示例 ```cpp #include <iostream> int main() { // 定义欧拉角(弧度) float yaw = M_PI / 4.0f; // 45度 (绕Z轴) float pitch = M_PI / 6.0f; // 30度 (绕Y轴) float roll = M_PI / 3.0f; // 60度 (绕X轴) // 换为Matrix4f Eigen::Matrix4f transform = eulerToMatrix4f(yaw, pitch, roll); // 打印结果 std::cout << "4x4 Transformation Matrix:\n" << transform << std::endl; return 0; } ``` ## 关键说明 1. **旋转顺序**:示例代码使用Z-Y-X旋转顺序(yaw-pitch-roll),这是最常见的顺序。如果需要其他顺序(如X-Y-Z),只需调整`Eigen::AngleAxisf`的相乘顺序: ```cpp // X-Y-Z顺序示例 rotation_matrix = Eigen::AngleAxisf(roll, Eigen::Vector3f::UnitX()) * Eigen::AngleAxisf(pitch, Eigen::Vector3f::UnitY()) * Eigen::AngleAxisf(yaw, Eigen::Vector3f::UnitZ()); ``` 2. **齐次变换矩阵**:得到的4×4矩阵形式为: $$ \begin{bmatrix} R_{3×3} & 0 \\ 0 & 1 \end{bmatrix} $$ 其中$R_{3×3}$是旋转部分,右下角的1表示齐次坐标的缩放因子[^2]。 3. **性能考虑**:如果需要频繁进行此类换,可以: - 直接使用`Eigen::Transform`类 - 缓存中间结果 - 使用双精度(`double`)计算以获得更高精度 ## 完整实现(包含平移) 如果需要包含平移的完整变换矩阵: ```cpp Eigen::Matrix4f createTransformMatrix(float yaw, float pitch, float roll, float tx, float ty, float tz) { Eigen::Matrix4f matrix = eulerToMatrix4f(yaw, pitch, roll); // 设置平移部分 matrix(0, 3) = tx; matrix(1, 3) = ty; matrix(2, 3) = tz; return matrix; } ``` ## 注意事项 1. 欧拉角存在万向锁问题,当pitch为±90°时会出现奇点 2. Eigen使用列优先存储,其他库交互时需注意内存布局 3. 旋转顺序不同会导致完全不同的结果,需实际应用一致 在机器人学、计算机视觉和3D图形学中,这种欧拉角到变换矩阵换是基础操作,用于表示物体在3D空间中的方向[^1]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zack_Liu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值