Note: 本教程假定你很熟悉ROS及其使用。請先閱讀ROS Documentation。另外,軟件包2dnav_erratic是一個使用本教程創建的基於Videre Erratic平臺的軟件包. |
Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags. |
在機器人上配置並使用導航功能包集
Description: 本教程一步步介紹如何在機器人上運行導航功能包集。包括:使用tf發送變換,發佈里程計信息,發佈來自激光的傳感器信息,基本的導航功能包集的配置。
Tutorial Level: INTERMEDIATE
目錄
機器人配置
假定我們已經以特定方式配置機器人,導航功能包集將使其可以運動。上圖概述了這種配置方式。白色的部分是必須且已實現的組件,灰色的部分是可選且已實現的組件,藍色的部分是必須爲每一個機器人平臺創建的組件。以下章節將介紹使用導航功能包集的先決條件以及如何滿足不同平臺。
ROS
導航功能包集假定機器人使用ROS系統。請查閱ROS documentation以瞭解如何在你的機器人上安裝ROS。
TF變換配置(其他變換)
導航功能包集需要機器人不斷使用tf發佈有關座標系之間的關係的信息。詳細的配置教程請查閱:Tf配置.
傳感器信息(sensor source)
導航功能包集使用來自傳感器的信息避開現實環境中的障礙物,它假定這些傳感器在ROS上不斷髮布sensor_msgs/LaserScan消息或者sensor_msgs/PointCloud消息。有關在ROS上發佈這些消息的教程,請查閱在ROS上發佈傳感器數據流。此外,一些已經有了ROS上的驅動的傳感器亦滿足這一教程。一下是部分ROS支持的傳感器以及相關驅動鏈接:
-
SCIP2.2-compliant Hokuyo Laser Devices as well as the Hokuyo Model 04LX, 30LX - urg_node(英文)
-
SICK LMS2xx Lasers - sicktoolbox_wrapper(英文)
里程信息(odometry source)
導航功能包集需要使用tf和nav_msgs/Odometry消息發佈的里程信息。這裏有一篇發佈里程信息的教程:在ROS上發佈里程信息. 以下列出部分支持里程計的平臺以及可用的驅動:
-
Videre Erratic: erratic_player(英文)
基座控制器(base controller)
導航功能包集假定它可以通過話題"cmd_vel"發佈geometry_msgs/Twist類型的消息,這個消息基於機器人的基座座標系,它傳遞的是運動命令。這意味着必須有一個節點訂閱"cmd_vel"話題, 將該話題上的速度命令(vx, vy, vtheta轉換爲電機命令(cmd_vel.linear.x, cmd_vel.linear.y, cmd_vel.angular.z)發送給移動基座。以下列出部分支持基座控制器的平臺以及可用的驅動:
-
Videre Erratic: erratic_player(英文)
地圖 (map_server)
導航功能包集的配置並不需要有一張地圖以供操作,但基於本教程的目的,我們假定你有一張地圖。請查閱教程創建一張地圖瞭解在你的系統環境下創建一張地圖的細節。
導航功能包集配置
本節介紹如何配置導航功能包集。假設上述所有需要的環境都已滿足。特別的,這意味着,機器人必須使用tf發佈座標幀,並從所有的傳感器接收 sensor_msgs/LaserScan 或者 sensor_msgs/PointCloud 消息用於導航,同時需要使用 tf 和 nav_msgs/Odometry 消息發佈導航消息,消息會以命令的形式下發給機器人底座。如果所需要的配置你都沒有,請參見機器人配置。
創建一個軟件包
首先,我們創建一個軟件包,用來保存我們所有的配置文件和啓動文件。這個軟件包需要包含所有用於實現 機器人配置小節所述依賴,就如其以依賴導航功能包集高級接口 move_base 軟件包一樣。因此, 爲你的軟件包選好位置,執行以下命令:
catkin_create_pkg my_robot_name_2dnav move_base my_tf_configuration_dep my_odom_configuration_dep my_sensor_configuration_dep
這個指令會創建一個包含運行導航功能包集所需依賴的軟件包。
創建機器人啓動配置文件
現在,我們有了一個存放所有配置文件和啓動文件的工作空間,我們會創建一個ROS launch文件來啓動所有的硬件以及發佈機器人所需的tf。打開你喜歡的編輯器,粘貼一下內容到my_robot_configuration.launch。你可以自由的將 "my_robot" 改成你的機器人的名字。以後,我們會對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>
這裏,我們會啓動機器人運行導航功能包所需的所有傳感器。用你的傳感器對應的ROS驅動包替換"sensor_node_pkg",用你的傳感器類型替換"sensor_node_type"(通常與節點名一致),用你的傳感器節點名替換"sensor_node_name","sensor_param"包含所有必需的參數。注意,如果你有多個傳感器,在這裏一起啓動它們。
<node pkg="odom_node_pkg" type="odom_node_type" name="odom_node" output="screen">
<param name="odom_param" value="param_value" />
</node>
這裏,我們啓動基座(底盤)的里程計。同樣,替換相應的pkg, type, name,並根據實際指定相關參數。
<node pkg="transform_configuration_pkg" type="transform_configuration_type" name="transform_configuration_name" output="screen">
<param name="transform_configuration_param" value="param_value" />
</node>
這裏,我們啓動相應的tf變換。同樣,替換相應的pkg, type, name,並根據實際指定相關參數。
配置代價地圖 (local_costmap) & (global_costmap)
導航功能包集需要兩個代價地圖來保存世界中的障礙物信息。一張代價地圖用於路徑規劃,在整個環境中創建長期的路徑規劃,另一個用於局部路徑規劃與避障。有一些參數兩個地圖都需要,而有一些則各不相同。因此,對於代價地圖,有三個配置項: common配置項, global配置項和local配置項。
注意: 接下來的內容只是代價地圖的基本配置項。想要查看完整的配置,參看costmap_2d文檔.
共同配置(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.0米遠的空間。
footprint: [[x0, y0], [x1, y1], ... [xn, yn]]
#robot_radius: ir_of_robot
inflation_radius: 0.55
這裏我們設置機器人的footprint或機器人半徑(如果是圓形的)。 指定的footprint時,機器人的中心被認爲是在(0.0,0.0),順時針和逆時針規範都支持。 我們還將設置代價地圖膨脹半徑。膨脹半徑應該設置爲障礙物產生代價的最大距離。 例如,膨脹半徑設定在0.55米意味着機器人所有路徑與障礙物保持0.55米或更的遠離(具有同樣的代價)。
observation_sources: laser_scan_sensor point_cloud_sensor
“observation_sources”參數定義了一系列傳遞空間信息給代價地圖的傳感器。每個傳感器定義在下一行。
laser_scan_sensor: {sensor_frame: frame_name, data_type: LaserScan, topic: topic_name, marking: true, clearing: true}
這一行設置“observation_sources”中提到的傳感器。這個例子定義了 laser_scan_sensor。 “frame_name”參數應設置爲傳感器座標幀的名稱,“data_type”參數應設置爲LaserScan或PointCloud,這取決於主題使用的消息,“topic_name”應該設置爲發佈傳感器數據的主題的名稱。 “marking”和“clearing”參數確定傳感器是否用於向代價地圖添加障礙物信息,或從代價地圖清除障礙信息,或兩者都有。
全局配置(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”參數決定了代價地圖更新的頻率。 “static_map”參數決定代價地圖是否根據map_server提供的地圖初始化。如果你不使用現有的地圖,設爲false。
本地配置(local_costmap)
下面我們將創建一個存儲特定的本地代價地圖配置選項的文件。新建一個文件:localal_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”參數決定了代價地圖發佈可視化信息的頻率。將“rolling_window”參數設置爲true,意味着隨着機器人在現實世界裏移動,代價地圖會保持以機器人爲中心。“width”、“height”、“resolution”參數分別設置局部代價地圖的寬度(米)、高度(米)和分辨率(米/單元)。 注意,這裏的分辨率和你的靜態地圖的分辨率可能不同,但我們通常把他們設成一樣的。
完整的配置選項
這裏是用於啓動和運行的最簡單的配置,更多的細節請參閱costmap_2d 文檔.
Base Local Planner 配置
Base_local_planner負責根據全局路徑規劃計算速度命令併發送給機器人基座。 我們需要根據我們的機器人規格配置一些選項使其正常啓動與運行。新建一個名爲base_local_planner_params.yaml的文件,內容如下:
注意: 本節只涵蓋TrajectoryPlanner的基本配置選項。 文檔的全部選項,請參閱base_local_planner 文檔.
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
上面的第一部分參數定義機器人的速度限制。 第二部分定義了機器人的加速度的限制。
爲導航功能包創建一個Launch啓動文件
現在我們已經有了所有的配置文件,我們需要在一個啓動文件中一起啓動他們,創建一個名爲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>
唯一需要修改的地方是更改地圖服務器使指向你的已有的地圖,並且,如果你有一臺差分驅動的機器人,將"amcl_omni.launch"改爲"amcl_diff.launch"。對於如何創建一張地圖,請查閱 創建一張地圖.
AMCL 配置(amcl)
AMCL有許多配置選項將影響定位的性能。 有關AMCL的更多信息請參閱amcl文檔.
運行導航功能包集
現在我們配置結束,我們可以運行導航功能包了。爲此我們需要在機器人上啓動兩個終端。 在一個終端上,我們將啓動 my_robot_configuration.launch 文件,在另一個終端上我們將啓動我們剛剛創建的move_base.launch
終端1:
roslaunch my_robot_configuration.launch
終端2:
roslaunch move_base.launch
祝賀你,導航功能包集現在應該運行了。關於如何通過圖形化界面給導航功能包集發送一個目標信息,請參閱rviz和導航教程。 如果你想使用代碼給導航功能包集發送導航目標,請參閱發送簡單導航目標教程。