• Sophus和Eigen 李群李代数 简单介绍


    Sophus中似乎没有李代数的表示(尽管库中都用SE3、SO3,但是对于这个库,作者似乎表达的是李群的意思);比如你定义一个李群,要将他表示成李代数。

    可以这样写:

    1 Sophus::SE3 SE3_;
    2 typedef Eigen::Matrix<double, 6, 1> Vector6d;
    3 Vector6d se3 = SE3_.log; 

    此外SE3的构造方式也可以是:

    cv::solvePnPRansac(pts3d, pts2d, K, Mat(), rvec, tvec, false, 100, 1.0, 0.99, inliers);
    
    T_c_w_estimated_ = SE3(
                     SO3(rvec.at<double>(0, 0), rvec.at<double>(1, 0), rvec.at<double>(2, 0)),
                Vector3d(tvec.at<double>(0, 0), tvec.at<double>(1, 0), tvec.at<double>(2, 0))
            );
     1 #include <iostream>
     2 #include <cmath>
     3 using namespace std;
     4 
     5 #include<opencv2\opencv.hpp>
     6 
     7 #include <Eigen/Core>
     8 #include <Eigen/Geometry>
     9 
    10 #include "so3.h"
    11 #include "se3.h"
    12 
    13 #define M_PI  3.1415926535897932384626433832795
    14 //CV_PI
    15 
    16 //参考 : https://www.cnblogs.com/gaoxiang12/p/5137454.html
    17 
    18 int main(int argc, char** argv)
    19 {
    20     // 沿Z轴转90度的旋转矩阵
    21     Eigen::Matrix3d R = Eigen::AngleAxisd(M_PI / 2, Eigen::Vector3d(0, 0, 1)).toRotationMatrix();
    22 
    23     //SO3:旋转矩阵群
    24     Sophus::SO3 SO3_R(R);               // Sophus::SO(3)可以直接从旋转矩阵构造
    25     Sophus::SO3 SO3_v(0, 0, M_PI / 2);  // 亦可从旋转向量构造
    26     Eigen::Quaterniond q(R);            // 或者四元数
    27     Sophus::SO3 SO3_q(q);
    28     // 上述表达方式都是等价的
    29     // 输出SO(3)时,以so(3)形式输出
    30     cout << "SO(3) from matrix: " << SO3_R << endl;
    31     cout << "SO(3) from vector: " << SO3_v << endl;
    32     cout << "SO(3) from quaternion :" << SO3_q << endl;
    33 
    34     // 使用对数映射获得它的李代数
    35     Eigen::Vector3d so3 = SO3_R.log();
    36     cout << "李代数 so3 = " << so3.transpose() << endl;
    37     cout << "李  群 SO3 = " << Sophus::SO3::exp(so3) << endl;
    38     // hat 为向量到反对称矩阵
    39     cout << "so3 hat=\n" << Sophus::SO3::hat(so3) << endl;
    40     // 相对的,vee为反对称到向量
    41     cout << "so3 hat vee= " << Sophus::SO3::vee(Sophus::SO3::hat(so3)).transpose() << endl; // transpose纯粹是为了输出美观一些
    42 
    43                                                                                             // 增量扰动模型的更新
    44     Eigen::Vector3d update_so3(1e-4, 0, 0); //假设更新量为这么多
    45     Sophus::SO3 SO3_updated = Sophus::SO3::exp(update_so3)*SO3_R;
    46     cout << "SO3 updated = " << SO3_updated << endl;
    47 
    48     /********************萌萌的分割线*****************************/
    49     cout << "************我是分割线*************" << endl;
    50     // 对SE(3)操作大同小异
    51     Eigen::Vector3d t(1, 0, 0);           // 沿X轴平移1
    52     Sophus::SE3 SE3_Rt(R, t);           // 从R,t构造SE(3)
    53     Sophus::SE3 SE3_qt(q, t);            // 从q,t构造SE(3)
    54     cout << "SE3 from R,t= " << endl << SE3_Rt << endl;
    55     cout << "SE3 from q,t= " << endl << SE3_qt << endl;
    56     // 李代数se(3) 是一个六维向量,方便起见先typedef一下
    57     typedef Eigen::Matrix<double, 6, 1> Vector6d;
    58     Vector6d se3 = SE3_Rt.log();
    59     cout << "李代数 se3 = " << se3.transpose() << endl;
    60     cout << "李  群 SE3 = " << Sophus::SE3::exp(se3) << endl;
    61     // 观察输出,会发现在Sophus中,se(3)的平移在前,旋转在后.
    62     // 同样的,有hat和vee两个算符
    63     cout << "se3 hat = " << endl << Sophus::SE3::hat(se3) << endl;
    64     cout << "se3 hat vee = " << Sophus::SE3::vee(Sophus::SE3::hat(se3)).transpose() << endl;
    65 
    66     // 最后,演示一下更新
    67     Vector6d update_se3; //更新量
    68     update_se3.setZero();
    69     update_se3(0, 0) = 1e-5;
    70     Sophus::SE3 SE3_updated = Sophus::SE3::exp(update_se3)*SE3_Rt;
    71     cout << "SE3 updated = " << endl << SE3_updated.matrix() << endl;
    72     cout << "SE3 updated = " << endl << SE3_updated << endl;
    73 
    74     cout << "the rotation_matrix of the SE3 updated = " << endl << SE3_updated.rotation_matrix() << endl;
    75     cout << "the translation of the SE3 updated = " << endl << SE3_updated.translation() << endl;


             // Eigen 变换矩阵T 与 李群
             Eigen::Isometry3d T = Eigen::Isometry3d::Identity();
             T.rotate(SE3_updated.rotation_matrix());
             T.pretranslate(SE3_updated.translation());

             cout << "the rotation_matrix of T = " << endl << T.rotation() << endl;
             cout << "the translation of T = " << endl << T.translation() << endl;

    76     return 0;
    77 }

    调试结果:自己看IDE看看

  • 相关阅读:
    python开源项目聚合推荐【1】
    python开发--Python实现延时操作的几种方式
    odoo开发笔记 -- 单台物理服务器上,利用docker部署多套odoo应用
    odoo开发笔记 -- odoo官方docker启动原理
    odoo开发笔记 -- odoo官方docker镜像部署
    odoo开发笔记 -- 借助模块queue_job实现异步方法调用
    odoo开发笔记 -- 提高访问安全性的一种方式
    python开发笔记-pymsslq连接操作SqlServer数据库
    运维笔记--Debian/Ubuntu系统离线安装pymssql,连接SqlServer
    python开发笔记-str转字典
  • 原文地址:https://www.cnblogs.com/winslam/p/9210277.html
Copyright © 2020-2023  润新知