LeGO-LOAM中的数学公式推导

2023-11-17

LeGO-LOAM是一种在LOAM之上进行改进的激光雷达建图方法,建图效果比LOAM要好,但是建图较为稀疏,计算量也更小了。

本文原地址:wykxwyc的博客

github注释后LeGO-LOAM源码:LeGO-LOAM_NOTED
关于代码的详细理解,建议阅读:

1.地图优化代码理解

2.图像重投影代码理解

3.特征关联代码理解

4.LeGO-LOAM中的数学公式推导

以上博客会随时更新,如果对你有帮助,请点击注释代码的github仓库右上角star按钮,你的鼓励将给我更多动力。

本文 记录重新读LeGO-LOAM的代码时看到的数学运算,记录这些数学运算背后的原理,会随时更新。

featureAssociation中的数学公式

To be continued.

mapOptmization中的数学公式

cornerOptimization中的协方差矩阵计算

随机变量的协方差是什么?
1.在概率论和统计中,协方差是对两个随机变量联合分布线性相关程度的一种度量。两个随机变量越线性相关,协方差越大,完全线性无关,协方差为零。(线性无关并不代表完全无关,更不代表相互独立。)

2.两个随机变量 X X X Y Y Y协方差的定义如下:
(CO-1) cov ⁡ ( X , Y ) = E [ ( X − E [ X ] ) ( Y − E [ Y ] ) ] \operatorname{cov}(X, Y)=\mathrm{E}[(X-\mathrm{E}[X])(Y-\mathrm{E}[Y])] \tag{CO-1} cov(X,Y)=E[(XE[X])(YE[Y])](CO-1)

如何判断两个随机变量的相关程度?
1.通过定义这两个变量之间的相关系数 η \eta η进行判断:
(CO-2) η = cov ⁡ ( X , Y ) var ⁡ ( X ) ⋅ var ⁡ ( Y ) \eta=\frac{\operatorname{cov}(X, Y)}{\sqrt{\operatorname{var}(X) \cdot \operatorname{var}(Y)}} \tag{CO-2} η=var(X)var(Y) cov(X,Y)(CO-2)

1表示完全线性相关,−1表示完全线性负相关,0表示线性无关。线性无关并不代表完全无关,更不代表相互独立。

样本的协方差矩阵
1.设多维随机变量 X = [ X 1 , X 2 , X 3 , … , X n ] T \mathbf{X}=\left[X_{1}, X_{2}, X_{3}, \dots, X_{n}\right]^{T} X=[X1,X2,X3,,Xn]T的协方差矩阵为 Σ \Sigma Σ,则协方差矩阵中的每个元素为:
(CO-3) Σ i j = cov ⁡ ( X i , X j ) = E [ ( X i − E [ X i ] ) ( X j − E [ X j ] ) ] \Sigma_{i j}=\operatorname{cov}\left(X_{i}, X_{j}\right)=\mathrm{E}\left[\left(X_{i}-\mathrm{E}\left[X_{i}\right]\right)\left(X_{j}-\mathrm{E}\left[X_{j}\right]\right)\right] \tag{CO-3} Σij=cov(Xi,Xj)=E[(XiE[Xi])(XjE[Xj])](CO-3)
上式表示的是 X i X_{i} Xi X j X_{j} Xj之间的协方差。

公式CO-3也揭示了协方差矩阵中每个元素的计算过程,整个矩阵为:
Σ = E [ ( X − E [ X ] ) ( X − E [ X ] ) T ] = [ cov ⁡ ( X 1 , X 1 ) cov ⁡ ( X 1 , X 2 ) … cov ⁡ ( X 1 , X n ) cov ⁡ ( X 2 , X 1 ) cov ⁡ ( X 2 , X 2 ) … cov ⁡ ( X 2 , X n ) ⋮ ⋮ ⋱ ⋮ cov ⁡ ( X n , X 1 ) cov ⁡ ( X n , X 2 ) ⋯ cov ⁡ ( X n , X n ) ] = [ E [ ( X 1 − E [ X 1 ] ) ( X 1 − E [ X 1 ] ) ] E [ ( X 1 − E [ X 1 ] ) ( X 2 − E [ X 2 ] ) ] ⋯ E [ ( X 1 − E [ X 1 ] ) ( X n − E [ X n ] ) ] E [ ( X 2 − E [ X 2 ] ) ( X 1 − E [ X 1 ] ) ] E [ ( X 2 − E [ X 2 ] ) ( X 2 − E [ X 2 ] ) ] ⋯ E [ ( X 2 − E [ X 2 ] ) ( X n − E [ X n ] ) ] ⋮ ⋮ ⋱ ⋮ E [ ( X n − E [ X n ] ) ( X 1 − E [ X 1 ] ) ] E [ ( X n − E [ X n ] ) ( X 2 − E [ X 2 ] ) ] ⋯ E [ ( X n − E [ X n ] ) ( X n − E [ X n ] ) ] ] \begin{aligned} &\Sigma =\mathrm{E}\left[(\mathbf{X}-\mathrm{E}[\mathbf{X}])(\mathbf{X}-\mathrm{E}[\mathbf{X}])^{T}\right] \\ &=\left[\begin{array}{cccc}{\operatorname{cov}\left(X_{1}, X_{1}\right)} & {\operatorname{cov}\left(X_{1}, X_{2}\right)} & {\dots} & {\operatorname{cov}\left(X_{1}, X_{n}\right)} \\ {\operatorname{cov}\left(X_{2}, X_{1}\right)} & {\operatorname{cov}\left(X_{2}, X_{2}\right)} & {\dots} & {\operatorname{cov}\left(X_{2}, X_{n}\right)} \\ {\vdots} & {\vdots} & {\ddots} & {\vdots} \\ {\operatorname{cov}\left(X_{n}, X_{1}\right)} & {\operatorname{cov}\left(X_{n}, X_{2}\right)} & {\cdots} & {\operatorname{cov}\left(X_{n}, X_{n}\right)}\end{array}\right] \\ &=\left[\begin{array}{cccc}{\mathrm{E}\left[\left(X_{1}-\mathrm{E}\left[X_{1}\right]\right)\left(X_{1}-\mathrm{E}\left[X_{1}\right]\right)\right]} & {\mathrm{E}\left[\left(X_{1}-\mathrm{E}\left[X_{1}\right]\right)\left(X_{2}-\mathrm{E}\left[X_{2}\right]\right)\right]} & {\cdots} & {\mathrm{E}\left[\left(X_{1}-\mathrm{E}\left[X_{1}\right]\right)\left(X_{n}-\mathrm{E}\left[X_{n}\right]\right)\right]} \\ {\mathrm{E}\left[\left(X_{2}-\mathrm{E}\left[X_{2}\right]\right)\left(X_{1}-\mathrm{E}\left[X_{1}\right]\right)\right]} & {\mathrm{E}\left[\left(X_{2}-\mathrm{E}\left[X_{2}\right]\right)\left(X_{2}-\mathrm{E}\left[X_{2}\right]\right)\right]} & {\cdots} & {\mathrm{E}\left[\left(X_{2}-\mathrm{E}\left[X_{2}\right]\right)\left(X_{n}-\mathrm{E}\left[X_{n}\right]\right)\right]} \\ {\vdots} & {\vdots} & {\ddots} & {\vdots} \\ {\mathrm{E}\left[\left(X_{n}-\mathrm{E}\left[X_{n}\right]\right)\left(X_{1}-\mathrm{E}\left[X_{1}\right]\right)\right]} & {\mathrm{E}\left[\left(X_{n}-\mathrm{E}\left[X_{n}\right]\right)\left(X_{2}-\mathrm{E}\left[X_{2}\right]\right)\right]} & {\cdots} & {\mathrm{E}\left[\left(X_{n}-\mathrm{E}\left[X_{n}\right]\right)\left(X_{n}-\mathrm{E}\left[X_{n}\right]\right)\right]}\end{array}\right] \end{aligned} Σ=E[(XE[X])(XE[X])T]=cov(X1,X1)cov(X2,X1)cov(Xn,X1)cov(X1,X2)cov(X2,X2)cov(Xn,X2)cov(X1,Xn)cov(X2,Xn)cov(Xn,Xn)=E[(X1E[X1])(X1E[X1])]E[(X2E[X2])(X1E[X1])]E[(XnE[Xn])(X1E[X1])]E[(X1E[X1])(X2E[X2])]E[(X2E[X2])(X2E[X2])]E[(XnE[Xn])(X2E[X2])]E[(X1E[X1])(XnE[Xn])]E[(X2E[X2])(XnE[Xn])]E[(XnE[Xn])(XnE[Xn])]
记上面公式为(CO-4)。

