从编译运行orbslam2提及

从编译运行orbslam2提及

0.基础

  "0.基础"而不是"0基础",把它放在1的前面,用0来强调作某件事以前必须已经完成某事的概念.正所谓磨刀不误砍柴工,若是你不想浪费3个小时坎坷的去砍柴,那最好老老实实花上1个小时磨好刀.
  本文面向具备cmake,linux shell,ROS基础的SLAM研究者.请读者自行学习如下知识:linux

  • robot SLAM基础与orbslam2简介
  • cmake基础
  • linux与linux shell基础
  • ROS基础

1.编译

第三方库的安装或现场编译

  首先orbslam2做为一个大型程序,并非彻底本身造的轮子,而是在一些非核心的地方使用了第三方库的.学计算机的都知道若是本身程序使用了第三方库,编译时须要找到头文件,连接时须要找到库文件.大型程序的构建过程也是同样的,orblsam2须要找到第三方库的头文件和库文件,这个交给cmake来处理,咱们重点来谈谈它的第三方库.这又分为两个种:程序员

  1. 直接使用第三方库.在orbslam2中就是OpenCV,Pangolin等.这一部分必须事先已经正确安装到系统中了
  2. 对第三方库作了修改的.在orbslam2中就是g2o,dbow等.这一部分必须由做者提供修改后的源码,现场编译

  为了说明这点,咱们能够查看工程的CMakeLists.txt文件shell

target_link_libraries(${PROJECT_NAME}
${OpenCV_LIBS}
${EIGEN3_LIBS}
${Pangolin_LIBRARIES}
${PROJECT_SOURCE_DIR}/Thirdparty/DBoW2/lib/libDBoW2.so
${PROJECT_SOURCE_DIR}/Thirdparty/g2o/lib/libg2o.so
)

  从上面代码能够看出,程序连接了5个库,其中OpenCV,EIGEN3,Pangolin来自系统中,DBoW2和g2o来自现场编译后生成的库文件.故咱们在构建orbslam等大型工程时,不是一上来就编译,而是要先解决依赖.这里略去第三方库的安装和编译方法.api

编译核心API库

  当全部依赖的库文件和头文件都准备就绪,就能够开始编译orbslam了.接着看CMakeLists.txt:app

add_library(${PROJECT_NAME} SHARED
src/System.cc
src/Tracking.cc
src/LocalMapping.cc
src/LoopClosing.cc
src/ORBextractor.cc
src/ORBmatcher.cc
src/FrameDrawer.cc
src/Converter.cc
src/MapPoint.cc
src/KeyFrame.cc
src/Map.cc
src/MapDrawer.cc
src/Optimizer.cc
src/PnPsolver.cc
src/Frame.cc
src/KeyFrameDatabase.cc
src/Sim3Solver.cc
src/Initializer.cc
src/Viewer.cc
)

  注意到做者的源码都编译成了一个动态库,根据cmake的命名规则,应该是一个叫libORB_SLAM2.so的文件.可是为何不直接编译可执行程序?非要画蛇添足地搞一个动态库?其实否则,之因此这样作出于两点缘由:ide

  1. 大型程序的编写都是OOP,众所周知OOP的优势有不少:便于分析,设计,编码,维护.这样说很抽象,简单举几个例子:
    • 例子1:小明编写了一个几万行的main.cpp,而后他崩溃了.后来他用OO思想设计了类,在main.cpp中调用,程序缩减到百行
    • 例子2:小明要编写3个单独的VO,回环,优化程序,他创建了三个大型工程,而后他崩溃了.后来他用OO思想设计了类,写了3个程序调用这些类,再后来他创造性的把三个模块整合,写出了完整的slam程序
    • 例子3:小明编写了一个单目slam程序,老板要求他再写一个双目的,他又得从新造轮子了,因此他依然崩溃了,后来他用OO思想设计了类,在已有程序中增长了一个双目类,成功完成了双目slam程序
  2. 封装成核心API库,便于发布给其余开发者使用

  封装成核心API库是一种有益之法,尤为是当你本身须要构建大型程序时,读者可自行体会.oop

编译做者提供的demo,并将其连接到上面生成的核心API库

再往下看,cmake就开始编译做者提供的demo了.做者提供了4个200来行左右的demo源程序,分别是rgbd_tum.cc,stereo_kitti.cc,mono_tum.cc,mono_kitti.cc学习

# Build examples

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/Examples/RGB-D)

add_executable(rgbd_tum
Examples/RGB-D/rgbd_tum.cc)
target_link_libraries(rgbd_tum ${PROJECT_NAME})

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/Examples/Stereo)

add_executable(stereo_kitti
Examples/Stereo/stereo_kitti.cc)
target_link_libraries(stereo_kitti ${PROJECT_NAME})

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/Examples/Monocular)

