機器人作業系統

ROS（Robot Operating System，一般譯為機器人操作系統），是專為機器人軟體開發所設計出來的一套電腦作業系統架構。它是一個開源的元級操作系統（後操作系統），提供類似於操作系統的服務，包括硬件抽象描述、底層驅動程序管理、共用功能的執行、程序間消息傳遞、程序發行包管理，它也提供一些工具和庫用於獲取、建立、編寫和執行多機融合的程序。
ROS的運行架構是一種使用ROS通信模塊實現模塊間P2P的松耦合的網絡連接的處理架構，它執行若干種類型的通訊，包括：
# 基於服務的同步RPC（遠程過程調用）通訊；
# 基於Topic的異步數據流通訊，還有參數服務器上的數據存儲。

**發展目標**
ROS的首要設計目標是在機器人研發領域提高代碼複用率。ROS是一種分佈式處理框架（又名Nodes）。這使可執行文件能被單獨設計，並且在運行時鬆散耦合。這些過程可以封裝到數據包（Packages）和堆棧（Stacks）中，以便於共享和分發。ROS還支持代碼庫的聯合系統。使得協作亦能被分發。這種從文件系統級別到社區一級的設計讓獨立地決定發展和實施工作成為可能。上述所有功能都能由ROS的基礎工具實現。
為了實現“共享與協作”這一首要目標，人們制訂了ROS架構中的其他支援性目標：- “輕便”：ROS是設計得儘可能方便簡易。不必替換主框架與系統，因為ROS編寫的代碼可以用於其他機器人軟件框架中。毫無疑問的，ROS更易於集成與其他機器人軟件框架。事實上ROS已完成與OpenRAVE、Orocos和Player的整合。- ROS-agnostic庫：建議的開發模型是使用clear的函數接口書寫ROS-agnostic庫。- 語言獨立性：ROS框架很容易在任何編程語言中執行。目前已經能在Python和C++中順利運行，同時添加有Lisp、Octave和Java語言庫。- 測試簡單：ROS有一個內建的單元/組合集測試框架，稱為“rostest”。這使得集成調試和分解調試很容易。- 擴展性：ROS適合於大型即時系統與大型的系統開發項目。

**ROS的概念**
ROS有三個層次的概念：分別為Filesystem level，Computation graph level， 以及Communication level。 以下內容具體的總結了這些層次及概念。除了這三個層次的概念， ROS也定義了兩種名稱-- Package資源名稱和Graph資源名稱。同樣會在以下內容中提及。

**ROS 的 Filesystem Level**
文件系統層概念就是碟片裡的資源，例如：-  Packages date=20130528150703 ：ROS的基本組織，可以包含任意格式文件。一個Package 可以包含ROS執行時處理的文件（nodes），一個ROS的依賴庫，一個數據集合，配置文件或一些有用的文件在一起。-  Manifests date=20130516012241 ：Manifests (manifest.xml) 提供關於Package元數據，包括它的許可信息和Package之間依賴關係，以及語言特性信息像編譯旗幟（編譯優化參數）。-  Stacks date=20130518205902 : Stacks 是Packages的集合，它提供一個完整的功能，像“navigation stack” Stack與版本號關聯，同時也是如何發行ROS軟件方式的關鍵。-  Manifest Stack Manifestsfix-attempted=yes : Stack manifests (stack.xml) 提供關於Stack元數據，包括它的許可信息和Stack之間依賴關係。-  Message (msg) types date=20130115093850 : 信息描述, 位置在路徑：my_package/msg/MyMessageType.msg, 定義數據類型在ROS的 messages ROS裡面。-  Service (srv) types date=20100626010530 : 服務描述,位置在路徑：my_package/srv/MyServiceType.srv, 定義這個請求和相應的數據結構 在ROS services 裡面。