2.样本的协方差矩阵的计算
样本集合为 { x ⋅ j = [ x 1 j , x 2 j , … , x n j ] T ∣ 1 ⩽ j ⩽ m } \left\{\mathbf{x}_{\cdot j}=\left[x_{1 j}, x_{2 j}, \ldots, x_{n j}\right]^{T} | 1 \leqslant j \leqslant m\right\} {xj=[x1j,x2j,,xnj]T1jm},m表示样本数量。

整个样本的协方差矩阵:
Σ ^ = [ q 11 q 12 ⋯ q 1 n q 21 q 21 ⋯ q 2 n ⋮ ⋮ ⋱ ⋮ q n 1 q n 2 ⋯ q n n ] = 1 m − 1 [ ∑ j = 1 m ( x 1 j − x ‾ 1 ) ( x 1 j − x ‾ 1 ) ∑ j = 1 m ( x 1 j − x ‾ 1 ) ( x 2 j − x ‾ 2 ) ⋯ ∑ j = 1 m ( x 1 j − x ‾ 1 ) ( x n j − x ‾ n ) ∑ j = 1 m ( x 2 j − x ‾ 2 ) ( x 1 j − x ‾ 1 ) ∑ j = 1 m ( x 2 j − x ‾ 2 ) ( x 2 j − x ‾ 2 ) ⋯ ∑ j = 1 m ( x 2 j − x ‾ 2 ) ( x n j − x ‾ n ) ⋮ ⋮ ⋱ ⋮ ∑ j = 1 m ( x n j − x ‾ n ) ( x 1 j − x ‾ 1 ) ∑ j = 1 m ( x n j − x ‾ n ) ( x 2 j − x ‾ 2 ) ⋯ ∑ j = 1 m ( x n j − x ‾ n ) ( x n j − x ‾ n ) ] = 1 m − 1 ∑ j = 1 m ( x . j − x ‾ ) ( x : j − x ‾ ) T \begin{aligned} &\hat{\Sigma} =\left[\begin{array}{cccc}{q_{11}} & {q_{12}} & {\cdots} & {q_{1 n}} \\ {q_{21}} & {q_{21}} & {\cdots} & {q_{2 n}} \\ {\vdots} & {\vdots} & {\ddots} & {\vdots} \\ {q_{n 1}} & {q_{n 2}} & {\cdots} & {q_{n n}}\end{array}\right] \\ &=\frac{1}{m-1}\left[\begin{array}{cccc}{\sum_{j=1}^{m}\left(x_{1 j}-\overline{x}_{1}\right)\left(x_{1 j}-\overline{x}_{1}\right)} & {\sum_{j=1}^{m}\left(x_{1 j}-\overline{x}_{1}\right)\left(x_{2 j}-\overline{x}_{2}\right)} & {\cdots} & {\sum_{j=1}^{m}\left(x_{1 j}-\overline{x}_{1}\right)\left(x_{n j}-\overline{x}_{n}\right)} \\ {\sum_{j=1}^{m}\left(x_{2 j}-\overline{x}_{2}\right)\left(x_{1 j}-\overline{x}_{1}\right)} & {\sum_{j=1}^{m}\left(x_{2 j}-\overline{x}_{2}\right)\left(x_{2 j}-\overline{x}_{2}\right)} & {\cdots} & {\sum_{j=1}^{m}\left(x_{2 j}-\overline{x}_{2}\right)\left(x_{n j}-\overline{x}_{n}\right)} \\ {\vdots} & {\vdots} & {\ddots} & {\vdots} \\ {\sum_{j=1}^{m}\left(x_{n j}-\overline{x}_{n}\right)\left(x_{1 j}-\overline{x}_{1}\right)} & {\sum_{j=1}^{m}\left(x_{n j}-\overline{x}_{n}\right)\left(x_{2 j}-\overline{x}_{2}\right)} & {\cdots} & {\sum_{j=1}^{m}\left(x_{n j}-\overline{x}_{n}\right)\left(x_{n j}-\overline{x}_{n}\right)}\end{array}\right] \\ &=\frac{1}{m-1} \sum_{j=1}^{m}\left(\mathbf{x} ._{j}-\overline{\mathbf{x}}\right)\left(\mathbf{x}_{ : j}-\overline{\mathbf{x}}\right)^{T} \end{aligned} Σ^=q11q21qn1q12q21qn2q1nq2nqnn=m11j=1m(x1jx1)(x1jx1)j=1m(x2jx2)(x1jx1)j=1m(xnjxn)(x1jx1)j=1m(x1jx1)(x2jx2)j=1m(x2jx2)(x2jx2)j=1m(xnjxn)(x2jx2)j=1m(x1jx1)(xnjxn)j=1m(x2jx2)(xnjxn)j=1m(xnjxn)(xnjxn)=m11j=1m(x.jx)(x:jx)T
记上面公式为CO-5。

