摘要
ROS機器人操作系統在機器人應用領域很流行,依托代碼開源和模塊間協作等特性,給機器人開發者帶來了很大的方便。我們的機器人“miiboo”中的大部分程序也采用ROS進行開發,所以本文就重點對ROS基礎知識進行詳細的講解,給不熟悉ROS的朋友起到一個拋磚引玉的作用。本章節主要內容:
2.ROS系統整體架構
由於ROS系統的組織架構比較復雜,簡單從一個方面來說明很難說清楚。按照ROS官方的說法,我們可以從3個方面來理解ROS系統整體架構,這3個方面分別是文件系統級、計算圖級、開源社區級。
2.1.從文件系統級理解ROS架構
如果你是剛剛接手ROS方面的開發或項目,你肯定會覺得ROS中的各種概念非常奇怪,但是當你對ROS的使用熟練之后,你就覺得這些概念很好理解了。與其他操作系統相似,一個ROS程序的不同組件要被放在不同的文件夾下,這些文件夾是根據不同的功能來對文件進行組織的,如圖3。
(圖3)文件系統級理解ROS架構
(1)工作空間
工作空間是一個包含功能包、可編輯源文件和編譯包的文件夾,當你想同時編譯不同的功能包時非常有用,並且可以保存本地開發包。當然,用戶可以根據自己的需要創建多個工作空間,在每個工作空間中開發不同用途的功能包。不過作為學習,我們先以一個工作空間為例。如圖3,我們創建了一個名為catkin_ws的工作空間,該工作空間下會有3個文件夾:src、build、devel。
src源文件空間:這個文件夾放置各個功能包和一個用於這些功能包的CMake配置文件CMakeLists.txt。這里做一下說明,由於ROS中的源碼采用catkin工具進行編譯,而catkin工具又是基於cmake技術的,所以我們會在src源文件空間和各個功能包中都會見到一個文件CMakeLists.txt,這個文件就是起編譯配置的作用。
build編譯空間:這個文件夾放置CMake和catkin編譯功能包時產生的緩存、配置、中間文件等。
devel開發空間:這個文件夾放置編譯好的可執行程序,這些可執行程序是不需要安裝就能直接運行的。一旦功能包源碼編譯和測試通過后,可以將這些編譯好的可執行文件直接導出與其他開發人員分享。
(2)功能包
功能包是ROS中軟件組織的基本形式,一個功能包具有用於創建ROS程序的最小結構和最少內容,它可以包含ROS運行的進程(節點)、配置文件等。如圖3,一個功能包中主要包含這幾個文件:
CMakeLists.txt功能包配置文件:用於這個功能包cmake編譯時的配置文件。
package.xml功能包清單文件:用xml的標簽格式標記這個功能包的各類相關信息,比如包的名稱、依賴關系等。主要作用是為了更容易的安裝和分發功能包。
include/<package_name>功能包頭文件目錄:你可以把你的功能包程序包含的*.h頭文件放在這里,include下之所以還要加一級路徑<package_name>是為了更好的區分自己定義的頭文件和系統標准頭文件,<package_name>用實際功能包的名稱替代。不過這個文件夾不是必要項,比如有些程序沒有頭文件的情況。
msg非標准消息定義目錄:消息是ROS中一個進程(節點)發送到其他進程(節點)的信息,消息類型是消息的數據結構,ROS系統提供了很多標准類型的消息可以直接使用,如果你要使用一些非標准類型的消息,就需要自己來定義該類型的消息,並把定義的文件放在這里。不過這個文件夾不是必要項,比如程序中只使用標准類型的消息的情況。
srv服務類型定義目錄:服務是ROS中進程(節點)間的請求/響應通信過程,服務類型是服務請求/響應的數據結構,服務類型的定義放在這里。如果要調用此服務,你需要使用該功能包名稱和服務名稱。不過這個文件夾不是必要項,比如程序中不使用服務的情況。
scripts可執行腳本文件存放目錄:這里用於存放bash、python或其他腳本的可執行文件。不過這個文件夾不是必要項,比如程序中不使用可執行腳本的情況。
launch文件目錄:這里用於存放*.launch文件,*.launch文件用於啟動ROS功能包中的一個或多個節點,在含有多個節點啟動的大型項目中很有用。不過這個文件夾不是必要項,節點也可以不通過launch文件啟動。
src功能包中節點源文件存放目錄:一個功能包中可以有多個進程(節點)程序來完成不同的功能,每個進程(節點)程序都是可以單獨運行的,這里用於存放這些進程(節點)程序的源文件,你可以在這里再創建文件夾和文件來按你的需求組織源文件,源文件可以用c++、python等來書寫。
為了創建、修改、使用功能包,ROS給我們提供了一些實用的工具,常用的有下面這些工具。
rospack:用於獲取信息或在系統中查找工作空間。
catkin_create_pkg:用於在工作空間的src源空間下創建一個新的功能包。
catkin_make:用於編譯工作空間中的功能包。
rosdep:用於安裝功能包的系統依賴項。
rqt_dep:用於查看功能包的依賴關系圖。
關於這些工具命令的具體使用方法,會在后面的章節中結合實例進行具體的講解。這里只是先介紹給大家,讓大家有個概念上的了解,感興趣的朋友也可以自己上網了解這些命令的具體用法。
(3)消息
消息是ROS中一個進程(節點)發送到其他進程(節點)的信息,消息類型是消息的數據結構,ROS系統提供了很多標准類型的消息可以直接使用,如果你要使用一些非標准類型的消息,就需要自己來定義該類型的消息。
ROS使用了一種精簡的消息類型描述語言來描述ROS進程(節點)發布的數據值。通過這種描述語言對消息類型的定義,ROS可以在不同的編程語言(如c++、python等)書寫的程序中使用此消息。不管是ROS系統提供的標准類型消息,還是用戶自定義的非標准類型消息,定義文件都是以*.msg作為擴展名。消息類型的定義分為兩個主要部分:字段的數據類型和字段的名稱,簡單點說就是結構體中的變量類型和變量名稱。比如下面的一個示例消息定義文件example.msg的內容,如圖4,int32、float32、string就是字段的數據類型,id、vel、name就是字段的名稱。
(圖4)一個示例消息定義文件
在大多數情況下,我們都可以使用ROS系統提供的標准類型的消息來完成任務,這得益於ROS系統提供了豐富的標准類型的消息。經常用到的類型包括:基本類型(std_msgs)、通用類型(sensor_msgs、geometry_msgs、nav_msgs、actionlib_msgs),如圖5。
(圖5)ROS系統提供的常用標准類型的消息
不難發現std_msgs下面定義的是經ROS封裝后的最基本的數據類型,比如Bool、Char、Int16等;sensor_msgs下面定義的是跟傳感器數據相關的數據類型,比如Image對應的就是攝像頭的數據類型,Imu對應的就是IMU傳感器的數據類型,LaserScan對應的就是激光雷達的數據類型,PointCloud對應的就是點雲掃描傳感器(如深度相機)的數據類型,Range對應的就是距離測量傳感器(如超聲波、紅外測距)的數據類型;geometry_msgs下定義的是跟幾何有關的數據類型,比如Pose用來描述機器人在空間的位姿,Quaternion用四元數描述空間方向,Transform用來描述不同坐標系之間的轉移關系,Twist用來描述機器人運動時的位姿、速度等狀態信息;nav_msgs下定義的是跟機器人導航相關的數據類型,比如OccupancyGrid是柵格地圖的數據類型,Odometry是機器人通過輪式碼盤或其他方式融合得到的里程計的數據類型,Path是路徑規划算法計算得到的導航路勁的數據類型;actionlib_msgs下定義的是actionlib控制過程相關的數據類型,比如GoalID描述發送出去的導航目標的ID號,GoalStatus描述執行導航目標過程的過程狀態信息。如果想了解更多ROS系統的消息類型的細節,最好的方式是去ROS wiki看官方的文檔,鏈接如下:
http://wiki.ros.org/common_msgs/
(4)服務
服務是ROS中進程(節點)間的請求/響應通信過程,服務類型是服務請求/響應的數據結構。服務類型的定義借鑒了消息類型的定義方式,所以這里就不在贅述了。區別在於,消息數據是ROS進程(節點)間多對多廣播式通信過程中傳遞的信息;服務數據是ROS進程(節點)間點對點的請求/響應通信過程傳遞的信息。
2.2.從計算圖級理解ROS架構
ROS會創建一個連接所有進程(節點)的網絡,其中的任何進程(節點)都可以訪問此網絡,並通過該網絡與其他進程(節點)交互,獲取其他進程(節點)發布的信息,並將自身數據發布到網絡上,這個計算圖網絡中的節點(node)、主題(topic)、服務(server)等都要有唯一的名稱做標識,如圖6。
(圖6)計算圖級理解ROS架構
(1)節點
節點是主要的計算執行進程,功能包中創建的每個可執行程序在被啟動加載到系統進程中后,該進程就是一個ROS節點,如圖6中的node1、node2、node3等都是節點(node)。節點都是各自獨立的可執行文件,能夠通過主題(topic)、服務(server)或參數服務器(parameter server)與其他節點通信。ROS通過使用節點將代碼和功能解耦,提高了系統的容錯力和可維護性。所以你最好讓每一個節點都具有特定的單一的功能,而不是創建一個包羅萬象的大節點。節點如果用c++進行編寫,需要用到ROS提供的庫roscpp;節點如果用python進行編寫,需要用到ROS提供的庫rospy。
ROS提供了處理節點的工具,用於節點信息、狀態、可用性等的查詢操作,例如可以用下面的命令對正在運行的節點進行操作。
rosnode info <node_name>:用於輸出當前節點信息。
rosnode kill <node_name>:用於殺死正在運行節點進程來結束節點的運行。
rosnode list:用於列出當前活動的節點。
rosnode machine <hostname>:用於列出指定計算機上運行的節點。
rosnode ping <node_name>:用於測試節點間的網絡連通性。
rosnode cleanup:用於將無法訪問節點的注冊信息清除。
關於這些工具命令的具體使用方法,會在后面的章節中結合實例進行具體的講解。這里只是先介紹給大家,讓大家有個概念上的了解,感興趣的朋友也可以自己上網了解這些命令的具體用法。
(2)消息
節點通過消息(message)完成彼此的溝通。消息包含一個節點發送給其他節點的信息數據。關於消息類型的知識在前面已經講述了,這里就不再展開。
ROS提供了獲取消息相關信息的命令工具,這里列舉出一些常用的命令,來具體看看吧。
rosmsg show <message_type>:用於顯示一條消息的字段。
rosmsg list:用於列出所有消息。
rosmsg package <package _name>:用於列出功能包的所有消息。
rosmsg packages:用於列出所有具有該消息的功能包。
rosmsg users <message_type>:用於搜索使用該消息類型的代碼文件。
rosmsg md5 <message_type>:用於顯示一條消息的MD5求和結果。
關於這些工具命令的具體使用方法,會在后面的章節中結合實例進行具體的講解。這里只是先介紹給大家,讓大家有個概念上的了解,感興趣的朋友也可以自己上網了解這些命令的具體用法。
(3)主題
每個消息都必須發布到相應的主題(topic),通過主題來實現在ROS計算圖網絡中的路由轉發。當一個節點發送數據時,我們就說該節點正在向主題發布消息;節點可以通過訂閱某個主題,接收來自其他節點的消息。通過主題進行消息路由不需要節點之間直接連接,這就意味着發布者節點和訂閱者節點之間不需要知道彼此是否存在,這樣就保證了發布者節點與訂閱者節點之間的解耦合。同一個主題可以有多個訂閱者也可以有多個發布者,不過要注意必須使用不同的節點發布同一個主題。每個主題都是強類型的,不管是發布消息到主題還是從主題中訂閱消息,發布者和訂閱者定義的消息類型必須與主題的消息類型相匹配。
ROS提供了操作主題的命令工具,這里列舉出一些常用的命令,來具體看看吧。
rostopic bw </topic_name>:用於顯示主題所使用的帶寬。
rostopic echo </topic_name>:用於將主題中的消息數據輸出到屏幕。
rostopic find <message_type>:用於按照消息類型查找主題。
rostopic hz </topic_name>:用於顯示主題的發布頻率。
rostopic info </topic_name>:用於輸出活動主題、發布的主題、主題訂閱者和服務的信息。
rostopic list:用於列出當前活動主題的列表。
rostopic pub </topic_name> <message_type> <args>:用於通過命令行將數據發布到主題。
rostopic type </topic_name>:用於輸出主題中發布的消息類型。
關於這些工具命令的具體使用方法,會在后面的章節中結合實例進行具體的講解。這里只是先介紹給大家,讓大家有個概念上的了解,感興趣的朋友也可以自己上網了解這些命令的具體用法。
(4)服務
在一些特殊的場合,節點間需要點對點的高效率通信並及時獲取應答,這個時候就需要用服務的方式進行交互。提供服務的節點叫服務端,向服務端發起請求並等待響應的節點叫客戶端,客戶端發起一次請求並得到服務端的一次響應,這樣就完成了一次服務通信過程,例如圖6中,node1向node3發起一次請求,並得到node3返回給node1的響應。服務通信過程中服務的數據類型需要用戶自己定義,與消息不同,節點並不提供標准服務類型。服務類型的定義文件都是以*.srv為擴展名,並且被放在功能包的srv/文件夾下。
ROS提供了操作服務的命令工具,這里列舉出一些常用的命令,來具體看看吧。
rosservice call </service_name> <args>:用於通過命令行參數調用服務。
rosservice find <service_type>:用於根據服務類型查詢服務。
rosservice info </service_name>:用於輸出服務信息。
rosservice list:用於列出活動服務清單。
rosservice type </service_name>:用於輸出服務類型。
rosservice uri </service_name>:用於輸出服務的ROSRPC URI。
關於這些工具命令的具體使用方法,會在后面的章節中結合實例進行具體的講解。這里只是先介紹給大家,讓大家有個概念上的了解,感興趣的朋友也可以自己上網了解這些命令的具體用法。
(5)節點管理器
節點管理器(master)用於節點的名稱注冊和查找等,也負責設置節點間的通信。如果在你的整個ROS系統中沒有節點管理器,就不會有節點、消息、服務之間的通信。由於ROS本身就是一個分布式的網絡系統,所以你可以在某台計算機上運行節點管理器,在這台計算機和其他台計算機上運行節點。
ROS中提供了跟節點管理器相關的命令行工具,就是roscre。
roscore:用於啟動節點管理器,這個命令會加載ROS節點管理器和其他ROS核心組件。
關於這些工具命令的具體使用方法,會在后面的章節中結合實例進行具體的講解。這里只是先介紹給大家,讓大家有個概念上的了解,感興趣的朋友也可以自己上網了解這些命令的具體用法。
(6)參數服務器
參數服務器(parameter server)能夠使數據通過關鍵詞存儲在一個系統的核心位置。通過使用參數,就能夠在節點運行時動態配置節點或改變節點的工作任務。參數服務器是可通過網絡訪問的共享的多變量字典,節點使用此服務器來存儲和檢索運行時的參數。
ROS中關於參數服務器的命令行工具,請看下面的常用命令。
rosparam list:用於列出參數服務器中的所有參數。
rosparam get <parameter_name>:用於獲取參數服務器中的參數值。
rosparam set <parameter_name> <value>:用於設置參數服務器中參數的值。
rosparam delete <parameter_name>:用於將參數從參數服務器中刪除。
rosparam dump <file>:用於將參數服務器的參數保存到一個文件。
rosparam load <file>:用於從文件將參數加載到參數服務器。
關於這些工具命令的具體使用方法,會在后面的章節中結合實例進行具體的講解。這里只是先介紹給大家,讓大家有個概念上的了解,感興趣的朋友也可以自己上網了解這些命令的具體用法。
(7)消息記錄包
消息記錄包(bag)是一種用於保存和回放ROS消息數據的文件格式。消息記錄包是一種用於存儲數據的重要機制,它可以幫助記錄一些難以收集的傳感器數據,然后通過反復回放數據進行算法的性能開發和測試。ROS創建的消息記錄包文件以*.bag為擴展名,通過播放、停止、后退操作該文件,可以像實時會話一樣在ROS中再現情景,便於算法的反復調試。
ROS提供消息記錄包相關的命令行工具,請看下面的常用命令。
rosbag <args>:用來錄制、播放和執行操作。
關於這些工具命令的具體使用方法,會在后面的章節中結合實例進行具體的講解。這里只是先介紹給大家,讓大家有個概念上的了解,感興趣的朋友也可以自己上網了解這些命令的具體用法。
2.3.從開源社區級理解ROS架構
ROS開源社區級的概念主要是ROS資源,即通過各個獨立的網絡社區分享ROS方面的軟件和知識。
(1)ROS發行版
ROS發行版跟Linux發行版起類似的作用,ROS發行版是內置了一系列常用功能包的ROS系統安裝包,可以被直接安裝到我們的操作系統中。如圖7,是ROS的各個發行版。
(圖7)ROS的各個發行版
(2)ROS軟件代碼庫
ROS依賴於開源或共享軟件的源代碼,這些代碼由不同的機構共享與發布,比如github源碼共享,ubuntu軟件倉庫等等。如圖8,是ROS軟件代碼庫的社區組織形式。
(圖8)ROS軟件代碼庫的社區組織形式
(3)ROS文檔社區
ROS wiki是記錄有關ROS系統各種文檔的主要論壇社區,任何人都可以注冊賬戶、貢獻自己的文件、提供更正或更新、編寫教程及其他行為。感興趣可以進入ROS wiki的主頁面瞧瞧http://wiki.ros.org/。
(4)ROS問答社區
ROS開發者可以通過這個資源去提問和尋找ROS相關的答案,ROS Answer主頁面
后記
------SLAM+語音機器人DIY系列【目錄】快速導覽------
第1章:Linux基礎
第2章:ROS入門
第3章:感知與大腦
第4章:差分底盤設計
第5章:樹莓派3開發環境搭建
第6章:SLAM建圖與自主避障導航
2.google-cartographer機器人SLAM建圖
第7章:語音交互與自然語言處理
第8章:高階拓展
2.centos7下部署Django(nginx+uwsgi+django+python3)
----------------文章將持續更新,敬請關注-----------------
如果大家對博文的相關類容感興趣,或有什么技術疑問,歡迎加入下面的《SLAM+語音機器人DIY》QQ技術交流群,一起討論學習^_^
關於我們:
視頻教程: