李群李代數(shù)在SLAM系統(tǒng)中的使用

這篇文章針對(duì)有一定SLAM基礎(chǔ)的同學(xué)或者對(duì)李群李代數(shù)的應(yīng)用感興趣的數(shù)學(xué)專業(yè)同學(xué),已經(jīng)很小眾了坠敷,但對(duì)于真正干這行并想要更深理解的同學(xué)可能會(huì)很有幫助,因此花了些時(shí)間整理發(fā)出來(lái)匠襟。要從理論推導(dǎo)到后面代碼應(yīng)用都讀懂難度還是比較大,盡量講解。
李群李代數(shù)其實(shí)已經(jīng)算SLAM里最深的數(shù)學(xué)知識(shí)了(至少我目前接觸到的)浩姥,而事實(shí)上的SLAM應(yīng)用也只是用了它們中的很小一部分疚察。這篇文章不會(huì)詳細(xì)地介紹李群李代數(shù),畢竟google或者百度一下lie group SLAM之類的已經(jīng)有不少人寫過(guò)相關(guān)博客或者論文了氯庆。這篇文章的重點(diǎn)是針對(duì)開源的SLAM系統(tǒng)蹭秋,推導(dǎo)出和代碼中應(yīng)用一致的公式,以幫助相關(guān)專業(yè)的同學(xué)知道李群李代數(shù)的現(xiàn)實(shí)應(yīng)用堤撵。下面這個(gè)鏈接是<視覺SLAM十四講>的作者所寫的關(guān)于李群李代數(shù)的入門
視覺SLAM中的數(shù)學(xué)基礎(chǔ) 第三篇 李群與李代數(shù) - 半閑居士 - 博客園
關(guān)于定義之類的我就不寫了仁讨,提取出幾個(gè)比較關(guān)鍵的部分。
李群關(guān)鍵點(diǎn): 旋轉(zhuǎn)矩陣\mathbf{R}和轉(zhuǎn)換矩陣\mathbf{T} = \begin{bmatrix} \mathbf{R} & \mathbf{t} \\ \mathbf{0} & 1 \end{bmatrix}分別屬于SO(3)和SE(3)李群实昨,我們重點(diǎn)針對(duì)SO(3)講解陪竿。李群有幾個(gè)(僅僅是這篇文章要使用的)重要性質(zhì). 性質(zhì)1: SO(3)和SE(3)李群矩陣和它的轉(zhuǎn)置互為逆矩陣\mathbf{R}\mathbf{R}^T = \mathbf{1},行列式為1(有為-1的情況但不會(huì)在SLAM中出現(xiàn))det \mathbf{R} = 1性質(zhì)2: 加法不封閉性和乘法封閉性族跛,即兩個(gè)李群矩陣相加后一般就不再是李群了闰挡,也就是李群當(dāng)中不存在加法。兩個(gè)李群想乘之后仍然是李群〗负澹現(xiàn)在如果有一個(gè)物體旋轉(zhuǎn)了角度\mathbf{R}_1长酗,再此基礎(chǔ)上我們?nèi)绻傩D(zhuǎn)一定角度,數(shù)學(xué)操作是對(duì)這個(gè)\mathbf{R}_1再乘上另一個(gè)旋轉(zhuǎn)矩陣\mathbf{R}_2桐绒,最終得到的\mathbf{R}_2\mathbf{R}_1仍然是一個(gè)旋轉(zhuǎn)矩陣夺脾。但是你如果把這兩個(gè)旋轉(zhuǎn)矩陣加起來(lái)\mathbf{R}_1 + \mathbf{R}_2則沒有任何實(shí)際的物理意義。性質(zhì)3:李群中的元素并不是獨(dú)立的茉继,一個(gè)旋轉(zhuǎn)矩陣有9個(gè)元素咧叭,而實(shí)際旋轉(zhuǎn)的自由度是3.
李代數(shù)關(guān)鍵點(diǎn):每一個(gè)李群都有一個(gè)對(duì)應(yīng)的李代數(shù),我們記為小寫的so(3)和se(3)烁竭。李代數(shù)的元素是線性獨(dú)立的菲茬。一個(gè)旋轉(zhuǎn)矩陣對(duì)應(yīng)的李代數(shù)有3個(gè)元素。記一個(gè)李代數(shù)為\phi = [\phi_1, \phi_2, \phi_3]^T派撕,定義如下操作
\phi^{\wedge} = \begin{bmatrix} 0 & -\phi_3 & \phi_2 \\ \phi_3 & 0 & \phi_1 \\ -\phi_2 & \phi_1 & 1 \end{bmatrix}
一個(gè)李群和它的李代數(shù)的對(duì)應(yīng)關(guān)系為矩陣指數(shù)關(guān)系
\mathbf{R} = exp(\phi^{\wedge}) = \mathbf{I} + \phi^{\wedge} + \frac{1}{2!} (\phi^{\wedge})^2 + \frac{1}{3!} (\phi^{\wedge})^3 +... = \sum_{n=0}^{\infty}\frac{1}{n!} (\phi^{\wedge})^n \tag{1}
李代數(shù)是有加法封閉性的婉弹,即兩個(gè)李代數(shù)相加\phi_1+ \phi_2仍可以得到一個(gè)李代數(shù),對(duì)這個(gè)新的so(3)李代數(shù)進(jìn)行指數(shù)操作可以得到一個(gè)新的旋轉(zhuǎn)矩陣exp((\phi_1+ \phi_2)^{\wedge})终吼。
李群李代數(shù)之間的關(guān)系對(duì)旋轉(zhuǎn)的求導(dǎo)有很大的幫助镀赌。第一個(gè)鏈接前言部分里的公式(2)所提到的非線性最小二乘就是SLAM問(wèn)題的關(guān)鍵。我把那個(gè)公式再寫一下
\underset{\mathbf{T}}{min} \ u(\mathbf{T}) = \sum_{i=1}^{N}|| \mathbf{q}_i - \mathbf{T}\mathbf{p}_i||^2 \tag{2}
已知兩對(duì)匹配的3d點(diǎn)(實(shí)際應(yīng)用中可能是圖像的2d點(diǎn)和它現(xiàn)實(shí)中的3d點(diǎn)的匹配际跪,或者2d圖像點(diǎn)和它在另一圖像中的對(duì)應(yīng)2d點(diǎn)匹配)\mathbf{p}和\mathbf{q}商佛,找到一個(gè)轉(zhuǎn)換矩陣\mathbf{T}使他們匹配后點(diǎn)與點(diǎn)之間的距離最小。最小二乘都會(huì)涉及到對(duì)要求解的量的求導(dǎo)姆打。即
\frac{ d(\mathbf{q}_i - \mathbf{T}\mathbf{p}_i)}{d\mathbf{T}}
\mathbf{p}和\mathbf{q}是已知常量威彰,所以關(guān)鍵在于
\frac{ d( \mathbf{T}\mathbf{p}_i)}{d\mathbf{T}} \tag{3}
這個(gè)式子乍一看還不簡(jiǎn)單?上下的\mathbf{T}約掉穴肘,結(jié)果自然就是\mathbf{p},但是實(shí)際上它是一個(gè)轉(zhuǎn)換矩陣舔痕,對(duì)一個(gè)轉(zhuǎn)換矩陣评抚,這么做是錯(cuò)誤的〔矗回想導(dǎo)數(shù)的定義
\frac{df(x)}{dx} = \lim_{\delta x \rightarrow 0} \frac{f(x+\delta x) - f(x)}{\delta x} \tag{4}
應(yīng)用在式子3中就應(yīng)該是
\frac{d(\mathbf{T}\mathbf{p}_i)}{d\mathbf{T}} = \lim_{\delta \mathbf{T} \rightarrow 0} \frac{(\mathbf{T}+\delta \mathbf{T})\mathbf{p} - \mathbf{T}\mathbf{p}}{\delta \mathbf{T}} \tag{5}
現(xiàn)在你應(yīng)該看到問(wèn)題來(lái)了慨代,由于李群的加法不封閉性,(\mathbf{T}+\delta \mathbf{T})根本就沒有意義啸如,不再是李群侍匙。導(dǎo)數(shù)的定義對(duì)李群不再有意義,我們上面假設(shè)能分子分母直接劃掉相同的變量得到結(jié)果是根據(jù)導(dǎo)數(shù)的定義得來(lái)的,即假設(shè)加法成立想暗,我們的式5就可以得到
\frac{d(\mathbf{T}\mathbf{p}_i)}{d\mathbf{T}} = \lim_{\delta \mathbf{T} \rightarrow 0} \frac{(\mathbf{T}+\delta \mathbf{T})\mathbf{p} - \mathbf{T}\mathbf{p}}{\delta \mathbf{T}} = \lim_{\delta \mathbf{T} \rightarrow 0} \frac{\delta \mathbf{T}\mathbf{p}}{\delta \mathbf{T}} = \mathbf{p}
但很遺憾妇汗,不行。
那么我們?nèi)绾螌?duì)轉(zhuǎn)換矩陣求導(dǎo)呢说莫?我們下面要講解的應(yīng)用中杨箭,把對(duì)轉(zhuǎn)換矩陣的求導(dǎo)分開為對(duì)位移的求導(dǎo)和對(duì)旋轉(zhuǎn)的求導(dǎo)(實(shí)際上有直接的公式可以應(yīng)用不用分開,但是分開求會(huì)很直觀)储狭。我們前面寫到\mathbf{T} = \begin{bmatrix} \mathbf{R} & \mathbf{t} \\ \mathbf{0} & 1 \end{bmatrix}互婿,\mathbf{p}寫為齊次點(diǎn)即(\mathbf{p}, 1)^T,代入式(3)辽狈,我們得到
\frac{ d( \mathbf{R}\mathbf{p}_i + \mathbf{t},1)^T}{d\mathbf{T}}
1作為常數(shù)部分我們不管慈参,前半部分可以分別對(duì)旋轉(zhuǎn)求導(dǎo)和對(duì)平移求偏導(dǎo)。
\frac{ \partial( \mathbf{R}\mathbf{p}_i + \mathbf{t})}{\partial \mathbf{t}} \\ \frac{ \partial( \mathbf{R}\mathbf{p}_i + \mathbf{t})}{\partial \mathbf{R}}
對(duì)位移的偏導(dǎo)非常好解決刮萌,位移是有加法的驮配,求偏導(dǎo)時(shí)\mathbf{R}\mathbf{p}_i視為常亮,所以上式的位移部分可以直接得到答案那就是單位矩陣\mathbf{I}尊勿。一切的問(wèn)題都來(lái)源于對(duì)旋轉(zhuǎn)矩陣的偏導(dǎo)
\frac{ \partial( \mathbf{R}\mathbf{p}_i + \mathbf{t})}{\partial \mathbf{R}} = \frac{ \partial( \mathbf{R}\mathbf{p}_i )}{\partial \mathbf{R}}
旋轉(zhuǎn)矩陣也是不存在加法的僧凤。那么我們?cè)撛趺崔k呢?接下來(lái)就是李代數(shù)的應(yīng)用了元扔。我們把上式等價(jià)于對(duì)旋轉(zhuǎn)的李代數(shù)求導(dǎo)躯保!為什么可以這么等價(jià)?我給出一個(gè)直觀的解釋澎语。我們知道途事,平移之所以能很簡(jiǎn)單的求導(dǎo)是因?yàn)闈M足加法封閉性,即如果我們把對(duì)平移的求導(dǎo)應(yīng)用到式(4)中擅羞,會(huì)有一個(gè)\delta \mathbf{t}尸变,這個(gè)\delta \mathbf{t}趨于0表示針對(duì)當(dāng)前的\mathbf{t}趨于不移動(dòng)。當(dāng)對(duì)旋轉(zhuǎn)求導(dǎo)時(shí)减俏,我們應(yīng)該找到一個(gè)小量召烂,"加"到旋轉(zhuǎn)上,使物體對(duì)于當(dāng)前旋轉(zhuǎn)娃承,不再旋轉(zhuǎn)奏夫,只要我們?cè)O(shè)計(jì)出一個(gè)小量,滿足這個(gè)條件历筝,我們就可以針對(duì)這個(gè)小量求導(dǎo)酗昼。我們不能直接加上一個(gè)所有元素都趨于0的旋轉(zhuǎn)小量\delta\mathbf{R},但是旋轉(zhuǎn)對(duì)應(yīng)的李代數(shù)可以梳猪。假設(shè)針對(duì)當(dāng)前的旋轉(zhuǎn)的李代數(shù)\mathbf{R} = exp(\phi^{\wedge})麻削,加上一個(gè)小量,\mathbf{R}' = exp((\phi + \delta \phi)^{\wedge}),當(dāng)\delta \phi趨于0時(shí)呛哟,旋轉(zhuǎn)不變叠荠,于是乎,我們可以針對(duì)這個(gè)小量求導(dǎo)竖共。有點(diǎn)晦澀蝙叛,多思考一下,這已經(jīng)是我能想到的最直觀的解釋了公给,理論證明可無(wú)窮盡也借帘。那么對(duì)旋轉(zhuǎn)的求導(dǎo)可以變換為
\begin{align} \frac{ \partial( \mathbf{R}\mathbf{p}_i )}{\partial \mathbf{R}} & = \frac{ \partial( exp(\phi^{\wedge})\mathbf{p}_i )}{\partial exp(\phi^{\wedge})} & = \lim_{\delta \phi \rightarrow 0} \frac{exp((\phi + \delta \phi)^{\wedge})\mathbf{p} - exp(\phi^{\wedge}\mathbf{p})}{\delta \phi} \end{align} \tag{6}
這個(gè)式子是可以求解的。這個(gè)式子在很多有關(guān)SLAM的書籍中寫到過(guò)淌铐。這里還是用大家很可能有的中文教材<視覺SLAM十四講>來(lái)講解的肺然。上面的式子對(duì)應(yīng)的是第一版十四講4.3.3的推導(dǎo)結(jié)果。這是李代數(shù)求導(dǎo)的第一種方法腿准。這種方法其實(shí)相對(duì)接下來(lái)要講的第二種方法直觀际起,因?yàn)橹辽傥覀兪歉鶕?jù)導(dǎo)數(shù)的定義,實(shí)實(shí)在在的有李代數(shù)的加法來(lái)求解的吐葱。第二種求導(dǎo)方法則不再拘泥于單純意義上的加法了街望。
旋轉(zhuǎn)矩陣真的沒有加法嗎?其實(shí)對(duì)于旋轉(zhuǎn)來(lái)說(shuō)弟跑,乘法就是加法灾前,我們要對(duì)一個(gè)旋轉(zhuǎn)"加上"另一個(gè)旋轉(zhuǎn),實(shí)際上是對(duì)旋轉(zhuǎn)矩陣做乘法孟辑。所以我們?nèi)绻麑?duì)當(dāng)前的旋轉(zhuǎn)量乘一個(gè)近乎于單位矩陣的旋轉(zhuǎn)哎甲,其實(shí)就是對(duì)它"加"了一個(gè)小量缔杉,當(dāng)這個(gè)旋轉(zhuǎn)小量趨于單位矩陣時(shí)碳却,就沒有旋轉(zhuǎn)發(fā)生。旋轉(zhuǎn)矩陣趨于單位陣對(duì)應(yīng)的李代數(shù)就趨于0向量庆聘。那么第二個(gè)求導(dǎo)方法就是針對(duì)當(dāng)前的旋轉(zhuǎn)乘上一個(gè)小的(近乎于單位矩陣)的旋轉(zhuǎn)小量貌虾,并對(duì)它的李代數(shù)趨于0時(shí)求極限吞加。
\begin{align} \frac{ \partial( \mathbf{R}\mathbf{p}_i )}{\partial \mathbf{R}} & = \frac{ \partial( exp(\phi^{\wedge})\mathbf{p}_i )}{\partial exp(\phi^{\wedge})} & = \lim_{\delta \varphi \rightarrow 0} \frac{exp(\varphi^{\wedge})exp(\phi^{\wedge})\mathbf{p} - exp(\phi^{\wedge}\mathbf{p})}{\delta \varphi} \end{align} \tag{7}
這就是十四講第一版書上4.3.4擾動(dòng)模型了。不過(guò)正如書上所說(shuō)尽狠,"擾動(dòng)"exp(\varphi)可以是左擾動(dòng)也可以是右擾動(dòng)衔憨。書上給出的求導(dǎo)結(jié)果是左擾動(dòng)結(jié)果,下面我給出右擾動(dòng)的推導(dǎo)過(guò)程以及結(jié)果晚唇。
\begin{align} \frac{\partial{ exp(\phi^{\wedge}) \mathbf{p} }}{\partial{\phi}} & = \underset{\varphi \to 0}{lim} \frac{exp(\phi^{\wedge}) exp(\varphi^{\wedge})\mathbf{p} - exp(\phi^{\wedge})\mathbf{p}}{\varphi} \\ & \overset{李群性質(zhì)1}{\approx} \underset{\varphi\to0}{lim} \frac{exp(\phi^{\wedge}) (\mathbf{I}+\varphi^{\wedge})\mathbf{p} - exp(\phi^{\wedge})\mathbf{p}}{\varphi} \\ & = \underset{\varphi \to 0}{lim} \frac{exp(\phi^{\wedge}) \varphi^{\wedge} \mathbf{p}}{\varphi} \\ & \overset{李代數(shù)性質(zhì)2}{=} - \underset{\varphi \to 0}{lim} \frac{exp(\phi^{\wedge}) \mathbf{p}^{\wedge}\varphi }{\varphi}\\ & = -exp(\phi^{\wedge}) \mathbf{p}^{\wedge} \\ & = -\mathbf{R} \mathbf{p}^{\wedge} \end{align}
這里"李群性質(zhì)1"是當(dāng)李代數(shù)很小時(shí)(所以我們稱之為擾動(dòng)),exp(\varphi^{\wedge}) \approx \mathbf{I} + \varphi^{\wedge}盗似,這里\mathbf{I}是3x3單位矩陣哩陕。"李代數(shù)性質(zhì)2"是\varphi^{\wedge} \mathbf{p} = - \mathbf{p}^{\wedge}\varphi。讀者可以自己證明。

