Eigen中eulerAngles()得到欧拉角的奇异问题
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()得到欧拉角的奇异问题相关推荐
- Eigen中的混叠(aliasing)问题
Eigen中的混叠(aliasing)问题 Eigen中aliasing指的是在赋值表达式的左右两边存在矩阵的重叠区域,这种情况下,有可能得到非预期的结果.如mat = 2*mat或者mat = ma ...
- [矩阵的三角分解系列六] Eigen中的三角分解
Eigen中的三角分解 简介 安装命令 三角分解函数 使用范例 矩阵的三角分解是求解线性方程组常用的方法,包括LU分解,LDU分解,杜利特(Doolittle)分解,克劳特(Crout)分解,LLT( ...
- [Eigen中文文档] 矩阵与向量运算
专栏总目录 本文目录 介绍 加法与减法 标量的标量乘法与除法 表达式模板 转置与共轭 (矩阵与矩阵)和(矩阵与向量)的乘积 点积和叉积 基本算术的简化运算 操作的有效性 英文原文(Matrix and ...
- eigen 编译_头条 | 使用eigen实现四元数、欧拉角、旋转矩阵、旋转向量间的转换...
点击上方蓝字,关注本公众号,获得更多资源上一篇文章介绍了四元数.欧拉角.旋转矩阵.轴角如何相互转换,本篇文章介绍如何用eigen来实现. 旋转向量 1,初始化旋转向量:旋转角为alpha,旋转轴为(x ...
- Eigen中四元数Quaterniond的初始
Quaterniond的初始 Eigen::Quaterniond q1(w, x, y, z);// 第一种方式Eigen::Quaterniond q2(Vector4d(x, y, z, w)) ...
- 万向节死锁_欧拉角的奇异问题和万向节死锁问题,会对实际的哪些应用带来什么问题?...
谢邀,这个问题打算认真回答一次,所以要准备准备,先留个爪子,后面娓娓道来,先简单点的说几句,起个头: 1.俯仰角90°的这个问题,又或者有时候我们称呼为横滚角,我一般会用横滚角说超过90°,这是依据实 ...
- [Eigen中文文档] 归约、访问者和广播
专栏总目录 本文目录 归约 范数计算 布尔归约 用户自定义的归约 访问者函数 局部归约 将局部归约与其他操作结合 广播 将广播与其他操作结合 英文原文(Reductions, visitors and ...
- [Eigen中文文档] 切片和索引
专栏总目录 本文目录 概述 基本的切片 编译时的大小和步长 倒序 索引序列 自定义索引列表 英文原文(Slicing and Indexing) 本文介绍了如何使用操作运算符operator()索引行 ...
- ROS中四元数、欧拉角、旋转矩阵等格式转换
未完- ROS接收到odometry格式消息: nav_msgs::Odometry pos_msg 具有: pos_msg.pose.pose.orientation.x; // xyzw pos_ ...
最新文章
- mysql mairadb skysql
- 寄存器理解 及 X86汇编入门
- push的时候 出现卡顿现象
- 程序员面试系列——大小端
- Linux怎么查看设置系统语言包
- proxy跨域不生效_vue前后端端口号不同,proxytable代理跨域无效
- linux 安装ftp下载,LINUX FTP安装与配置
- ImageLoader加载图片
- linux怎么运行g77,Linux安装g77编译器的技巧
- 一级计算机新增题库2上网题图解,计算机一级《MS Office》上机操作题题库(2)
- python数据结构与算法分析 第2版_题库 | 百度数据结构 / 算法面试题型介绍及解析 第 2 期...
- namp - 端口扫描 主机判断 漏洞分析
- ap_invoice_distributions_all与PO表关联问题
- HTML+CSS+JavaScript实现放大镜效果
- Auto.js:实现蚂蚁森林自动收能量(懒人的高效生活)
- [Linq] Linq如何调用外部方法?
- OpenGL 开始学习指南
- 15 python的文件操作
- 申请支付宝授权,提现测试环境步骤
- 单体对象 Singleton Object 提供的顶层方法
热门文章
- 关于打开虚拟机vmware镜像就蓝屏(注:主要针对轻薄本本以及高性能游戏本)
- 图像隐写,如何在图像中隐藏二维码
- HTML零基础快速入门(详细教程)
- 举一个在网上书店系统中的数据库存储过程设计的例子
- IP地址:10.10.1.1/24的“/24”是什么意思?
- 干货 | 携程旅行App iOS工程编译优化实践
- 计算机300分考研能调剂吗,考研调剂的问题
- Jenkins邮件通知配置报错问题解决
- 数形结合彻底解决2个球100层楼摔坏的问题 .
- 如何居中一个div?如何居中一个浮动元素?