SLAM本质剖析番外-李群李代数的微分和导数

news2024/11/28 4:50:01

0. 简介

这几个月,博主已经从SLAM算法的使用向着算法的数学推导进行了记录和分享,之前也分享了李群李代数关注核心一文,从现象中解释了李群和李代数表达的含义。但是这还不够,所以这次作者作为SLAM本质剖析的番外,来介绍李群李代数的微分和导数。

1. 旋转点求导

李群或者李代数上叠加微小量的情况呢?传统的求导过程中,我们常见的做法是对自变量添加一个微小值来进行:

f ′ ( x ) = lim ⁡ Δ x → 0 f ( x + Δ x ) Δ x f'(x) = \lim_{\Delta x\rightarrow0}\frac{f(x+\Delta x)}{\Delta x} f(x)=Δx0limΔxf(x+Δx)

但是这种形式对于旋转矩阵 S O ( 3 ) SO(3) SO(3) 我们不能这么做,因为李群对加法不封闭,因此两个旋转矩阵相加不一定是旋转矩阵,但是利用李代数,根据下面两个方向的 BCH 近似不难看出我们有两种思路进行求导,分别是:

  • 用李代数(旋转向量)来表示姿态,然后利用李代数加法叠加微小量并对该微小量进行求导

    • 李代数求导:在李群对应的李代数的局部坐标上,即:( ϕ , ϕ ∧ ∈ s o ( 3 ) \boldsymbol{\phi}, \boldsymbol{\phi}^\wedge\in \mathfrak{so}(3) ϕ,ϕso(3)) 上添加扰动,即: ϕ ← ϕ + δ ϕ \boldsymbol{\phi} \leftarrow \boldsymbol{\phi} + \delta\boldsymbol{\phi} ϕϕ+δϕ,由于李代数本身对应旋转向量,因此对旋转向量添加扰动相当于同时改变旋转轴和旋转角度。
  • 用李群(旋转矩阵)表示姿态,然后左/右乘上一个扰动,然后对该扰动求导,即左扰动模型和右扰动模型

    • 旋转矩阵右扰动求导:由于旋转矩阵没有加法,因此要对旋转矩阵本身添加扰动,需要先通过指数映射将李代数转化为李群,然后根据李群的运算来添加扰动,即: R ← R exp ⁡ ( ϕ ∧ ) \boldsymbol{R} \leftarrow \boldsymbol{R}\exp{(\boldsymbol{\phi}^\wedge)} RRexp(ϕ),由于是旋转矩阵右乘扰动,因此相当于是在局部坐标系下对旋转矩阵进行更新

    • 旋转矩阵左扰动求导:和右扰动同理,我们也可以将扰动添加在旋转矩阵左侧,即: R ← exp ⁡ ( ϕ ∧ ) R \boldsymbol{R} \leftarrow \exp{(\boldsymbol{\phi}^\wedge)}\boldsymbol{R} Rexp(ϕ)R,由于是旋转矩阵左乘扰动,因此相当于在全局坐标系下对旋转矩阵进行更新

李代数这样的形式我们可以理解,Ceres也是通过这样的形式进行来实现李代数的累加。但是李群就需要根据BCH来进行计算了。

2 J R 0 \boldsymbol{J}_{\boldsymbol{R}_0} JR0是什么

为了明白在李群李代数公式中各个成员的含义,我们给出例子来解释不同的变量。假设我们对空间一个点 p p p 使用旋转矩阵 ${R_0} $ 进行旋转得到 R 0 p {R_0} p R0p
J R = ∂ e ( R , p ) ∂ R = ∂ R p ∂ R \boldsymbol{J}_{R} = \frac{\partial \boldsymbol{e}(\boldsymbol{{R}}, \boldsymbol{p})}{\partial \boldsymbol{{R}}} = \frac{\partial \boldsymbol{{R}p}}{\partial \boldsymbol{R}} JR=Re(R,p)=RRp

该式子在实际计算时可以施加微小扰动 ϕ {\phi} ϕ,通过最小化扰动来对误差进行线性化,并近似转换为,从而求出在 R 0 R_0 R0 R R R的情况下 p p p的变化。此刻默认 e ( R 0 , p ) \boldsymbol{e}(\boldsymbol{R}_0, \boldsymbol{p}) e(R0,p)是已知的。