下面是激動(dòng)人心的實(shí)際應(yīng)用

有了李群的導(dǎo)數(shù)悍及,接下來(lái)就是實(shí)際應(yīng)用部分了闽瓢。 我這里的實(shí)際應(yīng)用不是說(shuō)讓你自己寫幾行代碼去實(shí)現(xiàn),而是去看看比較成熟的SLAM系統(tǒng)是在哪里用到上面的推導(dǎo)的心赶。這需要你打開相關(guān)的論文和代碼對(duì)比來(lái)看扣讼,需要些精力。我經(jīng)常操作的是視覺慣性slam缨叫,好的開源庫(kù)有VINS-FUSION,VINS-Mono(都來(lái)自于港科大椭符,前者更新有更強(qiáng)的應(yīng)用不過(guò)后者被更多人熟知),okvis等。okvis是多年前的作品耻姥,非常經(jīng)典销钝,但是代碼難度比前面的大不少。綜合了一下情況我決定使用VINS-Mono的代碼琐簇,把李代數(shù)的求導(dǎo)結(jié)果和他們的代碼里一一對(duì)應(yīng)起來(lái)蒸健。代碼在他們的github中 HKUST-Aerial-Robotics/VINS-Mono: A Robust and ... - GitHub
我們以VINS-Mono想要求解的reprojection error為例。
vins的原論文 VINS-Mono: A Robust and Versatile Monocular Visual ... - arXiv 式25把處于不同圖像的對(duì)應(yīng)的2d點(diǎn)投影到同一單位球上然后求殘差婉商。
在vins-mono里projection_factor.cppEvaluate函數(shù)中包含了誤差函數(shù)以及倒數(shù)的結(jié)果似忧。
首先來(lái)看前面幾行幾個(gè)參數(shù)

    Eigen::Vector3d Pi(parameters[0][0], parameters[0][1], parameters[0][2]);
    Eigen::Quaterniond Qi(parameters[0][6], parameters[0][3], parameters[0][4], parameters[0][5]);

    Eigen::Vector3d Pj(parameters[1][0], parameters[1][1], parameters[1][2]);
    Eigen::Quaterniond Qj(parameters[1][6], parameters[1][3], parameters[1][4], parameters[1][5]);

    Eigen::Vector3d tic(parameters[2][0], parameters[2][1], parameters[2][2]);
    Eigen::Quaterniond qic(parameters[2][6], parameters[2][3], parameters[2][4], parameters[2][5]);

    double inv_dep_i = parameters[3][0];

