ROS的全名是Robot Operating System,即機(jī)器人操作系統(tǒng)。雖然名字里有個(gè)“操作系統(tǒng)”,但它并不是獨(dú)立的操作系統(tǒng),而要依賴于宿主系統(tǒng)之上。這個(gè)宿主系統(tǒng)通常是Ubuntu,因?yàn)樗赨buntu有現(xiàn)成的軟件倉(cāng)庫(kù),但是事實(shí)上只要是Linux/Unix都可以從源代碼編譯安裝。
因此,ROS其實(shí)是運(yùn)行在PC上的一套便于機(jī)器人開(kāi)發(fā)的機(jī)制,它通常用作上位機(jī)(例如用于Parrot AR.Drone四軸飛行器時(shí)),也可以搭載在機(jī)器人上作為主控(例如Turtlebot機(jī)器人使用了搭載ROS的筆記本電腦作為主控)。
由于優(yōu)秀的中文資料本來(lái)就少,何況ROS一直在迭代,有的情況變化很大,因此,還是強(qiáng)烈建議通過(guò)ROS官方網(wǎng)站的英文文檔來(lái)學(xué)習(xí)ROS。相關(guān)學(xué)習(xí)資料和操作步驟附在文末。本文目的只是為入門(mén)提供一點(diǎn)知識(shí)儲(chǔ)備。斜體內(nèi)容可安全跳過(guò),回頭再看也不遲。
ROS運(yùn)行機(jī)制
ROS內(nèi)核
ROS內(nèi)核(roscore)是ROS運(yùn)行的基礎(chǔ),它里面有參數(shù)服務(wù)器(parameter server)。一個(gè)運(yùn)行中的ROS有且僅有一個(gè)ROS內(nèi)核,ROS上的一切都依賴于這個(gè)內(nèi)核。
ROS底層的通信是通過(guò)HTTP完成的,因此ROS內(nèi)核本質(zhì)上是一個(gè)HTTP服務(wù)器,它的地址一般是http://localhost:11311/ ,即本機(jī)的11311端口。當(dāng)需要連接到另一臺(tái)計(jì)算機(jī)上運(yùn)行的ROS時(shí),只要連上該機(jī)的11311端口即可。
節(jié)點(diǎn)
節(jié)點(diǎn)(node)是ROS運(yùn)行的基本單位,每個(gè)節(jié)點(diǎn)通常執(zhí)行整個(gè)系統(tǒng)的一小部分功能,比如發(fā)送機(jī)器人位姿信息、發(fā)送控制信息、執(zhí)行一定的計(jì)算任務(wù)等。
一個(gè)機(jī)器人的運(yùn)行,依賴于節(jié)點(diǎn)彼此之間的協(xié)作。因此,有人說(shuō)ROS是分布式的。
節(jié)點(diǎn)之間的通信,依靠消息(message)和服務(wù)(service)。
消息
通常,ROS系統(tǒng)中有若干主題(topic)。每個(gè)節(jié)點(diǎn)可以對(duì)主題進(jìn)行訂閱(subscribe)操作,也可以對(duì)主題進(jìn)行發(fā)布(publish)操作。節(jié)點(diǎn)可以向某個(gè)主題發(fā)布消息,然后訂閱了該主題的節(jié)點(diǎn)就會(huì)自動(dòng)收到消息。
消息是有類型的。一類消息可以由一些基本數(shù)據(jù)結(jié)構(gòu)組成。例如,表示姿態(tài)的Pose類型消息,就由6個(gè)64位浮點(diǎn)數(shù)組成,分別代表三維空間中姿態(tài)的六個(gè)參數(shù)。消息類型的定義寫(xiě)在msg文件里,格式很簡(jiǎn)單,十分類似C語(yǔ)言中變量的定義。具體請(qǐng)參考官方文檔。
服務(wù)
服務(wù)是節(jié)點(diǎn)之間除消息以外的另一種通信方式。每個(gè)節(jié)點(diǎn)都可以創(chuàng)建服務(wù)。其它節(jié)點(diǎn)可以向該服務(wù)發(fā)出一個(gè)請(qǐng)求(request),負(fù)責(zé)這個(gè)服務(wù)的節(jié)點(diǎn)就要相應(yīng)地返回一個(gè)應(yīng)答(response)。
消息與服務(wù)的不同之處,在于服務(wù)必須是一對(duì)一的,一問(wèn)一答,可靠性很高。消息則可以多對(duì)多,相比之下更公共。至于完成某項(xiàng)通信究竟用誰(shuí)更好,還要結(jié)合具體情況來(lái)看。
服務(wù)也和消息一樣,是有類型的。服務(wù)類型的定義寫(xiě)在srv文件里,格式與表示消息類型的msg文件類似,只不過(guò)要分別描述請(qǐng)求的類型和應(yīng)答的類型。具體請(qǐng)參考官方文檔。
數(shù)據(jù)和文件結(jié)構(gòu)
以下這些東西是ROS在你硬盤(pán)上的樣子。這里用catkin工作空間來(lái)講解。
包集
ROS的那些包集(package)里包含了ROS運(yùn)行所需要的資源,比如程序、消息和服務(wù)的類型定義等。
一個(gè)包集里包含一個(gè)package.xml文件,這個(gè)文件描述了這個(gè)包集的基本信息。如果是源碼包,通常還有個(gè)CMakeLists.txt文件,這個(gè)文件提供編譯和安裝包集時(shí)需要的信息,比如有哪些文件需要編譯、程序要調(diào)用哪些庫(kù)等。
包集編譯時(shí),所有的消息類型、服務(wù)類型的C++和Python庫(kù)都會(huì)重新生成,C++代碼會(huì)重新編譯,其它一些在CMakeLists.txt規(guī)定的任務(wù)都會(huì)執(zhí)行。
當(dāng)你在包集里新建一個(gè)C++文件時(shí),請(qǐng)記得修改CMakeLists.txt;當(dāng)你在包集里新建一個(gè)msg文件時(shí),請(qǐng)記得修改CMakeLists.txt;當(dāng)你在包集里新建一個(gè)srv文件時(shí),請(qǐng)記得修改CMakeLists.txt;當(dāng)你在包集里新建一個(gè)Python文件時(shí),不必修改CMakeLists.txt。詳見(jiàn)官方文檔。
程序
ROS支持用C++和Python來(lái)寫(xiě)程序,相關(guān)的包集叫做roscpp 和rospy。當(dāng)修改C++文件時(shí),要編譯整個(gè)包集;Python則不必。
ROS里運(yùn)行的節(jié)點(diǎn)都是由程序創(chuàng)建的。一個(gè)包集里可以有很多個(gè)程序,但它們未必都包含節(jié)點(diǎn),也有可能是其它工具,例如某個(gè)文件格式轉(zhuǎn)換的工具。
消息類型與服務(wù)類型
這些就是之前提到的msg文件和srv文件。包集每次編譯時(shí),會(huì)生成它們對(duì)應(yīng)的C++頭文件和Python模塊,編程時(shí)可方便地調(diào)用它們。
launch文件
當(dāng)需要有很多節(jié)點(diǎn)同時(shí)啟動(dòng)時(shí),一個(gè)個(gè)啟動(dòng)它們會(huì)比較累,這時(shí)如果寫(xiě)一個(gè)launch文件把這些節(jié)點(diǎn)都包括進(jìn)去,那么只要啟動(dòng)一個(gè)launch文件,就相當(dāng)于把這些節(jié)點(diǎn)都啟動(dòng)了。
包
包(bag)是ROS用來(lái)記錄運(yùn)行期間消息的格式。記錄完以后,隨時(shí)可以重放這些消息。我們可以用它來(lái)記錄機(jī)器人運(yùn)行時(shí)傳感器的數(shù)據(jù),留待運(yùn)行結(jié)束以后分析。
ROS常用包集
這些不是ROS所必需的,但在實(shí)際中會(huì)經(jīng)常用到。
TF
提供基本的位姿在不同坐標(biāo)系中變換功能,例如某個(gè)點(diǎn)相對(duì)于各關(guān)節(jié)的坐標(biāo)等,真的非常基本。
Actionlib
控制機(jī)器人時(shí),消息和服務(wù)不能滿足要求,還要有一種新的通信方式——動(dòng)作(action)。動(dòng)作類似于服務(wù),但是節(jié)點(diǎn)在向服務(wù)發(fā)出請(qǐng)求后,會(huì)在接下來(lái)一段時(shí)間內(nèi)獲得一系列反饋信息,直到動(dòng)作完成才會(huì)收到應(yīng)答。
std_msgs和common_msgs
這里的std_msgs定義了一系列基本的消息類型,如字符串等;而common_msgs定義了一系列常用消息類型,例如姿態(tài)、傳感器數(shù)據(jù)等。
URDF機(jī)器人模型
ROS里的機(jī)器人模型通常用URDF來(lái)描述。URDF包集會(huì)自動(dòng)解析URDF文件,并轉(zhuǎn)為程序可讀的格式,供ROS其它節(jié)點(diǎn)使用。URDF是在ROS中描述一個(gè)機(jī)器人最方便的方式。
Rviz
ROS三維仿真工具,除了機(jī)器人本身,ROS的很多東西都可以在這里仿真,例如TF、點(diǎn)云等。
RQT
這是ROS很多圖形界面的一個(gè)集合,它們會(huì)輸出各種用于調(diào)試、診斷的信息。例如將傳感器數(shù)據(jù)畫(huà)到坐標(biāo)里(rqt_plot)、繪制所有節(jié)點(diǎn)與消息的關(guān)系圖(rqt_graph)等,共計(jì)不少于10種。
Moveit!
ROS最著名的用于運(yùn)動(dòng)規(guī)劃(motion planning)的庫(kù)。它可以為機(jī)器人的動(dòng)作生成路徑。
與各種庫(kù)相連接的橋
很多常用的庫(kù),如果要連接到ROS里,可以使用橋(bridge)。像OpenCV這樣的常用庫(kù),它的橋已經(jīng)有人開(kāi)發(fā)好了,可以直接安裝到ROS。
當(dāng)然也可以挑戰(zhàn)一下自己寫(xiě)一個(gè)橋。
如何學(xué)習(xí)?
Nootrix發(fā)布有安裝了ROS的Ubuntu虛擬機(jī)。如果你沒(méi)有Linux系統(tǒng)的話,可以裝個(gè)VirtualBox虛擬機(jī)跑。
ROS版本還是最新的Indigo Igloo為宜。上一個(gè)版本Hydro的教程也可以使用,但是代碼未必通用。
再次強(qiáng)調(diào)一遍,要想學(xué)好ROS,請(qǐng)務(wù)必參照官方英文文檔。
入門(mén)可以從文檔的Tutorial部分開(kāi)始,一點(diǎn)一點(diǎn)照著tutorial來(lái),學(xué)完基本的以后再把常用包集的tutorial也刷一遍,這樣差不多就會(huì)了。
對(duì)于特定的包集,最好的辦法是找到它在ROS的網(wǎng)頁(yè),上面一般會(huì)有文檔或鏈接。
遇到問(wèn)題的話,請(qǐng)仔細(xì)查看相關(guān)庫(kù)的文檔,如無(wú)結(jié)果可用搜索引擎搜一搜自己遇到的問(wèn)題,還是不行的話,可以到官方的問(wèn)答站搜索問(wèn)題或提問(wèn)。
不過(guò)真要學(xué)好的話,最好還是用它來(lái)做一個(gè)機(jī)器人項(xiàng)目吧。