1. 程式人生 > >【無人駕駛系列二】基於ROS的無人駕駛系統

【無人駕駛系列二】基於ROS的無人駕駛系統

本文是無人駕駛技術系列的第二篇。在上篇解析光學雷達(LiDAR)技術之後,本文著重介紹基於機器人作業系統ROS的無人駕駛系統。文中將介紹ROS以及它在無人駕駛場景中的優缺點,並討論如何在ROS的基礎上提升無人駕駛系統的可靠性、通訊效能和安全性。

無人駕駛:多種技術的整合

無人駕駛技術是多個技術的整合,如圖1所示,一個無人駕駛系統包含了多個感測器,包括長距雷達、鐳射雷達、短距雷達、攝像頭、超聲波、GPS、陀螺儀等。每個感測器在執行時都不斷產生資料,而且系統對每個感測器產生的資料都有很強的實時處理要求。比如攝像頭需要達到60FPS的幀率,意味著留給每幀的處理時間只有16毫秒。但當資料量增大之後,分配系統資源便成了一個難題。例如,當大量的鐳射雷達點雲資料進入系統,佔滿CPU資源,就很可能使得攝像頭的資料無法及時處理,導致無人駕駛系統錯過交通燈的識別,造成嚴重後果。

圖片描述

圖1 無人駕駛系統範例

 

如圖2所示,無人駕駛系統整合了多個軟體模組(包括路徑規劃、避障、導航、交通訊號監測等)和多個硬體模組(包括計算、控制、感測器模組等),如何有效調配軟硬體資源也是一個挑戰。具體包括三個問題:第一,當軟硬體模組資料增加,執行期間難免有些模組會出現異常退出的問題,甚至導致系統崩潰,此時如何為提供系統自修復能力?第二,由於模組之間有很強的聯絡,如何管理模組間的有效通訊(關鍵模組間的通訊,資訊不可丟失,不可有過大的延時)?第三,每個功能模組間如何進行資源隔離?如何分配計算與記憶體資源?當資源不足時如何確認更高的優先順序執行?

圖片描述

圖2 無人駕駛軟硬體整合

 

簡單的嵌入式系統並不能滿足無人駕駛系統的上述需求,我們需要一個成熟、穩定、高效能的作業系統去管理各個模組。在詳細調研後,我們覺得機器人作業系統ROS比較適合無人駕駛場景。下文將介紹ROS的優缺點,以及如何改進ROS使之更適用於無人駕駛系統。

機器人作業系統(ROS)簡介

ROS是一個強大而靈活的機器人程式設計框架,從軟體構架的角度說,它是一種基於訊息傳遞通訊的分散式多程序框架。ROS很早就被機器人行業使用,很多知名的機器人開源庫,比如基於quaternion的座標轉換、3D點雲處理驅動、定位演算法SLAM等都是開源貢獻者基於ROS開發的。因為ROS本身是基於訊息機制的,開發者可以根據功能把軟體拆分成為各個模組,每個模組只是負責讀取和分發訊息,模組間通過訊息關聯。如圖3所示,最左邊的節點可能會負責從硬體驅動讀取資料(比如Kinect),讀出的資料會以訊息的方式打包,ROS底層會識別這個訊息的使用者,然後把訊息資料分發給他們。

圖片描述

圖3 ROS系統

 

ROS 1.0

ROS 1.0起源於Willow Garage的PR2專案,主要元件包括ROS Master、ROS Node和ROS Service三種。ROS Master的主要功能是命名服務,它儲存了啟動時需要的執行時引數,訊息釋出上游節點和接收下游節點的連線名和連線方式,和已有ROS服務的連線名。ROS Node節點是真正的執行模組,對收到的訊息進行處理,並且釋出新的訊息給下游節點。ROS Service是一種特殊的ROS節點,它相當於一個服務節點,接受請求並返回請求的結果。圖4展示了ROS通訊的流程順序,首先節點會向master advertise或者subscribe感興趣的topic。當建立連線時,下游節點會向上遊節點TCP Server釋出連線請求,等連線建立後,上游節點的訊息就會通過連線送至下游節點。

圖片描述

圖4 ROS Master Node通訊

 

ROS 2.0

