日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

VINS-Mono关键知识点总结——边缘化marginalization理论和代码详解

發布時間:2023/12/20 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 VINS-Mono关键知识点总结——边缘化marginalization理论和代码详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

VINS-Mono關鍵知識點總結——邊緣化marginalization理論和代碼詳解

  • VINS-Mono關鍵知識點總結——邊緣化marginalization理論和代碼詳解
    • 1. 邊緣化理論
      • 1.1 為什么要進行邊緣化操作?
      • 1.2 怎樣進行邊緣化呢?
      • 1.3 在實際的邊緣化操作中有什么需要注意的嗎?
    • 2. 代碼剖析
      • 2.1 優化變量分析
      • 2.1 MarginalizationInfo類分析
      • 2.3 第一步:調用addResidualBlockInfo()
      • 2.4 第二步:調用preMarginalize()
      • 2.5 第三步:調用marginalize()
      • 2.6 第四步:滑窗預移動

VINS-Mono關鍵知識點總結——邊緣化marginalization理論和代碼詳解

個人覺得整個VINS最難理解的部分就是邊緣化(marginalization),除去理論學習,僅僅看代碼前前后后就花了好幾天,也并沒有全部看懂,這里盡可能地對這部分只是詳細總結下

1. 邊緣化理論

邊緣化相關的理論主要是參考高博和賀博的課程以及三篇參考文獻:
《The Humble Gaussian Distribution》
《Exactly Sparse Extended Information Filters for Feature-Based SLAM》
《Consistency Analysis for Sliding-Window Visual Odometry》

1.1 為什么要進行邊緣化操作?

首先我們知道,如果僅僅從前后兩幀圖像來計算相機變換位姿, 其速度快但是精度低,而如果采用全局優化的方法(比如Bundle Adjustment),其精度高但是效率低,因此前輩們引入了滑窗法這樣一個方法,每次對固定數量的幀進行優化操作,這樣既保證了精度又保證了效率。既然是滑窗,在滑動的過程中必然會有新的圖像幀進來以及舊的圖像幀離開,所謂邊緣化就是為了使得離開的圖像幀得到很好的利用。

1.2 怎樣進行邊緣化呢?

我們根據運動模型和觀測模型建立HHH矩陣(高斯牛頓法中的JJTJJ^TJJT)的過程其實就是根據概率圖模型(多元高斯分布)建立各個節點變量間的信息矩陣(協方差矩陣的逆)的過程,而邊緣化則是去掉概率圖中的某一個節點后信息矩陣會發生怎樣的變換的問題。如下圖

其中x2=v2x1=w1x2+v1x3=w3x2+v3\begin{aligned} x_{2} &=v_{2} \\ x_{1} &=w_{1} x_{2}+v_{1} \\ x_{3} &=w_{3} x_{2}+v_{3} \end{aligned} x2?x1?x3??=v2?=w1?x2?+v1?=w3?x2?+v3??其中viv_ivi?相互獨立,且各自服從協方差為σi2\sigma^2_iσi2?的高斯分布,可以求得上面概率圖模型的信息矩陣為(求解過程成省略)Λ=Σ?1=[1σ12?w1σ120?w1σ12w12σ12+1σ22+w32σ12?w3σ220?w3σ321σ32]\boldsymbol{\Lambda}=\mathbf{\Sigma}^{-1}=\left[\begin{array}{cccc}{\frac{1}{\sigma_{1}^{2}}} & {-\frac{w_{1}}{\sigma_{1}^{2}}} & {0} \\ {-\frac{w_{1}}{\sigma_{1}^{2}}} & {\frac{w_{1}^{2}}{\sigma_{1}^{2}}+\frac{1}{\sigma_{2}^{2}}+\frac{w_{3}^{2}}{\sigma_{1}^{2}}} & {-\frac{w_{3}}{\sigma_{2}^{2}}} \\ {0} & {-\frac{w_{3}}{\sigma_{3}^{2}}} & {\frac{1}{\sigma_{3}^{2}}}\end{array}\right] Λ=Σ?1=????σ12?1??σ12?w1??0??σ12?w1??σ12?w12??+σ22?1?+σ12?w32???σ32?w3???0?σ22?w3??σ32?1??????邊緣化問題是假如我們將x3x_3x3?去掉之后,概率圖模型的信息矩陣會發生怎樣的變化,如下圖所示:

