首页 > Gmapping 乱七八糟

Gmapping 乱七八糟

笔记和总结:

void SlamGMapping::startLiveSlam()主要是订阅话题,主要有
scan_filter_-> registerCallback(boost::bind(&SlamGMapping::laserCallback,this, _1);
这句话就是要对激光雷达的数据进行处理的回调函数
接下来我们查看此回调函数
SlamGMapping::laserCallback(const sensor_msgs::LaserScan
::ConstPtr& scan)
//这个函数首先是调用initMapper(*scan)初始化函数,
//一些重要参数的初始化,将slam里的参数传递到 openslam 里 ,
//设定坐标系,坐标原点,以及采样函数随机种子的初始化,等等主
//要的调用有gsp_->setMatchingParameters(maxUrange_, maxRange_, sigma_, kernelSize_, lstep_, astep_, iterations_,lsigma_, ogain_, lskip_);   //激光雷达数据匹配的参数gsp_->setUpdateDistances(linearUpdate_, angularUpdate_, resampleThreshold_);  //设置更新距离的参数gsp_->setUpdatePeriod(temporalUpdate_); //设置更新的时间gsp_->GridSlamProcessor::init(particles_, xmin_, ymin_, //xmax_, ymax_, delta_, initialPose); //初始化粒子的大小gsp_->setllsamplestep(llsamplestep_);    //设置激光雷达的步长
还有很多就不再意义举例这个函数*要转到pf的核心代码了将调用processScan 返回的值是一个bool判断是否更新成功现在进入函数addScan(*scan, odom_pose)看看用到了哪些函数,
此函数的输入是激光雷达的数据和里程计的信息,很明显这里面就要
用到了里程计模型,以及传说中的粒子滤波,通过粒子滤波更新机器
人的位姿。所以这一个函数是gmapping的核心代码。
读取位姿和激光数据,返回下面的函数,处理数据
return gsp_->processScan(reading);   //处理激光数据也
//就是代码的核心都在这里  此函数在gridslamprocessor.cpp文
//件中,结束,回到laserCallback,还有最优一步updateMap1.  进入processScan(reading)就是要对运动模型采样的函数,
获取由运动采样获得的采样位 
pose=m_motionModel.drawFromMotion(it->pose, relPose, m_odoPose); //第一个参数是输出,第二个参数是当前位姿,
m_odoPose是上一时刻的位姿
//现在我们就进入drawFromMotion 函数中查看实现代码
//具体的实现理论与代码的分析可查看之前的博客  
//虽然写的不是很清楚  但是我已经尽力了更新位姿就是要计算机器人累计的平移和旋转
// accumulate the robot translation and rotation
OrientedPoint move=relPose-m_odoPose;
move.theta=atan2(sin(move.theta), cos(move.theta));
m_linearDistance+=sqrt(move*move);
m_angularDistance+=fabs(move.theta);
//在从运动模型采样后  也就是预测了粒子的位姿之后,
//接下来就是要根据测量数据对当前的粒子的位姿进行更新。2.  接下来就有另外一个重要函数
scanMatch(plainReading);//这个函数主要是根据测量
//数据与之前的地图比较更新粒子的位姿 以获得最优粒子位姿在这个函数中需要计算每个粒子的得分,如果得分低者将会被丢
弃或者权重下降,也就是为了寻找最优粒子。在程序中的顺序是scanMatch()此函数的具体是:GridSlamProcessor::scanMatch()//实现过程是在此函
//数的具体是:GridSlamProcessor.hxx文件中接下来就是在这里scanMatch()函数中的函数 第一个重要的函数:  
(1)从每一次的激光数据中获取新的位姿。计算最优粒子的修正后
的位姿并返回其得分 
score=m_matcher.optimize(corrected, it->map, it->pose, plainReading); //这里的corrected就是根据测量过得的修
正后的粒子位姿,那么在optimize 调用了 score 这个函数计算
粒子得分,具体理论的
//知识的研究详情查看《概率机器人》书中关于测量模型的解释在score 函数里,首先计算障碍物的坐标phit,然后将phit转换成网格坐标iPhit
计算光束上与障碍物相邻的非障碍物网格坐标pfree,pfree由phit沿激光束方向移动一个网格的距离得到,将pfree转换成网格坐标ipfree(增量,并不是实际值)
在iphit 及其附近8个(m_kernelSize:default=1)栅格(pr,对应自由栅格为pf)搜索最优可能是障碍物的栅格。
最优准则: pr 大于某一阈值,pf小于该阈值,且pr栅格的phit的平均坐标与phit的距离bestMu最小。得分计算:s +=exp(-1.0/m_gaussianSigma*bestMu*besMu) //距离越大,分数越小,分数的较大值集中在距离最小值处,符合正态分布模型
至此 score 函数结束并返回粒子(currentPose)得分,然后回到optimize函数所以optimize()的作用就是使用运动模型采样到的当前时刻的位姿 currentPose 进行微调,也就是传说中粒子滤波中的更新步骤。获得的位姿一定很接近正确位姿,所以该函数只是在之前粒子位姿的基础上对其进行前、后、左、右、左转、右转 共6次,然后选取得分最高的位姿,返回最终的得分
得到每个粒子的分数之后就是要判断粒子的得分是否满足要求,接下来是(2)现在我们返回到scanMatch()函数中在optimize函数 之后就是要根据当前粒子计算粒子的权重:并处理匹配失败的情况m_matcher.likelihoodAndScore(s, l, it->map, it->pose, plainReading);(3)在scanmatcher()函数中第三个重要的函数是根据粒子的权重,更新地图m_matcher.computeActiveArea(it->map, it->pose, plainReading); //用于计算每个粒子相应的位姿所扫描到的区域 ,   //计算过程首先考虑了每个粒子的扫描范围会不会超过子地图的大小,如果会,则resize地图的大小
//然后定义了一个activeArea 用于设置可活动区域,调用了gridLine() 函数,这个函数如何实现的,我不了解了
每次处理完一次的测量数据,之后还要进行权重更新。
updateTreeWeights(false);//权重更新
粒子集对目标分布的近似越差 权重的方差越大,在重采样的过程中还调用了registerScan ,这个函数和computeActive 函数有点像,不同的是,registerScan用于注册每个单元格的状态,自由、障碍,调用update()以及entroy()函数更新,最后是障碍物的概率 p=n/visits,障碍物的坐标用平均值来算完了后,又有一次权重计算。之后就是要重采样
到此处processScan 结束,回到laserCallback,还有最优一步updateMap
返回到laserCallback()函数之后就是要执行以下函数updateMap(*scan);   //地图更新,先得到最优的粒子(用权重和 weightSum判断 ),得到机器人最优轨迹 

更多相关:

  • 草色新雨中, 松声晚窗里。之前我们学习 Power Query 都是用鼠标就完成了很多复杂的操作。虽然 PowerQuery 已经将大部分常用功能内置成到功能区。基本能完成我们大部分的报表自动化功能。但是总有些复杂的或者个性化的问题是开发团队没有预先想到的,这时我们就需要学习 M 语言。一、M 语言在哪里?M语言的函数公式有三个地...

  • 前言从2020年3月份开始,计划写一系列文档--《小白从零开始学编程》,记录自己从0开始学习的一些东西。第一个系列:python,计划从安装、环境搭建、基本语法、到利用Django和Flask两个当前最热的web框架完成一个小的项目第二个系列:可能会选择Go语言,也可能会选择Vue.js。具体情况待定,拭目以待吧。。。基本概念表达式表...

  • 1.1函数1.1.1什么是函数函数就是程序实现模块化的基本单元,一般实现某一功能的集合。函数名:就相当于是程序代码集合的名称参数:就是函数运算时需要参与运算的值被称作为参数函数体:程序的某个功能,进行一系列的逻辑运算return 返回值:函数的返回值能表示函数的运行结果或运行状态。1.1.2函数的作用函数是组织好的,可重复使用的,用来...

  • 原标题:基于Python建立深度神经网络!你学会了嘛?图1 神经网络构造的例子(符号说明:上标[l]表示与第l层;上标(i)表示第i个例子;下标i表示矢量第i项)单层神经网络图2 单层神经网络示例神经元模型是先计算一个线性函数(z=Wx+b),接着再计算一个激活函数。一般来说,神经元模型的输出值是a=g(Wx+b),其中g是激活函数(...

  • 在学习MySQL的时候你会发现,它有非常多的函数,在学习的时候没有侧重。小编刚开始学习的时候也会有这个感觉。不过,经过一段时间的学习之后,小编发现尽管函数有很多,但是常用的却只有那几个。今天小编就把常用的函数汇总一下,为大家能够能好的学习MySQL中的函数。MySQL常使用的函数大概有四类。时间函数、数学函数、字符函数、控制函数。让我...

  • 今天我们来看看粒子特效, 何为粒子特效, 为了模拟燃烧的火焰, 天空飘下来的血环, 滴落的小雨, 这些无规律变化的物体, 我们引进了粒子特效这个名词, 粒子特效的原理是将无数的单个粒子组合使其呈现出固定形态,借由控制器,脚本来控制其总体或单个的运动,模拟出现真实的效果, 有朋友会问, 为什么我们不使用序列帧动画呢, 由于序列帧动画是...