☰
ROS Gmapping建图实战:从原理到调参避坑指南
2026/10/5 8:06:13 网站建设 项目流程

1. 先搞清楚Gmapping到底是干嘛的

做移动机器人这行,入门导航避不开的第一个坎就是建图。所谓建图,用大白话说就是让机器人拿着激光雷达在房间里走一圈,把周围的环境轮廓记下来,生成一张能让导航算法看懂的地图。Gmapping就是目前ROS生态里最常用、最成熟、也最容易上手的2D激光SLAM建图方案。

你搜资料的时候会看到“Gmapping建图”这个词被频繁提起,它本质上是由Gmapping算法包发布的开源SLAM方案,通过融合激光雷达数据和机器人里程计信息,在ROS框架下实时输出2D栅格地图。这些年出现过不少新方案,比如基于图优化的Cartographer、基于LIO思想的fast-lio、点云配准类的loam系列,但Gmapping依然在很多教学实验和实际工程项目里占据一席之地,原因就一个——它足够稳,足够简单,够用。

这篇东西就围绕“实验三:Gmapping建图”这个完整流程展开,从原理到实际操作,从launch文件怎么写到底层参数怎么调,再到我踩过的坑和排查思路。适合刚接触ROS和SLAM的初学者照着做,也适合已经跑通过一两次但总觉得建图效果不理想的人查漏补缺。

2. 方案选型:为什么选Gmapping而不是别的新算法

2.1 Gmapping的核心定位

先摆结论:Gmapping是做2D激光雷达室内建图的最佳入门方案,没有之一。

它的算法思想可以追溯到2007年Grisetti等人提出的Rao-Blackwellized粒子滤波SLAM框架,后来被集成进ROS的slam_gmapping功能包。每次接收到一帧激光数据,它都会根据当前机器人位姿和地图匹配度去更新一组粒子,每个粒子都代表机器人轨迹和环境地图的一种假设,最后选权重最高的那一组作为当前输出。

这个过程看着复杂,但用户层面感知到的就是:你给我激光和里程计,我还你一张不断更新的2D地图。Gmapping的定位非常聚焦,它只处理2D平面的SLAM问题,对应室内轮式机器人、扫地机器人、服务机器人这些典型运动场景。

2.2 对比新方案:fast-lio、Cartographer、loam这些要不要学

现在网络上关于fastlio2建图、mid360使用fast-lio建图的讨论越来越多,很多初学者一上来就被“3D激光+惯性导航+紧耦合”这些概念吸引,转头就嫌弃Gmapping老掉牙。我的看法是:方案没有绝对新旧,只有合不合适。

做一个快速对比:

方案输入传感器输出地图计算开销上手难度适合场景
Gmapping2D激光+里程计2D栅格地图低,普通笔记本可跑低,launch文件一拉就启动室内平地、结构化环境
Cartographer2D/3D激光+IMU+里程计2D/3D地图中高,需要后端优化中,配置项多复杂环境,大场景回环修正
fast-lio系列3D激光+IMU3D点云地图中,依赖算力中高,代码和配置都有门槛无人机、手持设备,快速运动场景
loam类3D激光,部分用IMU3D点云地图中高室外大场景、自动驾驶

如果你的实验平台是差速轮式机器人、单线激光雷达,环境是普通教室或办公室走廊,无脑上Gmapping就对了。它对算力几乎没要求,数据频率30赫兹以下都扛得住,而且地图更新流畅,处理不了的点还能靠调参补回来。反过来,如果你拿着的是Livox mid360这种固态激光雷达,打算做无人机建图,那Gmapping确实帮不了你,因为它的接口根本不接收3D点云加IMU融合数据。

所以,我的建议是先老老实实跑通Gmapping,把ROS的TF树、坐标系变换、地图消息格式这些基础概念弄明白,再去碰fast-lio这些进阶玩法。地基不牢,上来就跑fastlio2,最后大概率是编译过、跑起来了,但是完全不知道算法在干什么。

2.3 Gmapping方案的三个硬伤和应对方式

Gmapping不是完美的,了解它的短板才能知道什么时候该换方案。

第一个硬伤是不支持回环检测。所谓回环,就是机器人绕了一圈回到之前经过的位置时,算法能认出“我来过这里”并把地图重新拉正。Gmapping的粒子滤波框架天然不支持大规模回环修正,一旦建图过程中位姿漂移积累过多,地图就会错位。这也是它在大场景和长走廊环境下效果变差的直接原因。

