Troubleshooting
本頁提供一套系統化的 ROS 2 問題排查清單,涵蓋最常遇到的情況:Topic 消失、Type Mismatch、QoS 不相容、Domain ID 衝突、DDS Discovery 問題、Container Networking、Timestamp / Clock 問題、TF 錯誤,以及 Permission 問題。
每個章節都會提供對應指令,讓你在進入下一個檢查項目前,先確認或排除目前這個可能原因。
概述
大多數 ROS 2 問題都可以歸類到少數幾種類型。只要知道應該從哪裡開始檢查,通常都能透過命令列快速縮小問題範圍。
建議依照下方對應章節的順序逐項檢查,在同一個章節中由上往下進行,而不是直接猜測原因。
為什麼重要
「不能運作」本身並不是可直接採取行動的資訊。
一套簡短、可重複執行的 Diagnostic Sequence,可以把模糊的現象逐步縮小成明確且可修正的原因,也通常比反覆嘗試修改程式碼或設定更有效率。
Topic 消失
預期應該存在的 Node、Topic、Service 或 Action 完全沒有出現在系統中。
-
確認目前 Terminal 已經 source ROS 2 環境:
printenv ROS_DISTROwhich ros2可參考 CLI 基礎操作。
-
確認 Node 實際上正在執行,而不是啟動後立即 Crash:
ros2 node list如果沒有看到該 Node,請檢查啟動它的 Terminal 是否有 Stack Trace 或 Error。
-
確認
ROS_DOMAIN_ID一致:執行 Node 的 Terminal 與執行 CLI 的 Terminal 必須使用相同的ROS_DOMAIN_ID。可參考下方 Domain ID。 -
確認 Topic 完整解析後的名稱與 Namespace:
ros2 topic list程式碼中使用的 Relative Topic Name,可能會根據 Node 所在的 Namespace 被解析成不同的 Fully Qualified Name。
-
如果 Topic 已經存在,但
echo沒有任何輸出,檢查 QoS 是否不相容。可參考下方 QoS Mismatch。
Type Mismatch
兩個 Node 看起來使用相同的 Topic 或 Service Name,但無法交換資料;或 CLI Call 回報 Type Error。
ros2 topic type /some_topic
ros2 interface show <package>/msg/<Type>
- 通訊雙方的 Package Name 與 Type Name 必須完全一致。例如
std_msgs/msg/String與具有相同欄位的 Custom Message 並不是同一個 Type。 - 如果使用自訂 Interface Package,在修改任何
.msg、.srv或.action檔案後,請確認已重新 Build,並重新 source Overlay。使用到舊的 Generated Code 是常見的「以前可以,現在不行」原因。 - 對 Service / Action,可使用
ros2 interface show檢查 Request / Response 或 Goal / Result / Feedback 結構,再逐一比對 Client 實際送出的欄位。
QoS Mismatch
Publisher 與 Subscriber 都存在於相同 Topic 上,但資料沒有成功傳遞。
ros2 topic info /some_topic -v
這個指令會列出該 Topic 上每一個 Publisher 與 Subscriber 的 QoS Profile,包括 Reliability、Durability、History 與 Depth。
常見的不相容情況包括:
| Setting | 會造成 Delivery 失敗的不相容情況 |
|---|---|
| Reliability | Publisher 使用 BEST_EFFORT,Subscriber 使用 RELIABLE(Subscriber 要求的保證高於 Publisher 能提供的等級) |
| Durability | Publisher 使用 VOLATILE,Subscriber 使用 TRANSIENT_LOCAL(Subscriber 預期 Late-joining 時能取得最後一筆資料,但 Publisher 不會保留) |
解決方式是讓 Publisher 與 Subscriber 的 QoS Profile 彼此相容。
兩邊不需要完全相同,但 Publisher 提供的 QoS Guarantee 必須能滿足 Subscriber 所要求的 Profile。
Domain ID
Node 理論上應該彼此可見,但即使在相同 Network 中仍然看不到,而且沒有其他明顯原因。
printenv ROS_DOMAIN_ID
- 應該參與相同 ROS 2 DDS Domain 的 Node,通常需要使用相同的
ROS_DOMAIN_ID;未設定時預設為0。Domain ID 一致是一般 Discovery 的必要條件,但如果 Network、Middleware、Firewall 或 Discovery Setting 不相容,仍不保證一定能通訊。 - Advantech Robotic Suite 提供 Helper Script,可用來一致地修改設定;請參考 ROS 2 Domain ID。
- Host 與 Container Shell 都要分別確認。Container 不一定會自動繼承 Host 的 Environment Variable。
DDS Discovery
Node 已經使用相同 Domain ID,但仍然無法彼此發現,尤其是在跨機器、Wi-Fi 或 VPN 環境中。
-
Multicast-based Discovery 是大多數 RMW / DDS Implementation 的預設方式,但可能受到 Network Configuration、Firewall 或部分 Virtual / VPN Network Adapter 阻擋。先確認相關機器之間具備基本 Network Connectivity,例如使用
ping。 -
檢查目前使用的 RMW Implementation,因為這會影響 Discovery Behavior 與可使用的調整方式:
printenv RMW_IMPLEMENTATION -
ros2 doctor可以進行多項基本 Environment 與 Network 檢查,是合理的第一步:ros2 doctor --report -
如果 Node 分布在多台機器上,請確認 Firewall Rule 允許 DDS Traffic。實際使用的 Port 與 Protocol 取決於目前使用的 RMW Implementation,請參考該 Implementation 的文件,不要假設所有環境都使用相同 Port Range。
Containers
Advantech Robotic Suite 在部分 Platform 上會於 Container 中執行 ROS 2,因此 Container Boundary 也可能帶來額外的 Discovery 與 Environment 問題。
-
確認 Container 的 Network Mode 能支援所需的 DDS Discovery Traffic。對 Local Discovery 而言,Host Networking 通常是最直接的設定;Bridged Networking 則往往需要額外設定。
-
Host 上設定的 Environment Variable,例如
ROS_DOMAIN_ID、RMW_IMPLEMENTATION,不會自動出現在 Container 內,除非啟動 Container 時明確傳入,或在 Container Shell 中重新設定。兩邊都應獨立確認:docker exec -it <container_name> bash -c 'printenv ROS_DOMAIN_ID' -
如果 Container 內的 Node 看不到 Host 上或另一個 Container 中的 Node,先確認它們使用相同 Domain ID 與適當的 Network Mode,再進一步檢查更複雜的問題。
Timestamp 與 Clock
與時間相關的功能,例如 TF Lookup、Message Filtering 或 Synchronized Playback,行為不如預期。
- 確認相關 Node 是否預期使用 Simulated Time。如果某個 Node 的
use_sim_time為true,但系統中沒有任何來源發布/clock,該 Node 的 Clock 將不會正常前進。可參考 Rosbag。 - 如果 Timestamp 會跨多台機器進行比較,請確認各機器的 System Clock 已合理同步。過大的 Clock Skew 可能會產生看起來像 TF 或 QoS 問題的現象。
- 如果出現
"extrapolation into the future/past"類型的 TF Error,請參考下方 TF Issues。
TF Issues
完整的 Frame 與 Transform 說明可參考 TF2。
快速檢查流程:
ros2 run tf2_ros tf2_echo <source_frame> <target_frame>
ros2 run tf2_tools view_frames
"Frame does not exist"— 尚未有任何來源發布該 Frame ID 的 Transform。請檢查拼字,並確認對應 Publishing Node 正在執行。"Lookup would require extrapolation"— 要查詢的 Timestamp 超出 TF2 保留的 Buffer 範圍。如果不需要特定歷史時間,應改為要求最新可用 Transform。- RViz 中的 RobotModel 凍結、破碎或抖動 — 檢查是否有缺少或互相衝突的 TF、Timestamp / Simulated Time 問題,以及缺少或不一致的
/joint_states。如果正在播放 Bag,也要確認 Recorded TF 是否與 Live Node(例如robot_state_publisher)產生的 Transform 重疊。
Permissions
指令出現 Permission Denied,而不是 ROS 2 本身的錯誤。
-
Script-based Node 缺少 Executable Bit:對檔案執行
chmod +x。透過setup.py/colcon安裝的 Python Entry Point 通常不需要這一步,但手動執行的 Script 有時需要。 -
Device Access:Serial Port、USB Camera、CAN Interface 等硬體通常需要使用者加入特定 Group(例如
dialout),或設定udevRule。請依實際 Hardware Driver 文件確認所需 Group 或 Rule。 -
Container Volume / User Mismatch:Container 內建立的檔案可能屬於與 Host User 不同的 UID,導致 Host 端之後無法編輯或刪除。
-
rosdepPermission Error:rosdep init通常需要較高權限,因為它會建立 System-level Configuration:sudo rosdep initRun rosdep update as the normal user:
rosdep update
常用指令
# Environment
printenv ROS_DISTRO
printenv ROS_DOMAIN_ID
printenv RMW_IMPLEMENTATION
ros2 doctor --report
# Graph
ros2 node list
ros2 topic list -t
ros2 topic info <topic> -v
ros2 service list -t
ros2 action list -t
# TF
ros2 run tf2_ros tf2_echo <source_frame> <target_frame>
ros2 run tf2_tools view_frames
重點整理
- 依照問題類型逐步排查,例如 Missing Topic、Type Mismatch、QoS、Domain ID、DDS Discovery、Container、Timestamp、TF 與 Permission,而不是針對每一次問題各自猜測。
ros2 topic info -v與ros2 doctor --report可以獨立解決相當多「為什麼不能運作」類型的問題。- 需要彼此 Discovery 的 Node 通常必須使用相同的
ROS_DOMAIN_ID。RMW Implementation 與 Discovery / Transport Setting 也必須彼此相容。使用相同 RMW Implementation 通常可以簡化 Troubleshooting,但並不是絕對必要條件。 - TF 與 Playback 問題可能來自 Missing Transform、Timing Issue 或互相衝突的 TF Authority。播放 Bag 時,請確保重疊的 Transform 不會同時由多個 Source 產生。
下一步
如果問題已經解決,可以回到 ROS 2 學習地圖;如果需要更深入了解特定主題,可以重新查看 ROS 2 Domain ID、TF2 或 Rosbag。