激光SLAM之Gmapping(2)算法分析解读

  Gmapping的程序框架是依托Open_slam,该框架主要分成slam_gmapping和openslam_gmapping。在slam_gmapping可以从Lasercallback出发,作为整个框架的起点,Lasercallback函数在slam_gmapping.cpp文件中。

文章目录

  • 激光SLAM之Gmapping(2)算法分析解读
    • 主要函数及调用关系
      • ①InitMapper函数
      • ②addScan函数
      • ③Processscan函数
      • ④scanMach
      • ⑤Score
      • ⑥Likelihoodandscore
      • ⑦Resample
      • ⑧InitMapper
    • 算法结构
    • 参数解读

主要函数及调用关系

废话不多说,先上函数调用图

①InitMapper函数

  如果是首次调用lasercallback函数,则进入InitMapper。函数在同样的.cpp文件中。激光雷达测得数据数据,是在激光雷达为坐标系的数据。在InitMapper设置一个比激光雷达Z轴上高一个单位的一个点,用这个点来判断激光雷达是否发生了倾斜。接下来就是根据激光雷达的安装位置(正反安放)。初始化并设置一些参数。

②addScan函数

  成功将测量值加入之后,在Lasercallback下面就是两个坐标系的变换。在addscan函数是主要函数的。在该函数了成功获取到里程计位姿后,根据激光雷达的安装方式,对角度进行修改,然后将ROS的激光雷达采集的信息转换成gmapping能看懂的格式,设置和激光数据时间戳匹配的机器人的位姿。调用processscan函数。

③Processscan函数

  processscan函数在gridslamprocessor.cpp中,首先获取当前的位姿,然后在从里程计运动模型获取位姿,这里调用了drawFromMotion函数,这个函数在motionmodel.cpp中,drawFromMotion函数中的sample函数是形参作为方差,均值为0的高斯分布。sample函数是数值分析所近似生成的高斯分布,具体的函数实现在stat.cpp中。当前位姿与上一次位姿做差,计算做累计角度偏差和位移偏差。利用激光雷达测得距离做得分处理。非首帧调用scanMatch,upDateTreeWeight ,resample。首帧则调用invalidActiveArea, computeActiveArea, registerScan.

④scanMach

  该函数在gridslamprocessor.hxx中,对粒子的最优位姿进行计算:optimize,该函数在scanmacher.cpp;计算粒子最优位姿后,重新计算粒子的权重;粒子的权重由粒子的似然表示的,计算出来最优的位姿后,进行了地图的扩充。Optimize首先计算当前位置的得分,调用score函数,score函数在scanmacher.h。当前得分与上一次的得分差,要减少搜索步长,得到周围的方向里面最好的一个位姿和对应的得分。返回最优额位置和得分。计算当前的位姿和初始位姿的区别,区别越大增益越小。增益的计算odo_gain*=exp(-m_angularOdometryReliability*dth),-m_angularOdometryReliability为角度里程计的依赖,就是相信传感器传来的数据程度。dth为角度变化量。线性距离也是这样的。计算当前位姿的角度和初始角度的区别,如果里程计比较可靠的话,那么进行匹配的时候就需要对离初始位姿比较远的位姿施加惩罚得分=增益得分。

⑤Score

  score函数该函数先将激光雷达的坐标转换到世界坐标,先转换到机器人的坐标系,然后转到世界坐标。激光雷达击中到某一点,沿着激光方向的前一个点必是未击中的,得到击中点的栅格和前一个点的栅格。如果搜索出最优最可能被这个激光束击中的点,计算得分并返回该得分。

⑥Likelihoodandscore

  likelihoodandscore与score其类似。回到scanmatch函数,invalidateActiveArea和computeActiveArea,UpdateTreeweight。UpdateTreeweight在gridslamprocessor_tree.cpp。这里主要是更新权重,在这里调用normalize,然后调用resetTree把所有的粒子的所有轨迹清零,最后调用propagateweights。在propgateweight更新归一化的粒子权重。因为每一个粒子的路径都是从叶子节点开始的,得到了叶子节点,就得到了路径,所以叶子节点的子节点累计权重就等于每个粒子的权重。

