本文記錄了如何在遠端的 Ubuntu Linux 24.04 LTS 環境下,以無介面(headless)模式運用伺服器上的高規格 GPU 運行 CARLA 自動駕駛模擬器,並將畫面模擬顯示在本地端。

CARLA 是一套開放原始碼的自動駕駛模擬器,可以用來開發、訓練與驗證自動駕駛系統,但是這套自動駕駛模擬器需要比較高規格的 GPU 進行計算與畫面渲染,如果可以將需要大量運算的 CARLA 伺服器放在遠端的 GPU 上面跑,對於開發者來說會比較方便,不用把整台 CPU 的工作站放在辦公室。

以 Docker 執行 CARLA 伺服器

依照 Docker 官方文件先把 Docker 環境安裝好,在 Linux 系統下安裝完成後,記得要再進行 Docker 的權限設定。然後再依照 NVIDIA 官方文件安裝 NVIDIA Container Toolkit,讓 NVIDIA 的 GPU 可以正常在 Docker 容器內運行。

參考 CARLA Unreal Engine 5 官方的說明文件,下載 CARLA 0.10.0 版的 Docker 影像檔:

# 下載 CARLA 0.10.0 版的 Docker 影像檔
docker pull carlasim/carla:0.10.0

然後使用以下指令,以無介面模式啟動 CARLA 伺服器:

# 以無介面模式啟動 CARLA 伺服器
docker run \
    --rm \
    --runtime=nvidia \
    --net=host \
    --env=NVIDIA_VISIBLE_DEVICES=all \
    --env=NVIDIA_DRIVER_CAPABILITIES=all \
    carlasim/carla:0.10.0 bash CarlaUnreal.sh -RenderOffScreen \
    -nosound -fps=20 -benchmark -quality-level=epic

這裡 CarlaUnreal.sh 後方所指定的參數可以自行調整,以下是一些常用的參數與意義,這些參數是不分大小寫的:

  • -RenderOffScreen:螢幕外渲染模式,也就是不會將渲染畫面直接輸出至螢幕上。
  • -nosound:不要輸出聲音。
  • -fps=20:指定渲染畫面的 FPS(frames per second)值,也就是每秒的畫面張數。
  • -benchmark:以固定時間步長(fixed-step)運行每一格畫面,防止跳格,通常會搭配錄製或導出影片功能使用。
  • -quality-level=epic:渲染畫面的品質,可以選擇 lowepic

目前的 CARLA ue5-dev 分支搭配的 Unreal Engine 版本是 5.5,關於 CarlaUnreal.sh 其他可用的參數,可以參考 Unreal Engine 5.5 的官方文件CARLA 的文件

Client 端 Python API

這裡我們的 CARLA 伺服器採用的是 0.10.0 的版本,所以在 client 端的 CARLA Python API 也要用相同的版本,根據不同的作業系統,會有不同的做法,但原則都一樣,就是找到對應版本的 CARLA Python API,安裝使來使用即可。

Windows 11 桌面環境

如果自己的電腦是 Windows 11 系統,可以從 CARLA 的 GitHub 上面下載 CARLA_0.10.0.zip 這個預先編譯好的壓縮檔,把它解開之後會得到一個 Carla-0.10.0-Win64-Shipping 目錄,把裡面的 PythonAPI 整個複製到 Windows 11 中,在 PythonAPI/carla/dist 目錄中有對應各個 Python 版本的 wheel 套件,請依照自己 Windows 11 下的 Python 版本來安裝。

例如 Python 3.12 就安裝 carla-0.10.0-cp312-cp312-win_amd64.whl 這個 wheel 套件檔案,安裝之前建議可以使用 Python 的 venv 模組建立獨立的虛擬環境,再進行相關的模組安裝。

# 使用 pip 安裝 wheel 套件檔案
pip3 install carla-0.10.0-cp312-cp312-win_amd64.whl

然後再安裝一些必要的套件:

# 安裝必要套件
pip3 install pygame numpy

將 CARLA 提供的 carla 套件安裝完成後,就可以嘗試執行 PythonAPI/examples 目錄下的範例程式進行測試了。這裡要注意在執行時要指定遠端的 CARLA 伺服器的 IP 位址,同時也要注意防火牆等連線問題,預設的 CARLA 連線會使用 20002001 這兩個連接埠(port)。

假設我們的 CARLA 伺服器 IP 是 192.168.1.2,則以 manual_control.py 這個範例來說,我們可以用 --host 參數指定遠端的 CARLA 伺服器的 IP 位址:

# 執行 manual_control.py  範例程式
python3 manual_control.py --host 192.168.1.2

在桌面環境中因為只是單純顯示畫面,所以不需要高規格的 GPU 顯示卡也可以跑,但是由於 CARLA 渲染的畫面會從伺服器端傳送到本地端進行顯示,所以如果網路頻寬不夠的話,畫面就會有卡頓的現象。

