Nav2 導航系統總覽

2026-07-18
  • ros2
  • nav2
  • navigation
  • lifecycle-node

問題定義

前面章節建立的模型、模擬環境、感測器資料,都是讓機器人「知道自己周圍長什麼樣子」的基礎建設。但要讓機器人真正從 A 點自主移動到 B 點、途中避開障礙物,需要一整套協調運作的軟體:讀取地圖、定位自己的位置、規劃路徑、即時避障、把規劃結果轉成實際的速度指令。Nav2(Navigation2)就是 ROS2 生態系裡標準的自主導航框架,把這一整套流程模組化,讓你不用從零開始寫路徑規劃演算法。

核心概念說明

Nav2 是一組協同運作的伺服器,不是單一節點

Nav2 把導航拆成好幾個各自獨立、透過主題與動作介面溝通的伺服器:

伺服器職責
controller_server根據當前路徑與即時感測資料,計算實際要下達的速度指令
planner_server根據地圖,規劃一條從起點到終點的全域路徑
behavior_server執行行為(例如原地轉圈重新定位、後退避開卡死狀態)
bt_navigator用行為樹(Behavior Tree)協調上述伺服器的執行順序與條件分支
costmap (分為 global/local)把地圖與即時感測資料轉換成規劃演算法能用的「代價地圖」

這種分散式設計呼應了第 2 章介紹過的 ROS2 核心理念:每個伺服器職責單一、透過標準介面通訊,你可以只替換其中一個伺服器(例如換一個不同的路徑規劃演算法)而不影響其他部分。

生命週期節點:讓一整組伺服器可以被統一、有序地管理

Nav2 的伺服器都是生命週期節點(Lifecycle Node),這是 ROS2 提供的一種特殊節點型態,比一般節點多了明確的狀態機:Unconfigured → Inactive → Active → Finalized。這解決了一個實際問題——十幾個伺服器如果各自獨立啟動,很難確保它們都在正確的順序、正確的時機準備就緒(例如 controller_server 不該在 costmap 還沒載入地圖前就開始運作)。lifecycle_manager 這個節點負責統一管理一組生命週期節點的狀態轉換,確保整套系統是有序地「配置好、再啟動」,而不是各自為政。

bash
ros2 lifecycle get /controller_server
text
active [3]

三層座標系:map、odom、base_link

Nav2 的運作建立在第 4.3 節介紹的 TF 樹之上,並且遵循一套慣例:

  • base_link:機器人本體座標系,跟前面章節介紹的完全一樣。
  • odom:里程計座標系,由輪速計、IMU 等感測器累積計算得出,特性是短時間內連續平滑,但長時間會因為累積誤差而「漂移」(實際位置跟 odom 認為的位置逐漸偏離)。
  • map:全域地圖座標系,由定位演算法(比對即時感測資料與地圖)持續修正,特性是長時間精準,但修正發生的瞬間,mapodom 之間的轉換可能會有不連續的小跳動。

map → odom → base_link 這條 TF 鏈,讓控制器可以用平滑但會漂移的 odom 做即時控制(避免跳動造成控制不穩定),同時讓全域規劃用精準的 map 座標系工作,兩種特性分開處理、互不干擾,是理解 Nav2(以及後面 SLAM 章節)行為的關鍵前提。

實作範例:啟動最小化的 Nav2 系統,觀察生命週期轉換

這一節先不深入個別伺服器的參數調校(後面幾節會分別處理地圖建立與代價地圖),聚焦在觀察生命週期節點如何被統一管理。

1. 啟動 Nav2 的 controller_server 與對應的 lifecycle_manager

bash
ros2 run nav2_controller controller_server

另開終端機:

bash
ros2 run nav2_lifecycle_manager lifecycle_manager --ros-args \
  -p autostart:=true \
  -p node_names:="['controller_server']"

預期輸出

lifecycle_manager 的終端機會依序顯示狀態轉換過程:

text
[INFO] [lifecycle_manager]: Starting managed nodes bringup...
[INFO] [lifecycle_manager]: Configuring controller_server
[INFO] [lifecycle_manager]: Activating controller_server
[INFO] [lifecycle_manager]: Managed nodes are active

2. 確認節點目前的生命週期狀態

bash
ros2 lifecycle get /controller_server
text
active [3]