e ( R , p ) = e ( R 0 , p ) + J R 0 δ ϕ \boldsymbol{e}(\boldsymbol{R}, \boldsymbol{p}) = \boldsymbol{e}(\boldsymbol{R}_0, \boldsymbol{p}) + \boldsymbol{J}_{\boldsymbol{R}_0}\delta\boldsymbol{\phi} e(R,p)=e(R0,p)+JR0δϕ

得到基于 R 0 {R_0} R0的偏导 --------也就是 J R 0 \boldsymbol{J}_{\boldsymbol{R}_0} JR0 是函数在 R 0 \boldsymbol{R}_0 R0的雅可比矩阵

3 ⊕ \oplus ∧ \wedge × _{\times} × 的含义

对于李群而言,由于其没有向量空间上的加法操作,因此为了引入导数的概念,这里用一个映射将局部坐标 ξ \xi ξ 映射到李群元素 a a a 在李群空间附近的邻域上,用来作为李群上的 “加法” 操作,所以常常会使用 ⊕ \oplus 来表示李群的加法,如下所示:

a ⊕ ξ ≜ a exp ⁡ ( ξ ^ ) a\oplus \xi \triangleq a \exp{(\hat{\xi})} aξaexp(ξ^)

式中, ξ ∈ R n \xi\in\mathbb{R}^n ξRn a a a 系下的局部坐标,这个也是我们所说的极小值右乘的做法,以李群 SO(3) 为例,局部坐标可以表示为 ξ = ω t \xi = \omega t ξ=ωt,其几何意义为以 a a a 作为参考系下的一个角度扰动;

ξ ^ \hat{\xi} ξ^ ξ \xi ξ 的对应李代数,当然也可以像上面表示为 ξ ∧ \xi^{\wedge} ξ

exp ⁡ ξ \exp{\xi} expξ 为李代数到李群的指数映射;

ξ ^ = [ ω t ] × \hat{\xi} = [\omega t]_{\times} ξ^=[ωt]× 为李代数,李代数可以转化为反对称矩阵。通过 × _{\times} ×来表示角度扰动(旋转轴+旋转角度)的旋转向量。
在这里插入图片描述

4 由BCH得到的左扰动和右扰动基础公式

首先将旋转矩阵(李群 S O ( 3 ) SO(3) SO(3))转换为旋转向量(李代数 s o ( 3 ) \boldsymbol{\mathfrak{so}}(3) so(3)),并对旋转向量求导:

e ( R , p ) = R p = exp ⁡ ( ϕ ∧ ) p = exp ⁡ ( ( ϕ 0 + δ ϕ ) ∧ ) p = exp ⁡ ( ϕ 0 ∧ + δ ϕ ∧ ) p 将 J l ( ϕ 0 ) 简化为 J l ( ϕ 0 ) = ( R 0 R δ ) p B C H 近似 ≈ exp ⁡ ( ( J l δ ϕ ) ∧ ) exp ⁡ ( ϕ 0 ∧ ) p 泰勒展开并去除高阶项 ≈ ( I + ( J l δ ϕ ) ∧ ) exp ⁡ ( ϕ 0 ∧ ) p = exp ⁡ ( ϕ 0 ∧ ) p + ( J l δ ϕ ) ∧ exp ⁡ ( ϕ 0 ∧ ) p = R 0 p + ( J l δ ϕ ) ∧ R 0 p = e ( R 0 , p ) + ( J l δ ϕ ) ∧ R 0 p 利用 a ∧ b = − b ∧ a 性质 = e ( R 0 , p ) − ( R 0 p ) ∧ J l δ ϕ 根据之前的的公式默认为 = e ( R 0 , p ) + J R 0 δ ϕ ⇒ J R 0 = − ( R 0 p ) ∧ J l \begin{aligned} \boldsymbol{e}(\boldsymbol{R}, \boldsymbol{p}) &= \boldsymbol{Rp} = \exp{(\boldsymbol{\phi}^\wedge})\boldsymbol{p}\\ &= \exp{((\boldsymbol{\phi}_0 + \delta\boldsymbol{\phi})^\wedge})\boldsymbol{p}\\ &= \exp{(\boldsymbol{\phi}_0^\wedge + \delta\boldsymbol{\phi}^\wedge})\boldsymbol{p}\\ 将{J_l({\phi}_0)}简化为{J_l({\phi}_0)} &= (R_0R_{\delta})\boldsymbol{p}\\ \mathrm{BCH 近似}&\approx \exp{((\boldsymbol{J}_l\delta\boldsymbol{\phi})^\wedge})\exp{(\boldsymbol{\phi}_0^\wedge)}\boldsymbol{p} \\ \mathrm{泰勒展开并去除高阶项}&\approx (\boldsymbol{I} + (\boldsymbol{J}_l\delta\boldsymbol{\phi})^\wedge)\exp{(\boldsymbol{\phi}_0^\wedge)}\boldsymbol{p} \\ &= \exp{(\boldsymbol{\phi}_0^\wedge})\boldsymbol{p} + (\boldsymbol{J}_l\delta\boldsymbol{\phi})^\wedge\exp{(\boldsymbol{\phi}_0^\wedge)}\boldsymbol{p} \\ &= \boldsymbol{R}_0\boldsymbol{p} + (\boldsymbol{J}_l\delta\boldsymbol{\phi})^\wedge\boldsymbol{R}_0\boldsymbol{p} \\ &= \boldsymbol{e}(\boldsymbol{R}_0, \boldsymbol{p}) + (\boldsymbol{J}_l\delta\boldsymbol{\phi})^\wedge\boldsymbol{R}_0\boldsymbol{p} \\ \mathrm{利用a^\wedge b = -b^\wedge a 性质}&= \boldsymbol{e}(\boldsymbol{R}_0, \boldsymbol{p}) - (\boldsymbol{R}_0\boldsymbol{p})^\wedge\boldsymbol{J}_l\delta\boldsymbol{\phi} \\ 根据之前的的公式默认为 &= \boldsymbol{e}(\boldsymbol{R}_0, \boldsymbol{p}) + \boldsymbol{J}_{\boldsymbol{R}_0}\delta\boldsymbol{\phi} \\ \Rightarrow \boldsymbol{J}_{\boldsymbol{R}_0} &= - (\boldsymbol{R}_0\boldsymbol{p})^\wedge\boldsymbol{J}_l \end{aligned} e(R,p)Jl(ϕ0)简化为Jl(ϕ0)BCH近似泰勒展开并去除高阶项利用ab=ba性质根据之前的的公式默认为JR0=Rp=exp(ϕ)p=exp((ϕ0+δϕ))p=exp(ϕ0+δϕ)p=(R0Rδ)pexp((Jlδϕ))exp(ϕ0)p(I+(Jlδϕ))exp(ϕ0)p=exp(ϕ0)p+(Jlδϕ)exp(ϕ0)p=R0p+(Jlδϕ)R0p=e(R0,p)+(Jlδϕ)R0p=e(R0,p)(R0p)Jlδϕ=e(R0,p)+JR0δϕ=(R0p)Jl

最后我们得到以下结果:

J R 0 = − ( R 0 p ) ∧ J l ( ϕ 0 ) \boldsymbol{J}_{\boldsymbol{R}_0} = - (\boldsymbol{R}_0\boldsymbol{p})^\wedge\boldsymbol{J}_l(\boldsymbol{\phi}_0) JR0=(R0p)Jl(ϕ0)

因为 J l \boldsymbol{J}_l Jl一般乘上的是极小值,所以在一般情况是可以省略的。这就可以根据类似的推导得到左扰动公式:

e ( R , p ) = R p = exp ⁡ ( ψ ) ∧ R 0 p 泰勒展开并去除高阶项 ≈ ( I + ψ ∧ ) R 0 p = R 0 p + ψ ∧ R 0 p = e ( R 0 , p ) + ψ ∧ R 0 p 利用 a ∧ b = − b ∧ a 性质 = e ( R 0 , p ) − ( R 0 p ) ∧ ψ = e ( R 0 , p ) + J R 0 ψ ⇒ J R 0 = − ( R 0 p ) ∧ \begin{aligned} \boldsymbol{e}(\boldsymbol{R}, \boldsymbol{p}) &= \boldsymbol{Rp}\\ &= \exp{(\boldsymbol{\psi})^\wedge}\boldsymbol{R}_0\boldsymbol{p}\\ \mathrm{泰勒展开并去除高阶项}&\approx (\boldsymbol{I} + \boldsymbol{\psi}^\wedge)\boldsymbol{R}_0\boldsymbol{p}\\ &= \boldsymbol{R}_0\boldsymbol{p} + \boldsymbol{\psi}^\wedge\boldsymbol{R}_0\boldsymbol{p}\\ &= \boldsymbol{e}(\boldsymbol{R}_0, \boldsymbol{p}) + \boldsymbol{\psi}^\wedge\boldsymbol{R}_0\boldsymbol{p}\\ \mathrm{利用a^\wedge b = -b^\wedge a 性质}&= \boldsymbol{e}(\boldsymbol{R}_0, \boldsymbol{p}) - (\boldsymbol{R}_0\boldsymbol{p})^\wedge\boldsymbol{\psi} \\ &= \boldsymbol{e}(\boldsymbol{R}_0, \boldsymbol{p}) + \boldsymbol{J}_{\boldsymbol{R}_0}\boldsymbol{\psi} \\ \Rightarrow \boldsymbol{J}_{\boldsymbol{R}_0} &= - (\boldsymbol{R}_0\boldsymbol{p})^\wedge \end{aligned} e(R,p)泰勒展开并去除高阶项利用ab=ba性质JR0=Rp=exp(ψ)R0p(I+ψ)R0p=R0p+ψR0p=e(R0,p)+ψR0p=e(R0,p)(R0p)ψ=e(R0,p)+JR0ψ=(R0p)
不难看出来,利用左扰动模型计算的导数比使用李代数直接求导省去了一个 J l ( ϕ 0 ) \boldsymbol{J}_l(\boldsymbol{\phi}_0) Jl(ϕ0) 的计算,因此更为实用,同时理论上精度也会更高(因为在计算该矩阵时需要近似)。

下面是右扰动公式:
e ( R , p ) = R p = R 0 exp ⁡ ( ψ ) ∧ p 泰勒展开并去除高阶项 ≈ R 0 ( I + ψ ∧ ) p = R 0 p + R 0 ψ ∧ p = e ( R 0 , p ) + R 0 ψ ∧ p 利用 a ∧ b = − b ∧ a 性质 = e ( R 0 , p ) − R 0 p ∧ ψ = e ( R 0 , p ) + J R 0 ψ ⇒ J R 0 = − R 0 p ∧ \begin{aligned} \boldsymbol{e}(\boldsymbol{R}, \boldsymbol{p}) &= \boldsymbol{Rp}\\ &= \boldsymbol{R}_0\exp{(\boldsymbol{\psi})^\wedge}\boldsymbol{p}\\ \mathrm{泰勒展开并去除高阶项}&\approx \boldsymbol{R}_0(\boldsymbol{I} + \boldsymbol{\psi}^\wedge)\boldsymbol{p}\\ &= \boldsymbol{R}_0\boldsymbol{p} + \boldsymbol{R}_0\boldsymbol{\psi}^\wedge\boldsymbol{p}\\ &= \boldsymbol{e}(\boldsymbol{R}_0, \boldsymbol{p}) + \boldsymbol{R}_0\boldsymbol{\psi}^\wedge\boldsymbol{p}\\ \mathrm{利用a^\wedge b = -b^\wedge a 性质}&= \boldsymbol{e}(\boldsymbol{R}_0, \boldsymbol{p}) - \boldsymbol{R}_0\boldsymbol{p}^\wedge\boldsymbol{\psi} \\ &= \boldsymbol{e}(\boldsymbol{R}_0, \boldsymbol{p}) + \boldsymbol{J}_{\boldsymbol{R}_0}\boldsymbol{\psi} \\ \Rightarrow \boldsymbol{J}_{\boldsymbol{R}_0} &= - \boldsymbol{R}_0\boldsymbol{p}^\wedge\\ \end{aligned} e(R,p)泰勒展开并去除高阶项利用ab=ba性质JR0=Rp=R0exp(ψ)pR0(I+ψ)p=R0p+R0ψp=e(R0,p)+R0ψp=e(R0,p)R0pψ=e(R0,p)+JR0ψ=R0p

