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