【泡泡機器人原創專欄】Visual Inertial ORB-SLAM代碼詳細說明

2021-12-28 泡泡機器人SLAM

歡迎大家再次回到泡泡機器人的課堂。不久前,ORB-SLAM2的作者在原純視覺SLAM的基礎上,針對ORB-SLAM的一些固有問題,提出了一種全新的結合IMU的方法[2]。就在幾天前,王京大神開源了基於該算法的一種實現[1]。本文中,王京大神將為大家詳細講解該實現中的關鍵技術,希望本文可以幫助大家剛好地閱讀和理解相關代碼。

1.       前言

        這份學習代碼[1]參考Visual Inertial ORB-SLAM的論文[2],從ORB-SLAM2[3,4]的基本代碼修改而來。

         目前開源的Visual Inertial系統有OKVIS和ROVIO,但用到IMU Preintegration[5,14,15]的暫時沒開源,只在GTSAM[6]中包含了相關的IMU factor,而ORBSLAM作者的這部分代碼暫時也沒有開源。自己在嘗試上面論文的方法之後感覺論文裡初始化挺實用的、整體程序也不很難,所以就在寫完之後放到了github上供大家一起學習交流。

         由於能力有限,如果有bug還請包含並指出,作者盡力修正,也歡迎大家一起玩、一起改進。本文檔給出簡單的說明,以及主要的參考資料。

 

2.       ROS入口

        這份代碼暫時只寫了rosbag的接口,入口在Examples/ROS/ORB_VIO/ros_vio.cc中。每次讀取一個圖像msg和到這個圖像的一組IMU msg,在Tracking和LocalMapping計算完之後再對下一個圖像msg和下一組IMU msg進行處理(所以並不是實時的)。

(註:馮餘劍同學提供了去掉ROS的版本,在github的issue裡放了連結。)

 

3.       IMU參數

        目前只在EuRoc數據集[7,8]上進行了測試,IMU的參數寫死在IMU/imudata.cpp中,噪聲參數來源於數據集中的sensor.yaml,計算參考Kalibr[9,10]的wiki中所述IMU噪聲模型[11]。如這個wiki中所說,datasheet上所給的理論值一般是理想情況下的,實際使用時看情況要放大一些,所以程序中計算時有進行放大(但也只是大致試了幾個值,選了一個看起來好點的)。

         另外,EuRoc的數據中IMU和相機之間沒有延時,自己的數據需要Kalibr進行標定。

(註:這兩天在自己的硬體數據上跑起來了,見下文說明)

 

4.       IMU預積分(Preintegration)

        (Preintegration的實現在IMU/IMUPreintegrator.h和IMU/IMUPreintegrator.cpp中)

         Visual Inertial ORBSLAM中,IMU的使用方式是把相鄰幀或相鄰關鍵幀之間的IMU測量值利用預積分的方式計算一個近似高斯分布的「偽」測量量,這種方式可以把IMU的噪聲參數傳遞給這個偽測量量,得到預積分的不確定度。利用這個預積分作為幀間的觀測量加入優化中。

         此外,預積分能給出偽測量量相對於零偏變化的雅克比,這樣在零偏有修正時,可以計算一階近似值,而不用重複計算積分,減小計算量。

         預積分的公式參考Forster的論文和補充材料[5,14,15],需要說明的是早先的兩篇[14,15]中公式有稍許錯誤(3/2和一些下標不對)。SO3上左右雅克比、Adjoint等相關的理論公式可以參考[16]的7.1節,或者聯繫@高博的新書《視覺SLAM十四講》。@謝曉佳也有一份預積分的「部分」總結文檔,可以在qq群文件中找到。但感覺最好都自己手推一遍。

 

