從編譯運行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在哪兒?這是研究者之於工程師最本質的區別,你不只要有工程師的能力,還要有創新的思惟.
  • 在程序員,大學生,工程師氾濫的年代,做爲研究生的你如何脫引而出,創造價值?
  • ......
相關文章
相關標籤/搜索