跳到正文

Wiki

map_server(已有二維地圖載入與釋出)

約 16 分鐘閱讀

本文由簡體中文內容確定性轉換,並受版本化術語表保護。

1.map_server(已有二維地圖載入與釋出)

1.1.實車先看:空路徑由誰填寫,讀的是哪一張地圖

map_server讀取已有二維地圖的YAML及配套圖片,釋出OccupancyGrid給靜態代價層;當前工程通過launch的map引數填寫yaml_filename。 因此這裡的空字串是啟動時重寫的佔位值,不能單看這行就判斷沒有地圖。

实物/仿真入口:map启动参数
    → bringup_launch → localization_launch
    → 重写map_server.ros__parameters.yaml_filename
    → map_server:读取地图YAML → 找到配套PGM/PNG → 转为二维占用网格
    → 配置、激活生命周期节点 → 发布namespace/map
    → local_costmap、global_costmap中的static_layer

prior_pcd_file → small_gicp:用实时三维点云匹配先验PCD,提供定位TF

二維圖載入與三維PCD定位是不同的輸入鏈。map_server不讀取PCD,不把當前雷達點雲拿去匹配二維圖片,也不自行產生map→odom定位變換。兩種地圖仍須採用一致的尺度、方向和座標約定。二維圖與PCD的分工、先驗點雲定位

實車上看到的現象 先核對什麼 當前配置怎樣理解
YAML路徑為空,卻能夠載入地圖 launch傳入的map及有效yaml_filename 當前重寫流程會替換已有空值;實際路徑來自啟動引數
修改nav2_params.yaml中的路徑,啟動後仍用舊圖 上層map啟動引數 當前launch總會用map值重寫該鍵;單改引數檔案中的字串可能被覆蓋
實物入口預設啟動失敗,提示找不到地圖 實物預設地圖檔案是否存在 當前預設map/reality/rmul_2024.yaml在原始碼和安裝目錄均不存在,需提供自己的有效二維圖
節點啟動了,/map卻沒有地圖訊息 最終路徑、檔案讀取及生命週期狀態 有節點/釋出器不等於已經載入並激活地圖;空路徑可以配置,但不會自動產生地圖
建圖時沒看到map_server slam啟動分支 slam=True使用slam_toolbox釋出/map;此節點在slam=False的定位分支啟動
圖片看起來灰色,載入後卻成了空閒 地圖檔案的mode、free_thresh與畫素灰度 儲存和讀取的門檻不是同一計算;本版本三態灰205與0.25的組合有已驗證的未知狀態丟失問題

本次安裝的nav2_map_server為1.1.20,安裝的map_server/map_io標頭檔案與該版本一致。以下按此版本及當前工程啟動檔案說明。MapServer實現

1.2.引數

保留髮送的引數與上方原註釋。註釋中的tb3_simulation_launch.py是通用示例名稱;當前工程實際使用rm_navigation_reality_launch.py、rm_navigation_simulation_launch.py、bringup_launch.py和localization_launch.py。

# The yaml_filename does not need to be specified since it going to be set by defaults in launch.
# If you'd rather set it in the yaml, remove the default "map" value in the tb3_simulation_launch.py
# file & provide full path to map below. If CLI map configuration or launch default is provided, that will be used.
map_server:
  ros__parameters:
    yaml_filename: ""

1.2.1.ros__parameters(地圖檔案入口)

1.2.1.1.參數列
引數名 當前值 單位 實車處理建議 作用 調大效果 調小效果 生效條件/備註
yaml_filename "";整套啟動時由map引數重寫 不適用,地圖YAML檔案路徑字串 上實物前必須核對並正確配置 指定初始載入的二維地圖後設資料檔案 不適用 不適用 當前可保留空值佔位,通過map:=實際絕對路徑配置;檔案與圖片均需存在;直接啟動並留空則不載入初始地圖
1.2.1.2.引數詳解
1.2.1.2.1.yaml_filename(節點引數檔案與地圖檔案是兩種YAML)

nav2_params.yaml是ROS節點引數檔案,裡面有map_server、map_saver、costmap等引數分組。yaml_filename指向的是一張二維地圖的後設資料YAML,其中寫image、resolution、origin等;不能把它設成nav2_params.yaml本身,也不能直接指向PGM、PNG或PCD。

1.1.20在configure階段讀取yaml_filename。非空時讀取地圖YAML和圖片,失敗會使配置過程失敗;空字串則跳過初始載入,建立話題與服務,允許之後通過load_map服務裝入地圖。空字串不表示自動建圖、不表示讀取當前目錄的某張圖,也不表示使用PCD替代二維圖。初始載入與空路徑分支

當前安裝的RewrittenYaml只替換已有葉子鍵,bare key形式的yaml_filename重寫不會自動補入缺失鍵。保留yaml_filename這一行,空值可交給launch填寫;不能按註釋把整個鍵刪掉。 MapServer原始碼宣告的是字串型別而不是一個自動場地路徑預設值,路徑預設來自工程launch。1.1.20引數重寫

