Ubuntu16.04使用g2o库(SLAM十四讲跑例程报错)
2018.11.27
错误一
本人的g2o库已经安装过了,跑g2o优化的代码的时候,可以正常运行,当我跑PnP求解的代码时,出现如下错误:
CMakeFiles/slamEnd.dir/slamEnd.cpp.o: In function `g2o::LinearSolverCSparse<Eigen::Matrix<double, 6, 6, 0, 6, 6> >::solve(g2o::SparseBlockMatrix<Eigen::Matrix<double, 6, 6, 0, 6, 6> > const&, double*, double*)':
/opt/ros/indigo/include/g2o/solvers/csparse/linear_solver_csparse.h:126: undefined reference to `g2o::csparse_extension::cs_cholsolsymb(cs_di_sparse const*, double*, cs_di_symbolic const*, double*, int*)'
/opt/ros/indigo/include/g2o/solvers/csparse/linear_solver_csparse.h:130: undefined reference to `g2o::csparse_extension::writeCs2Octave(char const*, cs_di_sparse const*, bool)'
CMakeFiles/slamEnd.dir/slamEnd.cpp.o: In function `g2o::LinearSolverCSparse<Eigen::Matrix<double, 6, 6, 0, 6, 6> >::solveBlocks(double**&, g2o::SparseBlockMatrix<Eigen::Matrix<double, 6, 6, 0, 6, 6> > const&)':
/opt/ros/indigo/include/g2o/solvers/csparse/linear_solver_csparse.h:171: undefined reference to `g2o::csparse_extension::cs_chol_workspace(cs_di_sparse const*, cs_di_symbolic const*, int*, double*)'
CMakeFiles/slamEnd.dir/slamEnd.cpp.o: In function `g2o::LinearSolverCSparse<Eigen::Matrix<double, 6, 6, 0, 6, 6> >::solvePattern(g2o::SparseBlockMatrix<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, std::vector<std::pair<int, int>, std::allocator<std::pair<int, int> > > const&, g2o::SparseBlockMatrix<Eigen::Matrix<double, 6, 6, 0, 6, 6> > const&)':
/opt/ros/indigo/include/g2o/solvers/csparse/linear_solver_csparse.h:208: undefined reference to `g2o::csparse_extension::cs_chol_workspace(cs_di_sparse const*, cs_di_symbolic const*, int*, double*)'
在网上看到说可能是安装g2o之前没有安装libsuitesparse-dev,然后我就执行了一下:
sudo apt-get install libsuitesparse-dev
提示已经安装了,但是请大家务必先卸载libsuitesparse-dev:
apt-get --purge remove libsuitesparse-dev
然后再重新安装一次,安装过后,重新编译g2o进行安装,会发现问题就解决了。
错误二
随后再运行的时候依旧报错:
/home/stiles/Desktop/slambook-master/ch7/pose_estimation_3d2d.cpp: In function ‘void bundleAdjustment(std::vector<cv::Point3_<float> >, std::vector<cv::Point_<float> >, const cv::Mat&, cv::Mat&, cv::Mat&)’:
/home/stiles/Desktop/slambook-master/ch7/pose_estimation_3d2d.cpp:153: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 ); // 矩阵块求解器
^
In file included from /usr/local/include/g2o/core/block_solver.h:199:0,
from /home/stiles/Desktop/slambook-master/ch7/pose_estimation_3d2d.cpp:10:
/usr/local/include/g2o/core/block_solver.hpp:40:1: note: candidate: g2o::BlockSolver<Traits>::BlockSolver(std::unique_ptr<typename Traits::LinearSolverType>) [with Traits = g2o::BlockSolverTraits<6, 3>; typename Traits::LinearSolverType = g2o::LinearSolver<Eigen::Matrix<double, 6, 6, 0> >]
BlockSolver<Traits>::BlockSolver(std::unique_ptr<LinearSolverType> linearSolver)
^
/usr/local/include/g2o/core/block_solver.hpp:40:1: note: no known conversion for argument 1 from ‘g2o::BlockSolver<g2o::BlockSolverTraits<6, 3> >::LinearSolverType* {aka g2o::LinearSolver<Eigen::Matrix<double, 6, 6, 0> >*}’ to ‘std::unique_ptr<g2o::LinearSolver<Eigen::Matrix<double, 6, 6, 0> >, std::default_delete<g2o::LinearSolver<Eigen::Matrix<double, 6, 6, 0> > > >’
/home/stiles/Desktop/slambook-master/ch7/pose_estimation_3d2d.cpp:156:106: error: no matching function for call to ‘g2o::OptimizationAlgorithmLevenberg::OptimizationAlgorithmLevenberg(Block*&)’
g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg (( solver_ptr ));
点击一下错误提示,会看到错误在下面这两行代码处:
Block* solver_ptr = new Block(linearSolver);
g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg (( solver_ptr ));
根据错误提示,我们可以看到BlockSolver(std::unique_ptr linearSolver)是这样构造的,而源代码里面是Block* solver_ptr = new Block(linearSolver)这样构造的,后面的g2o::OptimizationAlgorithmLevenberg* solver查看源码会发现也是使用std::unique_ptr作为参数进行构造的,所以就将前面两行构造的代码改为:
std::unique_ptr<Block::LinearSolverType> linearSolver(new g2o::LinearSolverCSparse<Block::PoseMatrixType>());
std::unique_ptr<Block> solver_ptr(new Block ( linearSolver ));
再编译一次发现依旧有问题,可能还是构造参数的原因,仔细看一下g2o源码会发现:
其传递std::unique_ptr参数是使用std::move( xxx )来进行传递的,所以将涉及到传参的两行代码进一步修改:
整个过程主要改了上面三行代码,最终程序终于编译通过!
后面可以查一下std::unique_ptr、std::move相关的只是进行学习。