如何讓一台機台中的 Launch 檔也能啟動其他機台中的節點?

distributed-computing
之前看了林信男的這篇如何用一個 launch 檔啟動期胎台機器人上的節點(程式),看得我也心癢癢的,想說這樣的功能,真是 ROS 界的福音啊!趁著研究告一段落,比較有空的時候,也來試試。以下就是我的使用心得!
在開始之前,請先確定你已經完成了 DSA 無密碼遠端連線的設定,請參考這裡。如果還沒設定或還沒閱讀過,請連過去看。對!就是現在!我在這邊等著(啜飲焦糖瑪奇朵中)。
OK了嗎?好,確定一下你的 ~/.bashrc 裡面已經設定好 ROS Master 地址、你自己的 workspace 位置。都設定好了嗎?那我們繼續。
Launch 檔中有幾款標籤可以自由使用,請參考 這篇官方Launch/XML machine 標籤的用法教學 。雖然裡面有提供 password 選項,但既然我們能不須密碼遠端登入,那洩漏密碼這件事遍布成問題了。
ROS 的 Launch 檔裡,允許使用者針對各機台上的節點做啟動,但不可以遠端啟動另外一個 Launch 檔。此外,當初的設計應該是讓 Master 端用這樣的「至尊 Launch 檔」呼風喚雨,所以如果你是在非 master 的機台上呼叫這樣的 Launch 檔,你只會開啟這台基台上的節點而已。這是使用尚要注意的地方。在撰寫這類至尊 Launch 檔的語法上,我們需要用 <machine>標籤先宣告各機台,然後啟動各節點時,用 <node>裡面的 machine="" 來指定機台。
以下是一個範例檔。有很多標籤,既然是 Optional ,我就不使用了:
 ———————————————————————-
<launch>
<!–
This launch file activates both the robot and client side launches
going across all machines. Before using, please verify that all machines
are connected under the same network.
Make sure to set up DSA or password-less login to avoid compromising
your own password. Better if you can set DSA on all computers.
CAUTION: ONLY LAUNCH THIS FILE AT THE MASTER side, otherwise it won’t work.
–>
<arg name="client_ip" default="charly-MSI.local" />
<arg name="client_name" default="charly" />
  <!–The robot–>
  <machine name="myRobot"
  address="myRobot.local"
  user="bot" />
  <!–The client–>
  <machine name="client_pc"
  address="$(arg client_ip)"
  user="$(arg client_name)" />
  <!–機器人端開啟雷射測距儀–>
  <node machine="myRobot" pkg="hokuyo_node" type="hokuyo_node" name="hokuyo_node">
      <param name="frame_id" type="string" value="hokuyo_link" />
  </node>
  <!–客戶端開啟 Rviz–>
  <node machine="client_pc" name="rviz" pkg="rviz" type="rviz" args="-d $(arg rvizconfig)" required="true" />

</launch>

——————————————————————

自己使用的心得

雖然期盼已久的遠端單 launch file 開啟節點的夢終於實現了,但是我也碰到另外兩個問題,

問題一

所有的文件都解釋了如何啟動遠端節點的實作方法,但是竟然沒有超出四篇在談論如何遠端啟動對方的 launch 檔,亦言之,無法用 machine 標籤將別台機器的 launch 檔包進來。對我而言,目前我手上的專案根本無法一個節點一個節點置入 machine 標籤,因為一個專案就包括了數十個節點,改完手會斷。因次,我個人的使用經驗是挫折的,目前好像尚未能找到這樣的實作方法,看起來又必須重新回覆到之前遠端到各機台並個別啟動該機的 launch file 模式了,否則根本無法順利運作。

問題二

若你在非 master 節點所在的機台上啟動這個可控遠端的 launch 檔,你會遭遇到一則錯誤的訊息,就是 ROS 找不到 master, 所以無法啟動節點,laumch 就此關閉。這就表示,你只能在 master 的機台端啟動該 laumch 檔。
如果你的 master 剛好就在你現在所使用的電腦上,那就沒問題了,但如果你跟我一樣,master 放在機器人端,那麼你依舊每次還要遠端過去,然後才執行該 launch 檔,用久了自己都會嫌麻煩。那你可能會問,那為什麼不乾脆直接把 master 設在自己的電腦上就好?Well, 這世界上永遠都有特例,例如,當你所使用的機器人是公用的,隨時都會有好幾個人一起連到機器人的電腦上。除非今天你是老闆,否則應該沒有人敢一直請你開電腦,然後才遠端到你的電腦上,只為了啟動他的程式吧?
所以,主要的問題是 master 節點,這也可能是為什麼 ROS 2.0 可以改進的,就是去除必須啟動 master 節點才能做事的奇怪要求。

每次登入都要輸入密碼?用 DSA 實作無密碼遠端登入!

由於最近必須把所有的研究成果整合到一台全新的機器人平台上,所以有機會來嘗試一些之前沒時間嘗試的工具。譬如說只用一個 launch 檔同時開啟多台機器上的各個節點,這樣勢必會讓現在啟動機器人的方法發生革命性的變化,至少應該會更簡單。但在這之前,我想分享一下怎麼設定不需要密碼登入的遠端連線這回事,有這個前置動作,才會有更好的連線控制方法。好,那我們來實作看看!

