前言

我們在上一篇文章中介紹了Docker的安裝法,今天要介紹的是LIMO上如何利用Docker配置ROS2開發環境。

在開始安裝之前,我們先來介紹一下Docker是怎麼安裝這些容器的。

 

 

容器(Container)怎麼安裝?

使用虛擬機的時候,我們可能安裝完虛擬機,接著就是直接使用別人做好的虛擬機映像檔。這個映像檔因虛擬機軟體有些有特殊格式,比如VMWare可能會直接給你一個巨大的壓縮檔,解壓縮之後是個包含vmdk等一堆檔案的資料夾,直接用VM匯入後即可使用。而最常見的可能是以img為附檔名的映像檔,這種格式和我們燒錄SD卡時使用的一致,也是匯入後即可使用。

但使用這些檔案大家都能注意到一件事情,也就是檔案極其之大,小從3GB(Ubuntu20.04純系統)大至12GB(NV Jetson Nano系統),這使得我們在傳送時相當不便。

而容器不只好傳,甚至還有專門的集中區供各Docker用戶檢索下載。其最關鍵的原因是,容器本身只需要一個檔案就可以完整敘述裡面的內容物,這個檔案叫做DockerFile。同時,它也是我們使用Docker時最常用的安裝方法。

DockerFile是一個類似於批次檔的東西,開頭通常會先引用其他已經完善且常用的容器,比方說官方的Ubuntu容器。接著會寫明了建立容器時需要執行的所有指令--包含你安裝系統後需要安裝的所有函式庫以及設定指令。也就是說,我們使用DockerFile建立容器時,安裝完主系統核心後,就相當於我們一行一行輸入需要的指令安裝需要的包,因此不會像直接裝映像檔一樣下載龐大的檔案(當然,安裝完後也是有一定大小的)。

利用DockerFile安裝確實有其便利性,但就相對需要對它的知識才能夠自由調整安裝內容。畢竟某些函式庫就是需要先裝某一個才能裝下一個,如果一開始不知道而直接打進去安裝指令,有可能容器就建立失敗,要從一大串訊息裡挖出錯誤訊息也是個麻煩的事情。

因此對於初學者,我們比較推薦第二個方法,同時也是LIMO使用的做法:只裝包含系統的基本容器,連線進去慢慢打指令安裝需要的東西。

 

在LIMO配置ROS2容器

LIMO中配置ROS2的時候,我們第一步會安裝一個包含標準ROS2 FOXY版本的容器,這個容器由ROS官方發佈:

mkdir limo_foxy_dev && cd limo_foxy_dev
docker run --network=host  --cap-add=SYS_PTRACE --cap-add=SYS_RAWIO --security-opt=seccomp:unconfined --security-opt=apparmor:unconfined --volume=/tmp/.X11-unix:/tmp/.X11-unix --runtime=nvidia --device /dev/ttyTHS1:/dev/ttyTHS1 --device /dev/ttyUSB0:/dev/ydlidar --device /dev/bus/usb/:/dev/bus/usb -v $(pwd)/:workspace --env="DISPLAY=$DISPLAY" --name limo-foxy-dev  -w /workspace -id ros:foxy

第二行看起來很長,但其實拆開來解讀並不困難。

docker run會執行容器,若容器不存在,則會試著從我們前面提到的線上docker發佈集中區搜尋有沒有資源可供下載。我們可以從第二行最後面的內容看到-id ros:foxy,就是指定了ros的容器,其版本為foxy。

而中間的一大串由–帶頭的敘述則是建立容器時需要的參數,包含有網路的橋接、硬體裝置的映射等。這邊即使沒看懂也不影響,基本上由原廠處理這些問題即可。

 

安裝完這些東西之後,第二步我們試著連接進去:

docker exec -it limo-foxy-dev /bin/bash

exec這個指令會在容器中執行後續的命令,而-it則是附加的參數,有幾個選項可以選:

-d :分離模式,命令會在後台運行

-i :即使你什麼指令都沒打,也會維持命令列輸入的狀態

-t :分配一個終端機給它

因此,我們上面的指令會在執行完後保持接收命令列輸入的狀態:

(大概就像這樣子,可以注意到左邊的名稱變成root/nano,且工作目錄也從原本的變成容器中預設的工作目錄了)

注意:接下來的所有動作都是在容器中進行了喔!

 

第三步:設定ROS2的環境變數,讓他每次只要連入容器內的命令列就會自動載入--當然,那是為了之後方便,現在還是得先手動載入一次:

echo "source /opt/ros/foxy/setup.bash" >> /etc/bash.bashrc
source /opt/ros/foxy/setup.bash

 

第四步:安裝python的pip工具,以及更新ROS2函式庫的參考清單:

apt-get update #重要,Docker剛新建不會有apt清單,沒跑這行指令apt什麼都裝不起來!
apt install -y python3-pip nano openssh-server systemctl udev swig
pip install rosdep
rosdep init && rosdep update

 

第五步:安裝光達的SDK和相關的包

git clone https://github.com/YDLIDAR/YDLidar-SDK.git
mkdir -p YDLidar-SDK/build
cd YDLidar-SDK/build
cmake ..
make
make install
cd ..
pip install .
cd .. && rm -r YDLidar-SDK

 

第六步:複製LIMO的ROS2包

git clone --recursive https://github.com/agilexrobotics/limo_ros2.git src

 

接著的第七步會比較麻煩,我們需要調整一下光達的參數讓它可以正常運作。使用我們前面安裝的nano來開啟檔案:

nano /workspace/src/ydlidar_ros2/src/ydlidar_ros2_driver_node.cpp

開啟後我們需要對這幾行的數值進行更改,建議使用nano的 ctrl+/ 組合鍵跳轉到該行比較方便:

61行:int optval = 115200;
76行:optval = 3;
108行:b_optvalue = true;
134行:f_optvalue = 12.f;
143行:f_optvalue = 8.f;

 

(這是使用快捷鍵直接跳轉會看到的畫面,輸入行數後,編輯的輸入標就會移到該行囉。)

全部編輯完之後請按下ctrl + x,接著按下Y存檔。

 

第八步:安裝LIMO所依賴的ROS2包,並編譯LIMO本體的包(注意:時間會稍微長一點點)

rosdep install --from-paths src --ignore-src -r -y
colcon build --symlink-install

*如果看不懂第二行,建議閱讀出貨教材的ROS2章節:編譯

編譯過程中會有一些小警告,不影響編譯和正常執行,不用擔心。

執行完這一步,LIMO上的ROS2配置暫時告一段落--除了導航相關的資源還未安裝這一點外。

 

我們先嘗試驗證一下到現在安裝的包和硬體是否有正確配置:

source install/setup.bash
ros2 launch limo_bringup limo_start.launch.py

*第一行是標準的編譯包後載入參數,如果看不懂可閱讀出貨教材的ROS2章節:編譯

第二行會開啟LIMO的底盤啟動程序,包含了底盤和光達等硬體,正確執行的話應該如下顯示:

(關鍵就是看到YDLidar is scanning)

 

我們可以打開另外一個命令列,透過ROS2 topic指令確定目前執行的狀況:

(可以看到,imu、odom、scan這幾個頻道都建立成功,可以自行使用echo命令確認訊息。並且底盤控制用的cmd_vel也建立完成,可以使用pub命令嘗試控制看看)

 

若輸出畫面沒有異常,我們就完成第一階段的ROS2環境部署任務了,先稍作休息,我們下一篇文章再進行後面的動作。