如何配置機器人的導航功能
1、概述
ROS的二維導航功能包,簡單來說,就是根據輸入的里程計等傳感器的信息流和機器人的全局位置,通過導航算法,計算得出安全可靠的機器人速度控制指令。但是,如何在特定的機器人上實現導航功能包的功能,卻是一件較爲複雜的工程。作爲導航功能包使用的必要先決條件,機器人必須運行ROS,發佈tf變換樹,併發布使用ROS消息類型的傳感器數據。同時,爲了讓機器人更好的完成導航任務,開發者還要根據機器人的外形尺寸和性能,配置導航功能包的一些參數。
2、硬件要求
儘管導航功能包設計得儘可能通用,但是仍然對機器人的硬件有以下三個要求:
(1)導航功能包僅對差分等輪式機器人有效,並且假設機器人可直接使用速度指令進行控制,速度指令的格式爲:x方向速度、y方向速度、速度向量角度。
(2)導航功能包要求機器人必須安裝有激光雷達等二維平面測距設備。
(3)導航功能包以正方型的機器人爲模型進行開發,所以對於正方形或者圓形外形的機器人支持度較好,而對於其他外形的機器人來講,雖然仍然可以正常使用,但是表現則很有可能不佳。
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>
-
<node pkg="sensor_node_pkg" type="sensor_node_type" name="sensor_node_name" output="screen">
-
<param name="sensor_param" value="param_value" />
-
</node>
-
-
<node pkg="odom_node_pkg" type="odom_node_type" name="odom_node" output="screen">
-
<param name="odom_param" value="param_value" />
-
</node>
-
-
<node pkg="transform_configuration_pkg" type="transform_configuration_type" name="transform_configuration_name" output="screen">
-
<param name="transform_configuration_param" value="param_value" />
-
</node>
-
</launch>
讓我們來詳細的解讀以上內容的含義:
-
<launch>
-
<node pkg="sensor_node_pkg" type="sensor_node_type" name="sensor_node_name" output="screen">
-
<param name="sensor_param" value="param_value" />
這部分代碼用來啓動機器人的傳感器,根據以上格式,修改你所使用到的傳感器驅動包名稱、類型、命名等信息,並且添加驅動包節點需要使用到的參數。當然,如果你需要使用多個傳感器,可以使用相同的方法,啓動多個傳感器的驅動節點。
-
<node pkg="odom_node_pkg" type="odom_node_type" name="odom_node" output="screen">
-
<param name="odom_param" value="param_value" />
-
</node>
這部分代碼用來啓動機器人上的里程計,根據需要修改功能包名、類型、節點名、參數。
-
<node pkg="transform_configuration_pkg" type="transform_configuration_type" name="transform_configuration_name" output="screen">
-
<param name="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>
-
<master auto="start"/>
-
-
<!-- Run the map server -->
-
<node name="map_server" pkg="map_server" type="map_server" args="$(find my_map_package)/my_map.pgm my_map_resolution"/>
-
-
<!--- Run AMCL -->
-
<include file="$(find amcl)/examples/amcl_omni.launch" />
-
-
<node pkg="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="$(find my_robot_name_2dnav)/costmap_common_params.yaml" command="load" ns="local_costmap" />
-
<rosparam file="$(find my_robot_name_2dnav)/local_costmap_params.yaml" command="load" />
-
<rosparam file="$(find my_robot_name_2dnav)/global_costmap_params.yaml" command="load" />
-
<rosparam file="$(find my_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 。