LeGO-LOAM的代码中的协方差计算过程
1.LeGO-LOAM中的协方差采用公式OC-5中的计算方法,每个点云的维度为n=3,XYZ三个距离,一共有m=5个样本;
2.有一个区别就是代码中最后直接除以m=5,而公式OC-5中是除以m-1=4。

cornerOptimization中特征边缘的方向向量的计算

求方向向量的过程?
1.对识别为特征边缘的点计算它和它周围点的协方差矩阵,
2.然后用opencv库函数求解特征值和特征向量
3.会有一个大的特征值和两个小的特征值,大的特征值对应于方向向量。

为什么这个协方差矩阵的较大特征值对应的就是边缘的方向?
To be continued.

cornerOptimization中计算点到直线的距离

点指的是被认为是特征边缘上的点,直线就是特征边缘所在的这条直线。
简单来看就是计算点到直线的距离,用面积法进行计算。

在上图中,就是求点 X 0 X_{0} X0到紫色直线 0.2 V 0 0.2V_{0} 0.2V0的距离。

X 0 X_{0} X0对应于点pointSel,点 C C C对应于点 [ c x , c y , c z ] [c_{x},c_{y},c_{z}] [cx,cy,cz],先求绿色,蓝色线段构成的平行四边形面积,然后除以紫色的长度,得到距离值。

surfOptimization中如何计算点到平面的距离

To be continued

pointAssociateToMap中对坐标变换的数学表达

这个函数中通过乘以旋转矩阵的方式,对坐标进行了变换,由局部坐标系变换到地图的全局坐标系。
变换是先进行yaw角的变换,然后是roll角的变换,最后是pitch的变换(即z->x->y),按照坐标变换左乘矩阵的规则,有:
(PA-1) p ⃗ o = R y R x R z p ⃗ i + T \vec{p}_{o}=\mathbf{R}_{y}\mathbf{R}_{x}\mathbf{R}_{z} \vec{p}_{i}+\mathbf{T} \tag{PA-1} p o=RyRxRzp i+T(PA-1)

所以整体的旋转变换可以写成一个矩阵形式:
(PA-2) R t o t a l = R y R x R z = Y 1 X 2 Z 3 = [ c 1 c 3 + s 1 s 2 s 3 c 3 s 1 s 2 − c 1 s 3 c 2 s 1 c 2 s 3 c 2 c 3 − s 2 c 1 s 2 s 3 − c 3 s 1 c 1 c 3 s 2 + s 1 s 3 c 1 c 2 ] \mathbf{R}_{total}=\mathbf{R}_{y}\mathbf{R}_{x}\mathbf{R}_{z} \\ =Y_{1} X_{2} Z_{3}=\left[\begin{array}{ccc}{c_{1} c_{3}+s_{1} s_{2} s_{3}} & {c_{3} s_{1} s_{2}-c_{1} s_{3}} & {c_{2} s_{1}} \\ {c_{2} s_{3}} & {c_{2} c_{3}} & {-s_{2}} \\ {c_{1} s_{2} s_{3}-c_{3} s_{1}} & {c_{1} c_{3} s_{2}+s_{1} s_{3}} & {c_{1} c_{2}}\end{array}\right] \tag{PA-2} Rtotal=RyRxRz=Y1X2Z3=c1c3+s1s2s3c2s3c1s2s3c3s1c3s1s2c1s3c2c3c1c3s2+s1s3c2s1s2c1c2(PA-2)

注意:上面公式简写了 s i n , c o s sin,cos sin,cos函数的符号。

已知roll,pitch,yaw三个角如何求得旋转矩阵?

旋转有两种,一种是向量旋转,另一张是坐标系旋转。如下图所示:

向量旋转
图R-1是向量旋转,通过平面几何公式,很容易就能得到旋转后的向量坐标是:
(RO-1) v ′ = R θ v 0 = [ cos ⁡ θ − sin ⁡ θ sin ⁡ θ cos ⁡ θ ] × v 0 \mathbf{v}^{\prime}=\mathbf{R}_{\theta} \mathbf{v}_{0}= \left[\begin{array}{cc}{\cos \theta} & {-\sin \theta} \\ {\sin \theta} & {\cos \theta}\end{array}\right]\times \mathbf{v}_{0} \tag{RO-1} v=Rθv0=[cosθsinθsinθcosθ]×v0(RO-1)
其中有:
(RO-2) R θ = [ cos ⁡ θ − sin ⁡ θ sin ⁡ θ cos ⁡ θ ] \mathrm{R}_{\theta}=\left[\begin{array}{cc}{\cos \theta} & {-\sin \theta} \\ {\sin \theta} & {\cos \theta}\end{array}\right] \tag{RO-2} Rθ=[cosθsinθsinθcosθ](RO-2)