**ROS 的 Computation Graph Level**
Computation Graph Level（計算圖）就是用ROS的P2P（peer-to-peer網絡傳輸協議）網絡集中處理所有的數據。基本的Computation Graph的概念包括Node， Master， Parameter Server，messages, services, topics， 和bags， 以上所有的這些都以不同的方式給Graph傳輸數據。-  Nodes date=20130731070219 : Nodes（節點）是一系列運行中的程序。ROS被設計成在一定顆粒度下的模塊化系統。一個機器人控制系統通常包含許多Nodes。比如一個Node控制激光雷達，一個Node控制車輪馬達，一個Node處理定位，一個Node執行路徑規劃，另外一個提供圖形化界面等等。一個ROS節點是由 Libraries ROS client libraryfix-attempted=yes 寫成的, 例如  roscpp date=20130124102005  和  rospy date=20130729051729 . -  Master date=20130731063310 : ROS Master 提供了登記列表和對其他計算圖的查找。沒有Master，節點將無法找到其他節點，交換消息或調用服務。-  Server Parameter Serverfix-attempted=yes : 參數服務器使數據按照鍵的方式存儲。目前，參數服務器是Master的組成部分。-  Messages date=20130811063107 :節點之間通過messages來傳遞消息。一個message是一個簡單的數據結構，包含一些歸類定義的區。支持標準的原始數據類型（整數、浮點數、布爾數，等）和原始數組類型。message可以包含任意的嵌套結構和數組（很類似於C語言的結構structs）-  Topics date=20130501202116 : Messages以一種發佈/訂閱的方式傳遞。一個node可以在一個給定的topic中發佈消息。Topic是一個name被用於描述消息內容。一個node針對某個topic關注與訂閱特定類型的數據。可能同時有多個node發佈或者訂閱同一個topic的消息；也可能有一個node同時發佈或訂閱多個topic。總體上，發佈者和訂閱者不瞭解彼此的存在。主要的概念在於將信息的發佈者和需求者解耦、分離。邏輯上，topic可以看作是一個嚴格規範化的消息bus。每個bus有一個名字，每個node都可以連接到bus發送和接受符合標準類型的消息。-  Services date=20130501195259 :發佈/訂閱模型是很靈活的通訊模式，但是多對多，單向傳輸對於分佈式系統中經常需要的“請求/回應”式的交互來說並不合適。因此，“請求/回應” 是通過services來實現的。這種通訊的定義是一種成對的消息：一個用於請求，一個用於回應。假設一個節點提供了一個服務提供下一個 name date=20120823225830 和客戶使用服務發送請求消息並等待答覆。ROS的客戶庫通常以一種遠程調用的方式提供這樣的交互。-  Bags date=20130806091409 : Bags是一種格式，用於存儲和播放ROS消息。對於儲存數據來說Bags是一種很重要的機制。例如傳感器數據很難收集但卻是開發與測試中必須的。
在ROS的計算圖中，ROS的Master以一個name service的方式工作。它給ROS的節點存儲了topics和service的註冊信息。Nodes 與Master通信從而報告它們的註冊信息。當這些節點與master通信的時候，它們可以接收關於其他以註冊節點的信息並且建立與其它以註冊節點之間的聯繫。當這些註冊信息改變時Master也會回饋這些節點，同時允許節點動態創建與新節點之間的連接。
節點之間的連接是直接的； Master僅僅提供了查詢信息，就像一個DNS服務器。節點訂閱一個topic將會要求建立一個與發佈該topics的節點的連接，並且將會在同意連接協議的基礎上建立該連接。ROS裡面使用最廣的連接協議是TCPROS，這個協議使用標準的TCP/IP 接口。
這樣的架構允許解耦操作（decoupled operation），通過這種方式大型或是更為複雜的系統得以建立，其中names方式是一種行之有效的手段。names方式在ROS系統中扮演極為重要的角色： topics, services, and parameters 都有各自的names。每一個ROS客戶端庫都支持重命名，這等同於，每一個編譯成功的程序能夠以另一種形似【名字】運行。
例如，為了控制一個北陽激光測距儀（Hokuyo laser range-finder），可以啟動hokuyo_node 驅動，這個驅動可以給與激光儀進行對話並且在"掃描"topic下可以發佈sensor_msgs/LaserScan 的信息。為了處理數據，也許會寫一個使用laser_filters的node來訂閱"掃描"topic的信息。訂閱之後，過濾器將會自動開始接收激光儀的信息。注意兩邊是如何脫鉤工作的。 所有的hokuyo_node的節點都會完成發佈"掃描"，不需要知道是否有節點被訂閱了。所有的過濾器都會完成"掃描"的訂閱，不論知道還是不知道是否有節點在發佈"掃描"。 在不引發任何錯誤的情況下，這兩個nodes可以任何的順序啟動，終止，或者重啟。
以後也許會給機器人加入另外一個激光器，系統因此需要重新設置，所需要做的就是重新映射已經使用過的names。當開始的第一個hokuyo_node時，可以說它用base_scan代替了映射掃描，並且和過濾器節點做相同的事。現在，這些節點將會用base_scan的topic來通信從而代替,並且將不再監聽"掃描"topic的信息。然後就可以為新激光測距儀啟動另外一個hokuyo_node。

**參考文獻**
# http://www.ros.org/wiki/ros date=20130815074658 

**外部鏈接**
ROS官方網站 date=20171123064622