ROS实现最基础的slam,其中主要涉及3个基本包:
move_base包:用于让机器人在制定框架内移动到目标位置;
gmapping包:用于从激光扫描仪、深度摄像机来绘制地图;
amcl包:用于在现有的地图中定位。
ros的运动可以参考下图http://wiki.ros.org/navigation/Tutorials/RobotSetup:
这里写图片描述
move_base包:
作用:制定一个导航目标,提供一个相对特定参考坐标的机器人的目标姿态(位置和方向);move_base包使用MoveBaseActionGoal消息类型来指定目标。其中MoveBaseActionGoal消息类型可以看出目标由标准ROS header、goal_id和goal本身组成。goal里的PoseStamped消息类型依次由header和pose组成,其中pose包括了position和orientation。
节点运行前需要四个配置文件。定义了越过障碍物所需要的代价、机器人半径、移动速度以及路径规划时要考虑路长等等。
分别是:base_local_planner_params.yaml、costmap_common_params.yaml、global_costmap_params.yaml、local_costmap_params.yaml其路径一般在config中。
base_local_planner_params.yaml中的参数如下:
controller_frequency: 3.0 每3秒一次重新规划路径;注:更新规划的频率,建议3~5
min_vel_x: 0.05机器人的最小线速度;
max_vel_y,min_vel_y:只有x方向的一个线速度。而像麦克纳姆轮多个轮,可以有y方向的线速度;
max_rotation_vel: 1.0最大旋转速度;注:这个值不要设置太高。默认1.0rad/s;
min_vel_theta:最小角速度,单位rad/s。默认-1.0rad/s;
min_in_place_vel_theta: 原地旋转角速度的最小值,单位rad/s,默认0.5rad/s;
escape_vel: 机器人逃时速度。必须为负数,这样才能反向移动,这个速度是反转;
acc_lim_x: 2.5 x方向的最大线速度的加速度,单位m/s2。默认2.5m/s2;
acc_lim_y:同上,只是y方向的加速度。故对于两轮差速驱动,该值为0;
acc_lim_theta:角速度加速度限值,单位rad/s2。默认为3.2rad/s2;
holonomic_robot:是否全方向机器人。是的话true,不是后面跟false。对于两轮差速,该值为false;
yaw_goal_tolerance:允许机器人缩到目标的方向(弧度)偏差,该值设置小可能导致机器人接近目标振荡。默认为0.1;
xy_goal_tolerance:允许机器人所到目标的坐标(以米为单位)偏差,该值过小可能导致机器人在目标位置附近不断调整到精确的目标位置。默认为0.1;
latch_xy_goal_tolerance:目标坐标偏差锁存,如果上锁,机器人到达过坐标后只进行简单的方向调整,即使在公差外。默认为false;
pdist_scale:(path distance)地图单元格的路径距离系数,默认为0.6。决定有多接近路径;
gdist_scale:(goal distance)地图单元格两点距离的系数,默认为0.6。决定有多接近局部目标;
occdist_scale:沿障碍物轨迹最大距离系数;
heading_lookahead:原地旋转时向前看多少米,默认0.35;
heading_scoring: 通过机器人航向计算还是通过路径计算距离,默认false ; heading_scoring_timestep: 航向计算距离时,沿着模拟轨迹向前看的时间,默认0.8;
occdist_scale:控制器应该避开障碍物的的轻易程度,默认0.1;
oscillation_reset_dist: 在振荡标志被清零前,机器人必须在出行多远。默认0.05;
publish_cost_grid_pc:是否使用cost_grid发布。如果为true,在/ cost_cloud话题生成;sensor_msgs/ PointCloud2;
prune_plan: 设置为true,机器人行走1m后,结束动作;
sim_time: 模拟轨迹的时间,默认1.0s;
sim_granularity: 给定轨迹的步长,默认0.025米;
angular_sim_granularity: 给定角度轨迹的弧长,默认0.025弧度;
vx_samples: x方向速度的样本数,默认为8;
vy_samples: y方向速度的样本数,两轮差速为0;
vtheta_samples: 角速度的样本数,默认为20;
dwa:是否使用动态窗口方法(DWA),或者是否使用轨迹。默认为true。
costmap_common_params.yaml中的参数如下:
robot_radius: 0.165:对于圆形机器人这个时机器人的半径,单位时米。对于非圆形机器人来说,你可以用到接下来说到的footprint参数;
footprint:[[x0, y0], [x1, y1], [x2, y2], [x3, y3], etc]列表中的每一个坐标代表机器人的边上的一点,机器人的中心设为[0, 0]。单位时米。按照顺时针活着逆时针排列;
inflateon_radius:0.3 --地图上的障碍物的半径,单位为米。如果你的机器人不能很好地通过窄门或其他狭窄的地方,则稍微减少这个值。相反的,如果经常碰撞,则增大这个值。
global_costmap是为了全局路径规划服务的,如从这个房间到那个房间该怎么走。global_costmap_params.yaml中的参数如下:
global_costmap:
global_frame: /map
robot_base_frame: base_link
update_frequency: 5.0
static_map: true
global_costmap和robot_base_frame:定义机器人和地图之间的坐标变换,建立全局代价地图必须使用这个变换;
global_frame:/map 对于全局代价地图,我们用map框架作为global框架;
update_frequency:5.0 根据传感器数据,全局地图更新的瓶绿,单位为赫兹。这个数值越大你的计算机cpu负担就会越重。特别对于全局地图,通常会设定一个相对较小、在1.0到5.0之间的值;
static_map: 是否使用一个地图或者地图服务器来初始化全局代价地图,如果不使用静态地图,这个参数为false。
local_costmap是为局部路径规划服务的,如机器人局部有没有遇到行人之类的障碍。local_costmap_params.yaml中的参数如下:
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:/odom--对于本地代价地图来说,我们使用odometry框架来作为global框架;
robot_base_frame:/base_foot_print--这个通常不是/base_link就是/base_footprint。对于TurtleBot应设为/base_footprint;
publish_frequency:发布信息的频率,也就是costmap可视化信息发布的频率;
rolling_window:在机器人运动过程中,代价地图始终以机器人为中心,这个在源码里是个if函数;
width、height、resolution:代价地图的的尺寸和分辨率,单位都是m.一般情况下resolution的数值与建的static map的一致。
为了运行导航功能包集,还需要创建个启动文件 move_base.launch ,内容:
"move_base" type="move_base" respawn="false" name="move_base" output="screen">
file="$(find mrobot)/config/costmap_common_params.yaml" command="load" ns="global_costmap" />
file="$(find mrobot)/config/costmap_common_params.yaml" command="load" ns="local_costmap" />
file="$(find mrobot)/config/local_costmap_params.yaml" command="load" />
file="$(find mrobot)/config/global_costmap_params.yaml" command="load" />
file="$(find mrobot)/config/base_local_planner_params.yaml" command="load" />