SLAM十四讲ch7代码调整(undefined reference to symbol)

SLAM十四讲ch7代码调整——2021.6.14

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}
)

你可能感兴趣的:(SLAM视觉十四讲代码调整,c++)