Step 1  至少先確認能遠端

首先,我們需要確認兩台電腦能彼此遠端。請參考我的另一篇文章
在這邊只提醒各位,機器人端和客戶端個別都需要安裝 openssh-client 和 openssh-robot
$ sudo apt-get install openssh-client
$ sudo apt-get install opensh- server
直白來說,前者是遠端到別人那端時使用的,後者則是讓自己當伺服器或接受別人連到我們這邊。
如果不確定自己有什麼裝了什麼沒裝,可以安裝並使用 aptitude 這個小工具幫忙搜尋(如果你的系統中沒有。直接 apt- get install 它),用 Aptitude 搜尋方法如下:
$ aptitude search openssh*
在這一步快進入尾聲前,請確認自己的 .bashrc 內已經有以下:
export ROS-HOSTNAME=你的 Zeroconf 名稱
export ROS_MASTER_URI=http://[Master 的 Zeroconf 名稱]:11311/
例如我的設定如下:
export ROS_HOSTNAME=charly-MSI.local
export ROS_MASTER_URI=http://beebot.local:11311/
只要輸出的所有程式那行的前面出現 “i", 那麼就代表該程式已經安裝。

Step 2 打造金鑰

在機器人的終端機上打:
$ ssh -keygen -t dsa
這時終端機應該會跳出類似以下的訊息:
Enter file in which to save the key (/home/[機器人 host]/.ssh/id_dsa)
它已經有預設的儲存位置了, 就給把公鑰直接儲存在該路徑上吧!我們之後會需要它, 所以這一步就給它大方 Enter 鍵揍下去(噹噹噹噹!)
終端機會在輸出一行訊息:Enter passphrase:
就輸入密碼!
Enter same passphrase again: 再輸入密碼 Orz
所以目前公鑰存在以下路徑:/home/[我的機器人]/.ssh/id_rsa.pub
還有自己的私鑰, 這個永遠別給別人, 記得喔! /home/[我的機器人]/.ssh/id_rsa

Step 3 給對方公用金鑰

是的。你的家要讓朋友隨時進出,那你就要給朋友你的鑰匙。但這份鑰匙為了門禁驗證用,你只把半個鑰匙給人家,自己保留另外一半,或者用另外一種方式看,有點像你自己這邊設置門鎖。若其他朋友冒充你的朋友拿不知哪來的一半鑰匙開門,那對不起,依舊無法打開你家的門。
所以,再電腦遠端驗證中,你自己持有一把私鑰,給想要連近來的電腦一把公鑰。那要怎麼給呢?首先,先改公鑰(.ssh)執行權限:
$ cd
$ chmod 755 .ssh
複製公鑰到要遠端連進來的電腦上:
$ scp ~/.ssh/id_rsa.pub [客戶端電腦]@[客戶端電腦的 IP 或 Zeroconf]: .ssh/authorized_key
例如:
$ scp ~/.ssh/id_rsa.pub charly@charly-MSI:.ssh/authorized_key
現在,遠端到你的客戶端電腦上,打開終端機後,設定公鑰權限:
$ chmod 600 ~/ssh/authorized_keys
好了!設定完成!

Step 4 最後一次需要密碼的登入,此後一勞永逸

假設你從你的客戶端電腦用 ssh 遠端連線到機器人主機,例如:
$ ssh bot@myRobot.local
系統會問你最後一次輸入對方的密碼,一旦輸入好並登入後,之後便在也不會要求你輸入密碼。你已經可以順利以不輸入密碼的方式,登入對方的電腦。同樣的,若對方要遠端連線登入到你這台電腦,也必須照上述設定步驟,只是這次轉換角色而已。

Step 5 (Optional) 寫一個批次檔讓你每次都能輕鬆登入

科技始於人性。我不想每次都一直打 ssh 指令,有沒有更快的方式,讓登入便得更便捷自動?有的!批次檔現在可以更安全的幫你再不洩漏密碼的強況下,自動遠端登入。先在你中意的路徑下,建立一個文件檔,隨便取什麼名字,副檔名為 .sh,裡面打下遠端登入的指令即可。以下範例是我的遠端批次檔:
#! /bin/sh
ssh bot@myRobot.local
就這麼簡單!

最簡單讓你的平板變成電腦延伸螢幕的方法

(聲明:如欲轉載本文章,或者節錄文中的圖片或文字,請記得寫上出處。謝謝!)

自從辦公桌上架了第二顆螢幕後,就再也回不去使用單螢幕的時代了,理由很簡單,有個延伸桌面,真的可以把要同時進行的作業同時攤開來方便檢視,有使用延伸螢幕的人絕對知道我在說什麼。尤其時值研究開發時期,又要蒐集資料,撰寫論文的時候,更是拖不開使用雙螢幕。我之前想到使用家裡的電視當第二顆螢幕,但是占著不給爸媽看電視,好像也很不肖欸?

