C++利用eigen库实现求欧拉角

 更新时间:2023年11月01日 10:02:13   作者:Cc  
这篇文章主要为大家详细介绍了C++如何利用eigen库自带的matrix.eulerAngles()函数实现求欧拉角,文中的示例代码讲解详细,有需要的小伙伴可以参考下

不同顺序欧拉角转旋转矩阵对照公式

eigen库求欧拉角公式

分别试验eigen库自带的matrix.eulerAngles()函数,与根据上述公式推导的两种方法求欧拉角
eigen库求得欧拉角的范围一定是x−>roll方向在[0,π]之间,y−>pitch方向在[−π,π]之间,z−>yaw方向在[−π,π]之间,优先会保证x−>roll方向处于[0,π]之间,才回去算别的角度。

以下代码验证:

#include <iostream>
#include <cmath>
#include <Eigen/Dense>
Quaterniond q(0.704,-0.708,0.05,0.002)//定义一个四元数;
Matrix3d m = q.toRotationMatrix();//四元数转旋转矩阵;
cout << q << endl;
cout << m << endl;
Quaterniond q1(m);//旋转矩阵转四元数,验证下四元数是否和原来输入的四元数一致
cout << q1 << endl;
cout << "XYZ------------" << endl;
Vector3d v=m.eulerAngles(0,1,2);//旋转矩阵转欧拉角,以XYZ为旋转方向
cout << v << endl;
cout << "ZYX------------" << endl;
Vector3d v1=m.eulerAngles(2,1,0);//旋转矩阵转欧拉角,以ZYX为旋转方向
cout << v1 << endl;
Vector3d v2;

输出的结果为

-0.708i + 0.05j + 0.002k + 0.704//四元数
 0.994992 -0.073616  0.067568
-0.067984 -0.002536  0.997064
-0.073232 -0.996664 -0.007528//旋转矩阵
-0.70756i + 0.049969j + 0.00199876k + 0.704437//四元数
XYZ------------//先转x
 1.56325//x roll
 3.07397//y pitch
-3.06774//z yaw
ZYX------------//先转z
3.07337// z yaw
3.06825//y pitch
1.56324//x roll

可以看到以上两种旋转顺序情况下用eigen库自带的matrix.eulerAngles()函数会使得z yaw,y pitch方向上计算的欧拉角数值增大,不利于机器人做角度控制,原本机器人可能朝反方向转很小的一个角度,可能现在需要转很大一圈。

用公式推导编写的代码:

//接着上面代码段补充运行即可
double sy=sqrt(m(0,0) * m(0,0) +  m(0,1) * m(0,1));
        if (sy>0.00001)//判断万向锁奇异
        {
            v2(0) = std::atan2(-m(1, 2), m(2, 2));
            v2(1) = std::atan2(m(0, 2), sy);
            v2(2) = std::atan2(-m(0, 1), m(0, 0));
        }
        else//奇异
        {
            v2(0) = 0;
            v2(1) = std::atan2(m(0, 2), sy);
            v2(2) = std::atan2(-m(1, 0), m(2, 0));
        }
cout << "XYZ------------" << endl;
cout << v2 << endl;
        if (sy>0.00001)//判断万向锁奇异
        {
            v2(0) = std::atan2(m(2, 1), m(2, 2));
            v2(1) = std::atan2(m(2, 0), sy);
            v2(2) = std::atan2(-m(1, 0), m(0, 0));
        }
        else//奇异
        {
            v2(0) = std::atan2(-m(1, 2), m(1, 1));;
            v2(1) = std::atan2(m(2, 0), sy);
            v2(2) = 0;
        }
cout << "ZYX------------" << endl;
cout << v2 << endl;

输出结果:

XYZ------------
 -1.57835//x
0.0676197//y
 0.073852//z
ZYX------------
  -1.57835  //注意这里还是x,与`eigen`库自带的`matrix.eulerAngles()`出来的顺序不一样
-0.0732686
 0.0682201//注意这里还是z

这里角度明显小很多,两种不同的方法的结果可以通过加减π得到,但是XYZ、ZYX两种不同顺序下的结果还不一样

因此建议直接用公式推导出来的方法。

到此这篇关于C++利用eigen库实现求欧拉角的文章就介绍到这了,更多相关C++求欧拉角内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++ 继承的范例讲解

    C++ 继承的范例讲解

    继承是C++面向对象编程中的一门。继承是子类继承父类的特征和行为,或者是继承父类得方法,使的子类具有父类得的特性和行为。重写是子类对父类的允许访问的方法实行的过程进行重新编写,返回值和形参都不能改变。就是对原本的父类进行重新编写,但是外部接口不能被重写
    2022-06-06
  • C语言之浮点数的表示与储存方式

    C语言之浮点数的表示与储存方式

    这篇文章主要介绍了C语言之浮点数的表示与储存方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-03-03
  • 一文带你深入了解C++中的类型转换

    一文带你深入了解C++中的类型转换

    在C语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与接收返回值类型不一致时,就需要发生类型转化。本文主要介绍了C++中常见的四个类型转换,需要的可以参考一下
    2022-12-12
  • C++实现LeetCode(76.最小窗口子串)

    C++实现LeetCode(76.最小窗口子串)

    这篇文章主要介绍了C++实现LeetCode(76.最小窗口子串),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • C语言超详细讲解线性表

    C语言超详细讲解线性表

    线性表,数据结构中最简单的一种存储结构,专门用于存储逻辑关系为"一对一"的数据。线性表是基于数据在实际物理空间中的存储状态,又可细分为顺序表(顺序存储结构)和链表
    2022-07-07
  • C++中单链表的建立与基本操作

    C++中单链表的建立与基本操作

    以下是对C++中单链表的建立与基本操作进行了详细的介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2013-10-10
  • C++中的各种容器的使用方法汇总

    C++中的各种容器的使用方法汇总

    这篇文章主要介绍了C++中的各种容器的使用方法,本文结合示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-01-01
  • C++ const引用、临时变量 引用参数详解

    C++ const引用、临时变量 引用参数详解

    下面小编就为大家带来一篇C++ const引用、临时变量 引用参数详解。小编觉得挺不错的现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-01-01
  • OpenCV实现帧间差分法详解

    OpenCV实现帧间差分法详解

    这篇文章主要为大家详细介绍了OpenCV实现帧间差分法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • C/C++中CONST用法总结(推荐)

    C/C++中CONST用法总结(推荐)

    这篇文章主要介绍了C/C++中CONST用法总结(推荐),包括const常量与define宏定义的区别介绍,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2017-07-07

最新评论