第一部分:SO(3)和so(3)
1、SO(3)對應的李代數
SO(3)對應的李代數是定義在上向量,我們記作
。根據上一篇博客中的推導,可以知道,每個
都可以生成一個反對稱矩陣:
在此定義下,兩個向量的李括號(運算)爲:
由於和反對稱矩陣關係很緊密,在不引起歧義的情況下,可以說
的元素是三維向量或者三維反對稱矩陣,即:
到此,我們已經清楚了SO(3)對應的李代數的內容,它們是一個由三維向量組成的集合,其中每個向量都可以對應到三維反對稱矩陣,可以表達旋轉矩陣的導數。它和SO(3)的關係由指數映射給定:
2、SO(3)上的指數映射
由上面的內容可以知道,SO(3)中的每個元素都有對應的李代數,它們之間的關係由指數映射給定: 。那麼它具體應該怎麼去計算呢?
(1)再進入真正的計算公式的推導之前,首先來看一下如何利用Sophus庫來進行李羣和李代數的運算,因爲這比較簡單。
Eigen提供了幾何模塊,但是沒有提供對李代數的支持。Sophus是一個較好的李代數庫,它是Strasdat維護的,基於Eigen開發的,能夠較好的支持SO(3)、SE(3),此外還能夠支持SO(2)、SE(2)。
關於Sophus庫的配置在百度上可以找到很多教程,這裏不記錄了。下面是一個調用Sophus庫進行李代數運算的例子。
#include <iostream>
//Eigen
#include <Eigen/Core>
#include <Eigen/Geometry>
//Sophus
#include "sophus/so3.h"
using namespace std;
int main(int argc, char **argv)
{
//定義一個沿Z軸轉90度的旋轉
Eigen::Matrix3d R = Eigen::AngleAxisd(M_PI/2, Eigen::Vector3d(0,0,1)).toRotationMatrix();
//可以直接從旋轉矩陣構造SO(3)
Sophus::SO3 SO3_R(R);
//也可以直接從旋轉向量構造SO(3)
Sophus::SO3 SO3_V(0, 0, M_PI/2);
//也可以從四元數構造SO(3)
Eigen::Quaterniond q(R);
Sophus::SO3 SO3_Q(q);
//輸出SO(3)的時候,是以so(3)的形式顯示的
cout << "SO(3) from rotation_matrix : " << SO3_R << endl;
cout << "SO(3) from rotation_vector : " << SO3_V << endl;
cout << "SO(3) from quaternion : " << SO3_Q << endl;
//SO(3)---> so(3) 對數映射
Eigen::Vector3d so3 = SO3_R.log();
cout << "SO3_R.log() = " << so3 << endl;
//hat ---> 從三維向量到三維反對稱矩陣的運算
cout << "so3 hat = " << Sophus::SO3::hat(so3) << endl;
//vee ---> 從三維反對稱矩陣到三維向量
cout << "so3 hat vee = "<< Sophus::SO3::vee(Sophus::SO3::hat(so3)).transpose() << endl;
return 0;
}
下面是CMakeLists.txt的內容:
cmake_minimum_required(VERSION 3.5)
project(use_sophus)
find_package(Sophus REQUIRED)
include_directories(
${Sophus_INCLUDE_DIRS}
)
add_executable(useSophus
useSophus.cpp
)
target_link_libraries(useSophus
${Sophus_LIBRARIES}
)
(2)數學上的計算推導
通過上面的推導得到了計算的公式:
說明:實際上,這個公式和第3講中講到的“羅德里格斯公式 --- 描述旋轉矩陣和旋轉向量的轉換過程”形式相同,這表明,so(3)實際上就是由所謂的 旋轉向量 組成的空間,而指數映射公式即羅德里格斯公式。
3、從SO(3) ---> so(3) :對數映射
第二部分:SE(3)和se(3)
1、SE(3)對應的李代數
與上面相似的是SE(3),也有對應的李代數。與上面最大的不同是
位於
空間中,
位於
空間中。
下面直接給出的內容,如下:
對上式的說明:
(1)是一個6維向量
(2)向量的前3維
表示平移(注意和變換矩陣中平移不同,後面會解釋)
(3)向量的後3維
表示旋轉,實際上是
中的元素。
(4)在這裏符號的含義不同了,在
中是將3維向量映射成爲3*3反對稱矩陣,在這裏是將一個6維向量映射稱爲一個4*4的矩陣,並且不再表示反對稱了。
在中,也有類似的李括號運算:
2、SE(3)上的指數映射
(1)同樣的,首先來看一下如何調用Sophus庫來進行SE(3)和se(3)的相互運算。
#include <iostream>
//Eigen
#include <Eigen/Core>
#include <Eigen/Geometry>
//sophus
#include "sophus/se3.h"
using namespace std;
int main(int argc, char **argv)
{
//可以從旋轉矩陣,平移向量構造SE3
Eigen::Matrix3d rotation_matrix = Eigen::AngleAxisd(M_PI/2, Eigen::Vector3d(0, 0, 1)).toRotationMatrix();
Eigen::Vector3d t(1, 0, 0);
Sophus::SE3 SE3_RT(rotation_matrix, t);
//也可以從四元數,平移向量構造SE3
Eigen::Quaterniond q(rotation_matrix);
Sophus::SE3 SE3_QT(q, t);
cout << "SE3_RT = " << SE3_RT << endl;
cout << "SE3_QT" << SE3_QT << endl;
//SE3 --- se(3) : 對數映射
typedef Eigen::Matrix<double, 6, 1> Vector6d;
Vector6d se3 = Sophus::SE3::log(SE3_RT);
cout << "se3 = " << se3.transpose() << endl;
//同樣的,在SE3中也有 hat 和 vee 這兩個運符
cout << "se3 hat = " << "\n" << Sophus::SE3::hat(se3) << endl;
cout << "SE3 vee = " << "\n" << Sophus::SE3::vee(Sophus::SE3::hat(se3)) << endl;
return 0;
}
(2)數學公式推導
這裏直接給出se(3)上的指數映射公式:
下面說一下關於的整理:
我們可以這樣理解:平移部分經過指數映射之後,還發生了一次以爲係數矩陣的線性變換。
(3)對數映射
這裏沒有給出直接的公式,但是給出了對數映射的計算思路。
關於對數和指數映射就先到這裏了。下一篇會開始李代數求導和擾動模型的學習。