坐标系旋转
坐标系旋转就是相当于向量的逆旋转,所以有:
(RO-3) R θ ′ = [ cos ⁡ θ sin ⁡ θ − sin ⁡ θ cos ⁡ θ ] \mathrm{R}_{\theta}^{\prime}=\left[\begin{array}{cc}{\cos \theta} & {\sin \theta} \\ {-\sin \theta} & {\cos \theta}\end{array}\right] \tag{RO-3} Rθ=[cosθsinθsinθcosθ](RO-3)

三维空间中的坐标旋转
公式RO-2可以看做是绕z轴正向旋转 θ \theta θ的角度,只有 x , y x,y x,y坐标变化, z z z坐标不变,对应于yaw角的旋转,按照这种方式我们可以分别得到绕roll,pitch和yaw角的旋转公式:
(RO-4) R x ( α ) = [ 1 0 0 0 cos ⁡ α sin ⁡ α 0 − sin ⁡ α cos ⁡ α ] R y ( β ) = [ cos ⁡ β 0 − sin ⁡ β 0 1 0 sin ⁡ β 0 cos ⁡ β ] R z ( γ ) = [ cos ⁡ γ sin ⁡ γ 0 − sin ⁡ γ cos ⁡ γ 0 0 0 1 ] \begin{array}{l}{\mathrm{R}_{x}(\alpha)=\left[\begin{array}{ccc}{1} & {0} & {0} \\ {0} & {\cos \alpha} & {\sin \alpha} \\ {0} & {-\sin \alpha} & {\cos \alpha}\end{array}\right]} \\ {\mathrm{R}_{y}(\beta)=\left[\begin{array}{ccc}{\cos \beta} & {0} & {-\sin \beta} \\ {0} & {1} & {0} \\ {\sin \beta} & {0} & {\cos \beta}\end{array}\right]} \\ {\mathrm{R}_{z}(\gamma)=\left[\begin{array}{ccc}{\cos \gamma} & {\sin \gamma} & {0} \\ {-\sin \gamma} & {\cos \gamma} & {0} \\ {0} & {0} & {1}\end{array}\right]}\end{array} \tag{RO-4} Rx(α)=1000cosαsinα0sinαcosαRy(β)=cosβ0sinβ010sinβ0cosβRz(γ)=cosγsinγ0sinγcosγ0001(RO-4)
注意上式中的绕y轴的pitch旋转和另外两个有点不同。

LeGO中的坐标旋转问题
LeGO中的局部坐标系下的点转换到全局坐标系中去的过程在pointAssociateToMap中对坐标变换的数学表达中以及说明,根据公式PA-2,我们可以得到pointAssociateToMap对点进行的坐标变换:
旋转(记为公式RO-5):
R = [ c o s e x c o s e z + s i n e x s i n e y s i n e z c o s e z s i n e x s i n e y − c o s e x s i n e z c o s e y s i n e x c o s e y s i n e z c o s e y c o s e z − s i n e y c o s e x s i n e y s i n e z − c o s e z s i n e x c o s e x c o s e z s i n e y + s i n e x s i n e z c o s e x c o s e y ] R=\left[\begin{array}{ccc}{cos_{ex} cos_{ez}+sin_{ex} sin_{ey} sin_{ez}} & {cos_{ez} sin_{ex} sin_{ey}-cos_{ex} sin_{ez}} & {cos_{ey} sin_{ex}} \\ {cos_{ey} sin_{ez}} & {cos_{ey} cos_{ez}} & {-sin_{ey}} \\ {cos_{ex} sin_{ey} sin_{ez}-cos_{ez} sin_{ex}} & {cos_{ex} cos_{ez} sin_{ey}+sin_{ex} sin_{ez}} & {cos_{ex} cos_{ey}}\end{array}\right] R=cosexcosez+sinexsineysinezcoseysinezcosexsineysinezcosezsinexcosezsinexsineycosexsinezcoseycosezcosexcosezsiney+sinexsinezcoseysinexsineycosexcosey

平移:
t = [ t x t y t z ] t=\left[ \begin{array}{ccc} t_{x} \\ t_{y} \\ t_{z}\end{array} \right] t=txtytz

LMOptimization中如何进行优化迭代计算

先明确优化函数中的优化目标
优化函数优化的量是特征点与对应直线的距离(或者特征点与特征平面的距离)。
按照最优的情况下来说,特征点应该是在特征直线(或者特征平面)上的,所以距离应该为0.

但是当特征点到直线或者平面的距离不为0的时候,说明这个点由于运动产生了畸变,我们一开始估计的旋转 R R R和平移 T T T估计得不准确。所以对这个旋转和平移要进行调整。也就是每次优化后进行的如下操作:

transformTobeMapped[0] += matX.at<float>(0, 0);
transformTobeMapped[1] += matX.at<float>(1, 0);
transformTobeMapped[2] += matX.at<float>(2, 0);
transformTobeMapped[3] += matX.at<float>(3, 0);
transformTobeMapped[4] += matX.at<float>(4, 0);
transformTobeMapped[5] += matX.at<float>(5, 0);

其中的变换涉及到对旋转矩阵求雅克比,对距离求导等。

先明确一下优化中涉及到的定义
1.局部坐标系中的点
(LM-a) X ( k + 1 , i ) L = ( p x , p y , p z ) T X_{(k+1, i)}^{L}=(p x, p y, p z)^{T} \tag{LM-a} X(k+1,i)L=(px,py,pz)T(LM-a)
这里的点是特征点,边缘上的点或者平面上的点,点i在LiDAR坐标系下,k+1时刻的坐标.

2.变换 T ( k + 1 ) w T_{(k+1)}^{w} T(k+1)w表示特征点经过这个变换内包含的3个旋转个3个平移,可以准确地变换到全局地图中,与地图中特征边缘和平面的距离为0;