這幾行的parameter來(lái)源于傳入的要優(yōu)化的參數(shù),具體來(lái)源于在estimator.cpp中的這兩行

ProjectionFactor *f = new ProjectionFactor(pts_i, pts_j);
problem.AddResidualBlock(f, loss_function, para_Pose[imu_i], para_Pose[imu_j], para_Ex_Pose[0], para_Feature[feature_index]);

其中para_Pose[imu_i]對(duì)應(yīng)于parameter[0]丈秩,是IMUi時(shí)刻的位姿盯捌,para_Pose[imu_j]對(duì)應(yīng)于parameter[1],是IMUj時(shí)刻位姿癣籽,para_Ex_Pose[0]是相機(jī)和IMU的外參挽唉,對(duì)應(yīng)parameter[2]。最后一個(gè)就對(duì)應(yīng)inv_dep_i.即該像素點(diǎn)深度的倒數(shù)筷狼。這幾個(gè)是想要被優(yōu)化的量瓶籽。隨后幾行

    Eigen::Vector3d pts_camera_i = pts_i / inv_dep_i;
    Eigen::Vector3d pts_imu_i = qic * pts_camera_i + tic;
    Eigen::Vector3d pts_w = Qi * pts_imu_i + Pi;
    Eigen::Vector3d pts_imu_j = Qj.inverse() * (pts_w - Pj);
    Eigen::Vector3d pts_camera_j = qic.inverse() * (pts_imu_j - tic);