3. 手動觸發狀態轉換,觀察行為差異

bash
ros2 lifecycle set /controller_server deactivate
text
Transitioning successful

再次查詢會看到狀態變成 inactive——這時候即使有節點發送導航目標,controller_server 也不會有任何反應,因為它已經被明確地「停用」,這是生命週期節點跟一般節點最大的差異:一般節點只要行程還在跑就會處理收到的請求,生命週期節點則有明確的「目前處不處於工作狀態」開關。

常見錯誤與除錯技巧

錯誤一:伺服器啟動了,但 lifecycle_manager 一直卡在 Configuring,沒有進到 Activating

text
[INFO] [lifecycle_manager]: Configuring controller_server
(之後沒有任何進一步輸出,程式沒有結束但也沒有繼續)

原因:常見原因是 controller_server 需要的參數沒有正確提供(例如缺少必要的 plugin 名稱設定),導致 configure 這個轉換過程本身卡住或內部拋出例外,但沒有明確的錯誤訊息浮現到 lifecycle_manager 這一層。

排除方式:直接看 controller_server 自己的終端機輸出,而不是只看 lifecycle_manager 的畫面——生命週期轉換失敗的具體原因,通常會以 log 形式出現在被管理的節點自己的輸出裡:

bash
ros2 param get /controller_server controller_plugins

如果這裡回報找不到參數,代表啟動 controller_server 時沒有提供必要的參數檔案,需要補上(下一節開始會用到完整的參數檔案範例)。

錯誤二:ros2 lifecycle set 回報轉換失敗

text
Transition failed to trigger transition 3

原因:生命週期節點的狀態機有嚴格的合法轉換路徑(例如不能從 Unconfigured 直接跳到 Active,必須先經過 Inactive),如果嘗試觸發一個不合法的轉換順序就會失敗。

排除方式:先用 ros2 lifecycle get 確認節點目前實際所在的狀態,再對照生命週期狀態機圖確認要觸發的轉換是否合法,通常正確順序是 configureactivate

bash
ros2 lifecycle list /controller_server
text
- configure [1]
	Start: unconfigured
	Goal: configuring
- cleanup [2]
	Start: inactive
	Goal: cleaningup

這個指令會列出「目前狀態底下」合法的轉換選項,比憑印象猜測可靠。

小結

Nav2 由多個職責單一的伺服器組成,透過生命週期節點與 lifecycle_manager 統一管理啟動與狀態轉換,避免十幾個伺服器各自為政造成的時序問題;map → odom → base_link 的三層座標系設計,把「長期精準但會跳動」與「短期平滑但會漂移」兩種特性分開處理。有了這層架構認識,下一節要處理的是 map 座標系從何而來——用 SLAM Toolbox 建立一張地圖。

延伸閱讀

常見問題

faq_01.log
Nav2 一定要搭配真實機器人才能測試嗎?
不需要,Nav2 對底層機器人硬體的要求只有兩個介面:接收 cmd_vel 速度指令、發布 odometry 里程計資料。第 5 章介紹的 Gazebo 模擬完全能提供這兩個介面,實務上 Nav2 的行為調校絕大多數工作都是先在模擬環境裡完成,才進到真實機器人上做最後驗證。
faq_02.log
map、odom、base_link 這三個座標系為什麼不能只用一個代替?
因為它們分別代表不同性質、不能互相取代的資訊來源:map 是全域地圖座標系,位置修正(例如透過光達比對地圖)會讓 map 到 odom 之間的轉換偶爾跳動;odom 是里程計累積座標系,短時間內連續平滑但長時間會漂移;base_link 是機器人本體。把三層分開,讓『長時間精準但可能跳動』與『短時間平滑但會漂移』這兩種特性各自獨立存在,控制器可以放心用平滑的 odom 做即時控制,同時讓上層用 map 做全域定位修正,不會互相干擾。
faq_03.log
Nav2 的節點都需要手動一個個啟動嗎?
不需要,Nav2 提供官方的 bringup launch 檔案,一次啟動並管理所有伺服器的生命週期轉換,也是第 3.4 節介紹的 launch 檔案機制在真實大型系統裡的典型應用。本節為了說明架構會分開介紹每個伺服器的角色,實際開發時通常是透過 launch 檔案整組啟動。