目錄
1 導航概述
2 導航簡介
2.1 導航模塊簡介
1.全局地圖
2.自身定位
3.路徑規劃
4.運動控制
5.環境感知
2.2 導航坐標系odom、map
1.簡介
2.特點
3.坐標系變換
2.3 導航條件說明
1.硬件
2.軟件
3 導航實現
3.1 創建本篇博客的功能包
3.2 建圖--gmapping
3.2.1 gmapping簡介
3.2.2 gmapping節點說明
3.2.2.1訂閱的Topic
3.2.2.2發布的Topic
3.2.2.3服務
3.2.2.4參數
3.2.2.5所需的坐標變換
3.2.2.6發布的坐標變換
3.2.3 gmapping使用
3.2.3.1編寫gmapping節點相關launch文件
3.2.3.2 執行
3.3 地圖服務 map_server
3.3.1 map_server使用之地圖保存節點(map_saver)
3.3.2? map_server使用之地圖發布節點(map_saver)
3.3.3 地圖配置文件
3.4 amcl定位
3.4.1 概念
3.4.1.1訂閱的Topic
3.4.1.2發布的Topic
3.4.1.3服務
3.4.1.4調用的服務
3.4.1.5參數
3.4.16坐標變換
3.4.2 AMCL的使用
3.4.2.1 編寫AMCL相關的文件
3.4.2.2 編寫測試文件
3.5 路徑規劃move_base、代價地圖
3.5.1 簡介
3.5.2 move_base節點說明
3.5.3?move_base與代價地圖
3.5.4 move_base的使用
3.5.4.1 編寫launch文件
3.5.4.2 配置文件
3.4.5.3 launch文件集成
3.4.5.4 測試
3.4.5.5 顯示全局/本地代價地圖與全局/本地路徑規劃
3.4.5.6 配置文件的解釋
3.4.5.7 參數配置小技巧
3.5.5 導航與SLAM建圖
3.5.5.1?編寫launch文件
4 導航信息
4.1 地圖
4.2 里程計數據
4.3 TF
4.4 定位
4.5 路徑規劃
1 導航概述
????????導航是機器人系統中最重要的模塊之一,比如現在較為流行的服務型室內機器人,就是依賴于機器人導航來實現室內自主移動的,本章主要就是介紹仿真環境下的導航實現,主要內容有:
- 導航相關概念
- 導航實現:機器人建圖(SLAM)、地圖服務、定位、路徑規劃....以可視化操作為主。
- 導航消息:了解地圖、里程計、雷達、攝像頭等相關消息格式。
預期達成的學習目標:
- 了解導航模塊中的組成部分以及相關概念
- 能夠在仿真環境下獨立完成機器人導航
2 導航簡介
2.1 導航模塊簡介
????????在ROS中機器人導航(Navigation)由多個功能包組合實現,ROS 中又稱之為導航功能包集,關于導航模塊,官方介紹如下:
一個二維導航堆棧,它接收來自里程計、傳感器流和目標姿態的信息,并輸出發送到移動底盤的安全速度命令。
????????更通俗的講: 導航其實就是機器人自主的從 A 點移動到 B 點的過程。
????????秉著"不重復發明輪子"的原則,ROS 中導航相關的功能包集為機器人導航提供了一套通用的實現,開發者不再需要關注于導航算法、硬件交互... 等偏復雜、偏底層的實現,這些實現都由更專業的研發人員管理、迭代和維護,開發者可以更專注于上層功能,而對于導航功能的調用,只需要根據自身機器人相關參數合理設置各模塊的配置文件即可,當然,如果有必要,也可以基于現有的功能包二次開發實現一些定制化需求,這樣可以大大提高研發效率,縮短產品落地時間。總而言之,對于一般開發者而言,ROS 的導航功能包集優勢如下:
安全: 由專業團隊開發和維護
功能: 功能更穩定且全面
高效: 解放開發者,讓開發者更專注于上層功能實現
????????機器人是如何實現導航的呢?或換言之,機器人是如何從 A 點移動到 B 點呢?ROS 官方為了提供了一張導航功能包集的圖示,該圖中囊括了 ROS 導航的一些關鍵技術:
??????? 假定我們已經以特定方式配置機器人,導航功能包集將使其可以運動。上圖概述了這種配置方式。白色的部分是必須且已實現的組件,灰色的部分是可選且已實現的組件,藍色的部分是必須為每一個機器人平臺創建的組件。
總結下來,涉及的關鍵技術有如下五點:
全局地圖
自身定位
路徑規劃
運動控制
環境感知
????????機器人導航實現與無人駕駛類似,關鍵技術也是由上述五點組成,只是無人駕駛是基于室外的,而我們當前介紹的機器人導航更多是基于室內的。
????????
1.全局地圖
在現實生活中,當我們需要實現導航時,可能會首先參考一張全局性質的地圖,然后根據地圖來確定自身的位置、目的地位置,并且也會根據地圖顯示來規劃一條大致的路線.... 對于機器人導航而言,也是如此,在機器人導航中地圖是一個重要的組成元素,當然如果要使用地圖,首先需要繪制地圖。關于地圖建模技術不斷涌現,這其中有一門稱之為 SLAM 的理論脫穎而出:
SLAM(simultaneous localization and mapping),也稱為CML (Concurrent Mapping and Localization), 即時定位與地圖構建,或并發建圖與定位。SLAM問題可以描述為: 機器人在未知環境中從一個未知位置開始移動,在移動過程中根據位置估計和地圖進行自身定位,同時在自身定位的基礎上建造增量式地圖,以繪制出外部環境的完全地圖。
在 ROS 中,較為常用的 SLAM 實現也比較多,比如: gmapping、hector_slam、cartographer、rgbdslam、ORB_SLAM ....
當然如果要完成 SLAM ,機器人必須要具備感知外界環境的能力,尤其是要具備獲取周圍環境深度信息的能力。感知的實現需要依賴于傳感器,比如: 激光雷達、攝像頭、RGB-D攝像頭...
SLAM 可以用于地圖生成,而生成的地圖還需要被保存以待后續使用,在 ROS 中保存地圖的功能包是 map_server
另外注意: SLAM 雖然是機器人導航的重要技術之一,但是 二者并不等價,確切的講,SLAM 只是實現地圖構建和即時定位。
2.自身定位
導航伊始和導航過程中,機器人都需要確定當前自身的位置,如果在室外,那么 GPS 是一個不錯的選擇,而如果室內、隧道、地下或一些特殊的屏蔽 GPS 信號的區域,由于 GPS 信號弱化甚至完全不可用,那么就必須另辟蹊徑了,比如前面的 SLAM 就可以實現自身定位,除此之外,ROS 中還提供了一個用于定位的功能包: amcl
amcl(adaptiveMonteCarloLocalization)自適應的蒙特卡洛定位,是用于2D移動機器人的概率定位系統。它實現了自適應(或KLD采樣)蒙特卡洛定位方法,該方法使用粒子過濾器根據已知地圖跟蹤機器人的姿態。
3.路徑規劃
導航就是機器人從A點運動至B點的過程,在這一過程中,機器人需要根據目標位置計算全局運動路線,并且在運動過程中,還需要時時根據出現的一些動態障礙物調整運動路線,直至到達目標點,該過程就稱之為路徑規劃。在 ROS 中提供了 move_base 包來實現路徑規則,該功能包主要由兩大規劃器組成:
全局路徑規劃(gloable_planner)
根據給定的目標點和全局地圖實現總體的路徑規劃,使用 Dijkstra 或 A* 算法進行全局路徑規劃,計算最優路線,作為全局路線
本地時時規劃(local_planner)
在實際導航過程中,機器人可能無法按照給定的全局最優路線運行,比如:機器人在運行中,可能會隨時出現一定的障礙物... 本地規劃的作用就是使用一定算法(Dynamic Window Approaches) 來實現障礙物的規避,并選取當前最優路徑以盡量符合全局最優路徑
全局路徑規劃與本地路徑規劃是相對的,全局路徑規劃側重于全局、宏觀實現,而本地路徑規劃側重與當前、微觀實現。
4.運動控制
導航功能包集假定它可以通過話題"cmd_vel"發布
geometry_msgs/Twist
類型的消息,這個消息基于機器人的基座坐標系,它傳遞的是運動命令。這意味著必須有一個節點訂閱"cmd_vel"話題, 將該話題上的速度命令轉換為電機命令并發送。5.環境感知
感知周圍環境信息,比如: 攝像頭、激光雷達、編碼器...,攝像頭、激光雷達可以用于感知外界環境的深度信息,編碼器可以感知電機的轉速信息,進而可以獲取速度信息并生成里程計信息。
在導航功能包集中,環境感知也是一重要模塊實現,它為其他模塊提供了支持。其他模塊諸如: SLAM、amcl、move_base 都需要依賴于環境感知。
2.2 導航坐標系odom、map
1.簡介
定位是導航中的重要實現之一,所謂定位,就是參考某個坐標系(比如:以機器人的出發點為原點創建坐標系)在該坐標系中標注機器人。定位原理看似簡單,但是這個這個坐標系不是客觀存在的,我們也無法以上帝視角確定機器人的位姿,定位實現需要依賴于機器人自身,機器人需要逆向推導參考系原點并計算坐標系相對關系,該過程實現常用方式有兩種:
- 通過里程計定位:時時收集機器人的速度信息計算并發布機器人坐標系與父級參考系的相對關系。
- 通過傳感器定位:通過傳感器收集外界環境信息通過匹配計算并發布機器人坐標系與父級參考系的相對關系。
兩種方式在導航中都會經常使用。
2.特點
兩種定位方式都有各自的優缺點。
里程計定位:
- 優點:里程計定位信息是連續的,沒有離散的跳躍。
- 缺點:里程計存在累計誤差,不利于長距離或長期定位。
傳感器定位:
- 優點:比里程計定位更精準;
- 缺點:傳感器定位會出現跳變的情況,且傳感器定位在標志物較少的環境下,其定位精度會大打折扣。
兩種定位方式優缺點互補,應用時一般二者結合使用。
3.坐標系變換
上述兩種定位實現中,機器人坐標系一般使用機器人模型中的根坐標系(base_link 或 base_footprint),里程計定位時,父級坐標系一般稱之為 odom,如果通過傳感器定位,父級參考系一般稱之為 map。當二者結合使用時,map 和 odom 都是機器人模型根坐標系的父級,這是不符合坐標變換中"單繼承"的原則的,所以,一般會將轉換關系設置為: map -> odom -> base_link 或 base_footprint。
2.3 導航條件說明
導航實現,在硬件和軟件方面是由一定要求的,需要提前準備。
1.硬件
雖然導航功能包集被設計成盡可能的通用,在使用時仍然有三個主要的硬件限制:
它是為差速驅動的輪式機器人設計的。它假設底盤受到理想的運動命令的控制并可實現預期的結果,命令的格式為:x速度分量,y速度分量,角速度(theta)分量。
它需要在底盤上安裝一個單線激光雷達。這個激光雷達用于構建地圖和定位。
導航功能包集是為正方形的機器人開發的,所以方形或圓形的機器人將是性能最好的。 它也可以工作在任意形狀和大小的機器人上,但是較大的機器人將很難通過狹窄的空間。
2.軟件
導航功能實現之前,需要搭建一些軟件環境:
毋庸置疑的,必須先要安裝 ROS
當前導航基于仿真環境,先保證上一章的機器人系統仿真可以正常執行
在仿真環境下,機器人可以正常接收 /cmd_vel 消息,并發布里程計消息,傳感器消息發布也正常,也即導航模塊中的運動控制和環境感知實現完畢
后續導航實現中,我們主要關注于: 使用 SLAM 繪制地圖、地圖服務、自身定位與路徑規劃。
3 導航實現
本節內容主要介紹導航的完整性實現,旨在掌握機器人導航的基本流程,該章涉及的主要內容如下:
SLAM建圖(選用較為常見的gmapping)
地圖服務(可以保存和重現地圖)
機器人定位
路徑規劃
上述流程介紹完畢,還會對功能進一步集成實現探索式的SLAM建圖。
準備工作
請先安裝相關的ROS功能包:
安裝 gmapping 包(用于構建地圖):
sudo apt install ros-<ROS版本>-gmapping
安裝地圖服務包(用于保存與讀取地圖):
sudo apt install ros-<ROS版本>-map-server
安裝 navigation 包(用于定位以及路徑規劃):
sudo apt install ros-<ROS版本>-navigation
新建功能包,并導入依賴: gmapping map_server amcl move_base
3.1 創建本篇博客的功能包
??????? CMakeLists.txt配置:
cmake_minimum_required(VERSION 2.8.3) project(nav_robot)###################### ### Cmake flags ###################### set(CMAKE_BUILD_TYPE "Release") set(CMAKE_CXX_FLAGS "-std=c++11") set(CMAKE_CXX_FLAGS_RELEASE "-O3 -Wall -g -pthread")find_package(catkin REQUIRED COMPONENTSroscpprospyroslib# msgurdfxacrogmappingmap_serveramclmove_base )catkin_package()include_directories(${catkin_INCLUDE_DIRS})
??????? package.xml配置:
<?xml version="1.0"?> <package><name>nav_robot</name><version>0.0.0</version><description>A test</description><maintainer email="haha@nefu.com">haha</maintainer><author>HITLHW</author><license>BSD-3</license><buildtool_depend>catkin</buildtool_depend><build_depend>gmapping</build_depend><run_depend>gmapping</run_depend><build_depend>map_server</build_depend><run_depend>map_server</run_depend><build_depend>amcl</build_depend><run_depend>amcl</run_depend><build_depend>move_base</build_depend><run_depend>move_base</run_depend></package>
??????? 編譯一下:
??????? 沒問題。
3.2 建圖--gmapping
3.2.1 gmapping簡介
SLAM算法有多種,當前我們選用gmapping,后續會再介紹其他幾種常用的SLAM實現。
gmapping 是ROS開源社區中較為常用且比較成熟的SLAM算法之一,gmapping可以根據移動機器人里程計數據和激光雷達數據來繪制二維的柵格地圖,對應的,gmapping對硬件也有一定的要求:
- 該移動機器人可以發布里程計消息
- 機器人需要發布雷達消息(該消息可以通過水平固定安裝的雷達發布,或者也可以將深度相機消息轉換成雷達消息)
關于里程計與雷達數據,仿真環境中可以正常獲取的,不再贅述,柵格地圖如案例所示。
gmapping 安裝前面也有介紹,命令如下:
sudo apt install ros-<ROS版本>-gmapping
3.2.2 gmapping節點說明
gmapping 功能包中的核心節點是:slam_gmapping。為了方便調用,需要先了解該節點訂閱的話題、發布的話題、服務以及相關參數。
3.2.2.1訂閱的Topic
tf (tf/tfMessage)
- 用于雷達、底盤與里程計之間的坐標變換消息。
scan(sensor_msgs/LaserScan)
- SLAM所需的雷達信息。
3.2.2.2發布的Topic
map_metadata(nav_msgs/MapMetaData)
- 地圖元數據,包括地圖的寬度、高度、分辨率等,該消息會固定更新。
map(nav_msgs/OccupancyGrid)
- 地圖柵格數據,一般會在rviz中以圖形化的方式顯示。
~entropy(std_msgs/Float64)
- 機器人姿態分布熵估計(值越大,不確定性越大)。
3.2.2.3服務
dynamic_map(nav_msgs/GetMap)
- 用于獲取地圖數據。
3.2.2.4參數
~base_frame(string, default:"base_link")
- 機器人基坐標系。
~map_frame(string, default:"map")
- 地圖坐標系。
~odom_frame(string, default:"odom")
- 里程計坐標系。
~map_update_interval(float, default: 5.0)
- 地圖更新頻率,根據指定的值設計更新間隔。
~maxUrange(float, default: 80.0)
- 激光探測的最大可用范圍(超出此閾值,被截斷)。
~maxRange(float)
- 激光探測的最大范圍。
.... 參數較多,上述是幾個較為常用的參數,其他參數介紹可參考官網。
3.2.2.5所需的坐標變換
雷達坐標系→基坐標系
- 一般由 robot_state_publisher 或 static_transform_publisher 發布。
基坐標系→里程計坐標系
- 一般由里程計節點發布。
3.2.2.6發布的坐標變換
地圖坐標系→里程計坐標系
- 地圖到里程計坐標系之間的變換。
3.2.3 gmapping使用
3.2.3.1編寫gmapping節點相關launch文件
<launch> <param name="use_sim_time" value="true"/><node pkg="gmapping" type="slam_gmapping" name="slam_gmapping" output="screen"><remap from="scan" to="scan"/><param name="base_frame" value="base_footprint"/><!--底盤坐標系--><param name="odom_frame" value="odom"/> <!--里程計坐標系--><param name="map_update_interval" value="5.0"/><param name="maxUrange" value="16.0"/><param name="sigma" value="0.05"/><param name="kernelSize" value="1"/><param name="lstep" value="0.05"/><param name="astep" value="0.05"/><param name="iterations" value="5"/><param name="lsigma" value="0.075"/><param name="ogain" value="3.0"/><param name="lskip" value="0"/><param name="srr" value="0.1"/><param name="srt" value="0.2"/><param name="str" value="0.1"/><param name="stt" value="0.2"/><param name="linearUpdate" value="1.0"/><param name="angularUpdate" value="0.5"/><param name="temporalUpdate" value="3.0"/><param name="resampleThreshold" value="0.5"/><param name="particles" value="30"/><param name="xmin" value="-50.0"/><param name="ymin" value="-50.0"/><param name="xmax" value="50.0"/><param name="ymax" value="50.0"/><param name="delta" value="0.05"/><param name="llsamplerange" value="0.01"/><param name="llsamplestep" value="0.01"/><param name="lasamplerange" value="0.005"/><param name="lasamplestep" value="0.005"/></node><node pkg="joint_state_publisher" name="joint_state_publisher" type="joint_state_publisher" /><node pkg="robot_state_publisher" name="robot_state_publisher" type="robot_state_publisher" /><node pkg="rviz" type="rviz" name="rviz" /><!-- 可以保存 rviz 配置并后期直接使用--><!--<node pkg="rviz" type="rviz" name="rviz"/>--> </launch>
??????? 參數:
1.use_sim_time:使用仿真時間,仿真下設置該參數為true。
2.<remap from="scan" to="scan"/> 設置雷達話題:to后面要設置為自己激光雷達的話題
3.map_update_interval 地圖更新時間
4.maxUrange 雷達長度閾值
5.必須設置的:
????? <param name="base_frame" value="base_footprint"/><!--底盤坐標系-->
????? <param name="odom_frame" value="odom"/> <!--里程計坐標系-->3.2.3.2 執行
1.先啟動 Gazebo 仿真環境(此過程略)(上篇博客的)
roslaunch test gazebo_car.launch
2.然后再啟動地圖繪制的 launch 文件:
roslaunch nav_robot gmmaping.launch
3.啟動鍵盤鍵盤控制節點,用于控制機器人運動建圖
rosrun teleop_twist_keyboard teleop_twist_keyboard.py
??????? 調節RVIZ顯示
??????? 這三個是重合的。
??????? 我們添加map:
??????? 控制機器人運動構建地圖。
??????? 撞上了,...。
3.3 地圖服務 map_server
????????上一節我們已經實現通過gmapping的構建地圖并在rviz中顯示了地圖,不過,上一節中地圖數據是保存在內存中的,當節點關閉時,數據也會被一并釋放,我們需要將柵格地圖序列化到的磁盤以持久化存儲,后期還要通過反序列化讀取磁盤的地圖數據再執行后續操作。在ROS中,地圖數據的序列化與反序列化可以通過 map_server 功能包實現。
????????map_server功能包中提供了兩個節點: map_saver 和 map_server,前者用于將柵格地圖保存到磁盤,后者讀取磁盤的柵格地圖并以服務的方式提供出去。
3.3.1 map_server使用之地圖保存節點(map_saver)
訂閱的topic:
map(nav_msgs/OccupancyGrid)
- 訂閱此話題用于生成地圖文件。
????????地圖保存的語法比較簡單,編寫一個launch文件,內容如下:
<launch><arg name="filename" value="$(find mycar_nav)/map/nav" /><node name="map_save" pkg="map_server" type="map_saver" args="-f $(arg filename)" /> </launch>
????????其中 mymap 是指地圖的保存路徑以及保存的文件名稱。
????????SLAM建圖完畢后,執行該launch文件即可。
測試:
首先,參考上一節,依次啟動仿真環境,鍵盤控制節點與SLAM節點;
然后,通過鍵盤控制機器人運動并繪圖;
最后,通過上述地圖保存方式保存地圖。
結果:在指定路徑下會生成兩個文件,xxx.pgm 與 xxx.yaml
??????? 第一行是地圖保存的地址:我們創立文件夾:
??????? 第二行:filename是保存的地圖的名稱,我們來演示一下。
roslaunch test gazebo_car.launch roslaunch nav_robot gmmaping.launch rosrun teleop_twist_keyboard teleop_twist_keyboard.py
??????? 我們建立好地圖后,啟動我們的地圖保存節點:
roslaunch nav_robot octomapserver.launch
??????? 發現地圖已經被保存下來了:
????????xxx.pgm 本質是一張圖片,直接使用圖片查看程序即可打開。
????????xxx.yaml 保存的是地圖的元數據信息,用于描述圖片,內容格式如下:
image: /home/liuhongwei/Desktop/final/nav_zhaoxuzuo/src/map/nav.pgm resolution: 0.050000 origin: [-50.000000, -50.000000, 0.000000] negate: 0 occupied_thresh: 0.65 free_thresh: 0.196
3.3.2? map_server使用之地圖發布節點(map_saver)
發布的話題
map_metadata(nav_msgs / MapMetaData)
- 發布地圖元數據。
map(nav_msgs / OccupancyGrid)
- 地圖數據。
服務
static_map(nav_msgs / GetMap)
- 通過此服務獲取地圖。
參數
?frame_id(字符串,默認值:“map”)
- 地圖坐標系。
<launch><!-- 設置地圖的配置文件 --><arg name="map" default="nav.yaml" /><!-- 運行地圖服務器,并且加載設置的地圖--><node name="map_server" pkg="map_server" type="map_server" args="$(find mycar_nav)/map/$(arg map)"/> </launch>
??????? 直接執行這個launch文件就行。
??????? 我們在rviz添加map組件:
3.3.3 地圖配置文件
??????? 1.image:地圖資源的路徑
??????? 2.resolutuin:地圖刻度尺單位 m/像素
??????? 3.origin:地圖的位姿信息(相對于rviz的原點信息)
??????? 4.occupied_thresh:占用閾值
??????? 5.free_thresh:空閑閾值,判斷地圖某一點是否被占用
??????? 6.negate:取反
??????? 為了演示這些參數的作用,我們打開RVIZ:
????????origin就是右下角相對于axis的偏移。X+50 Y-50。第三個角度為偏航角度。
??????? 我們如果把第三個參數改稱0.3(弧度)
??????? 對于占用閾值,地圖中的障礙物判斷:
??????? 規則:白色可通行 黑色障礙物 藍黑未知區域,怎么判斷呢???地圖中每個像素都有取值[0,255] 白色255 黑0 ,像素值設置為x。根據像素值設置一個比例:
??????? p = 255-x / 255 白色0黑色1,如果p>占用閾值為障礙物,p<空閑閾值可以通行。
??????? 取反是黑的變白,白變黑。
3.4 amcl定位
3.4.1 概念
????????所謂定位就是推算機器人自身在全局地圖中的位置,當然,SLAM中也包含定位算法實現,不過SLAM的定位是用于構建全局地圖的,是屬于導航開始之前的階段,而當前定位是用于導航中,導航中,機器人需要按照設定的路線運動,通過定位可以判斷機器人的實際軌跡是否符合預期。在ROS的導航功能包集navigation中提供了 amcl 功能包,用于實現導航中的機器人定位。
????????AMCL(adaptive Monte Carlo Localization) 是用于2D移動機器人的概率定位系統,它實現了自適應(或KLD采樣)蒙特卡洛定位方法,可以根據已有地圖使用粒子濾波器推算機器人位置。
????????amcl 功能包中的核心節點是:amcl。為了方便調用,需要先了解該節點訂閱的話題、發布的話題、服務以及相關參數。
3.4.1.1訂閱的Topic
scan(sensor_msgs/LaserScan)
- 激光雷達數據。
tf(tf/tfMessage)
- 坐標變換消息。
initialpose(geometry_msgs/PoseWithCovarianceStamped)
- 用來初始化粒子濾波器的均值和協方差。
map(nav_msgs/OccupancyGrid)
- 獲取地圖數據。
3.4.1.2發布的Topic
amcl_pose(geometry_msgs/PoseWithCovarianceStamped)
- 機器人在地圖中的位姿估計。
particlecloud(geometry_msgs/PoseArray)
- 位姿估計集合,rviz中可以被 PoseArray 訂閱然后圖形化顯示機器人的位姿估計集合。
tf(tf/tfMessage)
- 發布從 odom 到 map 的轉換。
3.4.1.3服務
global_localization(std_srvs/Empty)
- 初始化全局定位的服務。
request_nomotion_update(std_srvs/Empty)
- 手動執行更新和發布更新的粒子的服務。
set_map(nav_msgs/SetMap)
- 手動設置新地圖和姿態的服務。
3.4.1.4調用的服務
static_map(nav_msgs/GetMap)
- 調用此服務獲取地圖數據。
3.4.1.5參數
~odom_model_type(string, default:"diff")
- 里程計模型選擇: "diff","omni","diff-corrected","omni-corrected" (diff 差速、omni 全向輪)
~odom_frame_id(string, default:"odom")
- 里程計坐標系。
~base_frame_id(string, default:"base_link")
- 機器人極坐標系。
~global_frame_id(string, default:"map")
3.4.16坐標變換
里程計本身也是可以協助機器人定位的,不過里程計存在累計誤差且一些特殊情況時(車輪打滑)會出現定位錯誤的情況,amcl 則可以通過估算機器人在地圖坐標系下的姿態,再結合里程計提高定位準確度。
- 里程計定位:只是通過里程計數據實現 /odom_frame 與 /base_frame 之間的坐標變換。
- amcl定位: 可以提供 /map_frame 、/odom_frame 與 /base_frame 之間的坐標變換。
3.4.2 AMCL的使用
3.4.2.1 編寫AMCL相關的文件
<launch> <node pkg="amcl" type="amcl" name="amcl" output="screen"><!-- Publish scans from best pose at a max of 10 Hz --><param name="odom_model_type" value="diff"/><!-- 里程計模式為差分 --><param name="odom_alpha5" value="0.1"/><param name="transform_tolerance" value="0.2" /><param name="gui_publish_rate" value="10.0"/><param name="laser_max_beams" value="30"/><param name="min_particles" value="500"/><param name="max_particles" value="5000"/><param name="kld_err" value="0.05"/><param name="kld_z" value="0.99"/><param name="odom_alpha1" value="0.2"/><param name="odom_alpha2" value="0.2"/><!-- translation std dev, m --><param name="odom_alpha3" value="0.8"/><param name="odom_alpha4" value="0.2"/><param name="laser_z_hit" value="0.5"/><param name="laser_z_short" value="0.05"/><param name="laser_z_max" value="0.05"/><param name="laser_z_rand" value="0.5"/><param name="laser_sigma_hit" value="0.2"/><param name="laser_lambda_short" value="0.1"/><param name="laser_lambda_short" value="0.1"/><param name="laser_model_type" value="likelihood_field"/><!-- <param name="laser_model_type" value="beam"/> --><param name="laser_likelihood_max_dist" value="2.0"/><param name="update_min_d" value="0.2"/><param name="update_min_a" value="0.5"/><param name="odom_frame_id" value="odom"/><!-- 里程計坐標系 --><param name="base_frame_id" value="base_footprint"/><!-- 添加機器人基坐標系 --><param name="global_frame_id" value="map"/><!-- 添加地圖坐標系 --><param name="resample_interval" value="1"/><param name="transform_tolerance" value="0.1"/><param name="recovery_alpha_slow" value="0.0"/><param name="recovery_alpha_fast" value="0.0"/> </node> </launch>
????????odom_model_type:運動類型,差速
???????? <param name="odom_frame_id" value="odom"/><!-- 里程計坐標系 -->
?????????<param name="base_frame_id" value="base_footprint"/><!-- 添加機器人基坐標系 -->
?????????<param name="global_frame_id" value="map"/><!-- 添加地圖坐標系 -->
3.4.2.2 編寫測試文件
??????? testamcl.launch
????????amcl節點是不可以單獨運行的,運行 amcl 節點之前,需要先加載全局地圖,然后啟動 rviz 顯示定位結果,上述節點可以集成進launch文件,內容示例如下:
<launch><arg name="map" default="nav.yaml" /><node name="map_server" pkg="map_server" type="map_server" args="$(find nav_robot)/map/$(arg map)"/><include file="$(find nav_robot)/launch/amcl.launch" /><node pkg="rviz" type="rviz" name="rviz"/> </launch>
??????? 先啟動gazebo仿真環境:roslaunch test gazebo_car.launch
??????? 啟動鍵盤控制節點:rosrun teleop_twist_keyboard tele_twist_keyboard.py
??????? 啟動集成的amcl的launch文件:roslaunch nav_robot testamcl.launch
??????? 啟動如下節點: ???
<node pkg="joint_state_publisher" type="joint_state_publisher" name="joint_state_publisher" /> <node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" />????????在啟動的 rviz 中,添加RobotModel、Map組件,分別顯示機器人模型與地圖,添加 posearray 插件,設置topic為particlecloud來顯示 amcl 預估的當前機器人的位姿,箭頭越是密集,說明當前機器人處于此位置的概率越高;
??????? 我們控制機器人運動!
????????箭頭越是密集,說明當前機器人處于此位置的概率越高;
3.5 路徑規劃move_base、代價地圖
3.5.1 簡介
????????毋庸置疑的,路徑規劃是導航中的核心功能之一,在ROS的導航功能包集navigation中提供了 move_base 功能包,用于實現此功能。
????????move_base 功能包提供了基于動作(action)的路徑規劃實現,move_base 可以根據給定的目標點,控制機器人底盤運動至目標位置,并且在運動過程中會連續反饋機器人自身的姿態與目標點的狀態信息。如前所述move_base主要由全局路徑規劃與本地路徑規劃組成。
3.5.2 move_base節點說明
????????move_base功能包中的核心節點是:move_base。為了方便調用,需要先了解該節點action、訂閱的話題、發布的話題、服務以及相關參數。
動作訂閱
move_base/goal(move_base_msgs/MoveBaseActionGoal)
- move_base 的運動規劃目標。
move_base/cancel(actionlib_msgs/GoalID)
- 取消目標。
動作發布
move_base/feedback(move_base_msgs/MoveBaseActionFeedback)
- 連續反饋的信息,包含機器人底盤坐標。
move_base/status(actionlib_msgs/GoalStatusArray)
- 發送到move_base的目標狀態信息。
move_base/result(move_base_msgs/MoveBaseActionResult)
- 操作結果(此處為空)。
訂閱的Topic
move_base_simple/goal(geometry_msgs/PoseStamped)
- 運動規劃目標(與action相比,沒有連續反饋,無法追蹤機器人執行狀態)。
發布的Topic
cmd_vel(geometry_msgs/Twist)
- 輸出到機器人底盤的運動控制消息。
服務
~make_plan(nav_msgs/GetPlan)
- 請求該服務,可以獲取給定目標的規劃路徑,但是并不執行該路徑規劃。
~clear_unknown_space(std_srvs/Empty)
- 允許用戶直接清除機器人周圍的未知空間。
~clear_costmaps(std_srvs/Empty)
- 允許清除代價地圖中的障礙物,可能會導致機器人與障礙物碰撞,請慎用。
3.5.3?move_base與代價地圖
????????機器人導航(尤其是路徑規劃模塊)是依賴于地圖的,地圖在SLAM時已經有所介紹了,ROS中的地圖其實就是一張圖片,這張圖片有寬度、高度、分辨率等元數據,在圖片中使用灰度值來表示障礙物存在的概率。不過SLAM構建的地圖在導航中是不可以直接使用的,因為:
- SLAM構建的地圖是靜態地圖,而導航過程中,障礙物信息是可變的,可能障礙物被移走了,也可能添加了新的障礙物,導航中需要時時的獲取障礙物信息;
- 在靠近障礙物邊緣時,雖然此處是空閑區域,但是機器人在進入該區域后可能由于其他一些因素,比如:慣性、或者不規則形體的機器人轉彎時可能會與障礙物產生碰撞,安全起見,最好在地圖的障礙物邊緣設置警戒區,盡量禁止機器人進入...
所以,靜態地圖無法直接應用于導航,其基礎之上需要添加一些輔助信息的地圖,比如時時獲取的障礙物數據,基于靜態地圖添加的膨脹區等數據。
????????
????????代價地圖有兩張:global_costmap(全局代價地圖) 和 local_costmap(本地代價地圖),前者用于全局路徑規劃,后者用于本地路徑規劃。
兩張代價地圖都可以多層疊加,一般有以下層級:
Static Map Layer:靜態地圖層,SLAM構建的靜態地圖。
Obstacle Map Layer:障礙地圖層,傳感器感知的障礙物信息。
Inflation Layer:膨脹層,在以上兩層地圖上進行膨脹(向外擴張),以避免機器人的外殼會撞上障礙物。
Other Layers:自定義costmap。
上圖中,橫軸是距離機器人中心的距離,縱軸是代價地圖中柵格的灰度值。
- 致命障礙:柵格值為254,此時障礙物與機器人中心重疊,必然發生碰撞;
- 內切障礙:柵格值為253,此時障礙物處于機器人的內切圓內,必然發生碰撞;
- 外切障礙:柵格值為[128,252],此時障礙物處于其機器人的外切圓內,處于碰撞臨界,不一定發生碰撞;
- 非自由空間:柵格值為(0,127],此時機器人處于障礙物附近,屬于危險警戒區,進入此區域,將來可能會發生碰撞;
- 自由區域:柵格值為0,此處機器人可以自由通過;
- 未知區域:柵格值為255,還沒探明是否有障礙物。
膨脹空間的設置可以參考非自由空間。
3.5.4 move_base的使用
路徑規劃算法在move_base功能包的move_base節點中已經封裝完畢了,但是還不可以直接調用,因為算法雖然已經封裝了,但是該功能包面向的是各種類型支持ROS的機器人,不同類型機器人可能大小尺寸不同,傳感器不同,速度不同,應用場景不同....最后可能會導致不同的路徑規劃結果,那么在調用路徑規劃節點之前,我們還需要配置機器人參數。具體實現如下:
- 先編寫launch文件模板
- 編寫配置文件
- 集成導航相關的launch文件
- 測試
3.5.4.1 編寫launch文件
<launch><node pkg="move_base" type="move_base" respawn="false" name="move_base" output="screen" clear_params="true"><rosparam file="$(find 功能包)/param/costmap_common_params.yaml" command="load" ns="global_costmap" /><rosparam file="$(find 功能包)/param/costmap_common_params.yaml" command="load" ns="local_costmap" /><rosparam file="$(find 功能包)/param/local_costmap_params.yaml" command="load" /><rosparam file="$(find 功能包)/param/global_costmap_params.yaml" command="load" /><rosparam file="$(find 功能包)/param/base_local_planner_params.yaml" command="load" /></node></launch>
????????clear_params:這個節點執行之前,參數重置。
????????respawn:節點關閉后不會重啟。
????????在功能包下新建 param 目錄,復制下載的文件到此目錄: costmap_common_params_burger.yaml、local_costmap_params.yaml、global_costmap_params.yaml、base_local_planner_params.yaml,并將costmap_common_params_burger.yaml 重命名為:costmap_common_params.yaml。
3.5.4.2 配置文件
#機器人幾何參,如果機器人是圓形,設置 robot_radius,如果是其他形狀設置 footprint robot_radius: 0.12 #圓形 # footprint: [[-0.12, -0.12], [-0.12, 0.12], [0.12, 0.12], [0.12, -0.12]] #其他形狀obstacle_range: 3.0 # 用于障礙物探測,比如: 值為 3.0,意味著檢測到距離小于 3 米的障礙物時,就會引入代價地圖 raytrace_range: 3.5 # 用于清除障礙物,比如:值為 3.5,意味著清除代價地圖中 3.5 米以外的障礙物#膨脹半徑,擴展在碰撞區域以外的代價區域,使得機器人規劃路徑避開障礙物 inflation_radius: 0.2 #代價比例系數,越大則代價值越小 cost_scaling_factor: 3.0#地圖類型 map_type: costmap #導航包所需要的傳感器 observation_sources: scan #對傳感器的坐標系和數據進行配置。這個也會用于代價地圖添加和清除障礙物。例如,你可以用激光雷達傳感器用于在代價地圖添加障礙物,再添加kinect用于導航和清除障礙物。 scan: {sensor_frame: laser, data_type: LaserScan, topic: scan, marking: true, clearing: true}
global_costmap:global_frame: map #地圖坐標系robot_base_frame: base_footprint #機器人坐標系# 以此實現坐標變換update_frequency: 1.0 #代價地圖更新頻率publish_frequency: 1.0 #代價地圖的發布頻率transform_tolerance: 0.5 #等待坐標變換發布信息的超時時間static_map: true # 是否使用一個地圖或者地圖服務器來初始化全局代價地圖,如果不使用靜態地圖,這個參數為false.
local_costmap:global_frame: odom #里程計坐標系robot_base_frame: base_footprint #機器人坐標系update_frequency: 10.0 #代價地圖更新頻率publish_frequency: 10.0 #代價地圖的發布頻率transform_tolerance: 0.5 #等待坐標變換發布信息的超時時間static_map: false #不需要靜態地圖,可以提升導航效果rolling_window: true #是否使用動態窗口,默認為false,在靜態的全局地圖中,地圖不會變化width: 3 # 局部地圖寬度 單位是 mheight: 3 # 局部地圖高度 單位是 mresolution: 0.05 # 局部地圖分辨率 單位是 m,一般與靜態地圖分辨率保持一致
TrajectoryPlannerROS:# Robot Configuration Parametersmax_vel_x: 0.5 # X 方向最大速度min_vel_x: 0.1 # X 方向最小速速max_vel_theta: 1.0 # min_vel_theta: -1.0min_in_place_vel_theta: 1.0acc_lim_x: 1.0 # X 加速限制acc_lim_y: 0.0 # Y 加速限制acc_lim_theta: 0.6 # 角速度加速限制# Goal Tolerance Parameters,目標公差xy_goal_tolerance: 0.10yaw_goal_tolerance: 0.05# Differential-drive robot configuration # 是否是全向移動機器人holonomic_robot: false# Forward Simulation Parameters,前進模擬參數sim_time: 0.8vx_samples: 18vtheta_samples: 20sim_granularity: 0.05
3.4.5.3 launch文件集成
??????? 如果要實現導航,需要集成地圖服務、amcl 、move_base 與 Rviz 等,集成示例如下:
<launch><arg name="map" default="nav.yaml" /><node name="map_server" pkg="map_server" type="map_server" args="$(find nav_robot)/map/$(arg map)"/><include file="$(find nav_robot)/launch/amcl.launch" /><include file="$(find nav_robot)/launch/move_base.launch" /><node pkg="rviz" type="rviz" name="rviz" /><node pkg="joint_state_publisher" type="joint_state_publisher" name="joint_state_publisher" /><node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" /></launch>
3.4.5.4 測試
1.先啟動 Gazebo 仿真環境(此過程略);
roslaunch test gazebo_car.launch
2.啟動導航相關的 launch 文件;
roslaunch nav_robot nav_test.launch
3.添加Rviz組件(參考演示結果),可以將配置數據保存,后期直接調用;
??????? 我們選擇一個2D Nav。
??????? 等一回。。。
??????? 導航到了!
3.4.5.5 顯示全局/本地代價地圖與全局/本地路徑規劃
??????? 我們先在RVIZ中提供一個全局的代價地圖:
??????? 再添加一個本地代價地圖:
??????? 添加路徑的全局路徑規劃,本地路徑規劃:
3.4.5.6 配置文件的解釋
costmap_common_params.yaml
????????該文件是move_base 在全局路徑規劃與本地路徑規劃時調用的通用參數,包括:機器人的尺寸、距離障礙物的安全距離、傳感器信息等。配置參考如下:
#機器人幾何參,如果機器人是圓形,設置 robot_radius,如果是其他形狀設置 footprint robot_radius: 0.12 #圓形 # footprint: [[-0.12, -0.12], [-0.12, 0.12], [0.12, 0.12], [0.12, -0.12]] #其他形狀obstacle_range: 3.0 # 用于障礙物探測,比如: 值為 3.0,意味著檢測到距離小于 3 米的障礙物時,就會引入代價地圖 raytrace_range: 3.5 # 用于清除障礙物,比如:值為 3.5,意味著清除代價地圖中 3.5 米以外的障礙物#膨脹半徑,擴展在碰撞區域以外的代價區域,使得機器人規劃路徑避開障礙物 inflation_radius: 0.2(米) #代價比例系數,越大則代價值越小 cost_scaling_factor: 3.0#地圖類型 map_type: costmap #導航包所需要的傳感器 observation_sources: scan #對傳感器的坐標系和數據進行配置。這個也會用于代價地圖添加和清除障礙物。例如,你可以用激光雷達傳感器用于在代價地圖添加障礙物,再添加kinect用于導航和清除障礙物。 scan: {sensor_frame: laser, data_type: LaserScan, topic: scan, marking: true, clearing: true}
??????? 我們的機器人是0.1m,但是考慮到還有一些別的突出,,把它的半徑設置為0.1m。
????????obstacle_range、raytrace_range表示當動態物體進入的時候,什么時候加入RVIZ中的代價地圖(障礙物距離我3m時會引入代價地圖中,障礙物距離我3.5m外清除出代價地圖)
??????? 將膨脹半徑增加,看看會出現什么樣的效果:
????????代價比例系數,越大則代價值越小。
??????? #導航包所需要的傳感器
????????observation_sources: scan
????????#對傳感器的坐標系和數據進行配置。這個也會用于代價地圖添加和清除障礙物。例如,你可以用激光雷達傳感器用于在代價地圖添加障礙物,再添加kinect用于導航和清除障礙物。
????????scan: {sensor_frame: laser, data_type: LaserScan, topic: scan, marking: true(是否用激光雷達用作障礙物的標注和清除), clearing: true}
??????? 全局代價地圖的配置 global_costmap_params.yaml
global_costmap:global_frame: map #地圖坐標系robot_base_frame: base_footprint #機器人坐標系# 以此實現坐標變換update_frequency: 1.0 #代價地圖更新頻率publish_frequency: 1.0 #代價地圖的發布頻率transform_tolerance: 1.0 #等待坐標變換發布信息的超時時間static_map: true # 是否使用一個地圖或者地圖服務器來初始化全局代價地圖,如果不使用靜態地圖,這個參數為false.
??????? 本地代價地圖:local_costmap_params.yaml
local_costmap:global_frame: odom #里程計坐標系robot_base_frame: base_footprint #機器人坐標系update_frequency: 10.0 #代價地圖更新頻率publish_frequency: 10.0 #代價地圖的發布頻率transform_tolerance: 0.5 #等待坐標變換發布信息的超時時間static_map: false #不需要靜態地圖,可以提升導航效果rolling_window: true #是否使用動態窗口,默認為false,在靜態的全局地圖中,地圖不會變化width: 3 # 局部地圖寬度 單位是 mheight: 3 # 局部地圖高度 單位是 mresolution: 0.05 # 局部地圖分辨率 單位是 m,一般與靜態地圖分辨率保持一致
??????? 機器人運動參數:基本的局部規劃器參數配置,這個配置文件設定了機器人的最大和最小速度限制值,也設定了加速度的閾值。
TrajectoryPlannerROS:# Robot Configuration Parametersmax_vel_x: 0.5 # X 方向最大速度min_vel_x: 0.1 # X 方向最小速速max_vel_theta: 1.0 # min_vel_theta: -1.0min_in_place_vel_theta: 1.0acc_lim_x: 1.0 # X 加速限制acc_lim_y: 0.0 # Y 加速限制acc_lim_theta: 0.6 # 角速度加速限制# Goal Tolerance Parameters,目標公差xy_goal_tolerance: 0.10yaw_goal_tolerance: 0.05# Differential-drive robot configuration # 是否是全向移動機器人holonomic_robot: false# Forward Simulation Parameters,前進模擬參數sim_time: 0.8vx_samples: 18vtheta_samples: 20sim_granularity: 0.05
????????Goal Tolerance Parameters,目標公差
? xy_goal_tolerance: 0.10
? yaw_goal_tolerance: 0.05??????? 允許和導航目標有一點距離和角度偏差。
????????是否是全向移動機器人:麥克輪設置為true。
????????前進模擬參數:本地路徑規劃和全局路徑規劃有點大像喝酒一樣!!如果差距比較大就要調試這些參數了,如果想讓本地路徑規劃和全局路徑規劃貼合的話可以將sim_time設置的長一點。
3.4.5.7 參數配置小技巧
????????以上配置在實操中,可能會出現機器人在本地路徑規劃時與全局路徑規劃不符而進入膨脹區域出現假死的情況,如何盡量避免這種情形呢?
全局路徑規劃與本地路徑規劃雖然設置的參數是一樣的,但是二者路徑規劃和避障的職能不同,可以采用不同的參數設置策略:
- 全局代價地圖可以將膨脹半徑和障礙物系數設置的偏大一些;
- 本地代價地圖可以將膨脹半徑和障礙物系數設置的偏小一些。
這樣,在全局路徑規劃時,規劃的路徑會盡量遠離障礙物,而本地路徑規劃時,機器人即便偏離全局路徑也會和障礙物之間保留更大的自由空間,從而避免了陷入“假死”的情形。
3.5.5 導航與SLAM建圖
????????SLAM建圖中,我們是通過鍵盤控制機器人移動實現建圖的,而后續又介紹了機器人的自主移動實現,那么可不可以將二者結合,實現機器人自主移動的SLAM建圖呢?
上述需求是可行的。雖然可能會有疑問,導航時需要地圖信息,之前導航實現時,是通過 ????????map_server 包的 map_server 節點來發布地圖信息的,如果不先通過SLAM建圖,那么如何發布地圖信息呢?SLAM建圖過程中本身就會時時發布地圖信息,所以無需再使用map_server,SLAM已經發布了話題為 /map 的地圖消息了,且導航需要定位模塊,SLAM本身也是可以實現定位的。
該過程實現比較簡單,步驟如下:
- 編寫launch文件,集成SLAM與move_base相關節點;
- 執行launch文件并測試。
3.5.5.1?編寫launch文件
????????集成SLAM與move_base相關節點
<launch><!-- 啟動SLAM節點 --><include file="$(find nav_robot)/launch/gmmapping.launch" /><!-- 運行move_base節點 --><include file="$(find nav_robot)/launch/move_base.launch" /><!-- 運行rviz --><node pkg="rviz" type="rviz" name="rviz" /> </launch>
1.首先運行gazebo仿真環境;
2.然后執行launch文件;
3.在rviz中通過2D Nav Goal設置目標點,機器人開始自主移動并建圖了;
4.最后可以使用 map_server 保存地圖。
??????? 設置目標點:
??????? OK~
4 導航信息
在導航功能包集中包含了諸多節點,毋庸置疑的,不同節點之間的通信使用到了消息中間件(數據載體),在上一節的實現中,這些消息已經在rviz中做了可視化處理,比如:地圖、雷達、攝像頭、里程計、路徑規劃...的相關消息在rviz中提供了相關組件,本節主要介紹這些消息的具體格式。
4.1 地圖
4.1.1 nav_msgs/MapMetaData
nav_msgs/MapMetaData
- 地圖元數據,包括地圖的寬度、高度、分辨率等。
nav_msgs/OccupancyGrid
- 地圖柵格數據,一般會在rviz中以圖形化的方式顯示。
調用
rosmsg info nav_msgs/MapMetaData
顯示消息內容如下:origin改變的話地圖相對于RVIZ也會改變time map_load_time float32 resolution #地圖分辨率 uint32 width #地圖寬度 uint32 height #地圖高度 geometry_msgs/Pose origin #地圖位姿數據geometry_msgs/Point positionfloat64 xfloat64 yfloat64 zgeometry_msgs/Quaternion orientationfloat64 xfloat64 yfloat64 zfloat64 w
4.1.2 nav_msgs/OccupancyGrid
調用
rosmsg info nav_msgs/OccupancyGrid
顯示消息內容如下:??????? 我們演示一下,讓map_server讀取地圖:
??????? 我們輸出map信息到一個txt文件:rostopic echo /map >> map.txt
??????? 看一下數據:
??????? 大部分數據都是-1表示未探索區域,0是空閑,100是占用。
??????? 但是全局代價地圖有0-100之間的數據,靠近障礙物高,遠離低。
std_msgs/Header headeruint32 seqtime stampstring frame_id #--- 地圖元數據 nav_msgs/MapMetaData infotime map_load_timefloat32 resolutionuint32 widthuint32 heightgeometry_msgs/Pose origingeometry_msgs/Point positionfloat64 xfloat64 yfloat64 zgeometry_msgs/Quaternion orientationfloat64 xfloat64 yfloat64 zfloat64 w #--- 地圖內容數據,數組長度 = width * height int8[] data
4.2 里程計數據
????????里程計相關消息是:nav_msgs/Odometry,調用
rosmsg info nav_msgs/Odometry
顯示消息內容如下:std_msgs/Header headeruint32 seqtime stampstring frame_id string child_frame_id geometry_msgs/PoseWithCovariance posegeometry_msgs/Pose pose #里程計位姿geometry_msgs/Point positionfloat64 xfloat64 yfloat64 zgeometry_msgs/Quaternion orientationfloat64 xfloat64 yfloat64 zfloat64 wfloat64[36] covariance geometry_msgs/TwistWithCovariance twistgeometry_msgs/Twist twist #速度geometry_msgs/Vector3 linearfloat64 xfloat64 yfloat64 zgeometry_msgs/Vector3 angularfloat64 xfloat64 yfloat64 z # 協方差矩陣float64[36] covariance
4.3 TF
坐標變換相關消息是: tf/tfMessage,調用
rosmsg info tf/tfMessage
顯示消息內容如下:geometry_msgs/TransformStamped[] transforms #包含了多個坐標系相對關系數據的數組std_msgs/Header headeruint32 seqtime stampstring frame_idstring child_frame_idgeometry_msgs/Transform transformgeometry_msgs/Vector3 translationfloat64 xfloat64 yfloat64 zgeometry_msgs/Quaternion rotationfloat64 xfloat64 yfloat64 zfloat64 w
4.4 定位
定位相關消息是:geometry_msgs/PoseArray,調用
rosmsg info geometry_msgs/PoseArray
顯示消息內容如下:std_msgs/Header headeruint32 seqtime stampstring frame_id geometry_msgs/Pose[] poses #預估的點位姿組成的數組geometry_msgs/Point positionfloat64 xfloat64 yfloat64 zgeometry_msgs/Quaternion orientationfloat64 xfloat64 yfloat64 zfloat64 w
4.5 路徑規劃
目標點相關消息是:move_base_msgs/MoveBaseActionGoal,調用
rosmsg info move_base_msgs/MoveBaseActionGoal
顯示消息內容如下:std_msgs/Header headeruint32 seqtime stampstring frame_id actionlib_msgs/GoalID goal_idtime stampstring id move_base_msgs/MoveBaseGoal goalgeometry_msgs/PoseStamped target_posestd_msgs/Header headeruint32 seqtime stampstring frame_idgeometry_msgs/Pose pose #目標點位姿geometry_msgs/Point positionfloat64 xfloat64 yfloat64 zgeometry_msgs/Quaternion orientationfloat64 xfloat64 yfloat64 zfloat64 w
路徑規劃相關消息是:nav_msgs/Path,調用
rosmsg info nav_msgs/Path
顯示消息內容如下:std_msgs/Header headeruint32 seqtime stampstring frame_id geometry_msgs/PoseStamped[] poses #由一系列點組成的數組std_msgs/Header headeruint32 seqtime stampstring frame_idgeometry_msgs/Pose posegeometry_msgs/Point positionfloat64 xfloat64 yfloat64 zgeometry_msgs/Quaternion orientationfloat64 xfloat64 yfloat64 zfloat64 w