20200607 ubuntu18跑G2O 图优化slam,但凡只要涉及g2o的部分,一律跑不通:
error: no matching function for call to ‘g2o::BlockSolver<g2o::BlockSolverTraits<-1, -1> >::BlockSolver(g2o::BlockSolver<g2o::BlockSolverTraits<-1, -1> >::LinearSolverType*&)’
SlamBlockSolver* solver_ptr = new SlamBlockSolver(linear_solver);
基本都是说g2o版本不对,g2o从github下载安装的。然后删库:
sudo rm -r /usr/local/lib/libg2o*
sudo rm -r /usr/local/include/g2o*
sudo rm -r /usr/local/bin/g2o*
下载高翔的第三方库中的老版本g2o,编译安装没报错但一堆的警告,预感不妙,果然还是不行。在来一次把删库重装g2o的master分支。这回改代码吧:
方法内容转载于:https://blog.csdn.net/robinhjwy/article/details/78084210
先贴一下g2o初始化的代码:
// 初始化g2o
typedef g2o::BlockSolver< g2o::BlockSolverTraits<6,3> > Block; // pose 维度为 6, landmark 维度为 3
Block::LinearSolverType* linearSolver = new g2o::LinearSolverCSparse<Block::PoseMatrixType>(); // 线性方程求解器
//std::unique_ptr<Block::LinearSolverType> linearSolver ( new g2o::LinearSolverCSparse<Block::PoseMatrixType>());
Block* solver_ptr = new Block ( linearSolver );
//std::unique_ptr<Block> solver_ptr ( new Block ( std::move(linearSolver))); // 矩阵块求解器
g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg ( solver_ptr);
//g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg ( std::move(solver_ptr));
g2o::SparseOptimizer optimizer;
optimizer.setAlgorithm ( solver );
安装好之后,运行第七章的3d2d程序,还是跑不通:
报错:
/home/robin/CLionProjects/slambook-robin/ch7/pose_estimation_3d2d/main.cpp:217:50: error: no matching function for call to ‘g2o::BlockSolver<g2o::BlockSolverTraits<6, 3> >::BlockSolver(g2o::BlockSolver<g2o::BlockSolverTraits<6, 3> >::LinearSolverType*&)’
Block* solver_ptr = new Block ( linearSolver );
点开位置发现是g2o初始化中的Block构造的时候报错:
Block* solver_ptr = new Block ( linearSolver );
继续点下面的错误信息:
In file included from /usr/local/include/g2o/core/block_solver.h:199:0,
from /home/robin/CLionProjects/slambook-robin/ch7/pose_estimation_3d2d/main.cpp:11:
/usr/local/include/g2o/core/block_solver.hpp:40:1: note: candidate: g2o::BlockSolver::BlockSolver(std::unique_ptr) [with Traits = g2o::BlockSolverTraits<6, 3>; typename Traits::LinearSolverType = g2o::LinearSolver<Eigen::Matrix<double, 6, 6, 0> >]
BlockSolver::BlockSolver(std::unique_ptr linearSolver)
发现跳转到了block_solver.hpp中BlockSolver的构造函数去了,发现是这样写的:
-
BlockSolver::BlockSolver(std::unique_ptr linearSolver)
-
BlockSolverBase(),
_linearSolver(std::move(linearSolver))
发现BlockSolver构造时需要的是std::unique_ptr类型的linearSolver参数,这里还知道是啥玩意儿,不过看见ptr猜测是个指针。对比程序中上面写的,发现是这样的:
Block::LinearSolverType* linearSolver
猜测是不是因为std::unique_ptr与Block::LinearSolverType*类型不一样导致的?
但是高博写的应该没有错误,是不是g2o更新导致用法不一样了?看一下高博书中自带的g2o的代码,发现果然不一样:
高博书中的g2o是这么写的:
BlockSolver::BlockSolver(LinearSolverType* linearSolver) :
BlockSolverBase(),
_linearSolver(linearSolver)
好,找到了问题原因,下面修改:
百度一发unique_ptr用法,这里是个网址:
http://blog.csdn.net/pi9nc/article/details/12227887
参考着进行改动:
// 初始化g2o
typedef g2o::BlockSolver< g2o::BlockSolverTraits<6,3> > Block; // pose 维度为 6, landmark 维度为 3
//Block::LinearSolverType* linearSolver = new g2o::LinearSolverCSparse<Block::PoseMatrixType>(); // 线性方程求解器
std::unique_ptr<Block::LinearSolverType> linearSolver ( new g2o::LinearSolverCSparse<Block::PoseMatrixType>());
//Block* solver_ptr = new Block ( linearSolver );
std::unique_ptr<Block> solver_ptr ( new Block ( linearSolver));
//std::unique_ptr<Block> solver_ptr ( new Block ( std::move(linearSolver))); // 矩阵块求解器
g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg ( solver_ptr);
//g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg ( std::move(solver_ptr));
g2o::SparseOptimizer optimizer;
optimizer.setAlgorithm ( solver );
把linearSolver和solver_ptr都改成了std::unique_ptr<>类型,并且初始化时不再用等号。
运行,发现还是报错:
/home/robin/CLionProjects/slambook-robin/ch7/pose_estimation_3d2d/main.cpp:218:65: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = g2o::LinearSolver<Eigen::Matrix<double, 6, 6, 0> >; _Dp = std::default_delete<g2o::LinearSolver<Eigen::Matrix<double, 6, 6, 0> > >]’
std::unique_ptr solver_ptr ( new Block ( linearSolver));
在这一句:
std::unique_ptr solver_ptr ( new Block ( linearSolver));
并且后面的一句:
g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg ( solver_ptr);
也是报错。
第一句的:
std::unique_ptrBlock::LinearSolverType linearSolver ( new g2o::LinearSolverCSparseBlock::PoseMatrixType());
并没有报错,说明这一句是对的!
观察报错两句,发现都存在将unique_ptr作为参数传递给类的构造函数中的用法,然后那篇博客中有个move指令,猜测是不是直接传递不行,要用move才对,继续修改:
// 初始化g2o
typedef g2o::BlockSolver< g2o::BlockSolverTraits<6,3> > Block; // pose 维度为 6, landmark 维度为 3
//Block::LinearSolverType* linearSolver = new g2o::LinearSolverCSparse<Block::PoseMatrixType>(); // 线性方程求解器
std::unique_ptr<Block::LinearSolverType> linearSolver ( new g2o::LinearSolverCSparse<Block::PoseMatrixType>());
//Block* solver_ptr = new Block ( linearSolver );
//std::unique_ptr<Block> solver_ptr ( new Block ( linearSolver));
std::unique_ptr<Block> solver_ptr ( new Block ( std::move(linearSolver))); // 矩阵块求解器
//g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg ( solver_ptr);
g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg ( std::move(solver_ptr));
g2o::SparseOptimizer optimizer;
optimizer.setAlgorithm ( solver );
在传递linearSolver和solver_ptr时,加上了std::move()。再试一发!
OK,没毛病了。