把電視當延伸螢幕
買一條 HDMI 線,一端接上電腦,另外一端接到電視,這樣就可以把電視當延伸螢幕了。但是除非你獨居,或電視本來就是你自己的,要不然有時並不是最好的辦法

很可惜最近都直接拿著筆電離開辦公室工作,但還是想要雙螢幕,怎麼辦?也沒有一萬多塊閒錢可以添購平板可攜式螢幕,但是手邊剛好有一台平板,且平板攜帶上比帶另一顆螢幕簡單多了。所以我腦筋就動到這台平板上。

要把平板變成延伸螢幕並不是這麼簡單。在不考慮直接買螢幕接上筆電,又要盡量省錢的前提下,我找到兩種解決方法,而且都有親身試驗過!

方法一:不管你是使用哪一種作業系統,讓專業的來就對了!

實際上就是直接上 Google Play 或 iStore 買人家開發好的 App,在平板端裝上 App,然後再電腦端安裝相對應的接口,然後透過 Wifi,或者USB連接電腦與平板,把平板的「開發人員選項」打開來(在 Adnroid 4.2 版之後,啟動的方法很像在找彩蛋,可以參考這裡),Voila !! 你就可以把平板當成延伸螢幕來用!

每款應用軟體都有各自的優缺點,所以在付費使用之前(是的!沒有一款是免費的!我在想可能開發真的很費工,如果發不出薪水,員工可能會告上法院!),請謹慎評估,符合自己需求的,才是最適合您的軟體。另一方面,有網友也指出,使用 Wifi為連接媒介的軟體會受限於網路連接的頻寬以及速度,所以在流暢度,或者在跨螢幕視窗的同步上,絕對無法達到最佳化,但至少這類軟體避免掉裝置通訊埠之間繁雜的設定,只要在同一個子網路下找得到對方,就絕對可以確保連得上。反之,走 USB 線的軟體的優點,就是可以在周遭環境沒有或找不到 Wifi的情況下,照樣可以順利連線,並且可以確保使用上的流暢度,包括跨螢幕視窗運作的流暢度,真的遠遠超越 Wifi 連接的軟體(看一下下面的影片就知道了!)。那為什麼還有人想使用前者?其實走 USB 線的軟體也有它的罩門(這就是為什麼我先暫時放棄的原因),在使用上,若兩個裝置打從出娘胎以來,就「合不來」,那你在怎麼努力修改設定,仍然不會讓他倆「相見歡」,原因我寫在下面的章節。

關於有哪些可以用的軟體,既然有網友寫了,這邊便不再多作贅述,直接看這邊吧!感謝!真的寫得很詳盡!下面展示一下 TwomonUSB 的 Demo 影片,就可以知道我在講什麼了!

讓我來講一下我的親身體驗吧!我也是查了幾小時的資料,甚至為此將我郵局的金融卡功能打開(就上郵局跟他講把所有卡的國外交易功能什麼的,全部功能都打開!),方便我在 Google Play上購買軟體。

看來看去,我決定使用走 USB 線的App,先嘗試安裝免費版本的 Splashtop Wired Display ,在短短的十分鐘內看看能不能美夢成真。安裝了電腦端軟體後,也下載並安裝 App 後,我把平板電腦的開發人員選項啟動,勾選了USB偵錯選項。電腦有偵測到平板裝置,但是就是不知道為什麼無法讓電腦端跟平板端的程式連線。妙的是用同一家公司開發的遠端軟體就連得上去。幾個小時候的嘗試後,我放棄。

Tablet as second monitor
source: http://mashable.com/2012/11/01/tablet-second-monitor/#1uql0LW91EqU

接著,雖然掛念之後要在 Linux 系統下無雙螢幕,Windows卻能享受的殘念下(因為我的筆電是雙系統的),我便購買了 TwmonUSB 這款頗受好評的 App。TwomonUSB 是由一家韓國公司 DevGuru 開發的,致力於讓平板變成電腦的延伸螢幕,而且比其他同款軟體好的地方,是它已經幫你安裝好所有需要的套件,所以你其實不需要親自設定什麼就可以用了,嗯…據說。

我忍痛的自掏腰包購買了 TwomonUSB,並設定好了後,奇怪?還是無法使用。莫非,我的平板就是跟我的筆電「合不來」?花了半個小時冒冷汗爬官網上的文,試過所有方法後,還是無法讓程式跑起來!購買後兩小時內,心灰意冷的退費,萬念俱灰又不甘心的放棄了。不過從安裝這個軟體的過程中,我也逐漸聊解這種軟體是怎麼運作的。這也就是我採用方法二的原因之一。

方法二:窮人超瞎玩法

DSC05471
將平板變成電腦的延伸螢幕

就像上面章節講到的,比起在 Windows上使用,我更想要應用在 Linux 系統下。Splashtop 在 Linux 上有開發 beta 版的 Splashtop Streamer,這只是連線的接口,真正發揮功能的,是智慧裝置端的 App,讓遠端桌面或者延伸螢幕的軟體可以連上電腦。