我們先不加證明的給出結論為:Σ2?1=[1σ12?w1σ12?w1σ12w12σ12+1σ22]\mathbf{\Sigma}_{2}^{-1}=\left[\begin{array}{cc}{\frac{1}{\sigma_{1}^{2}}} & {-\frac{w_{1}}{\sigma_{1}^{2}}} \\ {-\frac{w_{1}}{\sigma_{1}^{2}}} & {\frac{w_{1}^{2}}{\sigma_{1}^{2}}+\frac{1}{\sigma_{2}^{2}}}\end{array}\right] Σ2?1?=[σ12?1??σ12?w1????σ12?w1??σ12?w12??+σ22?1??]下面開始證明,現在假設a,ba,ba,b兩個高斯分布的變量之間的協方差矩陣為:K=[AC?CD]\mathbf{K}=\left[\begin{array}{cc}{A} & {C^{\top}} \\ {C} & {D}\end{array}\right] K=[AC?C?D?]其中A=cov?(a,a),D=cov?(b,b),C=cov?(a,b)A=\operatorname{cov}(a, a), D=\operatorname{cov}(b, b), C=\operatorname{cov}(a, b)A=cov(a,a),D=cov(b,b),C=cov(a,b),那么其聯合分布可以表示為邊際分布和條件部分的乘積如下:P(a,b)=P(a)P(b∣a)∝exp?(?12[ab]?[AC?CD]?1[ab])P(a, b)=P(a) P(b | a) \propto \exp \left(-\frac{1}{2}\left[\begin{array}{l}{a} \\ {b}\end{array}\right]^{\top}\left[\begin{array}{cc}{A} & {C^{\top}} \\ {C} & {D}\end{array}\right]^{-1}\left[\begin{array}{l}{a} \\ {b}\end{array}\right]\right) P(a,b)=P(a)P(ba)exp(?21?[ab?]?[AC?C?D?]?1[ab?])然后對高斯分布進行分解可以直接求的邊際分布P(a)P(a)P(a)和條件分布P(b∣a)P(b | a)P(ba)的表達形式,如下:P(a,b)∝exp?(?12[ab]?[AC?CD]?1[AC?CD]?1[Ab])∝exp?(?12[ab]?[I?A?1C?0I][A?100ΔA?1][I0?CA?1I][ab])∝exp?(?12[a?(b?CA?1a)?][A?100ΔA?1][ab?CA?1a])∝exp?(?12(a?A?1a)+(b?CA?1a)?ΔA?1(b?CA?1a))∝exp?(?12a?A?1a)exp?(?12(b?CA?1a)?ΔA?1(b?CA?1a))\begin{array}{l}{P(a, b)} \\ {\propto \exp \left(-\frac{1}{2}\left[\begin{array}{c}{a} \\ {b}\end{array}\right]^{\top}\left[\begin{array}{cc}{A} & {C^{\top}} \\ {C} & {D}\end{array}\right]^{-1}\left[\begin{array}{cc}{A} & {C^{\top}} \\ {C} & {D}\end{array}\right]^{-1}\left[\begin{array}{cc}{A} \\ {b}\end{array}\right]\right)} \\ {\propto \exp \left(-\frac{1}{2}\left[\begin{array}{c}{a} \\ {b}\end{array}\right]^{\top}\left[\begin{array}{cc}{I} & {-A^{-1} C^{\top}} \\ {0} & {I}\end{array}\right]\left[\begin{array}{cc}{A^{-1}} & {0} \\ {0} & {\Delta_{\mathrm{A}}^{-1}}\end{array}\right]\left[\begin{array}{cc}{I} & {0} \\ {-C A^{-1}} & {I}\end{array}\right]\left[\begin{array}{c}{a} \\ {b}\end{array}\right]\right)} \\{\propto \exp \left(-\frac{1}{2}\left[a^{\top}\left(b-C A^{-1} a\right)^{\top}\right]\left[\begin{array}{cc}{A^{-1}} & {0} \\ {0} & {\Delta_{\mathrm{A}}^{-1}}\end{array}\right]\left[\begin{array}{c}{a} \\ {b-C A^{-1} a}\end{array}\right]\right)} \\ {\propto \exp \left(-\frac{1}{2}\left(a^{\top} A^{-1} a\right)+\left(b-C A^{-1} a\right)^{\top} \Delta_{\mathrm{A}}^{-1}\left(b-C A^{-1} a\right)\right)} \\\propto \exp \left(-\frac{1}{2} a^{\top} A^{-1} a\right) \exp \left(-\frac{1}{2}\left(b-C A^{-1} a\right)^{\top} \Delta_{\mathrm{A}}^{-1}\left(b-C A^{-1} a\right)\right) \end{array} P(a,b)exp(?21?[ab?]?[AC?C?D?]?1[AC?C?D?]?1[Ab?])exp(?21?[ab?]?[I0??A?1C?I?][A?10?0ΔA?1??][I?CA?1?0I?][ab?])exp(?21?[a?(b?CA?1a)?][A?10?0ΔA?1??][ab?CA?1a?])exp(?21?(a?A?1a)+(b?CA?1a)?ΔA?1?(b?CA?1a))exp(?21?a?A?1a)exp(?21?(b?CA?1a)?ΔA?1?(b?CA?1a))?其中P(a)∝exp?(?12a?A?1a)P(a) \propto \exp \left(-\frac{1}{2} a^{\top} A^{-1} a\right) P(a)exp(?21?a?A?1a)P(b∣a)∝exp?(?12(b?CA?1a)?ΔA?1(b?CA?1a))P(b | a) \propto\exp \left(-\frac{1}{2}\left(b-C A^{-1} a\right)^{\top} \Delta_{\mathrm{A}}^{-1}\left(b-C A^{-1} a\right)\right) P(ba)exp(?21?(b?CA?1a)?ΔA?1?(b?CA?1a))P(a)~N(0,A)(1)P(a) \sim \mathcal{N}(0, A)\tag{1} P(a)N(0,A)(1)P(b∣a)~N(CA?1a,ΔA)(2)P(b | a) \sim \mathcal{N}\left(C A^{-1} a, \Delta_{A}\right)\tag{2} P(ba)N(CA?1a,ΔA?)(2)P(a)P(a)P(a)P(b∣a)P(b|a)P(ba)的協方差矩陣分別是,AAAΔA\Delta_AΔA?通過這個結論可以看出,從聯合分布中的協方差矩陣求得邊際概率的協方差矩陣AAA是簡單的,求得條件概率的協方差矩陣ΔA\Delta_AΔA?會相對復雜,但是呢,我們應該更加關注聯合分布的信息矩陣,因為我們在BA問題中研究的其實是信息矩陣而不是協方差矩陣,假設我們已知上述問題的信息矩陣為:[AC?CD]?1=[ΛaaΛabΛbaΛbb]\left[\begin{array}{cc}{A} & {C^{\top}} \\ {C} & {D}\end{array}\right]^{-1}=\left[\begin{array}{cc}{\Lambda_{a a}} & {\Lambda_{a b}} \\ {\Lambda_{b a}} & {\Lambda_{b b}}\end{array}\right] [AC?C?D?]?1=[Λaa?Λba??Λab?Λbb??]那么可以求得協方差矩陣各塊和信息矩陣各塊之間的關系為[AC?CD]?1=[A?1+A?1C?ΔA?1CA?1?A?1C?ΔA?1?ΔA?1CA?1ΔA?1]?[ΛaaΛabΛbaΛbb](3)\left[\begin{array}{cc}{A} & {C^{\top}} \\ {C} & {D}\end{array}\right]^{-1}=\left[\begin{array}{cc}{A^{-1}+A^{-1} C^{\top} \Delta_{\mathrm{A}}^{-1} C A^{-1}} & {-A^{-1} C^{\top} \Delta_{\mathrm{A}}^{-1}} \\ {-\Delta_{\mathrm{A}}^{-1} C A^{-1}} & {\Delta_{\mathrm{A}}^{-1}}\end{array}\right] \triangleq\left[\begin{array}{cc}{\Lambda_{a a}} & {\Lambda_{a b}} \\ {\Lambda_{b a}} & {\Lambda_{b b}}\end{array}\right]\tag{3} [AC?C?D?]?1=[A?1+A?1C?ΔA?1?CA?1?ΔA?1?CA?1??A?1C?ΔA?1?ΔA?1??]?[Λaa?Λba??Λab?Λbb??](3)由(1)我們知道P(b∣a)P(b|a)P(ba)的協方差矩陣為ΔA\Delta_AΔA?,那么它的信息矩陣就是ΔA?1\Delta_A^{-1}ΔA?1?,由(3)就可以知道其信息矩陣為Λbb\Lambda_{b b}Λbb?,同理,由(2)和(3)我們可以知道P(a)P(a)P(a)的信息矩陣為Λaa?ΛabΛbb?1Λba\Lambda_{a a}-\Lambda_{a b} \Lambda_{b b}^{-1} \Lambda_{b a}Λaa??Λab?Λbb?1?Λba?,由此我們就知道如何從聯合分布的信息矩陣中求解P(a)P(a)P(a)P(b∣a)P(b|a)P(ba)的信息矩陣了,這一點應用到我們上面最開始的問題中,已知聯合分布的信息矩陣為Σ?1=[1σ12?w1σ12θ?w1σ12w12σ12+1σ12+w32σ12w3σ32θw3σ321σ32]\mathbf{\Sigma}^{-1}=\left[\begin{array}{ccc}{\frac{1}{\sigma_{1}^{2}}} & {-\frac{w_{1}}{\sigma_{1}^{2}}} & {\theta} \\ {-\frac{w_{1}}{\sigma_{1}^{2}}} & {\frac{w_{1}^{2}}{\sigma_{1}^{2}}+\frac{1}{\sigma_{1}^{2}}+\frac{w_{3}^{2}}{\sigma_{1}^{2}}} & {\frac{w_{3}}{\sigma_{3}^{2}}} \\ {\theta} & {\frac{w_{3}}{\sigma_{3}^{2}}} & {\frac{1}{\sigma_{3}^{2}}}\end{array}\right] Σ?1=????σ12?1??σ12?w1??θ??σ12?w1??σ12?w12??+σ12?1?+σ12?w32??σ32?w3???θσ32?w3??σ32?1??????那么,其邊際概率的信息矩陣Σ2?1\mathbf{\Sigma}_{2}^{-1}Σ2?1?Σ2?1=Λaa?ΛabΛbb?1Λba=Λaa?[0?w3σ32]σ32[0?w3σ32]=Λaa?[000w3σ32]=[1σ12?w1σ12?w1σ12w12σ12+1σ22]\begin{aligned} \mathbf{\Sigma}_{2}^{-1} &=\Lambda_{a a}-\Lambda_{a b} \Lambda_{b b}^{-1} \Lambda_{b a} \\ &=\Lambda_{a a}-\left[\begin{array}{c}{0} \\ {-\frac{w_{3}}{\sigma_{3}^{2}}}\end{array}\right] \sigma_{3}^{2}\left[0-\frac{w_{3}}{\sigma_{3}^{2}}\right] \\ &=\Lambda_{a a}-\left[\begin{array}{cc}{0} & {0} \\ {0} & {\frac{w_{3}}{\sigma_{3}^{2}}}\end{array}\right] \\ &=\left[\begin{array}{cc}{\frac{1}{\sigma_{1}^{2}}} & {-\frac{w_{1}}{\sigma_{1}^{2}}} \\ {-\frac{w_{1}}{\sigma_{1}^{2}}} & {\frac{w_{1}^{2}}{\sigma_{1}^{2}}+\frac{1}{\sigma_{2}^{2}}}\end{array}\right] \end{aligned} Σ2?1??=Λaa??Λab?Λbb?1?Λba?=Λaa??[0?σ32?w3???]σ32?[0?σ32?w3??]=Λaa??[00?0σ32?w3???]=[σ12?1??σ12?w1????σ12?w1??σ12?w12??+σ22?1??]?這樣就證明了問題的結論,而這一步Λaa?ΛabΛbb?1Λba\Lambda_{a a}-\Lambda_{a b} \Lambda_{b b}^{-1} \Lambda_{b a}Λaa??Λab?Λbb?1?Λba?我們稱之為求Shur補的操作,我們將其應用到實際的更復雜中就是下面這種情況,下面這幅圖很好地說明了邊緣化的過程:

上圖中,ξ1\xi_1ξ1?ξ2\xi_2ξ2?ξ3\xi_3ξ3?ξ4\xi_4ξ4?ξ5\xi_5ξ5?ξ6\xi_6ξ6?分別為六個節點,通過邊緣化操作可以將原稀疏的矩陣變成稠密矩陣,而增加的稠密部分其實就是被邊緣化掉的那個節點傳遞給當前狀態的信息,也就是使得原本獨立的各個變量變得相關

1.3 在實際的邊緣化操作中有什么需要注意的嗎?

一個比較值得注意的問題是新老信息融合的問題,也就是FEJ算法的使用,如下所示:

承接上面的例子,當我們邊緣話掉變量ξ1\xi_1ξ1?有加入新的變量ξ7\xi_7ξ7?會有如下新老信息融合的情況發生,就ξ2\xi_2ξ2?這個矩陣而言,它的信息矩陣是有兩部分構成的。

