ORB-SLAM2在window下的配置 (7)[END]

来源:互联网 发布:2017手机淘宝修改差评 编辑:程序博客网 时间:2024/06/06 11:39

部署ORB-SLAM2


此系列博客终于接近尾声,走过前方配置依赖库的漫漫长路,我们终于要来部署ORB-SLAM2了!

ORB-SLAM2源码下载:https://github.com/raulmur/ORB_SLAM2

这一次,我们不再用CMake配置工程,我们手动新建一个vs工程,就称为ORB-SLAM2吧,将下载好的源码放在同个目录下,然后右键项目->添加现有代码,将头文件和源文件全部添加进来

此时随便打开一个.cpp来查看,include头文件那里都会有错,我们需要配置一下属性表。将之前制作的几个依赖库的属性表(OpenCV、Pangolin、DBoW2、Eigen3、g2o)添加到Release x64文件夹下,顺便将编译模式调为Release x64.别忘了,要将关于g2o和DBoW2的头文件都改掉,用尖括号来使用它们。

如果你还看到你的ORB-SLAM2头文件有错,多半是你没把源文件和头文件放在同个目录下(我也不喜欢这么做),这个时候可以右键项目->属性->VC++目录->包含目录,为其添加头文件目录,建议使用相对路径。

好了,先什么都不做,编译一下看看吧。不出意外的话,没有报依赖库的错误,而有不少ORB-SLAM2的错误:

  1. 表达式必须含有常量值
  2. 不可指定数组类型 float[N][N]
  3. “usleep”找不到标识符
  4. 表达式计算结果不是常数
  5. 无法打开“sys/time.h”
  6. 无法打开“stdint-gcc.h”
  7. std::vector<int,std::allocator<_Ty>>::vector: 对重载函数的调用不明确

我们来逐一解决,首先,错误1、2是同一种问题,就是使用变量去定义一个数组大小,这在C++标准下是不允许的,但gcc编译器对此支持,想必也是做了转换,我们只要将数组定义的时候用new关键字来定义就好了,如:

// float Distances[N][N];// 改为:float ** Distances = new float*[N];for (int i = 0; i < N; i++)    Distances[i] = new float[N];// 记得用完之后回收内存delete[] Distances;

第三个错误,usleep是linux下的函数,参数是微秒数,我们可以用以下语句替换:

#include <thread>// 设参数为m微秒std::this_thread::sleep_for(std::chrono::microseconds(m));

第四个错误,用变量初始化const变量,显然不是c++标准,gcc编译器支持它完全从程序员的角度来考虑的,我们将const关键字删除即可。

第五个错误,跳转到那里可以发现该头文件包含语句为_WINDOWS未定义的预处理器块中,该头文件是linux下的,我们不应该使用它。右键项目->属性->C++->预处理器->预处理器定义,新加一变量:_WINDOWS.

第六个错误,该头文件为gcc编译器的,我们这里一样用不到,把它删了就行。

第七个错误暂时不管,我们先编译一下,会发现,这个错误神奇般地消失了。不过出现了个新的棘手错误:C1001,编译器内部错误。。。
问题代码是:

// sparse_block_matrix.hpp,277行,g2ointernal::axpy(*a, srcVec, srcOffset, destVec, destOffset);if (destOffset < srcOffset)   internal::atxpy(*a, srcVec, destOffset, destVec, srcOffset);

好吧,又是你这个该死的函数。vs表示看不懂,我们只能进一步给它解释,将代码改成如下所示:

internal::template axpy<typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock>(*a, srcVec, srcOffset, destVec, destOffset);if (destOffset < srcOffset)    internal::template atxpy<typename SparseBlockMatrix<MatrixType>::SparseMatrixBlock>(*a, srcVec, destOffset, destVec, srcOffset);

改完编译一下,不出意外,还有一个地方要改:

// sparse_block_matrix_ccs.h,125行:// internal::atxpy(*a, srcVec, srcOffset, destVec, destOffset);// 改成:internal::template atxpy<SparseMatrixBlock>(*a, srcVec, srcOffset, destVec, destOffset);

再编译,又出错:

// sparse_block_matrix_diagonal.h,97行:// internal::axpy(A, srcVec, srcOffset, destVec, destOffset);// 改成:internal::template axpy<SparseMatrixBlock>(A, srcVec, srcOffset, destVec, destOffset);

其实我们又花了一些力气在修改g2o。再次编译,这一次终于没问题了,终于到了链接这一步,出现了链接错误:

  1. LNK2038 检测到“RuntimeLibrary”的不匹配项
  2. LNK2001 无法解析的外部符号 main

我们一个个解决,首先第一个问题,还记得是谁的锅吗?没错,就是pangolin的,当然如果你生成pangolin的时候已经把代码生成由Mt改为Md,那就没事了,我是保持默认,现在的解决方法是:右键项目->属性->C++->代码生成->运行库,从Md改成Mt.

第二个问题,我们似乎还没写main函数吧,我们可以添加一个main.cpp文件,增加以下代码:

#include "System.h"using namespace ORB_SLAM2;int main(){    System orbslam("../Run/Vocabulary/ORBvoc.txt", "../Run/Setting/KITTI03.yaml", System::eSensor::STEREO);    system("pause");    return 0;}

注意到,头文件设置因人而异,我已经把头文件所在的目录加在了项目VC++目录中,所以这写就没问题。字典和设置文件的放置我们也会有所不同,代码仅供参考,不可照搬。

好了,现在再编译一遍,惊喜地发现,已经生成exe了!现在为其配置运行环境,右键项目->属性->调试->调试,给它如下的值(仅供参考)

path=D:/Packages/DBoW2/lib/;D:/Packages/g2o_orbslam/lib/;D:/Packages/Pangolin/lib/;D:/Packages/OpenCV3_1/opencv/build/x64/vc14/bin/;

运行一下,期盼已久的界面终于出现了!
成功

好了,我的第一个系列的博客到此结束,希望大家多多指教,如果有更加方便的配置方法,敬请留言相告,多谢!


补充:我已经把这个系列的完整工程上传到了:http://download.csdn.net/detail/yfic000/9913200
有兴趣的同学可以下载来看看,我已经把所有的第三方库部署在工程目录下,所有的路径全部配置成了相对路径,工程使用vs2017可以直接打开编译。注意的是,opencv本来有debug的库,我为了节省空间,把它删掉了。如果有什么问题,欢迎留言。