第二个硬伤是计算量会随着粒子数增加而指数上涨。粒子数越多,对位置估计的覆盖越全面,但每一步运算量也越大。如果机器人的里程计质量很差,你需要调高粒子数来补偿,实时的压力马上显现。

第三个硬伤是它对运动速度敏感。转向过猛、直行速度太快,都会导致相邻两帧激光数据重叠太少,匹配失效,轻则地图畸变,重则算法直接“跑飞”。

理解这些短板很重要,它决定了你后面建图时该怎么控制机器人的运动方式——这也是很多人忽略的实操要点。

3. 正式开跑前的环境准备

3.1 硬件平台的选配逻辑

跑Gmapping实验,硬件方面其实不需要多豪华。一台CPU在i5以上、内存8G以上的笔记本,一个单线激光雷达(常见的有思岚A1/A2、镭神N10、极光等型号),加上一个能输出稳定里程计底盘的机器人就足够了。如果手头没有完整的机器人底盘,用带轮子的开发板方案、甚至手动推动激光雷达拿着走一圈都可以完成建图测试——不过这样就没有里程计输入,Gmapping的建图效果会明显变差,所以最好是轮式底盘配上轮式里程计。

关于激光雷达的型号选择,实验层面影响不大,但有一个关键参数必须知道——雷达数据的话题名和坐标系名。比如思岚A1发布的话题通常是/scan,坐标系为laser或base_laser_link,这要在后续launch文件里和TF树对应上。

3.2 软件环境:Ubuntu与ROS版本匹配

Gmapping在ROS Noetic和Melodic下都能跑,我的建议是直接上Ubuntu 20.04加ROS Noetic,资料最多、兼容性最好、出问题百度也能搜到答案。

安装时执行:

sudo apt install ros-noetic-gmapping

如果你的ROS版本是Melodic,就把noetic换成melodic,或者直接用源码编译:

cd ~/catkin_ws/src git clone https://github.com/ros-perception/slam_gmapping.git cd ~/catkin_ws && catkin_make

我特别建议大家不要把时间浪费在折腾系统环境上,能apt就apt,千万别为了“练手”去手动编译一堆依赖。这世上没有比ROS依赖冲突更浪费时间的事情了。

3.3 数据来源的三个选择

做这个实验,数据来源有三种方式。第一种是最理想的,真实机器人搭载激光雷达实跑,效果最接近工程实践;第二种是用离线bag包回放,适合在家里反复练习建图流程;第三种是用Gazebo仿真环境虚拟一个机器人,适合没有硬件条件的同学。

我个人强烈推荐初学者先用第二种,也就是录好一段bag包或下载现成的开源的bag,先把Gmapping跑通,看懂地图是怎么生成的,再上真机。为什么?因为用真机调试时,最容易崩的不是Gmapping本身,而是底盘驱动、雷达驱动和通信问题——这些东西会干扰你对SLAM算法本身的理解。

4. Gmapping建图核心实操全流程

4.1 整体流程拆解

从输入到输出,一个完整的Gmapping建图流程包含五个环节。

  1. 启动激光雷达驱动,让/scan话题有数据
  2. 启动底盘驱动和里程计,让/odom话题有数据,同时完整发布TF变换
  3. 启动gmapping节点,订阅/scan和TF树,发布地图相关话题
  4. 运行键盘控制节点或手柄控制,让机器人运动覆盖整个环境
  5. 建图完成后调用map_saver功能包保存地图

这里最容易被忽略的是TF树的完整性。Gmapping本身不关心你的机器人长什么样,它只关心三个坐标系:map(地图坐标系)、odom(里程计坐标系)、base_link或base_footprint(机器人基座坐标系)。激光雷达数据帧laser坐标系要通过静态变换挂到base_link下面,odom到base_link的变换由底盘驱动根据编码器数据实时发布。

一旦TF树断链,你会看到屏幕上疯狂刷TF错误,地图一动不动。我第一次跑的时候就是没配好雷达坐标系的静态变换,折腾了很久才反应过来。

4.2 launch文件的写法与逐行解读

直接给一个可以抄的launch文件,假设激光雷达话题是/scan,雷达坐标系是laser,机器人的odom到base_footprint的变换由底盘驱动(比如robot_base_node)发布。

