本文主要介紹了導航功能包集的配置和使用。
1 機器人設定
假定我們已經以特定方式設定好了機器人,導航功能包集將使其可以運動。上圖概述了這種配置方式。白色的部分是必須且已實現的組件,灰色的部分是可選且已實現的組件,藍色的部分是必須為每一個機器人平台定製建立的組件。
1.1 ROS
導航功能包集假定你的機器人使用ROS系統。請查閱ROS documentation以瞭解如何在你的機器人上安裝ROS。
1.2 TF變換配置(其他變換)
導航功能包集需要機器人不斷使用tf發布有關座標系之間的關係的資訊。詳細的配置教程請查閱:Tf配置.
1.3 感應器資訊(sensor source)
導航功能包集使用來自感應器的資訊實現避開實體環境中的障礙物,並且假定這些感應器在ROS上不斷髮布sensor_msgs/LaserScan訊息或者sensor_msgs/PointCloud訊息。有關在ROS上發布這些訊息的教程,請查閱在ROS上發布感應器資料流。以下是部分ROS已經支援的感應器以及相關驅動連結:
SCIP2.2-compliant Hokuyo Laser Devices as well as the Hokuyo Model 04LX, 30LX -urg_node(英文)
SICK LMS2xx Lasers - sicktoolbox_wrapper(英文)
1.4 裡程資訊(odometry source)
導航功能包集需要使用通過tf和nav_msgs/Odometry訊息發布的裡程資訊。這裡有一篇如何發布裡程資訊的教程:在ROS上發布裡程資訊. 以下列出部分支援裡程計的平台以及可用的驅動:
Videre Erratic: erratic_player(英文)
PR2: pr2_mechanism_controllers(英文)
1.5 基座控制器(base controller)
導航功能包集通過在"cmd_vel" topic上發布geometry_msgs/Twist類型的訊息,以達到給基座發送速度命令控制基座移動目的。這意味著必須有一個節點訂閱"cmd_vel" topic, 該topic上的速度資訊為(vx, vy, vtheta)<===>(cmd_vel.linear.x, cmd_vel.linear.y, cmd_vel.angular.z),並能將這些速度資訊轉換成控制馬達的命令發送給移動基座。
以下列出部分支援基座控制器的平台以及可用的驅動:
Videre Erratic: erratic_player(英文)
PR2: pr2_mechanism_controllers(英文)
1.6 地圖 (map_server)
雖然導航功能包集的配置並不需要操作地圖,但考慮到下面使用案例,我們假定你有一張地圖。如果沒有請查閱教程建立一張地圖瞭解如何在你的系統內容下建立一張地圖的細節。
2 導航功能包集設定
本部分將介紹如何配置導航功能包集。假設上述所有需要的環境都已滿足。這裡特別提醒的是,機器人必須能夠使用tf發布座標幀,能接收來自感應器的sensor_msgs/LaserScan 或者sensor_msgs/PointCloud 訊息供導航功能包集使用,能使用tf 和nav_msgs/Odometry 訊息發布裡程訊息,也能接受速度命令並發給基座。如果機器人所需要的這些配置你都沒有,請參考上面的機器人配置完成它們。
2.1 建立一個package
首先,我們建立一個package來儲存使用導航功能包集所必須設定檔和開機檔案。 這個package依賴一些其它的packages用於實現機器人配置小節所述,以及提供了供導航功能包集提供者的move_base 包。
現在為你的package選好位置,並執行以下命令:
catkin_create_pkg my_robot_name_2dnav move_base my_tf_configuration_dep my_odom_configuration_dep my_sensor_configuration_dep
2.2 建立機器人啟動設定檔
現在,我們有了一個存放設定檔和開機檔案的工作空間,我們會建立一個roslaunch檔案來啟動所有的硬體並發布機器人所需的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,並根據實際指定相關參數。
2.3 配置代價地圖 (local_costmap) & (global_costmap)
導航功能包集需要兩個代價地圖來儲存現實世界中的障礙物資訊。一張代價地圖用於在整個環境中建立長期的規劃,另一個用於局部規劃與即時避障。有一些參數兩個地圖都需要,而有一些則各不相同。因此,對於代價地圖,有三個配置項: common配置項, global配置項和local配置項。
注意: 接下來的內容只是代價地圖的基本配置項。想要查看完整的配置,參看costmap_2d文檔.
2.3.1 共同配置(local_costmap) & (global_costmap)
導航功能包集使用代價地圖儲存障礙物資訊。 這裡我們需要指出要監聽的感應器的話題,以更新資料。
為此我們建立一個名為costmap_common_params.yaml的檔案,內容如下:
obstacle_range: 2.5raytrace_range: 3.0footprint: [[x0, y0], [x1, y1], ... [xn, yn]]#robot_radius: ir_of_robotinflation_radius: 0.55observation_sources: laser_scan_sensor point_cloud_sensorlaser_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.5raytrace_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_robotinflation_radius: 0.55
這裡我們設定機器人的footprint或機器人半徑(如果是圓形的)。 指定的footprint時,機器人的中心被認為是原點(0.0,0.0),順時針和逆時針規範都支援。 將機器人的幾何參數告訴導航功能包集。這樣,機器人和障礙物之間就能保持一個合理的距離,也就是說,例如前方有個門,要提前探知機器人是否能穿過這個門。我們還將設定代價地圖膨脹半徑inflation_radius,給定機器人與障礙物之間必須要保持的最小距離。按照機器人的內切半徑對障礙物進行膨脹處理。 例如,膨脹半徑設定在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”參數確定感應器是否用於向代價地圖添加障礙物資訊,或從代價地圖清除障礙資訊,或兩者都有。
2.3.2 全域配置(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”參數定義了代價地圖參考的的機器人基座座標系。global_costmap和robot_base_frame定義機器人和地圖之間的座標變換,建立全域代價地圖必須使用這個變換。“update_frequency”參數決定了代價地圖更新的頻率。 “static_map”參數決定代價地圖是否根據map_server提供的地圖初始化。如果你不使用現有的地圖,設為false。
2.3.3 本地配置(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”參數分別設定代價地圖的寬度(米、)高度(米)和解析度(米/單元)。 注意,這裡的解析度和你的靜態地圖的解析度可能不同,但我們通常把他們設成一樣的。
2.3.4 完整的配置選項
這裡是用於啟動和啟動並執行最簡單的配置,更多的代價地圖設定細節請參閱costmap_2d 文檔.
2.4 基座局部規劃器配置
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
上面的第一部分參數定義機器人的速度限制。 第二部分定義了機器人的加速度的限制。 holonomic_robot: 如果你的機器人是全向移動機器人那麼此值為true,差分型的為false。
2.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>
唯一需要修改的地方是更改地圖伺服器指向你的已有的地圖,並且如果你有一台差分驅動的機器人,將"amcl_omni.launch"改為"amcl_diff.launch"。
對於如何建立一張地圖,請查閱建立一張地圖.
2.6 AMCL 配置(amcl)
AMCL有許多配置選項會影響定位的效能。 有關AMCL的更多資訊請參閱amcl文檔.
利用自適應蒙特卡羅定位(AMCL)演算法完成機器人定位,該方法是一種在2D環境下移動機器人的機率統計方法,這種方法在ROS系統中的具體實現是通過在已知地圖的基礎上使用粒子濾波演算法跟蹤機器人的位姿。如果你在rviz裡不通過2D Pose Estimate 按鈕設定初始位姿,則AMCL會假定你的機器人從座標原點開始運行。這個包預設雷射雷達資料,你也可以修改源碼,適應如雙目之類的感應器。amcl_diff.launch是專用於支援差分驅動機器人平台的。
3 運行導航功能包集
現在配置結束了,我們可以運行導航功能包集了。為此我們需要在機器人上啟動兩個終端。 在一個終端上,我們將運行有關機器人設定的 my_robot_configuration.launch 檔案,在另一個終端上我們將啟動我們剛剛建立的用於導航功能的move_base.launch。
終端1:
roslaunch my_robot_configuration.launch
終端2:
roslaunch move_base.launch
關於如何通過圖形化介面給導航功能包集發送目標資訊,請參閱rviz和導航教程。 如果你想使用代碼給導航功能包集發送導航目標,請參閱發送簡單導航目標教程。
4 故障排除