最後,我們要來講導航這個終端應用了。 結合7.AMCL和里程計的訊息,可以得到相對精準的機器人當前位置。而當我們在前面slam得到的地圖中給出目標地點後,就是nav2開始計算導航控制的時候了。 而導航分為兩個部分:全局路徑規劃和局部路徑規劃(避障) 我們在SLAM得到了地圖,首先,Nav2會先對地圖上標示為255的點進行膨脹運算,在地圖上的障礙物外圈加上一個車子寬度+安全距離的膨脹層: ![](https://hackmd.io/_uploads/SyfZaEeT2.png) (此為當事LIMO的畫面,亮藍色部分就是膨脹出來的結果,車子規畫路徑時會避開) 車子針對膨脹後,剩下的0(可通行)位置進行運算,找出一條分數最高的路徑規劃,這就是全局導航做的事情。 當然,實際場景常常會多出一些當時建圖時不存在的障礙物,這時候我們就需要局部路徑規劃了。其實和全局規劃時相同,差別在這次使用了光達的訊息,對光達打到當下的障礙物進行膨脹,並規劃出不會碰撞的路徑。 程式實踐上最簡單的狀況會拆成五層 全局地圖: * Static Map Layer:SLAM掃完的原始地圖 * Obstacle Map Layer:障礙層,前面提到的非靜態障礙 * Inflation Layer:前面提到的膨脹,避免碰撞用 局部地圖: * Obstacle Map Layer:障礙層,前面提到的非靜態障礙+動態障礙 * Inflation Layer:前面提到的膨脹,避免碰撞用 對於某一些應用,有可能會多增設一些層,一些導航機體會看到的虛擬牆或者虛擬軌道等應用就是額外添加層去達成的。 {%youtube -_Ah-t7P6X4 %} (某台商用機體的虛擬牆功能) 地圖處理完畢,接著要給出目標地點。通常使用Rviz點擊地圖給,或者以程式送POSE訊息到goal_pose頻道,其內容包含XYZ座標和機器人的姿態訊息。當nav2收到goal_pose後,便會依照前述的規則運算出到目標點的路徑規劃。 運算完路徑後,要將路徑轉換為機體的控制指令。這個動作我們鮮少自行撰寫,基本都是交由control_server這個節點去處理。需要調整的最多就是機體的一些運動參數而已。這個節點會持續發出[[0.基本底盤控制]]提到的twist訊息到cmd_vel頻道,底盤節點只要訂閱這頻道就可以受到控制完成導航任務: {%youtube 1DFpux4KSAM %} (使用Rviz給點的方式) --- {%youtube 9heZi-RkDzk %} (使用程式送goal_pose的方式) 參數調整得好不好會影響導航的表現,而控制命令目前也僅是直送,可能會看到一些頻繁修正路徑的狀況,這點也可以透過攔截cmd_vel頻道,設計PID節點來改善--但這就不在本次的科普內容了。