在繼續進展之前,來大致上講述一下連接的原理。要怎麼讓兩台電腦互相協作,並不是像拿一台螢幕接上電腦這麼簡單。兩台電腦其實很像是兩個自尊心很強的 Hosts,沒有人服氣令一個人。所以延伸螢幕軟體必須像是在電腦端宣告有一顆螢幕已經接上電腦,這包括安裝模擬用的螢幕顯卡程式,螢幕使用的 VGA接埠程式、也許還有VGA轉成USB訊號的程式。同時在平板電腦端則要設法讓平板變成一個從遠端桌面形式轉換後變成的延伸螢幕軟體。換句話說,延伸螢幕其實就是結合 VNC、遠端桌面、遠端輸入等等程式組成的軟體,並不實這麼簡單的和事佬,難怪人家寫好都要收費!

但我也找到了另外一種方法,是在英文論壇中找到的,不得不說這個老外還滿厲害的,不愧是 Taiwan Number One! Taiwan Number One !我草泥馬!!LOLOLOL

其實方法很簡單,就是在電腦端創建一個虛擬的第二顆螢幕,然後再用遠端軟體直接顯示這個虛擬螢幕,大功告成,請好好享用!

所以這邊問題就要分解成兩個步驟,第一,如何創造一個虛擬的第二螢幕?第二,使用遠端桌面。

Step 1 使用 RandR 創立虛擬顯示器(螢幕)

第一個問題的解法,我使用 RandR 這個管理 Linux 各顯示器埠口的工具。首先,打開終端機,安裝 xrandr,這樣打

$ sudo apt-get install arandr lxrandr

安裝好後,執行 RandR 來看看目前偵測得到的顯示器埠口。打開終端機,打:

$ xrandr

電腦應該會回覆:

Screen 0: minimum 8 x 8, current 2944 x 1080, maximum 16384 x 16384
eDP1 connected 1920×1080+1024+0 (normal left inverted right x axis y axis) 344mm x 194mm
1920×1080      60.1*+   59.9
1680×1050      60.0     59.9
1600×1024      60.2
1400×1050      60.0
1280×1024      60.0
1440×900       59.9
1280×960       60.0
1360×768       59.8     60.0
1152×864       60.0
1024×768       60.0
800×600        60.3     56.2
640×480        59.9
VGA1 disconnected (normal left inverted right x axis y axis)
DP1 disconnected (normal left inverted right x axis y axis)
HDMI1 disconnected (normal left inverted right x axis y axis)
HDMI2 disconnected (normal left inverted right x axis y axis)

拿我筆電作範例。從回傳的訊息中,可以看得出有五個顯示裝置:eDP1, VGA1, DP1, HDMI1, 和 HDMI2。其中 eDP1 為這台電腦的主要顯示器,它有好幾個解析度,以及各解析度的更新率(單位:Hz)。打星號(*)的,就是目前使用的解析度和更新率。

好!接下來,我們來創建一個虛擬螢幕,並把它擺在本機螢幕的左邊,請在終端機中打:

$ xrandr –addmode VIRTUAL1 1024×768

$ xrandr –output VIRTUAL1 –left-of eDP1

這樣子,我們先創立了叫做 VIRTUAL1 的虛擬顯示裝置,它的解析度為 1024 x 768,並且我們把 VIRTUAL1  的輸出放在 eDP1 的左邊。不知道為什麼,我第二行指令必須輸入個兩次才能讓顯示設定乖乖聽話。

如果再輸入指令 xrandr,現在會看到整個訊息的下方,會出現

VIRTUAL1 connected 1024×768+0+0 (normal left inverted right x axis y axis) 0mm x 0mm 1024×768         60.0*

等訊息,這樣一切正常。另外一個檢查的方式,是同時按住鍵盤上的 Windwos 及 s 鍵,透過 GNOME 的縮圖,可以看到有沒有出現第二顆螢幕。如果本機的螢幕像素反而降低,去 System Setting –> Display 裡面調回原本的最高解析度即可。從這邊,也可以看到確實有第二個顯示器。

值得注意的一件事,上述的設定在下一次開機時就會失效,網路上還有其他 xrandr 的使用方法,我的解法,是如果每次要用的時候,直接啟動 bash 文件幫我省下打那麼多指令。你要做的事,就是在你喜歡的路徑上,除存一份命名為 “virtual_monitor.sh" 的批次檔,譬如我直接存在桌面上。文件裡面這樣打(或直接這邊複製貼上):

#! /bin/bash

clear
echo “We will activate XrandR to activate virutal monitor"
xrandr –addmode VIRTUAL1 1024×768
xrandr –output VIRTUAL1 –left-of eDP1
xrandr –output VIRTUAL1 –left-of eDP1
echo “Virtual screen at your left side is activated! Enjoy!"

寫好後,儲存,關閉文件。接著,再打開終端機,cd 到你儲存該文件的路徑上,改變這份文件的可執行權限:

$ chmod a+x virtual_monitor.sh

下次要使用的時候,同樣在終端機中 cd 到這份文件的路徑上,執行:

$ ./virtual_monitor.sh

這樣應該就可以把第二顆螢幕架起來了。

如果對於 xrandr 使用上還有任何問題,可以 google 一下,譬如說這個備載齊全的網頁,或者直接在終端機打:

$ xrandr –help

或者

$ man xrandr

都會有額外的說明。

還活著嗎?最難的部份已經過了!我們進入下一步!

Step 2  使用 TeamViewer 顯示虛擬螢幕

使用了 Splashtop HD Extender 這款免費試用 App,發現提供的功能根本無法切換螢幕,爛!所以還是使用老牌且知名的遠端桌面軟體 TeamViewer。欸?那其實我也可以用另外一台電腦顯示延伸的桌面囉?沒錯!這樣就有點像是使用了 VNC 的意思了!我甚至使用我的手機當延伸螢幕!但是,這樣作有什麼意義?

廢話不多說,上 Google Play 安裝 TeamViewer 遠端控制版本。這不用我教了吧?

接著,遠端連線!我不知道為什麼我不能使用自己的 TeamViewer 帳號直接連線,那就用 TeamID 來連筆電吧!

切換顯示的螢幕。由於我的筆電使用 nVidia 顯卡,所以截至目前為止尚未支援 RandR,會產生TeamViewer 無法顯示第二螢幕的問題。nVidia 自己有開發一個類似的軟體 TwinView,可能會導致顯示上的問題。不管這麼多了!平板轉到虛擬螢幕上到一半,TeamViewer 當掉,那就用手機連看看…OK! 那再用平板連看看,兩次過後,可以顯示第二螢幕了!Yeah ! Gotcha bitch !搞定!

記得在平板端的 TeamViewer 設定中,勾選「顯示遠端游標」。

請勾選「顯示遠端游標」

至此大功告成!恭喜!你已經將你的平板轉成第二顆螢幕了,

結論

讓我們看看為了達成這項功能的花費:

平板的支架:NT$ 70

MicroUSB 訊號線:NT$ 30

姑且不算購入平板電腦的花費,總花費:NT$ 100 !! 架設所需時間,嗯…哥都替你耗費掉了,如果一切順利,你實際只需要 10 分鐘內搞定!

但是,這種方式你必須要接受以下幾件事實:

  • 跨螢幕視窗執行的流暢度?算了吧!
  • 附近沒有夠快的 Wifi AP?請自求多福!
  • 在延伸螢幕上播放影片絕對無法順暢,也就是說,只要有任何視頻,絕對無法順暢執行,甚至會拖慢其他 GUI 的顯示效果
  • 用一陣子後,或者只要連線一不穩,延神螢幕就會斷線,也就是說,程式會跳出,或者卡住當機
  • 所以最好是別在延伸螢幕上做太吃顯示資源的事。但我們既然是用來辦公的,那就乖乖用自己的文件或瀏覽靜態的網頁就好,你說對不對?

這是目前應急用的,倘若之後真的成功安裝好某個程式,或者用一組程式達到更穩定的平板轉延伸螢幕的話,再跟大家分享。同樣的,如果你有找到更好的辦法,也請不吝分享!謝謝!

好!那就先這樣吧!我打字手有點酸,時間也有點晚了!大家晚安!

 

 

 

 

更加認識 Gazebo

這篇文章實際上參考了Gazebo的官方教學,不過之後我會講解自己的實作過程。

首先,讓我們來了解組成 Gazebo 模擬的幾個中大關鍵要素。

世界檔!

這類文件主要由 Gazebo server 開啟,這類文件的格式被稱為 SDF
(Simulation Description Format),其副檔名為 .world。Gazebo已經內附了許多已經完成的世界模型,都放置在這個路徑下:<install_path>/share/gazebo-<version>/worlds.

模型檔!

顧名思義,就是描述機器人模型或者任何要放置在世界當中的文件。這類文件通常會被
<model> … </model> 的標籤包覆著。如果你想把你的模型加進一個世界檔中的話,你可以在世界檔中加加上:

 <include>
<uri>model://model_file_name</uri>

</include>

其實Gazebo已經有很多建立好的模型,你可以在官方位於 Bitbucket上的檔案庫內找到所需要的模型,執行的時候就會執行時間(Runtime)內載入,可以說是相當方便。如果你熟悉另外一種版本控制軟體 Mercurial
的話,你可以把整個模型資料庫克隆到你的本地端來:

$ hg clone https://bitbucket.org/osrf/gazebo_models

喔!別忘了先安裝 Hg (Mercurial)。
官方的教學網站都以實作 SDF格式為主,包括更進階的如何將自己的模型加入meshes、加上顏色、加上物理特性、貢獻到公共遠端檔案庫作分享,不過我將不會再多加解釋如何撰寫 SDF 文件,因為我使用另外一種方式匯入模型,想知道我怎麼做的,請看這邊

插件!(Plugins)