對(duì)應(yīng)vins的原論文式25第三個(gè)\mathcal{P}_l^{c_j}的求法。注意式子中的back projection函數(shù)\pi_c^{-1}(\cdot)在原文中它的作用是turns a pixel location into a unit vector using camera intrinsic parameters埂材。具體參見論文圖6. 代碼中的pts_i對(duì)應(yīng)的是公式中的
\pi_c^{-1}( \begin{bmatrix} u_l^{c_i} \\ v_l^{c_i} \end{bmatrix} )
這是論文中所說(shuō)的指向球面的unit vector塑顺。用它除以深度的倒數(shù)(乘上深度),就對(duì)應(yīng)代碼中的pts_i / inv_dep_i俏险,獲得一個(gè)在相機(jī)坐標(biāo)系下的3d點(diǎn)
\frac{1}{\lambda}_l \pi_c^{-1}( \begin{bmatrix} u_l^{c_i} \\ v_l^{c_i} \end{bmatrix} )
這個(gè)3d點(diǎn)乘以相機(jī)到body(或者說(shuō)IMU)坐標(biāo)系下的轉(zhuǎn)換矩陣得到在IMU坐標(biāo)系下的坐標(biāo)严拒。
\mathbf{R}_c^b \frac{1}{\lambda}_l \pi_c^{-1}( \begin{bmatrix} u_l^{c_i} \\ v_l^{c_i} \end{bmatrix} + \mathbf{p}_c^b )
對(duì)應(yīng)的代碼中的qic * pts_camera_i + tic。剩下的式25的第3個(gè)式子的位姿變換和代碼的每一行一一對(duì)應(yīng)竖独。上式用\mathbf{T}_{b_i}^{\omega}轉(zhuǎn)到世界坐標(biāo)系裤唠,再轉(zhuǎn)到j 圖像所在的坐標(biāo)系最后轉(zhuǎn)到j相機(jī)下的unit vectorpts_camera_j.
\mathcal{P}_l^{c_j} = \mathbf{R}_b^c( \mathbf{R}_{\omega}^{b_j}( \mathbf{R}_{b_i}^{\omega}( \mathbf{R}_c^b \frac{1}{\lambda}_l \pi_c^{-1}( \begin{bmatrix} u_l^{c_i} \\ v_l^{c_i} \end{bmatrix} + \mathbf{p}_c^b ) + \mathbf{p}_{b_i}^{\omega} - \mathbf{p}_{b_j}^{\omega}) - \mathbf{p}_c^b \tag{8}
隨后
代碼中

#ifdef UNIT_SPHERE_ERROR 
    residual =  tangent_base * (pts_camera_j.normalized() - pts_j.normalized());
#else
    double dep_j = pts_camera_j.z();
    residual = (pts_camera_j / dep_j).head<2>() - pts_j.head<2>();
#endif

UNIT_SPHERE_ERROR才和式25的第一行對(duì)應(yīng),如果不用的話就和普通的pinhole相機(jī)模型的點(diǎn)對(duì)應(yīng)莹痢。為了方便起見种蘸,我還是推導(dǎo)的不用UNIT_SPHERE_ERROR所得到的雅各比矩陣墓赴。因?yàn)槲野l(fā)現(xiàn)VINS, parameter.h中的#define UNIT_SPHERE_ERROR這一行被注釋掉了。
代碼下一行
residual = sqrt_info * residual;
okvis也有這一行航瞭,這是因?yàn)閏eres能接受的最小二乘優(yōu)化只能是最簡(jiǎn)單的形式e^Te诫硕,而帶有協(xié)方差的優(yōu)化的形式為e^TP^{-1}e,所以代碼中會(huì)對(duì)P^{-1}做LLT分解刊侯,有LL^T = P^{-1}章办,那個(gè)sqrt_info自然就是L^T了。
綜上針對(duì)某一個(gè)像素點(diǎn)在i,jframe下的像素坐標(biāo)我們的residual就是