ROS 2.0的改進主要是為了讓ROS能夠符合工業級的執行標準,採用了DDS(資料分發服務)這個工業級別的中介軟體來負責可靠通訊,通訊節點動態發現,並用shared memory方式使得通訊效率更高。通過使用DDS,所有節點的通訊拓撲結構都依賴於動態P2P的自發現模式,所以也就去掉ROS Master這個中心節點。如圖5所示,RTI Context、PrismTech OpenSplice和Twin Oaks都是DDS的中介軟體提供商,上層通過DDS API封裝,這樣DDS的實現對於ROS Client透明。設計上ROS主頁詳細討論了用DDS的原因,詳情參見http://design.ros2.org/articles/ros_on_dds.html

圖片描述

圖5 ROS 2.0 DDS

 

在無人車駕駛系統中, 我們選擇依舊基於ROS 1.0 開發,而不是ROS 2.0,主要有以下幾點考慮:

  1. ROS 2.0是一個開發中的框架,很多功能還不是很完整,有待更多的測試與驗證。而在無人駕駛環境中,穩定性與安全性是至關重要的,我們需要基於一個經過驗證的穩定系統來保證系統的穩定性、安全性和效能,以達到無人車的要求。
  2. DDS本身的耗費。我們測試了直接在ROS 1.0上使用DDS中介軟體,其中國防科技大學有一個開源專案MicROS已經做了相關的嘗試,詳情參見https://github.com/cyberdb/micROS-drt。但是實驗發現在一般的ROS通訊場景中(100K傳送者接收者通訊),ROS on DDS的吞吐率並不及ROS 1.0,主要原因是DDS框架本身的耗費要比ROS多一些,同時用了DDS以後CPU佔用率有明顯提高。但是我們也確認了使用DDS之後,ROS的QoS高優先順序的吞吐率和組播能力有了大幅提升。我們的測試基於PrismTech OpenSplice的社群版,在它的企業版中有針對單機的優化,比如使用了共享記憶體的優化,我們暫未測試。
  3. DDS介面的複雜性。DDS本身就是一套龐大的系統,其介面的定義極其複雜,同時文件支援較薄弱。

系統可靠性

如上文所述,系統可靠性是無人駕駛系統最重要的特性。試想幾個場景:第一,系統執行時ROSMaster出錯退出,導致系統崩潰;第二,其中一個ROS節點出錯,導致系統部分功能缺失。以上任何一個場景在無人駕駛環境中都可能造成嚴重的後果。對於ROS而言,其在工業領域的應用可靠性是非常重要的設計考量,但是目前的ROS設計對這方面考慮得比較少。下面就討論實時系統的可靠性涉及的一些要素。

去中心化

ROS重要節點需要熱備份,以便宕機時可以隨時切換。在ROS 1.0的設計中,主節點維護了系統執行所需的連線、引數和主題資訊,如果ROS Master宕機了,整個系統就有可能無法正常執行。去中心化的解決方案有很多,如圖6所示,我們可以採用主從節點的方式(類似ZooKeeper),同時主節點的寫入資訊隨時備份,主節點宕機後,備份節點被切換為主節點,並且用備份的主節點完成資訊初始化。

圖片描述

圖6 基於ZooKeeper的監控和報警

 

實時監控和報警

對於執行的節點實時監控其執行資料,並檢測到嚴重的錯誤資訊時報警。目前ROS並沒有針對監控做太多的構架考慮,然而這塊方面恰恰是最重要的。對於執行時的節點,監控其執行資料,比如應用層統計資訊、執行狀態等,對將來的除錯、錯誤追蹤都有很多好處。如圖7所示,實時監控從軟體構架來說主要分成3部分:ROS節點層的監控資料API,讓開發者能夠設定所需的統計資訊,通過統一的API進行記錄;監控服務端定期從節點獲取監控資料(對於緊急的報警資訊,節點可以把訊息推送給監控服務端);獲取到監控資料後,監控服務端對資料進行整合、分析、記錄,在察覺到異常資訊後報警。

圖片描述

圖7 基於ZooKeeper的監控和報警

 

節點宕機狀態恢復

節點宕機的時候,需要通過重啟的機制恢復節點,這個重啟可以是無狀態的,但有些時候也必須是有狀態的,因此狀態的備份格外重要。節點的宕機檢測也是非常重要的,如果察覺到節點宕機,必須很快地使用備份的資料重啟。這個功能我們也已經在ZooKeeper框架下實現了。

系統通訊效能提升

由於無人駕駛系統模組很多,模組間的資訊互動很頻繁,提升系統通訊效能會對整個系統性能提升的作用很大。我們主要從以下三個方面來提高效能:

