Eigen中得到欧拉角的奇异问题

1.1.关于欧拉角范围的定义

欧拉角的实际范围是:

roll:[−π,π];pitch:[−π/2,π/2];yaw:[−π,π]roll:[-\pi, \pi];\quad pitch:[-\pi/2, \pi/2];\quad yaw:[-\pi, \pi]roll:[−π,π];pitch:[−π/2,π/2];yaw:[−π,π]

Eigen库中欧拉角范围是:

0:[0:π];1:[−π:π];2:[−π:π]0: [0:\pi];\quad 1:[-\pi:\pi];\quad 2: [-\pi:\pi]0:[0:π];1:[−π:π];2:[−π:π]

1.2.Eigen中确保第一个角度的转换

Eigen库中所有均是右手坐标系的右乘,即内在旋转,输出欧拉角第一个范围[0, pi],第二个范围[-pi, pi],第三个范围[-pi, pi],所有的输出结果以保证第一个值的范围
在Eigen,把轴角、旋转矩阵和四元数转换成欧拉角具体为:

// 轴角 -> 欧拉角(Z-Y-X,即RPY) (确保第一个值的范围在[0, pi])
Eigen::Vector3d eulerAngle_aa = angleAxis_ea.matrix().eulerAngles(2,1,0);
cout << "EulerAngle(y,p,r) <-- AngleAxis: " << eulerAngle_aa.transpose()*180/M_PI << endl;// 旋转矩阵 -> 欧拉角(Z-Y-X,即RPY)(确保第一个值的范围在[0, pi])
Eigen::Vector3d eulerAngle_rm = rotationMatrix_ea.eulerAngles(2,1,0);
cout << "EulerAngle(y,p,r) <-- RotationMatrix: " << eulerAngle_rm.transpose()*180/M_PI << endl;// 四元数 -> 欧拉角(Z-Y-X,即RPY)  (确保第一个值的范围在[0, pi])
Eigen::Vector3d eulerAngle_qu = quaternion_ea.matrix().eulerAngles(2,1,0);
cout << "EulerAngle(y,p,r) <-- Quaternion: " << eulerAngle_qu.transpose()*180/M_PI << endl;

以上方法转换得到的欧拉角输出原则为:
Eigen库中所有均是右手坐标系的右乘,即内在旋转,不论输出顺序如何,输出欧拉角第一个值范围[0, pi],第二个范围[-pi, pi],第三个范围[-pi, pi],所有的输出结果以保证第一个值的范围为基础。例如:

四元数xyzw(0.00392036,−0.00511095,−0.613622,0.789573)xyzw(0.00392036, -0.00511095, -0.613622, 0.789573)xyzw(0.00392036,−0.00511095,−0.613622,0.789573);
在Eigen中转换为欧拉角ypr(1.82026,−3.13833,−3.12913)ypr(1.82026, -3.13833, -3.12913)ypr(1.82026,−3.13833,−3.12913);

如果要确保输出的pitch角满足范围[−π/2,π/2][-\pi/2, \pi/2][−π/2,π/2],

即得到欧拉角ypr(−1.32133,−0.00325971,0.0124636)ypr(-1.32133, -0.00325971, 0.0124636)ypr(−1.32133,−0.00325971,0.0124636),

则需要单独处理。

1.3.确保pitch角度范围的转换

为了获得满足pitch角度范围的欧拉角,

  • 可以使用 Conversion between quaternions and Euler angles 中给出的从四元数转换欧拉角的算法(基于Eigen进行了修改测试):
//四元数 --> 欧拉角(Z-Y-X,即RPY)(确保pitch的范围[-pi/2, pi/2])
Eigen::Vector3d Quaterniond2EulerAngles(Eigen::Quaterniond q) {Eigen::Vector3d angles;// roll (x-axis rotation)double sinr_cosp = 2 * (q.w() * q.x() + q.y() * q.z());double cosr_cosp = 1 - 2 * (q.x() * q.x() + q.y() * q.y());angles(2) = std::atan2(sinr_cosp, cosr_cosp);// pitch (y-axis rotation)double sinp = 2 * (q.w() * q.y() - q.z() * q.x());if (std::abs(sinp) >= 1)angles(1) = std::copysign(M_PI / 2, sinp); // use 90 degrees if out of rangeelseangles(1) = std::asin(sinp);// yaw (z-axis rotation)double siny_cosp = 2 * (q.w() * q.z() + q.x() * q.y());double cosy_cosp = 1 - 2 * (q.y() * q.y() + q.z() * q.z());angles(0) = std::atan2(siny_cosp, cosy_cosp);return angles;
}
  • 也可以基于旋转矩阵转换欧拉角,引用自eigen-eulerangles-returns-incorrect-values:
//旋转矩阵 --> 欧拉角(Z-Y-X,即RPY)(确保pitch的范围[-pi/2, pi/2])
Eigen::Vector3d eulerAngle_mine;
Eigen::Matrix3d rot = rotationMatrix_ea;
eulerAngle_mine(2) = std::atan2(rot(2, 1), rot(2, 2));
eulerAngle_mine(1) = std::atan2(-rot(2, 0), std::sqrt(rot(2, 1) * rot(2, 1) + rot(2, 2) * rot(2, 2)));
eulerAngle_mine(0) = std::atan2(rot(1, 0), rot(0, 0));