<launch> <!-- 1. 启动激光雷达驱动,根据具体雷达型号调整 --> <node name="rplidar_node" pkg="rplidar_ros" type="rplidarNode" output="screen"> <param name="serial_port" value="/dev/ttyUSB0"/> <param name="frame_id" value="laser"/> <param name="angle_compensate" value="true"/> <param name="scan_mode" value="Standard"/> </node> <!-- 2. 发布激光雷达到机器人基座的静态坐标变换 --> <node pkg="tf2_ros" type="static_transform_publisher" name="base_to_laser"> <param name="frame_id" value="base_footprint"/> <param name="child_frame_id" value="laser"/> <!-- x y yaw pitch roll,按实际安装位置改 --> <param name="translation" value="0.1 0 0.2"/> <param name="rotation" value="0 0 0"/> </node> <!-- 3. 启动Gmapping核心节点 --> <node pkg="gmapping" type="slam_gmapping" name="slam_gmapping" output="screen"> <param name="base_frame" value="base_footprint"/> <param name="odom_frame" value="odom"/> <param name="map_frame" value="map"/> <param name="map_update_rate" value="5.0"/> <param name="maxUrange" value="12.0"/> <param name="maxRange" value="14.0"/> <param name="particles" value="30"/> <param name="minimumScore" value="100"/> <param name="linearUpdate" value="0.2"/> <param name="angularUpdate" value="0.3"/> <param name="temporalUpdate" value="0.5"/> <param name="xmin" value="-10.0"/> <param name="ymin" value="-10.0"/> <param name="xmax" value="10.0"/> <param name="ymax" value="10.0"/> <param name="delta" value="0.05"/> <param name="sigma" value="0.05"/> <param name="kernelSize" value="3"/> <param name="iterations" value="5"/> <param name="srr" value="0.01"/> <param name="srt" value="0.02"/> <param name="str" value="0.01"/> <param name="stt" value="0.02"/> <param name="lsigma" value="0.1"/> <param name="ogain" value="3.0"/> <param name="lskip" value="0"/> <param name="minimumScore" value="100"/> </node> </launch>

逐行解读几个关键点。

base_frame必须和你的机器人TF树里的基座坐标系名称一致,常见的有base_link、base_footprint。odom_frame默认是odom,一般不用改。map_frame是map。

maxUrange和maxRange控制激光雷达的可用测距范围。maxUrange是用于匹配的最大有效距离,maxRange是雷达本身的最大量程。如果这两个值设置不当,会出现地图边缘产生大量噪声,或者远处墙壁被截断成两段的情况。

particles是粒子数,默认30。粒子数越多,估算越准但越吃CPU。如果你的雷达数据质量好、里程计准确,20到30就够用,调太高反而会因为更新太慢导致建图过程卡顿。

linearUpdate和angularUpdate非常重要。它们表示机器人直线运动多少米、转动多少弧度才触发一次SLAM更新。数值越小更新越频繁,地图越精细,但运算压力也越大。我一般设0.2和0.3,在速度和精度之间取平衡。如果你机器人走太快或算法跟不上,可以把这两个值适当调大。

4.3 启动之后要做什么

launch文件写好之后,roslaunch一键启动,然后开一个Rviz窗口可视化建图过程:

roslaunch your_package gmapping.launch rviz

在Rviz左侧Displays面板添加Map显示项,Topic选择/map,图像显示类型选择OccupancyGrid,就能实时看到地图一点点生成。

控制机器人运动是建图实验里最讲究的部分。走太快会掉帧,走太慢效率低,转向太猛会跑飞。我的经验是:直线速度控制在0.2到0.3米每秒,转向角速度在0.3到0.6弧度每秒,经过走廊或门口时尤其要慢。环境越复杂,就越要稳。建图过程中尽量覆盖每一个角落,同一个区域来回扫两遍效果好得多。

4.4 保存地图的两种正确姿势

建图完成别急着关机,先保存地图。保存命令是:

rosrun map_server map_saver -f ~/map/my_map

这会在~/map/目录下生成两个文件,my_map.pgm是图像文件,my_map.yaml是地图元数据。如果你不想用命令行,也可以在Rviz里点击2D Pose Estimate调整地图角度后再保存,不过新手不建议,容易把地图搞歪。