5.       待估計狀態NavState

        (NavState的實現在IMU/NavState.h/和IMU/NavState.cpp中)

         NavState名字來源於GTSAM,包含位置P、速度V、旋轉R、陀螺零偏bg、加速度計零偏ba。除此以外,考慮到優化過程中要計算零偏的變化量,但預積分的方式保持了零偏不變,所以在NavState中加入了陀螺和加速度計的零偏增量dbg/dba。

         每當新建一個關鍵幀時,會利用到目前為止已經估計好的當前幀零偏bg/ba及零偏增量dbg/dba來初始化關鍵幀的零偏為bg+dbg/ba+dba,而把零偏增量初始化為0。在優化更新過程中,只更新增量dbg/dba而保持bg/ba不變(這樣就不用重新計算預積分了)。

         NavState的更新方式參考了論文[14]的補充材料[15],應該也可以有其他方式。

 

6.       VINS初始化

        (這部分在LocalMapping.cc的TryInitVIO()函數中)

         對單目VI系統來說,個人感覺初始化是比較麻煩的部分。

         之前很多的工作可能是用IMU初始化一個初始姿態,然後慢慢估計和收斂尺度,或者由其他傳感器提供尺度,這些相關工作了解還不是特別多,但感覺不那麼「優雅」。感覺比較優雅的方式:沈劭劼老師有專門針對單目VINS無先驗要求的初始化的討論[12,13],但暫時沒有開源,自己試著寫了個挫挫的視覺前端跑起來並不好用,還是需要個好的視覺前端的……

         在此基礎上,ORBSLAM的作者對[13]的做法進行了改進,利用已有的純VSLAM的地圖,分步驟來估計陀螺零偏、加速度計零偏和尺度、重力加速度。按照論文的介紹實現之後,發現可以基本復現論文中兩個數據集初始化的結果(從這個角度看感覺這方法還比較實用)。

         具體的方法參考論文,寫的程序中以學習為目的,所以在前15秒,每來一個新的關鍵幀,都會用所有的關鍵幀進行一次計算,把結果存下來,然後可以用pyplotscripts中的文件畫出初始化各變量的變化情況。

         需要說明的是,我推導公式的時候,發現和論文中部分符號不太一致,建議自己整理推導下。程序中重力方向認為是(0,0,1),這應該並不影響最終結果。

 

7.       新加g2o相關節點/邊

        (相關實現在IMU/g2otypes.h和IMU/g2otypes.cpp中)

         因為在ORBSLAM的框架下,優化用的庫是g2o,需要根據需要增加g2o的edge/vertex。


    具體的對照論文中的圖(原文中Fig 2)。

         VertexNavStatePVR中包含了上圖中的位姿P和速度v,VertexNavStateBias中包含了上圖中的IMU零偏b。(按作者圖裡的意思,他可能把PR和V也分開成兩類vertex了。)

         EdgeNavStatePVR作為上圖中上面的綠框所指edge,是一個多元邊,連結相鄰兩幀的PVR和兩幀中較早一幀的Bias。它的測量(測量值和不確定度)由預積分給出。

         EdgeNavStateBias作為上圖中下面的綠框所指edge,連接相鄰兩幀的bias。它的測量的值保持為0,不確定度由IMU隨機遊走參數確定。

         EdgeNavStatePVRPointXYZ作為上圖中左邊藍框所指edge,連接PVR和地圖點。

         EdgeNavStatePVRPointXYZOnlyPose作為上圖中右邊藍框所指edge,是一個一元邊,用於poseOptimization中的pose only Bundle Adjustment。

         EdgeNavStatePriorPVRBias作為上圖中的灰色框所指edge,包含marginalize之後的當前幀prior信息。(這裡需要說明,計算marginalize的結果用到g2o的computeMarginals()函數,我發現這個函數在cholmod/csparse的solver中才有,而ORBSLAM2中只有Eigen的solver。所以程序裡在Thirdparty/g2o/solvers中增加了cholmod的求解器,相關計算時用這個。)

         VertexGyrBias和EdgeGyrBias用於初始化時的陀螺零偏估計。(需要說明的是用到這部分的估計器本質上是一個線性估計器,一步就能收斂。)

         其他定義的NavState相關的Edge/Vertex是之前測試15DoF節點時留下的,也就是說把上述VertexNavStatePVR和VertexNavStateBias合在一起。但這樣的一個可能問題是,兩者本質上噪聲本是可以分開考慮的,IMU測量值的噪聲不應該影響bias。如果合在一起,在優化中進行robust kernel相關的操作時也得一起操作,導致bias的更新會受到測量噪聲的影響。所以這部分之後就參考論文中的方式把PVR和bias分開寫了。

