AMCL代码详解(三)创建粒子模型
AMCL中创建粒子模型的方式有两种:
1.高斯分布模型
第一种方式的模型主要使用了高斯模型去建立了一系列粒子点:
// // 使用高斯模型(均值,协方差)初始化滤波器
void pf_init(pf_t *pf, pf_vector_t mean, pf_matrix_t cov)
{int i;//创建粒子sample集set,粒子sample对象,概率密度函数pdf//pf_sample_set_t中包含了位姿权重,kd树,簇等多个因素pf_sample_set_t *set;//pf_sample_t包含了位姿以及权重两个因素pf_sample_t *sample;pf_pdf_gaussian_t *pdf;//初始化粒子sample集setset = pf->sets + pf->current_set;// Create the kd tree for adaptive sampling//创建kdtree为了选择性采样pf_kdtree_clear(set->kdtree);//粒子sample集set的sample数目设定set->sample_count = pf->max_samples;//使用高斯模型(均值,协方差)创建pdf//这里设置了一个高斯模型pdf = pf_pdf_gaussian_alloc(mean, cov);// Compute the new sample poses//计算新的粒子sample对象的位姿//使用for循环遍历粒子sample集set的每个sample对象for (i = 0; i < set->sample_count; i++){sample = set->samples + i;//对粒子sample的权重进行初始化sample->weight = 1.0 / pf->max_samples;//对粒子sample的位姿使用pdf模型产生//这里用到了一个位姿,方差以及随机数,产生了一个以初始值为中心的随机坐标点sample->pose = pf_pdf_gaussian_sample(pdf);// Add sample to histogram//以kdtree数据结构的方式添加/存储粒子sample 或者说以kdtree数据结构的方式表达直方图pf_kdtree_insert(set->kdtree, sample->pose, sample->weight);}//对 w_{slow} , w_{fast} 进行设置pf->w_slow = pf->w_fast = 0.0;//销毁释放pdf占用的内存pf_pdf_gaussian_free(pdf);// Re-compute cluster statistics//再次计算粒子sample集set的簇cluster的统计特性,输入为粒子滤波器pf,和set pf_cluster_stats(pf, set); //set converged to 0//粒子sample集set收敛到0pf_init_converged(pf);return;
}
前面主要是建立了几个结构体,具体信息可以在.h文件中查看这些结构体的定义。在创建完结构体之后,首先使用:
pf_kdtree_clear(set->kdtree);
清空了一个kd树。详细代码在pf_kdtree.cc中,将set结构体中的树清空,为后面插入位姿做准备。
然后算法通过:
pdf = pf_pdf_gaussian_alloc(mean, cov);
调用pf_pdf.c中的代码创建了一个高斯模型:
// Create a gaussian pdf
//这里相当于建立了一个高斯概率密度模型
//包含了均值,方差以及还有一个方差特征值分解得到的特征值以及特征向量
pf_pdf_gaussian_t *pf_pdf_gaussian_alloc(pf_vector_t x, pf_matrix_t cx)
{//double m[3][3]矩阵pf_matrix_t cd;//pf_vector_t x; //double v[3];//pf_matrix_t cx; //double m[3][3];//pf_matrix_t cxi;//double m[3][3];//double cxdet;// Decomposed covariance matrix (rotation * diagonal)//pf_matrix_t cr;//pf_vector_t cd;pf_pdf_gaussian_t *pdf;//在内存的动态存储区中分配num个长度为size的连续空间,函数返回一个指向分配起始地址的指针;如果分配不成功,返回NULL。//void* calloc(unsigned int num,unsigned int size);pdf = calloc(1, sizeof(pf_pdf_gaussian_t));//对结构体中的前两项赋值。pdf->x = x;pdf->cx = cx;//pdf->cxi = pf_matrix_inverse(cx, &pdf->cxdet);// Decompose the convariance matrix into a rotation// matrix and a diagonal matrix.// cx为输入,对其进行特征值分解,特征值存入cd中,特征向量存入cr中pf_matrix_unitary(&pdf->cr, &cd, pdf->cx);pdf->cd.v[0] = sqrt(cd.m[0][0]);pdf->cd.v[1] = sqrt(cd.m[1][1]);pdf->cd.v[2] = sqrt(cd.m[2][2]);// Initialize the random number generator//pdf->rng = gsl_rng_alloc(gsl_rng_taus);//gsl_rng_set(pdf->rng, ++pf_pdf_seed);//rand48用于产生0-1之间的均匀分布的随机数srand48(++pf_pdf_seed);return pdf;
}
然后通过下面的for循环更新出一系列位姿
// Compute the new sample poses//计算新的粒子sample对象的位姿//使用for循环遍历粒子sample集set的每个sample对象for (i = 0; i < set->sample_count; i++){sample = set->samples + i;//对粒子sample的权重进行初始化sample->weight = 1.0 / pf->max_samples;//对粒子sample的位姿使用pdf模型产生//这里用到了一个位姿,方差以及随机数,产生了一个以初始值为中心的随机坐标点sample->pose = pf_pdf_gaussian_sample(pdf);// Add sample to histogram//以kdtree数据结构的方式添加/存储粒子sample 或者说以kdtree数据结构的方式表达直方图pf_kdtree_insert(set->kdtree, sample->pose, sample->weight);}
在这里sample_count为粒子的数量,初始时每个粒子的权重是一样的。然后在pf_pdf_gaussian_sample函数中使用初始位姿、方差以及一个随机数综合产生一个符合高斯分布的随机位姿。作为第i个粒子的位姿。
接着将该位姿插入到kd树中。kd树作为AMCL的核心数据结构,担负的重要职能便是能自如地插入新的位姿
// Add sample to histogram//以kdtree数据结构的方式添加/存储粒子sample 或者说以kdtree数据结构的方式表达直方图pf_kdtree_insert(set->kdtree, sample->pose, sample->weight);
这里:
pf->w_slow = pf->w_fast = 0.0;
与参数alpha_slow和alpha_fast相关,这些字段用于触发recover机制,增加随机位姿, 用以削弱粒子滤波器的粒子匮乏问题的影响。这里初始化时设置为0
这个:
//销毁释放pdf占用的内存pf_pdf_gaussian_free(pdf);
基本不用看,就是释放了一下内存。
后面两个:
// Re-compute cluster statistics//再次计算粒子sample集set的簇cluster的统计特性,输入为粒子滤波器pf,和set pf_cluster_stats(pf, set);
为一个粒子sample集重新计算其簇的均值/协方差进而得出粒子集合的均值/协方差。粒子sample->粒子簇cluster->粒子集set的统计特性:均值和协方差 粒子的分数在pf_kdtree.c中
一个粒子集中有很多个簇,簇中包含了这个簇中粒子的数量、权重、均值方差等信息。这里的簇似乎跟kd树是对应的,差不多有多少个kd树就有多少个簇。不知道理解的对不对。
另外就是这个计算出来的簇的统计特性是干嘛用的?这里暂时还不是很清楚。需要再往下看一看。
2.其他模型
这里的过程与上面的高斯模型基本一致,主要区别再于这里:
sample->pose = (*init_fn) (init_data);
其生成的位姿根据传参的两个参数变化,而高斯分布中传入的是均值与方差,从而生成随机数。
AMCL代码详解(三)创建粒子模型相关推荐
- AMCL代码详解(五)根据激光观测更新粒子权重
上一篇中讲述了里程计在amcl中的作用,算法根据里程计反馈对每个粒子的位姿进行更新.在粒子更新后,则需要根据激光的观测数据对粒子的权重进行更新,这里主要看一下激光电云在amcl中的作用: 1.激光回调 ...
- AMCL代码详解(七)amcl中的kd-Tree
1.kd-Tree基础 kd树(k-dimensional树的简称),是一种分割k维数据空间的数据结构,主要应用于多维空间关键数据的近邻查找(Nearest Neighbor)和近似最近邻查找(App ...
- AMCL代码详解(六)amcl中的重采样
1.重采样判断 上一章讲述了amcl中如何根据激光观测更新粒子权重,当粒子更新完后amcl会需要根据程序判断是否需要进行重采样.这个判断在粒子观测更新权重后进行判断,代码在amcl_node.cpp中 ...
- Pytorch|YOWO原理及代码详解(二)
Pytorch|YOWO原理及代码详解(二) 本博客上接,Pytorch|YOWO原理及代码详解(一),阅前可看. 1.正式训练 if opt.evaluate:logging('evaluating ...
- VINS技术路线与代码详解
VINS技术路线 写在前面:本文整和自己的思路,希望对学习VINS或者VIO的同学有所帮助,如果你觉得文章写的对你的理解有一点帮助,可以推荐给周围的小伙伴们,当然,如果你有任何问题想要交流,欢迎随时探 ...
- Transformer代码详解: attention-is-all-you-need-pytorch
Transformer代码详解: attention-is-all-you-need-pytorch 前言 Transformer代码详解-pytorch版 Transformer模型结构 各模块结构 ...
- 【初篇】DHT11连接STM32、One wire单总线原理、GPIO代码详解
目录 一.DHT11单总线原理 二.代码详解 三.代码 代码见文章末尾 一.DHT11单总线原理 DHT11温湿度传感器只需要一根线即可和MCU进行数据交换,无数据传输时,单线应为高电平状态,具体流程 ...
- Keras YOLOv3代码详解(三):目标检测的流程图和源代码+中文注释
Keras YOLOv3源代码下载地址:https://github.com/qqwweee/keras-yolo3 YOLOv3论文地址:https://pjreddie.com/media/fil ...
- Meta最新模型LLaMA细节与代码详解
Meta最新模型LLaMA细节与代码详解 0. 简介 1. 项目环境依赖 2. 模型细节 2.1 RMS Pre-Norm 2.2 SwiGLU激活函数 2.3 RoPE旋转位置编码 3. 代码解读 ...
最新文章
- Jmeter性能测试 入门
- VDI序曲二 RemotoAPP晋级篇
- html轮廓位置,html – 具有边框/轮廓的六边形
- CSS3中word-break和word-wrap有什么区别?
- JVM插桩之二:Java agent基础原理
- Fiori应用的书签模式 - bookmark
- Task On The Board CodeForces - 1367D(思维)
- Kubernetes 架构与设计
- 【转】Symstore 详细使用
- 【天梯选拔月赛】参与者人数(并查集模版题!remember find_father写法!)
- “完数”(C代码+流程图)
- 简单的Map集合练习题
- php swfobject,swfobject参数详细介绍
- 改进YOLOv5!GSConv+Slim Neck进一步提升YOLOv5性能!
- aac +sbr +ps
- 跨境卖家:如何让海外KOL营销达到理想效果?
- Apache Ambari介绍
- SpringBoot2.x 监听器详解
- Python实现替换照片人物背景,精细到头发丝(附上代码) | 机器学习
- 区分bug 前后端归属之后,我再也不背锅了
热门文章
- 计算机中带符号数的,大学计算机基础1.4_计算机中带符号数的表示方法.ppt
- 计算机体系结构基础最近的知识点
- 财务凭证校验(Validation) [GGB0/OB28]
- 自制Jlink_OB(STM32c8t6)
- 2018年4月工业用微型计算机,2018年自考《工业用微型计算机》预测试题及答案
- 【mba市场营销论文】MP公司人工关节植入物的市场营销分析(节选)
- 安卓 文本框怎么贴近边缘_手机来电闪光,边缘闪光,炫酷超任性
- dpi重启后会恢复_Win8等设备DPI设置过大后的还原办法
- 在新版Vue中引入外部字体
- 大数据语义分析:灵玖中文分词的分词处理