add_executable(mono_tum
Examples/Monocular/mono_tum.cc)
target_link_libraries(mono_tum ${PROJECT_NAME})

add_executable(mono_kitti
Examples/Monocular/mono_kitti.cc)
target_link_libraries(mono_kitti ${PROJECT_NAME})

总共生成了4个demo程序,先编译,后link到前面生成的核心API库上.优化

2.运行

  程序的运行并不像咱们在使用win时的那么简单,由于程序具备专业性,不具有相关专业基础知识的人每每会在各类错误提示中浪费本身的时间.但总的来讲也是有规律可循的,其实也简单,仅仅是提供程序运行所必要的数据和配置文件便可.推荐你们保持良好的习惯,阅读官方提供的运行说明.了解程序运行所须要的数据和配置,事先将其准备好,而后按照做者的教程运行.orbslam2的运行略.ui

3.练习:编译运行做者提供的基于ros的demo

  请注意,以上的程序是普通的桌面程序,是直接利用驱动来读取相机数据的,下面编译基于ros的demo,固然这部分也是略

4.报错

  软件工程是个系统工程,一个小问题也会形成大错误.因此报错是件很日常的事.即便是对于老手.面对报错,咱们应该

  1. 首先心态上要放平稳
  2. 其次要仔细查看错误提示,冷静地作逻辑分析
  3. 最后要善用google,你要相信本身不是特殊的,你踩过的坑别人确定也踩过

5.启发

  若是看完一篇文章,没有收获,纯属浪费时间;若是看完一篇文章,能解决另外一个问题,那么起码不亏;若是看完一篇文章,能解决一类问题,你才叫正真的赚到了.读到这里,若是你以为没有收获,请关闭页面,不要再浪费你本身的时间.若是你如今以为学习了一些经验技巧,那么就能够继续了.

6.提升:从新启程,举一反三

  你能够尝试编译运行较新的DSO,这里咱们来试试高翔博士基于orbslam2改写的orbslam2带点云程序

1

首先下载源码.看过说明以后大概有了了解,但仍然不甚明了,不知orbslam2_modified.zip与ORB_SLAM2_modifiedy文件夹有什么异同.这是我遇到的第一个问题,详细查看了ORB_SLAM2_modifiedy下的文件,确实有修改,且第三方库完整,决定编译这个文件夹.

2

接着照例查看CMakeLists.txt,其内容基本与orbslam相同,可是从逻辑上讲应该增长点云库的,这里咱们先无论它.而后查看build.sh的安装脚本,过程也是与orbslam2大同小异,只是最后多了一个词典转换程序(提供),用于讲词典转换成二进制的.通过查看以后,得出的结论是,编译过程基本类似,改动主要在代码层面.

3

经过刚才的文件查看,发现一些潜在问题,就是build文件夹已经存在,甚至第三方库已经编译成功.若干demo的可执行程序已经编译出来了.表面上看是捡了便宜,不用编译了,其实这样是会带来许多麻烦的.为何这么说?

  1. cmake过的build文件夹内含有编译信息,记录了文件绝对路径,你下载下来,接着make,会报错说找不到文件.这时应该删除build,从新cmake
  2. 已经在别人的机器上编译好的程序或库,在本身的机器上颇有多是不能运行的,尤为是这些程序须要动态库的状况下,会出现一堆找不到各类动态库

4

  • 开始编译第三方库,用make clean清理已经生成的,删除build,从新编译dbow和g2o两个库,成功.
  • 开始编译核心API库和demo,编译错误,找不到pcl的一个头文件,印证了前面的逻辑推理,在CMakeLists.txt中加pcl,继续编译,成功.
  • 开始编译基于ros的demo,出现错误,提示出现相同文件.由于我机器上编译过orbslam2的基于ros的demo,因此多是ros包重复.把原来的包移个位置,继续编译,成功.

5

  • 最终选择运行基于ros的rgbddemo程序,先确认数据与配置,词典位置,相机参数文件位置,以及最重要的订阅的话题,核对发布的话题,与rgbddemo中订阅的话题是否一致,发现不一致,修改源程序的话题订阅,从新编译,经过.
  • ok,万事俱备,先开一个发布kinect数据的launch,而后运行rgbddemo程序,最终效果以下所示:



7.沉思

  走到这里,你已经会编译运行各类开源slam项目了,也许你是付出不少时间精力,学习各类cmake,shell教程,被各类报错折磨,可是我仍是要打击你一下,构建开源项目是最基本的工程素养,外面随便一个工程师都会.到目前为止咱们只是编译别人的工程,跑跑别人的代码.

  • 可是你的ideal在哪儿?这是研究者之于工程师最本质的区别,你不只要有工程师的能力,还要有创新的思惟.
  • 在程序员,大学生,工程师泛滥的年代,做为研究生的你如何脱引而出,创造价值?
  • ......
相关文章
相关标签/搜索