8.       程序其他修改

         假設讀者對ORBSLAM基本了解,在其基礎上程序中其他修改就是參考論文[2],在不改變整體架構的前提下,按自己的理解進行一些相關的調整。主要的有:

         KeyFrame/Frame中增加必要的數據;

         VINS初始化完成後,Local Window從covisible window改為最近N個關鍵幀(N=10);

         新建關鍵幀和去除冗餘關鍵幀時,考慮要讓相鄰關鍵幀之間間隔時間不能太長;

         實現論文中Tracking在地圖是否有更新時的兩種不同策略;

         實現重定位時的重新估計和一些小細節;

         修改閉環時的一些小細節;

         ……其他的自己也得找一陣,用BeyondCompare吧……

 

9.       關於自己的硬體

        自己所組的IMU+攝像頭硬體是3DM-GX3-25和UI-1221-LE,幀率分別是200Hz和20Hz。IMU設置為200Hz的幀率,相機設置為外部觸發,並且固定曝光。用一個單片機採集和轉發IMU的200Hz數據,每10幀數據觸發一次相機,也就是圖像保持20Hz輸出。

         採用這個方式的原因在於想處理好延時。這種方式下,假如IMU-STM32之間串口傳輸耗時變化不大,那麼IMU的數據採集時間點和圖像數據採集時間點(這個時間點是相機曝光時間的中點,參見VI-SENSOR的論文[17])之間的延時基本是固定的。通過kalibr可以標定出來。



關於kalibr的標定可以再囉嗦一點遇到的小坑。最開始程序在自己的硬體錄的數據上效果很差,會出現莫名其妙的錯誤結果(比如相機位姿方向明顯反了)。之後對相機重新進行內參標定時(用ROS自帶的camera_calibration),把畸變階次提高到k1~k6&p1~p2保證去畸變的效果較好(用的鏡頭視角偏大,畸變明顯)。然後錄kalibr的標定數據時,先對圖像進行去畸變,並且讓運動激勵充分(足夠的三軸加速度和角速度激勵),標定出來的結果就比較合理了(外參的旋轉和平移量和肉眼觀察相近)。感覺這部分還是要仔細處理好的,自己吃了不少虧,嘗試了N多遍……

         這裡給一個手持上述傳感器在實驗室跑的結果錄像(非實時,另外沒仔細調,結果並不算完美)。

         連結:http://v.youku.com/v_show/id_XMTkxMjgzMzMwOA==.html

 

10.   總結

        總的來說,除了所加的IMU這部分外,改動並不大,這也得益於ORBSLAM這個視覺SLAM框架寫的很好,個人感覺作為一個學習入手的材料挺好的。

         所以再次強調,目前寫的這部分只是面向學習的代碼,非實時,沒有細調各處邏輯和參數,也可能有各種bug和可改進之處,歡迎感興趣的同學交流討論一起改進。

         另外,本程序在Ubuntu14.04 + ROS indigo + OpenCV 2.4.8(ROS 自帶)下測試,其他環境需要可能需要相應調整。而自己攢的硬體感覺是比較好的,對於性能更低點的比如MPU6050的IMU、捲簾快門的相機,並沒有測試,不確定效果如何。

 

11.   致謝

     感謝@張騰、@謝曉佳、@張明明的指點和討論,感謝@高翔幫忙debug。感謝@胡佳興和@李承陽兩位「給」的IMU。

 

參考資料

[1] https://github.com/jingpang/LearnVIORB

[2] Raúl Mur-Artal and Juan D. Tardós. Visual-inertial monocular SLAM with map reuse. arXiv preprint arXiv:1610.05949.

