ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ROS+Gazebo实现TurtleBot3扫地机器人仿真:从SLAM建图到弓字清扫

ROS+Gazebo实现TurtleBot3扫地机器人仿真:从SLAM建图到弓字清扫 做机器人仿真最怕什么在我看来不是算法难而是你花了一个星期把环境搭好、代码跑通结果发现根本没法在真机上复现或者调试一次要烧一次硬件成本和耐心都撑不住。我一开始接触ROS的时候也走过不少弯路后来用TurtleBot3在Gazebo里把一套完整的“建图、定位、导航、规划清扫路径”跑通之后突然就明白了仿真不是玩具它是你把机器人逻辑想清楚的最好方式。这篇就来完整记录我的实操全流程——怎么用ROS加Gazebo把TurtleBot3当成一台简易扫地机器人来跑包含环境搭建、SLAM建图、move_base导航以及我写的一个“弓字形”清扫脚本。无论你是刚装完Ubuntu的纯新手还是想在项目里做路径规划验证的开发者这个过程都值得你亲手走一遍。选择这套组合还有一个很现实的原因TurtleBot3的仿真模型几乎复刻了真实硬件的传感器配置激光雷达、IMU、轮式里程计都有对应插件你在仿真里调过的参数放到实物上有八成以上可以直接用。扫地机器人本质上就是一个装了两个驱动轮、一个万向轮、头顶加了一颗雷达的差速底盘TurtleBot3 Burger的底盘结构跟它极其相似拿它模拟扫地机器人不是硬凑是真的很对口。1. 项目整体设计与思路拆解1.1 为什么是TurtleBot3而不是自己建模很多人一开始会有个误区觉得既然是扫地机器人干脆自己用SolidWorks画一个模型导进Gazebo算了。我不反对但强烈不建议作为入门第一步。自己建模涉及三件事模型文件格式转换、物理参数质量、惯性张量、摩擦系数标定、传感器插件配置。这三件事每一个都能让你卡上两三天。比如你从Blender导出一个DAE格式的模型放进Gazebo后机器人往往会像踩在冰面上一样原地打滑原因就是轮胎的摩擦系数没设这类问题在入门阶段非常劝退。TurtleBot3的好处在于它把底盘、雷达、IMU这样一套标准配置全给你封装好了。Burger型号是两轮差速驱动带一个360度激光雷达LDS-01的仿真插件底座还有一颗IMU。这套硬件组合跟市面上不少家用扫地机器人的传感器配置非常接近激光雷达负责测距和建图轮式里程计负责短距离位姿推算IMU用来修正姿态漂移。所以你练的是通用能力不是TurtleBot3专用技巧。1.2 扫地机器人功能模块怎么拆我在动手之前先把“扫地机器人”这件事拆成了四层这也是后面所有步骤的主线感知层激光雷达扫描周围环境实时输出距离数据轮式里程计输出机器人每一帧的相对运动建图与定位层SLAM算法把雷达数据拼成全局地图同时估计机器人在地图中的位姿后续导航时再换成AMCL做蒙特卡洛定位规划层move_base负责全局路径规划和局部避障给机器人一条从A到B的路线行为层这是最像“扫地逻辑”的部分决定机器人怎么走才能覆盖整个房间——常见的有弓字形往返、沿墙、螺旋覆盖等TurtleBot3自带的仿真包覆盖了前三层但行为层需要自己写。这也正是“模拟扫地机器人”最有价值的一环你不可能只靠手搓遥控器去“扫”完一个地图必须让机器自己在房间内规划出合理的覆盖路径。1.3 仿真环境怎么选版本这个坑我提一下因为我见过太多人在版本搭配上翻车。ROS本身分ROS 1和ROS 2两个大版本的启动方式、话题通信、参数系统都不完全一样。当前主流还是ROS 1 Noetic Gazebo 11配Ubuntu 20.04生态成熟TurtleBot3官方教程最完善ROS 2 Humble Gazebo 11或Ignition配Ubuntu 22.04更接近新项目方向但教程相对分散我这次以ROS 1 Noetic为主线来写因为大部分人第一次跑TurtleBot3仿真用Noetic是最稳的全网踩坑记录也最多。你如果已经装了ROS 2 Humble整体流程的框架是一样的只是launch命令和包名略有区别这我在后面也会顺带提。2. 环境准备从空白系统到能启动Gazebo2.1 安装ROS手动源安装和一键脚本都能用如果你用的是Ubuntu 20.04最可靠的方式是官方源安装这里给出核心命令sudo sh -c echo deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main /etc/apt/sources.list.d/ros-latest.list sudo apt install curl curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add - sudo apt update sudo apt install ros-noetic-desktop-full这一步会装完整版ROS包含Gazebo 11、RViz、move_base等常用仿真和导航工具总大小约3GB需要一点耐心。如果网络环境不好也可以尝试国内镜像源或开源社区维护的一键安装脚本网上搜“鱼香ROS一键安装”就能找到脚本本质就是把上面的步骤封装成自动执行适合不想折腾源配置的初学者。我自己在虚拟机里装的时候也用过这种方式省事不少。2.2 安装TurtleBot3功能包和依赖装完ROS本体以后还需要安装TurtleBot3的仿真包和导航相关包sudo apt install ros-noetic-turtlebot3 ros-noetic-turtlebot3-simulations ros-noetic-turtlebot3-navigation sudo apt install ros-noetic-slam-gmapping ros-noetic-map-server ros-noetic-amcl ros-noetic-move-base这里解释一下每个包的用途turtlebot3-simulationsGazebo仿真模型和launch文件turtlebot3-navigationTurtleBot3在真实机器人上用的导航配置仿真也要用slam-gmapping基于激光雷达的2D SLAM算法用来建图map-server保存和加载地图amcl蒙特卡洛定位导航时确定机器人在地图中的位置move-base核心导航框架负责任务级的路径规划和避障2.3 设置环境变量这是最容易漏的一步TurtleBot3在不同型号之间的模型文件不一样所以ROS官方要求设置一个环境变量来指定型号。你可以在每个终端里执行export TURTLEBOT3_MODELburger但这样做每开一个新终端就得重新设置一次非常容易忘。我直接把这一行加进了~/.bashrcecho export TURTLEBOT3_MODELburger ~/.bashrc source ~/.bashrc这样所有终端都会自动加载不然后面启动launch文件时会报“TURTLEBOT3_MODEL is not set”或者一直提示找不到模型。2.4 提前解决Gazebo模型下载慢的坑很多人在第一次启动Gazebo时卡了半天界面里一片灰白什么都没有其实是Gazebo默认要从国外服务器在线下载模型文件。解决办法有两个第一个是检查~/.gazebo/models目录如果没有就手动创建然后把常用的模型放进去。第二个更高效的方法是直接用git把模型仓库克隆下来git clone https://github.com/osrf/gazebo_models.git ~/.gazebo/models如果git下载也慢可以尝试在GitHub页面上下载压缩包再解压。做完这步之后后续启动仿真就不会再卡在“Downloading model ...”这一步了。3. 跑通第一段仿真看到机器人在房间动起来3.1 启动Gazebo世界环境准备好以后第一次真正跑仿真的感觉还是很爽的。打开一个终端输入roslaunch turtlebot3_gazebo turtlebot3_world.launch这个命令会做三件事启动Gazebo服务器、启动Gazebo客户端界面、加载TurtleBot3 Burger模型到仿真世界。turtlebot3_world是一个已经布置好的室内环境里面有墙壁、简单的家具障碍物非常适合做SLAM和导航测试。启动过程中如果终端输出里出现很多红色的model下载失败信息别慌大概率是模型缺失回到上面的模型目录检查一下就行。等到Gazebo界面加载完整、中央出现一个带蓝色激光线束的小车就说明成功了。3.2 用键盘控制机器人移动此时机器人还瘫在原地我们需要让它动起来。新开一个终端安装并启动键盘遥控节点sudo apt install ros-noetic-teleop-twist-keyboard rosrun teleop_twist_keyboard teleop_twist_keyboard.py这个节点把键盘按键映射成/cmd_vel话题上的速度指令。在终端里按w前进、s后退、a左转、d右转Gazebo里的小车就会跟着动。Gazebo界面上还能看到激光雷达扫描出的蓝色线条碰到墙壁时线条就会弯折这就是雷达数据可视化的效果。有个细节值得注意键盘节点默认线速度是0.5米每秒这个速度在仿真里看起来不算快但建图时如果一直高速旋转激光帧之间会出现较大畸变后面SLAM建出来的图会糊。我建议进入建图环节之前把速度调低一些启动键盘节点时加参数rosrun teleop_twist_keyboard teleop_twist_keyboard.py _speed:0.2 _turn_speed:0.53.3 检查话题、TF和里程计看得到机器人能动只是第一步仿真作为开发环境的价值在于你可以随时“透视”机器人的内部状态。新开一个终端用以下几个命令验证最基本的数据流rostopic list这个命令会列出所有正在通信的话题。你需要重点关注的是/scan激光雷达数据、/odom里程计数据、/cmd_vel速度指令、/imu惯性测量单元数据。只要这四个话题都在说明传感器插件正常。再看机器人各部件之间的坐标变换rosrun rqt_tf_tree rqt_tf_tree或者更简单的方式是rosrun tf view_frames这会在当前目录生成一个frames.pdf打开后能看到base_link到laser、odom等各个坐标系之间的关系。如果TF树断裂后面AMCL或move_base一定会报错所以这一步不要跳过。4. 让机器人拥有“房间地图”SLAM建图实操4.1 SLAM选型先用gmapping打底扫地机器人要清扫的前提是知道房间轮廓。SLAM的方法有很多Gmapping基于粒子滤波对小场景和单层雷达效果不错算力要求也不高Cartographer是Google开源的那套加入了子图匹配回环修正能力强但配置复杂很多。TurtleBot3仿真里默认推荐gmapping我用下来感觉对于这个场景足够启动也极简。启动SLAMroslaunch turtlebot3_slam turtlebot3_slam.launch slam_methods:gmapping这个launch会启动slam_gmapping节点并打开RViz可视化界面。RViz里会显示机器人模型、激光雷达点云以及正在逐步构建的地图。刚开始地图是空的随着机器人走动地图会像拼图一样慢慢展开。4.2 建图操作速度要慢转向要稳启动SLAM之后接下来就是手动控制机器人在环境里“逛一圈”。我实际操作有个心得建图质量跟操作手法的关系非常大不是任何速度都能建出好图。首先是速度前面提过遥控节点默认的线速度太快建议降到0.15到0.2m/s转向速度控制在0.5rad/s以内。其次是路线规划尽量从房间一端开始沿着墙走“回”字形一圈一圈往里缩这样雷达能同时看到内外两侧的墙壁特征点丰富粒子滤波不容易发散。最后是尽量避免原地多次小角度转向转向时激光数据容易产生错位如果发现某段地图歪了可以慢慢倒回去重新扫一遍。大概花五分钟把整个地图扫完RViz里应该能看到一个清晰闭合的室内轮廓。如果扫的过程中机器人撞到障碍物在纯仿真里不会真的损坏但你会发现地图上障碍物边缘会出现奇怪的缺口这是碰撞后机器人位姿被弹开导致的属于仿真中的正常现象别当成SLAM算法有问题。4.3 保存地图一条命令的事建完图先别关终端把地图保存下来rosrun map_server map_saver -f ~/map这会在家目录生成map.pgm和map.yaml两个文件。PGM是地图图片YAML是地图的元信息包括分辨率、原点坐标、占用阈值等。保存成功后打开PGM看一下黑色是障碍物白色是空地灰色是未知区域。如果灰色占了一大片说明没有扫全得回到Gazebo里继续补扫。到这里“地图”这个扫地机器人最重要的先验知识就已经拿到手了。后面导航和规划路径全都要靠这张图。5. 给机器人装上“大脑”导航与清扫路径实现5.1 启动导航栈定位加路径规划清扫和建图的区别在于清扫时机器人已经知道自己在哪里并且知道整个房间的地图它要做的是在地图上规划路线而不是边扫边探索。这个阶段用的是导航栈。roslaunch turtlebot3_navigation turtlebot3_navigation.launch map_file:$HOME/map.yaml这行命令会启动三个核心节点AMCL负责定位move_base负责全局和局部路径规划加上RViz可视化界面。启动后RViz里会看到机器人模型但它还不确定自己在哪里。有一个手法我很常用在RViz顶部工具栏点击“2D Pose Estimate”然后在地图上机器人对应的位置拉一个箭头先给它一个初始位姿。这个操作等价于告诉它“你大概在这个位置、朝向这个方向”。AMCL定位收敛后机器人周围的粒子会逐渐聚集到真实位姿附近。如果粒子到处散开说明初始位姿给得偏差太大重新拉一次即可。5.2 理解move_base的路径规划逻辑在清扫脚本写出来之前先用RViz里的“2D Nav Goal”给机器人打个点看它能不能自己走过去。点下去之后绿色线是全局路径红色线是局部路径机器人会沿着规划出来的路线绕过障碍物前进。move_base内部有两层规划器全局规划器global_planner基于静态地图算出一条从当前点到目标点的大致路径局部规划器local_planner基于实时激光数据在小范围内躲避动态障碍物两层规划器各有一个代价地图叫costmap。代价地图把障碍物向外膨胀了一圈膨胀的半径由inflation_radius参数控制。扫地机器人过窄通道时经常卡住很大概率就是膨胀半径太大机器人觉得自己过不去。如果你在后面的自主清扫脚本中发现某个狭窄路口机器人一直绕路优先调小costmap里inflation_radius的值而不是怀疑算法坏了。5.3 模拟扫地逻辑弓字形覆盖脚本导航栈能做的只是“从A点到B点”扫地机器人的核心是用一条合理路径覆盖整个房间。最经典的方案就是弓字形路径沿房间一边走到底然后平移一个机身宽度再反向走回来像农田耕犁一样一行行扫过去。这一步需要写一个Python节点利用move_base的action接口连续下发目标点。我写了一个简化版本下面这段代码可以当成起点来改#!/usr/bin/env python3 import rospy import actionlib from move_base_msgs.msg import MoveBaseAction, MoveBaseGoal from geometry_msgs.msg import PoseStamped, Quaternion import math class SweepCleaner: def __init__(self): rospy.init_node(sweep_cleaner) self.client actionlib.SimpleActionClient(move_base, MoveBaseAction) self.client.wait_for_server() # 清扫区域左下角和右上角单位米按实际地图修改 self.min_x 0.0 self.max_x 3.0 self.min_y 0.0 self.max_y 3.0 self.robot_width 0.5 # 每行间距略小于机器人直径 def make_goal(self, x, y): goal MoveBaseGoal() goal.target_pose.header.frame_id map goal.target_pose.header.stamp rospy.Time.now() goal.target_pose.pose.position.x x goal.target_pose.pose.position.y y goal.target_pose.pose.orientation.w 1.0 return goal def run(self): y self.min_y direction 1 # 1 向右走-1 向左走 while y self.max_y: if direction 1: x self.max_x else: x self.min_x goal self.make_goal(x, y) self.client.send_goal(goal) self.client.wait_for_result() y self.robot_width direction * -1 if __name__ __main__: SweepCleaner().run()这段代码的逻辑是从房间左下角开始先向右走到边界然后上行一个机身宽度再向左走到边界。循环往复形成弓字形覆盖。实际项目中你还需要在拐点时加上旋转动作以及根据代价地图检测未覆盖区域但基础骨架就是这个。运行之前记得给脚本加执行权限chmod x sweep_cleaner.py python3 sweep_cleaner.py然后就可以在RViz里看到机器人走走停停按你给的矩形区域做往返运动。这个效果我可以说已经非常接近一台真正扫地机器人的行为模式了。5.4 参数微调的几条经验扫地覆盖跑起来之后你会发现很多实际问题跟想象中不一样。第一行距不能大于机器人直径否则行与行之间会漏扫。Burger模型直径大概是17厘米我用0.15米作为行距覆盖比较密但就是慢。如果你只是做演示可以放大到0.2米视觉上依然能看出清扫效果。第二机器人到达每个目标点都会先完全停下来再转向下一行这样效率很低。真正的扫地机器人会在行驶过程中直接转弯。解决办法是给每个目标点传入带有朝向的Quaternion让机器人在到达时提前做姿态调整而不是停稳再转。第三move_base超时问题。如果某个目标点在costmap里被标记成不可达机器人会一直尝试然后卡住。我建议在send_goal之后加一个超时判断超过30秒没到达就放弃当前点直接去下一个避免整个清扫流程卡死。6. 常见问题与排查技巧实录6.1 Gazebo界面闪烁或者黑屏这个问题我在热词里看到很多人问。Gazebo的渲染基于OpenGL如果你的电脑是双显卡或者跑在虚拟机里经常会出现界面闪烁、黑屏或画面撕裂。最快的验证方法是强制Gazebo用软件渲染export LIBGL_ALWAYS_SOFTWARE1但软件渲染性能比较差大场景里机器人动起来会有点卡。有条件的话可以安装系统的NVIDIA或AMD专用驱动然后用GPU渲染。另外有时不是渲染问题而是Gazebo同时开启了多个客户端实例多个进程抢同一个渲染窗口这种关掉多余的gzclient进程就能解决。6.2 模型加载后机器人乱飞或者掉到地下如果你在Gazebo里看到机器人外观正常但一启动就乱飞、下沉或抖动基本可以确定是模型加载的物理参数出了问题。TurtleBot3官方模型很少出现这种问题倒是自己导入的外部模型特别容易中招。检查点有两个模型文件的mass和inertia是否合理以及是否设置了合适的surface摩擦参数。如果你用的是TurtleBot3原装模型还出现乱飞那大概率是Gazebo版本太旧和ROS Noetic自带的Gazebo 11不兼容需要升级Gazebo或重新安装完整版的desktop-full包。6.3 move_base启动后一直报“No transform from odom to map”这个报错在导航启动时非常常见。本质上是因为没有定位数据AMCL没有发出从map到odom坐标系的变换。常见原因有三种一是初始位姿没设置回到RViz用“2D Pose Estimate”给一个初始位置二是map_frame、odom_frame、base_frame这三个坐标系名字不对打开launch文件确认一下TurtleBot3默认使用map、odom、base_footprint或base_link三是TF树本身断了用rosrun rqt_tf_tree rqt_tf_tree检查整棵TF树是否从map一直连到laser。6.4 导航时机器人在原地打转机器人到达目标点的过程中如果一直原地旋转通常是局部规划器的问题。常见原因就是costmap的膨胀半径设得太大导致机器人认为自己周围全是障碍物任何速度指令都会被标记为“可能碰撞”。此时适当调小inflation_radius或者检查雷达话题/scan是否输出正常数据如果雷达数据是空的局部规划器等于瞎子只能在原地转圈。6.5 仿真速度越来越慢跑了一段时间后Gazebo帧率明显下降这跟模型下载缓存、粒子数量持续增长都有关系。gmapping的粒子数默认是30如果建图场景很大可以试着把粒子数调小一些地图精度会略降但流畅度明显提升。此外长时间开着多次启动的launch文件会产生大量僵尸进程用htop查一下把不再需要的roscore和gzserver进程清掉。6.6 常见问题速查表现象直接原因快速处理启动launch报TURTLEBOT3_MODEL未设置缺少环境变量执行export TURTLEBOT3_MODELburger并写入bashrcGazebo界面空白或一直显示Downloading model模型缓存为空或网络差手动clone gazebo_models到~/.gazebo/modelsGazebo窗口闪烁/黑屏OpenGL渲染冲突设置LIBGL_ALWAYS_SOFTWARE1或更新显卡驱动SLAM建图扭曲、重影移动速度太快导致激光畸变降低遥控速度沿墙慢速重扫保存地图后全是灰/大片未知区域房间没走完回到Gazebo继续在未知区域巡逻扫描导航时报No transform from odom to mapAMCL未初始化在RViz中用2D Pose Estimate指定初始位姿move_base导航原地打转costmap膨胀过大或雷达数据异常调小inflation_radius检查/scan话题输出清扫脚本到达点后不走下一行目标点被代价地图视为不可达调小膨胀半径或跳过该目标点并加超时逻辑6.7 热词相关心得补充在海量热词里“为什么Gazebo界面一直在闪”被提问最多其次是“Gazebo安装ros环境ubuntu22”这类环境问题。我个人补充两条实用经验一是使用Ubuntu 22.04配ROS 2 Humble的用户如果遇到Gazebo启动异常优先确认是否装了ros-humble-gazebo-ros-pkgs这个包经常被遗漏二是“gazebo使用gpu加速”这一点对室内小场景作用有限Gazebo的物理引擎计算才是瓶颈与其纠结渲染不如把粒子数和地图分辨率调低一点。清扫路径策略这块我还有个小建议不要只盯着move_base默认的规划器试试把全局规划器切换成NavfnROS有时候在狭窄通道里的表现反而比默认的GlobalPlanner更稳定。这些都是在反复调参中得到的经验纯看文档是体会不到的。7. 写在最后把仿真成果向真机迈进TurtleBot3这套仿真流程跑完之后你手里拿到的不仅是一段能动的Gazebo演示而是一整套现代机器人开发的基本工作流仿真建模、传感器数据检查、SLAM建图、定位、导航规划、行为调度。这套工作流稍加变化就能延伸到其他机器人的研发里。我个人的建议是下一步不要急着加复杂的策略先用日志和数据把仿真的每个环节记录下来雷达扫描频率是多少、一次完整的弓字形清扫耗时多久、覆盖率能达到多少。这些指标会让你对机器人的性能有更直观的认识后面换到真机时你也会养成先量化再优化的习惯。如果你有动力可以接着尝试把TurtleBot3换成Waffle Pi型号看它对载重能力的变化或者在Gazebo里加几个动态障碍物观察局部规划器避障时的真实表现。总之TurtleBot3是一座桥跨过它以后你会发现ROS和Gazebo能做的事情远比你最初想象的多。
返回列表