选择在Windows下做slam开发,真是踩了无比多的坑,费神又费时。
那么为什么不听前人劝在linux下开发呢? 我也想啊,but.....&&&
言归正传,这节介绍G2O的编译安装及踩过的坑。
系统:win7
cmake: cmake3.8.6
vs: vs2015 x64/ win32
一、参考前人的博客Windows+Visual Studio下生成g2o库教程(结合Cholmod库) - CSDN博客和关于SLAM的那些事——通用图优化(G2O)环境搭配(windows8.1 vs2013) - CSDN博客(感谢前人的经验分享)。请按照以上两篇内容一步一步完成相关操作。在这一过程中,如果你有足够耐心、足够细心、足够清晰的话,那么G2O就已经成功编译并将相关include/library/dll路径配置成功。
二、大功告成后跑一个小的例子测试验证。
仍然是上面两篇博客中“Gao Xiang”提供的例子,但稍有改动,改动部分如下:
// 先构造求解器
g2o::SparseOptimizer optimizer;
// 使用Cholmod中的线性方程求解器
g2o::BlockSolver_6_3::LinearSolverType* linearSolver = new g2o::LinearSolverCholmod();
// 6*3 的参数
g2o::BlockSolver_6_3* block_solver = new g2o::BlockSolver_6_3(std::unique_ptr(linearSolver));
// L-M 下降
g2o::OptimizationAlgorithmLevenberg* algorithm = new g2o::OptimizationAlgorithmLevenberg(std::unique_ptr(block_solver));
三、到此,你也许跟我一样窃喜,终于大功告成了。然而,当我尝试用别的优化算法时,坑出现了。(重点)
将以上第二步中代码修改为如下:
typedef g2o::BlockSolver> Block; // Pose 的维度为6, landmark 维度为3
Block::LinearSolverType* linearSolver = new g2o::LinearSolverCSparse();
Block* solver_ptr = new Block(std::unique_ptr(linearSolver));
g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg(std::unique_ptr(solver_ptr));
此时F5提示link2019错误,初步分析应该是CSPARSE头文件或lib库文件缺失。如下:
error LNK2019: 无法解析的外部符号 "__declspec(dllimport) bool __cdecl g2o::csparse_extension::writeCs2Octave(char const *,struct cs_di_sparse const *,bool)" (__imp_?writeCs2Octave@csparse_extension@g2o@@YA_NPEBDPEBUcs_di_sparse@@_N@Z),该符号在函数 "public: virtual bool __cdecl g2o::LinearSolverCSparse>::solve(class g2o::SparseBlockMatrix> const &,double *,double *)" (?solve@?$LinearSolverCSparse@V?$Matrix@N$05$05$0A@$05$05@Eigen@@@g2o@@UEAA_NAEBV?$SparseBlockMatrix@V?$Matrix@N$05$05$0A@$05$05@Eigen@@@2@PEAN1@Z) 中被引用1>BundleAdjustment.obj :
error LNK2019: 无法解析的外部符号 "__declspec(dllimport) struct cs_di_numeric * __cdecl g2o::csparse_extension::cs_chol_workspace(struct cs_di_sparse const *,struct cs_di_symbolic const *,int *,double *)" (__imp_?cs_chol_workspace@csparse_extension@g2o@@YAPEAUcs_di_numeric@@PEBUcs_di_sparse@@PEBUcs_di_symbolic@@PEAHPEAN@Z),该符号在函数 "public: virtual bool __cdecl g2o::LinearSolverCSparse>::solveBlocks(double * * &,class g2o::SparseBlockMatrix> const &)" (?solveBlocks@?$LinearSolverCSparse@V?$Matrix@N$05$05$0A@$05$05@Eigen@@@g2o@@UEAA_NAEAPEAPEANAEBV?$SparseBlockMatrix@V?$Matrix@N$05$05$0A@$05$05@Eigen@@@2@@Z) 中被引用1>BundleAdjustment.obj :
error LNK2019: 无法解析的外部符号 "__declspec(dllimport) int __cdecl g2o::csparse_extension::cs_cholsolsymb(struct cs_di_sparse const *,double *,struct cs_di_symbolic const *,double *,int *)" (__imp_?cs_cholsolsymb@csparse_extension@g2o@@YAHPEBUcs_di_sparse@@PEANPEBUcs_di_symbolic@@1PEAH@Z),该符号在函数 "public: virtual bool __cdecl g2o::LinearSolverCSparse>::solve(class g2o::SparseBlockMatrix > const &,double *,double *)" (?solve@?$LinearSolverCSparse@V?$Matrix@N$05$05$0A@$05$05@Eigen@@@g2o@@UEAA_NAEBV?$SparseBlockMatrix@V?$Matrix@N$05$05$0A@$05$05@Eigen@@@2@PEAN1@Z) 中被引用
返回检查第一步骤末尾g2o vs2015环境变量的配置,并没有遗漏,csparse相关的lib和头文件都在里面。 进一步分析,在cmake配置时,csparse的包含文件是这样的:
可以看到此处csparse的包含文件是g2o下的external下的csparse。而按照一种博文配置的g2o vs2015环境变量并没包含这个头文件。找到问题所在:缺失csparse头文件路径。解决:在项目中添加inlude文件路径:你的文件目录/g2o-masterwin32/EXTERNAL/csparse。再测试,成功。
四、顺便将external目录下的ceres,freegult目录路径一并添加,以防后期用到。
以上就是我在安装过程中踩过的坑,分享之。