2025年7月3日 星期四

ROS2 for Docker by GPU, USB, ttyACM drive

 docker run 命令是用來啟動一個具備特定功能的 Docker 容器,

讓您可以在其中進行 ROS 2 開發,特別是當您需要用到 GPU、序列埠通訊以及圖形化介面時。

以下是這個命令各部分的詳細說明:


Docker 啟動命令說明

Bash
xhost +local:docker # 開放 X11 存取(若尚未執行)
  • xhost +local:docker: 這條指令是在主機 (host) 電腦上執行的。它用來管理 X 伺服器的存取控制列表 (Access Control List, ACL)。

    • +local:docker 允許本地的 Docker 容器連接到主機的 X 伺服器。

    • 這樣做的目的是讓容器內的圖形化應用程式(例如 RViz2Gazebo 的圖形介面 gzclient)能夠在您的主機螢幕上顯示。

    • 備註: 這會稍微降低 X 伺服器的安全性,因為它允許所有本地 Docker 容器的圖形應用程式存取您的顯示器。在測試或開發結束後,您可以執行 xhost -local:dockerxhost - 來撤銷此權限,或使用更安全的 xhost +SI:localuser:$USER


Bash
docker run -it --rm \
    --name ros2dev \
    --gpus all \
    --net=host \
    --privileged \
    --env DISPLAY=$DISPLAY \
    --env QT_X11_NO_MITSHM=1 \
    --volume /tmp/.X11-unix:/tmp/.X11-unix:rw \
    --volume $(pwd)/data:/home/ubuntu/data \
    --device /dev/ttyACM0:/dev/ttyACM0 \
    --device /dev/ttyUSB0:/dev/ttyUSB0 \
    ros2-humble-ubuntu
  • docker run: 啟動一個新的 Docker 容器。

  • -it: 這是 -i (interactive) 和 -t (tty) 的組合。

    • -i 保持標準輸入開放,讓您可以在容器內互動。

    • -t 分配一個偽終端機,讓您能像在一般終端機一樣操作容器。

  • --rm: 當容器停止時,自動移除容器及其關聯的檔案系統。這有助於保持您的系統清潔,避免產生過多的僵屍容器。

  • --name ros2dev: 為這個容器指定一個名稱為 ros2dev。這讓您可以更容易地透過名稱而不是容器 ID 來管理或重啟它。

  • --gpus all: 這個參數允許容器存取主機的所有 GPU。

    • 這對於需要 GPU 加速的應用程式非常重要,例如深度學習、電腦視覺應用,或 Gazebo 等需要強大圖形渲染的模擬器。

    • 前提: 您的主機必須安裝 NVIDIA 驅動和 Docker 的 NVIDIA Container Toolkit。

  • --net=host: 讓容器使用主機的網路堆棧。

    • 這表示容器會直接使用主機的 IP 位址和網路介面,而不是 Docker 自己的橋接網路。

    • 優點: 簡化了 ROS 2 節點之間的通訊設定,因為容器內的節點可以直接看到主機上的其他 ROS 2 節點,反之亦然,無需複雜的埠映射。

    • 缺點: 降低了容器的網路隔離性。

  • --privileged: 授予容器幾乎與主機相同的權限。

    • 這是一個非常強大且高風險的參數,它允許容器直接存取主機的設備和核心功能。

    • 在此情境下的用途: 為了確保對 /dev/ttyACM0/dev/ttyUSB0 等設備的完全存取,以及有時為了讓某些 GPU 或圖形功能正常運作,可能會需要這個參數。

    • 備註: 如果可以,盡量避免使用 --privileged,而改用更精細的權限控制(例如 --cap-add),但對於複雜的 ROS 2 硬體介面,有時不得不使用。

  • --env DISPLAY=$DISPLAY: 將主機的 DISPLAY 環境變數值傳遞給容器。

    • $DISPLAY 通常包含 X 伺服器的位址,例如 :0localhost:0.0

    • 這是實現 X11 Forwarding 的核心,告訴容器內部的圖形應用程式應該在哪個顯示器上輸出。

  • --env QT_X11_NO_MITSHM=1: 設定一個 Qt 相關的環境變數。

    • Qt 是許多圖形化 ROS 2 工具(如 RViz2、Gazebo 的 gzclient)使用的圖形庫。

    • 這個變數有時可以解決在 X11 轉發時可能遇到的圖形渲染問題或崩潰,特別是與 X 共享記憶體擴展相關的問題。

  • --volume /tmp/.X11-unix:/tmp/.X11-unix:rw: 掛載主機上的 X11 socket 目錄到容器內。

    • /tmp/.X11-unix 是 X 伺服器用於本地通信的 Unix domain socket 檔案所在目錄。

    • rw 表示讀寫權限。

    • 這是 X11 Forwarding 的另一核心步驟,讓容器能夠通過這個掛載點與主機的 X 伺服器進行通信。

  • --volume $(pwd)/data:/home/ubuntu/data: 掛載主機的本地資料夾到容器內。

    • $(pwd)/data: 主機上當前工作目錄下的一個名為 data 的資料夾。

    • /home/ubuntu/data: 容器內部對應的目標路徑。

    • 用途: 這允許您在主機和容器之間共享開發檔案、ROS 2 工作區、模型、日誌等數據,方便您在容器外編輯代碼,而在容器內運行和測試。

  • --device /dev/ttyACM0:/dev/ttyACM0: 將主機的 /dev/ttyACM0 設備映射到容器內的相同路徑。

    • ttyACM0 通常是連接 Arduino、某些 STM32 開發板或其他 USB 序列設備的名稱。

    • 這使得容器內部的 ROS 2 節點可以直接存取這個序列埠設備,與外部硬體進行通訊。

  • --device /dev/ttyUSB0:/dev/ttyUSB0: 將主機的 /dev/ttyUSB0 設備映射到容器內的相同路徑。

    • ttyUSB0 通常是用於連接 FTDI 晶片、某些 USB 轉序列埠轉接器、或一些 LiDAR 設備的名稱。

    • 類似於 ttyACM0,這也讓容器內的程序能存取這個序列埠。

  • ros2-humble-ubuntu: 這是您要使用的 Docker Image 的名稱。這個 Image 應該預先包含了 ROS 2 Humble 和 Ubuntu 作業系統。


總之,這個 Docker 命令設定了一個功能強大且具備GPU 加速、圖形顯示能力、序列埠通訊、以及主機文件共享的 ROS 2 開發環境,非常適合需要與硬體互動、進行模擬或視覺化操作的 ROS 2 專案。

沒有留言:

張貼留言