ROS 2 Domain ID
ROS_DOMAIN_ID 用來選擇 ROS 2 Process 所使用的 DDS Domain。需要彼此通訊的 Node 與工具通常必須位於相同 Domain,而互不相關的系統則可以使用不同的 Domain ID,避免彼此意外 Discovery。
概述
ROS 2 Communication 建立在 DDS Discovery 之上,而 Domain ID 是 DDS 用來判斷哪些 Participant 屬於同一個 Discovery Domain 的第一層設定之一。
在一般 ROS 2 Discovery 情況下,需要彼此通訊的 Participant 通常必須使用相同的 Domain ID,包括:
- ROS 2 Node
- CLI Terminal
- RViz2
- rosbag Recording 或 Playback Process
- 執行在 Container 內的 ROS 2 Application
相同的 Domain ID 是一般 Discovery 的必要條件,但並不足以單獨保證通訊成功。Network Connectivity、Firewall Rule、DDS / RMW Configuration、Discovery Setting、Message Type 與 QoS Compatibility 仍然都會影響結果。
Domain ID 不是 Security Boundary
Domain ID 不會驗證 Participant 身分、不會加密 Traffic,也無法阻止其他系統選擇相同的 ID。
如果需要 Access Control、Authentication 或 Encryption,應使用適當的 Network Control 與 ROS 2 / DDS Security Mechanism。
當 ROS_DOMAIN_ID 沒有設定,且 Launcher 或 Application 也沒有另外覆寫時,ROS 2 一般預設使用 0。
不要假設所有 Robotic Suite Package 都使用 0。例如:
- 文件中的 Isaac package 使用
90 - 文件中的 QIR package 使用
55
在修改 Domain ID 之前,請先確認目前安裝版本的 Launch Configuration。
為什麼重要
同一個 Network 中可能同時存在多台 Robot、Development Machine、Container 或 Test Environment。
如果互不相關的系統使用相同 Domain ID,它們可能會 Discovery 到原本不應該加入同一個 ROS 2 System 的 Node。
反過來,如果原本應該彼此通訊的 Process 使用不同 Domain ID,通常就無法 Discovery 到對方。
因此,一致的 Domain ID 可以協助定義預期的 ROS 2 Discovery Group,尤其適用於:
- 同一個 Network 上有多台 Robot
- Host 與 Container Deployment
- 共用的 Development Lab
- RViz2 或 CLI Tool 執行在 Robot Container 之外
- rosbag Recording 與 Playback
- Multi-machine ROS 2 System
核心概念
相同 Domain ID
需要彼此通訊的 Participant 通常必須使用相同的 ROS_DOMAIN_ID。
例如:
Host ROS 2 node ROS_DOMAIN_ID=42
Container ROS 2 node ROS_DOMAIN_ID=42
RViz2 ROS_DOMAIN_ID=42
ros2 CLI ROS_DOMAIN_ID=42
只要其他 Network 與 Middleware 條件也符合,這些 Participant 就可以加入同一個 DDS Discovery Domain。
不同 Domain ID
使用不同 Domain ID 的 Participant,通常會位於不同的 DDS Discovery Domain。
例如:
Robot A ROS_DOMAIN_ID=42
Robot B ROS_DOMAIN_ID=43
當多個獨立系統共用相同 Physical Network 時,這種方式可以避免彼此 Discovery。
選擇 Domain ID
為每一個預期彼此通訊的系統指定一個 Domain ID;對於共用同一 Network、但彼此獨立的系統,則使用不同且尚未分配的 ID。
對預設 DDS UDP Port Mapping 而言,ROS 2 官方 Domain ID 文件 將 0 到 101 描述為在常見 Platform Configuration 下較保守、通常適合使用的範圍。
這不代表 101 以上的 ID 是無效的。
DDS 會根據 Domain ID 與 Participant 數量推導 UDP Port,因此實際安全範圍會受到作業系統 Ephemeral Port Range,以及單一 Host 上 DDS Participant 數量影響。
不要假設整個 0 到 232 範圍在所有 Deployment 中都一定安全。若要為大型或 Production System 選擇 Domain ID,請確認官方文件中的 Platform 與 Participant Constraint。
以下範例使用 42 僅作為示範。請替換成實際分配給你的系統的 Domain ID。
Production System 不要在沒有遵循該 Deployment 所規定的 Stop、Configuration 與 Restart Procedure 前,直接修改正在執行中的 Robot 或 Production Workload Domain ID。
實作步驟
1. 檢查目前 Environment
以下範例使用 Linux 上的 Bash。
先依照 CLI Basics 說明,source 正確的 ROS 2 Distribution 與必要的 Workspace Overlay。
以標準 ROS 2 Humble Installation 為例:
source /opt/ros/humble/setup.bash
printenv ROS_DISTRO
printf 'ROS_DOMAIN_ID=%s\n' "${ROS_DOMAIN_ID-unset}"
請依實際安裝的 ROS 2 Distribution 使用正確的 Setup Path。
如果 ROS_DOMAIN_ID 顯示為 unset,而 Launcher 或 Application 也沒有另外 Override,ROS 2 一般會使用預設值 0。
2. 設定目前 Shell 的 Domain ID
完成 ROS 2 Environment 與 Workspace Overlay Source 後:
export ROS_DOMAIN_ID=42
printenv ROS_DOMAIN_ID
最後一個指令應該會輸出:
42
每一個會進行以下操作的 Shell 都應該分別確認:
- 啟動 ROS 2 Node
- 執行 RViz2
- Record 或 Play Rosbag
- 使用 CLI Command 檢查 ROS 2 Graph
export 只會影響目前 Shell,以及之後從該 Shell 啟動的 Process。
它不會修改:
- 已經執行中的 Node
- 另一個 Terminal
- 已存在的 Container Process
- 由 Service Manager 啟動的 Service
修改 Domain ID 後,請安全停止並從正確 Environment 重新啟動受影響的 ROS 2 Process。
3. 必要時設定為 Persistent
對 Interactive Bash Terminal,先檢查目前 Startup Configuration:
grep -n 'ROS_DOMAIN_ID' ~/.bashrc
如果已經存在 Assignment,應直接修改原本的設定,而不是再增加一筆。
如果沒有任何預期的 Assignment,可以加入:
export ROS_DOMAIN_ID=42
請將它放在不會被後續 Startup Script 覆寫的位置。
不要重複在 .bashrc 中加入多筆 ROS_DOMAIN_ID 設定。
開啟新的 Terminal 後再次確認:
printenv ROS_DOMAIN_ID
Login Shell、其他 Shell Type、Service Manager、SDK Launcher 與 Container 可能會使用不同的 Configuration Source。
應修改真正用來啟動目標 Process 的 Environment,而不是無差別地修改整台機器上的所有 Environment。
4. 分別設定 Host 與 Container Environment
修改 Host Shell 不會自動修改 Container 內的 Environment。
同樣地,在某個 docker exec Shell 中執行 export ROS_DOMAIN_ID=...,也不會修改 Container 的 Startup Configuration 或其他已經執行中的 Process。
General FAQ 中記錄了 Robotic Suite 的 Compose Layout,以及既有的 stop.sh / launch.sh Lifecycle Workflow。
對使用這套 Layout 的 Release,先確認目標 Container:
docker ps --format '{{.Names}}'
設定 Container Name,並進入對應 Configuration Directory:
container_name=your_existing_container
cd "/usr/local/Advantech/ros/container/docker/docker-compose/${container_name}"
編輯現有的 docker-compose.yml。
請保留檔案原本使用的 environment Syntax。
如果 Service 使用 List Syntax:
environment:
- ROS_DOMAIN_ID=42
如果使用 Mapping Syntax:
environment:
ROS_DOMAIN_ID: 42
不要移除或覆蓋其他無關的 Environment Setting。
這個設定屬於 Container Configuration,不會自動從 Host 繼承。
如果 Compose File 使用 Variable Interpolation,請確認實際是哪一個 Shell 或 Environment File 提供該變數。
安全停止相關 Workload 後,FAQ 中記錄的 Lifecycle Workflow 為:
cd /usr/local/Advantech/ros/container/docker
./stop.sh "$container_name" && ./launch.sh "$container_name"
修改後的 Compose Environment 必須在 Container Create 或 Recreate 時才能真正套用。
單純執行:
docker restart <container_name>
只會保留既有 Container Configuration,不會套用修改後的 Compose Environment Definition。
請確認目前安裝版本中的 Robotic Suite Lifecycle Script 是否會 Recreate Container,或確實會套用更新後的設定。
如果該 Release 使用不同的 Recreation Procedure,請依該版本文件操作。
接著獨立確認 Container Environment:
docker exec "$container_name" printenv ROS_DOMAIN_ID
如果 Host-side ROS 2 Process 與 Container 內 Process 需要彼此通訊,兩者應使用相同的 Assigned Domain ID。
同時也要檢查 Container 內實際用來啟動 ROS 2 的 Shell 或 Launcher,因為 Startup Script 仍可能覆寫 Container-level Environment。
相同的 Domain ID 無法修正不相容的 Container Network Mode,也無法解決被阻擋的 DDS Discovery Traffic。
5. 驗證預期的 ROS 2 Graph
從正確 source 的 Shell 中,明確指定 Domain ID 進行檢查:
ROS_DOMAIN_ID=42 ros2 node list
ROS_DOMAIN_ID=42 ros2 topic list -t
你應該會看到屬於目標 Running System 的 Node 與 Topic。
不要預期會出現固定清單,實際 Graph 取決於目前有哪些 Process 正在執行。
單純看到 Empty Graph,並不能證明 Domain ID 一定設定錯誤。Network 或 DDS Discovery 問題也可能產生相同現象。
6. 選擇性執行純文字 Connectivity Test
如果要做獨立測試,請使用雙方事先約定、目前沒有其他系統使用的 Domain ID,並確認 Environment 中已安裝 demo_nodes_cpp。
不要啟動 Robot Driver,也不要送出 Actuator Command。
在第一個已經 source 的 Terminal 中:
ROS_DOMAIN_ID=42 ros2 run demo_nodes_cpp talker \
--ros-args -r chatter:=/domain_id_check
在第二個已經 source 的 Terminal 中:
ROS_DOMAIN_ID=42 ros2 run demo_nodes_cpp listener \
--ros-args -r chatter:=/domain_id_check
Listener 應該會持續顯示 Talker 發出的文字 Message。
使用:
Ctrl+C
停止兩個範例。
若要跨 Host / Container,或兩台 Host 進行測試,請先確認雙方 Network Configuration 與 Launch Environment,再分別在兩側各執行一個範例。
預期成果
正確設定 Domain ID 後:
- 需要彼此通訊的 Process 使用相同的
ROS_DOMAIN_ID ros2 node list與ros2 topic list -t可以看到預期的 ROS 2 Graph- 選擇性的 Talker / Listener Test 在雙方使用相同 Domain ID 時可以正常通訊
- 使用不同 Domain ID 的獨立 ROS 2 System,通常不會出現在相同 Discovery Graph 中
請記得,相同 Domain ID 只代表通訊設定中的其中一個條件。
DDS Discovery 仍然依賴彼此相容的 Network、Middleware 與 Discovery Configuration。
常用指令
# Check the current shell
printenv ROS_DOMAIN_ID
printf 'ROS_DOMAIN_ID=%s\n' "${ROS_DOMAIN_ID-unset}"
# Set the current shell
export ROS_DOMAIN_ID=42
# Inspect one domain explicitly
ROS_DOMAIN_ID=42 ros2 node list
ROS_DOMAIN_ID=42 ros2 topic list -t
# Check a container
docker exec "$container_name" printenv ROS_DOMAIN_ID
# Restart the ROS 2 CLI daemon for the domain being inspected
ROS_DOMAIN_ID=42 ros2 daemon stop
ROS_DOMAIN_ID=42 ros2 node list
常見問題
-
Shell 已經顯示新的 ID,但執行中的 Node 仍然使用舊值 — 修改 Environment Variable 不會改變已經執行中的 Process。請安全重新啟動相關 Process,並檢查 Launcher、Service Manager 或 Container Environment 是否有額外 Override。
-
Domain ID 相同,但 Discovery 仍然失敗 — 檢查 Network Reachability、Multicast 或已設定的 Discovery Server Access、Firewall Rule、Container Networking、
ROS_LOCALHOST_ONLY,以及彼此相容的 RMW / DDS Setting。可參考 DDS Discovery。 -
Topic 看得到,但沒有收到 Message — 這代表 Domain ID 與 Discovery 至少已經部分正常。接著檢查完整 Topic Name、Message Type、Active Publisher 與 QoS Compatibility。可參考 QoS Mismatch。
-
Graph 中出現不預期的 Robot — 檢查雙方實際的 Launch Environment。如果兩個系統應該彼此獨立,請分配不同的 Domain ID。ROS 2 Namespace 本身不會建立獨立 DDS Domain。
-
Host 看得到 ROS 2 Node,但 Container 看不到 — 分別檢查 Container 內的 Domain ID,並確認 Container Network Mode 支援需要的 DDS Discovery Traffic。
-
CLI Graph Information 看起來過期 — ROS 2 CLI daemon 與 Domain ID 有關。可以重新啟動目前正在檢查的 Domain Daemon:
ROS_DOMAIN_ID=42 ros2 daemon stopROS_DOMAIN_ID=42 ros2 node list下一次 Graph Query 會重新啟動 Daemon。
這些指令只會操作 Domain ID
42對應的 Daemon;不會重新啟動 Application Node,也不會停止屬於其他 Domain ID 的 Daemon。
重點整理
- 需要彼此 Discovery 與通訊的 ROS 2 Process,通常必須使用相同的
ROS_DOMAIN_ID。 - 當多個獨立 ROS 2 System 共用相同 Physical Network 時,可以使用不同 Domain ID 進行隔離。
- 相同 Domain ID 是一般 Discovery 的必要條件,但 Network、DDS / RMW、Firewall、Message Type 與 QoS Setting 仍可能造成通訊失敗。
- Host Shell、Container、Service 與不同 Terminal 必須分別確認,因為它們不會自動共用相同 Environment。
ROS_DOMAIN_ID是 Discovery Group Setting,不是 Authentication 或 Security Mechanism。- 選擇 Domain ID 時應考慮 DDS Port Allocation 與 Platform Constraint,不要假設理論範圍中的每個值在所有環境中都一定安全。