3.将从局部坐标系变换到全局地图坐标系的变换定义成一个函数 G ( . ) G( .) G(.)这个函数将局部点 X ( k + 1 , i ) L X^{L}_{(k+1, i)} X(k+1,i)L转换到全局点 X ( k + 1 , i ) w X_{(k+1, i)}^{w} X(k+1,i)w
(LM-b) X ( k + 1 , i ) w = G ( X ( k + 1 , i ) L , T ( k + 1 ) w ) = R ⋅ X ( k + 1 , i ) L + t X_{(k+1, i)}^{w}=G\left(X_{(k+1, i)}^{L}, T_{(k+1)}^{w}\right)=R \cdot X_{(k+1, i)}^{L}+t \tag{LM-b} X(k+1,i)w=G(X(k+1,i)L,T(k+1)w)=RX(k+1,i)L+t(LM-b)

4.定义误差
(LM-c) loss = d = D ( X ( k + 1 , i ) w , m a p ) \text {loss}=d=D\left(X_{(k+1, i)}^{w}, map\right) \tag{LM-c} loss=d=D(X(k+1,i)w,map)(LM-c)

结合公式LM-b,LM-c
(LM-d) l o s s = d = D ( X ( k + 1 , i ) w , m a p ) = D ( G ( X ( k + 1 , i ) L , T ( k + 1 ) w ) , m a p ) = D ( R ⋅ X ( k + 1 , i ) L + t , m a p ) \begin{aligned} &amp; loss=d=D\left(X_{(k+1, i)}^{w}, map\right) \\ &amp; =D\left(G\left(X_{(k+1, i)}^{L}, T_{(k+1)}^{w}\right), map\right) \\ &amp; =D\left(R \cdot X_{(k+1, i)}^{L}+t, map\right) \\ \end{aligned} \tag{LM-d} loss=d=D(X(k+1,i)w,map)=D(G(X(k+1,i)L,T(k+1)w),map)=D(RX(k+1,i)L+t,map)(LM-d)

5.误差对旋转求偏导的过程

(LM-e) ∂ loss ⁡ ∂ e x = ∂ D ( G ( X ( k + 1 , i ) L , T ( k + 1 ) w ) , m a p ) ∂ e x = ∂ D ( . ) ∂ G ( . ) ⋅ ∂ G ( . ) ∂ e x = ∂ D ( . ) ∂ G ( . ) ⋅ ∂ ( R ⋅ X ( k + 1 , 1 ) L + t ) ∂ e x = ∂ D ( . ) ∂ G ( . ) ⋅ ∂ ( R ⋅ X ( k + 1 , i ) L ) ∂ e x + ∂ D ( . ) ∂ G ( . ) ⋅ ∂ ( t ) ∂ e x = ∂ D ( . ) ∂ G ( . ) ⋅ ∂ ( R ⋅ X ( k + 1 , i ) L ) ∂ e x \begin{array}{c} {\frac{\partial \operatorname{loss}}{\partial e x}=\frac{\partial D\left(G\left(X_{(k+1, i)}^{L}, T_{(k+1)}^{w}\right), map\right)}{\partial e x}} \\ {=\frac{\partial D( .)}{\partial G( .)} \cdot \frac{\partial G( .)}{\partial e x}}\\ {=\frac{\partial D( .)}{\partial G( .)} \cdot \frac{\partial\left(R \cdot X_{(k+1,1)}^{L}+t\right)}{\partial e x}}\\ {=\frac{\partial D( .)}{\partial G( .)} \cdot \frac{\partial\left(R \cdot X_{(k+1, i)}^{L}\right)}{\partial e x}+\frac{\partial D( .)}{\partial G( .)} \cdot \frac{\partial(t)}{\partial e x}} \\ {=\frac{\partial D( .)}{\partial G( .)} \cdot \frac{\partial\left(R \cdot X_{(k+1, i)}^{L}\right)}{\partial e x}} \end{array} \tag{LM-e} exloss=exD(G(X(k+1,i)L,T(k+1)w),map)=G(.)D(.)exG(.)=G(.)D(.)ex(RX(k+1,1)L+t)=G(.)D(.)ex(RX(k+1,i)L)+G(.)D(.)ex(t)=G(.)D(.)ex(RX(k+1,i)L)(LM-e)

6.误差对平移求偏导的过程

(LM-f) ∂ loss ⁡ ∂ x = ∂ D ( G ( X ( k + 1 , i ) L , T ( k + 1 ) w ) , m a p ) ∂ x = ∂ D ( . ) ∂ G ( . ) ⋅ ∂ G ( . ) ∂ x = ∂ D ( . ) ∂ G ( . ) ⋅ ∂ ( R ⋅ X ( k + 1 , 1 ) L + t ) ∂ x = ∂ D ( . ) ∂ G ( . ) ⋅ ∂ ( R ⋅ X ( k + 1 , i ) L ) ∂ x + ∂ D ( . ) ∂ G ( . ) ⋅ ∂ ( t ) ∂ x = 0 + ∂ D ( . ) ∂ G ( . ) ⋅ ∂ ( t ) ∂ x = ∂ D ( . ) ∂ G ( . ) \begin{array}{c} {\frac{\partial \operatorname{loss}}{\partial x}=\frac{\partial D\left(G\left(X_{(k+1, i)}^{L}, T_{(k+1)}^{w}\right), map\right)}{\partial x}} \\ {=\frac{\partial D( .)}{\partial G( .)} \cdot \frac{\partial G( .)}{\partial x}}\\ {=\frac{\partial D( .)}{\partial G( .)} \cdot \frac{\partial\left(R \cdot X_{(k+1,1)}^{L}+t\right)}{\partial x}}\\ {=\frac{\partial D( .)}{\partial G( .)} \cdot \frac{\partial\left(R \cdot X_{(k+1, i)}^{L}\right)}{\partial x}+\frac{\partial D( .)}{\partial G( .)} \cdot \frac{\partial(t)}{\partial x}} \\ {=0+\frac{\partial D( .)}{\partial G( .)} \cdot \frac{\partial(t)}{\partial x}} \\ {=\frac{\partial D( .)}{\partial G( .)}} \end{array} \tag{LM-f} xloss=xD(G(X(k+1,i)L,T(k+1)w),map)=G(.)D(.)xG(.)=G(.)D(.)x(RX(k+1,1)L+t)=G(.)D(.)x(RX(k+1,i)L)+G(.)D(.)x(t)=0+G(.)D(.)x(t)=G(.)D(.)(LM-f)

