当前位置: 首页 > article >正文

gmapping算法源码实现分析(一)

gmapping算法源码实现分析一—— slam-gmapping功能包主干流程分析1.slam_gmapping.cpp初始化流程:SlamGmapping() 构造函数 ├─ init() - 创建 GridSlamProcessor 实例读取参数 └─ startLiveSlam() - 设置订阅和回调 ├─ 创建 LaserScan 订阅 (通过 MessageFilter) ├─ 注册 laserCallback 回调 └─ 启动 publishLoop 线程 (定期发布 map-odom 变换)激光雷达数据处理流程:laserCallback(scan) ├─ 节流控制 (throttle_scans_) ├─ 首次扫描: initMapper(scan) │ ├─ 计算激光坐标系姿态 │ ├─ 创建 RangeSensor 和 OdometrySensor │ ├─ 设置 GMapping 参数 │ └─ 调用 gsp_-init() 初始化粒子滤波器 │ └─ addScan(scan, odom_pose) ├─ 获取里程计姿态 getOdomPose() ├─ 准备激光数据 (处理角度反转) ├─ 创建 RangeReading └─ 调用 gsp_-processScan(reading) ← 核心算法入口 如果 processScan 成功: ├─ 获取最佳粒子的位姿 ├─ 计算 map_to_odom_ 变换 ├─ 更新地图 updateMap(scan) (按时间间隔) └─ 发布地图和元数据2.核心算法层 - openslam_gmapping功能包(gridslamprocessor.cpp)processScan 的实际执行流程:boolGridSlamProcessor::processScan(constRangeReadingreading,intadaptParticles){// 步骤1: 获取相对位姿并初始化OrientedPoint relPosereading.getPose();if(!m_count){m_lastPartPosem_odoPoserelPose;// 第一次扫描初始化}// 步骤2: 运动模型更新 - 为每个粒子绘制新位姿for(ParticleVector::iterator itm_particles.begin();it!m_particles.end();it){OrientedPointpose(it-pose);// 根据运动模型从上一帧位姿采样新位姿posem_motionModel.drawFromMotion(it-pose,relPose,m_odoPose);}// 步骤3: 累积位移并检查是否达到更新阈值OrientedPoint moverelPose-m_odoPose;m_linearDistancesqrt(move*move);m_angularDistancefabs(move.theta);m_odoPoserelPose;boolprocessedfalse;// 步骤4: 判断是否需要处理 (距离/角度/时间阈值)if(!m_count||m_linearDistancem_linearThresholdDistance||m_angularDistancem_angularThresholdDistance||(period_0.0(reading.getTime()-last_update_time_)period_)){last_update_time_reading.getTime();double*plainReadingnewdouble[m_beams];// 复制激光数据到数组RangeReading*reading_copynewRangeReading(...);if(m_count0){// 步骤5a: 非首帧 - 执行 scan matching 重采样scanMatch(plainReading);// ← 对每个粒子进行扫描匹配优化onScanmatchUpdate();updateTreeWeights(false);// 更新轨迹树权重resample(plainReading,adaptParticles,reading_copy);// ← 重采样}else{// 步骤5b: 首帧 - 仅注册扫描到地图for(ParticleVector::iterator itm_particles.begin();it!m_particles.end();it){m_matcher.invalidateActiveArea();m_matcher.computeActiveArea(it-map,it-pose,plainReading);m_matcher.registerScan(it-map,it-pose,plainReading);// 创建轨迹树节点TNode*nodenewTNode(it-pose,0.,it-node,0);node-readingreading_copy;it-nodenode;}}updateTreeWeights(false);delete[]plainReading;// 步骤6: 重置状态供下一帧使用m_lastPartPosem_odoPose;m_linearDistance0;m_angularDistance0;m_count;processedtrue;// 更新粒子的 previousPosefor(ParticleVector::iterator itm_particles.begin();it!m_particles.end();it){it-previousPoseit-pose;}}m_readingCount;returnprocessed;}3.地图更新流程 - updateMap (slam_gmapping.cpp)voidSlamGmapping::updateMap(constsensor_msgs::msg::LaserScan::ConstSharedPtr scan){// 创建临时的 ScanMatcherMapScanMatcherMapsmap(center,xmin_,ymin_,xmax_,ymax_,delta_);// 遍历最佳粒子的轨迹树重建地图for(TNode*nbest.node;n;nn-parent){matcher.invalidateActiveArea();matcher.computeActiveArea(smap,n-pose,((*n-reading)[0]));matcher.registerScan(smap,n-pose,((*n-reading)[0]));}// 调整 ROS 地图消息大小if(map size changed){重新分配 map_.data}// 将栅格概率转换为 OccupancyGrid 格式for(x,y){doubleoccsmap.cell(p);if(occ0)→-1(未知)elseif(occocc_thresh_)→100(障碍)else→0(空闲)}// 发布地图sst_-publish(map_);sstm_-publish(map_.info);}4.坐标变换发布 - publishTransformvoidSlamGmapping::publishTransform(){// 定期发布 map - odom 的静态变换// map_to_odom_ 在 laserCallback 中计算:// map_to_odom_ (odom_to_laser * laser_to_map).inverse()transform.transformtf2::toMsg(map_to_odom_);tfB_-sendTransform(transform);}总结主要流程是:ROS2 Wrapper 层: 接收 LaserScan → 转换格式 → 调用底层算法GridSlamProcessor 层:运动模型预测粒子位姿扫描匹配优化位姿粒子重采样维护轨迹树地图生成层: 从最佳粒子轨迹重建 OccupancyGrid 并发布

相关文章:

gmapping算法源码实现分析(一)

gmapping算法源码实现分析(一) —— slam-gmapping功能包主干流程分析 1. slam_gmapping.cpp 初始化流程: SlamGmapping() 构造函数├─> init() - 创建 GridSlamProcessor 实例,读取参数└─> startLiveSlam() - 设置订阅和回调├─&g…...

2026年降AI工具会不会被知网检测到深度解读:使用降AI工具算学术不端吗免费完整分析

2026年降AI工具会不会被知网检测到深度解读:使用降AI工具算学术不端吗免费完整分析 关于降AI工具被知网检测到解读,我整理了几个核心问题,逐一分析。 实战方案先给出来:应对AIGC检测最有效的是专业工具深层文本重构,…...

2026年降AI后语义失真攻略:过度改写论点跑偏4.8元修复语义同时达标完整方案

2026年降AI后语义失真攻略:过度改写论点跑偏4.8元修复语义同时达标完整方案 从AI率71%到5.9%,我用了一个晚上。降AI后语义失真修复完整经历。 核心工具:嘎嘎降AI(www.aigcleaner.com),4.8元,达…...

伽马暴宇宙学分析中流量阈值选择的敏感性研究

1. 研究背景与核心问题在伽马射线暴(GRB)的宇宙学研究领域,一个长期困扰我们的核心问题是:我们看到的GRB样本,究竟在多大程度上反映了它们在宇宙中的真实分布?这听起来像是个哲学问题,但在实际操…...

别再只用SSH了!给CentOS 7.9服务器装上图形桌面,用VNC远程操作真香

解锁CentOS 7.9图形化运维:VNC远程桌面实战指南在Linux服务器管理的日常工作中,纯命令行操作虽然高效,但遇到复杂的文件管理、图形化工具调试或团队协作时,图形界面往往能事半功倍。本文将带您从零开始,为CentOS 7.9服…...

Windows 11热键冲突别抓狂!用OpenArk一键揪出‘元凶’并释放你的Ctrl+C

Windows 11热键冲突终极排查指南:用OpenArk精准定位并解决问题每次按下CtrlC却毫无反应,或者发现AltTab突然失效时,那种挫败感简直让人抓狂。作为每天要与数十个软件打交道的设计师,我深刻理解热键冲突对工作效率的致命影响。本文…...

基于变分自编码器的类星体光谱无监督分析:QUEST工具原理与实践

1. 项目概述与核心价值如果你也和我一样,长期和斯隆数字巡天(SDSS)这类大型巡天项目产生的海量光谱数据打交道,那你一定理解那种感受:面对动辄数十万条光谱,传统的基于模板匹配或人工特征提取的分析方法&am…...

用Linux内核模块复现AMDGPU的dma-fence:一个可运行的Ring Buffer同步模型Demo

从零构建Linux内核模块:AMDGPU风格dma-fence环形缓冲区同步模型实战在Linux内核开发领域,GPU驱动开发一直被认为是技术门槛较高的方向之一。AMDGPU作为现代显卡的开源驱动,其内部实现涉及复杂的同步机制,其中dma-fence作为核心同步…...

CentOS7 搭建 Kubernetes 集群

CentOS7 搭建 Kubernetes 集群完整指南 基于提供的文档,本文提供kubeadm快速搭建(推荐新手)和二进制手动搭建(生产可控)两种方案,所有步骤均适配CentOS7系统。 一、通用前置准备(两种方式都需执…...

ARMv9 SME指令集:FDOT浮点点积操作深度解析

1. SME指令集与浮点点积操作概述在当代处理器架构设计中,向量化计算能力已成为衡量芯片性能的关键指标。作为ARMv9架构的重要扩展,SME(Scalable Matrix Extension)指令集专门针对矩阵运算进行了深度优化,其中多向量浮点…...

3D激光SLAM入门:点云曲率计算与LOAM边缘/平面特征提取(附代码)

专栏系列:3D激光SLAM从零到精通 | 难度:中级 | 预计阅读:25分钟 前置知识:Python编程,numpy基础,3D点云的基本概念 摘要 本文深入讲解3D激光SLAM中最基础也是最关键的一环——点云特征提取。我们将从LOAM论…...

AlphaEvolve:LLM与进化算法融合的自动代码优化系统

1. 项目概述:AlphaEvolve系统架构与核心思想AlphaEvolve代表了当前算法自动优化领域最前沿的技术突破。这个由Google DeepMind团队开发的系统,创造性地将大语言模型(LLM)的代码生成能力与进化算法的迭代优化机制相结合,形成了一个自主进化的编…...

图自编码器在金融风控中的拓扑模式检测实践

1. 项目概述:当图机器学习遇上金融风控在金融科技领域摸爬滚打了十几年,我见过太多风控系统从“规则为王”到“数据驱动”的变迁。早期的反洗钱(AML)和反欺诈系统,本质上是一套复杂的“如果-那么”规则库:如…...

为什么你的ChatGPT公众号打开率不足8%?腾讯内部流出的3类高唤醒标题公式(限时公开)

更多请点击: https://intelliparadigm.com 第一章:ChatGPT公众号打开率低迷的底层归因诊断 公众号打开率持续低于行业均值(5.2% vs 行业中位数12.7%),表面是内容吸引力不足,实则暴露了用户触达链路中多个结…...

ChatGPT绘画提示词生成效率革命(92%设计师不知道的5层语义嵌套法)

更多请点击: https://kaifayun.com 第一章:ChatGPT绘画提示词生成效率革命(92%设计师不知道的5层语义嵌套法) 传统提示词工程常陷于“关键词堆砌”误区,而真正高阶的生成控制源于语义结构的纵深组织。5层语义嵌套法将…...

Windows屏幕录制全栈实现:Graphics Capture+FFmpeg零拷贝编码

1. 这不是“调个API就完事”的录制功能,而是要亲手把屏幕变成可编程的视频流管道很多人看到“FFmpeg屏幕录制”第一反应是:网上一搜,几十个C#封装库,NuGet install一下,几行代码start()就完事。我去年也这么想——直到…...

互联网大厂Java面试实录:严肃面试官 vs 求职程序员的三轮技术问答

第一轮:Java基础与核心知识考察面试官(严肃): - 请简述Java内存模型中堆和栈的区别? - 你能解释一下JUC包中ReentrantLock的基本用法吗? - 多线程中synchronized和Lock的区别有哪些?程序员(稍显…...

全波形反演新思路:大步长梯度优化器如何克服周波跳跃难题

1. 项目概述:当梯度优化器“大步快跑”时,它能跳出周波跳跃的陷阱吗?在地球物理勘探领域,全波形反演(FWI)被誉为速度建模的“圣杯”,它通过迭代匹配模拟地震数据与观测数据,来反推地…...

Product Hunt 每日热榜 | 2026-05-23

1. TestSprite 3.0 标语:让一群并行的智能代理在几分钟内测试你的应用程序。 介绍:TestSprite 能够独立生成并运行你应用程序的端到端测试。对于后端,我们现在可以生成复杂的集成测试,支持动态变量、自动清理和数据流调试。对于…...

ZS315Q Type-C转DP1.4带PD100w方案,边投屏边充电,告别接口焦虑

作为轻薄本、游戏本用户,外接DP显示器时你是不是也遇到过这样的痛点:想投屏到大屏工作娱乐,Type-C接口被视频线占了,充电口就得另占一个,本来接口就没几个,鼠标U盘全都排不上队;更烦人的是就算不…...

HTTPS静态资源403/404根因排查:从Nginx配置到SELinux权限

1. 这不是SSL证书的问题,而是HTTP服务配置的“隐身故障”你刚在云服务商控制台花了几十块钱买了张正规CA签发的SSL证书,上传到Nginx或Apache,配好了443端口,https://yourdomain.com打开首页也绿锁高亮,一切看起来都对—…...

Scalify:基于e-graph的分布式机器学习计算图等价性验证工具

1. 项目概述在分布式机器学习的世界里,我们常常面临一个看似简单实则棘手的问题:我写的这个并行化代码,真的和单机版本在数学上等价吗?这个问题背后,是无数个深夜调试的工程师,是那些在数百个GPU上跑了一周…...

共有云环境redis的热key怎么处理

共有云Redis热key处理方案共有云Redis常见形态:集群分片、读写分离实例,业务跑在ECS、ACK容器上,具备弹性扩容、自带监控诊断、一键启停能力。一、云上专属:快速定位热key不用自己写脚本抓取,直接用平台工具排查1、控制…...

时序数据库 + 微服务:MyEMS 如何支撑千万级测点的能源管理平台

在工业能源数字化的实践中,一个常被低估的命题是:当一家大型制造集团拥有数十个厂区、每个厂区部署数千台智能表计和传感器,全集团同时在线的测点数量突破千万级别时,能源管理系统应当具备怎样的技术底色?这不是一个关…...

别急着买云服务器!手把手教你用闲置Win10电脑搭建个人SSH服务器(保姆级教程)

闲置Win10变身SSH服务器:零成本打造远程开发环境家里那台吃灰的旧电脑,其实藏着个免费云服务器——这话听起来像天方夜谭?去年我用一台2015年的联想笔记本搭建的SSH服务器,至今稳定运行着三个Python爬虫和两个测试项目。下面这套方…...

山东大学软件学院项目实训-基于语言大模型的智能居家养老健康守护系统-个人博客(五)

智能健康陪诊与个性化干预 Agent 的设计与实现 前言 在基于语言大模型的智能居家养老系统中,我主要负责面向老人端的两个核心 AI Agent 的构建:健康陪诊 Agent 与 健康干预 Agent。前者作为首页全科问答入口提供 24 小时健康咨询服务,后者深度…...

手把手教你解锁影驰B360M主板隐藏的fTPM 2.0,绕过限制升级Win11(附BIOS修改避坑指南)

解锁影驰B360M主板fTPM 2.0的完整实战手册当Windows 11的升级提示弹出时,许多使用影驰B360M主板的用户发现自己的设备被系统要求拒之门外——原因很简单:主板BIOS中缺少必要的fTPM 2.0支持选项。这并非硬件不支持,而是厂商在固件层面隐藏了相…...

量子计算硬件指纹识别:从噪声特性到设备认证

1. 量子计算中的硬件指纹识别:从错误校正到设备认证量子计算机的噪声特性一直被视为阻碍其可靠运行的主要障碍。但有趣的是,这些看似有害的噪声特征,实际上可能成为每台量子设备的"身份证"。就像人类的指纹具有唯一性一样&#xff…...

量子核方法在工业音频异常检测中的实践与性能突破

1. 项目概述:当量子计算遇见工厂“听诊器” 在工厂车间里,设备运转的轰鸣声对经验丰富的老师傅而言,就像一首熟悉的交响乐。哪个齿轮的啮合声变“涩”了,哪台电机的运转声带上了不该有的“颤音”,他们往往能第一时间察…...

[Python] Python中自带模块级的单例模式-不需要定义单例类

Python中的单例场景 一般一些需要在模块中全局维护的变量(变量修改范围在模块内);简单方式是构建一个全局变量,然后不符合编码规范:1.线程安全与并发问题;2.测试隔离困难;3.缺乏多实例/多租户支…...