这里有一个很多新手不知道的坑:如果map_saver保存出来的地图全黑或全灰,往往是/map话题的数据还没稳定,或者你的地图分辨率设置得过小导致窗口范围不够。保存前先在Rviz确认地图加载完整、边界清晰,再执行保存。

5. 建图中的坐标系原理与核心机制理解

5.1 Gmapping为什么非要TF树

很多初学者跑通了Gmapping,但对坐标系一头雾水,出了问题不知道怎么查。我在这里花点篇幅把TF树讲透。

在Gmapping的运行机制里,有三个核心坐标系始终在参与计算。map是固定世界坐标系,原点就是启动Gmapping那一刻机器人所在的位置,所有地图数据最终都要映射到这个坐标系里。odom是以机器人启动点为原点的坐标系,它是通过底盘轮式编码器积分得到的短期位姿估计,会随运动逐渐累积漂移。base_footprint(或base_link)是跟随机器人移动的基座坐标系。

Gmapping每处理一帧激光数据,都要从TF树中读取map到odom的变换和odom到base_link的变换,两者合成后得到机器人当前在地图坐标系中的位姿,再把激光点投影到地图栅格上,完成一次地图更新。

换句话说,Gmapping的数学本质就是:通过比较激光数据与当前地图的匹配度,不断修正map到odom这个变换的估计,让机器人位姿的预测尽可能准确。这也是为什么很多人一看到TF报错就崩溃——整个算法都建立在这条坐标系链上,断任何一环,输出就是零。

5.2 粒子滤波原理的通俗化理解

Gmapping的核心算法是粒子滤波,我习惯用“团队投票”来给学生解释这件事。

想象你有几十个“假设机器人”,每一个都带着一份自己的地图草稿,沿着可能的轨迹在环境里走动。每一步,每个假设都根据里程计数据做预测,然后根据当前激光扫描和地图草稿的匹配程度来打分——匹配度高的假设,得分高;匹配度差的假设,得分低。然后按照得分高低重新抽取下一轮的假设群体,得分高的假设会被多次复制,得分低的被淘汰。如此反复迭代,最后存活下来的那些假设就收敛到机器人的真实位姿,它们携带的地图也合并成最终输出。

之所以叫“Rao-Blackwellized”,是因为这个算法把完整SLAM问题分解成了“估计机器人轨迹”和“根据轨迹估计地图”两个子问题。轨迹用粒子表示,地图在已知轨迹条件下用解析方式更新。这种分解方式让计算量大幅下降,是Gmapping在小场景里能实时运行的根本原因。

理解了这个机制,你就明白为什么里程计质量对Gmapping建图影响这么大。粒子滤波的预测是靠里程计给“方向感”的,如果里程计本身漂移严重,粒子分布就发散,收敛就慢,地图就容易分层、错位。提升建图效果的第一优先级永远是改善里程计,而不是调粒子数。

5.3 栅格地图的生成逻辑

Gmapping输出的是OccupancyGrid消息,也就是栅格地图。它把环境划分成一个个小格子,默认分辨率delta=0.05,也就是每格5厘米。每个格子的值表示该区域被占用的概率,从0到100,数值越高越可能是障碍物。

建图过程中,每帧激光数据被投影到当前估计的机器人位姿周围,激光束命中的位置标记为“占用”,光束穿过的区域标记为“空闲”,未探测区域为“未知”。随着机器人移动,传感器从不角度扫描同一区域,栅格概率不断累积更新,地图逐渐从模糊变清晰。

这里有个小技巧:如果在建图时发现地图边缘出现一圈“毛刺”或“鬼影墙”,多半是雷达的测距噪声和运动模糊造成的。你可以通过调低maxUrange拦截远处低置信度的激光点,或者调高minimumScore让低匹配度的帧被丢弃,效果立竿见影。

6. 关键参数调优与实战注意事项

6.1 最值得调的十一个参数

Gmapping的参数很多,但真正值得花时间调的就十一个,其余保持默认就行。

参数名作用调整建议
particles粒子数量里程计差就调大,30到80之间
minimumScore帧匹配最低得分雷达噪声大时适当提高,默认50到100
linearUpdate平移多少米触发更新走太快可减小,地图乱跳可增大
angularUpdate转多少弧度触发更新同linearUpdate逻辑
maxUrange匹配使用的最远距离场景大就调大,太小会截断墙壁
maxRange雷达最大量程略大于雷达标称值即可
map_update_rate地图发布频率默认5.0,不用动
delta地图分辨率0.05默认,精细地图可调0.025,但更吃算力
srr/srt/str/stt里程计噪声模型里程计不准就调大,准确可减小
sigma高斯平滑标准差默认0.05够用
lskip每N束激光取一束雷达线数少就设0,线数多可提高