⑦Resample

  该函数在gridslamprocessor.hxx。首先是备份老的粒子的轨迹,即保留叶子的节点。然后是需要重采样还是不需要重采样,如果不需要重采样,则权值不变。只为轨迹创建一个新的节点,每个粒子更新地图。当有效值小于阈值的时候需要重采样,通过resampleIndexes提取到需要删除的粒子。删除粒子后,保留当前的粒子并在保存的粒子的节点里新增一个节点。删除要删除粒子的节点,保留的粒子进行数据更新,将每个粒子的设置同一个权重。最后更新一下地图。

⑧InitMapper

  该函数是激光雷达测到数据是在激光雷达坐标系下测的,在Init-Mapper设置一个比激光雷达高一米的点用来判断激光雷达是否倾斜,根据激光雷达排放位置对角度进行调整。设置参数和初始化参数。

算法结构

输入:St−1S_{t-1}St−1​前一时刻的粒子集信息
     ZtZ_tZt​最新时刻的观测数据
     UtU_tUt​最新的里程计数据
求解:StS_tSt​当前时刻的粒子集信息
    初始化XVt=XV_t=XVt​=初始化XVtXV_tXVt​
For  所有St−1i∈St−1S^i_{t-1}\in S_{t-1}St−1i​∈St−1​执行
    提取相关位姿信息Xt−1iX^i_{t-1}Xt−1i​,权值信息Wt−1iW^i_{t-1}Wt−1i​,对应地图信息mt−1im^i_{t-1}mt−1i​
//执行扫描匹配
    xvti=xvt−1i⨁utxv^i_t=xv^i_{t-1}\bigoplus u_txvti​=xvt−1i​⨁ut​根据控制信息估计移动机器人位姿信息
    xv^ti=argmaxp(x∣mt−1i,zt,xvti)x\hat{v}^i_t=arg\,max p(x\mid m^i_{t-1},z_t,xv^i_t)xv^ti​=argmaxp(x∣mt−1i​,zt​,xvti​) 通过估计出的位姿,结合当前观测信息与前一时刻的地图进行扫描匹配,求出匹配程度最高的位姿信息。
if   xv^ti=failurethenx\hat{v}^i_t=failure\,thenxv^ti​=failurethen 如果扫描匹配估计失败,则执行
   xvti∼ρ(xvt∣xvt−1i,ut)xv^i_t\,\sim\rho(xv_t\mid xv^i_{t-1},u_t )xvti​∼ρ(xvt​∣xvt−1i​,ut​)根据控制信息分布粒子集
   wti=wt−1i⋅p(zt∣mt−1i,xvti)w^i_t\,=\,w^i_{t-1}\cdot p(z_t\mid m^i_{t-1},xv^i_t)wti​=wt−1i​⋅p(zt​∣mt−1i​,xvti​)然后相应更新粒子权值
else 否则
//在xv^tix\hat{v}^i_txv^ti​附近采样
for  k=1,⋯,Kk=1,\cdots,Kk=1,⋯,K执行
   xvk∼{xvj∣∣xvi−xv^i∣<Δ}xv_k \sim \{xv_j\mid |xv_i-x\hat{v}^i|<\Delta\}xvk​∼{xvj​∣∣xvi​−xv^i∣<Δ}在xvxvxv的估计值附近进行采样,估计位姿
end for    循环终止
//计算高斯分布
   μti=(0,0,0)T\mu^i_t=(0,0,0)^Tμti​=(0,0,0)T初始化位姿均值
   ηi=0\eta^i=0ηi=0初始化权值