[3] Raúl Mur-Artal and Juan D. Tardós. ORB-SLAM2: an Open-Source SLAM System for Monocular, Stereo and RGB-D Cameras. ArXiv preprint arXiv:1610.06475

[4] https://github.com/raulmur/ORB_SLAM2

[5] Christian Forster, Luca Carlone, Frank Dellaert, Davide Scaramuzza, "On-Manifold Preintegration for Real-Time Visual-Inertial Odometry," IEEE Transactions on Robotics (in press), 2016 .

[6] https://bitbucket.org/gtborg/gtsam/

[7] M. Burri, J. Nikolic, P. Gohl, T. Schneider, J. Rehder, S. Omari, M. Achtelik and R. Siegwart, The EuRoC micro aerial vehicle datasets, International Journal of Robotic Research, DOI: 10.1177/0278364915620033, early 2016.

[8] http://projects.asl.ethz.ch/datasets/doku.php?id=kmavvisualinertialdatasets

[9] Paul Furgale, Joern Rehder, Roland Siegwart (2013). Unified Temporal and Spatial Calibration for Multi-Sensor Systems. In Proceedings of the IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS), Tokyo, Japan.

[10] https://github.com/ethz-asl/kalibr

[11] https://github.com/ethz-asl/kalibr/wiki/IMU-Noise-Model

[12] Shen, S., Mulgaonkar, Y., Michael, N., & Kumar, V. (2016). Initialization-Free Monocular Visual-Inertial State Estimation with Application to Autonomous MAVs. In Experimental Robotics (pp. 211-227). Springer International Publishing.

[13] Yang, Z., & Shen, S. (2016). Monocular Visual-Inertial State Estimation With Online Initialization and Camera-IMU Extrinsic Calibration.

[14] Forster, C., Carlone, L., Dellaert, F., & Scaramuzza, D. (2015). IMU preintegration on manifold for efficient visual-inertial maximum-a-posteriori estimation. In Robotics: Science and Systems XI (No. EPFL-CONF-214687).

[15] http://rpg.ifi.uzh.ch/docs/RSS15_Forster_Supplementary.pdf

[16] Barfoot, State Estimation for Robotics: A Matrix-Lie-Group Approach, 2015. http://asrl.utias.utoronto.ca/~tdb/bib/barfoot_ser15.pdf

[17] Nikolic, J., Rehder, J., Burri, M., Gohl, P., Leutenegger, S., Furgale, P. T., & Siegwart, R., A Synchronized Visual-Inertial Sensor System with FPGA Pre-Processing for Accurate Real-Time SLAM. IEEE International Conference on Robotics and Automation (ICRA), Hongkong, China.

 

【版權聲明】泡泡機器人SLAM的所有文章全部由泡泡機器人的成員花費大量心血製作而成的原創內容,希望大家珍惜我們的勞動成果,轉載請務必註明出自【泡泡機器人SLAM】微信公眾號,否則侵權必究!同時,我們也歡迎各位轉載到自己的朋友圈,讓更多的人能進入到SLAM這個領域中,讓我們共同為推進中國的SLAM事業而努力!

【注】商業轉載請聯繫劉富強(liufuqiang_robot@hotmail.com)進行授權。普通個人轉載,請保留版權聲明,並且在文章下方放上「泡泡機器人SLAM」微信公眾帳號的二維碼即可。

【編輯】張韻

