本文主要是了解ROS的系統架構、文件夾結構以及工作所需的核心文件。
ROS系統架構主要被設計和划分為三部分,每一部分代表一個層級的概念:文件系統級(The filesystem level)、計算圖級(The computation graph level)、開源社區級(The community level)。
一、理解ROS文件系統級
與其他操作系統類似,一個ROS程序的不同組件要被放在不同的文件夾下。這些文件夾是根據功能的不同來對文件進行組織的:
- 功能包(Package):功能包是ROS中軟件組織的基本形式。一個功能包具有用於創建ROS程序的最小結構和最少內容。它可以包含ROS運行的進程(節點)、配置文件等;
- 功能包清單(Package Manifest):功能包清單提供關於功能包、許可信息、依賴關系、編譯標志等的信息。一個包的清單有一個名為package.xml的文件管理;
- 綜合功能包(Metapackage):將幾個具有某些功能的功能包組織在一起,就獲得了一個綜合功能包(Stack)。
- 消息類型(Message(msg) type):消息是一個節點發送到其他節點的信息。ROS系統有很多的標准消息類型。消息類型的說明存儲在對應功能包的msg文件夾下。
- 服務類型(Servic(src) type):服務描述說明存儲在對應功能包的src文件夾下,定義了在ROS中由每個進程提供的關於服務請求和響應的數據結構。
1.1 工作空間
工作空間就是一個包含功能包、可編輯源文件或編譯包的文件夾。當想同時編譯不同的功能包時非常有用,並且可以用來保存本地開發包,一般包含src、bulid和devel這三個文件夾。
- 源文件空間(src文件夾):在源文件空間放置了功能包、項目、克隆包等。在這個空間中最重要的是CMakefile.txt。當你在工作空間中配置功能包時,src文件夾CMakefile.txt調用CMake。
- 編譯空間(build文件夾):在build文件夾里,CMake和catkin為功能包和項目保存緩存信息、配置和其他中間文件。
- 開發空間(devel文件夾):devel文件夾用來保存編譯后的程序,這些是無需安裝就能用來測試的程序。
1.2 功能包
功能包指的是一種特定的文件結構和文件夾組合。這種結果如下所示:
- include/package_name/:此目錄包含了你需要的庫的頭文件。
- msg/:如果你要開發非標准消息,請把文件放在這里。
- script/:其中包括Bash、Pytho或其他任何腳本的可執行腳本文件。
- src/:這是存儲程序源文件的地方。你可能會為節點在此創建一個文件夾。
- CMakefile.txt:這是CMake的生成文件。
- package.xml:這是功能包清單文件。
功能包的目錄結構圖如下圖所示:
CMakeLists.txt 文件的內容結構圖如下圖所示:
package.xml 文件的內容結構圖如下圖所示:
功能包還能配置launch文件,launch文件編寫規則如下圖所示:
為了創建、修改或使用功能包,ROS給我們提供了一些工具:
- rospack find [package_name] 使用此命令可以返回功能包的路徑信息
- catkin_create_pkg 用於創建一個新的功能包
- catkin_make 用於編譯工作空間
- rosdep 此命令安裝功能包的系統依賴項
- rqt_dep 用來查看功能包的依賴關系圖
若要在文件夾和功能包之間移動文件,ROS提供了非常有用的rosbash功能包,其中包含了一些非常類似於LInux命令的命令,例如:
- roscd 此命令用來更改目錄
- rosed 此命令用來編輯文件
- roscp 此命令用於從一些功能包復制文件
- roscd 此命令列出功能包的目錄
- rosls 此命令列出功能包下的文件
1.3 綜合功能包
綜合功能包是一些只有一個package.xml文件的特定包,它不包含其他文件,如代碼等。綜合功能包用於引用其他功能特性類似的功能包,例如導航包、ros_tutorials等。
如果你想定位 ros_tutorials 綜合功能包,可以使用下面的命令:
rosstack find ros_tutorials
顯示路徑為: /opt/ros/indigo/share/ros_tutorials
。
1.4 消息
ROS使用了一種簡化的消息類型描述語言來描述ROS節點發布的數據值。通過這樣的描述語言,ROS能夠使用多種編程語言生成不同類型消息的源代碼。
ROS提供了很多預定義消息類型。如果你創建了一種新的消息類型,那么就要把消息的類型定義放到功能包的msg文件夾下。在該文件夾中,有用於定義各種消息的文件。這些文件都以.msg為擴展名。
消息類型必須具有兩個主要部分:字段和常量。字段定義了要在消息中傳輸的數據類型,例如int32、string或之前創建的新類型。常量用於定義字段的名稱。
在ROS中有一些處理消息的工具。例如 rosmsg 命令行工具能夠輸出消息定義信息,並可以找到使用該消息類型的源文件。
1.5 服務
ROS使用了一種簡化的服務描述語言來描述ROS的服務類型。這直接借鑒了ROS msg消息的數據格式,以實現節點之間的請求/響應通信。服務的描述存儲在功能包的 srv/ 子目錄下 .srv 文件中。
若要調用服務,你需要使用該功能包的名稱及服務名稱。例如 sample_package/srv/sample.srv 文件,可以把它稱為 sample_package1/sample1 服務。
ROS中有一些執行服務的工具。rossrv 工具能輸出服務說明、.srv 文件所在的功能包名稱,並可以找到使用某一服務類型的源代碼文件。
如果你想要在ROS中創建一個服務,可以使用服務生成器。這些工具能夠從基本的服務說明中生成代碼。你只需要在 CMakefile.txt 文件中加一行 gensrv() 命令。
二、理解ROS計算圖級
ROS會創建一個連接到所有進程的網絡。在系統中的任何節點都可以訪問此網絡,並通過該網絡與其他節點交互,獲取其他節點發布的信息,並且將自身數據發布到網絡上。如下圖所示:
在這一層級中最基本的概念包括節點、節點管理器、參數服務器、消息、服務、主題和消息記錄,這些概念都以不同的方式向計算圖級提供數據:
- 節點(Node) 節點是主要的計算執行進程。最好讓每一個節點都具有特定的單一的功能,而不是創建一個包羅萬象的大節點。節點需要使用如 roscpp 或 rospy 的ROS客戶端進行編寫。
- 節點管理器(Master) 節點管理器向ROS系統中其他節點提供命名和注冊服務。它像服務一樣追蹤主題的發布者和訂閱者。節點管理器的作用是使節點之間能夠互相查找。一旦這些節點找到了彼此,就能建立點對點的通信。
- 參數服務器(Parameter Server) 參數服務器是可通過網絡訪問的共享的多變量字典。節點使用此服務器來存儲和檢索運行時的參數。
- 消息(Message) 節點通過消息完成彼此的溝通。消息包括一個節點發生到其他節點的信息數據。ROS中包括很多種標准類型的消息,同時你也可以基於標准消息開發自定義類型的消息。
- 主題(Topic) 每個消息都必須有一個名稱來被ROS網絡路由。每一條消息都要發布到相應的主題。當一個節點發送數據時,我們就說該節點正在向主題發布消息。節點可以通過訂閱某個主題,接受來自其他節點的消息。主題的名稱必須是獨一無二的,否則在同名主題之間的消息路由就會發生錯誤。
- 服務(Service) 當你需要直接與節點通信並獲得應答時,將無法通過主題實現,從而需要服務。此外,服務必須有唯一的名稱。當一個節點提供某個服務時,所有的節點都可以通過使用ROS客戶端編寫的代碼與它通信。
- 消息記錄包(Bag) 消息記錄包是一種用於保存和回收ROS消息數據的文件格式(.bag)。它能夠獲取並記錄各種難以收集的傳感器數據。我們可以通過消息記錄包反復獲取實驗數據,進行必要的開發和算法測試。在使用復雜機器人進行實驗工作時,需要經常使用消息記錄包。
2.1 節點(Node)
ROS有另一種類型的節點,稱為 nodelet。這類特殊節點可以在單個進程中運行多個節點,其中每個 nodelet 為一個線程(輕量級進程)。這樣,可以在不使用ROS網絡的情況下與其他節點通信,通信效率更高,並避免網絡堵塞。nodelet 對於攝像頭和3D傳感器這類數據傳輸量非常大的設備特別有用。
ROS提供了處理節點的工具,如rosnode。用rosnode -h
命令,可以查看此工具的所有支持命令:
- rosnode info [node_name] 輸出當前節點信息
- rosnode kill [node_name] 結束當前運行節點進程或發送給定信號
- rosnode list 列出當前活動節點
- rosnode machine hostname 列出某一特定計算機上運行的節點或列出主機名稱
- rosnode ping [node_name] 測試節點間的連通性
- rosnode cleanup 將無法訪問節點的注冊信息清除
使用某個節點時,只需要寫出包名和節點名字就可以調用節點,不需要寫路徑。
$ rosrun [package_name] [node_name]
修改節點的名字可以直接在命令行進行(同時可以運行該節點做其他任務):
$ rosrun turtlesim turtlesim_node __name:=my_turtle
更改節點中的參數,只需要在參數名稱前添加一個下划線,例如將參數(param)就設置為浮點數9.0:
$ rosrun book_tutorials tutorialx _param:=9.0
2.2 主題(Topic)
一個主題可以有多個訂閱者也可以有多個發布者,但是需要注意用不同的節點發布同樣的主題,否則會產生沖突。
每個主題都是強類型的,發布到主題上的消息必須與主題的ROS消息類型相匹配,並且節點只能接受類型匹配的消息。節點要想訂閱主題,就必須具有相同的消息類型。
ROS的主題可以使用 TCP/IP 和 UDP 傳輸。基於 TCP 傳輸稱為 TCPROS,它使用 TCP/IP 長連接。這是ROS默認的傳輸方式。
基於 UDP 傳輸稱為 UDPROS,它是一種低延遲高效率的傳輸方式,但可能產生數據丟失。所以它適合像遠程操控的任務。
ROS有一個 rostopic 工具用於主題操作。使用rostopic -h
命令,可以查看此工具的所有支持命令:
- rostopic echo [/topic_name] 將消息輸出到屏幕
- rostopic find message_type 按照類型查找主題
- rostopic info [/topic_name] 輸出活動主題、發布的主題、主題訂閱者和服務的信息
- rostopic list 輸出活動主題的列表
- rostopic pub [/topic_name] [type] [args] 將數據發布到主題。它允許我們直接從命令行中對任意主題創建和發布數據。
- rostopic type [/topic_name] 輸出主題的類型,或者說主題中發布的消息類型
- rostopic hz [/topic_name] 顯示主題的發布頻率
- rostopic bw [/topic_name] 顯示主題所使用的帶寬
2.3 服務(Service)
當你需要直接與節點通信並獲得應答時,將無法通過主題實現,從而需要服務。服務需要由用戶開發,節點並不提供標准服務。包含服務源代碼的文件存儲在 srv 文件夾中。
像主題一樣,服務關聯一個以功能包中 .srv 文件名稱來命名的服務類型。與其他基於ROS文件系統的類型一樣,服務類型是功能包名稱和 .srv 文件名稱的組合。例如 chapter2_tutorials/srv/chapter2srv1.srv 文件的服務類型是 chapter2_tutorials/chapter2srv1。
ROS關於服務的命令行工具有兩個:rossrv 和 rosservice。我們可以通過 rossrv 看到有關服務數據結構的信息,並且與 rosmsg 具有完全一致的用法。使用rosservice -h
命令,可以查看此工具的所有支持命令:
- rosservice args [/service_name] 打印服務參數
- rosservice call [/service_name] args 根據命令行參數調用服務
- rosservice find [msg-type] 根據服務類型查詢服務
- rosservice info [/service_name] 輸出服務信息
- rosservice list 輸出活動服務清單
- rosservice type [/service_name] 輸出服務類型
- rosservice uri [/service_name] 輸出服務的ROSRPC URI
2.4 消息(Message)
消息的類型在ROS中按照以下標准命名方式進行約定:功能包名稱 /.msg 文件名稱。例如,std_msgs/msg/String.msg 的消息類型是 std_msgs/String。
ROS有一個 rosmsg 工具用於消息操作。使用rosmsg -h
命令,可以查看此工具的所有支持命令:
- rosmsg show 顯示一條消息的字段
- rosmsg list 列出所有消息
- rosmsg package 列出功能包的所有消息
- rosmsg packages 列出所有具有該消息的功能包
- rosmsg md5 顯示一條消息的MD5求和結果
2.5 消息紀錄包
消息紀錄包是由ROS創建的一組文件。它使用 .bag 格式保存消息、主題、服務和其他ROS數據信息。你可以在事件發生后,通過使用可視化工具調用和回放數據,檢查在系統中到底發生了什么。
若要使用紀錄包文件,我們可以使用以下ROS工具:
- rosbag 用來錄制、播放和執行其他操作
- rqt_bag 用來可視化圖形環境中的數據
2.6 節點管理器
節點管理器通常使用 roscore 命令運行,它會加載ROS節點管理器及其他ROS核心組件。
2.7 參數服務器
參數服務器使用 XMLRPC 數據類型為參數賦值,包括以下類型:
- 32位整數(32-bit integer)
- 布爾值(Boolean)
- 字符串(String)
- 雙精度浮點(Double)
- 列表(List)
ROS中關於參數服務器的工具是 rosparam。使用'rosparam -h'命令,可以查看此工具的所有支持命令:
- rosparam list 列出了服務器中的所有參數
- rosparam get [parameter] 獲取參數值
- rosparam set [parameter] [value] 設置參數值
- rosparam delete [parameter] 刪除參數
- rosparam dump file 將參數服務器保存到一個文件
- rosparam load file 加載參數文件到參數服務器
三、理解ROS開源社區級
ROS開源社區級的概念主要是ROS資源,其能夠通過獨立的網絡社區分享軟件和知識。這些資源包括:
- 發行版
- 軟件庫
- ROS維基
- Bug提交系統
- 郵件列表
- ROS問答
- 博客