建图算法:
要求: 高更新频率、小测量噪声的激光扫描仪,不需要里程计,可手持建图。
在hector_slam程序中,最重要的是hector_mapping节点:
(1)订阅的主题:
scan(类型:sensor_msgs/LaserScan):激光雷达的扫描数据,通常由设备的运行的节点提供,例如:hokuyo node
syscommand(类型:std_msgs/String) : 系统命令,直接受“reset”,当接受该命令时,重设map frame 和robot 位置到初始的状态。
(2)发布的主题:
map_metadata(类型:nav_msgs/MapMetaData):发布地图Meta数据,其余节点可以获取到map元数据,锁定并且定期更新。
map(类型:nav_msgs/OccupancyGrid):发布地图栅格数据,其余节点可以获取到map数据,锁定并且定期更新。
slam_out_pose(类型:geometry_msgs/PoseStamped):无协方差的预估机器人姿态。
poseupdate(类型:geometry_msgs/PoseWithCovarianceStamped):使用高斯预估不确定性的预估机器人姿态。
(3)服务:
dynamic_map(类型:nav_msgs/GetMap):使用该服务,获取地图数据。
(4)需要的tf
->base_fram激光雷达坐标系与基坐标系之间的变换,通常是固定值,由robot_state_publisher或者a tf static_transform_publisher发布。
(5)提供的tf
map->odom :在map坐标系中预估的robot姿态,当pub_map_odom_transform为true时发布。
目前激光2Dslam用得最广的方法,gmapping采用的是RBPF的方法,优点是定位准确,但需要完整的硬件平台。
更能实现的需求:
基于激光雷达
RB粒子滤波算法
二位栅格地图
机器人里程计信息
OpenSlam算法
输出地图话题:nav_msgs/OccupancyGrid
主要节点:slam_gmapping
该slam_gmapping节点发生在sensor_msgs /激光扫描信息,并建立一个映射(nav_msgs / OccupancyGrid)。可以通过ROS 主题或服务检索地图。
(1)订阅主题
tf(tf / tfMessage) :需要进行激光,基准和测距的相关框架转换,即激光雷达坐标系与基坐标系之间的变换。
scan (sensor_msgs / LaserScan):激光扫描从中创建地图。
(2)发布主题
map_metadata(nav_msgs / MapMetaData):从此主题获取地图数据,将其锁定并定期更新。
map(nav_msgs / OccupancyGrid):从此主题获取地图数据,将其锁定并定期更新
〜entropy (std_msgs / Float64):机器人姿态分布的熵的估计值(较高的值表示较大的不确定性)。
(3)服务
dynamic_map(nav_msgs / GetMap):调用此服务以获取地图数据。
(4) 必需的tf转换
<传入激光数据的框架> → base_link :通常是固定值,由robot_state_publisher或tf static_transform_publisher定期广播。
base_link → odom:通常由里程表系统(例如,移动基座的驱动器)提供,
(5) 提供tf转换
地图 → odom :在地图框架内的机器人姿势的当前估计。
karto_slam是基于图优化的方法,用高度优化和非迭代cholesky矩阵进行稀疏系统解耦作为解。图优化方法利用图的均值表示地图,每个节点表示机器人轨迹的一个位置点和传感器测量数据集,箭头的指向的连接表示连续机器人位置点的运动,每个新节点加入,地图就会依据空间中的节点箭头的约束进行计算更新。
karto_slam的ROS版本,其中采用的稀疏点调整(the Spare Pose Adjustment(SPA))与扫描匹配和闭环检测相关。landmark越多,内存需求越大,然而图优化方式相比其他方法在大环境下制图优势更大.在某些情况下karto_slam更有效,因为他仅包含点的图(robot pose),求得位置后再求map。
core_slam是为了更加简单容易地理解性能损失最小化的一种slam算法。将算法简化为距离计算与地图更新的两个过程, 第一步,每次扫描输入,用基于简单的粒子滤波算法来计算距离,粒子滤波的匹配器用于激光与地图的匹配,每个滤波器粒子代表机器人可能的位置和相应的概率权重,这些都依赖之前的迭代计算。选择好最好的假设分布,即低权重粒子消失,新粒子生成。在更新步骤,扫描得到的线加入地图中,当障碍出现时,围绕障碍点绘制调整点集,而非仅一个孤立点。
整个移动机器人的控制系统如上图所示。
具体的各功能模块之间的任务结构如下图所示,其中base_controller节点将订阅的cmd_vel信息通过串口或其它通信接口发送给下位机(嵌入式控制板)。下位机中根据机器人运动学公式进行解算,将机器人速度转换为每个轮子的速度,然后通过CAN总线(或其它总线接口)将每个轮子的转速发送给电机驱动板控制电机转动。电机驱动板对电机转速进行闭环控制(PID控制),并统计单位时间内接收到的编码器脉冲数,计算出轮子转速。
base_controller节点将接收到的cmd_vel速度信息转换为自定义的结构体或union类型的数据(自定义的数据类型中可以包含校验码等其它信息),并通过串口发送控制速度信息(speed_buf)或读取机器人传回的速度信息 (speed_buf_rev)。base_controller节点正确读取到底层(比如嵌入式控制板)传回的速度后进行积分,计算出机器人的估计位置和姿态,并将里程计信息和tf变换发布出去。
里程计又包含2方面的信息:
一是位姿(位置和角度),即(x, y,θ)
二是速度,即(前进速度v和转向速度ω)
里程计信息的数据获取的途径是:
首先laser_scan_matcher 这个包,这个包能根据/scan 数据发布2D位姿的数据, 我们是否可以根据2D位姿数据来转换成表示位置的下x,y, z 以及表示姿态的四元数。
速度的获取:根据2D位姿和时间变量,来计算前进速度和转向速度。2D位姿数据包含:float64 x, float64 y, float64 theta,根据dt 时间里dx,dy,dtheta, 就可以算出前进速度,和转向速度。如果2D位姿数据足够精准,基本都用不上陀螺仪校准。