导航常用的数据类型
std_msgs/Header
标准消息头
uint32 seq #序号 time stamp #时间戳 string frame_id #该数据所在的坐标系
geometry_msgs/Point
空间三维坐标
float64 x float64 y float64 z
geometry_msgs/Quaternion
表示旋转的四元数
float64 x float64 y float64 z float64 w
geometry_msgs/Pose
表示位姿
geometry_msgs/Point position geometry_msgs/Quaternion orientation
geometry_msgs/PoseWithCovariance
存在不确定性的位姿
geometry_msgs/Pose pose float64[36] covariance
其中协方差数组是以行优先顺序的6x6协方差矩阵。该协方差矩阵以固定轴x,y,z得到的。
geometry_msgs/Vector3
表示三维空间中的向量
float64 x float64 y float64 z
geometry_msgs/Twist
表示速度,包括线速度和角速度
geometry_msgs/Vector3 linear geometry_msgs/Vector3 angular
geometry_msgs/TwistWithCovariance
表示带有不确定性的速度
geometry_msgs/Twist twist float64[36] covariance
其中协方差数组是以行优先顺序的6x6协方差矩阵。该协方差矩阵以固定轴x,y,z得到的。
nav_msgs/Odometry
表示估计的位置和速度
std_msgs/Header header #时间戳和坐标系 string child_frame_id #子坐标系 geometry_msgs/PoseWithCovariance pose #相对与header.frame_id坐标系中的位置 geometry_msgs/TwistWithCovariance twist #相对于child_frame_id坐标系的速度
常用/odom作为frame_id,而/base_link作为child_frame_id。
导航常用坐标系
/odom_frame,里程计的参考的坐标系。
/base_frame,里程计测量的参考系。
/map_frame,世界坐标系,刚开始和/odom_frame重合,但随着里程计的误差逐渐累积,两个坐标系存在误差。
重点:里程计测量的是/base_frame相对于/odom_frame的变换值。定位系统(比如SLAM)估计的是机器人在/map_frame下的位姿信息,提供/base、/odom、/map之间的坐标变换。
常用主题
/cmd_vel (geometry_msgs/Twist)
常用于控制机器人底座的运动,其中linear.x指向机器人前方,linear.y指向左方,linear.z垂直向上满足右手坐标系。angular.z表示机器人沿着z轴的角速度。
AMCL功能包
AMCL(adaptive Monte Carlo Localization)自适应蒙特卡洛定位,是机器人在二维移动过程中概率定位系统,采用粒子滤波器来跟踪地图中机器人位姿。
AMCL的通信
AMCL的参数
move_base功能包
文档:http://wiki.ros.org/move_base/
节点:move_base
move_base是ROS中用于路径规划并控制机器人底座进行导航的功能包。它内部包含了全局规划器和局部规划器,同时支持符合nav_core::BaseGlobalPlanner接口的自定义全局规划器和符合nav_core::BaseLocalPlanner接口的自定义局部规划器。move_base内部维护两个代价地图,分别用于全局规划和局部规划。move_base的框架如下:
上图的中间是move_base,外围的节点需要为move_base提供各种信息。
全局规划器:根据给定目标位置和全局地图进行总体路径规划,可以使用Dijkstra或A*算法进行全局路径规划,计算机器人到目标位置的最优路线。
局部规划器:实际情况中,机器人无法严格按照全局路线行驶,所以需要针对地图信息和动态障碍物规划每个周期内的行驶路线,使之尽量符合全局最优路径。常用Dynamic Window Approaches算法搜索躲避和行进的多条路径,综合各评价标准(是否会撞击障碍物、所需要的时间等)选择最优路径,并计算行驶周期内的线速度和角速度。
全局代价地图:用于全局路径规划。
局部代价地图:用于局部路径规划。
内部组件
costmap_2d costmap_2d包
nav_core nav_core::BaseGlobalPlanner和nav_core::BaseLocalPlanner接口
base_local_planner 基座局部路径规划器
navfn 全局路径规划器
clear_costmap_recovery 用于清除costmap的修复操作
rotate_recovery 旋转修复操作
代价地图的配置
1.两种代价地图的通用配置
obstacle_range: 2.5 #设置机器人检测障碍物的最大范围,这里2.5表示2.5m范围内检测到的障碍信息才会在地图中进行更新。 raytrace_range: 3.0 #设置机器人检测自由空间的最大范围,若设置为3.0,则表示在3m的范围内,机器人根据传感器的信息清除范围内的自由空间。 robot_radius: 0.165 #机器人的半径 inflation_radius: 0.1 #机器人应该与障碍物保持的最小安全距离 max_obstacle_height: 0.6 #障碍物的最大高度 min_obstacle_height: 0.0 #障碍物的最小高度 observation_sources: scan #代价地图需要关注的传感器信息 scan: {data_type: LaserScan, topic: /scan, marking: true, clearing: true, expected_update_rate: 0} #列出传感器信息,marking和clearing表示是否需要使用传感器实时信息来添加或清除代价地图中的障碍物信息。
2.全局代价地图配置
global_costmap: global_frame: /map #设置全局代价地图在哪个参考系下运行 robot_base_frame: /base_footprint #设置代价地图可以参考的机器人本体的坐标系 update_frequency: 1.0 #全局地图信息更新的频率 publish_frequency: 0 static_map: true #决定代价地图是否需要根据map_server提供的地图信息进行初始化,若不使用已有地图或map_server,则设置该参数为false rolling_window: false resolution: 0.01 transform_tolerance: 1.0 map_type: costmap
3.局部代价地图配置
local_costmap: global_frame: /odom #设置局部代价地图在哪个参考系下运行 robot_base_frame: /base_footprint #机器人本体的坐标系 update_frequency: 3.0 #代价地图信息更新频率 publish_frequency: 1.0 #代价地图发布可视化信息的频率 static_map: false #与全局代价地图相同 rolling_window: true #设置机器人移动过程中是否需要滚动窗口,以保持机器人处于中心位置 width: 6.0 #代价地图的长 m height: 6.0 #宽 m resolution: 0.01 #分辨率 m/cell transform_tolerance: 1.0 map_type: costmap
局部规划器的配置
因为局部规划器需要直接控制机器人底座运行,故需要配置较多的参数:
controller_frequency: 3.0 #控制信息发布频率 recovery_behavior_enabled: false clearing_rotation_allowed: false #使用Trajectory Rollout算法。 TrajectoryPlannerROS: max_vel_x: 0.3 min_vel_x: 0.05 max_vel_y: 0.0 # zero for a differential drive robot min_vel_y: 0.0 min_in_place_vel_theta: 0.5 escape_vel: -0.1 acc_lim_x: 2.5 acc_lim_y: 0.0 # zero for a differential drive robot acc_lim_theta: 3.2 holonomic_robot: false yaw_goal_tolerance: 0.1 # about 6 degrees xy_goal_tolerance: 0.1 # 10 cm latch_xy_goal_tolerance: false pdist_scale: 0.9 gdist_scale: 0.6 meter_scoring: true heading_lookahead: 0.325 heading_scoring: false heading_scoring_timestep: 0.8 occdist_scale: 0.1 oscillation_reset_dist: 0.05 publish_cost_grid_pc: false prune_plan: true sim_time: 1.0 sim_granularity: 0.025 angular_sim_granularity: 0.025 vx_samples: 8 vy_samples: 0 # zero for a differential drive robot vtheta_samples: 20 dwa: true simple_attractor: false
move_base中的通信
move_base中的参数
fake_localization功能包
文档:http://wiki.ros.org/fake_localization
源代码:https://github.com/ros-planning/navigation/tree/melodic-devel/fake_localization
节点:fake_localization
该功能包可以代替move_base所需的定位系统,兼容ACML的输出格式,常用于仿真环境中,因此使用该方式定位所需的计算资源较少。具体地说,fake_localization将里程计数据转换为定位位姿信息,其格式与ACML相同。
( 1 ) Subscribed Topics
base_pose_ground_truth ([nav_msgs/Odometry][1]) 仿真器发布的机器人位置信息。
initialpose ([geometry_msgs/PoseWithCovarianceStamped][2]) 允许使用像rviz或nav_view这样的工具来设置fake_localization的自定义位姿。(Allows for setting the pose of fake_localization using tools like rviz or nav_view to give a custom offset from the ground truth source being published.)
( 2 ) Published Topics
amcl_pose ([geometry_msgs/PoseWithCovarianceStamped][3]) 通过仿真器报告的位姿。
particlecloud ([geometry_msgs/PoseArray][4]) 在rviz和nav_view中使用,来可视化机器人位姿的粒子云。
( 3 ) Parameters
~odom_frame_id (string, default: "odom") 里程计坐标系名字。
~delta_x (double, default: 0.0) 地图坐标系与仿真器坐标系原点在x轴方向的偏移。
~delta_y (double, default: 0.0) 地图坐标系与仿真器坐标系原点在y轴方向的偏移。
~delta_yaw (double, default: 0.0) 地图坐标系与仿真器坐标系原点在yaw偏航角的偏移。
~global_frame_id (string, default: /map) 指定使用tf发布global_frame_id→odom_frame_id转换的坐标系。
~base_frame_id (string, default: base_link)机器人基座坐标系。 New in 1.1.3
( 4 ) Provided tf Transforms
/map → <value of odom_frame_id parameter> 发布/map坐标系到/odom坐标系的变换,从而可以查询到/map到机器人本体的坐标变换。
Gazebo激光导航仿真
这里采用古月居大佬《ROS机器人开发实践》中的实例。
仿真环境的代码:https://github.com/huchunxu/ros_exploring/tree/master/robot_mrobot/mrobot_gazebo ;
导航的代码:https://github.com/huchunxu/ros_exploring/tree/master/robot_mrobot/mrobot_navigation
启动仿真环境:roslaunch mrobot_gazebo mrobot_laser_nav_gazebo.launch
启动导航程序:roslaunch mrobot_navigation fake_nav_demo.launch
启动完成后,在rviz界面设置目标点,仿真环境中的机器人即可移动到该目标位置。使用rqt_graph命令来分析一下各节点的通信情况:
首先要搞清楚各节点的功能。
/move_base :核心节点,进行路径规划,包括全局路径规划和局部路径规划,其中局部路径规划直接输出速度控制消息。
/map_server:地图服务器,解析地图文件,并发布OccupancyGrid消息。
/map_odom_broadcaster:tf广播器,发布/map坐标系到/odom坐标系的静态坐标变换。
/fake_localization:虚拟定位,直接查询里程计的输出,以里程计的定位信息作为定位系统的定位信息,发布/map到机器人本体的坐标变换。
/gazebo:仿真环境,这里主要指仿真环境中的机器人。
/robot_state_publisher:查询机器人各关节的状态(角度等),转换为tf消息,即该节点发布仿真机器人各关节的坐标变换。
/joint_state_publisher:根据urdf,发布机器人的关节状态信息。
查看一些此时的tf树:
再结合move_base的结构图:
可知,对于move_base:
上面的move_base_simple/goal来自rviz,可以通过rviz的界面设置导航目标。
左边的/tf来自fake_localization,该节点通过/gazabo得到/odom到/base_footprint的坐标变换,从/robot_state_publisher得到base_footprint到baselink的变换关系,从/map_odom_broadcaster得到map到odom的变换关系。最终发送给move_base的是baselink相对于map的位姿。
左边的odom来自/gazebo,该里程计记录的是baselink相对于odom的测量。
右边的map来自map_server。
右边的sensor topics来自/gazebo,为sensor_msgs/LaseScan。
下面的cmd_vel发送给/gazebo,用于控制机器人的运行。
参考文献
[0]胡春旭.ROS机器人开发实践.