很多教程不会细讲srr、srt、str、stt这四个噪声参数。它们分别对应“直行时的距离噪声”“直行时的角度噪声”“转向时的距离噪声”“转向时的角度噪声”。如果你的机器人底盘差,轮子打滑严重,把这几项从0.01调到0.02甚至0.03,粒子分布会更发散,反而有助于在不确定中找到正确位置。但过度调大也有风险,会让位姿估计抖动加剧,地图模糊。

6.2 地图错位和重影的排查思路

建图过程中最常遇到的现象是地图错位或者墙壁重影。排查顺序很重要,我从经验里总结出四步走。

第一步检查激光雷达的数据本身。打开Rviz的LaserScan显示,如果扫描点包含了很多飞点、跳变,说明雷达放在震动环境中或者供电不足。雷达一定要固定牢靠,USB线接触不良也经常导致数据卡顿。

第二步检查里程计的发布频率和数值。用手推机器人直线运动,在终端里echo/odom话题,确认线速度和角速度数值没有异常跳变。如果里程计在静止时还在缓慢变化,说明编码器校准有问题或IMU融合参数不对。

第三步观察TF变换是否有延迟。运行rqt_tf_tree查看TF树结构是否完整,运行tf_monitor看各个变换的发布频率是否稳定。TF延迟会导致激光数据和位姿对不上时间戳,产生明显的拖影。

第四步才是调Gmapping参数。在确认数据源没有大问题之后,根据地图现象反推参数。如果地图整体错位,优先提高particles和minimumScore;如果边缘噪点多,调maxUrange和sigma;如果转弯时地图变形,调angularUpdate。

6.3 建图过程中的运动控制心得

控制机器人“怎么走”是建图效果好坏的分水岭。

我的具体操作习惯是:先从房间的一个角落出发,沿墙走一圈,让机器人建立一个初始的“环境轮廓”;然后进入内部通道,走S形或Z字形路径把区域内部覆盖;最后绕到对面墙再走一圈闭合整体地图。遇到走廊或门框时,把速度降到平时的三分之一。

建图全过程不要中途大幅度调整机器人朝向,不要快速原地转圈,不要从一个区域直接瞬移到另一个区域。很多人把建图跑飞了,就是因为图方便,把机器人飞快地从一个房间推到另一个房间,中途经过一扇窄门,激光数据剧烈跳变,算法瞬间失去匹配基准,地图当场起飞。

如果你用的手柄或键盘控制,方向键操作的流畅度很重要。我的手感是:方向键不要按一下松一下,而是平滑持续地推动,让机器人保持恒定角速度转弯。

6.4 保存地图后的验收标准

建图完成后,保存下来的地图质量直接决定后续导航能不能用。判断地图合格有三个标准。

第一,墙壁线条清晰、单像素厚度、没有明显重影。第二,房间结构比例和实际环境一致,用卷尺测一个房间的长度,对比地图中的像素距离乘以分辨率,误差在10厘米以内算合格。第三,地图中没有大面积黑色噪点区域,空白区域均匀一致,没有莫名其妙的“孤岛”障碍物。

如果保存出来的地图在导航时出现机器人撞墙的情况,往往是地图里的墙壁位置有偏差,而不是导航算法的问题。很多人在导航环节骂天骂地,回头一看地图,边界歪了十厘米,什么都白搭。所以建图实验一定要把质量关,图不行就重建,别将就。

7. 实战中的常见问题与排查笔记

7.1 问题速查表

我把实操中会反复遇到的问题整理成一张速查表,遇到类似现象直接对号入座。