for  all  xj∈{x1,…,xk}x_j\in\{x_1,\dots,x_k\}xj​∈{x1​,…,xk​} do对所有粒子执行如下操作
   μti=μti+xj⋅p(zt∣mt−1i,xj)⋅p(xt∣xt−1i,ut)\mu^i _t=\mu^i_t+x_j\cdot p(z_t\mid m^i_{t-1},x_j) \cdot p(x_t\mid x^i_{t-1},u_t)μti​=μti​+xj​⋅p(zt​∣mt−1i​,xj​)⋅p(xt​∣xt−1i​,ut​)计算位姿
   ηti=ηti+p(zt∣mt−1i,xj)⋅p(xt∣xt−1i,ut)\eta^i_t=\eta^i_t+p(z_t\mid m^i_{t-1},x_j)\cdot p(x_t\mid x^i_{t-1},u_t)ηti​=ηti​+p(zt​∣mt−1i​,xj​)⋅p(xt​∣xt−1i​,ut​) 计算权值
end for
  μti=μti/ηti\mu^i_t = {\mu^i_t}/{\eta^i_t}μti​=μti​/ηti​ 求加权
  ∑ti=0\sum_t^i=0∑ti​=0 初始化协方差
for all   xj∈{x1,⋯,xk}x_j \in\{x_1,\cdots,x_k\}xj​∈{x1​,⋯,xk​} 执行
  ∑ti=∑ti+(xvj−μi)(xvj−μi)T⋅p(zt∣mt−1i,xj)⋅p(xt∣xt−1i,ut)\sum_t^i = \sum_t^i +(xv_j-\mu^i)(xv_j-\mu^i)^T \cdot p(z_t\mid m^i_{t-1},x_j)\cdot p(x_t\mid x^i_{t-1},u_t)∑ti​=∑ti​+(xvj​−μi)(xvj​−μi)T⋅p(zt​∣mt−1i​,xj​)⋅p(xt​∣xt−1i​,ut​) 计算协方差
end for
  ∑ti=∑ti/ηti\sum_t^i =\sum_t^i/\eta^i_t∑ti​=∑ti​/ηti​ 求加权平均协方差
//根据所得的均值和协方差采样新的位姿估计
  xvti∼N(μti,∑ti)xv^i_t\sim N(\mu^i_t , \sum_t^i)xvti​∼N(μti​,∑ti​) 根据正态分布采样新位姿
//更新重要性权重
  wti=wt−1i⋅ηtiw^i_t=w^i_{t-1} \cdot \eta^i_twti​=wt−1i​⋅ηti​
end if
//更新地图
  mti=integrateScan(mt−1i,xvti,zt)m^i_t=integrateScan(m^i_{t-1},xv^i_t,z_t)mti​=integrateScan(mt−1i​,xvti​,zt​) 根据新获取的位姿信息,结合之前的地图和最新的观测值更新地图
//更新粒子集
  St=St∪{(xvti,wti,mti)}St=St \cup\{(xv^i_t,w^i_t,m^i_t)\}St=St∪{(xvti​,wti​,mti​)} 更新粒子集的位姿信息,权值信息和地图信息
end for
  Neff=1∑i=1N(w~t)2Neff= \frac{1}{\sum_{i=1} ^N (\widetilde{w}^t)^2}Neff=∑i=1N​(wt)21​ 通过将权值归一化后,求取有效粒子数
if  Neff<TNeff<TNeff<T
then  若有效粒子低于阈值
   St=resampling(St)St=resampling(St)St=resampling(St) 执行重采样
end if

参数解读

