欧拉角的三维空间旋转

欧拉角的旋转顺规

欧拉角的旋转顺序不能随意改变,要注意描述时所参考的坐标系。

本质上是因为:线性变换不满足乘法交换律。
在这里插入图片描述

右手坐标系的任意一个旋转矩阵均属于 ,即 阶特殊正交群(如何通俗地解释李群和李代数的关系? )。将绕 x,y,z 轴的旋转分别用 阶矩阵表示为:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在描述旋转矩阵一般会用到固定坐标系 [公式] 和活动坐标系 [公式] 。固定坐标系在物体旋转的过程中保持不变,而活动坐标系则始终跟随着物体进行旋转或平移。
在这里插入图片描述

对于固定坐标系

图 1 中表示的两种旋转变换过程是相对于活动坐标系 而言的,其可以描述为:上一行:先绕 的 轴旋转 弧度,然后绕 的 轴旋转 弧度;下一行:先绕 的 轴旋转 弧度,然后绕 的 轴旋转 弧度;仅仅是改变了欧拉角的旋转顺序,但可以看到,最终的结果却是不一样的。
在这里插入图片描述对于图 1 的上一行变换,有:
在这里插入图片描述
对于图 1 的下一行变换,有:
在这里插入图片描述

对于固定坐标系

如果是相对于固定坐标系 [公式] ,其矩阵运算的顺序与相对于活动坐标系正好相反。为了对比,这里换个例子,如下图所示的魔方旋转:
在这里插入图片描述其可以描述为:

第一个魔方:先绕 [公式] 的 [公式] 轴旋转 [公式] 弧度,然后绕 [公式] 的 [公式] 轴旋转 [公式] 弧度;第二个魔方:先绕 [公式] 的 [公式] 轴旋转 [公式] 弧度,然后绕 [公式] 的 [公式] 轴旋转 [公式] 弧度;

对于第一个魔方,有:
在这里插入图片描述
对于第二个魔方,有:
在这里插入图片描述
对比可以发现和前面的相对活动坐标系的结果相反。

slam里常用rpy的旋转顺规,重点看参考坐标系是活动坐标系还是固定坐标系。

左乘: 坐标系不动,点动,则左乘。【若绕静坐标系(世界坐标系)旋转,则左乘,也是变换矩阵乘坐标矩阵;】

右乘: 点不动,坐标系动,则右乘。【若是绕动坐标系旋转(自身建立一个坐标系),则右乘,也就是坐标矩阵乘变换矩阵】

示例代码(loam)

void TransformToStartIMU(pcl::PointXYZHSV *p)
{
  /********************************************************************************
    Ry*Rx*Rz*Pl, transform point to the global frame,世界坐标系
  *********************************************************************************/

  // 在使用IMU的时候,laser的坐标系需要转换到全局坐标系的。旋转顺规ZXY
  //绕z轴旋转(imuRollCur)
  float x1 = cos(imuRollCur) * p->x - sin(imuRollCur) * p->y;
  float y1 = sin(imuRollCur) * p->x + cos(imuRollCur) * p->y;
  float z1 = p->z;
  //绕x轴旋转(imuPitchCur)
  float x2 = x1;
  float y2 = cos(imuPitchCur) * y1 - sin(imuPitchCur) * z1;
  float z2 = sin(imuPitchCur) * y1 + cos(imuPitchCur) * z1;
 //绕y轴旋转(imuYawCur)
  float x3 = cos(imuYawCur) * x2 + sin(imuYawCur) * z2;
  float y3 = y2;
  float z3 = -sin(imuYawCur) * x2 + cos(imuYawCur) * z2;

  /********************************************************************************
    Rz(pitch).inverse * Rx(pitch).inverse * Ry(yaw).inverse * Pg
    transfrom global points to the local frame  当前Sweep第一帧时候IMU坐标系
  *********************************************************************************/
  
  //绕y轴旋转(-imuYawStart)
  float x4 = cos(imuYawStart) * x3 - sin(imuYawStart) * z3;
  float y4 = y3;
  float z4 = sin(imuYawStart) * x3 + cos(imuYawStart) * z3;
  //绕x轴旋转(-imuPitchStart)
  float x5 = x4;
  float y5 = cos(imuPitchStart) * y4 + sin(imuPitchStart) * z4;
  float z5 = -sin(imuPitchStart) * y4 + cos(imuPitchStart) * z4;
  //绕z轴旋转(-imuRollStart),然后叠加平移量
  p->x = cos(imuRollStart) * x5 + sin(imuRollStart) * y5 + imuShiftFromStartXCur;
  p->y = -sin(imuRollStart) * x5 + cos(imuRollStart) * y5 + imuShiftFromStartYCur;
  p->z = z5 + imuShiftFromStartZCur;
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值