在前一節中,采用gmapping包實作了機器人工作環境的地圖建構,這一節将利用amcl包和move_base包實作移動機器人的自主導航。至此已完成整個移動機器人導航仿真的工作,完整代碼見:http://download.csdn.net/detail/wangchao7281/9717920
amcl
amcl是移動機器人在2D環境中的機率定位系統。它實作了自适應(或KLD采樣)蒙特卡羅定位方法,其使用粒子濾波器來針對已知的地圖跟蹤機器人的位姿。目前情況下,該節點僅能使用雷射掃描資料和雷射雷達地圖來工作。它可以通過修改代碼以擴充到其他傳感器資料。
amcl接收基于雷射的地圖,雷射掃描和tf變換消息,并輸出位姿估計。在啟動時,amcl根據提供的參數初始化其粒子濾波器。注意,如果沒有設定初始化參數,則根據預設值初始濾波器狀态将是以(0,0,0)為中心的中等大小的粒子雲。在rviz中可以通過2D Pose Estimate按鈕來初始化位姿。
在ROS自帶的檔案中,
rospack find amcl
/examples/amcl_diff.launch支援差分驅動機器人平台,而amcl_omni.launch 支援全向移動機器人平台。
在啟動launch檔案前,可以配置一系列的參數來滿足系統的要求。其中比較重要的幾個參數如下:
1. 參數min_particles和max_particles設定了算法運作所允許的粒子最小和最大數量。粒子數越多,結果越精确,CPU消耗也越高。
2. 參數laser_model_type用于配置雷射雷達的類型。
3. 參數laser_likehood_max_dist用于設定地圖中障礙物膨脹的最大距離,使用此參數前提是laser_type_model選擇了likehood_field模式。
詳見:http://wiki.ros.org/amcl
move_base
move_base包提供了一個動作的實作(參見actionlib包),在地圖上給定一個目标,move_base将會規劃出路徑并使機器人避開障礙物進而到達目标。詳見:http://wiki.ros.org/move_base
move_base節點将全局導航和局部導航連結在一起以完成其導航任務。全局導航用于建立到地圖上最終目标或一個遠距離目标的路徑,局部導航用于建立到近距離目标和為了臨時躲避障礙物的路徑,例如機器人四周一個4x4 m的方形視窗。
move_base節點支援任何遵循nav_core包中指定的nav_core :: BaseGlobalPlanner接口的全局規劃以及任何遵循nav_core包中指定的nav_core :: BaseLocalPlanner接口的局部規劃。move_base節點還維護兩個代價地圖,分别為全局代價地圖和局部代價地圖。
在運作move_base節點之前需要四個配置檔案,這些文建定義了一系列相關參數,包括越過障礙物的代價、機器人的半徑、路勁規劃時的需要考慮未來多長的路,機器人的的最大速度等等,四個配置檔案分别如下
- base_local_palnner_params.yaml
- costmap_common_params.yaml
- global_costmap_params.yaml
- local_costmap_params.yaml
具體的參數配置資訊參見http://wiki.ros.org/base_local_planner、http://wiki.ros.org/costmap_2d
部落客在仿真過程中發現對導航效果有較大影響的參數如下:
1.基本局部規劃器配置(base_local_palnner_params.yaml)
- max_vel_x:機器人的最大線速度,機關是 m/s,對于室内機器人來說0.5就已經很快了。
- max_rotation_vel:機器人的最大旋轉速度,機關是 rad/s,不要把這個值設的過高,不然機器人會錯過目标方向。
- yaw_goal_tolerance:至多距離目标方向的偏差,把這個值設的太小可能會導緻機器人在目标附近徘徊。
- xy_goal_tolerance:至多距離目标位置的偏差,把這個值設的太小可能會導緻機器人在目标附近徘徊。注意:不要把最大誤差設定的比地圖分辨率還小,否則機器人會一直在目标附近徘徊而永遠到不了目标。
- pdist_scale:全局路徑規劃和到達目的之間的權重。
- gdist_scale:到達目的位置和全局路徑規劃之間的權重。
2.代價地圖共同的參數配置(costmap_common_params.yaml)
- inflation_radius:地圖上障礙物的膨脹半徑,機關為 m,如果機器人不能很好的通過狹窄的地方,則稍微減小這個值,相反,如果機器人不斷的撞到東西,則稍微增大這個值。
仿真實作
首先啟動機器人模型
<launch>
<!-- these are the arguments you can pass this launch file, for example paused:=true -->
<arg name="paused" default="true"/>
<arg name="use_sim_time" default="true"/>
<arg name="gui" default="true"/>
<arg name="headless" default="false"/>
<arg name="debug" default="false"/>
<remap from="robot/laser/scan" to="/scan"/>
<include file="$(find gazebo_ros)/launch/empty_world.launch">
<arg name="world_name" value="$(find nav_sim)/urdf/wall.world"/>
<arg name="use_sim_time" value="$(arg use_sim_time)"/>
<arg name="debug" value="$(arg debug)" />
<arg name="gui" value="$(arg gui)" />
</include>
<!-- Load the URDF into the ROS Parameter Server -->
<arg name="model" default="$(find nav_sim)/urdf/myrobot.xacro" />
<param name="robot_description" command="$(find xacro)/xacro.py $(arg model)" />
<!-- Run a python script to send a service call the gazebo_ros to spawn a URDF robot -->
<node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen"
args="-urdf -model robot -param robot_description -z 0.05"/>
<node name="rviz" pkg="rviz" type="rviz" args="-d $(find nav_sim)/urdf/navigation.rviz"/>
<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
<node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher"/>
</launch>
然後啟動amcl和move_base
<?xml version="1.0"?>
<launch>
<!-- Run the map server -->
<node name="map_server" pkg="map_server" type="map_server" args="$(find nav_sim)/maps/map.yaml" output="screen"/>
<include file="$(find amcl)/examples/amcl_diff.launch" >
</include>
<node pkg="move_base" type="move_base" respawn="false" name="move_base" output="screen">
<param name="controller_frequency" value="10.0"/>
<param name="controller_patiente" value="15.0"/>
<rosparam file="$(find nav_sim)/launch/costmap_common_params.yaml" command="load" ns="global_costmap" />
<rosparam file="$(find nav_sim)/launch/costmap_common_params.yaml" command="load" ns="local_costmap" />
<rosparam file="$(find nav_sim)/launch/local_costmap_params.yaml" command="load" />
<rosparam file="$(find nav_sim)/launch/global_costmap_params.yaml" command="load" />
<rosparam file="$(find nav_sim)/launch/base_local_planner_params.yaml" command="load" />
</node>
</launch>
上圖包圍機器人的紅色部分即為用于機器人定位系統的李子雲,點雲的分布表示了再定位系統中機器人位姿的不确定性。
點選2D Nav Goal按鈕可以設定機器人要達到的目标點,然後move_base會規劃處一條綠色的全局路徑,和不斷規劃藍色的局部路徑。粒子點雲也随着機器人的移動不确定性逐漸減少,機器人的位姿估計更加準确。
move_base的一項重要功能是當機器人遇到障礙物時,能夠對原定路徑進行重新規劃和計算,我在gazebo環境中臨時添加了一個新的物體,機器人檢測到新的障礙物并重新規劃路徑。
在仿真過程中,可以使用rqt_reconfigure在不重新啟動仿真的情況下對參數值進行修改,使用以下指令:
$ rosrun rqt_reconfigure rqt_reconfigure
節點關系圖:
仿真過程視訊:http://v.youku.com/v_show/id_XMTg2NzY4MjY5Ng==.html
參考文獻
- http://wiki.ros.org/
- ROS by Example vol1 indigo
- Learnning ROS for Robotics Programming second edition