\mathbf{r} = (\mathcal{P}_l^{c_j} /z_j - \widehat{\mathcal{P}}_l^{c_j} )_{1:2}

式子中\widehat{\mathcal{P}}_l^{c_j}來(lái)源于測(cè)量(比如我們通過(guò)特征點(diǎn)匹配的方法知道了i,j是對(duì)應(yīng)的滨彻,那時(shí)得到的j的坐標(biāo)就是通過(guò)測(cè)量得到的), (\cdot)_{1:n}表示取向量第1位到第n位藕届。把上式具體寫出來(lái)就是
\mathbf{r} = \begin{bmatrix} x_{c_j}/z_{c_j} - \widehat{u}_{c_j} \\ y_{c_j}/z_{c_j} - \widehat{v}_{c_j} \end{bmatrix} \tag{9}
residual需要求導(dǎo)的對(duì)象是body在iframe時(shí)的pose,即(\mathbf{R}_{b_i}^{\omega}, \mathbf{p}_{b_i}^{\omega})疮绷。
首先我們計(jì)算簡(jiǎn)單的對(duì)位置求導(dǎo)翰舌。
\frac{\partial{\mathbf{r}}}{\partial{\mathbf{p}_{b_i}^{\omega}}} = \frac{\partial{\mathbf{r}}}{\partial{\mathcal{P}_l^{c_j}}} \frac{\partial{\mathcal{P}_l^{c_j}}}{\partial{\mathbf{p}_{b_i}^{\omega}}}
其中\mathbf{r}為2維,\mathcal{P}_l^{c_j}為3d點(diǎn)(x_{c_j}, y_{c_j}, z_{c_j})冬骚,很容易得到
\frac{\partial{\mathbf{r}}}{\partial{\mathcal{P}_l^{c_j}}} = \begin{bmatrix} 1/z_{c_j} & 0 & -x_{c_j}/z_{c_j}^2 \\ 0 & 1/z_{c_j} & -y_{c_j}/z_{c_j}^2 \end{bmatrix} \tag{10}
然后(8)式對(duì)\mathbf{p}_{b_i}^{\omega}求導(dǎo)椅贱,得到
\frac{\partial{\mathbf{r}}}{\partial{\mathcal{P}_l^{c_j}}} = \mathbf{R}_b^c \mathbf{R}_{\omega}^{b_j}
對(duì)應(yīng)代碼中的