新老信息融合的問題在于舊的求解雅克比矩陣的變量線性化點和和新的求解雅克比矩陣的變量線性化點不同,可能會導致信息矩陣的零空間發生變化,使得不客觀的變量變得可觀,從而引入錯誤信息,這個解釋可能會比較抽象,更加具體的解釋可以參看賀博的博客SLAM中的marginalization 和 Schur complement,上述問題的解決辦法呢就是FEJ算法:不同殘差對同一個狀態求雅克比時,線性化點必須一致。這樣就能避免零空間退化而使得不可觀變量變得可觀,具體來說就是計算r27r_{27}r27?ξ2ξ_2ξ2? 的雅克比時,ξ2ξ_2ξ2? 的線性話點必須和 r12r_{12}r12?對其求導時一致。


2. 代碼剖析

上面理論搞清楚了其實只是第一步,由于VINS-mono優化的變量較多,VINS-mono的邊緣化操作實際上要復雜很多,VINS-mono的邊緣化相關代碼在estimator.cpp的Estimator類的optimization()函數中,該函數先會先進行后端非線性優化然后緊接著就是邊緣化操作,下面就針對這個函數中的邊緣化相關代碼進行剖析。

2.1 優化變量分析

首先我們確定下參與邊緣化操作的變量有哪些,這個可以從vector2double()函數中看出來,因為ceres中變量必須用數組類型,所以需要這樣一個函數進行數據類型轉換,如下:

void Estimator::vector2double() {for (int i = 0; i <= WINDOW_SIZE; i++){para_Pose[i][0] = Ps[i].x();para_Pose[i][1] = Ps[i].y();para_Pose[i][2] = Ps[i].z();Quaterniond q{Rs[i]};para_Pose[i][3] = q.x();para_Pose[i][4] = q.y();para_Pose[i][5] = q.z();para_Pose[i][6] = q.w();para_SpeedBias[i][0] = Vs[i].x();para_SpeedBias[i][1] = Vs[i].y();para_SpeedBias[i][2] = Vs[i].z();para_SpeedBias[i][3] = Bas[i].x();para_SpeedBias[i][4] = Bas[i].y();para_SpeedBias[i][5] = Bas[i].z();para_SpeedBias[i][6] = Bgs[i].x();para_SpeedBias[i][7] = Bgs[i].y();para_SpeedBias[i][8] = Bgs[i].z();}for (int i = 0; i < NUM_OF_CAM; i++){para_Ex_Pose[i][0] = tic[i].x();para_Ex_Pose[i][1] = tic[i].y();para_Ex_Pose[i][2] = tic[i].z();Quaterniond q{ric[i]};para_Ex_Pose[i][3] = q.x();para_Ex_Pose[i][4] = q.y();para_Ex_Pose[i][5] = q.z();para_Ex_Pose[i][6] = q.w();}VectorXd dep = f_manager.getDepthVector();for (int i = 0; i < f_manager.getFeatureCount(); i++)para_Feature[i][0] = dep(i);if (ESTIMATE_TD)para_Td[0][0] = td; }

可以看出來,這里面生成的優化變量由:
para_Pose(6維,相機位姿)、
para_SpeedBias(9維,相機速度、加速度偏置、角速度偏置)、
para_Ex_Pose(6維、相機IMU外參)、
para_Feature(1維,特征點深度)、
para_Td(1維,標定同步時間)
五部分組成,在后面進行邊緣化操作時這些優化變量都是當做整體看待。

2.1 MarginalizationInfo類分析

然后,我們先看下和邊緣化類MarginalizationInfo

