2025年7月3日 星期四

ROS2 (Docker Display TO GPU by X11 Forwarding 或 VNC)

 要在 Docker 容器內執行 Gazebo 的 gzclient 並進行驗證,

這通常需要一些額外的設定,因為 gzclient 是一個圖形介面應用程式,

而 Docker 容器預設是沒有圖形介面的。


核心概念:X11 Forwarding 或 VNC

要在 Docker 容器內顯示圖形應用程式,主要有兩種方法:

  1. X11 Forwarding (推薦且更直接): 透過將容器內的 X 應用程式顯示轉發到您主機的 X 伺服器上。

  2. VNC Server (更複雜,但適用於無法直接 X11 Forwarding 的情況): 在容器內運行一個 VNC 伺服器,然後從主機使用 VNC 客戶端連接到容器的 VNC 伺服器。

以下我們將著重說明更常用且直接的 X11 Forwarding 方法。


方法一:透過 X11 Forwarding 執行 gzclient

這是最直接的方法,讓容器內的圖形應用程式直接顯示在您的主機桌面。

前提條件:

  1. 您的主機上必須有 X 伺服器在運行。

    • Linux (Ubuntu/Debian 等): 大多數桌面版 Linux 都內建了 X 伺服器。

    • macOS: 您需要安裝 XQuartz (可從 xquartz.org 下載)。

    • Windows: 您需要安裝一個 X 伺服器軟體,例如 VcXsrv 或 Xming (可從 SourceForge 下載)。

  2. 在 Docker 容器內安裝 Gazebo。

步驟:

  1. 在主機上啟用 X 伺服器存取 (只在 Linux 主機需要): 在您的 主機 終端機中執行此命令:

    Bash
    xhost +local:docker
    

    這個命令允許本地 Docker 容器連接到您的 X 伺服器。注意: 這是個安全漏洞,因為它允許所有本地的 Docker 容器存取您的 X 伺服器。完成測試後,您可以執行 xhost -local:dockerxhost - 來撤銷權限。更安全的做法是使用 xhost +SI:localuser:$USER

  2. 啟動 Docker 容器並配置 X11 轉發: 使用以下命令啟動您的 Docker 容器。關鍵的參數是 -e DISPLAY=$DISPLAY-v /tmp/.X11-unix:/tmp/.X11-unix

    Bash
    docker run -it \
        --env="DISPLAY" \
        --env="QT_X11_NO_MITSHM=1" \
        --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
        --privileged \
        --net=host \
        <您的 Docker Image 名稱> \
        bash
    
    • -it: 以互動模式進入容器。

    • --env="DISPLAY": 將主機的 DISPLAY 環境變數傳遞給容器,告訴它 X 伺服器在哪裡。

    • --env="QT_X11_NO_MITSHM=1": 這個變數有時可以解決 Qt 應用程式(如 gzclient)在某些 X11 設定下的問題。

    • --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw": 將主機的 X11 socket 文件掛載到容器內,這是 X 應用程式與 X 伺服器通信的通道。

    • --privileged: 這個參數給予容器更多權限,在某些情況下對於圖形或設備存取可能會需要 (但不是所有情況都必須)。

    • --net=host: 讓容器使用主機的網路堆棧。這簡化了 X11 轉發的網路設定,因為容器可以直接看到主機的網路介面。

  3. 在容器內執行 Gazebo 和 gzclient 進入容器的 shell 後,您可以像在普通 Ubuntu 環境中一樣啟動 Gazebo:

    Bash
    # 如果您的環境變數沒有自動設置,可能需要先 source ROS 2 環境
    source /opt/ros/humble/setup.bash # 替換為您的 ROS 2 版本
    
    # 啟動 Gazebo 的空白世界 (這會同時啟動 gzserver 和 gzclient)
    ros2 launch gazebo_ros gazebo.launch.py
    

    如果一切設定正確,Gazebo 的圖形視窗應該會在您的主機桌面上彈出。

如何驗證:

  • 看到 Gazebo 視窗彈出: 最直接的驗證方法就是看到 gzclient 的圖形視窗在您的主機桌面正常顯示。

  • 在視窗內操作: 嘗試在 Gazebo 視窗中移動相機、插入一些簡單的模型(如立方體、球體),如果能正常互動,則表示成功。

  • 檢查日誌: 如果 gzclient 啟動失敗,檢查容器終端和主機終端的日誌輸出,尋找類似 qt.qpa.xcb: could not connect to display 或其他圖形相關的錯誤訊息。如果沒有此類錯誤,那麼 X11 轉發很可能正常。


方法二:在容器內運行 VNC Server (較複雜)

這種方法會在容器內創建一個虛擬桌面,您需要一個 VNC 客戶端來連接。

步驟:

  1. Dockerfile 配置: 您需要在 Dockerfile 中安裝 VNC 伺服器 (如 tightvncservernovnc) 和一個輕量級的桌面環境 (如 xfce4)。

  2. 啟動容器並運行 VNC 伺服器: 啟動容器後,您需要啟動 VNC 伺服器並暴露 VNC 埠。

  3. 從主機連接: 使用 VNC 客戶端連接到容器的 VNC 伺服器。

這種方法通常在以下情況下使用:

  • 主機是 Windows,但您不想安裝 X 伺服器。

  • 您希望在容器內擁有一個獨立的桌面環境。

  • 您需要透過網頁瀏覽器存取容器內的圖形介面 (結合 novnc)。

對於簡單的 gzclient 驗證,X11 Forwarding 通常是更簡單、更推薦的方法。

選擇適合您主機環境和需求的驗證方法,並確保所有前置條件都已滿足。


執行 xhost +local:docker 命令並看到了 

non-network local connections being added to access control list 

的輸出。

這個輸出不是錯誤訊息,而是一個確認訊息。它表示您的 xhost 命令已成功執行,並且您的 X 伺服器已將來自本地 Docker 容器的非網路連接添加到其存取控制列表(access control list)中。

這就是您在設定 Docker 容器的 X11 轉發時所期望的行為。它允許 Docker 容器內的圖形應用程式(例如 Gazebo 的 gzclient 或 RViz2)在您的主機桌面顯示。

總結:

  • xhost +local:docker 執行成功了

  • 您可以繼續下一步,啟動您的 Docker 容器,並配置好 DISPLAY 環境變數和掛載 /tmp/.X11-unix

如果您在執行完上述步驟後,在 Docker 容器內啟動 gzclient 或其他圖形應用程式時仍然遇到顯示問題,那可能需要檢查 Docker 容器的啟動參數、X 伺服器本身是否運行正常,或者驅動程式的問題。但就 xhost 這一步而言,它已經成功了。


沒有留言:

張貼留言