每次带学生做机器人项目,总会遇到同样的场景:理论课讲了一堆坐标变换、概率定位、路径规划,真到实验环节却卡在第一公里——要么实验室只有两台实体小车,排队半小时摸不到键盘;要么好不容易启动程序,小车直接撞墙,电池和电机倒是没什么事,旁边的师兄心态先崩了。其实移动机器人开发最理想的第一站,不是真机,而是仿真环境。
这篇文章会把 ROS2 从仿真到自主导航的完整链路串起来讲清楚:先借助 Stage 这种轻量 2D 仿真器快速跑通 SLAM 建图,再切换到 Ignition/Gazebo 这类 3D 物理仿真环境验证 Nav2 导航。整个过程不需要昂贵硬件,只要一台装有 Ubuntu 的电脑,就能亲手完成“机器人在地图中运动 → 扫描环境 → 构建地图 → 规划路径 → 自主导航”的闭环。无论你是刚接触 ROS2 的初学者,还是被导航参数折腾过的进阶开发者,都可以按这篇文章的步骤逐步实操,遇到问题也能直接查到排查思路。
1. 为什么建议从仿真环境入门移动机器人开发
1.1 仿真环境不是“玩具”,而是工程杠杆
很多初学者对仿真有一种误解,觉得“跑仿真 = 玩游戏”,没什么技术含量。实际上,仿真环境是现代机器人研发流程中不可或缺的环节。工业界在把新算法部署到真实机器人之前,通常都会先在仿真里做大量验证:传感器噪声怎么模拟、动态障碍物如何避让、导航失败后如何恢复,这些场景在真机上复现成本极高,但在仿真环境中只需要几行命令就能反复测试。
更重要的是,仿真环境能让学习者把注意力集中在“算法本身”而不是“硬件琐事”上。真实机器人涉及电池电量、电机驱动、IMU 校准、轮子打滑、通信丢包等一系列问题,这些对新手来说属于额外负担。先通过仿真把 SLAM 建图和 Nav2 导航的完整链路跑通,建立对话题、节点、TF 坐标变换、代价地图这些核心概念的整体认知,再迁移到真机上,学习曲线会平缓很多。
1.2 一条完整的机器人自主移动链路
自主移动机器人要实现“从 A 点走到 B 点”,表面上看是导航问题,实际背后是一条完整的数据链路:
- 传感器数据采集:激光雷达发布
/scan话题,里程计发布/odom话题,这些是所有上层功能的数据基础。 - SLAM 建图与定位:机器人一边运动一边扫描周围环境,构建出占用栅格地图,同时确定自己在地图中的位置。
- 导航规划与控制:有了一张地图和当前位姿后,导航系统才能规划出一条从起点到目标点的无碰撞路径,并输出速度指令控制机器人移动。
这中间任何一个环节的质量都会影响最终效果。比如建图时机器人速度太快导致地图重影,后面导航必然出问题;再比如 TF 树的坐标系关系没配置好,导航系统完全无法工作。这也是为什么我建议把“仿真 → 建图 → 导航”作为一条完整链路来学习,而不是单独研究某个工具包。
1.3 本文实战目标与前置要求
通过本文的实战,你将掌握以下能力:
- 使用 ROS2 的仿真器启动一个带激光雷达与里程计的移动机器人。
- 使用 slam_toolbox 在 Stage 仿真环境中进行实时 SLAM 建图。
- 使用地图保存工具导出 pgm/yaml 地图文件。
- 在 Ignition/Gazebo 3D 仿真环境中启动 Nav2,完成自主导航与避障。
前置要求方面,你需要准备一台安装 Ubuntu 22.04 的电脑,并安装好 ROS2 Humble。当然,如果你使用的是其他 ROS2 发行版,原理完全一致,只是部分软件包名称和路径会有差异。另外需要掌握基本的 Linux 终端操作,知道cd、ls、source这些命令的含义即可。
2. ROS2、SLAM 与 Nav2 核心概念速览
2.1 ROS2 相比 ROS1 的架构变化
很多老教程还停留在 ROS1,但新项目基本都在向 ROS2 迁移。ROS2 在架构上的最大变化是底层通信改用了 DDS(Data Distribution Service,数据分发服务)。DDS 支持真正的分布式通信,节点可以运行在不同的机器上而无需中心节点(roscore)来中转,同时引入了服务质量策略(QoS),让数据传输的可靠性、实时性可以按需配置。
对开发者来说,ROS2 还有一个影响日常开发的变化:功能包的构建系统从 catkin 变成了 colcon,launch 启动文件全面支持 Python 编写,这让我们可以写出更灵活的启动脚本。比如在导航实战中,一个 launch 文件可以同时启动仿真器、导航节点、Rviz2,并给不同节点设置不同的参数,这在 ROS1 时代实现起来要繁琐得多。
2.2 SLAM:建图与定位的双重职责
SLAM 的全称是 Simultaneous Localization and Mapping,中文一般翻译为“同时定位与建图”。可以这样理解:机器人被放到一个陌生的房间里,它一边移动,一边用激光雷达测量周围障碍物的距离,并且这些测量结果同步更新地图。与此同时,它还要知道自己在当前地图中的位置。这就是“同时”的含义——定位帮助建图,建图反过来又服务于定位,两者互相依赖。
常见的开源 SLAM 方案有很多,比如本文使用的 slam_toolbox,还有 Google 的 Cartographer,以及视觉领域的 ORB-SLAM 系列。对于初学者来说,slam_toolbox 配置简单、效果稳定,非常适合作为入门选择。Cartographer 对参数调校和传感器质量要求更高,适合后续进阶研究。
2.3 Nav2:可组合的导航框架
Nav2(Navigation2)是 ROS2 官方推荐的导航框架,它是 ROS1 中 move_base 的继任者。Nav2 把导航功能拆解成许多独立的组件:全局规划器(Planner)、局部规划器(Controller)、代价地图(Costmap)、行为树(Behavior Tree)等。
整个导航流程大致这样:用户在地图中指定一个目标点 → 全局规划器基于静态地图规划出一条全局路径 → 局部规划器根据实时传感器数据躲避动态障碍物 → 控制器输出线速度与角速度指令 → 机器人底盘执行移动。Nav2 功能的丰富性也意味着参数非常多,这也是为什么许多新手在用 Nav2 时容易感到挫败。本文会以最小配置跑通流程,告诉你哪些参数是必须关心的,哪些可以先放着不管。
2.4 Stage 与 Ignition/Gazebo 的定位差异
Stage 是一个轻量级 2D 仿真器,它模拟的是机器人在二维平面上的运动,激光雷达数据直接基于二维地图计算,渲染也非常朴素。它的优点是启动快、占用资源低,适合快速验证 SLAM 建图和导航算法。对于学习阶段来说,Stage 可以让我们把精力完全放在建图流程上,不必担心 3D 物理引擎带来的各种干扰。
Ignition 则是 Gazebo 的下一代仿真平台,现在官方也将其称为 Gazebo Sim。它提供完整的三维物理引擎、传感器仿真和逼真的渲染效果,适合验证一些与真实场景更贴近的算法。需要理解的是,无论仿真器是 2D 还是 3D,对于上层的 SLAM 和 Nav2 来说,它们都只是提供传感器话题与里程计话题的数据源。这部分抽象能力就是 ROS2 的魅力所在——同样的建图和导航代码,可以无缝切换不同的仿真后端。
3. 环境准备与 ROS2 基础配置
3.1 操作系统与 ROS2 安装
本文以 Ubuntu 22.04 + ROS2 Humble 为例,这是目前教程资源最丰富、兼容性最好的组合之一。安装 ROS2 之前,请确保系统软件源可以正常访问,并已经安装好curl和software-properties-common等基础工具。
首先添加 ROS2 软件源并安装桌面版:
sudo apt update && sudo apt install curl sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null sudo apt update && sudo apt upgrade sudo apt install ros-humble-desktop安装完成后,需要把 ROS2 环境变量写入 shell 配置文件,否则每次打开新终端都要手动 source:
echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc source ~/.bashrc这里强烈建议使用ros-humble-desktop完整版,因为它包含了 Rviz2、Gazebo、演示示例等一系列常用工具。如果只装了基础版,后面很多命令会提示找不到包,排查起来非常麻烦。
3.2 创建 colcon 工作空间
ROS2 中,我们通常使用 colcon 来构建功能包。创建一个工作空间需要两个目录:src用于存放源代码,构建后的产物会放在build和install目录中。
mkdir -p ~/ros2_ws/src cd ~/ros2_ws colcon build每次构建完成后,记得 source 工作空间的 setup 文件:
source ~/ros2_ws/install/setup.bash在实际开发中,这个 source 语句同样建议写入~/.bashrc。需要注意的是,如果本机同时有多个 ROS2 工作空间,后 source 的工作空间会覆盖先 source 的同名包,这一点在调试功能包报错时经常被忽略。
3.3 安装演示机器人依赖包
本文实战部分将使用 TurtleBot3 这个经典的 ROS2 演示机器人平台,因为它有非常完善的仿真支持。我们需要的功能包包括:
sudo apt install ros-humble-turtlebot3-gazebo ros-humble-turtlebot3-navigation2 ros-humble-turtlebot3-teleop sudo apt install ros-humble-slam-toolbox ros-humble-nav2-map-server ros-humble-stage-ros2如果你在安装stage-ros2时提示找不到包,可以先搜索一下当前发行版的可用版本:
apt search ros-humble-stage不同 ROS2 发行版的软件包名称会有差异,比如在 Rolling 或其他版本上可能叫stage-ros2,也可能已经内置到仿真仓库中。以实际查询到的包名为准即可。
启动 TurtleBot3 仿真前,还需要设置一个环境变量来指定机器人型号:
export TURTLEBOT3_MODEL=burger echo "export TURTLEBOT3_MODEL=burger" >> ~/.bashrc设置完所有环境后,可以运行一个简单的节点测试环境是否正常:
ros2 run turtlesim turtlesim_node如果能看到小乌龟窗口,说明 ROS2 安装和环境配置基本没有问题。
4. Stage 仿真 + SLAM 建图实战
4.1 Stage 仿真器初体验
Stage 仿真器在 ROS2 中的入口节点是stageros,它通过读取.world文件来加载地图和机器人模型。.world文件是一种基于文本的建模格式,可以定义墙壁、障碍物、机器人传感器等元素。下面是一个简化版的世界文件示例,它创建了一个带围墙的矩形房间,里面放了几面内部隔墙:
// 文件路径:~/ros2_ws/src/stage_demo/world/simple.world define floor model ( size [6 6 1] color "gray" ) define block model ( size [0.2 1 1] color "red" ) model ( name "floor" pose [0 0 0 0] floor ) model ( name "wall1" pose [1 0 0 0] block ) model ( name "wall2" pose [-1 0.5 0 0] block )需要说明的是,这个文件主要是展示 Stage 世界文件的书写思路,实际使用中建议从stage_ros2官方仓库中的示例世界文件开始修改。Stage 本身不提供内建的 TurtleBot3 模型,所以如果希望使用 TurtleBot3 的传感器模型,需要自己在.world文件中定义差速底盘模型并挂载激光雷达。对初学者来说,我更推荐直接使用stage_ros2自带的机器人模型,或者通过ros2 launch stage_ros2提供的示例启动文件来加载默认世界。
启动 Stage 仿真后,可以用下面的命令检查传感器话题是否正常发布:
ros2 topic list ros2 topic hz /scan如果/scan话题有数据输出,说明激光雷达传感器工作正常,可以开始建图。
4.2 启动 slam_toolbox 在线建图
slam_toolbox 是 ROS2 中非常流行的 2D 激光 SLAM 工具,它支持在线建图和地图持久化。在线异步建图模式(online_async)比较适合本场景,因为它在处理激光数据时不会阻塞控制流程,建图过程会更流畅。
ros2 launch slam_toolbox online_async_launch.py use_sim_time:=true这里设置use_sim_time:=true非常关键。在仿真环境中,系统必须使用仿真器发布的/clock话题作为时间源,而不是使用宿主机系统时间,否则传感器数据的时间戳会错乱,建图结果会出现漂移。
slam_toolbox 运行后,会在以下话题上输出建图结果:
/map:实时更新的占用栅格地图。/map_metadata:地图的元数据。/slam_toolbox/scan_visualization:激光扫描的可视化信息。
在 Rviz2 中打开地图话题,就能看到机器人不断扫描并逐步构建地图的实时画面。可以先确认这一层数据流是通的,再进行遥控建图。
4.3 键盘遥控与建图操作
建图的本质是“控制机器人在环境中移动,让激光雷达扫描到所有区域”。因此这一步需要手动遥控机器人走遍整个环境。TurtleBot3 提供了键盘遥控节点:
ros2 run turtlebot3_teleop teleop_keyboard运行后,终端会显示控制按键说明:w前进、s后退、a左转、d右转、x停止。建图时最重要的技巧是“慢速、匀速、全覆盖”。速度越快,激光数据逐帧之间的位姿变化越大,SLAM 算法匹配点云时的误差也越大。尤其是转角处,一定要把线速度降下来,多旋转几圈让激光雷达充分扫描到墙角结构,否则建出来的地图边缘会产生重影。
另外一个常见失误是“跑完一圈就结束”。真正合格的地图需要保证:机器人经过的区域被激光覆盖,且机器人在运动过程中能够反复观测到之前的特征点,这样回环检测才能生效,地图才不会出现累计漂移。所以在建图过程中,建议让机器人走两遍主要道路,一遍快速摸底,一遍缓慢精扫。
4.4 保存地图
建图完成后,需要把 slam_toolbox 生成的栅格地图保存到磁盘上。ROS2 中地图保存工具是 Nav2 的map_saver:
mkdir -p ~/maps ros2 run nav2_map_server map_saver_cli -f ~/maps/simple_map执行成功后,会在~/maps目录下生成两个文件:
simple_map.pgm:栅格地图图片文件,每个像素对应一个占用值。simple_map.yaml:地图描述文件,包含分辨率、原点、占用阈值等信息。
simple_map.yaml的内容大致如下:
image: simple_map.pgm resolution: 0.050000 origin: [-10.000000, -10.000000, 0.000000] negate: 0 occupied_thresh: 0.65 free_thresh: 0.196这个 yaml 文件是后续导航时必须提供给 Nav2 的核心文件之一,不要随意删除或重命名,尤其是image字段的路径,必须保持相对路径正确。
5. Ignition/Gazebo 仿真 + Nav2 导航实战
5.1 3D 仿真环境与机器人模型
完成 Stage 中的 SLAM 建图后,接下来进入导航环节。导航需要验证机器人在已知地图中的定位、全局路径规划和局部避障能力,这些功能在 3D 仿真环境下观察更为直观。这里我们使用 TurtleBot3 在 Ignition/Gazebo 中的仿真环境。如果你安装的是 Gazebo Classic,可以直接用官方提供的 launch 文件启动一个带 TurtleBot3 的世界:
export TURTLEBOT3_MODEL=burger ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py如果你使用的是 Ignition 版本,思想完全一致:仿真器负责输出机器人的/scan、/odom、/tf等话题,Nav2 只关心这些话题,不关心后端到底是 Stage、Gazebo 还是 Ignition。启动后可以在 Rviz2 中确认/scan数据是否正常,并观察三维场景中机器人所在的位置。
仿真环境启动后,需要保证use_sim_time环境参数为 true,这样才能让 Nav2 的节点使用仿真时间。可以在 Rviz2 的面板中设置,也可以在执行 launch 时显式传递use_sim_time:=true。
5.2 启动 Nav2 导航栈
导航需要一张“预先建好的地图”,以及机器人在该地图中的初始位置。TurtleBot3 提供了导航 launch 文件,会同时启动 Nav2 的核心组件、AMCL 定位模块、机器人状态发布器和 Rviz2:
ros2 launch turtlebot3_navigation2 navigation2.launch.py use_sim_time:=true map:=/home/你的用户名/maps/simple_map.yaml其中map参数指定第 4 节中保存的地图文件。执行后,Rviz2 窗口会加载出来,中央显示地图,机器人模型会出现在某个初始位置。
如果机器人在地图中的初始位置和实际不符,导航就无法正常工作。这时需要手动修正:在 Rviz2 中点击 “2D Pose Estimate” 按钮,然后在地图上拖拽调整机器人位姿,把机器人的估计位置与实际位置对齐。这个步骤看似简单,但经常被忽略,一旦位姿初始化错误,后面所有的规划都会失败。
Nav2 启动成功后,可以看到以下关键节点在运行:
ros2 node list通常包括/amcl、/planner_server、/controller_server、/behavior_server、/bt_navigator等。这些组件分别负责定位、全局规划、局部规划、行为管理和导航任务编排。
5.3 Rviz2 中发布目标点
导航的核心操作是在 Rviz2 中给机器人指定目标点。点击 Rviz2 顶部工具栏的 “Navigation2 Goal” 按钮,然后在地图上点击一个目标位置并拖动调整朝向,松开鼠标后,Nav2 会开始处理导航任务。
你会在地图上看到几条重要信息:
- 绿色的细线:全局规划路径,由全局规划器基于静态代价地图生成。
- 红色/绿色的区域:代价地图,红色代表致命障碍物区域,Lethal cost 不允许机器人进入;绿色代表膨胀区域,机器人会尽量避开。
- 机器人周围的局部路径曲线:由局部规划器实时更新的路径,会依据激光雷达数据不断调整,以实现动态避障。
如果一切正常,机器人会先旋转调整朝向,然后沿着全局路径移动。如果路径上有障碍物,局部规划器会尝试绕开;如果绕不开,机器人会停下来等待,直到障碍物移开或导航任务超时。
为了测试导航算法的可靠性,可以在机器人前进路径上手动添加障碍物,观察 Nav2 是否能及时重新规划路径。在仿真环境中,这一步只需要在世界文件里增加一个模型,或使用 Ignition 的模型放置功能即可。
5.4 从建图到导航的串联思路
到这里,你已经分别完成了“用 Stage 建图”和“在 Gazebo/Ignition 中导航”两个独立任务。但在实际工程中,这两个环节通常是在同一个场景下接续完成的:先在仿真的地图上建图,保存地图后,再用同一张地图启动导航。
串联时有一个容易踩的坑:建图时的地图原点与导航时的地图原点不一致。SLAM 工具建图时通常以机器人启动位置为原点,而 Nav2 加载地图后,AMCL 定位模块会重新估算机器人在地图中的位置。如果保存地图后修改过地图文件,或者在导航 launch 中指定了错误的初始位姿,机器人就会出现在地图之外,导致导航直接失败。遇到这种情况,先删除或重置 AMCL 的初始位姿,再重新用 “2D Pose Estimate” 手动初始化即可。
另一个值得关注的话题是 “重定位” 问题。SLAM 建图和导航定位其实是两种不同的任务:建图是对未知环境进行探索,定位是在已知地图中确定自身位置。Nav2 中不需要跑 SLAM,只需要跑 AMCL,这也是为什么导航系统中不会启动 slam_toolbox 节点。
6. 常见问题与排查思路
在实际操作中,几乎没有哪条命令是第一次就能完美跑通的。下面汇总几个最高频的问题,按“现象 → 原因 → 解决”的思路整理成表,方便你快速对照。
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| 启动节点提示找不到包 | 环境变量未 source,或功能包没有安装 | 检查source /opt/ros/humble/setup.bash,并确认 apt 包安装成功 |
/scan话题没有数据 | 仿真器未启动,或机器人模型没有挂载激光雷达 | 检查ros2 topic list,确认仿真进程正常运行 |
| Rviz2 中看不到地图 | 地图话题未添加,或use_sim_time不匹配 | 检查/map话题,并确保所有节点统一使用仿真时间 |
| slam_toolbox 建图出现重影 | 机器人移动过快,或 TF 时间戳漂移 | 降低遥控速度,检查 TF 树的坐标关系 |
| Nav2 导航规划失败 | 地图与当前环境不匹配,或目标点设置在障碍物内 | 检查地图文件,重新初始化机器人位姿,选择可通行目标点 |
| 机器人不走直线、蛇形摇摆 | 局部规划器参数调节不当,或底盘模型不匹配 | 调整 controller_server 中的最大速度、加速度参数 |
| 导航时机器人原地旋转不停 | 机器人位姿初始化不准确,或目标点朝向设置不合理 | 重新用 “2D Pose Estimate” 初始化位姿 |
这里重点说一个经常让新手困扰的现象:所有节点都正常启动,Rviz2 也有地图,但 Nav2 就是规划不出路径。排查顺序建议如下:
- 检查目标点是否位于代价地图的 free 区域,而不是障碍物内。
- 检查全局代价地图的话题名是否和地图话题一致,必要时在 Rviz2 中查看 Global Costmap 层是否显示地图。
- 检查 TF 树是否完整,运行
ros2 run tf2_ros tf2_echo map odom,看是否有数据输出。 - 检查 AMCL 定位是否收敛,Rviz2 中的粒子是否集中在一个区域。
如果以上都正常,但导航仍然失败,可以尝试重启 Nav2 节点,并在navigation2.launch.py中增加params_file参数,使用官方默认参数文件重新启动。
7. 最佳实践与工程建议
7.1 用 launch 文件管理仿真与导航流程
手动一条条敲命令虽然能加深理解,但工程效率太低。建议把仿真、建图、导航的启动过程封装进 launch 文件。ROS2 的 launch 文件采用 Python 编写,可以方便地设置节点间的依赖顺序、共享参数和条件判断。例如,一个建图 launch 文件可以同时启动仿真器、slam_toolbox、Rviz2 和键盘遥控节点,并通过use_sim_time参数统一时间源。
写 launch 文件时,建议保持“一个文件只做一件事”的原则。不要试图在一个 launch 文件里塞下建图和导航两类任务,因为建图阶段和导航阶段的节点集合差异很大,混合在一起不仅调试困难,还会导致不必要的资源浪费。
7.2 关注 TF 树与话题约定
在 ROS2 的移动机器人系统中,TF 树是一切算法的前提。典型的移动机器人 TF 树至少包含以下坐标关系:
map→odom:由 AMCL 发布,用于定位。odom→base_footprint:由里程计或仿真器发布,表示机器人相对起始位置的位姿。base_footprint→base_scan或laser_link:由机器人描述文件发布,表示激光雷达相对机器人中心的位置。
如果某个坐标变换缺失,SLAM 或导航节点会在启动时直接报错。排查 TF 问题最直接的工具是:
ros2 run tf2_ros tf2_monitor这个命令会周期性输出所有 TF 变换的状态,方便检查哪个变换没有发布。在实际工程中,我还建议把机器人的 URDF 文件单独维护,不要和仿真器配置混在一起,方便在真机和仿真之间切换。
7.3 仿真到真机的注意事项
很多参数在仿真环境中能正常工作,迁移到真机会立刻失效。最典型的就是底盘运动学参数:仿真的 TurtleBot3 是理想化模型,没有轮子打滑、没有电机响应延迟、没有电池电压下降带来的推力减少。真机上需要重新标定里程计,确认odom话题输出的位移和实际位移一致,否则建图和导航都会出现严重漂移。
另外,仿真中激光雷达的数据是理想无噪声的,真机激光雷达需要标定外参和噪声参数。如果仿真和真机使用不同的雷达型号,Nav2 的代价地图参数也建议重新调整。我的建议是:仿真阶段重在理解整个系统的数据流,真机阶段再针对硬件特性逐项调优。
7.4 参数与配置管理
Nav2 的参数非常庞杂,如果每次都是改一点重启一次,会非常低效。建议把 Nav2 相关参数统一放到一个 yaml 文件中,并做好版本管理。例如,代价地图的膨胀半径、机器人底盘半径、最大速度限制等参数集中在一个nav2_params.yaml里。使用 Git 管理这些参数文件,记录每次调参的原因和效果,长期来看会节省大量时间。
同时要留意,Nav2 官方仓库会随发行版更新参数文件的版本。不同 ROS2 发行版之间,Nav2 参数的节点名、参数名可能有差异。因此,当你在网上下载到一份 Nav2 参数文件时,不要直接套用,先对比一下官方默认参数文件,确认节点名一致再使用。
8. 总结与学习路线
8.1 本文掌握了什么
到这一步,你已经完成了一条完整的 ROS2 移动机器人自主导航闭环:
- 用 Stage 2D 仿真器快速启动机器人。
- 使用 slam_toolbox 实时建图。
- 使用 map_saver 保存地图。
- 切换到 Gazebo/Ignition 3D 仿真器启动 Nav2 导航。
- 在 Rviz2 中发布目标点,完成自主导航与避障。
这个闭环最大的价值在于,它让你真正理解了 SLAM 和 Nav2 在整个机器人系统中的位置:SLAM 负责“对环境建模和对自身定位”,Nav2 负责“在地图中规划并执行移动”。二者通过地图、坐标变换和传感器话题紧密协作,而这种协作方式不会因仿真器或机器人硬件的变化而改变。
8.2 下一步可以继续钻研的方向
跑通基础链路之后,可以往以下几个方向深入:
- 参数调优:反复调整 Nav2 的代价地图膨胀半径、全局规划器算法(如 A*、Dijkstra)、局部规划器算法(如 DWB、Regulated Pure Pursuit),观察机器人路径质量和平滑度变化。
- 多传感器融合:在仿真中同时使用激光雷达和相机,引入视觉 SLAM 或激光视觉融合建图。
- 行为树与任务规划:学习 Nav2 中的行为树机制,通过 BehaviorTree.CPP 自定义机器人的复杂任务流程。
- 真实机器人部署:把仿真中跑通的建图与导航流程迁移到真实底盘上,关键是做好里程计标定、传感器外参标定和参数调整。
如果你在实践过程中卡住了,优先回看 TF 树、话题数据和use_sim_time这三个因素,多数问题都能从它们身上找到根源。希望这篇 ROS2 仿真建图与 Nav2 导航实战教程能帮你顺利打通机器人自主移动的第一段路,后续的进阶探索,就留给不断实践中的你了。