1.2.1.2.2.當前launch怎樣決定最終地圖
啟動位置 map引數來源 對yaml_filename的作用
rm_navigation_reality_launch.py 使用者map:=路徑;未指定時按world生成share/map/reality/場地名.yaml 傳給bringup;當前world預設rmul_2024
rm_navigation_simulation_launch.py 使用者map:=路徑;未指定時按world生成share/map/simulation/場地名.yaml 傳給bringup;當前world預設rmuc_2025
bringup_launch.py 接收上層map 用RewrittenYaml重寫已有yaml_filename,再傳給定位分支
localization_launch.py 接收map,單獨啟動時此引數無預設值 再用map重寫yaml_filename,獨立程序與元件兩種分支均載入結果
直接啟動map_server並提供節點引數 使用者傳入yaml_filename 未經過上述重寫時,直接使用節點得到的值;生命週期另需配置和啟用

當前整套啟動以map啟動引數為準。 想改用自己的地圖,優先明確傳map:=地圖YAML的絕對路徑;修改nav2_params.yaml中的值並不能阻止兩處重寫。若要改成完全由節點引數檔案決定,必須調整當前bringup與localization的重寫邏輯,並核對上層必需引數;不是隻去修改註釋提到的TB3檔案。本文只記錄接線,沒有修改啟動檔案。

實際重寫位置見bringup_launch.py、localization_launch.py。

1.2.1.2.3.本次預設檔案檢查(實物預設圖尚未提供)

當前安裝包share目錄為:

/home/tungchiahui/UserFolder/MySource/ysu2026_rm_sentry/ysu2026_rm_sentry_nav/install/pb2025_nav_bringup/share/pb2025_nav_bringup
預設入口 預設相對share目錄的路徑 本次靜態檢查
實物,world=rmul_2024 map/reality/rmul_2024.yaml 原始碼和安裝副本均沒有該檔案;當前原始碼map/reality僅有reserve佔位檔案
模擬,world=rmuc_2025 map/simulation/rmuc_2025.yaml 原始碼和安裝副本均存在,配套rmuc_2025.pgm也存在

這是對當前這份工作空間和預設入口的檔案檢查,不表示其他工作空間沒有實物圖,也不表示使用者曾經指定的map路徑失敗。使用自己建的二維圖時,還要給prior_pcd_file選擇與之座標一致的PCD,不能只讓兩份檔名看起來相同。

當前模擬預設地圖後設資料為:

image: rmuc_2025.pgm
mode: trinary
resolution: 0.05
origin: [-3.58, -9.44, 0]
negate: 0
occupied_thresh: 0.65
free_thresh: 0.25

這裡只引用已有地圖檔案說明格式,不是map_server的額外ROS引數。原檔案見rmuc_2025.yaml。

1.2.1.2.4.地圖後設資料(圖片如何變成真實座標和佔用值)
地圖檔案欄位 單位/含義 當前應怎樣核對
image 配套圖片路徑 相對路徑按地圖YAML所在目錄解析;搬移時需同時保留圖片,不能只複製YAML
resolution m/圖片畫素 決定真實平面格距;此例5 cm,不是定位精度;修改它會改變整圖物理尺度
origin [x米、y米、yaw弧度] 第三個數是繞z的偏航角,不是z高度;載入的二維原點z設為0
negate 0/1,畫素明暗是否反轉 此例0:深色表示較高佔用;不是把地圖座標軸反轉
mode trinary/scale/raw trinary按閾值輸出0、100、-1;scale還表達中間值;raw按畫素數直接解釋,不能隨意換模式後繼續按普通黑白圖理解
free_thresh、occupied_thresh 無量綱,畫素換算後的佔用門檻 載入時讀的是本地圖檔案的值,不讀取map_saver節點的default門檻

普通無透明通道灰度圖、negate=0、trinary時,令灰度g為0~255,則佔用比例為1−g/255;嚴格大於occupied_thresh設100,嚴格小於free_thresh設0,其餘設-1。儲存時對輸入0~100佔用值採用另一套包含邊界的比較,不能把兩種門檻比較混寫。後設資料解析與畫素載入

本版本預設三態儲存的未知灰205重新讀取時,1−205/255≈0.19608,小於0.25,會變成空閒0。 本次已直接用安裝的libmap_io在臨時檔案中驗證:輸入未知-1,用trinary、0.25/0.65儲存再讀取得到0;free改0.196後該未知格仍為-1。這個問題只針對滿足上述讀寫條件的圖片,不能據此斷言所有來源的地圖都丟未知。完整閾值條件、驗證資料和處理建議見map_saver。

1.2.1.2.5.與global_costmap和三維定位的幾何關係