参数 意义 类型
tf(tf/tfMessage) 需要进行激光,基准和测距的相关框架转换
scan(sensor_msgs/LaserScan) 激光扫描从中创建地图
map_metadata(nav_msgs/MapMetaData) 从此主题获取地图数据,将其锁定并定期更新
map(nav_msgs/OccupancyGrid) 从此主题获取地图数据,将其锁定并定期更新
entropy(std_msgs/Float64) 机器人姿态分布的熵的估计值(较高的值表示较大的不确定性)
dynamic_map(nav_msgs/GetMap) 调用此服务以获取地图数据
inverted_laser (改为使用变换数据)激光是正面朝上(扫描按CCW排序)还是上下颠倒(扫描按顺序排列)? string,默认“false”
throttle_scans 处理 int,默认:“1”
base_frame 框架连接到移动基座 string,默认:“base_link"
map_frame 框架附加到地图 string,默认:“map”
odom_frame 框架连接到里程计系统 string,默认:“odom”
map_update_interval 在更新地图之间的时间长度(以秒为单位)。降低该数量更频繁地更新占用网格,代价是更大的计算负荷 float,默认值:5.0
maxUrange 激光的最大可用范围。光束被裁剪为该值。 float,默认值:80.0
sigma 贪心终点匹配使用的sigma float,默认值:0.05
kernelSize 内核中要查找一个对应关系 int,default:1
Istep 翻译的优化步骤 float,default:0.05
astep 旋转的优化步骤 float,默认值: 0.05
iteration 扫描匹配器的迭代次数 int, default:5
Isigma 用于计算的波束可能性的sigma float,默认值:0.075
ogain 在评估可能性时使用的增益,用于平滑重采样效果 float,默认值:3.0
Iskip 每次扫描中要跳过的光束数 int,默认值:0
minimumScore 考虑扫描结果的最小分数匹配好。当使用具有有限范围(例如5m)的激光扫描仪时,可以避免在大的开放空间中跳跃姿态估计。分数上升到600+,例如当遇到跳跃估计问题时,尝试50 float,default:0.05
srr 作为平移函数的平移误差(rho/rho) float,默认值:0.1
srt 作为旋转函数的平移误差(rho/theta) float,默认值:0.2
str 作为平移函数的旋转中的测量误差(θ/ rho) float,默认值:0.1
stt 作为旋转函数的旋转中的测量误差(θ/ θ) float,默认值:0.2
linearUpdate 每次机器人翻译远处时,处理一次扫描 float,default:0.5
angularUpdate 每次机器人旋转这么远处理一次扫描 float,default:0.5
temporalUpdate 如果上次扫描处理时间早于更新时间(秒),则处理扫描。小于零的值将关闭基于时间的更新 float,default:-0.1
resampleThreshold 基于Neff的重采样阈值 float,default:0.5
particles 过滤器中的粒子 int,默认值:30
xmin 初始地图大小X最小值 float,默认值:-100.0
ymin 初始地图大小Y最小值 float,默认值:-100.0
xmax 初始地图大小X最大值 float,默认值:100.0
ymax 初始地图大小Y最大值 float,默认值:100.0
delta 地图分辨率 float,默认值:0.05
IIsamplerange 可能性的平移采样范围 float,默认值:0.01
Iisamplestep 可能性的平移采样步骤 float,默认值:0.01
Iasamplerange 角度采样范围的可能性 float,默认值:0.005
Iasamplestep 角度采样步骤的可能性 float,默认值:0.005
transform_publish_period 转换发布之间的时间长度(以秒为单位) float,默认值:0.05
occ_thersh gmapping的占用值得阈值。具有较大占用率的单元被认为是占用的(即,在所得的sensor_msgs/LaserScan中设置为100)。 float,默认值:0.25
maxRange 传感器最大范围。如果传感器范围内没有障碍物的区域在地图中显示为自由空间,则设置maxUrange<实际传感器的最大范围<=maxRang。 float

