Eigen使用的坑

先记录一个很详细的博客,还没完全看懂,后面再看

欧拉角、四元数、旋转矩阵推导及相互关系

1、切记Eigen的类型不会自动转换 

YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY

2、Eigen中的向量其实就是单行矩阵,就是这么定义的

typedef float T;
typedef Eigen::Matrix<T, 3, 1> Vector3t;
typedef Eigen::Matrix<T, 4, 4> Matrix4t;
typedef Eigen::Matrix<T, Eigen::Dynamic, 1> VectorXt;//列向量,列数是1 

3、欧拉角转四元数&&四元数转欧拉角

float roll = 1.5707, pitch = 0, yaw = 0.707;
Quaternionf q;
q = AngleAxisf(roll, Vector3f::UnitX())
	* AngleAxisf(pitch, Vector3f::UnitY())
	* AngleAxisf(yaw, Vector3f::UnitZ());
std::cout << "Quaternion" << std::endl << q.coeffs() << std::endl;
std::cout << q.matrix().eulerAngles(0,1,2) << endl;

4、角速度不能用欧拉角旋转表示,这是在跟自己自找麻烦!!!!为什么不先用简单的来让自己少犯错误呢??

这里在由增量角度计算四元数时,应该不是绕固定轴转的,就是正常的绕某个顺序转的,但是我从惯导拿到的角速度确是围绕固定轴算的,是真真正正的单轴的,所以会出错!!!

自己之所以一开始算的数值相差比较小,是因为在水平面上,roll和pitch都比较小,导致这两个值对yaw的影响比较小!!!

详见下面程序输出,如果把roll,pitch,以及droll,dpitch都改小一点,差别就不大了

#include<Eigen\Dense>
#include<iostream>
using namespace Eigen;
using namespace std;

int main(int argc, char **argv)
{

	//原始角度
	float roll=1, pitch=1, yaw=1.4;
	Quaternionf q;
	q = AngleAxisf(roll, Vector3f::UnitX())
		* AngleAxisf(pitch, Vector3f::UnitY())
		* AngleAxisf(yaw, Vector3f::UnitZ());
	std::cout <<"原始角度:"<<endl<< q.matrix().eulerAngles(0, 1, 2) << endl;
	//std::cout << "四元数:" << std::endl << q.coeffs() << std::endl;

	//角度增量
	float droll=0.1, dpitch=0.1, dyaw=0.8;
	cout << "角度增量:" << droll << " " << dpitch << " " << dyaw << endl;
	Quaternionf dq;
	dq = AngleAxisf(droll, Vector3f::UnitX())
		* AngleAxisf(dpitch, Vector3f::UnitY())
		* AngleAxisf(dyaw, Vector3f::UnitZ());

	Vector3f angles = (q*dq).matrix().eulerAngles(0, 1, 2);//roll pitch yaw
	cout <<"由角度增量算出的角度"<< roll + droll << " " << pitch + dpitch << " " << yaw + dyaw << endl;
	cout << "使用四元数算出的角度: " <<endl<< angles << endl;
}

5、又一个坑!!!

这里给了自己一个很好的教训,先拿一些特殊例子看看,不要一开始就0 0 0

	Vector3f next_angles = angles + raw_gyro * dt;
	next_angles << 6.28, 0.0001, 0;
	cout << "next_angles1: " << next_angles << endl;

	Quaternionf qt_ = AngleAxisf(next_angles[0], Vector3f::UnitX())
		* AngleAxisf(next_angles[1], Vector3f::UnitY())
		* AngleAxisf(next_angles[2], Vector3f::UnitZ());
	qt_.normalize();
	cout << "qt_: " << qt_.coeffs() << endl;
	cout << "next_angles2: " <<qt_.matrix().eulerAngles(0, 1, 2) << endl;

输出结果: 

 本来输入的相当于0,0,0,但是结果却相差了PI。这是由于四元数表示的三维的旋转,而不是表示一个角度。

图例分析:

就跟名词和动词的区别一样。由惯导读出的欧拉角,其本来是表示一个角度,是一个名词。但是当表示旋转时,欧拉角的特定顺序也赋予了它能够表示旋转的功能,换句话说,roll,pitch,yaw不仅能表示一个姿态,也能表示一个旋转。当它表示一个姿态的时候,旋转的固定轴是没有发生变化的;但是当它表示一个旋转动作的时候,在它转换为四元数或者旋转矩阵时,其旋转轴发生了变换!!!

我所迷惑的是,我记得有两种转换方式,一种是绕固定轴,一种是绕自己的轴,那么到底是按哪个轴的???谁能解答一下

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt 是一个强大的跨平台应用程序开发框架,而 Eigen 是一个高性能的线性代数库。在 Qt 开发中,你可以使用 Eigen 来增强图形处理、数学运算和数据分析等功能,特别是在处理矩阵和向量计算时。 将 Eigen 集成到 Qt 应用中,通常涉及以下几个步骤: 1. **安装 Eigen**:首先确保你的系统已经安装了 Eigen,可以通过包管理器或直接从 Eigen 官网下载源代码编译。 2. **包含头文件**:在你的 Qt 项目中,添加 Eigen 的头文件 `<Eigen/Dense>` 或 `<Eigen/Sparse>`,取决于你需要的线性代数类型。 3. **使用 Eigen 类型**:创建 Eigen 的矩阵(`MatrixXd`、`VectorXd`)或向量(`Vector3d`)实例,它们提供了丰富的数学操作方法,如矩阵乘法、转置、求逆等。 4. **连接信号槽**:如果你需要在 Qt 控件的事件响应中使用 Eigen,可能需要将 Eigen 的计算结果与 Qt 对象绑定起来。 5. **模板和智能指针**:Eigen 提供了模板类,可以方便地与 Qt 的智能指针(如 `QSharedPointer` 或 `std::unique_ptr`)一起使用,以避免内存泄漏。 6. **性能优化**:尽管 Eigen 已经是高效库,但在大规模计算时,仍需考虑内存管理和并行计算,Qt 的多线程支持可以在此时发挥作用。 相关问题: 1. Eigen 在 Qt 中主要用于哪些数学计算? 2. 如何在 Qt 的信号槽连接中使用 Eigen 的结果? 3. Eigen 的模板类如何与 Qt 智能指针配合使用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值