前面global_costmap預設不滾動,StaticLayer會按/map後設資料調整主圖尺寸、格距和平面原點;這裡載入哪張圖,直接決定它的有效網格,而不是由costmap中的初始0.05獨立決定。全域性圖的尺寸接管

MapServer把origin第三個數寫入地圖四元數,但當前Nav2 1.1.20的StaticLayer平面網格主要使用origin.position.x/y與格距,非滾動合成按同格索引,不按任意origin yaw重新旋轉網格。當前示例yaw=0;若將地圖YAML改為非零yaw,應單獨核對消費者,不能認為所有節點都會自動正確旋轉。靜態層網格建立

frame_id只是訊息座標系名稱。給圖片改原點、旋轉、裁剪或重取樣後,需同時考慮PCD定位和map↔odom;僅把frame_id寫成map不證明實際對齊。

1.2.2.相關原始碼預設項(原YAML未顯式配置)

1.2.2.1.參數列
引數名 當前值 單位 實車處理建議 作用 調大效果 調小效果 生效條件/備註
topic_name map,MapServer預設 不適用,話題名稱 上實物前必須核對並正確配置 選擇完整OccupancyGrid釋出話題 不適用 不適用 相對名稱按節點namespace解析;例如/red_standard_robot1/map;需與兩張costmap的static_layer輸入一致
frame_id map,MapServer預設 不適用,座標系名稱 上實物前必須核對並正確配置 設定地圖訊息header.frame_id 不適用 不適用 不建立TF、不變換圖片或原點;當前應與全域性網格、PCD定位約定一致
use_sim_time 原分組未寫;標準ROS預設False 不適用,布林 上實物前必須核對並正確配置 決定MapServer填寫載入時間和訊息時間戳時使用的時鐘 不適用 不適用 當前bare-key重寫只改已有鍵,沒有給本分組補入此鍵;模擬不能只憑入口True推斷本節點也True,外部覆蓋需另查

兩份節點引數檔案的map_server段完全一致,均只有yaml_filename空字串。當前預設接線未在此分組補入use_sim_time;在沒有其他覆蓋時標準預設為False,模擬入口傳True不會經該重寫自動補到這裡。此結論來自引數及啟動原始碼,未對執行節點取快照;需要統一時間域時應顯式配置,再檢查有效引數。載入後的時間戳

1.2.3.生命週期、換圖與驗證範圍

1.2.3.1.釋出與服務

MapServer是生命週期節點。configure時載入初始圖並建立服務/釋出器;activate時釋出已載入完整圖。當前localization_launch的lifecycle_manager_localization管理map_server,autostart=True時自動配置、啟用;單獨執行可執行程式不能只停在“程序已建立”。

完整地圖使用Transient Local、Reliable、KeepLast(1),保留最近一張圖供相容的晚加入訂閱者讀取。它不是週期性重讀磁碟或定時釋出新地圖;原檔案改了不會自動熱更新。地圖釋出與啟用

介面 預設名稱,帶機器人namespace時示例 行為
完整地圖話題 /red_standard_robot1/map 初始啟用有圖時釋出;成功load_map後釋出新圖;保留最近完整圖
GetMap服務 /red_standard_robot1/map_server/map 返回當前記憶體OccupancyGrid;Active狀態才處理;Active但尚未載入圖時不能當作已有有效地圖
LoadMap服務 /red_standard_robot1/map_server/load_map 請求map_url載入地圖YAML;Active狀態才處理,成功後更新記憶體併發布新圖

當前MapServer沒有為yaml_filename、topic_name、frame_id建立執行中重讀/重建的引數回撥。引數設定成功不代表換圖成功;換圖應走LoadMap服務或重新配置/重啟。服務載入成功也不自動更換small_gicp的目標PCD,切換場地時還要同步定位目標與座標約定。服務載入

1.2.3.2.本次核對與後續實物檢查
  • 本次已核對: nav2_map_server 1.1.20及安裝標頭檔案;兩套節點引數與安裝副本一致;五份相關launch與安裝副本一致;實際map重寫接線;實物預設地圖缺失、模擬預設YAML/圖片存在。
  • 本次離線驗證: 在臨時目錄直接呼叫已安裝地圖IO庫完成小地圖儲存/讀取,確認trinary灰205、free=0.25會丟未知身份,0.196的對應例子保留;未啟動ROS地圖節點、話題或服務,未寫入工程地圖目錄。
  • 原始碼能確認: 空路徑分支、configure/activate行為、完整圖QoS、Active服務條件、相對圖片路徑解析、地圖後設資料含義,以及引數重寫與執行中換圖的邊界。
  • 實物待核實: 啟動時實際map與有效yaml_filename、二維圖/PCD對齊、圖中未知區域儲存和重新載入、時間域、生命週期狀態及靜態層的有效地圖後設資料;本次未執行整套導航或進行實車驗證。