相比于左扰动的模型中计算 R p \boldsymbol{Rp} Rp 的反对称矩阵,右扰动模型计算的是 p \boldsymbol{p} p 的反对称矩阵,因此有细微的区别,使用时注意区分。

5 连乘李群的求导

…详情请参照古月居

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/166671.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基础数字(一)位运算 哈希(数组中元素出现次数)

目录 力扣剑指 Offer II 070. 排序数组中只出现一次的数字 数组中只出现一次的数(其它数出现k次)_牛客题霸 数组中只出现一次的两个数字_牛客题霸_牛客网 数组中出现次数超过一半的数字_牛客题霸_牛客网 缺失的第一个正整数_牛客题霸_牛客网 力扣剑指…

[杂记]算法:前缀和与差分数组

这篇讲一下前缀和与差分数组的关系 1. 前缀和 1.1 一维数组前缀和 前缀和在处理数组中的连续子数组的某一段加和的问题中很有用, 因为是拿空间换时间, 可以将线性复杂度降低为常数时间复杂度. 前缀和的道理很简单, 对于数组arr[i],i0,...,n−1arr[i], i 0, ..., n - 1arr[i…

《Linux Shell脚本攻略》学习笔记-第四章

4.1 简介 本章主要介绍sed、awk、grep、cut等命令,这些工具可以相互结合以满足文本处理需求。 正则表达式是一种基础的模式匹配技术。 4.2 使用正则表达式 正则表达式是由字面文本和具有特殊意义的符号组成的。 1)位置标记 位置标记锚点是标识字符串位置…

Anaconda安装、opencv环境配置、jupyter notebook使用虚拟环境

目录一、Anaconda 的安装二、opencv 3.4.1.15版本安装三、jupyter notebook使用虚拟环境四、运行报错-缺库一、Anaconda 的安装 Anaconda官网:Anaconda Installers Anaconda历史版本:Anaconda Index of 这边建议和我装一样anaconda3 python3.7&#xf…

opencv的图像基本操作(基于jupyter Notebook)

opencv的基本操作cv2是opencv在python中的缩写,函数开头用cv2cv2.imread(cat.jpg) #读入图片cat.jpgcv2.imwrite(mycat.png,img) #图片img保存为mycat.pngcv2.imshow(image,img) #创建窗口,显示图像cv2.waitKey(10000) #等待时间,以 毫秒为单…

整数分解

问题描述 将 3 分解成两个正整数的和, 有两种分解方法, 分别是 312312 和 321321 。注意顺序不同算不同的方法。 将 5 分解成三个正整数的和, 有 6 种分解方法, 它们是 113122113122 131212221311131212221311 。 请问, 将 2021 分解成五个正整数的和, 有多少种分解方法? …

Android大厂面试100题,涵盖测试技术、环境搭建、人力资源

测试技术面试题 1、什么是兼容性测试?兼容性测试侧重哪些方面? 2、我现在有个程序,发现在Windows上运行得很慢,怎么判别是程序存在问题还是软硬件系统存在问题? 3、测试的策略有哪些? 4、正交表测试用例…

Sinutrain下载安装与开启OPC UA---kalrry

Sinumerik下载安装与开启OPC UA---kalrry前言一、安装前准备二、Win7安装1、软件安装2、开启授权3、文件配置4、客户端连接三、Win10/11安装四、启动后使用前言 本教程只适用于 Sinutrain-v4.7 版本,其他版本配置目录有所改变建议安装到默认路径,否则后…

【云原生】k8s安全机制