jaco_i.leftCols<3>() = ric.transpose() * Rj.transpose();


\frac{\partial{\mathbf{r}}}{\partial{\mathcal{P}_l^{c_j}}} = \mathbf{R}_b^c \mathbf{R}_{\omega}^{b_j} = (\mathbf{R}_c^b)^{-1} (\mathbf{R}_{b_j}^{\omega})^{-1} = (\mathbf{R}_c^b)^T (\mathbf{R}_{b_j}^{\omega})^T
這里用到了SO(3)群的基本性質(zhì),SO(3)下的矩陣的逆等于它的轉(zhuǎn)置只冻。
之后我們對(duì)旋轉(zhuǎn)求導(dǎo)數(shù)
\frac{\partial{\mathbf{r}}}{\partial{\mathbf{R}_{b_i}^{\omega}}} = \frac{\partial{\mathbf{r}}}{\partial{\mathcal{P}_l^{c_j}}} \frac{\partial{\mathcal{P}_l^{c_j}}}{\partial{\mathbf{R}_{b_i}^{\omega}}}
導(dǎo)數(shù)的前一部分和式10一樣庇麦,后一部分涉及到李群的求導(dǎo),為書寫方便我們先令
\frac{1}{\lambda}_l \pi_c^{-1}( \begin{bmatrix} u_l^{c_i} \\ v_l^{c_i} \end{bmatrix}) = \mathcal{P}_l^{c_i}喜德,因?yàn)樽笫奖緛?lái)就是iframe像素點(diǎn)投影到相機(jī)平面的3d點(diǎn)山橄。后一部分
\begin{align} \frac{\partial{\mathcal{P}_l^{c_j}}}{\partial{\mathbf{R}_{b_i}^{\omega}}} & \overset{代入式8}{=} \frac{\partial{\mathbf{R}_b^c( \mathbf{R}_{\omega}^{b_j}( \mathbf{R}_{b_i}^{\omega}( \mathbf{R}_c^b \mathcal{P}_l^{c_i} + \mathbf{p}_c^b ) + \mathbf{p}_{b_i}^{\omega} - \mathbf{p}_{b_j}^{\omega}) - \mathbf{p}_c^b}}{\partial{\mathbf{R}_{b_i}^{\omega}}} \\ & = \frac{\partial{\mathbf{R}_b^c \mathbf{R}_{\omega}^{b_j} \mathbf{R}_{b_i}^{\omega} \mathbf{R}_c^b \mathcal{P}_l^{c_i} }}{\partial{\mathbf{R}_{b_i}^{\omega}}} \end{align}
現(xiàn)在只對(duì)\mathbf{R}_{b_i}^{\omega}求導(dǎo)數(shù),那其他量視為是常量舍悯,我們令C_1 = \mathbf{R}_b^c \mathbf{R}_{\omega}^{b_j}航棱,另外3d點(diǎn)\mathbf{R}_c^b\mathcal{P}_l^{c_i}得到的是body 坐標(biāo)系下的3d點(diǎn),我們記為\mathcal{P}_l^{b_i}萌衬。那么上式就變成了
\begin{align} \frac{\partial{\mathcal{P}_l^{c_j}}}{\partial{\mathbf{R}_{b_i}^{\omega}}} & = \frac{\partial{C_1 \mathbf{R}_{b_i}^{\omega} \mathcal{P}_l^{b_i} }}{\partial{\mathbf{R}_{b_i}^{\omega}}} \\ & = C1 \frac{\partial{ \mathbf{R}_{b_i}^{\omega} \mathcal{P}_l^{b_i} }}{\partial{\mathbf{R}_{b_i}^{\omega}}} \end{align} \tag{11}
現(xiàn)在的問(wèn)題就是如何得到\frac{\partial{ \mathbf{R}_{b_i}^{\omega} \mathcal{P}_l^{b_i} }}{\partial{\mathbf{R}_{b_i}^{\omega}}}了,簡(jiǎn)單記為\frac{\partial{ \mathbf{R} \mathcal{P} }}{\partial{\mathbf{R}}}饮醇。那這兒很明顯了,應(yīng)用我們右擾動(dòng)的推導(dǎo)結(jié)果秕豫,可以直接得到
\begin{align} \frac{\partial{\mathcal{P}_l^{c_j}}}{\partial{\mathbf{R}_{b_i}^{\omega}}} & = C_1\frac{\partial{ \mathbf{R}_{b_i}^{\omega} \mathcal{P}_l^{b_i} }}{\partial{\mathbf{R}_{b_i}^{\omega}}} \\ & \overset{因?yàn)橛昧死钊盒再|(zhì)1}{\approx} -C_1 \mathbf{R}_{b_i}^{\omega} (\mathcal{P}_l^{b_i})^{\wedge} \end{align}
代入C_1 = \mathbf{R}_b^c\mathbf{R}_{\omega}^{b_j}朴艰,我們就有了
\frac{\partial{\mathcal{P}_l^{c_j}}}{\partial{\mathbf{R}_{b_i}^{\omega}}} \approx - \mathbf{R}_b^c\mathbf{R}_{\omega}^{b_j} \mathbf{R}_{b_i}^{\omega} = - (\mathbf{R}_c^)^T(\mathbf{R}_{b_j}^{\omega})^T \mathbf{R}_{b_i}^{\omega}(\mathcal{P}_l^{b_i})^{\wedge} \tag{12}
這和代碼中的

