Apollo进阶课程㊱丨Apollo ROS深入介绍
原文鏈接:進階課程?丨Apollo ROS深入介紹?
ROS是一個強大而靈活的機器人編程框架,從軟件構(gòu)架的角度說,它是一種基于消息傳遞通信的分布式多進程框架。ROS本身是基于消息機制的,可以根據(jù)功能把軟件拆分成為各個模塊,每個模塊只是負責讀取和分發(fā)消息,模塊間通過消息關(guān)聯(lián)。
上周阿波君為大家詳細介紹了「進階課程? | Apollo ROS原理—4」。
主要講解五個比較基礎(chǔ)的方面:第一是ROS Services;第二是ROS Actions;第三是ROS Time;第四是ROS Bags;第五是調(diào)試工具。
本周阿波君將繼續(xù)與大家分享Apollo ROS的相關(guān)課程。下面,我們一起進入進階課程第36期。
目前ROS僅適用于Apollo 3.0之前的版本,最新代碼及功能還請參照Apollo 3.5及5.0版本。
目錄
1. ROS Packages
2. Eclipse下編譯ROS基本工程
3.通過hello world了解ROS基本的運行邏輯
4. ROS提供的日志系統(tǒng)
5. ROS提供的subscriber和publisher功能
6. ROS除了message的另外兩種通信方式
6.1 service
6.2 parameter
7.ROS的可視化工具RViz
本節(jié)內(nèi)容主要介紹ROS中一些不是特別常見的屬性。
1. ROS Packages
創(chuàng)建一個ROS開發(fā)環(huán)境和寫一個C++工程有點類似,通過catkin create可以創(chuàng)建一個簡單的工程。其中的文件組織方式如上圖所示,包括:
- SRC存放源文件;
- MSG存放節(jié)點之間進行通信的消息定義;
- SRV存放節(jié)點之間進行服務(wù)通信的時候的服務(wù)定義;
- CONFIG存放配置文件相關(guān)的信息;
- INCLUDE存放頭文件相關(guān)的信息;
- Launch存放節(jié)點啟動和它相關(guān)的節(jié)點之間的啟動文件。
上面介紹的package組織方式只是官方推薦的一種組織方式,使用catkin build編譯,當source完環(huán)境變量之后,通過Ros提供的命令比如ROS run或者ROS launch啟動時,package name可以自動補全,package里面包含的節(jié)點或者launch文件也是可以自動尋找,所以官方推薦使用這種組織方式。
DEVEL和BUILD這兩個目錄是build時自動產(chǎn)生的兩個臨時目錄。
此外,開發(fā)環(huán)境還有描述ROS Package相關(guān)工作區(qū)的兩個文件:Package.xml和Cmakelists.txt。
Package.xml定義了可執(zhí)行文件依賴的一些庫,包括編譯和運行時依賴庫,同時定義了軟件版本信息等常見的描述文件。
Cmakelists.txt定義了怎么編譯ROS工程的規(guī)則,主要定義了以下幾個部分:
下面是Cmakelists文件的一個例子。
從上到下依次指定了Cmake的版本、project的名字、ROS工程所依賴的c++的版本、另外是依賴的庫文件,最后生成可執(zhí)行文件以及這個文件所鏈接的依賴庫。
2. Eclipse下編譯ROS基本工程
工程建立好之后,catkin build可以直接對工程進行編譯。直接用 catkin build去編譯,會把整個工程目錄里面的所有的package進行統(tǒng)一編譯,如果是構(gòu)建一個比較復(fù)雜的系統(tǒng),可能一個文件夾包含了很多節(jié)點或者package包,編譯時間會比較久,可以通過指定package名,編譯某一個固定的package包,提升編譯效率。
下面介紹在Eclipse下如何編譯ROS基本工程
首先是設(shè)置工作ROS工作區(qū),然后將ROS package導(dǎo)入到Eclipse設(shè)置的工作區(qū)。
通過Eclipse提供的build或者run等功能去調(diào)試ROS工程。同時Eclipse里面提供的快捷鍵在編譯程序里面同樣適用。
3.通過hello world了解ROS基本的運行邏輯
上圖的hello world程序展現(xiàn)了ROS框架寫Node所使用的核心要素:
Include 就是include ROS的一個基本環(huán)境;
Main函數(shù)里面有三行需要重點注意:
- init:引入ROS的一個基本環(huán)境,指定節(jié)點使用的node名字和一些參數(shù)信息;
- NodeHandle:node和整個ROS框架進行通信所使用的一個句柄指針;
- 數(shù)據(jù)發(fā)送的頻率:looprate(10)以10赫茲發(fā)送消息。
最底下的while循環(huán)以10赫茲的消息頻率進行發(fā)送,同時進行計數(shù)。
Spinonce:有一幀消息就把這消息立馬發(fā)送出去,同時進行下一輪的消息等待。
4. ROS提供的日志系統(tǒng)
在示例程序里面有一個ROS_INFO,它就是ROS提供的日志系統(tǒng);
ROS的日志系統(tǒng)是分級的,即在編寫節(jié)點程序的時候?qū)Υ蛴〉男畔⑦M行分級,對不同的分級,ROS會提供不同的顏色和格式進行展示。分級的作用是為了幫助開發(fā)者快速地定位到關(guān)鍵信息,不會對整個節(jié)點的邏輯產(chǎn)生實質(zhì)性的影響。
日志系統(tǒng)提供了兩種格式ROS_INFO與ROS_INFO_stream:
- ROS_INFO:默認把信息打印到當時運行的屏幕上。
- ROS_INFO_stream:它是流式數(shù)據(jù),默認輸出到后臺這個節(jié)點所對應(yīng)的日志文件。
5. ROS提供的subscriber和publisher功能
Subscriber與Publisher有三點明顯的區(qū)別:
1、回調(diào)函數(shù):subscriber作為信息的接收方有一個回調(diào)函數(shù),回調(diào)函數(shù)定義了它接收到的每一幀信息如何使用;上圖listener回調(diào)函數(shù)比較簡單,它接收到信息后只是進行了打印處理。Publisher沒有回調(diào)函數(shù),它不需要對消息進行處理。
2、聲明的時候:subscriber把回調(diào)函數(shù)傳入到對應(yīng)的node初始化程序里面。publisher聲明的時候只需要注冊要往哪一個topic上去發(fā)信息,同時還設(shè)置隊列長度。
3、Rosspin:在ROS構(gòu)架里所有的回調(diào)函數(shù)都不是主動觸發(fā)的。Rosspin是阻塞性的,聲明Rosspin之后,就阻塞在此,程序不會退出,它會一直監(jiān)聽自己對應(yīng)的隊列里面是否有新消息的到達,若有新消息到達就會觸發(fā)回調(diào)函數(shù)處理。
如果Subscriber的主程序里除了訂閱消息之外還有其他的功能則可以采用rosspin once,對所有已達消息進行回調(diào)函數(shù)的處理。同時可以寫一個while循環(huán),rosspin once按照一定的頻率去處理回調(diào)函數(shù)的消息。ROS提供Rosspin這兩種方式,就是為了滿足這兩種場景。第一種是阻塞,只有一個回調(diào)函數(shù)進行處理,第二種是訂閱回調(diào)函數(shù)消息以外,他還進行了一些封裝和處置。
看似很復(fù)雜的自動駕駛,節(jié)點整體寫下來都是比較簡單的,就是按照上圖Subscriber與Publisher方式來寫。但是在實際的自動駕駛系統(tǒng)里面,所有的模塊都不是簡單的一個角色,它可能既是消息的訂閱者也是消息的發(fā)送者,是一個復(fù)雜交互的功能,甚至是用到很多數(shù)據(jù)融合或者是消息對齊。
6. ROS除了message的另外兩種通信方式
ROS節(jié)點之間的通信除了基于message消息訂閱和發(fā)布模型之外還有另外兩種方式,雖然另外兩種方式使用的比較少,但是在某些特定的場合是比較有用的。
6.1 service
節(jié)點可以啟動service去注冊一項服務(wù),另外一個節(jié)點在使用這項服務(wù)的時候可以直接call service完成一些實時的數(shù)據(jù)通訊交互。Message是一個被動的消息行為,發(fā)送者發(fā)送消息的時候并不知道消息會被誰去消費,接收者在接收消息的時候也不知道目前有幾個發(fā)送節(jié)點在發(fā)送,發(fā)送和接收之間是一個什么狀態(tài)也是不知道的,他們是一個松耦合和透明的關(guān)系。Service彌補了這種通信方式的不足,它需要及時回應(yīng)。Client向server去發(fā)送service請求的時候,需要實時等待一個response,根據(jù)響應(yīng)做出下一步的行為指示。
6.2 parameter
Parameter通信方式借鑒了service的原理。它啟動了Parameter service,Parameter service是一個全局的服務(wù)器,各個節(jié)點在進行參數(shù)設(shè)置和獲取的時候可以通過Parameter service的方式輕易完成。因為Parameter不像基于message消息通訊方式那么頻繁,一個參數(shù)在設(shè)置完成之后,在整個網(wǎng)絡(luò)拓撲運行期間所有的節(jié)點只需要在一個地方取此參數(shù)就行或者某個節(jié)點根據(jù)自己的運行狀態(tài)去改變這個參數(shù)。
Parameter對應(yīng)有一套ROS所使用的基本命令行工具—rosparam。
rosparam其它工具相比,有兩個不同的地方:get和set。get是get某一個全局參數(shù)的值;set是設(shè)置某一個全局參數(shù)的值。
上圖展示的例子是通過node所提供的nodeHandler指針去調(diào)用它的getparam,得到某個參數(shù)的數(shù)值。當它進行一些運算之后,也可以通過setparam去設(shè)置參數(shù)的值。設(shè)置之后,整個系統(tǒng)參數(shù)服務(wù)器里面對應(yīng)的這個參數(shù)就會被設(shè)置成對應(yīng)的值,其他節(jié)點在得到這個值之后再作出相應(yīng)的處理。
7.ROS的可視化工具RViz
自動駕駛節(jié)點比較多,網(wǎng)絡(luò)拓撲也比較復(fù)雜,每個節(jié)點在進行消息通訊的時候有很多channel同時運行,如果只是通過命令行工具去查看節(jié)點的狀態(tài)和節(jié)點之間的拓撲,會很麻煩。ROS提供了一些比較好用的可視化工具立體化展示某一個拓撲結(jié)構(gòu)里面的拓撲網(wǎng)絡(luò),RViz就是其中之一。
RViz在整個ROS生態(tài)里可以看成是一個節(jié)點,它定義了整個拓撲結(jié)構(gòu)里面所有的消息,然后按照固定的格式進行圖形化展示,同時提供很多debug相關(guān)的功能。因為RViz也是一個普通的節(jié)點,所以在啟動的時候可以通過rosrun命令的方式去啟動RViz相關(guān)的功能。
RViz也提供了很多插件可以放到諸如eclipse這樣的功能插件里面,在進行eclipse開發(fā)時可以通過eclipse的plugin去調(diào)取RViz的相關(guān)功能,進行可視化調(diào)試。
總結(jié)
以上是生活随笔為你收集整理的Apollo进阶课程㊱丨Apollo ROS深入介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 指定身故受益人的时候有哪些注意要点?受益
- 下一篇: PasSrv.exe - PasSrv是