g2o error: no matching function for call to ‘g2o::OptimizationAlgorithmLevenberg::OptimizationAlgori

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,没毛病了。

  • 13
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值