激光SLAM之Gmapping(2)算法分析解读相关推荐

  1. 3D激光SLAM:LOAM 论文--算法详细解读

    3D激光SLAM:LOAM 论文--算法详细解读 LOAM简介 论文里面的符号表示 算法部分 激光雷达里程计 A 特征点提取 B 找特征点的匹配对 C 运动估计 lidar 建图 测试结果 LOAM是 ...

  2. 从零开始搭二维激光SLAM --- 基于GMapping的栅格地图的构建

    上篇文章讲解了如何在ROS中发布栅格地图,以及如何向栅格地图赋值. 这篇文章来讲讲如何将激光雷达的数据构建成栅格地图. 雷达的数据点所在位置表示为占用,从雷达开始到这点之间的区域表示为空闲. 1 GM ...

  3. 3D激光SLAM:LeGO-LOAM论文解读---激光雷达里程计与建图

    3D激光SLAM:LeGO-LOAM论文解读---激光雷达里程计与建图 激光雷达里程计 针对LOAM的改进 激光雷达建图 原文 激光雷达里程计 激光雷达里程计模块的功能就是:估计相邻帧之间的位姿变换. ...

  4. 2D激光SLAM::AMCL发布的odom----map坐标TF变换解读

    摘自:https://blog.csdn.net/dieju8330/article/details/96770964 2D激光SLAM::AMCL发布的odom----map坐标TF变换解读 die ...

  5. 【激光SLAM】 01 cartographer环境建立以及建图测试(详细级)

    [激光SLAM]cartographer环境建立以及建图测试(详细级) cartographer Launch the 2D backpack demo. Download the 3D backpa ...

  6. 激光SLAM入门学习笔记

    激光SLAM入门学习笔记 激光SLAM入门学习笔记 一.推荐阅读书籍 二.推荐公众号.知乎.博客 1.公众号 2.知乎 3.博客 三.推荐阅读论文&代码(参考泡泡机器人) 2D激光SLAM 3 ...

  7. 激光slam与视觉slam

    文章目录 介绍 前端差异 后端优化 回环检测 视觉/激光优劣势对比 开源算法 视觉slam开源算法 激光slam开源算法 其他开源代码地址参考 知识点 激光雷达的参数定义 深度摄像头会不会取代雷达 结 ...

  8. 激光SLAM深度剖析

    激光SLAM深度剖析系列文章索引 本系列文章,是对激光SLAM的深度解读,一作为学习用,二作为分享用. 详细的解释.直观的图表.丰富的注释.简化的测试代码. 作者:公众号:小白学移动机器人 之前写过的 ...

  9. 室内+室外激光SLAM关键算法、代码和实战剖析正式开课(cartographer+LOAM+ LIO-SAM)

    应用背景介绍 高精地图作为自动驾驶的眼睛,在自动驾驶研发中占据极大的份额,而激光SLAM则是高精地图定位导航算法的关键技术,其重要性不言而喻,在AI产品如矿卡.汽车.清扫车和扫地机器人等领域都占据一席 ...

最新文章

  1. 1个多月就能看到效果的减肥大法 - 生活至上,美容至尚!
  2. linux suse 时区设置,suse设置时间服务器
  3. 解决SQL注入与XSS攻击
  4. [云炬创业管理笔记]第三章测试4
  5. python抓取中文网页乱码
  6. union 和 union all
  7. gradle 编译java_Java的Gradle依赖关系,使用编译还是实现?
  8. php删除文见,php如何删除文件夹
  9. CouchDB未授权访问漏洞记录(端口:5984、6984,CVE-2017-12635,CVE-2017-12636)复现失败
  10. 骑士资本高频交易系统事故案例分析
  11. mdf转sql mysql_如何将SQL数据库.MDF格式的导入到mysql数据库里面啊
  12. python对excel数据分析常用功能(一文学会如何用Python实现excel基础功能)
  13. idea maven 显示wating for maven import completionomitted for duplicate jar
  14. 山寨电子以改良式研发谋求蜕变
  15. leetcode1083. 销售分析 II(SQL必会呀)
  16. oracle数据迁移到mysql
  17. 一键修改计算机名和用户名,电脑用户名怎么改_电脑用户名(计算机名)修改方法_牛游戏网...
  18. python helper函数_使函数定义以python文件顺序独立
  19. kubernetes系列之五:IPVS概览
  20. win11开机不能进系统桌面怎么解决

热门文章

  1. 关于 二维码 与 NFC 之间的出身贫贱说
  2. 第七章 企业与政府信息资源管理
  3. 酷狗计算机科技有限公司待遇,酷狗怎么样
  4. 物联网设备已成大型DDoS攻击马前卒
  5. A-Level多少分才能上英国TOP10?
  6. C语言 n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,计算最后留下的是最初第几号人
  7. 微信小游戏分享给好友或朋友圈
  8. 操作系统 | PV操作练习题汇总(一)
  9. 计算机打不开找不到应用程序,win10系统打不开压缩包提示“找不到应用程序的方法...
  10. Axure RP 9 原型设计【交互】功能的使用,让你的原型变成高仿真的有灵魂的演示文档。