zoukankan      html  css  js  c++  java
  • 第4章 李群李代数

    一、概述

    1. 李群和李代数的核心思想

      1. 可以理解为专门用于矩阵旋转的东西,符合封结幺逆法则;

      2. 李群可以理解为旋转矩阵,李代数可以理解为旋转向量

      3. 李群是连续群,李代数可以表出李群的导数,所以李代数表示的是李群的局部性质;

      4. 进而我们可以理解为:旋转向量表达了旋转矩阵的局部(旋转发生那一瞬间的领域内)性质;

      5. 由拉格朗日中值定理可知:导数控制函数。李代数控制李群,(phi)控制(R)【1】

        也就是说想要估计出函数值,我们可以研究该函数的导数,用来描述某个点领域内性质。故而我们需要建立对李群的求导模型,通过分析导数的性质来估计出相机在这一时刻(领域内)的位姿。

        但是我们知道是指只有一个运算的集合(我们选择矩阵乘法),所以李群不对加法封闭【2】,但是我们知道李代数是建立在向量空间上的,支持加法运算。所以我们需要一种让李群映射到李代数的机制,然后通过对李代数求导,求出李群的导数。不过,对李代数求导后的结果非常复杂,所以我们需要寻找另外一种求导方式【3】,这就是我们接下来所要介绍的内容。

        【注】

        【1】:某个名牌大学考研的复试题——你知道导数的作用是什么吗?

        【2】:李群也是一种群。甭跟我扯什么鳄鱼不是鱼、日本人不是人。

        【3】:对谁求导不重要,因为我们总可以通过这个导数控制相同的函数。

    2. 李群的两种求导模型(都是映射到了李代数空间)

      1. BCH公式线性化(将李群的变化与李代数的变化联系起来);

      2. 对李代数求导的求导模型;(复杂)

        1. 需要求出左右雅可比矩阵的逆;
      3. 对微扰动求导的扰动模型;(精简)

        1. 不需要求出左右雅可比矩阵的逆;
    3. 这两种求导模型都是会有误差存在的

    4. 李群和李代数的基础符号

      1. 特殊正交群(SO(3)),特殊欧式群(SE(3))

      2. 特殊正交群上的李代数(mathfrak{so}(3)),这里我们具象化为三维(phi)向量或者反对称阵(widehat{phi})

        李代数so(3)的定义

      3. 特殊欧式群上的李代数(mathfrak{se}(3)),这里我们具象化为六维(xi)向量或者四维方阵(widehat{xi})

        李代数se(3)的定义

        ( ho)表示三维空间中的平移,(phi)表示三维空间中的旋转。

      4. 反对称矩阵与相应的三维向量:(wedge)(vee)

        反对称矩阵与相应的三维向量

      5. 向量(overrightarrow{a})(overrightarrow{omega})都表示旋转向量的单位方向向量,( heta)表示旋转角,(overrightarrow{phi})表示旋转向量,(R)表示旋转矩阵;

      6. 有时为了格式不显得过于复杂,会省略掉向量标识(overrightarrow{})

    5. Sophus库的使用

      1. (SO(3))(mathfrak{so}(3))

        // 构造旋转向量、旋转矩阵、四元数
        Eigen::AngleAxisd RV = Eigen::AngleAxisd(M_PI/2, Eigen::Vector3d(0,0,1));
        Eigen::Matrix3d RM = RV.toRotationMatrix();
        Eigen::Quaterniond QD(RM);
        // 通过上述旋转表述构造李群
        Sophus::SO3d SO3_RM(RM);
        Sophus::SO3d SO3_QD(QD);
        // 输出SO(3)时,以so(3)形式输出
        cout << "SO(3) from matrix    :" << SO3_RM.log().transpose() << endl;
        cout << "SO(3) from quaternion:" << SO3_QD.log().transpose() << endl;
        
        // 使用对数映射获得它的李代数
        Eigen::Vector3d so3 = SO3_RM.log();
        cout << "so3 = " << so3.transpose() << endl;
        // hat为向量到反对称矩阵
        cout << "so3 hat=" << endl << Sophus::SO3d::hat(so3) << endl;
        // vee为反对称矩阵到向量
        cout << "so3 hat vee= " << Sophus::SO3d::vee(Sophus::SO3d::hat(so3)).transpose() << endl; 
        
        // 增量扰动模型的更新
        Eigen::Vector3d update_so3(1e-4, 0, 0);
        Sophus::SO3d SO3_updated = Sophus::SO3d::exp(update_so3) * SO3_RM;
        cout << "SO3 updated = " << endl << SO3_updated.matrix() << endl;
        
      2. (SE(3))(mathfrak{se}(3))

        // 构造旋转向量、旋转矩阵、四元数
        Eigen::AngleAxisd RV = Eigen::AngleAxisd(M_PI/2, Eigen::Vector3d(0,0,1));
        Eigen::Matrix3d RM = RV.toRotationMatrix();
        Eigen::Quaterniond QD(RM);
        // 通过上述旋转表述构造李群
        Sophus::SO3d SO3_RM(RM);
        Sophus::SO3d SO3_QD(QD);
        // 对SE(3)操作大同小异
        Eigen::Vector3d t(1,0,0);           // 沿X轴平移1
        Sophus::SE3d SE3_RMt(RM, t);           // 从R,t构造SE(3)
        Sophus::SE3d SE3_QDt(QD, t);            // 从q,t构造SE(3)
        cout << "SE3 from RM,t = " << SE3_RMt.log().transpose() << endl;
        cout << "SE3 from QD,t = " << SE3_QDt.log().transpose() << endl;
        // 李代数se(3) 是一个六维向量,方便起见先typedef一下
        typedef Eigen::Matrix<double,6,1> Vector6d;
        Vector6d se3 = SE3_RMt.log();
        cout << "se3 = " << se3.transpose() << endl;
        // 观察输出,会发现在Sophus中,se(3)的平移在前,旋转在后.
        // 同样的,有hat和vee两个算符
        cout << "se3 hat = " << endl << Sophus::SE3d::hat(se3) << endl;
        cout << "se3 hat vee = " << Sophus::SE3d::vee(Sophus::SE3d::hat(se3)).transpose() << endl;
        
        // 最后,演示一下更新
        Vector6d update_se3; //更新量
        update_se3.setZero();
        update_se3(0,0) = 1e-4;
        Sophus::SE3d SE3_updated = Sophus::SE3d::exp(update_se3) * SE3_RMt;
        cout << "SE3 updated = " << endl << SE3_updated.matrix() << endl;
        

    二、详述

    1. 从物理角度引出

      从物理角度引出

      假设有一个三维的向量(overrightarrow{p(0)})绕着旋转轴(overrightarrow{omega})旋转了( heta)角度(旋转所需时间为(t))到达了(overrightarrow{p(t)})处,由小学二年级就学过的知识知道:(overrightarrow{速度}=overrightarrow{角速度} imesoverrightarrow{(旋转中心,旋转点)})

      我们不妨设(overrightarrow{p(t)})领域处的速度为(overset{ullet}{overrightarrow{p(t)}}),故而有公式:(overset{ullet}{overrightarrow{p(t)}}=overrightarrow{omega} imesoverrightarrow{p(t)}=widehat{overrightarrow{omega}}cdotoverrightarrow{p(t)})【1】。这其实是一个关于(overrightarrow{p(t)})的微分方程【2】,并且当(overrightarrow{omega})是单位向量,即值为(1 mathbf{rad/s})时有( heta=t),所以不难解出:

      [overrightarrow{p(t)}=e^{widehat{overrightarrow{omega}}cdot{t}}cdot{overrightarrow{p(0)}},由此我们不难看出overrightarrow{p(0)}到overrightarrow{p(t)}的旋转矩阵:R(t)=e^{widehat{overrightarrow{omega}}cdot{t}}=e^{widehat{overrightarrow{omega}}cdot{ heta}}=e^{widehat{overrightarrow{phi}}}; ]

      所以我们便可的出结论:旋转向量和旋转矩阵存在指数映射关系,且多对一对应(旋转周期性)。

      为了统一化表述,我们称旋转矩阵为李群(SO(3)),旋转向量为(mathfrak{so}(3)),它们之间有指数映射关系。

      【注】

      【1】:如果这个时候你仍然以向量为参考,那可能有点儿不太好理解,但要是将视线移至坐标系身上的化,也就是说是坐标系在旋转,那就不难理解:旋转轴是(overrightarrow{omega}),旋转中心是原点。

      【2】

      [egin{aligned} &overset{ullet}{x(t)}=acdot{x(t)},且x(0)=x_0&Longrightarrow&quad x(t)=e^{at}cdot{x_0}; \\ &overset{ullet}{X(t)}=Acdot{X(t)},且X(0)=X_0&Longrightarrow&quad X(t)=e^{At}cdot{X_0}; end{aligned} ]

    2. 指数与对数映射

      1. 矩阵的泰勒展开

        [e^{widehat{overrightarrow{omega}}cdot{ heta}}=sum_{n=0}^{infty}{frac{1}{n!}(overrightarrow{omega}}{ heta})^n=sum_{n=0}^{infty}{frac{{ heta}^n}{n!}(overrightarrow{omega}})^n ]

      2. 反对称阵的性质

        [egin{cases} widehat{overrightarrow{omega}}cdot{widehat{overrightarrow{omega}}}=overrightarrow{omega}cdot{overrightarrow{omega}^T}-I \\ widehat{overrightarrow{omega}}cdot{widehat{overrightarrow{omega}}cdot{widehat{overrightarrow{omega}}}}=-{widehat{overrightarrow{omega}}} end{cases} ]

      3. 指数映射的推导

        1. (mathfrak{so}(3) Longrightarrow SO(3))的推导
          SO(3)的指数映射推导过程
        2. (mathfrak{se}(3) Longrightarrow SE(3))的推导

          SE(3)的指数映射推导过程

          如果你尝试这将上面的(J)泰勒展开,将会得到下面的公式(请务必有印象!):

          SE(3)的指数映射推导过程2

          而旋转矩阵(R)通过上述的(mathfrak{so}(3) Longrightarrow SO(3))已经给出。

      4. 对数映射的推导

        1. (SO(3)Longrightarrowmathfrak{so}(3))的推导

          SO(3)的对数映射推导过程

          只有伞兵才会这样推导,之前在《矩阵旋转》中就提到了如何从旋转矩阵到旋转向量,我们只需知道旋转矩阵的迹(mathbf{tr}(R))解出( heta),并解出特征值为1的特征向量并归一化得到(omega)

        2. (SE(3)Longrightarrowmathfrak{se}(3))的推导

          由上述(SO(3)Longrightarrowmathfrak{so}(3))我们可以通过旋转(R)求出旋转向量(phi),而(overrightarrow{t}=J ho)( ho=J^{-1}overrightarrow{t})

    3. 李群和李代数的对应关系

      李群和李代数的对应关系

    三、李代数的求导和扰动模型(左乘)

    1. BCH公式和它的线性近似式

      1. BCH公式的引出

        在高等数学中,我们研究的大部分问题都是标量(也就是纯数值)的问题,所以一定满足下面恒等式

        [ln(e^Acdot{e^B})equiv{A+B}\ ln(e^widehat{a}cdot{e^widehat{b}})equiv{(a+b)^{wedge}} ]

        但是很不幸的是,我们在SLAM中研究的是向量(或者说矩阵),反正不是标量,所以不能满足上式。这个东西在向量空间中的计算很是复杂,但是这个世界上总有些神仙捣鼓这种玩意儿,比如Baker-Campbell-Hausdorff这哥仨就为这个东西的计算给出了BCH公式。

      2. BCH的完全展开

        [ln(e^Acdot{e^B})=A+B+frac{1}{2}[A,B]+frac{1}{12}[A,[A,B]]-frac{1}{12}[B,[A,B]]+cdots ]

        其中([,])表示李括号运算。也就是说,这天底下就没有干干净净的事,矩阵指数之积会产生一堆李括号余项。

      3. BCH线性近似式

        但凡事不能说得太绝对。虽说这BCH公式的完全展开很复杂,但是后面那一堆东西叫做余项啊!也就是说,当(overrightarrow{phi_1})或者(overrightarrow{phi_2})是小量的时候,它们的高阶就是高阶无穷小量了,可以被忽略的!这个时候BCH公式就变得非常‘和蔼可亲’了(近乎线性的表达)

        [ln(e^{widehat{phi_1}}cdot{e^{widehat{phi_2}}})^{vee}approx egin{cases} 左乘模型:J_l^{-1}(phi_2)cdot{phi_1}+phi_2,当phi_1为小量时; \\ 右乘模型:J_r^{-1}(phi_1)cdot{phi_2}+phi_1,当phi_2为小量时; end{cases} ]

        至此,我们将李群(SO(3))(旋转矩阵)和李代数(mathfrak{so}(3))(旋转向量)线性化了。

        可以理解为:旋转矩阵(R_2)左乘了一个微小旋转矩阵(R_1),相当于旋转向量(phi_2)加上了经过左雅可比逆(J_l^{-1}(phi_2))旋转后的旋转向量(phi_1)。右乘微小矩阵(R_2)亦可模仿理解。

      4. BCH公式的意义

        1. 李群 (Longrightarrow) 李代数

          [egin{cases} 左乘模型:e^{widehat{Deltaphi}}cdot{e^{widehat{phi}}}=e^{【J_l^{-1}(phi)cdot{Deltaphi}+phi】^{wedge}} \\ 右乘模型:e^{widehat{phi}}cdot{e^{widehat{Deltaphi}}}=e^{【J_r^{-1}(phi)cdot{Deltaphi}+phi】^{wedge}} end{cases} ]

        2. 李代数 (Longrightarrow) 李群

          [e^{【phi+Deltaphi】^{wedge}}= egin{cases} 左乘模型:e^{【phi+J_l^{-1}(phi)cdot{J_l(phi){Deltaphi}}】^{wedge}} =e^{【J_l(phi){Deltaphi}】^{wedge}}cdot{e^{widehat{phi}}} \\ 右乘模型:e^{【phi+J_r^{-1}(phi)cdot{J_r(phi){Deltaphi}}】^{wedge}} =e^{widehat{phi}}cdot{e^{【J_r(phi){Deltaphi}】^{wedge}}} end{cases} ]

        3. 李代数解决李群的求导问题

          李群没有加法,所以很难用导数的一般定义去求导数,但是李代数允许加法【1】。所以如果想要对李群求导数,我们可以运用指数映射法则和BCH公式转换成李代数,然后用定义区求导数(乘除变加减)。

          【注】【1】:李群是群,不对加法封闭。李代数定义在向量空间,对加法封闭。

      5. 左右雅可比矩阵的计算

        左右雅可比矩阵的计算

      6. (SE(3))上同样有线性化公式

        在SE(3)上同样有线性化公式

        其中的左右雅可比矩阵表述十分复杂,并且我们以后不会用到它来计算,所以就将其视为一个常数符号。

    2. 李代数(SO(3))的求导

      假设一个向量(overrightarrow{p})经过了旋转矩阵(R)的作用,旋转矩阵对应的李代数(旋转向量)为(phi)

      1. 对李代数求导(求导模型)

        [公式 控制egin{aligned} &frac{part{(Rp)}}{part{phi}} = frac{part{(Rp)}}{part{phi}} = frac{part{(e^{widehat{phi}}cdot{p})}}{part{phi}} \\=&underset{Deltaphi ightarrow0}{lim} frac{(e^{(phi+Deltaphi)^{wedge}}-e^{phi^{wedge}})cdot{p}}{Deltaphi} ,(利用左乘模型得) \\=&underset{Deltaphi ightarrow0}{lim} frac{(e^{【J_l(phi){Deltaphi}】^{wedge}}cdot{e^{widehat{phi}}}-e^{phi^{wedge}})cdot{p}}{Deltaphi} ,(利用矩阵的等价无穷小替换) \\=&underset{Deltaphi ightarrow0}{lim} frac{【J_l(phi){Deltaphi}】^{wedge}cdot{e^{widehat{phi}}p}}{Deltaphi} ,(将反对陈矩阵wedge符号换成叉积 imes,再交换顺序) \\=& -【e^{widehat{phi}}p】^{wedge}J_l(phi) = -(Rp)^{wedge}J_l{(phi)} end{aligned} ]

      2. 对微扰动求导(扰动模型)

        假设这个时候对(R)有一个作用在左边的微小扰动(Delta R),对应的李代数为(psi)。(左右干扰模型不同!!)

        [egin{aligned} &frac{part{(Rp)}}{part{psi}} = frac{part{(Rp)}}{part{psi}} = frac{part{(e^{widehat{phi}}cdot{p})}}{part{psi}} \\=&underset{Deltaphi ightarrow0}{lim} frac{(e^{psi^{wedge}}e^{phi^{wedge}}-e^{phi^{wedge}})cdot{p}}{psi} ,(利用矩阵的等价无穷小替换) \\=&underset{Deltaphi ightarrow0}{lim} frac{psi^{wedge}cdot{e^{phi^{wedge}}p}}{psi} ,(将反对陈矩阵wedge符号换成叉积 imes,再交换顺序) \\=& -【e^{widehat{phi}}p】^{wedge}=-(Rp)^{wedge} end{aligned} ]

    3. 李代数(SE(3))的求导

      李代数SE(3)的求导

      第2、3行是因为用矩阵的等价无穷小替换;


    四、评估轨迹的误差

    1. 向量的长度(或大小)

      1. 欧式距离

        在三维及三维以下的向量空间中,向量的长度的平方是坐标值的平方和。

      2. 欧式推广

        在n维坐标系中,我们也可以用这一思想表示向量的长度(或者称之为大小)。

        [overrightarrow{alpha}=[alpha_1,alpha_2,cdots,alpha_n]^T,则||overrightarrow{alpha}||_2^2=alpha_1^2+alpha_2^2+cdots+alpha_n^2 ]

    2. 矩阵的左右乘法区别

    3. 每个位姿李代数误差

      我们记第(i)时刻的真实轨迹为(T_{(GT,i)})、观测(估计)轨迹为(T_{(Esti,i)})、绝对轨迹误差(T_{(ATE,i)})

      由于误差的作用使得真实轨迹变换到了估计轨迹,我们的关注点是坐标系的变换,所以有三者的转换公式:(T_{(Esti,i)}=T_{(GT,i)}cdot{T_{(ATE,i)}}),即有(T_{(ATE,i)}=T_{(GT,i)}^{-1}cdot{T_{(Esti,i)}})

      得到了每个位姿的误差公式,那如何确定误差的大小呢?我们知道李群是很难估计大小的,所以我们可以借助其对应的李代数来确定大小,这就需要用到对数映射公式:(xi=【log(T)】^{vee})

      所以每个位姿的李代数上的误差为:(【log(T_{(GT,i)}^{-1}cdot{T_{(Esti,i)}})】^{vee}),那么它的大小也就可以用二范数来计算。

      当然我们也可以计算第i时刻的邻域(Delta{t})时间内,真实轨迹(的变化量)与估计轨迹(的变化量)的相对误差:

      [【log(T_{(GT,i)}^{-1}cdot{T_{(GT,i+Delta{t})}})^{-1}(T_{(Esti,i)}^{-1}cdot{T_{(Esti,i+Delta{t})}})】^{vee} ]

  • 相关阅读:
    描述下jvm的gc机制,常用的jvm调优方法,oom如何产生,如何处理oom 问题?
    大数据hadoop 面试经典题
    redis 个人理解和常用命令以及应用场景
    Hadoop 源码编译 step by step 最简洁的步骤
    Openstack 的介绍 ,安装以及简单应用
    Docker 的介绍 ,安装以及简单应用
    星型模型和雪花模型的应用场景
    php向js的函数内传递参数-用经纬度计算2点间的距离
    php-URL方法下载远程图片
    微信开发-js接口的使用无法使用分享功能的一些说明
  • 原文地址:https://www.cnblogs.com/SimbaWang/p/14819511.html
Copyright © 2011-2022 走看看