插件,就像在瀏覽器加了某個小軟體,就可以擋掉 Youtube
的討厭的廣告,或者提供更多方便的功能一樣,在模擬界,插件也能賦予模型或者世界更多采多姿的可能性,甚至改變 Gazebo
顯示物件的方法(據說)。插件可以直接用終端機以指令召喚,或者寫在世界檔內默默召喚。插件通常會被server啟動,但有時候 Client
也可以啟動,方便使用者即時做調整。
 
其他更多資訊,請看官方網站的介紹
 

ROS 遠端連線

其實機器人本身就是一台電腦,不管你今天是用什麼主機板或開發版,到最後,一定得再接上網路,才可能跑 ROS (除非你把機器人有連上網卡的主機設成熱點,不過這樣好像治標不治本),否則會顯示「找不到 master」等錯誤訊息。其實,我們常常也會碰到需要遠端監控或操作的狀況,除了看起來比較酷以外,還有更實際的原因:我們需要將比較需要做運算的演算法,在另外一台電腦上執行,而機器人上的主機,只需要收感測器資料加控制馬達就可以了。ROS便提供了多台主機共享
Topics 的方法,藉由乙太網路存取資源,實際上多台電腦用起來,跟用一台電腦差不多,但省去許多要熟悉 Socket架設之類的麻煩。好,不囉嗦,步驟如下:

內容一覽:

1         準備步驟

1.1        自我連線檢測

1.2        雙方連線檢測

2         遠端連線

3         ROS 資源共享

1. 準備步驟
1.1 自我連線檢測

我們實際的例子,就是一台電腦連機器人:

Fig. 1.

遠端連線機器人示意圖

首先,必須先確認 Robot 端主機和 Client 端主機皆連線到同一個乙太網內。我們打開機器人電腦上的終端機,用ping 做連線檢測。這邊有兩種方式:
(1)  
IP 來檢測。如果不知道自己的IP的話,在終端機輸入:

$ ifconfig

終端機應該會輸出以下訊息:

請看 wlan0中 inet addr IP位址,這就是這台電腦的 IP 位址。看你是用什麼方式連線,如果網路是直接接在數據機上的話,應該是看 io 那部分找對應的 IP。這樣的位址會隨著你連線到不同的路由器或子網路而變更,因此如果今天要是由其他裝置遠端
ping 這台機器的話,必須先在這端知道自己的 IP。不過好處是,你將會很確定自己的位址只是對,因此連不上去可能是另外一台的網路設定出問題。

那麼現在就可以來 ping 自己。假設我取得了我的 IP,是192.168.120.101,現在來試試看:

$ ping 192.168.2.109

順利的話,終端機會出現以下訊息,

PING 192.168.2.109 (192.168.2.109) 56(84) bytes of data.
64 bytes from 192.168.2.109: icmp_seq=1 ttl=64 time=0.045 ms
64 bytes from 192.168.2.109: icmp_seq=2 ttl=64 time=0.046 ms
64 bytes from 192.168.2.109: icmp_seq=3 ttl=64 time=0.046 ms
64 bytes from 192.168.2.109: icmp_seq=4 ttl=64 time=0.042 ms
^C
— 192.168.2.109 ping statistics —
4 packets transmitted, 4 received, 0% packet loss, time 2997ms
rtt min/avg/max/mdev = 0.042/0.044/0.046/0.008 ms

表示自我連線測試成功。如果沒有,請確認實體連線是否正常,然後再檢測 Linux上網路連線設定是否正確。可以參考「埃羅魯巴特」中的疑難排解。
(2)  
使用 Zeroconf 的方式 ping 自己。Zeroconf 是一系列能自動整合網路連線的技術。你可以直接使用 Zeroconf 的名稱來取代 IP,因此就算你有多台機器都同時連線在另外一個網域上,在不清楚每台的IP情況下,仍然可以透過 Zeroconf 找到對方。Zeroconf
的名稱,就是:

[hostname的名稱].local
直接在終端機上打:

$ hostname

回覆的訊息,就是你這台主機的 hostname,譬如我的是 charly-MSI,那麼zeroconf就是 charly-MSI.local,如下:

charly-MSI

Ping 自己:

$ ping charly-MSI.local

回覆的訊息跟方法 (1) 中一樣,連線正常。

PING charly-MSI (127.0.1.1) 56(84) bytes of data.
64 bytes from charly-MSI (127.0.1.1): icmp_seq=1 ttl=64 time=0.012 ms
64 bytes from charly-MSI (127.0.1.1): icmp_seq=2 ttl=64 time=0.045 ms
64 bytes from charly-MSI (127.0.1.1): icmp_seq=3 ttl=64 time=0.046 ms
64 bytes from charly-MSI (127.0.1.1): icmp_seq=4 ttl=64 time=0.047 ms
^C
— charly-MSI ping statistics —
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 0.012/0.037/0.047/0.015 ms

 1.2. 雙方連線檢測

我們再次使用 ping 來互測對方連線,如果從 Client 端能連線到 Robot 端,並且反之亦然,表示連線正常。那麼我們就可以進入到下一個步驟。

Client 端終端機輸入:

$ ping myRobot.local

接著在 Robot端終端機輸入:

$ ping myClient.local

