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看看