文章目录0参考链接1基本流程整理2代码文件3代码使用示例
0参考链接
[从零开始一起学习SLAM |了解地图优化,逐步了解g2o代码]
[深度理解图优化与g2o:g2o篇]
本文参考以上两个链接,如果想了解更多信息,请参考以上两个
1整理基本流程
图的核心
3358www.Sina.com/是整个图的核心,SparseOptimizer为实心箭头,示出了SparseOptimizer是Optimizable Graph,从而导致了超车
is-a
定点和边包括这个超图(HyperGraph )在许多顶点(HyperGraph:Vertex )和边) HyperGraph:Edge 这些顶点从Base Vertex (即optimizablegraph : vertex )继承,并且边可以从BaseUnaryEdge、BaseBinaryEdge或BaseMultiEdge、多边形继承
has-many:相当于等号
is-a:意味着包含必需的组件
has-a:与has-a相同,至少需要一个
has-many
核心空间优化器包含优化配置的对象。 优化配置是通过优化配置实现的。 其中迭代策略可以在Gauss-Newton (高斯天真狗法,简称GN )、leve rnberg-marquardt (lm法)、Powell’sdogleg三者中任选一种()我们常用
配置SparseOptimizer的优化算法和求解器
优化健康内部包含求解器,该求解器实际上由块求解器组成。 这个块解决器有两个部分。 一个是SparseBlockMatrix,用于计算稀疏的雅可比矩阵和Hessian矩阵。 一个是线性方程组求解器,用于计算迭代过程中最重要的步骤Hx=b。 线性解决程序有几种方法: PCG、CSparse和Choldmod
2代码文件$ tree-L3-d .—bin—build ((cmake files (3.9.1 ) )、cmake (g2o (apps )、(cmake files ) ) ceres (cs parse (free glut (g2o (apps (g2o _ CLI ) ) ) ) ) ) (es(core ) anchored_inverse_depth65 (()-- g2o _ unfold (-- ICP (-- interactive _ slam ((line _ slam () ) )
│ ├── csparse│ │ ├── dense│ │ ├── eigen│ │ ├── pcg│ │ ├── slam2d_linear│ │ └── structure_only│ ├── stuff│ └── types│ ├── data│ ├── deprecated│ ├── icp│ ├── sba│ ├── sclam2d│ ├── sim3│ ├── slam2d│ ├── slam2d_addons│ ├── slam3d│ └── slam3d_addons├── lib└── scriptg2o项目中含有若干文件夹。刨开那些gitignore之类的零碎文件,主要有以下几个:
EXTERNAL 三方库,有ceres, csparse, freeglut,可以选择性地编译;cmake_modules 给cmake用来寻找库的文件。我们用g2o时也会用它里头的东西,例如FindG2O.cmakedoc 文档。包括g2o自带的说明书(难度挺大的一个说明文档)。g2o 最重要的源代码都在这里!script 在android等其他系统编译用的脚本 3 代码使用举例 typedef g2o::BlockSolver< g2o::BlockSolverTraits<3,1> > Block; // 每个误差项优化变量维度为3,误差值维度为1// 第1步:创建一个线性求解器LinearSolverBlock::LinearSolverType* linearSolver = new g2o::LinearSolverDense<Block::PoseMatrixType>(); // 第2步:创建BlockSolver。并用上面定义的线性求解器初始化Block* solver_ptr = new Block( linearSolver ); // 第3步:创建总求解器solver。并从GN, LM, DogLeg 中选一个,再用上述块求解器BlockSolver初始化g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg( solver_ptr );// 第4步:创建终极rydqj 稀疏优化器(SparseOptimizer)g2o::SparseOptimizer optimizer; // 图模型optimizer.setAlgorithm( solver ); // 设置求解器optimizer.setVerbose( true ); // 打开调试输出// 第5步:定义图的顶点和边。并添加到SparseOptimizer中CurveFittingVertex* v = new CurveFittingVertex(); //往图中增加顶点v->setEstimate( Eigen::Vector3d(0,0,0) );v->setId(0);optimizer.addVertex( v );for ( int i=0; i<N; i++ ) // 往图中增加边{ CurveFittingEdge* edge = new CurveFittingEdge( x_data[i] ); edge->setId(i); edge->setVertex( 0, v ); // 设置连接的顶点 edge->setMeasurement( y_data[i] ); // 观测数值 edge->setInformation( Eigen::Matrix<double,1,1>::Identity()*1/(w_sigma*w_sigma) ); // 信息矩阵:协方差矩阵之逆 optimizer.addEdge( edge );}// 第6步:设置优化参数,开始执行优化optimizer.initializeOptimization();optimizer.optimize(100);