都能連上,跳到下一步。

2. 遠端連線

我們可以使用 ssh從 Client 端連線到 Robot 端:

$ ssh myRobot.local

如果你機器人的 ssh 要求比較多的話,那就連登入的使用者名稱都寫下去:

$ ssh myRobot@myRobot.local

那如果你還想要遠端連線時遠端存取圖形化使用者介面(GUI),那記得把 Xorg 打開,如下:

$ ssh –X myRobot.local

連線得到的話,輸入被遠端連線的電腦密碼,登入。

3. ROS資源共享

為了讓每台主機上的 ROS 都能共用資源,我們必須確認 Client 能知道誰是 Master,因此,我們可以打開用起來最順手的文件編輯器,譬如說我打開 vim,將以下指令存入 ~/.bashrc

$ vim ~/.bashrc

譬如說我的機器人 hostname叫 myRobot,那我們則拉到文件最後一行,在下面寫:

export ROS_HOSTNAME=myRobot.local

Client 端則也寫上

export ROS_HOSTNAME=myClient.local

那現在要讓大家知道誰是老大。如果你像我們的例子一樣,一個電腦連一個接器人的話,通常機器人會被設為 Master,電腦則為 Client,那麼就在 Client 端的 ~/.bashrc中,加入:

export ROS_MASTER_URI=http://myRobot.local:11311

這樣 Client 就知道機器人是老大。記得後面的 :11311 要加上去喔!其實你也可以將
Master 設在 Client 端,但是不管怎麼樣,永遠只能有一個 Master!這很重要,所以請容許我強調三次:

永遠只能有一個 Master

永遠只能有一個 Master

永遠只能有一個 Master

那你可能會問,那萬一有時候我想要在一台機器測完某個功能後,再連上
Master 怎麼辦?很簡單,涼拌!開玩笑的!你可以回到
~/.bashrc
中,把 export ROS_MASTER_URI那行給註解掉,儲存離開,關掉你現在在使用的終端機以及裡面的所有分頁,然後再打開新的終端機,啟動
roscore,這樣子,你就可以將這台電腦與 master
的主機徹底切割!(可謂又是另一種別開生面的神切割啊啊啊啊啊!)

接著,為了讓兩台以上的電腦同步,請記得使用
chrony
來同步時間,如果沒有這個軟體的話,在終端機中這樣安裝:

$ sudo apt-get install chrony

安裝完後,在 Client端終端機打:

$ ntpdate myRobot.local

如果一切正確,電腦會顯示兩者電腦的時間差,並會自動同步。

站在巨人的肩膀上,下載並使用大師的作品完成自己的拼圖

在「ROS 略談基本安裝步驟」中,我們有談過可以下載不同的包裹模組化的安裝進自己的專案中那要怎麼做呢?以下會詳加解釋:


內容一覽:

1.如何安裝別人的包裹
1.1
Debian 安裝
1.2
從原始碼編譯 (build from source)
2.
使用的方法
3.
下載使用的建議
4.
更新包裹

1. 如何安裝別人的包裹

當我們開始上 Google 搜尋的時候,我們通常會看到
ROS
所提供的包裹,如果你進入該頁面,在標題的下方就會出現 ROS
的不同版本,選擇你所使用版本。往下看,會有 git source
並附有檔案庫連結,有時會註明是哪一個分支。如果進入內文閱覽,可能還能查到要怎麼直接 apt-get install
安裝以及從原始碼編譯。但上述狀況並不是每一個包裹的 ROS Wiki 頁面都有,那要怎麼安裝?

1.1 Debian 安裝

較少包裹會提供 Debian 檔,相當於 Windows
setup 安裝檔。通常只有態度嚴謹的專案會附一個交代清楚的
README
交代怎麼安裝怎麼用。在 Linux中,通常有兩種安裝方式,
(1)
下載到你指定的資料夾內,用 One software Center 將檔案安裝
(2)
使用終端機安裝。打開終端機,輸入:

$ sudo apt-get install ros-[你的ROS 版本]-[包裹名稱]

輸入密碼,按下 y ,一路綠燈,輕鬆可用。但是萬一 ROS
Wiki
上面只提供 git source 連結呢?

1.2 從原始碼編譯 (build from source)

你有兩個選擇,如果這個專案只有一個 master 分支,並且也確定這個包裹可以在你的
ROS
版本執行後,先複製git source 的網址,直接在終端機上打:

$ git clone [git source 網址]

e.g. git clone https://github.com/cra-ros-pkg/robot_localization

有時你可能只想要特定分支的檔案庫那就這樣打:

$ git clone [git source 網址] –branch [分支]

e.g. git clone https://github.com/cra-ros-pkg/robot_localization –branch indigo-devel

這樣就可以下載到你的 ROS workspace/src內。
別急,這個時候再回到上一層,到你的 workspace (workspace 最頂層的路徑),然後 catkin_make 編譯。如果沒出現錯誤的話,輕鬆可用!如果出現錯誤的話,請確認有把所需要的 dependencies 都安裝起來,可以在 終端機上打:

$ rosdep update

