第4講 李羣和李代數2

第一部分:SO(3)和so(3)

1、SO(3)對應的李代數\large so(3)

      SO(3)對應的李代數是定義在\large \mathbb{R}^{3}上向量,我們記作\large \phi。根據上一篇博客中的推導,可以知道,每個\large \phi都可以生成一個反對稱矩陣:

\large \Phi =\phi ^{\Lambda }=\begin{bmatrix} 0 & -\phi_{3} & \phi_{2} \\ \phi_{3} & 0 & -\phi_{1} \\ -\phi_{2} & \phi_{1} & 0 \end{bmatrix} \epsilon \mathbb{R}^{3*3}

在此定義下,兩個向量\large \phi_{1},\phi_{2}的李括號(運算)爲:

\large [\phi_{1},\phi_{2}]=[\Phi_{1}\Phi_{2}-\Phi_{2}\Phi_{1}]^{\vee }

由於\large \phi和反對稱矩陣關係很緊密,在不引起歧義的情況下,可以說\large so(3)的元素是三維向量或者三維反對稱矩陣,即:

\large so(3)= \begin{Bmatrix} \phi\epsilon \mathbb{R}^{3},\Phi =\phi^{\Lambda }\epsilon \mathbb{R}^{3*3} \end{Bmatrix}

到此,我們已經清楚了SO(3)對應的李代數\large so(3)的內容,它們是一個由三維向量組成的集合,其中每個向量都可以對應到三維反對稱矩陣,可以表達旋轉矩陣的導數。它和SO(3)的關係由指數映射給定:\large R=exp(\phi^{\Lambda })

2、SO(3)上的指數映射

      由上面的內容可以知道,SO(3)中的每個元素都有對應的李代數,它們之間的關係由指數映射給定:   \large R=exp(\phi^{\Lambda })。那麼它具體應該怎麼去計算呢?

(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)數學上的計算推導

通過上面的推導得到了計算\large R=exp(\phi^{\Lambda })的公式:

\exp(\phi ^{\Lambda }) = \exp(\theta a^{\Lambda }) =\cos\theta I+(1-\cos\theta )aa^{T}+\sin\theta a^{\Lambda }

說明:實際上,這個公式和第3講中講到的“羅德里格斯公式 --- 描述旋轉矩陣和旋轉向量的轉換過程”形式相同,這表明,so(3)實際上就是由所謂的 旋轉向量 組成的空間,而指數映射公式即羅德里格斯公式。

3、從SO(3) ---> so(3) :對數映射

\phi =(\ln R)^{\vee }=[\sum_{n=0}^{\infty }\frac{(-1)^{n}}{n+1}(R-I)^{n+1}]^{\vee }

 

第二部分:SE(3)和se(3)

1、SE(3)對應的李代數\large se(3)

與上面相似的是SE(3),也有對應的李代數\large se(3)與上面最大的不同是\large {\color{Red} se(3)}位於\large {\color{Red} \mathbb{R}^6}空間中,\large {\color{Red} so(3)}位於\large {\color{Red} \mathbb{R}^3}空間中。

下面直接給出\large se(3)的內容,如下:

對上式的說明:

(1)\large \vec{\xi }是一個6維向量

(2)\large \vec{\xi }向量的前3維\large \rho表示平移(注意和變換矩陣中平移不同,後面會解釋)

(3)\large \vec{\xi }向量的後3維\large \phi表示旋轉,實際上是\large so(3)中的元素。

(4)在這裏\large \Lambda符號的含義不同了,在\large so(3)中是將3維向量映射成爲3*3反對稱矩陣,在這裏是將一個6維向量映射稱爲一個4*4的矩陣,並且不再表示反對稱了。

\large se(3)中,也有類似的李括號運算:

\large [\xi _{1},\xi _{2}]=(\xi _1^{\Lambda} \xi _2^{\Lambda }- \xi _2^{\Lambda }\xi _1^{\Lambda})^{\vee }

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)上的指數映射公式:

exp(\xi ^{\Lambda })=\begin{bmatrix} \sum_{n=0}^{\infty }\frac{1}{n!} (\phi ^{\Lambda })^{n}&\sum_{n=0}^{\infty }\frac{1}{(n+1)!} (\phi ^{\Lambda })^{n} \textbf{p} \\ 0^{T} & 1 \end{bmatrix} \doteq \begin{bmatrix} R & \textbf{J}\textbf{P} \\ 0^{T} & 1 \end{bmatrix} =T

下面說一下關於\textbf{J}的整理:

我們可以這樣理解:平移部分經過指數映射之後,還發生了一次以\textbf{J}爲係數矩陣的線性變換。

(3)對數映射

這裏沒有給出直接的公式,但是給出了對數映射的計算思路。

關於對數和指數映射就先到這裏了。下一篇會開始李代數求導和擾動模型的學習。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章