總體結構
根據ROS系統代碼的維護者和分布來標示,主要有兩大部分:
- main:核心部分,主要由Willow Garage公司和一些開發者設計、提供以及維護。它提供了一些分布式計算的基本工具,以及整個ROS的核心部分的程序編寫。
- universe:全球范圍的代碼,有不同國家的ROS社區組織開發和維護。一種是庫的代碼,如OpenCV、PCL等;庫的上一層是從功能角度提供的代碼,如人臉識別,他們調用下層的庫;最上層的代碼是應用級的代碼,讓機器人完成某一確定的功能。
一般是從另一個角度對ROS分級的,主要分為三個級別:計算圖級、文件系統級、社區級。
計算圖級 Computation Graph level
計算圖是ROS處理數據的一種點對點的網絡形式。程序運行時,所有進程以及他們所進行的數據處理,將會通過一種點對點的網絡形式表現出來。這一級主要包括幾個重要概念:節點(node)、消息(message)、主題(topic)、服務(service)。
節點 Node
節點就是一些直行運算任務的進程。ROS利用規模可增長的方式是代碼模塊化:一個系統就是典型的由很多節點組成的。在這里,節點也可以被稱之為“軟件模塊”。我們使用“節點”使得基于ROS的系統在運行的時候更加形象化:當許多節點同時運行時,可以很方便的將端對端的通訊繪制成一個圖表,在這個圖表中,進程就是圖中的節點,而端對端的連接關系就是其中弧線連接。
消息 Message
節點之間是通過傳送消息進行通訊的。每一個消息都是一個嚴格的數據結構。原來標準的數據類型(整型,浮點型,布爾型等等)都是支持的,同時也支持原始數組類型。消息可以包含任意的嵌套結構和數組(很類似于C語言的結構structs)。
主題 Topic
消息以一種發布/訂閱的方式傳遞。一個節點可以在一個給定的主題中發布消息。一個節點針對某個主題關注與訂閱特定類型的數據。可能同時有多個節點發布或者訂閱同一個主題的消息。總體上,發布者和訂閱者不了解彼此的存在。
服務 Service
雖然基于話題的發布/訂閱模型是很靈活的通訊模式,但是它廣播式的路徑規劃對于可以簡化節點設計的同步傳輸模式并不適合。在ROS中,我們稱之為一個服務,用一個字符串和一對嚴格規范的消息定義:一個用于請求,一個用于回應。這類似于web服務器,web服務器是由URIs定義的,同時帶有完整定義類型的請求和回復文檔。需要注意的是,不像話題,只有一個節點可以以任意獨有的名字廣播一個服務:只有一個服務可以稱之為“分類象征”,比如說,任意一個給出的URI地址只能有一個web服務器。
節點控制器 Master
在上面概念的基礎上,需要有一個控制器可以使所有節點有條不紊的執行,這就是一個ROS的控制器(Master)。
ROS Master通過RPC(Remote Procedure Call Protocol,遠程過程調用)提供了登記列表和對其他計算圖表的查找。沒有控制器,節點將無法找到其他節點,交換消息或調用服務。
比如控制節點訂閱和發布消息的模型如下:
ROS的控制器給ROS的節點存儲了主題和服務的注冊信息。節點與控制器通信從而報告它們的注冊信息。當這些節點與控制器通信的時候,它們可以接收關于其他以注冊及節點的信息并且建立與其它以注冊節點之間的聯系。當這些注冊信息改變時控制器也會回饋這些節點,同時允許節點動態創建與新節點之間的連接。
節點與節點之間的連接是直接的,控制器僅僅提供了查詢信息,就像一個DNS服務器。節點訂閱一個主題將會要求建立一個與出版該主題的節點的連接,并且將會在同意連接協議的基礎上建立該連接。
另:ROS控制器控制服務:
文件系統級 Filesystem level
ROS文件系統級指的是在硬盤上面查看的ROS源代碼的組織形式。
ROS中有無數的節點、消息、服務、工具和庫文件,需要有效的結構去管理這些代碼。在ROS的文件系統級,有以下幾個重要概念:包(package)、堆(stack)、
包 Package
ROS的軟件以包的方式組織起來。包包含節點、ROS依賴庫、數據套、配置文件、第三方軟件、或者任何其他邏輯構成。包的目標是提供一種易于使用的結構以便于軟件的重復使用。總得來說,ROS的包短小精干。
堆 Stack
堆是包的集合,它提供一個完整的功能,像“navigation stack”。Stack與版本號關聯,同時也是如何發行ROS軟件方式的關鍵。
ROS是一種分布式處理框架。這使可執行文件能被單獨設計,并且在運行時松散耦合。這些過程可以封裝到包(Packages)和堆(Stacks)中,以便于共享和分發。下圖是在包和堆在文件中的具體結構:
Manifests (manifest.xml):提供關于Package元數據,包括它的許可信息和Package之間依賴關系,以及語言特性信息像編譯旗幟(編譯優化參數)。
Stack manifests (stack.xml):提供關于Stack元數據,包括它的許可信息和Stack之間依賴關系。
社區級 Community level
ROS的社區級概念是ROS網絡上進行代碼發布的一種表現形式。結構如下圖所示:
代碼庫的聯合系統。使得協作亦能被分發。這種從文件系統級別到社區一級的設計讓獨立地發展和實施工作成為可能。正是因為這種分布式的結構,似的ROS迅速發展,軟件倉庫中包的數量指數級增加。
文件系統工具
代碼分布在許多ROS packages中,用命令行工具比如ls和cd去尋找起來非常的枯燥,這就是為什么提供ROS工具去幫助你的原因。
rospack
rospack可以看到許多packages的信息。這里我們以find選項為例,用來返回package的路徑。用法:
$ rospack find [package_name]
例子:
$ rospack find roscpp
返回:
/opt/ros/indigo/share/roscpp
roscd
roscd是rosbash套件的一部分,可以用來改變當前工作目錄。
用法:
$ roscd [location_name[/subdir]]
例子:
$ roscd roscpp
可以用Unix命令打印絕對路徑:
$ pwd
可以看到:
/opt/ros/indigo/share/roscpp
注意:roscd和其它ros工具只會在ROS_PACKAGE_PATH中指定了的目錄中才能找到ROS packages,查看ROS_PACKAGE_PATH,可以用命令:
$ echo $ROS_PACKAGE_PATH
ROS_PACKAGE_PATH中有許多用冒號分開的路徑,看起來像:
/home/ros/catkin_ws/src:/opt/ros/indigo/share:/opt/ros/indigo/stacks
roscd命令也可以進入packages或者stack的子目錄
$ roscd roscpp/cmake
輸出:
/opt/ros/indigo/share/roscpp/cmake
roscd log
roscd log命令可以進入ROS儲存log文件的文件夾。注意如果你至今還沒有運行任何ros程序,那么會出現錯誤說命令不存在。
如果你之前已經運行過一些ros程序,可以運行:
$ roscd log
rosls
rosls是rosbash套件的一部分,可以列出一個packages中的目錄。
用法:
$ rosls [location_name[/subdir]]
例子:
$ rosls roscpp_tutorials
返回:
cmake package.xml srv
回顧
不難發現ros工具的名字都是在對應的UNIX命令的前面加上一個ros:
- rospack = ros + pack(age)
- roscd = ros + cd
- rosls = ros + ls
現在你可以在ROS中到天馬行空了,讓我們一起創建一個package吧。