註:rosdep 必須在ROS安裝後,先
sudo rosdep init 初始化後,方能使用其他指令。
如果還是不行,打:

$ rosdep install [你的包裹]

然後,如果還是不行,請確認所需包裹套件等等,皆有被安裝起來,大致上就會解決問題。

2. 使用的方法

ok。下載完編譯過後,然後呢?通常 Readme 有寫好的專案都會告訴使用者怎麼用,譬如說跑 demo, 裡面各節點的輸出輸入Topics, 有哪些 rosservices,有哪些參數可以調。但若不巧什麼都沒寫怎麼辦?通常在一份 ROS 專案內,至少會有 src, devel, launch 這幾個資料夾。我的做法是直接進 launch 資料夾,打開其中一個 launch 檔。這份
launch
檔可能會啟動其他 launch files。因此只要逐步觀察,就可以發現有哪些節點或哪些 launch 檔被使用,他們之間的關係又是如何。再來,跳出 launch 資料夾,來到 src
資料夾,我的習慣是看過除了CMakelists.txt, src資料夾和 Makefile 檔後,大致了解整個專案原始碼放哪邊,所需要的標頭當和實作檔放在哪邊,nodelets 所需要的 plugin.xml 等又放在哪邊。接著就可以進入CMakelists 中大致瀏覽一下,看採用了哪些 dependencies和連結了哪些 includes。再往下移動,在 add_executable()  裡面,所謂的節點,是由那幾個 cpp 檔組成,又有幾個節點被編譯連結。 這一步做到後,就可以接續看各節點所對應的程式碼,並了解怎麼實作的。

啊!對!忘了講拿到包裹怎麼樣,當然是實際執行看看囉!了解各 launch 檔的功用後,就是要實際執行,看看有沒有像預期般執行功能。如果有,那就可以自己寫一個 launch 檔,納入某些功能,加入自己的專案中。如果到達這一步,恭喜你!你已經開始會使用這個包裹了!至於有沒有了解底下的原理,那又是另外一回事。

3. 下載使用的建議

從我自己開發中遭遇的慘痛經驗,建議讀者們如果要加入第三方包裹的功能進自己的專案內,請務必確認第三方的包裹是放在ROS工作空間可以獨立進行 git 更新的位置。換句話說,這個包裹建議不要放在讀者自己的包裹內,因為這樣,下載下來的包裹本來在版本更新的角度而言,都是一個獨立可隨時更新的檔案庫。若把一個檔案庫
A
放到一個檔案庫 B 裡面去的話,A 會被視作 B 的一部分,因而無法單純用 git pull
來作更新,沒辦法更新,有時意味著一些臭蟲解不掉,而我們使用者根本不知情到底哪裡出了錯誤。因此,我的做法是直接將第三方包裹直接 git clone ROS 工作區間/src
下,這樣我自己的 launch 檔能直接用

$(find [
第三方包裹])
直接自動化找到所需節點或檔案位置,又可以讓第三方包裹得以保持更新。

一個實際的例子,就我個人觀察和感覺(所以請別亂 quote
),就是 ROS 自己本身的架構,加入了某一版本的 OpenCV PCL,當這兩個第三方
libraries
更新版本,使用者想引用更新的實作功能時,才發現ROS 不支援,原因是ROS
內所使用的 libraries 屬於舊版本,如果使用者自己打算繞過這個問題,直接引用較新版的同款 libraries, 則會碰上系統參數衝突。為了這樣的問題大傷腦筋,真的是既浪費時間又沒效率。因此開發者便決定從 ROS Indigo 過後,取消內建的 OpenCV PCL,改由使用者自己安裝,並自行 include 進自己的程式碼內。當初想要大一統囊括所有需求的美意,便因為第三方版本更新的需求,而必須予以更動。但這樣的架構反而能給予使用者更大的開發彈性與便利性。

4. 更新包裹

其實很簡單。cd 進入自己的 ROS 工作空間/src/[某一個包裹],譬如說

$ cd ~/catkin_ws/src/navigation

這樣在版本控制的角度就進入了一個檔案庫當中。再輸入

$ git pull

這樣會更新本地端的檔案庫。接著回到工作空間最頂端的

$ cd ~/catkin_ws

輸入進行編譯,

$ catkin_make

這樣即完成包裹的更新。

 

 

寫在前面

大家好!由於近日研究機器人的關係,開始使用 ROS,但是大部份的資料都是英文的,國內少數幾位先驅,包括我的同學賴柏任(可以點我!去拜訪他的部落格),開始撰寫關於這個框架的教學部落格,因此,我也想開始創建自己的自學天地,當作筆記本,在與其他人合作時,也可以幫忙大家快速上手。

換句話說,這網站的存在宗旨是除存關於ROS以及機器人導航等相關學習筆記,但讚未來也有可能加入其他區塊的知識。但我並不打算將 ROS 的官方教學網頁直接應翻中,所以,還請各位看官們配合著各官方教學看。在這個網頁僅提供我自己對這些大架構的了解,也希望能幫助大家了解其中的意函。祝學習愉快!