相關焦點

  • 新手入門SLAM必備資料
    首先學習SLAM需要會C和C++,網上很多代碼還用了11標準的C++。第二要學會用Linux。第三要會cmake,vim/emacs及一些編程工具。第四要會用openCV, PCL, Eigen等第三方庫。只有學會了這些東西,才能真正上手編一個SLAM系統。如果要跑實際機器人,還要會ROS。下面將為大家推薦SLAM入門的學習書籍、SLAM公開課、SLAM學習網站、SLAM開原始碼等資料大全。
  • ORB-SLAM3 單目地圖初始化(終結篇)
    歡迎大家一起交流成長~一、前言請閱讀本文之前最好把ORB-SLAM3的單目初始化過程再過一遍(ORB-SLAM3 細讀單目初始化過程(上)、超詳細解讀ORB-SLAM3單目初始化(下篇)),以提高學習效率。單目初始化過程中最重要的是兩個函數實現,分別是構建幀(Frame)和初始化(Track)。
  • 孩子的好拍檔,酷比魔方泡泡智能交互機器人評測
    三款產品各有不同的功能特點側重,今天我們要來評測的是泡泡智能交互機器人。目前在京東眾籌上架的這款產品是具備AI人工智慧、大數據、雲計算、語音語義分析、語音合成的多功能家庭陪護機器人。【開箱介紹】泡泡機器人外包裝為白色,上蓋打開設計,上蓋印有酷比魔方字樣,包裝正面印有泡泡機器人正面外觀圖,下方印有智能互動、智能陪伴、智能學習、實時翻譯四大主要功能特點。
  • 讓無人機自主避障教學研究邁向更高處slam導航避障算法
    感知障礙階段"在開闊場地飛行,儘量避開人群,避免因操作失誤而帶來的安全事故」是目前大部分消費級無人機的使用說明上都會出現的一項標註,因此各無人機開發商為了降低安全事故的發生機率,都將避障技術作為了開發的重點。
  • 估值超400億元的泡泡瑪特即將上市
    本文章由三文娛原創,轉載請註明出處。上半年Pucky和Dimoo給泡泡瑪特帶來的收益已經超過Molly。潮玩的熱潮,就要衝上一個高峰。就在昨天,泡泡瑪特比原計劃提前兩天結束了國際配售,即將在12月11日正式以數字9992為股票代碼在香港聯合交易所掛牌上市。泡泡瑪特在招股首日面向散戶部分的股票發行,已獲得78倍超額認購;泡泡瑪特擬通過上市發行1.36億股,每股發售價格介於31.50-38.50港元,募資金額遠高於此前預期。
  • 專欄:獨立站之Facebook登錄集成|給你代碼
    完整代碼示例下面的代碼將在 HTML 頁面中加載和初始化 JavaScript SDK。用您的應用ID替換 {app-id},再用要使用的圖譜 API 版本替換 {api-version}。除非有特殊原因必須使用較舊版本,否則請指定最新版本: v6.0。<!
  • visual studio 2015怎麼把英文界面變成中文?
    visual studio 2015怎麼把英文界面變成中文界面?最新的vs2015,剛下載下來時是全英文界面,如何將它改成中文界面呢。下面介紹一下詳細的教程,需要的朋友可以參考下最新的vs2015,剛下載下來時是全英文界面,如何將它改成中文界面呢。
  • 超好用的Visual Studio編程軟體,你在用嗎?
    寫代碼並不是年輕的專利用過很多編程軟體,最終還是覺得VS好用,果斷去下載安裝。visual studio不僅可以編寫C,C++,還可以編寫python,還可寫網頁等等語言,功能很強大。再次記錄下來,以便查看。1.搜索「visual studio」打開官網,點擊下載,我選擇的是community版本2.
  • 泡泡瑪特機器人商店首次亮相日本
    中國潮流玩具集團POP MART泡泡瑪特也參加了本次展會,在展會中,POP MART泡泡瑪特不僅帶來了基本在售潮玩,其機器人商店更是首次亮相日本,就讓我們在展會中與中國潮玩相遇吧!事實上,在剛剛過去的2019年,不少中國身影走出國門。
  • 匯集全球優秀設計師 泡泡瑪特助力中國原創潮玩品牌化
    隨著中國超級市場與超級商場地位逐漸穩固,加強自主品牌建設、發展品牌經濟、打造專屬中國的原創品牌已經成為新時期各企業發展的重點。在潮流玩具領域,作為行業領導者的POP MART泡泡瑪特就通過以設計師與IP為原點打造成熟的潮玩發展平臺,推動中國原創潮玩企業向著品牌化的道路發展。
  • 《原創視頻》專欄2016回顧
    --《原創視頻》專欄2016回顧 --2016原創視頻專欄成績單:
  • 泡泡瑪特,頂著」泡泡」講故事?
    如今泡泡瑪特旗下運營85個IP,包括12個自有IP、22個獨家IP及51個非獨家IP。與泡泡瑪特迅猛的發展形成鮮明對比的是,直到2018年,泡泡瑪特仍算不上一個創投圈的明星項目,在當時的投資人眼裡,泡泡瑪特似乎沒有什麼投資價值。結果才兩年時間,泡泡瑪特面向一級市場融資的大門已經永遠關閉,沒有上車的投資人內心想法肯定是:瑪特,誰能想到你這泡泡竟然能吹這麼大。
  • 研究人員詳細闡述了如何讓穿上「網襪」的黏土變成變形機器人
    打開APP 研究人員詳細闡述了如何讓穿上「網襪」的黏土變成變形機器人 機器人大講堂 發表於 2020-12-23 13:52:47
  • 工業機器人結構原理!詳細解析機器人手臂!
    工業機器人(機械手,機械臂,機械手臂)-隨著自動化和工業4.0的普及發展,機器人機械手在各個行業都有使用,它是自動化改造常用的機器設備,今天海智機器人就講講工業機器人結構和動作原理,詳細解析機器人手臂組成和配件。
  • 泡泡裙公主杯「第三屆國際青少年兒童【繪本原創】大賽徵稿通知
    >第三屆國際青少年兒童【繪本原創】大賽徵稿通知——暨泡泡裙公主表情特輯徵稿2016,萬物更新,2016「泡泡裙公主杯」第三屆國際青少年兒童【繪本原創】大賽正式拉開帷幕。本次活動的在前兩屆的基礎上增加重大亮點,跨行業大聯合,美育藝術共締造【跨行業10強聯合發起+全國300家兒童美術機構發起】:中國繪本美術引領者寶貝計畫連鎖品牌聯合中國建設銀行、北京大學、娃哈哈集團、360兒童衛士手錶、宜信財富、布丁機器人、接力出版社、大聖歸來發行方影聯傳媒、素質教育研究、中國繪本協會及全國近300家兒童美術機構聯合發起;並由北京市教委第19屆藝術節網絡技術支持方
  • 泡泡糖忍戰超詳細新手攻略 Ninjala快速上手指南
    使用「忍者泡泡糖」進行對戰的動作遊戲Ninjala是一款免費的switch聯網對戰遊戲,發售還到不到一周,卻已經榮登Jump社區熱度榜首,下面小編就為大家帶來相關解決方法,有需要的小夥伴不要錯過了!
  • 《超級機器人大戰X》原創主角詳細情報公開
    萬代南夢宮公布了即將在3月29日推出的PS4/PS Vita《超級機器人大戰X》的最新情報,包含了原創主角、主角機體、機體特殊能力介紹等。
  • app 安全和馬甲包代碼混淆的demo的手把手教你的詳細教程
    Security-And-CodeConfuse(安全與編解碼器)App Security And CodeConfuse (app 安全和代碼混淆的demo的手把手教你的詳細教程)本篇文章內容一)為什麼要進行代碼混淆二)代碼混淆的兩種方法(①宏替換 ②腳本實現替換)三)代碼混淆參考的博客及說明1)為什麼要進行代碼混淆
  • Red Velvet IRENE裴珠泫獨特的氛圍,The original visual
    Red Velvet IRENE裴珠泫獨特的氛圍,The original visualRed Velvet的IRENE裴珠泫公開了穿著強烈的黑色衣服的照片。特別是臉部特寫的照片引起了關注,對此網民們引用Red Velvet的歌詞表示為「The original visual」。另一方面,IRENE所屬的Red Velvet-IRENE & 澀琪Seul Gi小分隊,在6日發行了專輯,正在展開了活躍的活動。
  • LOL手遊100036等錯誤代碼詳細解決辦法 全部錯誤代碼分享
    首頁 > 部落 > 關鍵詞 > lol最新資訊 > 正文 LOL手遊100036等錯誤代碼詳細解決辦法 全部錯誤代碼分享