6. ∂ D ( ⋅ ) ∂ G ( ⋅ ) \frac{\partial D(\cdot)}{\partial G(\cdot)} G()D()的求解
(LM-g) ∂ D ( . ) ∂ G ( . ) = ∂ d ( ∂ X ( ( k + 1 , i ) ) w ) \frac{\partial D( .)}{\partial G( .)}=\frac{\partial d}{\left(\partial X_{((k+1, i))}^{w}\right)} \tag{LM-g} G(.)D(.)=(X((k+1,i))w)d(LM-g)

公式LM-g中对全局坐标系中的点求导,可以理解成求一个全局点的移动方向,点在这个方向上移动, d d d减小得最快。

所以这个方向就是沿着垂线的方向。
所以点到直线的方向就是底边的垂线方向。
点到平面的方向就是平面的法线方向。

∂ D ( . ) ∂ G ( . ) = ∂ d ( ∂ X ( ( k + 1 , i ) ) w ) = ( ∂ d ∂ x , ∂ d ∂ y , ∂ d ∂ z ) = ( l a , l b , l c ) \frac{\partial D( .)}{\partial G( .)}=\frac{\partial d}{\left(\partial X_{((k+1, i))}^{w}\right)}=\left(\frac{\partial d}{\partial x},\frac{\partial d}{\partial y},\frac{\partial d}{\partial z}\right)=(la,lb,lc) G(.)D(.)=(X((k+1,i))w)d=(xd,yd,zd)=(la,lb,lc)

所以总结一下上面求解的两个部分:
(LM-h) ∂ ( R ∗ X ( k + 1 , i ) L ) ∂ e x = ∂ ( R ) ∂ e x ⋅ X ( k + 1 , i ) L = ∂ ( R ) ∂ e x ⋅ ( p x , p y , p z ) T = [ s y ⋅ c x ⋅ s z c z ⋅ s y ⋅ c x − s x ⋅ s y − s x ⋅ s z − s x ⋅ c z − c x c y ⋅ c x ⋅ s z c y ⋅ c z ⋅ c x − c y ⋅ s x ] ⋅ ( p x , p y , p z ) T \begin{aligned} &amp;\frac{\partial\left(R * X_{(k+1, i)}^{L}\right)}{\partial e x}=\frac{\partial\left(R \right)}{\partial e x}\cdot X_{(k+1, i)}^{L} \\ &amp; =\frac{\partial\left(R \right)}{\partial e x}\cdot \left( p_x,p_y,p_z \right)^{T} \\ &amp; =\left[\begin{array}{ccc}{sy \cdot cx \cdot sz} &amp; {cz \cdot sy \cdot cx} &amp; {-sx \cdot sy} \\ {-sx \cdot sz} &amp; {-sx \cdot cz} &amp; {-cx} \\ {cy \cdot cx \cdot sz} &amp; {cy \cdot cz \cdot cx} &amp; {-cy \cdot sx}\end{array}\right] \cdot \left( p_x,p_y,p_z\right)^T \end{aligned} \tag{LM-h} ex(RX(k+1,i)L)=ex(R)X(k+1,i)L=ex(R)(px,py,pz)T=sycxszsxszcycxszczsycxsxczcyczcxsxsycxcysx(px,py,pz)T(LM-h)

同样的做法可以求得
∂ ( R × X ( k + 1 , i ) L ) ∂ e y \frac{\partial\left(R \times X_{(k+1, i)}^{L}\right)}{\partial e y} ey(R×X(k+1,i)L)
以及
∂ ( R × X ( k + 1 , i ) L ) ∂ e z \frac{\partial\left(R \times X_{(k+1, i)}^{L}\right)}{\partial e z} ez(R×X(k+1,i)L)
,分别对应于代码中的ary和arz。

迭代计算的过程
代码中用的是高斯-牛顿法进行迭代计算求解的。
高斯-牛顿法的基本形式为:
J T J Δ x = − J ⋅ f ( x ) J^{T}J \Delta{x}=-J \cdot f(x) JTJΔx=Jf(x)

代码中,雅克比矩阵 J J JmatA,
(matA) m a t A = [ ∂ d ∂ r o l l ∂ d ∂ p i t c h ∂ d ∂ y a w ∂ d ∂ t x ∂ d ∂ t y ∂ d ∂ t z ] matA=\left[\begin{array}{ccc} {\frac{\partial{d}}{\partial{roll}}} \\ {\frac{\partial{d}}{\partial{pitch}}} \\ {\frac{\partial{d}}{\partial{yaw}}} \\ {\frac{\partial{d}}{\partial{t_x}}} \\ {\frac{\partial{d}}{\partial{t_y}}} \\ {\frac{\partial{d}}{\partial{t_z}}} \\ \end{array} \right] \tag{matA} matA=rolldpitchdyawdtxdtydtzd(matA)

transformFusion中的数学公式

To be continued.

参考文献及链接

1.苦力笨笨的博客:https://www.cnblogs.com/terencezhou/p/6235974.html
2.知乎SLAM专栏-「能儿」的回答:https://zhuanlan.zhihu.com/p/57351961
3.mathworld.wolfram.comhttp://mathworld.wolfram.com/RotationMatrix.html
4.维基百科旋转矩阵解释:https://en.wikipedia.org/wiki/Euler_angles#Definition_by_intrinsic_rotations

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