故障现象可能原因解决方案
启动后Rviz看不到地图/map话题没发布检查TF树是否完整,rostopic list看话题是否存在
地图一动不动激光话题或TF断链rqt_tf_tree查看TF,确认/scan有数据
地图边缘全是毛刺激光噪声偏大调低maxUrange,提高minimumScore
地图转弯处错位转向过快或里程计不准降低角速度,调大srr等噪声参数
地图有整面墙缺失maxUrange设置过小增大maxUrange到环境最远距离以上
保存的地图为全灰map_saver保存过早或地图未完成确认Rviz中地图加载完整后再保存
建图过程越来越卡粒子数过高或地图分辨率过小减小particles,把delta调到0.05
ROS报错无法连接雷达USB权限问题sudo chmod 666 /dev/ttyUSB0或配置udev规则
里程计漂移剧烈轮子打滑或编码器未校准检查底盘结构,校准轮径和轮距参数
地图出现规律性条纹雷达帧率与底盘运动频率共振降低底盘速度,或调整雷达驱动采样频率

7.2 三个典型踩坑实录

第一个坑是USB供电不足。有一段时间我用思岚A1建图,地图上总是出现周期性扇形噪点,排查了很久,最后发现是USB线太长导致雷达供电不稳。换一根短粗的USB线后问题消失。从此我的原则是,雷达供电尽量用独立供电模块,别偷懒直接插笔记本USB口。

第二个坑是时间戳不同步。有一次我把雷达驱动和底盘驱动分别手动启动,中间隔了几分钟,结果雷达数据的时间戳和TF变换的时间戳对不上,地图一直抖动。后来统一改用launch文件按序启动,问题才解决。ROS的TF系统对时间同步极其敏感,数据源的时钟必须在同一个维度上。

第三个坑是静态变换参数写错。我的雷达实际安装位置是底盘中心前方10厘米、高度20厘米,但粗心在static_transform_publisher的参数里写成了0 0 0。结果建出来的地图看起来也能用,但整个地图的墙壁厚度明显偏大,细节模糊。TF的平移和旋转参数一定要按实际安装尺寸去量,不要凭感觉填。

7.3 地图保存的编码细节

map_saver生成的.yaml文件值得打开看一眼:

image: my_map.pgm resolution: 0.050000 origin: [-7.024816, -6.396039, 0.0] negate: 0 occupied_thresh: 0.65 free_thresh: 0.196

这里的resolution就是每格对应米数,origin是地图左下角在map坐标系中的坐标。如果你在地图上发现了奇怪的斜向偏移,或者导航时起点定位偏差很大,检查一下origin的值是否和预期一致。

还有一个被忽略的细节:occupied_thresh和free_thresh决定栅格值被解释为占用还是空闲的门槛。如果你在导航时发现机器人总喜欢贴着墙走,可以适当调高occupied_thresh,让地图把靠近墙的模糊区域判定为占用,安全距离自然就有了。

8. 从实验到工程:Gmapping之外的进阶思路

跑通Gmapping只是SLAM世界的门口,真正做工程项目时,你大概率会碰到几个Gmapping搞不定的场景。

第一个场景是大空间工厂或仓库,面积超过几千平方米,纯靠Gmapping建出来的地图会有累积误差,闭合成环时墙面会对不上。这时候你需要Cartographer这类带闭环检测的图优化方案,或者用多个局部地图拼接的思路。

第二个场景是室外环境,2D激光只能感知一个平面高度的情况,地面起伏、坡道会彻底扰乱建图。此时fast-lio、loam这类3D方案才靠谱,Livox mid360搭配fast-lio2就是目前手持建图和无人机建图中非常热门的组合,建图效果比2D方案高一个维度。

第三个场景是机器人长时间运行时的地图维护。建图只是一次性的,但实际应用中环境会变化,家具移动、门开关、货架调整都会让旧地图失真。工程上通常的做法是定期重扫,或用AMCL定位结合代价地图做实时更新。

我的建议是:把Gmapping当成理解SLAM原理的“跳板”,别把它当成终身方案。学完这个实验,你应该理解粒子滤波的思想、ROS TF树的作用、栅格地图的生成逻辑,这些知识在以后接触任何SLAM方案时都能复用。

如果你要进阶,玩法很多。可以试试用hector_slam纯激光建图(不依赖里程计,但要求雷达帧率极高);也可以用karto_slam体验图优化思想;还可以装上cartographer感受一下工业级方案的配置复杂度。但无论玩哪个,建议先在bag包上跑通,再上真机。

最后再分享一个我在实际项目里的习惯:每次建图前,先花两分钟推着机器人绕环境走一圈不开算法,确认所有区域雷达都能扫到,角落没有雷达盲区,再正式启动Gmapping。这比边建边发现盲区再回头补扫要省事得多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询