機器人作業系統

**ROS**（英語：Robot Operating System，一般譯為**機器人作業系統**），是專為機器人軟體開發所設計出來的一套電腦作業系統架構。它是一個開源的元級作業系統（後作業系統），提供類似於作業系統的服務，包括硬體抽象描述、底層驅動程序管理、共用功能的執行、程序間消息傳遞、程序發行包管理，它也提供一些工具和庫用於獲取、建立、編寫和執行多機融合的程序。

ROS 的運行架構是一種使用 ROS 通信模塊實現模塊間 P2P 的鬆耦合的網絡連接的處理架構，它執行若干種類型的通訊，包括：

1. 基於服務的同步 RPC（遠程過程調用）通訊；
2. 基於 Topic 的異步數據流通訊，還有參數伺服器上的數據存儲。

## 發展目標

ROS 的首要設計目標是在機器人研發領域提高代碼復用率。ROS 是一種分布式處理框架（又名 Nodes）。這使可執行文件能被單獨設計，並且在運行時鬆散耦合。這些過程可以封裝到數據包（Packages）和堆疊（Stacks）中，以便於共享和分發。ROS 還支持代碼庫的聯合系統。使得協作亦能被分發。這種從文件系統級別到社區一級的設計讓獨立地決定發展和實施工作成為可能。上述所有功能都能由 ROS 的基礎工具實現。

為了實現「共享與協作」這一首要目標，人們制訂了 ROS 架構中的其他支援性目標：

* 「輕便」：ROS 是設計得儘可能方便簡易。不必替換主框架與系統，因為 ROS 編寫的代碼可以用於其他機器人軟體框架中。毫無疑問的，ROS 更易於集成與其他機器人軟體框架。事實上 ROS 已完成與 OpenRAVE、Orocos 和 Player 的整合。
* ROS-agnostic 庫：【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 （頁面存檔備份，存於網際網路檔案館）：ROS 的基本組織，可以包含任意格式文件。一個 Package 可以包含 ROS 執行時處理的文件（nodes），一個 ROS 的依賴庫，一個數據集合，配置文件或一些有用的文件在一起。
* Manifests （頁面存檔備份，存於網際網路檔案館）：Manifests (manifest.xml) 提供關於 Package 元數據，包括它的許可信息和 Package 之間依賴關係，以及語言特性信息像編譯旗幟（編譯優化參數）。
* Stacks （頁面存檔備份，存於網際網路檔案館）: Stacks 是 Packages 的集合，它提供一個完整的功能，像「navigation stack」 Stack 與版本號關聯，同時也是如何發行 ROS 軟體方式的關鍵。
* Manifest Stack Manifests: Stack manifests (stack.xml) 提供關於 Stack 元數據，包括它的許可信息和 Stack 之間依賴關係。
* Message (msg) types （頁面存檔備份，存於網際網路檔案館）: 信息描述，位置在路徑：my\_package/msg/MyMessageType.msg, 定義數據類型在 ROS 的 messages ROS 裡面。
* Service (srv) types （頁面存檔備份，存於網際網路檔案館）: 服務描述，位置在路徑：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 （頁面存檔備份，存於網際網路檔案館）: Nodes（節點）是一系列運行中的程序。ROS 被設計成在一定顆粒度下的模塊化系統。一個機器人控制系統通常包含許多 Nodes。比如一個 Node 控制雷射雷達，一個 Node 控制車輪馬達，一個 Node 處理定位，一個 Node 執行路徑規劃，另外一個提供圖形化界面等等。一個 ROS 節點是由 Libraries ROS client library 寫成的，例如 roscpp （頁面存檔備份，存於網際網路檔案館） 和 rospy （頁面存檔備份，存於網際網路檔案館）.
* Master （頁面存檔備份，存於網際網路檔案館）: ROS Master 提供了登記列表和對其他計算圖的查找。沒有 Master，節點將無法找到其他節點，交換消息或調用服務。
* Server Parameter Server: 參數伺服器使數據按照鍵的方式存儲。目前，參數伺服器是 Master 的組成部分。
* Messages （頁面存檔備份，存於網際網路檔案館）: 節點之間通過 messages 來傳遞消息。一個 message 是一個簡單的資料結構，包含一些歸類定義的區。支持標準的原始數據類型（整數、浮點數、布爾數，等）和原始數組類型。message 可以包含任意的嵌套結構和數組（很類似於 C 語言的結構 structs）
* Topics （頁面存檔備份，存於網際網路檔案館）: Messages 以一種發布 / 訂閱的方式傳遞。一個 node 可以在一個給定的 topic 中發布消息。Topic 是一個 name 被用於描述消息內容。一個 node 針對某個 topic 關注與訂閱特定類型的數據。可能同時有多個 node 發布或者訂閱同一個 topic 的消息；也可能有一個 node 同時發布或訂閱多個 topic。總體上，發布者和訂閱者不了解彼此的存在。主要的概念在於將信息的發布者和需求者解耦、分離。邏輯上，topic 可以看作是一個嚴格規範化的消息 bus。每個 bus 有一個名字，每個 node 都可以連接到 bus 發送和接受符合標準類型的消息。
* Services （頁面存檔備份，存於網際網路檔案館）: 發布 / 訂閱模型是很靈活的通訊模式，但是多對多，單向傳輸對於分布式系統中經常需要的「請求 / 回應」式的交互來說並不合適。因此，「請求 / 回應」 是通過 services 來實現的。這種通訊的定義是一種成對的消息：一個用於請求，一個用於回應。假設一個節點提供了一個服務提供下一個 name （頁面存檔備份，存於網際網路檔案館）和客戶使用服務發送請求消息並等待答覆。ROS 的客戶庫通常以一種遠程調用的方式提供這樣的交互。
* Bags （頁面存檔備份，存於網際網路檔案館）: 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。

## 參考文獻

1. http://www.ros.org/wiki/ros （頁面存檔備份，存於網際網路檔案館）

## 外部連結

ROS 官方網站 （頁面存檔備份，存於網際網路檔案館）