LeGO-LOAM中的数学公式推导 的相关文章

  • SLAM方法汇总

    原文 http blog csdn net smartxxyx article details 53068855 目录 SLAM概述 SLAM一般处理流程包括track和map两部分 所谓的track是用来估计相机的位姿 也叫front e
  • 《视觉SLAM十四讲》第一版源码slambook编译调试

    slambook master ch2 编译正常 log如下 slambook master ch2 mkdir build cd build cmake make j8 The C compiler identification is G
  • Ubuntu18.04 安装速腾聚创最新驱动RSLidar_SDK采集XYZIRT格式的激光点云数据 --SLAM不学无术小问题

    Ubuntu18 04 安装速腾聚创最新驱动RSLidar SDK采集XYZIRT格式的激光点云数据 新款驱动支持RS16 RS32 RSBP RS128 RS80 RSM1 B3 RSHELIOS等型号 注意 该教程旨在引导安装 可能现在
  • 基于深度相机的三维重建技术

    本文转载自http www bugevr com zblog id 14 原创作者bugeadmin 转载至我的博客 主要是为了备份 日后查找方便 谢谢原创作者的分享 三维重建 3D Reconstruction 技术一直是计算机图形学和计
  • 激光SLAM直接线性方法里程计运动模型及标定

    原创作者 W Tortoise 原创作者文章 https blog csdn net learning tortosie article details 107763626 1 里程计运动模型 1 1 两轮差分底盘的运动模型 1 2 三轮全
  • 【大一立项】如何亲手搭建ROS小车:硬件和软件介绍

    本次博客将详细介绍上篇博客中提到的ROS小车的硬件和软件部分 由于十一实验室不开门 所以部分代码还没有上传到Github 下位机 下位机使用Arduino 因为大一上刚学完用Arduino做循迹小车 其实Arduino作为ROS小车的下位机
  • 从零开始一起学习SLAM(9)不推公式,如何真正理解对极约束?

    文章目录 对极几何基本概念 如何得到极线方程 作业 此文发于公众号 计算机视觉life 原文链接 从零开始一起学习SLAM 不推公式 如何真正理解对极约束 自从小白向师兄学习了李群李代数和相机成像模型的基本原理后 感觉书上的内容没那么难了
  • 经典坐标变换案例代码剖析

    题目 设有小萝卜一号和小萝卜二号位于世界坐标系中 记世界坐标系为W 小萝卜们的坐标系为R1和 R2 小萝卜一号的位姿为q2 0 35 0 2 0 3 0 1 T t1 0 3 0 1 0 1 T 小萝卜二号的位姿为q2 0 5 0 4 0
  • 单目视觉里程记代码

    在Github上发现了一个简单的单目vo 有接近500星 链接如下 https github com avisingh599 mono vo 这个单目里程计主要依靠opencv实现 提取fast角点并进行光流跟踪 然后求取本质矩阵并恢复两帧
  • 图像匹配算法

    图像匹配算法分为3类 基于灰度的匹配算法 基于特征的匹配算法 基于关系的匹配算法 1 基于灰度的模板匹配算法 模板匹配 Blocking Matching 是根据已知模板图像到另一幅图像中寻找与模板图像相似的子图像 基于灰度的匹配算法也称作
  • ORB-SLAM2:基于可识别特征的自主导航与地图构建

    目录 ORB SLAM2 基于可识别特征的自主导航与地图构建 简介 地图 A 地图特征点或3D ORB B 关键帧 C 可视化图像 位置识别 A 图像识别数据库 B 高效优化的ORB匹配 C 视觉一致性 自主导航追踪 A ORB特征获取 B
  • docker dbus-x11

    本来想用terminator启动nvidia docker 显示出图形界面的 结果发现启动的时候出问题了 terminator 1 dbind WARNING 07 31 53 725 Couldn t connect to accessi
  • 无人车

    1 无人车四大核心技术 自动驾驶实际包含三个问题 一是我在哪 二是我要去哪 三是如何去 第一个问题是环境感知和精确定位 无人车需要的是厘米级定位 厘米级定位是无人驾驶的难点之一 不光是车辆本身的语义级定位 还有一个绝对坐标定位 第二个问题是
  • 舒尔补-边际概率-条件概率

    margin求边际概率的时候喜欢通过舒尔补的形式去操作信息矩阵 如p b c 求积分p a b c da 从上图可知 边缘概率直接看协方差矩阵比较方便 边际概率的方差就是取对应联合分布中相应的协方差块 信息矩阵是由舒尔补的形式计算 此形式也
  • 二.全局定位--开源定位框架livox-relocalization实录数据集测试

    相关博客 二十五 SLAM中Mapping和Localization区别和思考 goldqiu的博客 CSDN博客 二十五 SLAM中Mapping和Localization区别和思考 goldqiu的博客 CSDN博客 基于固态雷达的全局
  • Ubuntu18.04安装pcl(过程/坑记录式教程)

    Ubuntu18 04安装pcl 1 下载pcl 2 安装依赖项 3 编译 4 安装 5 网上教程说要安装QT5和VTK 但按照本文的 本文记录了安装时出现的问题 出错的安装命令也记录了 建议浏览一遍再参考 不要错用了错误的指令 1 下载p
  • LOAM算法详解

    激光SLAM 帧间匹配方法 Point to Plane ICP NDT Feature based Method 回环检测方法 Scan to Scan Scan to Map LOAM创新点 定位和建图的分离 里程计模块 高频低质量的帧
  • Eigen几何模块的使用方法

    include
  • ORB_SLAM2运行官方数据集/自己数据集

    官方数据集运行结果 WeChat 20230210194425 可以正常运行 自己数据集运行结果 自己的数据集 主要是用手机摄像头采集的实验室进行了一下简单的运行 可以成功运行 但是由于查看的相关程序的是死循环不能像运行官方数据集那样完整保
  • Ubuntu18.04安装Autoware1.15(解决Openplanner无法绕障的问题:Openplanner2.5)

    文章目录 一 下载Autoware1 15源码 二 安装依赖 三 修改CUDA版本 四 编译以及报错解决 编译 1 报 undefined reference to cv Mat Mat 的错就按照下面方式改相应包 2 遇到OpenCV的C