Windows 11 顯示 CARLA 遠端 GPU 模擬畫面

Windows 11 顯示 CARLA 遠端 GPU 模擬畫面

另外 PythonAPI/util 目錄中也一些工具程式可以使用。

Ubuntu Linux 桌面環境

若自己的桌面環境是 Ubuntu Linux,作法也是跟 Windows 11 類似,先從 CARLA 的 GitHub 上面下載 CARLA_0.10.0.tar.gz 這個預先編譯好的壓縮檔,裡面一樣有一個 PythonAPI 目錄,後續的操作方式就跟 Windows 11 環境完全相同。

# 下載 CARLA_0.10.0.tar.gz
wget -O CARLA_0.10.0.tar.gz https://tiny.carla.org/carla-0-10-0-linux-tar

# 只解壓縮 Carla-0.10.0-Linux-Shipping/PythonAPI 目錄
tar zxvf CARLA_0.10.0.tar.gz Carla-0.10.0-Linux-Shipping/PythonAPI

# 使用 pip 安裝 wheel 套件檔案
cd Carla-0.10.0-Linux-Shipping/PythonAPI/carla/dist
pip3 install carla-0.10.0-cp312-cp312-linux_x86_64.whl

# # 安裝必要套件
pip3 install pygame numpy

接著就可以按照一樣的方式,執行 PythonAPI/examples 下的範例程式了。

# 執行 manual_control.py  範例程式
python3 manual_control.py --host 192.168.1.2

從 Docker 影像檔中取得 PythonAPI

如果自己的 Ubuntu Linux 桌面環境用的 Python 版本剛好也是 3.10,可以直接從剛剛上面的 Docker 影像檔中取出 PythonAPI 目錄,就不用再下載一次整個 CARLA_0.10.0.tar.gz

以下指令會將 Docker 容器內的 PythonAPI 目錄直接複製到目前目錄下。

# 從 Docker 影像檔中複製出 PythonAPI
docker run --rm -v $(pwd):/output carlasim/carla:0.10.0 cp -r /home/carla/PythonAPI /output

SSH 安全加密通道

如果不想讓 CARLA 伺服器的 20002001 連接埠直接暴露在外頭,可以在 SSH 連線時建立安全加密通道(SSH tunnel),將伺服器上面的 20002001 連接埠導向至本地端,這樣使用上會更方便.且更安全。

以 Linux 系統為例,可以使用以下指令來建立 SSH 安全加密通道:

# 建立 SSH 安全加密通道
ssh -L 2000:localhost:2000 -L 2001:localhost:2001 [email protected]

其中 gtwang192.168.1.2 要記得換成自己的帳號名稱與伺服器 IP 位址。

然後在遠端執行 CARLA 的 Docker 容器時,只將 20002001 連接埠開在本機:

# 以無介面模式啟動 CARLA 伺服器(傾聽埠只開在本機)
docker run \
    --rm \
    --runtime=nvidia \
    --env=NVIDIA_VISIBLE_DEVICES=all \
    --env=NVIDIA_DRIVER_CAPABILITIES=all \
    -p 127.0.0.1:2000:2000 -p 127.0.0.1:2001:2001 \
    carlasim/carla:0.10.0 bash CarlaUnreal.sh -RenderOffScreen \
    -nosound -fps=20 -benchmark -quality-level=epic

這樣在本地端執行範例程式時就可以直接連到 localhost,自動透過 SSH 安全加密通道轉發至遠端伺服器:

# 執行 manual_control.py  範例程式(連線至 localhost)
python3 manual_control.py

這是在 Ubuntu Linux 24.04 桌面環境下執行的畫面。

Ubuntu Linux 24.04 顯示 CARLA 遠端 GPU 模擬畫面

Ubuntu Linux 24.04 顯示 CARLA 遠端 GPU 模擬畫面

這裡使用 Docker 預設的橋接(bridge)網絡模式,只將 20002001 連接埠開在本機,雖然比較安全,但是 CARLA 就會被關在 Docker 容器內,若要跟外頭的 ROS 2 溝通就會有問題。

ROS 2

如果 Docker 容器內的 CARLA 需要跟外面的 ROS 2 溝通時,就要採用原始的主機(host)網路模式,加上 --ros2 參數:

# 以無介面模式啟動 CARLA 伺服器(啟用 ROS 2)
docker run \
    --rm \
    --runtime=nvidia \
    --net=host \
    --env=NVIDIA_VISIBLE_DEVICES=all \
    --env=NVIDIA_DRIVER_CAPABILITIES=all \
    carlasim/carla:0.10.0 bash CarlaUnreal.sh -RenderOffScreen \
    -nosound -fps=20 -benchmark -quality-level=epic --ros2

這樣在遠端的伺服器上面,就可以透過 ROS 2 跟 Docker 容器內的 CARLA 交換資料了。而如果不想讓太多連接埠開放在網路上,可以使用 Ubuntu Linux 本身的防火牆去保護。

參考資料