1.首先大部分的代码需要在Cmakelists中更新至c++14,否则会出现如下报错
/usr/local/include/g2o/core/base_fixed_sized_edge.h:174:32: error: ‘index_sequence’ is not a member of ‘std’
174 | struct HessianTupleType<std::index_sequence<Ints...>> {
调整方法:
set( CMAKE_CXX_FLAGS "-std=c++14 -O3" )
2.新版g2o库中不再存在原先的VertexSBAPointXYZ,将所有报错的地方改为VertexPointXYZ即可:
typedef g2o::BlockSolver< g2o::BlockSolverTraits<6,3> > Block; // pose维度为 6, landmark 维度为 3
//Block::LinearSolverType* linearSolver = new g2o::LinearSolverEigen(); // 线性方程求解器(原代码对照)
std::unique_ptr<Block::LinearSolverType> linearSolver (new g2o::LinearSolverEigen<Block::PoseMatrixType>());//新编译方式
//Block* solver_ptr = new Block( std::unique_ptr(linearSolver) ); // 矩阵块求解器(原代码对照)
std::unique_ptr<Block> solver_ptr (new Block ( std::move(linearSolver) ));//新编译方式
//g2o::OptimizationAlgorithmGaussNewton* solver = new g2o::OptimizationAlgorithmGaussNewton( unique_ptr(solver_ptr) );//(原代码对照)
g2o::OptimizationAlgorithmGaussNewton* solver = new g2o::OptimizationAlgorithmGaussNewton( std::move(solver_ptr) );//新编译方式
g2o::SparseOptimizer optimizer;
optimizer.setAlgorithm( solver );
/home/dyfluid/slambook-master/ch7/pose_estimation_3d2d.cpp:177:14: error: ‘VertexSBAPointXYZ’ is not a member of ‘g2o’; did you mean ‘VertexPointXYZ’?
177 | g2o::VertexSBAPointXYZ* point = new g2o::VertexPointXYZ();
| ^~~~~~~~~~~~~~~~~
| VertexPointXYZ
3.新版本g2o中API接口变了,有两种修改模式,基本意义相同但第二种更简洁:
首先是根据报错来修改Block的初始化方法,在每个语句对应加入unique_ptr:
typedef g2o::BlockSolver< g2o::BlockSolverTraits<6,3> > Block; // pose维度为 6, landmark 维度为 3
/*Block::LinearSolverType* linearSolver = new g2o::LinearSolverCSparse(); // 线性方程求解器
Block* solver_ptr = new Block ( linearSolver ); // 矩阵块求解器
g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg ( solver_ptr );*/
Block::LinearSolverType* linearSolver = new g2o::LinearSolverEigen<Block::PoseMatrixType>(); // 线性方程求解器
Block* solver_ptr = new Block( std::unique_ptr<Block::LinearSolverType>(linearSolver) ); // 矩阵块求解器
g2o::OptimizationAlgorithmGaussNewton* solver = new g2o::OptimizationAlgorithmGaussNewton( unique_ptr<Block>(solver_ptr) );
g2o::SparseOptimizer optimizer;
optimizer.setAlgorithm( solver );
参考增加智能指针 std::unique_ptr
第二种方法是根据新版本中的示例来进行语句修改:
// 初始化g2o
typedef g2o::BlockSolver< g2o::BlockSolverTraits<6,3> > Block; // pose 维度为 6, landmark 维度为 3
/*Block::LinearSolverType* linearSolver = new g2o::LinearSolverCSparse(); // 线性方程求解器
Block* solver_ptr = new Block ( linearSolver ); // 矩阵块求解器
g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg ( solver_ptr );*/
std::unique_ptr<Block::LinearSolverType> linearSolver ( new g2o::LinearSolverCSparse<Block::PoseMatrixType>()); // 线性方程求解器
std::unique_ptr<Block> solver_ptr ( new Block ( std::move(linearSolver))); // 矩阵块求解器
g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg ( std::move(solver_ptr));
g2o::SparseOptimizer optimizer;
optimizer.setAlgorithm ( solver );
参考新版本定义方法
4.在修改完代码编译后有可能出现如下报错(undefined reference to symbol ‘XXXX’):
[ 20%] Built target pose_estimation_2d2d
[ 40%] Built target triangulation
[ 60%] Built target feature_extraction
[ 80%] Built target pose_estimation_3d3d
[ 90%] Linking CXX executable pose_estimation_3d2d
/usr/bin/ld: CMakeFiles/pose_estimation_3d2d.dir/pose_estimation_3d2d.cpp.o: undefined reference to symbol '_ZTVN3g2o14VertexPointXYZE'
/usr/bin/ld: /usr/local/lib/libg2o_types_slam3d.so: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/pose_estimation_3d2d.dir/build.make:102:pose_estimation_3d2d] 错误 1
make[1]: *** [CMakeFiles/Makefile2:111:CMakeFiles/pose_estimation_3d2d.dir/all] 错误 2
make: *** [Makefile:84:all] 错误 2
DSO missing的原因基本上是因为有库没有连接上,导致未识别。最保险的方法是在最前端将所有库设置为G2O_LIBS:
SET(G2O_LIBS g2o_cli g2o_ext_freeglut_minimal g2o_simulator g2o_solver_slam2d_linear g2o_types_icp g2o_types_slam2d g2o_core g2o_interface g2o_solver_csparse g2o_solver_structure_only g2o_types_sba g2o_types_slam3d g2o_csparse_extension g2o_opengl_helper g2o_solver_dense g2o_stuff g2o_types_sclam2d g2o_parser g2o_solver_pcg g2o_types_data g2o_types_sim3 cxsparse )
我是在pose_estimation_3d2d中出现问题,所以可以在随后对应的链接中加入${G2O_LIBS}
target_link_libraries( pose_estimation_3d2d
${OpenCV_LIBS}
g2o_core g2o_stuff g2o_types_sba g2o_csparse_extension ${G2O_LIBS}
${CSPARSE_LIBRARY}
)
在排查以后发现是g2o_types_slam3d未链接,所以直接只加入g2o_types_slam3d也可以:
target_link_libraries( pose_estimation_3d2d
${OpenCV_LIBS}
g2o_core g2o_stuff g2o_types_sba g2o_csparse_extension g2o_types_slam3d
${CSPARSE_LIBRARY}
)