尾巴

【1】Conversion between quaternions and Euler angles
【2】eigen-eulerangles-returns-incorrect-values

Eigen中eulerAngles()得到欧拉角的奇异问题相关推荐

  1. Eigen中的混叠(aliasing)问题

    Eigen中的混叠(aliasing)问题 Eigen中aliasing指的是在赋值表达式的左右两边存在矩阵的重叠区域,这种情况下,有可能得到非预期的结果.如mat = 2*mat或者mat = ma ...

  2. [矩阵的三角分解系列六] Eigen中的三角分解

    Eigen中的三角分解 简介 安装命令 三角分解函数 使用范例 矩阵的三角分解是求解线性方程组常用的方法,包括LU分解,LDU分解,杜利特(Doolittle)分解,克劳特(Crout)分解,LLT( ...

  3. [Eigen中文文档] 矩阵与向量运算

    专栏总目录 本文目录 介绍 加法与减法 标量的标量乘法与除法 表达式模板 转置与共轭 (矩阵与矩阵)和(矩阵与向量)的乘积 点积和叉积 基本算术的简化运算 操作的有效性 英文原文(Matrix and ...

  4. eigen 编译_头条 | 使用eigen实现四元数、欧拉角、旋转矩阵、旋转向量间的转换...

    点击上方蓝字,关注本公众号,获得更多资源上一篇文章介绍了四元数.欧拉角.旋转矩阵.轴角如何相互转换,本篇文章介绍如何用eigen来实现. 旋转向量 1,初始化旋转向量:旋转角为alpha,旋转轴为(x ...

  5. Eigen中四元数Quaterniond的初始

    Quaterniond的初始 Eigen::Quaterniond q1(w, x, y, z);// 第一种方式Eigen::Quaterniond q2(Vector4d(x, y, z, w)) ...

  6. 万向节死锁_欧拉角的奇异问题和万向节死锁问题,会对实际的哪些应用带来什么问题?...

    谢邀,这个问题打算认真回答一次,所以要准备准备,先留个爪子,后面娓娓道来,先简单点的说几句,起个头: 1.俯仰角90°的这个问题,又或者有时候我们称呼为横滚角,我一般会用横滚角说超过90°,这是依据实 ...

  7. [Eigen中文文档] 归约、访问者和广播

    专栏总目录 本文目录 归约 范数计算 布尔归约 用户自定义的归约 访问者函数 局部归约 将局部归约与其他操作结合 广播 将广播与其他操作结合 英文原文(Reductions, visitors and ...

  8. [Eigen中文文档] 切片和索引

    专栏总目录 本文目录 概述 基本的切片 编译时的大小和步长 倒序 索引序列 自定义索引列表 英文原文(Slicing and Indexing) 本文介绍了如何使用操作运算符operator()索引行 ...

  9. ROS中四元数、欧拉角、旋转矩阵等格式转换

    未完- ROS接收到odometry格式消息: nav_msgs::Odometry pos_msg 具有: pos_msg.pose.pose.orientation.x; // xyzw pos_ ...

最新文章

  1. mysql mairadb skysql
  2. 寄存器理解 及 X86汇编入门
  3. push的时候 出现卡顿现象
  4. 程序员面试系列——大小端
  5. Linux怎么查看设置系统语言包
  6. proxy跨域不生效_vue前后端端口号不同,proxytable代理跨域无效
  7. linux 安装ftp下载,LINUX FTP安装与配置
  8. ImageLoader加载图片
  9. linux怎么运行g77,Linux安装g77编译器的技巧
  10. 一级计算机新增题库2上网题图解,计算机一级《MS Office》上机操作题题库(2)
  11. python数据结构与算法分析 第2版_题库 | 百度数据结构 / 算法面试题型介绍及解析 第 2 期...
  12. namp - 端口扫描 主机判断 漏洞分析
  13. ap_invoice_distributions_all与PO表关联问题
  14. HTML+CSS+JavaScript实现放大镜效果
  15. Auto.js:实现蚂蚁森林自动收能量(懒人的高效生活)
  16. [Linq] Linq如何调用外部方法?
  17. OpenGL 开始学习指南
  18. 15 python的文件操作
  19. 申请支付宝授权,提现测试环境步骤
  20. 单体对象 Singleton Object 提供的顶层方法

热门文章

  1. 关于打开虚拟机vmware镜像就蓝屏(注:主要针对轻薄本本以及高性能游戏本)
  2. 图像隐写,如何在图像中隐藏二维码
  3. HTML零基础快速入门(详细教程)
  4. 举一个在网上书店系统中的数据库存储过程设计的例子
  5. IP地址:10.10.1.1/24的“/24”是什么意思?
  6. 干货 | 携程旅行App iOS工程编译优化实践
  7. 计算机300分考研能调剂吗,考研调剂的问题
  8. Jenkins邮件通知配置报错问题解决
  9. 数形结合彻底解决2个球100层楼摔坏的问题 .
  10. 如何居中一个div?如何居中一个浮动元素?