ROS Tutorial Introduction
ROS Tutorial Introduction
此篇為中央大學數學系上課所用的 ROS 教材,若非修課生,Demo 部分需要注意一下自己的機器人設定。 原文放在 hackmd 上,我會不定期更新過來,若發現教材有誤,歡迎到 hackmd 上修改,或是可以發 issue 給我。
什麼是 ROS?
ROS 全名叫 Robot Operating System,但它其實是一種中介軟體(Middleware),妳也可以說它是一個軟體框架(Software Framework),所以他是一種抽象化的概念,不是應用程式,也不是作業系統。
那它主要會幫我們連結各個軟體和零件之間的溝通,並且會提供一些 logging 的工具,那機器人的中介軟體有很多,像是 ROS、JAUS、Mira 等等。
為什麼需要 ROS?
最一開始的狀況
最一開始大家都各寫各的,但要寫機器人是一件非常困難的事,妳需要熟知如何撰寫每種零件的 code,當然,有大神克服了,完成了很多作品。
然而當日子一久,機器人技術的規模和範圍不斷擴大,零件也越來越多,此時前面那位大神的 code 在別人手上可能就跑不起來了,因為零件不同。
這會造成一個問題,就算是同樣的功能的 code,由於每個人的零件不同,所以都還要再重寫一次,這就導致了代碼的重用性很低(重造輪子),而且這類 code 的規模很大,而且還是需要從驅動層級開始寫的,因此非常不方便,且需要非常高的專業能力。
框架
因此就有人提出了框架的想法,什麼是框架? 框架是一種規則(思想),其實就是某種半成品,框架提供了一個基礎的架構,就好像房子的地基和骨架一樣,必須配合妳自己寫的 code 才能生出一個完整的應用程式。
好處就是整個結構可以被重複使用,如果有了框架,那麼做東西就不需要再從頭建造了。
而前面也提到 ROS 算是一種軟體框架,ROS 幫我們把硬體與軟體之間的溝通都做好了,我們只需要寫我們「溝通的過程/效用」就好,而不用再從「溝通的原理」開始寫,也因此我們可以專注於開發演算法及其應用,同時也降低了高度專業能力的限制。
ROS 的架構
Peer to peer (P2P)
ROS 主要是依靠 P2P 架構實作的,講這個之前先讓大家稍微理解一下簡單的主從式架構:
客戶端(clients) 會去向伺服器請求資料,這邊這個伺服器裡面有很多資料,像是客戶的帳密、金額,或是你遊戲帳號裡面的寶物有哪些之類的。以早期的線上遊戲來說,每次客戶端有更改資料的動作時都會發送一個請求(request) 給伺服器,假設你打了怪,賺到了 10 元,它就會把這個資訊送到伺服器上,伺服器就會幫你記錄下來;
而如果拿網頁舉例子,像是 FB,妳點了某個人的個人頁面,妳就會向伺服器發送一個請求(request),伺服器收到這個請求後就會知道妳要進入這個人的個人頁面,因此將妳導向這個人的個人頁面,妳就成功進去了。
因此伺服器的權限非常的大,並且可以處理非常多的東西。
但這會有一個問題,那就是如果發送請求的人非常多,且請求發送的非常頻繁,那麼伺服器的速度可能就會變得非常慢,甚至當機掛掉,DDoS 的原理就是這樣。
那如果 ROS 使用了主從式架構,很有可能也會有類似的問題,因此 ROS 使用的是 Peer-To-Peer (一種分散式系統架構),Middleware 通常都會是分散式系統架構:
在這種架構下,每台電腦(節點)都同時是客戶端與伺服器端,所有人都負責儲存了全部或部分的所有資料,並且也都會處理收到的請求。
這樣做的優點是能夠擁有很好的平行處理能力,效能也會比較好,缺點是如果規模太大整個網路會很亂,且會很吃網路,但因為機器人的網路規模通常很小,所以不太會有這個問題,另一個缺點就是安全性,如果沒有做特別的處理,傳輸的文件可能會被動手腳,或是失真。
那 p2p 有一些變型,這邊舉三個例子,看下面這張圖:
上面這三個分別為
中心化P2P
英文為 Centralized P2P architecture
- 有一個中心伺服器來幫忙連結溝通其他節點的訊息資料,並對這些請求做出回應 (但本身並不保存檔案)
- 節點負責處理、發布訊息資料,讓中心伺服器知道節點需要什麼檔案、資料,讓其他節點下載資源
- 有 index 可以找到絕對地址
例子像是最初的 Napster
純P2P
英文為 Pure P2P architecture
- 節點同時是客戶端和伺服器端
- 沒有中心伺服器
例子像是 Gnutella
混合型P2P
英文為 Hybrid P2P architecture
- 有多個伺服器來處理其他節點的訊息資料
- 同時有上面兩個的特性
例子像是 Skype
那麼 ROS 的架構是第一種,Centralized P2P:
我們會有一片樹梅派來跑 server 的 code,或是像我們一樣用主機來跑 server 的 code,然後各個零件能夠互相傳遞、存取資料。
架構及名詞解釋
現在我們已經知道 ROS 是用 P2P 來實作的了,那麼現在我們要來簡單看一下這些東西在 ROS 裡面的名詞及概念。
Node
在 ROS 裡面,P2P 架構裡面的一個節點我們叫他 Node,Node 是一個你跑起來的程序(Process),一個完整的系統會有很多個 Node。
一個 Node 通常會是有單一功能的 Process,當然妳一個 Node 要有很多功能也可以,總之核心概念就是模組化(Modular Design)。
舉個例子,一個簡單的導航程式,裡面可能是有一個 Node 是操控雷達,一個 Node 操控馬達、輪子,一個 Node 計算自己的定位(Localization),一個 Node 來計算路徑規劃,一個 Node 顯示圖形介面,等等。
所以你可以看見它其實就是很多個 Process 組合起來的,那麼這些 code 妳可以用 roscpp 或 rospy 來寫,好像還有其他另外支援的語言套件,但我只熟這兩個了。
Master
Master 是一個特殊的 Node,也就是我們前面所說的 Server,Master 會幫忙查找 Node,紀錄妳想傳遞的訊息的種類等等。
如果沒有 Master,Node 與 Node 間會找不到對方,妳的資料傳遞、設備呼叫請求等等的溝通就會失效。
Messages
上面有說一個完整的系統會有很多個 Node,那麼 Node 間要傳遞資料需要靠 Messages 來溝通。
Message 是一種資料結構,裡面會有 type field,type field 通常指的是一個基類(base class) 裡面的變數,這個變數會拿來當作子類的 type 來使用,舉個例子(來源):
1 |
|
上面的 Pet::type
就是一個 type field,在 Dog 這個子類裡面我們用 type
來當作了它的型態。
Messeage 裡面可以有標準的基本型態,整數、浮點數、布林值之類的,也可以是基本型態的陣列,且 Message 內可以包含巢狀類(nested class)。
Topic
Message 在發布時我們會給它加上 Topic,妳可以把 Message 想像成一個箱子,Node 間要傳遞資料時會把資料放到這個箱子裡面,並在這個箱子上面貼上一個標籤,這個標籤就是 Topic。
覺得太抽象的話可以看下面那個小節的圖。
Publisher & Subscriber
讓我們先小整理一下,Message 是 Node 間拿來溝通的工具,因此 Message 由 Node 發布,也由 Node 接收。
於是在 ROS 裡面,發布 Message 出來的 Node 我們叫它 Publisher,接收 Message 的 Node 我們叫它 Subscriber,看看下面這張圖:
Node 會通過 Topic 來找要接收它需要的訊息,我們稱之為訂閱,例如規劃路徑的 Node 希望和雷達的 Node 拿掃到的資料,那麼規劃路徑的 Node 就是 Subscriber,雷達的 Node 則是 Publisher
而 Message 裡面可能裝很多個整數的陣列,Topic 可能是「雷達資料」,以上方那個圖來說就是:
而同一種 Topic 的 Message 也可以由不同的 Node 發布,也就是有不同的 Publisher 發布同樣 Topic 的 Message; 例如妳雷達有兩顆,而且妳為他們寫了兩個 Node,那麼這兩個 Node 都可以發布「雷達資料」這種 Topic 的 Message:
同理,同一種 Topic 的 Message 也可以有不同的 Node 訂閱,有就是有不同的 Subscriber 訂閱同樣 Topic 的 Message; 例如規劃路徑的 Node 需要雷達的資料,建地圖的 Node 也需要雷達的資料,那這兩個 Node 都可以訂閱「雷達資料」這種 Topic 的 Message。
如果一個 Node 同時在收資料與發資料,那這個 Node 就同時是 Subcriber 與 Publisher。
資訊的傳遞
實際上在傳遞資訊時還會需要 Master 來幫忙 Node 之間的通訊,那麼 ROS 的訊息傳送時是使用 TCP/IP 協定的連線,且一旦兩個訊息接起來後就不會再經過 Master 了:
一開始 Publisher 會先去向 Master 註冊,然後 Publisher 就會開始發布它的訊息(封包);而當 Subscriber 需要相對應的訊息時就會去詢問 Master,那當它訂閱到那個 Topic 時它們就建立了連線,不再透過 Master 來傳遞資訊。
所以 Master 會負責 Node 之間的通訊,他們之間是 TCP/IP 協定的連線。
而因為 Middleware 會做序列化(Serialization),所以你 C++ 寫出來的 Node 和 Python 寫出來的 Node 也可以溝通。
Package
Package 是一個 ROS 軟體的基本單位,Package 會有裡面會有很多個 Node,然後可能會包含有相關的函式庫、資料集(dataset)、配置文件(configuration file),或其他能幫助你整合、規劃專案的檔案。
換句話說,Package 是妳在建立和發布專案時最基本的單位,因為妳的專案很可能是程式與程式之間在溝通的,妳把那些 Node 整合起來,配合妳自己寫的函式庫,蒐集的資料等等的,整個包裝起來成一個能讓別人使用的程式,這樣的東西就是一個 Package。
Demo (By OG)
VB image
Ubuntu & Linux
Ubuntu是基於Debian,以桌面應用為主的Linux發行版。Ubuntu有三個正式版本,包括電腦版、伺服器版及用於物聯網裝置和機器人的Core版。前述三個版本既能安裝於實體電腦,也能安裝於虛擬電腦。
Terminal & CLI
linux 基本指令 :
cd:用以移動到目標路徑
cp:複製檔案到指定路徑
mv:移動檔案到指定路徑
rm:刪除檔案
ls:顯示當前路徑下的資料夾與檔案
nano:一種CLI的編輯軟體
vim:一種CLI的編輯軟體
SSH :
Secure Shell是一種加密的網路傳輸協定,可在不安全的網路中為網路服務提供安全的傳輸環境。SSH通過在網路中建立安全隧道來實現SSH客戶端與伺服器之間的連接。SSH最常見的用途是遠端登入系統,人們通常利用SSH來傳輸命令列介面和遠端執行命令。
ssh username@server_location -p port
username:遠端操作時的使用者帳號
server_location:你要連接的電腦,可能是ip或URI
port:ssh 專用的port,預設為22
請注意,接下來開始會有兩台主機進行運作。一台是你的電腦,一台是機器人。
請留意你到底是在哪台機器上操作!!!
ROS
roscore & rosrun & roslaunch
在運行node之前都必須先啟動master,master就是ROS系統中負責管理Node的一個功能,他負責node與node之間的溝通橋樑,因此在執行node之前一定要先把master開啟。然後在ros中提供兩種方法去執行你的Node,一種是rosrun、一種是roslaunch。
roscore
roscore可以讓你啟動master
1 | roscore |
rosrun
rosrun可以讓你去執行特定package下的code,使用方法如下
1 | rosrun <package> <executable> |
roslaunch
roslaunch則透過預先設定的launch file幫你一次開啟很多程式
1 | # 因為launch file 是放在某個package底下,還是要加package |
rosnode & rostopic
在ros中你可以使用以下兩種指令去檢視正在運行的node及topic
- rosnode 動作 參數
- rostopic 動作 參數
rosnode
在rosnode中提供以下幾種動作可以使用
1 | rosnode info <node_name> #print information about node |
rostopic
在rostopic中提供以下幾種動作可以使用
1 | rostopic bw <topic_name> #display bandwidth used by topic |
機器人初連接
Turtlesim
1 | initialize ros master |
Minibot & Turtlebot
網路設定
筆電網卡設定
–>ipv4–>ip :10.0.0.2–>mask :255.255.255.0–>store
1 | gedit ~/.bashrc |
1 | source ~/.bashrc |
連線
使用新版VM
啟動機器人的指令,一定要在機器人上執行!!!
1 | ssh連接機器人 |
起動 rviz 視覺化套件
1 | rviz |
遙控機器人
1 | Extra moving !!! |