博客轉自:https://blog.csdn.net/hcx25909/article/details/50539417
1、概述
ROS的二維導航功能包,簡單來說,就是根據輸入的里程計等傳感器的信息流和機器人的全局位置,通過導航算法,計算得出安全可靠的機器人速度控制指令。但是,如何在特定的機器人上實現導航功能包的功能,卻是一件較為復雜的工程。作為導航功能包使用的必要先決條件,機器人必須運行ROS,發布tf變換樹,並發布使用ROS消息類型的傳感器數據。同時,為了讓機器人更好的完成導航任務,開發者還要根據機器人的外形尺寸和性能,配置導航功能包的一些參數。
2、硬件要求
盡管導航功能包設計得盡可能通用,但是仍然對機器人的硬件有以下三個要求:
- 導航功能包僅對差分等輪式機器人有效,並且假設機器人可直接使用速度指令進行控制,速度指令的格式為:x方向速度、y方向速度、速度向量角度。
- 導航功能包要求機器人必須安裝有激光雷達等二維平面測距設備。
- 導航功能包以正方型的機器人為模型進行開發,所以對於正方形或者圓形外形的機器人支持度較好,而對於其他外形的機器人來講,雖然仍然可以正常使用,但是表現則很有可能不佳。
3、機器人配置
導航功能包的結構如上圖所示,在自己的機器人平台上實現自主導航,簡單來說,就是按照上圖將需要的功能按照需求完成即可。其中白色的部分是ROS功能包已經完成的部分,不需要我們去實現,灰色的是可選的部分,也由ROS完成,在使用中根據需求使用,需要關注的重點部分是藍色部分,這些需要我們根據輸入輸出的要求完成相應的功能。
3.1、ROS
首先,請確保你的機器人安裝了ROS框架。
3.2、tf變換(sensortransforms)
導航功能包要求機器人以tf樹的形式發布各個相關參考系的變換關系。
3.3、傳感器信息(sensor sources)
導航功能包需要采集機器人的傳感器信息,以達到實時避障的效果。這些傳感器要求能夠通過ROS發布
sensor_msgs/LaserScan或者sensor_msgs/PointCloud 格式的消息,也就是二維雷達信息或者三維點雲數據。ROS社區已經支持大部分激光雷達、Kinect等設備的驅動,可以直接使用社區提供的驅動功能包發布滿足要求的傳感器信息。如果你使用的傳感器沒有ROS支持,或者你想使用自己的驅動,也可以自己將傳感器信息封裝成要求的格式。
3.4、里程計信息(odometrysource)
導航功能包要求機器人發布nav_msgs/Odometry格式的里程計信息,同時在也要發布相應的tf變換。
3.5、機器人控制器(base_controller)
導航功能包最終的輸出是針對機器人geometry_msgs/Twist格式的控制指令,這就要求機器人控制節點具備解析控制指令中速度、角度的能力,並且最終通過這些指令控制機器人完成相應的運動目標。
3.6、地圖(map_server)
地圖並不是導航功能所必需的。
4、導航功能包集的配置
在滿足以上條件的前提下,我們來針對導航功能進行一些配置。
4.1、創建一個功能包
首先,我們需要創建一個功能包,用來存儲導航需要用到的所有的配置文件和launch啟動文件。在創建功能包的時候,我們需要添加相關的所有依賴,包括機器人配置中使用到的功能包,當然不要忘記了move_base功能包,因為該包有很多我們后面需要用到的接口。找到合適的位置,輸入以下命令來創建包:
catkin_create_pkg my_robot_name_2dnav move_base my_tf_configuration_depmy_odom_configuration_dep my_sensor_configuration_dep
4.2、創建機器人啟動文件
現在,我們已經有了一個存儲各種文件的工作空間,下一步,我們來創建一個機器人啟動文件,用來啟動機器人配置中所提到的所有硬件,並發布相應的消息和變換關系。 打開編輯器,輸入以下格式的內容,並保存為my_robot_configuration.launch命名的文件:
<launch> <nodepkg="sensor_node_pkg" type="sensor_node_type"name="sensor_node_name" output="screen"> <paramname="sensor_param" value="param_value" /> </node> <nodepkg="odom_node_pkg" type="odom_node_type"name="odom_node" output="screen"> <paramname="odom_param" value="param_value" /> </node> <nodepkg="transform_configuration_pkg"type="transform_configuration_type"name="transform_configuration_name" output="screen"> <paramname="transform_configuration_param" value="param_value"/> </node> </launch>
讓我們來詳細的解讀以上內容的含義:
<launch> <nodepkg="sensor_node_pkg" type="sensor_node_type"name="sensor_node_name" output="screen"> <paramname="sensor_param" value="param_value" />
這部分代碼用來啟動機器人上的里程計,根據需要修改功能包名、類型、節點名、參數。
<nodepkg="transform_configuration_pkg"type="transform_configuration_type"name="transform_configuration_name" output="screen"> <paramname="transform_configuration_param" value="param_value"/> </node>
這部分代碼需要啟動機器人相關的坐標變換。
4.3、代價地圖的配置 (local_costmap)& (global_costmap)
導航功能包使用兩種代價地圖存儲周圍環境中的障礙信息,一種用於全局路徑規划,一種用於本地路徑規划和實時避障。兩種代價地圖需要使用一些共同和獨立的配置文件:通用配置文件,全局規划配置文件,本地規划配置文件。以下將詳細講解這三種配置文件:
1. 通用配置文件(Common Configuration (local_costmap) &(global_costmap))
代價地圖用來存儲周圍環境的障礙信息,其中需要注明地圖關注的機器人傳感器消息,以便於地圖信息進行更行。針對兩種代價地圖通用的配置選項,創建名為costmap_common_params.yaml的配置文件:
obstacle_range: 2.5 raytrace_range: 3.0 footprint: [[x0, y0], [x1, y1], ... [xn, yn]] #robot_radius: ir_of_robot inflation_radius: 0.55 observation_sources: laser_scan_sensor point_cloud_sensor laser_scan_sensor: {sensor_frame: frame_name, data_type: LaserScan, topic: topic_name, marking: true, clearing: true} point_cloud_sensor: {sensor_frame: frame_name, data_type: PointCloud, topic: topic_name, marking: true, clearing: true}
詳細解析以上配置文件的內容:
obstacle_range: 2.5 raytrace_range: 3.0
這兩個參數用來設置代價地圖中障礙物的相關閾值。obstacle_range參數用來設置機器人檢測障礙物的最大范圍,設置為2.5意為在2.5米范圍內檢測到的障礙信息,才會在地圖中進行更新。raytrace_range參數用來設置機器人檢測自由空間的最大范圍,設置為3.0意為在3米范圍內,機器人將根據傳感器的信息,清除范圍內的自由空間。
footprint: [[x0, y0], [x1, y1], ... [xn, yn]] #robot_radius: ir_of_robot inflation_radius: 0.55
這些參數用來設置機器人在二維地圖上的占用面積,如果機器人外形是圓形,則需要設置機器人的外形半徑。所有參數以機器人的中心作為坐標(0,0)點。inflation_radius參數是設置障礙物的膨脹參數,也就是機器人應該與障礙物保持的最小安全距離,這里設置為0.55意為為機器人規划的路徑應該與機器人保持0.55米以上的安全距離。
observation_sources: laser_scan_sensorpoint_cloud_sensor
observation_sources參數列出了代價地圖需要關注的所有傳感器信息,每一個傳感器信息都將在后邊列出詳細信息。
laser_scan_sensor: {sensor_frame: frame_name, data_type:LaserScan, topic: topic_name, marking: true, clearing: true}
以激光雷達為例,sensor_frame標識傳感器的參考系名稱,data_type表示激光數據或者點雲數據使用的消息類型,topic_name表示傳感器發布的話題名稱,而marking和clearing參數用來表示是否需要使用傳感器的實時信息來添加或清楚代價地圖中的障礙物信息。
2. 全局規划配置文件(Global Configuration (global_costmap))
全局規划配置文件用來存儲用於全局代價地圖的配置參數,我們使用global_costmap_params.yaml來命名,內容如下:
global_costmap: global_frame: /map robot_base_frame: base_link update_frequency: 5.0 static_map:true
global_frame參數用來表示全局代價地圖需要在那個參考系下運行,這里我們選擇了map這個參考系。robot_base_frame參數表示代價地圖可以參考的機器人本體的參考系。update_frequency參數絕地全局地圖信息更新的頻率,單位是Hz。static_map參數決定代價地圖是否需要根據map_server提供的地圖信息進行初始化,如果你不需要使用已有的地圖或者map_server,最好將該參數設置為false。
3. 本地規划配置文件(Local Configuration (local_costmap))
本地規划配置文件用來存儲用於本地代價地圖的配置參數,命名為local_costmap_params.yaml,內容如下:
local_costmap: global_frame: odom robot_base_frame: base_link update_frequency: 5.0 publish_frequency: 2.0 static_map:false rolling_window: true width: 6.0 height: 6.0 resolution:0.05
"global_frame", "robot_base_frame","update_frequency", 和 "static_map"參數的意義與全局規划配置文件中的參數相同。publish_frequency設置代價地圖發布可視化信息的頻率,單位是Hz。rolling_window參數是用來設置在機器人移動過程中是否需要滾動窗口,以保持機器人處於中心位置。"width," "height," 和"resolution" 設置設置代價地圖長(米)、高(米)和分辨率(米/格)。分辨率可以設置的與靜態地圖不同,但是一般情況下兩者是相同的。
4.4 本地規划器配置
本地規划器base_local_planner的主要作用是根據規划的全局路徑,計算發布給機器人的速度指令。該規划器需要我們根據機器人的規格,配置一些相應的參數。我們創建名為base_local_planner_params.yaml的配置文件:
TrajectoryPlannerROS: max_vel_x: 0.45 min_vel_x: 0.1 max_vel_theta: 1.0 min_in_place_vel_theta: 0.4 acc_lim_theta: 3.2 acc_lim_x: 2.5 acc_lim_y: 2.5 holonomic_robot: true
該配置文件聲明了機器人的本地規划采用Trajectory Rollout算法。第一段設置了機器人的速度閾值,第二段設置了機器人的加速度閾值。
4.5 為導航功能包創建一個啟動文件
到此為止,我們已經創建完畢所有需要用到的配置文件,接下來我們需要創建一個啟動文件,來啟動所有需要的功能。創建move_base.launch的文件:
<launch> <masterauto="start"/> <!-- Runthe map server --> <nodename="map_server" pkg="map_server"type="map_server" args="$(find my_map_package)/my_map.pgm my_map_resolution"/> <!---Run AMCL --> <includefile="$(find amcl)/examples/amcl_omni.launch" /> <nodepkg="move_base" type="move_base" respawn="false"name="move_base" output="screen"> <rosparam file="$(find my_robot_name_2dnav)/costmap_common_params.yaml"command="load" ns="global_costmap" /> <rosparam file="$(findmy_robot_name_2dnav)/costmap_common_params.yaml" command="load"ns="local_costmap" /> <rosparam file="$(findmy_robot_name_2dnav)/local_costmap_params.yaml" command="load" /> <rosparam file="$(findmy_robot_name_2dnav)/global_costmap_params.yaml" command="load"/> <rosparam file="$(findmy_robot_name_2dnav)/base_local_planner_params.yaml"command="load" /> </node> </launch>
在該配置文件中,你需要修改的只有map-server輸入的地圖,以及如果使用差分驅動的機器人,需要修改"amcl_omni.launch"成"amcl_diff.launch" 。
4.6 AMCL功能包的設置
AMCL有許多的參數設置,會影響機器人的定位效果,具體參考amcldocumentation。
5、運行導航功能包
現在,我們已經完成了所有需要的工作,最后一步,運行啟動文件,開始導航之旅:
roslaunch my_robot_configuration.launch roslaunch move_base.launch
現在導航功能包應該已經可以順利運行了,但這絕對不是結束,因為你只能從終端里看到一端亂蹦的代碼,如何使用更友好的方式進行機器人導航呢?如果你想使用UI界面,請參考rviz and navigationtutorial,如果你想使用代碼,請參考Sending SimpleNavigation Goals 。