class MarginalizationInfo {public:~MarginalizationInfo();int localSize(int size) const;int globalSize(int size) const;//添加參差塊相關信息(優化變量,待marg的變量)void addResidualBlockInfo(ResidualBlockInfo *residual_block_info);//計算每個殘差對應的雅克比,并更新parameter_block_datavoid preMarginalize();//pos為所有變量維度,m為需要marg掉的變量,n為需要保留的變量void marginalize();std::vector<double *> getParameterBlocks(std::unordered_map<long, double *> &addr_shift);std::vector<ResidualBlockInfo *> factors;//所有觀測項int m, n;//m為要邊緣化的變量個數,n為要保留下來的變量個數std::unordered_map<long, int> parameter_block_size; //<優化變量內存地址,localSize>int sum_block_size;std::unordered_map<long, int> parameter_block_idx; //<優化變量內存地址,在矩陣中的id>std::unordered_map<long, double *> parameter_block_data;//<優化變量內存地址,數據>std::vector<int> keep_block_size; //global sizestd::vector<int> keep_block_idx; //local sizestd::vector<double *> keep_block_data;Eigen::MatrixXd linearized_jacobians;Eigen::VectorXd linearized_residuals;const double eps = 1e-8; };

先說變量,這里有三個unordered_map相關的變量分別是:
parameter_block_size、
parameter_block_idx、
parameter_block_data,
他們的key都同一是long類型的內存地址,而value分別是,各個優化變量的長度各個優化變量在id各個優化變量對應的double指針類型的數據
對應的有三個vector相關的變量分別是:
keep_block_size、
keep_block_idx、
keep_block_data,
他們是進行邊緣化之后保留下來的各個優化變量的長度各個優化變量在id各個優化變量對應的double指針類型的數據
還有
linearized_jacobians、
linearized_residuals,
分別指的是邊緣化之后從信息矩陣恢復出來雅克比矩陣和殘差向量

2.3 第一步:調用addResidualBlockInfo()

對于函數我們直接看optimization中的調用會更直觀,首先會調用addResidualBlockInfo()函數將各個殘差以及殘差涉及的優化變量添加入上面所述的優化變量中:
首先添加上一次先驗殘差項:

if (last_marginalization_info) {vector<int> drop_set;for (int i = 0; i < static_cast<int>(last_marginalization_parameter_blocks.size()); i++)//last_marginalization_parameter_blocks是上一輪留下來的殘差塊{if (last_marginalization_parameter_blocks[i] == para_Pose[0] ||last_marginalization_parameter_blocks[i] == para_SpeedBias[0])//需要marg掉的優化變量,也就是滑窗內第一個變量drop_set.push_back(i);}// construct new marginlization_factorMarginalizationFactor *marginalization_factor = new MarginalizationFactor(last_marginalization_info);ResidualBlockInfo *residual_block_info = new ResidualBlockInfo(marginalization_factor, NULL,last_marginalization_parameter_blocks,drop_set);marginalization_info->addResidualBlockInfo(residual_block_info); }

然后添加第0幀和第1幀之間的IMU預積分值以及第0幀和第1幀相關優化變量

{if (pre_integrations[1]->sum_dt < 10.0){IMUFactor* imu_factor = new IMUFactor(pre_integrations[1]);ResidualBlockInfo *residual_block_info = new ResidualBlockInfo(imu_factor, NULL,vector<double *>{para_Pose[0], para_SpeedBias[0], para_Pose[1], para_SpeedBias[1]},//優化變量vector<int>{0, 1});//這里是0,1的原因是0和1是para_Pose[0], para_SpeedBias[0]是需要marg的變量marginalization_info->addResidualBlockInfo(residual_block_info);} }

最后添加第一次觀測滑窗中第0幀的路標點以及其他相關的滑窗中的幀的相關的優化變量

{int feature_index = -1;for (auto &it_per_id : f_manager.feature){it_per_id.used_num = it_per_id.feature_per_frame.size();//這里是遍歷滑窗所有的特征點if (!(it_per_id.used_num >= 2 && it_per_id.start_frame < WINDOW_SIZE - 2))continue;++feature_index;int imu_i = it_per_id.start_frame, imu_j = imu_i - 1;//這里是從特征點的第一個觀察幀開始if (imu_i != 0)//如果第一個觀察幀不是第一幀就不進行考慮,因此后面用來構建marg矩陣的都是和第一幀有共視關系的滑窗幀continue;Vector3d pts_i = it_per_id.feature_per_frame[0].point;for (auto &it_per_frame : it_per_id.feature_per_frame){imu_j++;if (imu_i == imu_j)continue;Vector3d pts_j = it_per_frame.point;if (ESTIMATE_TD){ProjectionTdFactor *f_td = new ProjectionTdFactor(pts_i, pts_j, it_per_id.feature_per_frame[0].velocity, it_per_frame.velocity,it_per_id.feature_per_frame[0].cur_td, it_per_frame.cur_td,it_per_id.feature_per_frame[0].uv.y(), it_per_frame.uv.y());ResidualBlockInfo *residual_block_info = new ResidualBlockInfo(f_td, loss_function,vector<double *>{para_Pose[imu_i], para_Pose[imu_j], para_Ex_Pose[0], para_Feature[feature_index], para_Td[0]},//優化變量vector<int>{0, 3});marginalization_info->addResidualBlockInfo(residual_block_info);}else{ProjectionFactor *f = new ProjectionFactor(pts_i, pts_j);ResidualBlockInfo *residual_block_info = new ResidualBlockInfo(f, loss_function,vector<double *>{para_Pose[imu_i], para_Pose[imu_j], para_Ex_Pose[0], para_Feature[feature_index]},//優化變量vector<int>{0, 3});//為0和3的原因是,para_Pose[imu_i]是第一幀的位姿,需要marg掉,而3是para_Feature[feature_index]是和第一幀相關的特征點,需要marg掉marginalization_info->addResidualBlockInfo(residual_block_info);}}} }

上面添加殘差以及優化變量的方式和后端線性優化中添加的方式相似,因為邊緣化類應該就是仿照ceres寫的,我們可以簡單剖析下上面的操作,
第一步定義損失函數,對于先驗殘差就是MarginalizationFactor,對于IMU就是IMUFactor,對于視覺就是ProjectionTdFactor,這三個損失函數的類都是繼承自ceres的損失函數類ceres::CostFunction,里面都重載了函數

virtual bool Evaluate(double const *const *parameters, double *residuals, double **jacobians) const;

這個函數通過傳入的優化變量值parameters,以及先驗值(對于先驗殘差就是上一時刻的先驗殘差last_marginalization_info,對于IMU就是預計分值pre_integrations[1],對于視覺就是空間的的像素坐標pts_i, pts_j)可以計算出各項殘差值residuals,以及殘差對應個優化變量的雅克比矩陣jacobians。

第二步定義ResidualBlockInfo,其構造函數如下

ResidualBlockInfo(ceres::CostFunction *_cost_function, ceres::LossFunction *_loss_function, std::vector<double *> _parameter_blocks, std::vector<int> _drop_set)

這一步是為了將不同的損失函數_cost_function以及優化變量_parameter_blocks統一起來再一起添加到marginalization_info中。變量_loss_function是核函數,在VINS-mono的邊緣化中僅僅視覺殘差有用到couchy核函數,另外會設置需要被邊緣話的優化變量的位置_drop_set,這里對于不同損失函數又會有不同:
對于先驗損失,其待邊緣化優化變量是根據是否等于para_Pose[0]或者para_SpeedBias[0],也就是說和第一幀相關的優化變量都作為邊緣化的對象。
對于IMU,其輸入的_drop_set是vector{0, 1},也就是說其待邊緣化變量是para_Pose[0], para_SpeedBias[0],也是第一政相關的變量都作為邊緣化的對象,這里值得注意的是和后端優化不同,這里只添加了第一幀和第二幀的相關變量作為優化變量,因此邊緣化構造的信息矩陣會比后端優化構造的信息矩陣要小
對于視覺,其輸入的_drop_set是vector{0, 3},也就是說其待邊緣化變量是para_Pose[imu_i]和para_Feature[feature_index],從這里可以看出來在VINS-mono的邊緣化操作中會不僅僅會邊緣化第一幀相關的優化變量,還會邊緣化掉以第一幀為起始觀察幀的路標點。

第三步是將定義的residual_block_info添加到marginalization_info中,通過下面這一句

marginalization_info->addResidualBlockInfo(residual_block_info);

然后可以看下addResidualBlockInfo()這個函數的實現如下:

void MarginalizationInfo::addResidualBlockInfo(ResidualBlockInfo *residual_block_info) {factors.emplace_back(residual_block_info);std::vector<double *> &parameter_blocks = residual_block_info->parameter_blocks;//parameter_blocks里面放的是marg相關的變量std::vector<int> parameter_block_sizes = residual_block_info->cost_function->parameter_block_sizes();for (int i = 0; i < static_cast<int>(residual_block_info->parameter_blocks.size()); i++)//這里應該是優化的變量{double *addr = parameter_blocks[i];//指向數據的指針int size = parameter_block_sizes[i];//因為僅僅有地址不行,還需要有地址指向的這個數據的長度parameter_block_size[reinterpret_cast<long>(addr)] = size;//將指針強轉為數據的地址}for (int i = 0; i < static_cast<int>(residual_block_info->drop_set.size()); i++)//這里應該是待邊緣化的變量{double *addr = parameter_blocks[residual_block_info->drop_set[i]];//這個是待邊緣化的變量的idparameter_block_idx[reinterpret_cast<long>(addr)] = 0;//將需要marg的變量的id存入parameter_block_idx} }

這里其實就是分別將不同損失函數對應的優化變量、邊緣化位置存入到parameter_block_sizes和parameter_block_idx中,這里注意的是執行到這一步,parameter_block_idx中僅僅有待邊緣化的優化變量的內存地址的key,而且其對應value全部為0

2.4 第二步:調用preMarginalize()

上面通過調用addResidualBlockInfo()已經確定優化變量的數量、存儲位置、長度以及待優化變量的數量以及存儲位置,下面就需要調用preMarginalize()進行預處理,preMarginalize()實現如下:

void MarginalizationInfo::preMarginalize() {for (auto it : factors)//在前面的addResidualBlockInfo中會將不同的殘差塊加入到factor中{it->Evaluate();//利用多態性分別計算所有狀態變量構成的殘差和雅克比矩陣std::vector<int> block_sizes = it->cost_function->parameter_block_sizes();for (int i = 0; i < static_cast<int>(block_sizes.size()); i++){long addr = reinterpret_cast<long>(it->parameter_blocks[i]);//優化變量的地址int size = block_sizes[i];if (parameter_block_data.find(addr) == parameter_block_data.end())//parameter_block_data是整個優化變量的數據{double *data = new double[size];memcpy(data, it->parameter_blocks[i], sizeof(double) * size);//重新開辟一塊內存parameter_block_data[addr] = data;//通過之前的優化變量的數據的地址和新開辟的內存數據進行關聯}}} }

其中 it->Evaluate()這一句里面其實就是調用各個損失函數中的重載函數Evaluate(),這個函數前面有提到過,就是

virtual bool Evaluate(double const *const *parameters, double *residuals, double **jacobians) const;

這個函數通過傳入的優化變量值parameters,以及先驗值(對于先驗殘差就是上一時刻的先驗殘差last_marginalization_info,對于IMU就是預計分值pre_integrations[1],對于視覺就是空間的的像素坐標pts_i, pts_j)可以計算出各項殘差值residuals,以及殘差對應個優化變量的雅克比矩陣jacobians。此外這里會給parameter_block_data賦值,這里引用崔華坤老師寫的《VINS 論文推導及代碼解析》中的例子

parameter_block_sizes中的key值就是上表中的左邊第一列,value值就是上表中的中間一列(localSize)
parameter_block_data中的key值就是上表中的左邊第一列,value值就是上表中的右邊第一列(double*的數據)

2.5 第三步:調用marginalize()

前面兩步已經將數據都準備好了,下面通過調用marginalize()函數就要正式開始進行邊緣化操作了,實現如下:

void MarginalizationInfo::marginalize() {int pos = 0;for (auto &it : parameter_block_idx)//遍歷待marg的優化變量的內存地址{it.second = pos;pos += localSize(parameter_block_size[it.first]);}m = pos;//需要marg掉的變量個數for (const auto &it : parameter_block_size){if (parameter_block_idx.find(it.first) == parameter_block_idx.end())//如果這個變量不是是待marg的優化變量{parameter_block_idx[it.first] = pos;//就將這個待marg的變量id設為pospos += localSize(it.second);//pos加上這個變量的長度}}n = pos - m;//要保留下來的變量個數//通過上面的操作就會將所有的優化變量進行一個偽排序,待marg的優化變量的idx為0,其他的和起所在的位置相關TicToc t_summing;Eigen::MatrixXd A(pos, pos);//整個矩陣A的大小Eigen::VectorXd b(pos);A.setZero();b.setZero();TicToc t_thread_summing;pthread_t tids[NUM_THREADS];ThreadsStruct threadsstruct[NUM_THREADS];int i = 0;for (auto it : factors)//將各個殘差塊的雅克比矩陣分配到各個線程中去{threadsstruct[i].sub_factors.push_back(it);i++;i = i % NUM_THREADS;}for (int i = 0; i < NUM_THREADS; i++){TicToc zero_matrix;threadsstruct[i].A = Eigen::MatrixXd::Zero(pos,pos);threadsstruct[i].b = Eigen::VectorXd::Zero(pos);threadsstruct[i].parameter_block_size = parameter_block_size;threadsstruct[i].parameter_block_idx = parameter_block_idx;int ret = pthread_create( &tids[i], NULL, ThreadsConstructA ,(void*)&(threadsstruct[i]));//分別構造矩陣if (ret != 0){ROS_WARN("pthread_create error");ROS_BREAK();}}for( int i = NUM_THREADS - 1; i >= 0; i--) {pthread_join( tids[i], NULL ); A += threadsstruct[i].A;b += threadsstruct[i].b;}//TODOEigen::MatrixXd Amm = 0.5 * (A.block(0, 0, m, m) + A.block(0, 0, m, m).transpose());Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> saes(Amm);Eigen::MatrixXd Amm_inv = saes.eigenvectors() * Eigen::VectorXd((saes.eigenvalues().array() > eps).select(saes.eigenvalues().array().inverse(), 0)).asDiagonal() * saes.eigenvectors().transpose();//舒爾補Eigen::VectorXd bmm = b.segment(0, m);Eigen::MatrixXd Amr = A.block(0, m, m, n);Eigen::MatrixXd Arm = A.block(m, 0, n, m);Eigen::MatrixXd Arr = A.block(m, m, n, n);Eigen::VectorXd brr = b.segment(m, n);A = Arr - Arm * Amm_inv * Amr;b = brr - Arm * Amm_inv * bmm;//這里的A和b應該都是marg過的A和b,大小是發生了變化的//下面就是更新先驗殘差項Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> saes2(A);//求特征值Eigen::VectorXd S = Eigen::VectorXd((saes2.eigenvalues().array() > eps).select(saes2.eigenvalues().array(), 0));Eigen::VectorXd S_inv = Eigen::VectorXd((saes2.eigenvalues().array() > eps).select(saes2.eigenvalues().array().inverse(), 0));Eigen::VectorXd S_sqrt = S.cwiseSqrt();Eigen::VectorXd S_inv_sqrt = S_inv.cwiseSqrt(); }

第一步,秉承這map數據結構沒有即添加,存在即賦值的語法,上面的代碼會先補充parameter_block_idx,前面提到經過addResidualBlockInfo()函數僅僅帶邊緣化的優化變量在parameter_block_idx有key值,這里會將保留的優化變量的內存地址作為key值補充進去,并統一他們的value值是其前面已經放入parameter_block_idx的優化變量的維度之和,同時這里會計算出兩個變量m和n,他們分別是待邊緣化的優化變量的維度和以及保留的優化變量的維度和。

第二步,函數會通過多線程快速構造各個殘差對應的各個優化變量的信息矩陣(雅克比和殘差前面都已經求出來了),然后在加起來,如下圖所示:

因為這里構造信息矩陣時采用的正是parameter_block_idx作為構造順序,因此,就會自然而然地將待邊緣化的變量構造在矩陣的左上方。

第三步,函數會通過shur補操作進行邊緣化,然后再從邊緣化后的信息矩陣中恢復出來雅克比矩陣linearized_jacobians和殘差linearized_residuals,這兩者會作為先驗殘差帶入到下一輪的先驗殘差的雅克比和殘差的計算當中去。

2.6 第四步:滑窗預移動

在optimization的最后會有一部滑窗預移動的操作,就是下面這一段代碼

std::unordered_map<long, double *> addr_shift; for (int i = 1; i <= WINDOW_SIZE; i++)//從1開始,因為第一幀的狀態不要了 {//這一步的操作指的是第i的位置存放的的是i-1的內容,這就意味著窗口向前移動了一格addr_shift[reinterpret_cast<long>(para_Pose[i])] = para_Pose[i - 1];//因此para_Pose這些變量都是雙指針變量,因此這一步是指針操作addr_shift[reinterpret_cast<long>(para_SpeedBias[i])] = para_SpeedBias[i - 1]; } for (int i = 0; i < NUM_OF_CAM; i++)addr_shift[reinterpret_cast<long>(para_Ex_Pose[i])] = para_Ex_Pose[i]; if (ESTIMATE_TD) {addr_shift[reinterpret_cast<long>(para_Td[0])] = para_Td[0]; } vector<double *> parameter_blocks = marginalization_info->getParameterBlocks(addr_shift);if (last_marginalization_info)delete last_marginalization_info;//刪除掉上一次的marg相關的內容 last_marginalization_info = marginalization_info;//marg相關內容的遞歸 last_marginalization_parameter_blocks = parameter_blocks;//優化變量的遞歸,這里面僅僅是指針

值得注意的是,這里僅僅是相當于將指針進行了一次移動,指針對應的數據還是舊數據,因此需要結合后面調用的slideWindow()函數才能實現真正的滑窗移動,此外
last_marginalization_info就是保留下來的先驗殘差信息,包括保留下來的雅克比linearized_jacobians、殘差linearized_residuals、保留下來的和邊緣化有關的數據長度keep_block_size、順序keep_block_idx以及數據keep_block_data。
last_marginalization_info就是保留下來的滑窗內的所有的優化變量

這里需要明確一個概念就是,邊緣化操作并不會改變優化變量的值,而僅僅是改變了優化變量之間的關系,而這個關系就是通過信息矩陣體現的。

到此邊緣化操作的流程就介紹完了,上面介紹的邊緣化最老幀的情況,邊緣化次新幀的方式類似,在此就不再贅述,如果有什么問題歡迎交流~

此外,對其他SLAM算法感興趣的同學可以看考我的博客SLAM算法總結——經典SLAM算法框架總結

總結

以上是生活随笔為你收集整理的VINS-Mono关键知识点总结——边缘化marginalization理论和代码详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

亚洲无毛专区 | 人成在线免费视频 | 亚洲日本欧美在线 | 一本一道久久a久久精品蜜桃 | 国产精品久久久久久久久免费 | 黄色三级久久 | 免费在线观看av不卡 | 亚洲男人天堂a | 天天五月天色 | 中文字幕在线播放一区 | 亚洲精品久久久蜜桃 | 天天干天天射天天爽 | 最近中文字幕大全中文字幕免费 | 欧美成人中文字幕 | 在线观看国产麻豆 | 九九日九九操 | japanesexxx乱女另类 | 一区二区三区四区五区在线 | 91手机在线看片 | 国产91精品久久久久久 | 伊人影院99| 日韩在线网| 中文字幕在线免费播放 | 在线免费观看涩涩 | 色偷偷97| 国产精品成人一区二区三区 | 国产精品毛片一区二区三区 | 美女网站免费福利视频 | 欧美另类重口 | 91看片在线播放 | 97人人超碰在线 | 亚洲精品久久久久www | 久av在线| 狠狠色丁香婷婷综合久小说久 | 婷婷国产在线 | 日韩一区二区三区在线看 | 欧美午夜剧场 | 中文字幕黄色av | 亚洲精品国产精品乱码在线观看 | 狠狠插狠狠干 | 日韩视频中文字幕 | 最新av在线播放 | 国产精品美女免费视频 | 一区二区理论片 | 香蕉影院在线观看 | 人成在线免费视频 | 91精品免费视频 | 国产精品k频道 | 天天操夜夜看 | 国产美女免费看 | 91热在线| 欧美 激情 国产 91 在线 | 久久视频一区 | 丁香六月天 | 久久精品成人热国产成 | 精品国产一区二 | 在线免费看黄色 | 91精品秘密在线观看 | 五月天久久综合 | 激情综合电影网 | 日韩综合一区二区 | 91在线视频免费观看 | 99精品视频一区二区 | 亚洲片在线观看 | 免费观看丰满少妇做爰 | 99综合电影在线视频 | 特级a老妇做爰全过程 | 天天爽天天爽夜夜爽 | 五月天久久综合网 | 亚洲在线视频免费 | 国产无限资源在线观看 | 在线免费色 | 日韩视频免费在线 | 国产视频在线一区二区 | 久久久久久蜜桃一区二区 | 九九热99视频 | 91亚洲欧美激情 | 国产69精品久久app免费版 | 人人干天天干 | 日韩av一区二区三区四区 | 国产精品视频99 | 在线观看a视频 | 国产日产在线观看 | 免费看v片网站 | 久久国产成人午夜av影院潦草 | 色婷婷综合视频在线观看 | 国产xxxx| 国产一区二区在线观看视频 | 天天综合天天综合 | 97色国产| 成人久久18免费网站麻豆 | 中文字幕精品一区久久久久 | 久久国产精品99久久久久久丝袜 | 日韩av黄 | 日韩影片在线观看 | 日本最新一区二区三区 | 国产精品白浆 | 亚洲乱码久久久 | 国产91在线 | 美洲 | 日本激情中文字幕 | 亚洲区另类春色综合小说 | 亚洲欧美视频在线播放 | 欧美激情第八页 | 欧美日韩视频一区二区三区 | 国产综合激情 | 久久国产精品一区二区三区四区 | 人人超碰人人 | 日韩a在线观看 | 18性欧美xxxⅹ性满足 | 中文字幕 二区 | 欧洲一区二区在线观看 | 国产精品视频免费看 | 国语自产偷拍精品视频偷 | 国产精品专区在线观看 | 99色资源| 欧美特一级 | 草久视频在线观看 | 国产一区二区精品在线 | 久在线观看| av黄色免费网站 | 精品一区二区在线免费观看 | 欧美日韩不卡在线 | 四虎在线免费视频 | 日韩精品一区二区三区三炮视频 | 999免费视频| 黄色91在线 | 人人干人人做 | 中文字幕888 | 人人干网站 | 青青河边草免费直播 | 久久精品久久精品久久 | 免费在线观看av不卡 | 亚洲无吗av | 草久视频在线观看 | 日韩理论在线播放 | 国产在线久草 | 狠狠色噜噜狠狠狠狠 | 精品一区二区日韩 | 国产视频在线观看一区二区 | 四虎成人在线 | 十八岁以下禁止观看的1000个网站 | 高清国产一区 | 99精品在线直播 | 99国产视频在线 | 国产裸体视频网站 | 成人精品国产免费网站 | 在线观看中文av | 亚洲一区二区三区毛片 | 天天干.com | 婷婷伊人综合 | 国内外激情视频 | 99精品热视频只有精品10 | 在线导航福利 | 国产在线1区 | 免费在线一区二区三区 | 人人藻人人澡人人爽 | 91日韩在线视频 | 中文字幕av在线电影 | 日韩av电影网站在线观看 | 成人午夜剧场在线观看 | 综合久久久久久久 | 色视频在线观看免费 | 91av在线不卡 | 99免费视频 | 欧美另类色图 | 一本一本久久a久久 | 久久久免费少妇 | 亚洲精品国产精品乱码不99热 | 婷婷五综合 | 91字幕| 久久成人免费电影 | www久久久| 久久免费视频在线观看6 | 亚洲在线视频免费 | 国产激情小视频在线观看 | 二区三区视频 | 国产精品毛片久久久久久久久久99999999 | 欧美久久久久久久久久 | 久久一级电影 | 国产特黄色片 | 欧美精品一区二区三区四区在线 | 国内精品一区二区 | 91看片淫黄大片一级在线观看 | 日日夜夜爱 | 免费高清无人区完整版 | 国产在线观看你懂的 | 黄色大片日本免费大片 | 欧美精品久久人人躁人人爽 | 看av免费网站 | 久久高清国产 | 国产淫片免费看 | 亚洲91中文字幕无线码三区 | 久久久国产精品一区二区三区 | 五月情婷婷 | 亚洲精选99 | 亚洲成人av在线播放 | 色婷婷激情网 | 91九色porny在线 | 91豆麻精品91久久久久久 | 91福利小视频 | 亚洲国产天堂av | 日韩免费观看视频 | 欧美成人中文字幕 | 成年人在线免费看视频 | 一区二区三区在线观看免费视频 | 日韩资源在线 | 欧美成人久久 | 五月天国产精品 | 日韩a在线 | 欧美日韩国产一二三区 | 欧美日韩久久久 | 天天激情天天干 | 97视频免费观看2区 亚洲视屏 | 久久精品福利视频 | 国产在线成人 | 成年人视频免费在线 | 伊人影院av | 日日夜夜干 | 国产高清网站 | 色噜噜在线观看视频 | 韩国av免费观看 | 中文字幕在线日亚洲9 | 丁香资源影视免费观看 | 中文字幕一二 | 99久久久国产免费 | 日韩一级精品 | 免费男女羞羞的视频网站中文字幕 | 国产视频在线一区二区 | 一本一本久久a久久精品综合小说 | 中文字幕影片免费在线观看 | 51久久夜色精品国产麻豆 | 福利一区二区三区四区 | 日韩毛片精品 | 亚洲无在线 | 亚洲精品日韩av | 岛国一区在线 | 欧美日韩一区二区视频在线观看 | 日日综合 | 日韩国产欧美在线播放 | 精品国产乱码久久久久久天美 | 99精品视频免费 | 亚洲精品综合欧美二区变态 | 玖玖视频在线 | 成人资源在线播放 | 激情小说网站亚洲综合网 | 探花视频免费观看 | 婷婷久久网| 久久久久久久久久影视 | 五月天激情视频在线观看 | 国产第一二区 | 国产亚洲综合精品 | 玖玖爱免费视频 | 国产69精品久久久久9999apgf | 91福利试看 | 天天操人人要 | 国产精品久久久久久久久久了 | 欧美性生活小视频 | 综合亚洲视频 | 天天操天天色天天 | 草久久久久 | 国产视频一级 | 欧美 日韩 国产 成人 在线 | 高清不卡一区二区在线 | 久久久久久综合 | 超碰国产在线播放 | 五月开心六月婷婷 | 亚洲不卡123 | 午夜免费在线观看 | 国产一级免费观看 | 亚洲精品在线免费播放 | 国产精品入口麻豆www | 国产录像在线观看 | 日韩毛片在线一区二区毛片 | 国产亚洲在| 免费在线观看国产黄 | 美女福利视频 | 毛片网在线 | 亚洲aaa级 | 日韩欧美在线免费观看 | 国产在线91精品 | 国产日韩av在线 | www日韩在线 | 成人小视频在线播放 | 国产精品高潮呻吟久久av无 | 成年人黄色大片在线 | 午夜av在线免费 | 久久精品视频日本 | 欧美国产日韩在线观看 | 国产成人精品女人久久久 | 欧美激情视频一区二区三区 | 日本中文字幕网站 | 中文字幕一区二区在线观看 | 波多野结衣一区 | 在线观看久草 | 国产在线精品一区二区不卡了 | 国产一区二区在线观看视频 | 在线亚洲精品 | 香蕉影视 | 日日操天天射 | 日韩午夜三级 | 国产电影黄色av | 婷婷久久精品 | 日精品在线观看 | 久久电影网站中文字幕 | 免费看一级特黄a大片 | 午夜一级免费电影 | 国产成人资源 | 另类老妇性bbwbbw高清 | 91免费高清观看 | 中文字幕久久精品一区 | 精品二区久久 | 五月婷婷六月综合 | 国产亚洲精品成人av久久影院 | 最新色视频 | 精品国产一区二区三区久久影院 | 欧美伦理一区二区三区 | 日本黄区免费视频观看 | 欧美色888 | 日本色小说视频 | 国产日韩欧美在线 | 久久99国产精品久久 | 欧美日本中文字幕 | 一区二区毛片 | 人人讲下载 | 丝袜美女在线 | 91麻豆精品国产91久久久久 | 欧美午夜性 | 日b黄色片 | 夜夜躁日日躁狠狠躁 | 精品国产一区二区三区免费 | 午夜视频在线瓜伦 | 波多野结衣在线观看视频 | 中文在线a∨在线 | 成人黄色在线播放 | 日日爱av | 日免费视频 | 国产免费黄色 | 成人午夜电影免费在线观看 | 91成人亚洲 | 久久视讯 | 在线视频日韩一区 | av一级在线观看 | 亚洲播放一区 | 热99久久精品| 精品一区精品二区高清 | 摸bbb搡bbb搡bbbb| 97视频在线免费播放 | 久久精品伊人 | 色婷婷av一区| 国产一级片免费观看 | 国产一区二区电影在线观看 | 色综合久久久 | 欧美中文字幕久久 | 日本三级全黄少妇三2023 | 天天做综合网 | 色在线视频 | 欧美日韩精品国产 | 在线а√天堂中文官网 | 狠狠色丁香婷婷综合久小说久 | 色av男人的天堂免费在线 | 欧美 日韩 性 | 成人小电影在线看 | 国产资源网站 | 亚洲激情免费 | 国产成人一区二区在线观看 | 免费韩国av| 午夜手机电影 | 韩日精品在线观看 | 在线免费试看 | 天天操天天干天天操天天干 | 欧美日韩国产一区二区三区 | 日韩专区av | 国产在线播放不卡 | 波多野结衣视频一区二区三区 | 欧美一级日韩三级 | 久久黄网站 | 日韩字幕 | 久久99国产精品免费网站 | 久久精品日本啪啪涩涩 | 在线观看av中文字幕 | 夜色资源站国产www在线视频 | 中文字幕欧美日韩va免费视频 | 午夜精品一区二区国产 | 成人小视频免费在线观看 | 国产专区精品 | 99亚洲视频 | 久久9精品 | 亚洲区另类春色综合小说 | 蜜臀av夜夜澡人人爽人人 | 国产美女精品视频免费观看 | 五月天狠狠操 | 特黄特色特刺激视频免费播放 | 欧美在线视频一区二区三区 | 国产精品大片免费观看 | 久久天天操 | 久草视频手机在线 | 国产一级特黄毛片在线毛片 | 肉色欧美久久久久久久免费看 | 996久久国产精品线观看 | 亚洲国产人午在线一二区 | 亚洲国产精品人久久电影 | 免费av看片 | 麻豆视频免费在线观看 | 91久久精品日日躁夜夜躁国产 | 久久久久麻豆 | 欧美日韩中文在线 | 亚洲欧美在线观看视频 | 亚洲视频专区在线 | 国产 在线 高清 精品 | 日韩在线视频精品 | www.夜夜爱 | 亚洲最大av在线播放 | 日韩av成人| 在线黄av| 99久久超碰中文字幕伊人 | 久草国产精品 | 又黄又刺激又爽的视频 | 夜夜高潮夜夜爽国产伦精品 | 日韩在线不卡视频 | 97成人免费 | 一区二区三区污 | 五月婷婷视频在线 | 天天干国产 | 色综合色综合色综合 | 欧美性视频网站 | 三级毛片视频 | 黄色91在线| 狠狠操操操 | 美女视频黄色免费 | 国产精品久久久久久a | 91桃色国产在线播放 | 欧美日韩国产在线一区 | 日韩三级av | 欧美另类美少妇69xxxx | 亚洲最新av网址 | 久久激情五月婷婷 | 天天做日日做天天爽视频免费 | 免费日韩一区二区三区 | 久久99精品久久久久蜜臀 | 在线日韩中文 | 美女精品在线观看 | 97精品在线视频 | 五月天天天操 | 精品久久久久久国产 | 国产精品国产三级国产专区53 | 精品国产亚洲一区二区麻豆 | 91丨九色丨蝌蚪丰满 | 亚洲黄色一级电影 | 日韩欧美不卡 | 黄色小视频在线观看免费 | 免费福利在线 | 亚洲国产视频在线 | 国产黄色片免费观看 | 国产精品久久久久免费 | 正在播放 国产精品 | 天天射天天操天天干 | 欧美在线观看视频免费 | 国产一区二区在线播放 | 六月激情 | 亚洲午夜大片 | 黄色成人在线网站 | 久久福利精品 | 色免费在线 | 中文字幕在线不卡国产视频 | 久久久久免费 | 国产美女永久免费 | 日韩中文字幕视频在线 | 996久久国产精品线观看 | a级一a一级在线观看 | 久久99国产视频 | 99精品99 | 婷婷视频导航 | 99热精品久久 | 黄色av电影一级片 | 亚洲 欧美 国产 va在线影院 | 久久久久久看片 | 色天天中文 | 夜夜嗨av色一区二区不卡 | 亚洲三级性片 | 在线观看免费黄色 | 九九色网| 成人av网页| 亚洲国产精品女人久久久 | 99精彩视频在线观看免费 | 欧美一级性生活视频 | 国产一级片观看 | 夜夜操网 | 亚洲一片黄 | 日本黄区免费视频观看 | 欧美日韩不卡一区二区 | 色九九影院| 一区二区三区高清 | 亚洲国产成人久久 | 国产二区av | 国产在线观看免费 | 人人玩人人添人人澡97 | 精品视频区| 成年人三级网站 | 黄色一级影院 | 久久精品视频在线观看 | 成人啪啪18免费游戏链接 | 又大又硬又黄又爽视频在线观看 | 成人a视频片观看免费 | 久久久久久久久久久久99 | 欧美日韩不卡一区 | 亚洲夜夜爽| a黄色影院 | 欧美激情第八页 | 午夜精品久久久久久久99 | 成人三级网址 | 夜夜骑天天操 | 中文字幕麻豆 | 99久久综合狠狠综合久久 | 欧美韩国日本在线观看 | 91精品一区二区在线观看 | 欧洲一区二区在线观看 | 免费在线观看不卡av | 色婷婷久久一区二区 | 91在线porny国产在线看 | 99久久国产免费看 | 欧美色婷 | 2019中文字幕网站 | 国产精品手机视频 | 久久久久综合 | 久久人操 | 久久久久久久久久久网站 | 一区二区三区免费在线观看视频 | 色a综合 | 精品国产一区二区三区在线 | 成人超碰在线 | 国产一区欧美在线 | 精品 激情 | 97电影网手机版 | 五月激情电影 | 免费观看的av网站 | av在线小说 | av免费观看高清 | 国产精品麻豆99久久久久久 | 精品久久免费看 | 国产美女网 | 国产一区二区网址 | 一区二区三区在线影院 | 超级av在线 | 日韩视频在线观看视频 | 国产一二区免费视频 | 久久成人国产精品入口 | 天天色天 | 天天操天天色综合 | 国产一区视频在线播放 | 午夜91视频| 黄色大片网 | 成人在线黄色电影 | 欧美成人精品三级在线观看播放 | 久久视频在线 | 美女精品在线观看 | 91污视频在线| 91伊人影院 | 久久国产精品影视 | 国产第一页在线播放 | 西西大胆啪啪 | 亚洲一级在线观看 | 精品a在线 | 五月婷婷综合激情网 | 成人av一级片 | 麻豆小视频在线观看 | 亚洲精品日韩一区二区电影 | 超碰资源在线 | 精品主播网红福利资源观看 | 日韩r级在线 | 男女拍拍免费视频 | 精品1区2区3区 | 女人18毛片a级毛片一区二区 | 色天天天| 日韩精品免费在线视频 | 97精品视频在线播放 | 久亚洲 | 亚洲精品乱码久久久久久9色 | 奇米网8888| 国产午夜一区 | 久久免费视频在线观看30 | 国产夫妻自拍av | 久久久高清 | 青草视频免费观看 | 欧美日韩中文视频 | 免费看一级 | 日韩欧美一区二区三区在线 | 91麻豆精品国产91 | www.亚洲精品在线 | 五月婷久 | 国产一级一片免费播放放a 一区二区三区国产欧美 | 色www精品视频在线观看 | 黄色毛片电影 | av高清免费在线 | 最近2019年日本中文免费字幕 | 欧美aa一级| 香蕉影院在线播放 | 91黄色在线看 | a级国产片 | 亚州成人av在线 | 免费看黄的视频 | 色播六月天 | 天天干夜夜夜操天 | 国产不卡视频 | 日韩在线观看中文字幕 | 婷婷去俺也去六月色 | 日日日网| 久久久久电影 | 中文字幕在线观 | 欧美日韩一区二区免费在线观看 | 久久久精品午夜 | 欧美精品首页 | 夜夜夜夜操 | 欧美天天综合网 | 91av综合| 91视频在线观看免费 | 韩国视频一区二区三区 | 欧美巨大| 国产91对白在线播 | 日韩大片免费在线观看 | 最近更新好看的中文字幕 | 国产精品免费人成网站 | 日韩网站在线免费观看 | 中文字幕在线观看亚洲 | 欧美性爽爽 | 国产精品乱码久久久久 | 国产成人精品久 | 日韩有码网站 | 日韩精品欧美视频 | 91精品国自产在线偷拍蜜桃 | 国产成人亚洲在线电影 | 精品一区91 | 欧美日韩69| 天天插天天操天天干 | 九九色在线观看 | 亚洲一区 影院 | 欧美日韩视频在线一区 | 日日操操操 | 999久久久久久久久久久 | 日韩理论电影在线观看 | 国产aaa毛片| 国产精品video爽爽爽爽 | 综合天堂av久久久久久久 | 中文字幕999 | 国产三级久久久 | 婷婷丁香综合 | 深爱激情开心 | 久久综合久久88 | 亚洲国产午夜视频 | 久久久久一区 | 亚洲3级 | 久色免费视频 | 成年人免费看片网站 | 欧美日本一区 | 亚洲婷久久| 亚洲欧美日韩一二三区 | av不卡中文| 久久精品一二三区白丝高潮 | 日韩欧美视频一区二区 | 丁香 久久 综合 | 91av影视 | 亚洲国产操 | 欧美精品在线一区 | 99热 精品在线 | 国产黄在线免费观看 | 国产亚洲精品久久久久久久久久 | 精品国产精品一区二区夜夜嗨 | 久久精品网址 | 天天爽天天搞 | 国产免费a | 久久久黄色av | 麻豆视频免费入口 | 日韩视频在线播放 | 国产精品第十页 | 公与妇乱理三级xxx 在线观看视频在线观看 | 国产精品精品久久久 | 天天夜操 | 欧美一级免费黄色片 | 国产小视频在线播放 | 精品国产美女 | 中文字幕一区二区三区在线视频 | 性色av免费在线观看 | 免费看一级特黄a大片 | 亚洲a在线观看 | 黄色大片日本免费大片 | 人人爽爽人人 | 国产精品九九九九九九 | 操处女逼 | 午夜在线日韩 | 久久97久久97精品免视看 | 黄色aaa毛片 | 97碰碰碰| 奇米导航 | 欧洲精品久久久久毛片完整版 | 蜜臀久久99精品久久久无需会员 | 日韩在线网 | 亚洲精品视频网站在线观看 | 99c视频高清免费观看 | 亚洲精品一区二区三区高潮 | 欧美精品国产综合久久 | 久久av伊人 | 国产香蕉97碰碰久久人人 | 99综合影院在线 | 亚洲免费一级电影 | 91精品对白一区国产伦 | 亚洲综合视频在线 | 亚洲日本中文字幕在线观看 | 国产精品美女在线观看 | 99热精品国产一区二区在线观看 | 成年人在线视频观看 | 国产丝袜一区二区三区 | 欧美福利久久 | 97国产大学生情侣白嫩酒店 | 手机成人免费视频 | 亚洲日本精品视频 | 久久97久久97精品免视看 | 又黄又爽又刺激的视频 | 成人av一区二区兰花在线播放 | 亚洲精品女 | 91av在线精品 | 久久久免费看视频 | 久久五月情影视 | 日本中文字幕在线看 | 午夜精品一区二区三区在线播放 | 免费黄色在线网址 | 99精品影视 | 日韩av电影一区 | 99精品国产99久久久久久97 | 久久综合色播五月 | 九九热re| 青青五月天 | 精品国产一区二区三区久久影院 | 亚洲精品高清视频 | 射久久久 | 欧美aa在线| 国产黄色av网站 | 国产亚洲观看 | 久久精品视频在线 | 激情伊人五月天久久综合 | 国产麻豆视频在线观看 | 91丨九色丨首页 | 亚州国产精品久久久 | 日韩动态视频 | 日本最新中文字幕 | 国产精品久久久久永久免费看 | 国外调教视频网站 | 天天操夜夜逼 | 久久高清免费视频 | 欧美大码xxxx | 欧美在线观看视频免费 | 国产精品一区二区美女视频免费看 | 久久久久成人精品免费播放动漫 | 免费观看视频黄 | 五月亚洲婷婷 | 91麻豆福利 | 天天干天天干天天 | 韩国一区二区三区在线观看 | 久香蕉 | 色婷婷六月天 | 日韩成人xxxx | 97成人免费视频 | 国产视频手机在线 | 欧美国产日韩一区 | 日本天天操 | 久久精品久久99精品久久 | 日韩久久一区二区 | 青青草华人在线视频 | 日韩欧美专区 | 国产九九九视频 | 成人小视频在线观看免费 | 久久综合日 | 亚洲精品18日本一区app | 国产99久久99热这里精品5 | 国产日韩精品在线 | 亚洲精品国精品久久99热一 | 中文理论片 | 午夜av一区 | 黄色福利| av高清一区| 91视频免费 | 久热免费 | 久久久免费看片 | 免费色av | 精品日韩中文字幕 | 激情综合色综合久久 | 国产视频一二区 | 亚洲国产网址 | 久久五月激情 | 国产精品原创av片国产免费 | 国产成人777777| www蜜桃视频 | 国产中文字幕网 | 日本不卡一区二区三区在线观看 | 香蕉网在线播放 | 日韩精品视 | 日本bbbb摸bbbb | 亚洲国产精品久久久久久 | 久久精品欧美一区二区三区麻豆 | 精品视频免费久久久看 | 成年美女黄网站色大片免费看 | 精品在线你懂的 | 午夜视频在线观看一区 | 日韩精品视频在线观看免费 | 久草精品在线播放 | 伊甸园永久入口www 99热 精品在线 | av在线观 | 99成人精品 | 99理论片 | 免费一级片观看 | 成年免费在线视频 | 欧美精品一区二区免费 | 久青草视频在线观看 | 一区二区三区高清在线 | 一区二区三区手机在线观看 | 欧美淫视频 | 精品国产一区二区三区久久久蜜月 | 国产一区二区免费在线观看 | 国产伦理久久精品久久久久_ | 水蜜桃亚洲一二三四在线 | 久久不射影院 | 日本中文字幕在线免费观看 | 天天天天天天天天操 | 射久久久| 狠狠黄 | 欧美一级片免费播放 | av中文字幕在线播放 | 久久在线观看 | 国产午夜小视频 | 成人一区二区三区中文字幕 | 国产精品一区免费在线观看 | 色偷偷男人的天堂av | 欧美网址在线观看 | 欧美亚洲国产一卡 | 99精品一区二区三区 | 1024手机看片国产 | 日韩在线一级 | 超碰在线人人爱 | 亚洲传媒在线 | 国产成人久久精品一区二区三区 | 亚洲精选视频在线 | 一级黄网| 欧美成人黄 | 蜜桃麻豆www久久囤产精品 | 免费看的黄色 | a级成人毛片 | 国产欧美精品一区二区三区四区 | 久久人人爽爽 | 欧美成人日韩 | 91在线免费视频 | 91成年人网站 | 在线免费色视频 | 久久人91精品久久久久久不卡 | 亚洲精品91天天久久人人 | 欧美在线a视频 | 五月婷婷国产 | 色天天综合久久久久综合片 | 黄色三级免费观看 | 亚洲精品国偷自产在线99热 | 欧美日韩视频在线观看免费 | 黄色www免费 | 亚洲精品日韩一区二区电影 | 国产日韩视频在线播放 | 日韩精品91偷拍在线观看 | 亚洲激情在线视频 | 在线精品视频免费观看 | 久久久精品影视 | 亚洲视频,欧洲视频 | 亚洲精品综合一区二区 | 日本高清免费中文字幕 | 国产一区二区在线免费观看 | 国产精品日韩精品 | 日批视频国产 | 亚洲精品一区二区18漫画 | 国产精品久久麻豆 | 日韩精品一区二区在线观看 | 黄色网www| 久久最新网址 | 蜜桃视频在线视频 | 五月天亚洲综合小说网 | 亚洲精品动漫成人3d无尽在线 | 超碰97在线资源站 | 91色九色| av网站有哪些 | 久久99亚洲精品 | 五月天网页 | 欧美国产日韩在线观看 | 亚洲丝袜一区 | 免费在线观看一区 | 天天干天天拍天天操天天拍 | 久久国产色 | 中文视频在线 | 国产高清视频免费 | 免费亚洲婷婷 | 制服丝袜成人在线 | 天天拍夜夜拍 | 国产视频精品久久 | 久久成年人视频 | 亚洲精品视频在线看 | 亚洲三级国产 | 国产99精品 | 国产女v资源在线观看 | 99久久综合狠狠综合久久 | 欧美最猛性xxxxx(亚洲精品) | 91精品国产乱码 | 九九综合九九综合 | 丁香久久综合 | 免费观看性生交 | 福利一区二区三区四区 | 久久精品视频免费观看 | 欧美色图p | 91精品在线观看入口 | 欧美99精品| 成人一级免费电影 | 96久久 | 91九色蝌蚪视频网站 | 中文字幕第 | 日韩欧美高清一区二区 | 久久免费国产 | 国产一区二区三区高清播放 | 日本精品中文字幕在线观看 | 成人免费xxxxxx视频 | 伊人影院av | 久久99精品热在线观看 | 久久久精品| 中文字幕你懂的 | 麻豆国产精品一区二区三区 | 欧美天天干 | 亚洲精选视频免费看 | 成人精品亚洲 | 成人av电影在线播放 | 免费日韩一区二区 | 中文字幕激情 | 91视频在线看 | 日韩成人精品一区二区三区 | 91精品视频在线 | 久久这里精品视频 | 国产亚洲视频在线观看 | 国产成人精品三级 | 成人av资源站 | 久章草在线 | 99国产精品久久久久久久久久 | 亚洲国产av精品毛片鲁大师 | avove黑丝 | 久久久久久久久久久国产精品 | 久久综合电影 | 91最新在线 | a午夜在线 | 在线国产激情视频 | 国产精品毛片一区视频播不卡 | 国产第一福利网 | 日韩中文字| 欧美精品一区二区性色 | 国产精品久久久久久av | 免费在线一区二区三区 | 玖玖国产精品视频 | 亚洲国产三级 | 成年人在线播放视频 | 香蕉网站在线观看 | 亚洲乱码久久久 | 激情av在线播放 | www.香蕉| 欧美日韩国产一区二区在线观看 | 亚洲最新av在线 | 久久激情综合网 | 蜜臀av在线一区二区三区 | 91传媒在线| 免费开视频 | 久久夜色精品国产欧美乱 | 日黄网站 | 日韩精品不卡在线 | 亚洲精品午夜久久久 | 一区二区三区高清不卡 | 成人免费 在线播放 | 欧美日韩二区在线 | 超级碰碰碰视频 | 操碰av | 久久午夜影视 | 久久久久久高潮国产精品视 | 成人国产精品久久久 | 狠狠艹夜夜干 | 99视频免费播放 | 天天se天天cao天天干 | 国产高清 不卡 | 国产精品久久视频 | 亚洲天堂网在线播放 | 在线免费中文字幕 | 亚洲国产欧洲综合997久久, | 中文字幕在线一区观看 | 日日干天天 | 午夜精品久久久久久久99无限制 | 日韩午夜三级 | 国产在线播放一区二区三区 | 亚洲精品在线观看视频 | 精品国产一区在线观看 | 丁香色天天 | 亚洲少妇自拍 | 日韩免费久久 | 成人久久精品视频 | 中文在线免费一区三区 |