在写下这篇文章时,我已经安装好了SLAM需要的举并跑通了ORB-SLAM2。但是这样带来的坏处是,我在做书上的实验时,总有库的版本出现问题,或者其他奇奇怪怪的问题,很是麻烦,所以还是建议大家先跟着书上的实验一步步做下去,最后再跑大型框架。
1.g2o和Eigen版本冲突
在书中的第六章,安装g2o时,在编译中就碰到了版本冲突问题,在编译中疯狂报错,我贴上一部分错误代码,实际上错误代码都是比较重复性的内容,很容易就看出来是和Eigen相关的错误。
/usr/include/eigen3/Eigen/src/Core/util/StaticAssert.h:32: error: static assertion failed: YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY
#define EIGEN_STATIC_ASSERT(X,MSG) static_assert(X,#MSG);
各种诸如此类的问题从头跳到尾。由于我在跑ORB-SLAM2时已经安装了最新的Eigen3.3.10,之前安装Ceres时已经报错和Eigen3.3冲突了,所以我又安装了Eigen3.2。
①最好清除掉Eigen3.3版本,以免以后又出现奇奇怪怪的错误。
sudo updatedb
locate eigen3
这两行语句定位了Eigen3的位置,进入对应文件夹手动删除即可。会显示很多很多文件,不要怕,其实仔细看他们都在一个文件夹里,删掉那个文件夹就可以了。
②然后登录eigen的官网http://eigen.tuxfamily.org/index.php?title=Main_Page,下载eigen3.2。
下载解压后,进入解压后的文件夹,使用如下命令编译安装:
mkdir build
cd build
cmake ..
make
sudo make install
这样就可以了,再次编译安装g2o,编译完成!奶思!
2.《SLAM十四讲g2o实验报错》
高高兴兴安装好g2o后,跑书上的实验竟然又报错了:
/home/christina/slambook/useg2o/main.cpp:77:49: error: no matching
function for call to ‘g2o::BlockSolver<g2o::BlockSolverTraits<3, 1> >::BlockSolver(g2o::BlockSolver<g2o::BlockSolverTraits<3, 1> >::LinearSolverType*&)’
Block* solver_ptr = new Block( linearSolver );
^
/home/christina/slambook/useg2o/main.cpp:77:49: note: candidate is:
In file included from /usr/local/include/g2o/core/block_solver.h:199:0,
from /home/wxy/slambook/useg2o/main.cpp:4:
/usr/local/include/g2o/core/block_solver.hpp:40:1: note: g2o::BlockSolver<Traits>::BlockSolver(std::unique_ptr<typename Traits::LinearSolverType>) [with Traits = g2o::BlockSolverTraits<3, 1>; typename Traits::LinearSolverType = g2o::LinearSolver<Eigen::Matrix<double, 3, 3> >]
BlockSolver<Traits>::BlockSolver(std::unique_ptr<LinearSolverType> linearSolver)
这是智能指针出现了问题,原代码中用到的是普通的指针,将初始化中用等号赋值的地方改成用std::unique_ptr赋值,将linearSolver和solver_ptr用移动语言也就是std::move来实现。具体请参照这个博客https://www.cnblogs.com/xueyuanaichiyu/p/7921382.html
修改如下代码:
// 构建图优化,先设定g2o
typedef g2o::BlockSolver< g2o::BlockSolverTraits<3,1> > Block; // 每个误差项优化变量维度为3,误差值维度为1
std::unique_ptr<Block::LinearSolverType> linearSolver ( new g2o::LinearSolverDense<Block::PoseMatrixType>());
// Block::LinearSolverType* linearSolver = new g2o::LinearSolverDense<Block::PoseMatrixType>(); // 线性方程求解器
std::unique_ptr<Block> solver_ptr ( new Block ( std::move(linearSolver)));
//Block* solver_ptr = new Block( linearSolver ); // 矩阵块求解器
// 梯度下降方法,从GN, LM, DogLeg 中选
g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg ( std::move(solver_ptr));
// g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg( solver_ptr );
// g2o::OptimizationAlgorithmGaussNewton* solver = new g2o::OptimizationAlgorithmGaussNewton( solver_ptr );
// g2o::OptimizationAlgorithmDogleg* solver = new g2o::OptimizationAlgorithmDogleg( solver_ptr );
g2o::SparseOptimizer optimizer; // 图模型
optimizer.setAlgorithm( solver ); // 设置求解器
optimizer.setVerbose( true ); // 打开调试输出
OK,再次编译运行,成功,nice!
最后,还想吐槽一下,我之前装什么都是装最新版本,不听前辈的劝告。现在学习SLAM碰到了好多版本问题,各种磕磕碰碰,以后还是老老实实用稳定的旧版本吧,新版本坑太多啦,对于小白比较难解决。不过好处就是新版本很多函数性能可定是优化的,而且自己动手解决这些困难,对学习也是很有帮助的。