To add navigation to a robot, we need to launch 3 nodes:
- map_server: to provide the static map {“*.yaml” & “*.pgm”}, against which the robot will localize and plan.
- amcl: to localize the robot against the static map.
- move_base: to handle global planning and local control for the robot.
amcl 是移动机器人二维环境下的概率定位系统,它实现了自适应(或 kdl 采样)的 蒙特卡洛定位 方法,其中针对已有的地图使用 粒子滤波器 跟踪一个机器人的姿态。
move_base 提供了 ROS 导航的配置,运行,交互接口,主要包括两个部分:
amcl
amcl(Adaptive Monte Carlo Localization) —-> pose(position, oriention) <—- map 坐标系
自主定位
- 全局定位:通过测机器人的绝对未知来定位,定位的精度较高,并且可以用来修复局部定位的定位误差
- 局部定位:通过测量相对于机器人初始位置的距离和方向来确定当前的位姿,但随着时间的累计造成定位的误差较大,无法精确定位
AMCL maintains a set of poses, representing where it thinks the robot might be, each of these candidate pose has associated with a probability: higher-probability poses are more likely to be where the robot actually is.
When amcl first starts up, you have to give it the initial pose(position and oriention) of the robot as this is something amcl cannot figure out on its own.
As the robot moves around ,the sensor readings are compared to the readings that would be expected for each of the poses, according to the map:
- consistent with the map, probablity ↗
- inconsistent with the map, probablity ↘
Over time, candidate poses with very low probability go away, while those with high probability stick around.
move_base
在 ROS 的导航中,首先会通过全局路径规划,计算出机器人到目标位置的全局路线,这一功能是 navfn 这个包实现的。
navfn 通过 Dijkstra 最优路径的算法,计算 costmap 上的最小花费路径,作为机器人的全局路线。(将来在算法上应该还会加入 A* 算法)
本地的实时规划是利用 base_local_planner 包实现的,该包使用 Trajectory Rollout 和 Dynamic Window Approaches 算法计算每个周期内应该行驶的速度和角度(dx, dy, dtheta velocities)
base_local_planner 这个包通过地图数据,通过算法搜索到达目标的多条路径,利用一些评价标准(是否会撞到障碍物,所需要的时间等等),选取最优的路径,并且计算所需要的实时速度和角度。
Trajectory Rollout 和 Dynamic Window Approaches 算法的主要思路如下:
(1) 采样机器人当前的状态(dx, dy, dtheta)
(2) 针对每个采样速度,计算机器人以该速度行驶一段时间后的状态,得出一条行驶路线
(3) 利用一些评价标准为多条路线打分
(4) 根据打分,选择最优路线
(5) 重复上面的过程
move_base 有一下几个重要的配置文件:
- costmap_common_params.yaml(通用代价地图参数):
We define our laser to be an observation source, as a result, data published on the scan topic will be used to update the costmaps, both inserting obstacles(marking) and asserting free space(clearing).
footprint; observation_source - global_common_params.yaml(全局规划代价地图参数):
Tell the global costmap to use a static map (to be provided by the map server) and that it should do its reasoning in the map frame, while it should consider the canonical(基底) frame of the robot to be base_link.
global_frame; robot_base_frame; static_map - local_common_params.yaml(局部规划代价地图参数):
Tell the local costmap to use a small rolling window: the robot always remains at the center of the window, with obstacle data outside the window being discarded, and potentially reobserved later, as the robot moves.
costmap_2d
- Provides an implementation of a 2D costmap that takes in sensor data from the world, builds a 2D or 3D occupancy grid od the data and inflates costs in a 2D costmap based on the occupancy grid and a user specificed radius.
- Also provides support for map_server based intialization of a costmap, rolling window based costmaps, and parameter based subscription and configuration of sensor topics.
在 ROS 的导航中,costmap_2d 这个包主要负责根据传感器的信息建立和更新二维或三维的地图。ROS 的地图(costmap) 采用网格(grid)的形式,每个网格的值从 0~255 分为三种状态: 占有(有障碍物),无用(空闲的),未知。因此有五种状态:
(1) Lethal(致命的):机器人中心与该网格的中心重合,此时机器人必然与障碍物冲突
(2) Possibly circumscribed(外切):网格的外切圆与机器人的轮廓外切,此时机器人相当于靠在障碍物附近,所以不一定冲突
(3) Inscribed(内切):网格外切圆与机器人的轮廓内切,此时的机器人必然与障碍物冲突
(4) Free space(自由空间):没有障碍物的空间
(5) Unknown:未知的空间