随机推荐

  • qt creator debug无法调试 进入 qt源码

    qt creator无法调试qt源码的问题 如果自己写的代码无法调试请移步这里 qt下载地址 https download qt io archive qt https download qt io new archive qt 正常来讲
  • .net 5 开发 linux 桌面应用_Electron跨平台桌面应用开发工具

    一 简介 Electron是github发布的跨平台桌面应用开发工具 支持Web技术开发桌面应用 其本身是基于C 开发的 GUI核心来自于Chrome 而JavaScript引擎使用v8 简单来说 Electron相当于一个浏览器的外壳 可
  • Jupyter-02-numpy:创建ndarray 数组

    创建ndarray 数组的方法 import numpy as np 创建ndarray 数组需要调用numpy库 用列表创建 创建一维数组 arr1 np array 1 2 3 4 arr1 s a b c np array s 用元组
  • Scala中的元祖Tuple

    Scala中元祖是一组任意数据类型的集合 与列表一样 元组也是不可变的 但与列表不同的是元组可以包含不同类型的元素 数组 元祖 定义 元素中数据类型相同 元素不同数据类型 声明 val arr Array 1 2 3 var tuple 1
  • 华为服务器系统故障,服务器系统故障

    服务器系统故障 内容精选 换一换 需在所有云服务器上安装Data Provider软件 SAP技术支持人员通过该软件收集云服务器所在的平台信息 以便在SAP系统故障 性能下降时进行定位和分析 SAP NetWeaver所在的服务器上 在创建
  • 导致java.lang.UnsatisfiedLinkError错误的一种解决办法

    欢迎转载请注明出处http blog csdn net ning gg article details 53641254 在程序中加入so文件导致java lang UnsatisfiedLinkError错误的一种解决办法 可能这个解决办
  • 学Java需要的英语水平以及关键词汇总

    还是需要英语的 但是是编程英语 和从小到大学的 英语 不是一回事 Java语言的输出语句 System out print 你好 此处的 System表示 系统 out表示 在 外面 print表示 打印 每一个单词之间使用 英文输入法的点
  • streamlit——搭建学生评分网站(告别问卷星)

    streamlit搭建多人评分网站 文章目录 streamlit搭建多人评分网站 一 引言 二 数据准备 三 streamlit代码 四 数据合并代码 一 引言 当需要对班级内多人进行打分时 为了不使用问卷星等平台进行评分 使用pandas
  • AJAX核心基础知识之倒计时抢购案例

    倒计时 分析 两个时间 目标时间 当前时间 目标时间 当前时间 计算时间差中包含多少小时 多少分钟 多少秒 每间隔一秒钟重新获取当前时间 定时器 重算时间 核心问题 1当前时间不可以获取客户端本地的 本地的时间客户可以肆意修改 获取服务器的
  • 遗传算法理解(通俗易懂)

    最近研究模糊识别的一些经典算法 为更好地理解遗传算法的运算过程 下面用手工计算来简单地模拟遗传算法的各个主要执行步骤 例 求下述二元函数的最大值 1 个体编码 遗传算法的运算对象是表示个体的符号串 所以必须把变量 x1 x2 编码为一种 符
  • Gitee问题解决1:Gitee如何下载历史提交版本

    1 把在线的git历史版本代码下载到本地 打开gitee某个项目的主页 点击统计 点击提交 能够看到自己历史的提交信息 选择需要下载版本出的浏览文件 通过左上方黄色框能够看到提交版本的id 之后点击克隆 下载 点击下载ZIP即可 解压 2
  • mysql中sql语句使日期增加一年

    mysql表中有一些字段是显示日期的 因为各种需要 需要将它时间往后调整1年 mysql 日期增加一年的更新语句更新的语句如下 UPDATE table SET date DATE ADD date INTERVAL 1 YEAR 如果要增
  • 递推和递归、迭代的关系简介

    递推和递归 迭代的关系简介 在编程里 递推关系可以通过递归或者迭代来实现 但是递归和迭代又不仅仅只能用来实现递推关 有更广泛的用途 递推 递归和迭代都是解决问题的方法 它们之间有一定的联系 递归和迭代可以用于实现递推关系 但它们也有各自独立
  • k8s中Endpoint是什么

    在Kubernetes K8s 中 Endpoint是一种资源对象 用于表示一个Service所依赖的真实后端节点的Pod信息 它存储了一组IP地址和端口号的列表 这些IP地址和端口号对应着提供相同服务的Pod实例 主要作用 Endpoin
  • 预估db2、oracle、teradata数据库sql执行代价和时间方法

    DB2 只能得到cost 1 执行存贮过程建表 CALL SYSPROC SYSINSTALLOBJECTS EXPLAIN C CAST NULL AS VARCHAR 128 数据库用户名 2 执行 EXPLAIN PLAN SET Q
  • Unity中容易被忽略的小技巧

    今天在游戏蛮牛上看到慕容小匹夫的一篇文章 感觉对自己现在的水平很实用 就给转载了过来 以便日后好温习一下 这里还是要支持原创作者 原文地址在这里 一 编辑器染色 一个常见的工作情景是我们在调整场景内的某些组件参数时 没有注意到自己是在Pla
  • iphone查看/private/var/mobile/Containers/Data/Application/文件

    xcode查看iPhone的private var 文件夹 xcode连接iPhone真机 选择app下载Containers文件夹到mac电脑中 查看手机中下载的文件 使用xcode真机调试的时候 文件目录都是这种 private var
  • 51单片机用c语言在液晶1602上显示汉字,51单片机LCD1602显示汉字(中文)源程序...

    include stc15f2k60s2 h define uchar unsigned char define uint unsigned int 数据端口接 P0 sbit lcdrs P2 7 端口定义 sbit lcdrw P2 6
  • php 自带过滤和转义函数

    php 自带过滤和转义函数 函数名 释义 介绍 htmlspecialchars 将与 单双引号 大于和小于号化成HTML格式 转成 amp 转成 quot 转成 039 lt 转成 lt gt 转成 gt htmlentities 所有字
  • LeGO-LOAM中的数学公式推导

    LeGO LOAM是一种在LOAM之上进行改进的激光雷达建图方法 建图效果比LOAM要好 但是建图较为稀疏 计算量也更小了 本文原地址 wykxwyc的博客 github注释后LeGO LOAM源码 LeGO LOAM NOTED 关于代码