部署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的错误:
- 表达式必须含有常量值
- 不可指定数组类型 float[N][N]
- “usleep”找不到标识符
- 表达式计算结果不是常数
- 无法打开“sys/time.h”
- 无法打开“stdint-gcc.h”
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>
std::this_thread::sleep_for(std::chrono::microseconds(m));
第四个错误,用变量初始化const变量,显然不是c++标准,gcc编译器支持它完全从程序员的角度来考虑的,我们将const关键字删除即可。
第五个错误,跳转到那里可以发现该头文件包含语句为_WINDOWS未定义的预处理器块中,该头文件是linux下的,我们不应该使用它。右键项目->属性->C++->预处理器->预处理器定义,新加一变量:_WINDOWS.
第六个错误,该头文件为gcc编译器的,我们这里一样用不到,把它删了就行。
第七个错误暂时不管,我们先编译一下,会发现,这个错误神奇般地消失了。不过出现了个新的棘手错误:C1001,编译器内部错误。。。
问题代码是:
internal::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);
改完编译一下,不出意外,还有一个地方要改:
internal::template atxpy<SparseMatrixBlock>(*a, srcVec, srcOffset, destVec, destOffset);
再编译,又出错:
internal::template axpy<SparseMatrixBlock>(A, srcVec, srcOffset, destVec, destOffset);
其实我们又花了一些力气在修改g2o。再次编译,这一次终于没问题了,终于到了链接这一步,出现了链接错误:
- LNK2038 检测到“RuntimeLibrary”的不匹配项
- 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的库,我为了节省空间,把它删掉了。如果有什么问题,欢迎留言。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)