jaco_i.rightCols<3>() = ric.transpose() * Rj.transpose() * Ri * -Utility::skewSymmetric(pts_imu_i);

對(duì)應(yīng)混移。
總的來(lái)說(shuō)代碼第一個(gè)求導(dǎo)部分得到了殘差對(duì)iframe處位姿的求導(dǎo)祠墅。

        if (jacobians[0])
        {
            Eigen::Map<Eigen::Matrix<double, 2, 7, Eigen::RowMajor>> jacobian_pose_i(jacobians[0]);

            Eigen::Matrix<double, 3, 6> jaco_i;
            jaco_i.leftCols<3>() = ric.transpose() * Rj.transpose();\\對(duì)位移求導(dǎo)
            jaco_i.rightCols<3>() = ric.transpose() * Rj.transpose() * Ri * -Utility::skewSymmetric(pts_imu_i);\\對(duì)旋轉(zhuǎn)求導(dǎo)

            jacobian_pose_i.leftCols<6>() = reduce * jaco_i;\\reduce為式10
            jacobian_pose_i.rightCols<1>().setZero(); \\這里有一個(gè)0列,回顧前面可以發(fā)現(xiàn)我們?cè)谇笃珜?dǎo)時(shí)忽略了一個(gè)1的
        }

其他部分的推導(dǎo)我就不講了歌径,以后有時(shí)間的話我會(huì)寫上IMU部分的推導(dǎo)毁嗦,有預(yù)積分會(huì)麻煩很多。
你自己如果有興趣的話回铛,你可以推導(dǎo)okvis的reprojection error部分狗准,它也是用ceres優(yōu)化芯急,優(yōu)化部分的結(jié)構(gòu)和VINS-MONO相似。雖然他們的代碼更難讀懂驶俊,但是我已經(jīng)推導(dǎo)過(guò)了,和前面的講解一致免姿,所以你也可以試一下饼酿。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市胚膊,隨后出現(xiàn)的幾起案子故俐,更是在濱河造成了極大的恐慌,老刑警劉巖紊婉,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件药版,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡喻犁,警方通過(guò)查閱死者的電腦和手機(jī)槽片,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)肢础,“玉大人还栓,你說(shuō)我怎么就攤上這事〈洌” “怎么了剩盒?”我有些...
    開封第一講書人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)慨蛙。 經(jīng)常有香客問(wèn)我辽聊,道長(zhǎng),這世上最難降的妖魔是什么期贫? 我笑而不...
    開封第一講書人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任跟匆,我火速辦了婚禮,結(jié)果婚禮上唯灵,老公的妹妹穿的比我還像新娘贾铝。我一直安慰自己,他們只是感情好埠帕,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開白布垢揩。 她就那樣靜靜地躺著,像睡著了一般敛瓷。 火紅的嫁衣襯著肌膚如雪叁巨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,050評(píng)論 1 291
  • 那天呐籽,我揣著相機(jī)與錄音锋勺,去河邊找鬼蚀瘸。 笑死,一個(gè)胖子當(dāng)著我的面吹牛庶橱,可吹牛的內(nèi)容都是我干的贮勃。 我是一名探鬼主播,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼苏章,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼寂嘉!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起枫绅,我...
    開封第一講書人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤泉孩,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后并淋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體寓搬,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年县耽,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了句喷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡兔毙,死狀恐怖脏嚷,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情瞒御,我是刑警寧澤父叙,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站肴裙,受9級(jí)特大地震影響趾唱,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蜻懦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一甜癞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧宛乃,春花似錦悠咱、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至谆奥,卻和暖如春眼坏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背酸些。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工宰译, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留檐蚜,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓沿侈,卻偏偏與公主長(zhǎng)得像闯第,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子缀拭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351