ORB-SLAM中優化使用g2o庫,先複習一下g2o的用法,上類圖html
其中SparseOptimizer就是咱們須要維護的優化求解器,他是一個優化圖,也是一個超圖(包含若干頂點和一元二元多元邊),怎樣定義圖的頂點(優化變量_estimate)和邊(偏差項_error)是用戶須要考慮的問題,能夠從g2o/types查找是否已經有定義好的頂點或邊,若沒有,須要本身去實現。算法
本身實現的時候注意,基本都是去繼承BaseVertex<D,T>; BaseUnaryEdge<D,E,VertexXi>...這幾個模板類,根據須要實現(override)虛函數.app
這張類圖的下半部分就是咱們初始化優化求解器時須要指定的求解方法。ide
求解的梯度降低算法能夠選擇GN,LM(最經常使用),或者DogLeg;函數
算法求解器還包括兩部分,優化
//variable size solver using BlockSolverX = BlockSolverPL<Eigen::Dynamic, Eigen::Dynamic>; // solver for BA/3D SLAM using BlockSolver_6_3 = BlockSolverPL<6, 3>; // solver fo BA with scale using BlockSolver_7_3 = BlockSolverPL<7, 3>; // 2Dof landmarks 3Dof poses using BlockSolver_3_2 = BlockSolverPL<3, 2>;
能夠設置爲動態的BlockSolverXspa
所以,ORB-SLAM中優化求解器初始化過程以下:線程
g2o::SparseOptimizer optimizer; g2o::BlockSolver_6_3::LinearSolverType * linearSolver; // 線性方程求解器 linearSolver = new g2o::LinearSolverEigen<g2o::BlockSolver_6_3::PoseMatrixType>(); // 稀疏矩陣塊求解器 g2o::BlockSolver_6_3 * solver_ptr = new g2o::BlockSolver_6_3(linearSolver); // 梯度降低算法 g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg(solver_ptr); optimizer.setAlgorithm(solver);
ORB中使用的這些優化函數是很是重要的,在視覺SLAM中有很強的通用性,本身實現的時候徹底能夠參考其實現方法。分爲:code
1. BundleAdjustment()htm
2. PoseOptimization()
3. OptimizeEssentialGraph()
4. OptimizeSim3()
使用到的g2o頂點包括:
1. VertexSE3Expmap():SE(3)位姿
2. VertexSim3Expmap():Sim(3)位姿
3. VertexSBAPointXYZ():地圖點座標
使用到的g2o邊包括:
1. EdgeSE3ProjectXYZ():BA中的重投影偏差(3D-2D(u,v)偏差),將地圖點投影到相機座標系下的相機平面。
2. EdgeSE3ProjectXYZOnlyPose():PoseEstimation中的重投影偏差,將地圖點投影到相機座標系下的相機平面。優化變量只有pose,地圖點位置固定,是一邊元,雙目中使用的是EdgeStereoSE3ProjectXYZOnlyPoze()。
3. EdgeSim3():Sim3之間的相對偏差。優化變量只有Sim3表示的pose,用於OptimizeEssentialGraph。
4. EdgeSim3ProjectXYZ():重投影偏差。優化變量Sim3位姿與地圖點,用於閉環檢測中的OptimizeSim3。