内容预知 前言 1. 认证(Authentication) 1.1 k8s集群内的三种认证方式 1.2 k8s集群内的认证说明 (1)需要被认证的访问类型 (2)安全性说明 (3)证书颁发的方式 (4&a…

Qt中使用qt自带的函数实现各种进制间的相互转换,easy.

文章目录一.十进制转各种进制第一种:使用QString的静态函数number第二种:使用QString的拼接函数arg二.各种进制相互转换一.十进制转各种进制 第一种:使用QString的静态函数number ①使用QString的静态函数number即可,如我把字符…

嵌入式linux-进程状态与进程关系

1. 进程状态 1.1什么是进程状态 Linux 系统下进程通常存在 6 种不同的状态,分为:就绪态、运行态、僵尸态、可中断睡眠状态(浅度 睡眠)、不可中断睡眠状态(深度睡眠)以及暂停态。 下面我们来一一总结一下&…

数据湖之Hudi基础:入门介绍和编译部署

主要记录下Hudi的概述和打包编译等内容,方便参考 文章目录简介官网发展历史Hudi特性使用场景安装部署编译环境准备编译hudi1.源码包上传到服务器2.修改pom文件3.修改源码兼容hadoop34.手动安装kafka依赖(非必须)5.解决spark模块依赖冲突6.执行…

【基础篇】4 # 链表(上):如何实现LRU缓存淘汰算法?

说明 【数据结构与算法之美】专栏学习笔记 链表结构 数组需要一块连续的内存空间来存储,对内存的要求比较高, 而链表并不需要一块连续的内存空间,它通过指针将一组零散的内存块串联起来使用。 结点:指的是内存块后继指针 next…

Postgresql源码(98)lex与yacc的定制交互方式

1 背景知识一:LEX %option prefix Postgresql中使用%option prefix"core_yy",影响范围:yy_create_buffer,yy_delete_buffer,yy_flex_debug,yy_init_buffer,yy_flush_buffer,yy_load_buffer_state,yy_switch_to_buffer,yyin,yyleng…

【并发编程十一】c++线程同步——future

【并发编程十一】c线程同步——future一、互斥二、条件变量三、future1、promise1.1、子线程设值,主线程获取1.2、主线程设置值,子线程获取1.3、shared_future2、async2.1、不开新线程的async2.2、开新线程的async3、packaged_task3.1、不使用bind3.2、提…

Kafka-概述

一、Kafka是什么 1.定义 Apache Kafka 是一款开源的消息引擎系统。 消息引擎系统是一组规范。企业利用这组规范在不同系统之间传递语义准确的消息,实现松耦合的异步式数据传递。 二、消息队列的使用场景 传统消息队列的应用场景包括 缓存/削峰、解耦、异步通信 …

vue(透传属性,$attrs)

官方文档 https://cn.vuejs.org/guide/components/attrs.html 案例 <FirstLevel class"attr-test-class" name"zs" age"18"></FirstLevel>FirstLevel组件没有用props去申明name和age&#xff0c;所以这两个属性会透视传递。 <…

RT-Thread系列--组件初始化

一、目的RT-Thread里面有个特别有意思的软件设计叫做组件自动初始化。有些小伙伴可能是第一次听说&#xff0c;所以这边我解释一下&#xff0c;请看下面的代码片段static void clock_init() {// 时钟初始化 } static void uart_init() {// 串口初始化 } static void i2c_init()…

SpringBoot自定义拦截器

&#x1f341;博客主页&#xff1a;&#x1f449;不会压弯的小飞侠 ✨欢迎关注&#xff1a;&#x1f449;点赞&#x1f44d;收藏⭐留言✒ ✨系列专栏&#xff1a;&#x1f449;SpringBoot专栏 &#x1f525;欢迎大佬指正&#xff0c;一起学习&#xff01;一起加油&#xff01; …

JavaScript 浏览器的重排和重绘

文章目录JavaScript 浏览器的重排和重绘概述浏览器解析过程重排重绘优化将多次改变样式的属性操作合并为一次需要多次重排的元素设置为绝对定位减少DOM操作复杂元素处理先设置display为none处理完后再显示缓存频繁操作的属性减少使用table布局使用事件委托绑定事件处理程序利用…