第一,目前同一個機器上的ROS節點間的通訊使用網路棧的loop-back機制,也就是說每一個數據包都需要經過多層軟體棧處理,這將造成不必要的延時(每次20微秒左右)與資源消耗。為了解決這個問題,我們可以使用共享記憶體的方法把資料memory-map到記憶體中,然後只傳遞資料的地址與大小資訊,從而把資料傳輸延時控制在20微秒內,並且節省了許多CPU資源。

第二,現在ROS做資料broadcast的時候,底層實現其實是使用multiple unicast,也就是多個點對點的傳送。假如要把資料傳給5個節點,那麼同樣的資料會被拷貝5份。這造成了很大的資源浪費,特別是記憶體資源的浪費。另外,這樣也會對通訊系統的吞吐量造成很大壓力。為了解決這個問題,我們使用了組播multicast機制:在傳送節點和每一接收節點之間實現點對多點的網路連線。如果一個傳送節點同時給多個接收節點傳輸相同的資料,只需複製一份相同的資料包。組播機制提高了資料傳送效率,減少了骨幹網路出現擁塞的可能性。圖8對比了原有的通訊機制(灰線)與組播機制(橙色)的效能,隨著接收節點數量增加(X軸),原有的通訊機制的資料吞吐量急劇下降,而組播機制的資料吞吐量則比較平穩,沒有受到嚴重影響。

圖片描述

圖8 Multicast效能提升

 

第三,對ROS的通訊棧研究,我們發現通訊延時很大的損耗是在資料的序列化與反序列化的過程。序列化將記憶體裡物件的狀態資訊轉換為可以儲存或傳輸的形式。在序列化期間,物件將其當前狀態寫入到臨時或永續性儲存區。之後,可以通過從儲存區中讀取或反序列化物件的狀態,重新建立該物件。為了解決這個問題,我們使用了輕量級的序列化程式,將序列化的延時降低了50%。

系統資源管理與安全性

如何解決資源分配與安全問題是無人駕駛技術的一個大課題。想象兩個簡單的攻擊場景:第一,其中一個ROS的節點被劫持,然後不斷地分配記憶體,導致系統記憶體消耗殆盡,造成系統OOM而開始關閉不同的ROS節點程序,從而整個無人駕駛系統崩潰。第二,ROS的topic或者service被劫持, ROS節點之間傳遞的資訊被偽造,導致無人駕駛系統行為異常。

我們選擇的方法是使用Linux Container(LXC)來管理每一個ROS節點程序。簡單來說,LXC提供輕量級的虛擬化以便隔離程序和資源,而且不需要提供指令解釋機制以及全虛擬化等其他複雜功能,相當於C++中的NameSpace。LXC有效地將單個作業系統管理的資源劃分到孤立的群組中,以更好地在孤立的群組之間平衡有衝突的資源使用需求。對於無人駕駛場景來說,LXC最大的好處是效能損耗小。我們測試發現,在執行時LXC只造成了5%左右的CPU損耗。

除了資源限制外,LXC也提供了沙盒支援,使得系統可以限制ROS節點程序的許可權。為了避免有危險性的ROS節點程序可能破壞其他ROS節點程序的執行,沙盒技術可以限制可能有危險性的ROS節點訪問磁碟、記憶體以及網路資源。另外為了防止節點中的通訊被劫持,我們還實現了節點中通訊的輕量級加密解密機制,使黑客不能回放或更改通訊內容。

結論

要保證一個複雜的系統穩定、高效地執行,每個模組都能發揮出最大的潛能,需要一個成熟有效的管理機制。在無人駕駛場景中,ROS提供了這樣一個管理機制,使得系統中的每個軟硬體模組都能有效地進行互動。原生的ROS提供了許多必要的功能,但是這些功能並不能滿足無人駕駛的所有需求,因此我們在ROS之上進一步地提高了系統的效能與可靠性,完成了有效的資源管理及隔離。我們相信隨著無人駕駛技術的發展,更多的系統需求會被提出,比如車車互聯、車與城市交通系統互聯、雲車互聯、異構計算硬體加速等,我們也將會持續優化這個系統,力求讓它變成無人駕駛的標準系統。

無人駕駛技術系列文章將討論ROS系統、高精地圖、路徑規劃、底層控制和視覺識別等技術。整體規劃如下,敬請期待:

  1. LiDAR
  2. ROS
  3. Map
  4. GPS + IMU
  5. Camera
  6. Planning
  7. Control
  8. Data platform
  9. Simulation
  10. Communications