SLAM基础知识与算法框架

Eigen 库 | 实现位姿表示

第 3 章 Eigen 库 | 实现位姿表示

3.1 Eigen 库

  官网:[http://eigen.tuxfamily.org][1]。

  文档:[http://eigen.tuxfamily.org/dox/][2]。

  快速参考:[http://eigen.tuxfamily.org/dox/group__QuickRefPage.html][3]。

3.2 Eigen 基本操作

  完整代码:[https://github.com/deng-ke/slam-base/tree/master/EigenMatrix][4]。

3.2.1 模块和头文件

序号 模块 头文件 内容
1 Core #include Matrix/Array类、基础运算
2 Geometry #include 旋转/平移/缩放,2D/3D变换
3 LU #include 求逆,行列式,LU分解
4 Cholesky #include LLT和LDLT Cholesky分解
5 Householder #include Householder变换
6 SVD #include SVD分解
7 QR #include QR分解
8 Eigenvalues #include 特征值/特征向量分解
9 Sparse #include 稀疏矩阵的存储和运算
10 Dense #include 包含了1-4、6-8头文件
11 Eigen #include Dense/Sparse头文件

3.2.2 Matrix

3.2.2.1 矩阵、向量定义

  • 基本定义:矩阵、向量都是 Matrix 模板类的对象,主要使用前三个参数,剩下为默认值。
Eigen::Matrix<float, 2, 3> matrix_23;
Eigen::Matrix<float,3,1> vd_3d;
  • 动态大小:
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > matrix_dynamic1;
Eigen::Matrix< double, 1, Eigen::Dynamic > matrix_dynamic2;
  • 简写定义:typedef 了一些简写:

3_1.jpg

Eigen::Vector3d v_3d;
Eigen::MatrixXd matrix_x;

3.2.2.2 矩阵、向量初始化

  • 直接初始化:
matrix_23 << 1, 2, 3, 4, 5, 6;
  • 初始化为 0:
Eigen::Matrix3d matrix_33 = Eigen::Matrix3d::Zero();

3_2.jpg

3.2.2.3 访问矩阵中的元素

for (int i=0; i<2; i++) {
    for (int j=0; j<3; j++)
        cout<<matrix_23(i,j)<<"\t";
    cout<<endl;
}

3_3.jpg

3.2.3 运算

  • 四则运算:以矩阵和向量相乘为例:
v_3d << 3, 2, 1;
vd_3d << 4,5,6;
Eigen::Matrix<float, 2, 1> result1 = matrix_23 * vd_3d;
cout << "matrix_23 * vd_3d = " << endl << result1 << endl;
Eigen::Matrix<double, 2, 1> result2 = matrix_23.cast<double>() * v_3d;
cout << "matrix_23 * v_3d = " << endl << result2 << endl;  //需显式转换类型

3_4.jpg

  • 其它运算:包括转置、逆、迹等:
cout << "转置:" << endl << matrix_33.transpose() << endl;
cout << "各元素和:" << endl << matrix_33.sum() << endl;
cout << "迹:" << endl << matrix_33.trace() << endl;
cout << "数乘:" << endl << 10*matrix_33 << endl;
cout << "逆:" << endl << matrix_33.inverse() << endl;
cout << "行列式:" << endl << matrix_33.determinant() << endl;
//实对称矩阵可保证对角化成功:
Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigen_solver ( matrix_33.transpose()*matrix_33 );
cout << "特征值和特征向量:" << endl;
cout << "Eigen values = \n" << eigen_solver.eigenvalues() << endl;
cout << "Eigen vectors = \n" << eigen_solver.eigenvectors() << endl;

3_5.jpg

3.2.4 解方程

  两种方法:直接求逆、利用 QR 分解。方法 2 更快。

  • 直接求逆解方程:
clock_t time_stt = clock();
Eigen::Matrix<double,MATRIX_SIZE,1> x = matrix_NN.inverse()*v_Nd;
cout << "直接求逆解方程:" << endl;
cout << "time use=" << endl << 1000* (clock() - time_stt)/(double)CLOCKS_PER_SEC << "ms"<< endl;
cout << "x=" << endl << x << endl;

3_6.jpg

  • 用 QR 分解解方程:
time_stt = clock();
x = matrix_NN.colPivHouseholderQr().solve(v_Nd);
cout << "利用QR分解解方程:" << endl;
cout << "time use=" << endl << 1000*  (clock() - time_stt)/(double)CLOCKS_PER_SEC <<"ms" << endl;
cout << "x=" << endl << x << endl;

3_7.jpg

3.3 Eigen 实现位姿表示

  完整代码:[https://github.com/deng-ke/slam-base/tree/master/EigenGeometry][5]。

  主要用到 Geometry 模块,该模块实现的类,包含旋转矩阵、变换矩阵、旋转向量、欧拉角、四元数等对位姿的描述方式。

3_8.jpg

3.3.1 旋转向量/矩阵

  AngleAxis 定义旋转向量;Matrix3 定义旋转矩阵。两种方式可将旋转向量转换为旋转矩阵。

/***************************************************************************
     *旋转向量/矩阵;旋转向量转换为旋转矩阵
     ***************************************************************************/
    Eigen::AngleAxisd rotation_vector ( M_PI/4, Eigen::Vector3d ( 0,0,1 ) );
    Eigen::Matrix3d rotation_matrix = Eigen::Matrix3d::Identity();
    Eigen::Vector3d v ( 1,0,0 );
    cout.precision(3);
    /*两种方式:旋转向量 to 旋转矩阵*/
    cout<<"rotation matrix =\n"<<rotation_vector.matrix() <<endl;
    rotation_matrix = rotation_vector.toRotationMatrix();
    /*使用旋转向量变换*/
    Eigen::Vector3d v_rotated = rotation_vector * v;
    cout<<"(1,0,0) after rotation = "<<v_rotated.transpose()<<endl;
    /*使用旋转矩阵变换*/
    v_rotated = rotation_matrix * v;
    cout<<"(1,0,0) after rotation = "<<v_rotated.transpose()<<endl<<endl;

3_9.jpg

3.3.2 变换矩阵

/***************************************************************************
     *变换矩阵
     ***************************************************************************/
    /*定义,并用旋转矩阵、平移向量进行初始化*/
    //T为4*4。用于一个旋转3维向量
    Eigen::Isometry3d T=Eigen::Isometry3d::Identity();
    T.rotate ( rotation_vector );
    T.pretranslate ( Eigen::Vector3d ( 1,3,4 ) );
    cout << "Transform matrix = \n" << T.matrix() <<endl;
    /*使用变换矩阵*/
    Eigen::Vector3d v_transformed = T*v;
    cout<<"v tranformed = "<<v_transformed.transpose()<<endl<<endl;

3_10.jpg

3.3.3 欧拉角

/***************************************************************************
     *欧拉角;
     ***************************************************************************/
    Eigen::Vector3d euler_angles = rotation_matrix.eulerAngles ( 2,1,0 );
    cout<<"yaw pitch roll = "<<euler_angles.transpose()<<endl<<endl;

3_11.jpg

3.4 四元数

/***************************************************************************
     *四元数
     ***************************************************************************/
    /*旋转矩阵转换为四元数*/
    Eigen::Quaterniond q = Eigen::Quaterniond ( rotation_vector );
    cout<<"quaternion = \n"<<q.coeffs() <<endl;
    /*旋转向量转换为四元数*/
    q = Eigen::Quaterniond ( rotation_matrix );
    cout<<"quaternion = \n"<<q.coeffs() <<endl;
    /*使用四元数*/
    v_rotated = q*v; //*经过了重载,原本:qvq-1
    cout<<"(1,0,0) after rotation = "<<v_rotated.transpose()<<endl;

3_12.jpg

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
DK的头像-邓轲
相关推荐
  • 暂无相关文章
  • 评论 抢沙发

    请登录后发表评论

      暂无评论内容