相信不少刚接触 ROS2 的同学都有过这种感觉教程刷了不少demo 也跑过几个但一台虚拟机器人到底怎么从“能走”变成“会认路”始终是一团迷雾。尤其是仿真、建图、导航这三个环节分开看都似懂非懂连在一起就不知道怎么串起来。这篇文章就是来解决这个问题的。我会用一套完整闭环的思路从 Stage 二维仿真环境讲起先用最快速度跑通 SLAM 建图再基于地图做 Nav2 自主导航最后扩展到 Ignition/Gazebo 这类三维仿真环境并补充 3D 激光雷达接入导航的常见做法。整个流程不需要真实机器人一台普通 Ubuntu 电脑就够了。如果你正在学习 ROS2 机器人开发或者准备从 SLAM 建图走向自主导航落地这篇文章可以作为你的一份手把手实操笔记。全程以 ROS2 Humble 为环境基准代码、参数、命令都会给出完整版本。1. 背景与核心概念从“仿真—建图—导航”到底在解决什么问题1.1 ROS2 到底是什么ROS2Robot Operating System 2是一套开源的机器人软件开发框架它并不是传统意义的操作系统而是一组用于构建机器人应用的通信中间件、工具库和生态规范。相比 ROS1ROS2 基于 DDS 通信支持多机通信、实时性更好、安全性更强也是当前机器人领域的主流开发平台。在 ROS2 里机器人的大脑被拆分成了很多独立节点例如传感器驱动节点、SLAM 节点、导航节点。这些节点之间通过话题、服务、动作等机制互相通信。比如激光雷达驱动会持续发布/scan话题SLAM 节点订阅/scan和里程计话题然后输出地图和机器人位姿。1.2 SLAM让机器人一边走路一边记地图SLAM 是 Simultaneous Localization and Mapping 的缩写中文一般叫“即时定位与地图构建”。它的核心问题可以这样理解机器人在一个完全陌生的环境中没有 GPS也不知道自己在哪里它要一边移动一边根据传感器数据判断“我在哪”同时把周围环境的地图画出来。听起来像鸡生蛋的问题定位需要地图建图需要准确位姿。SLAM 算法就是通过激光雷达、里程计、IMU 等传感器信息用概率估计的方式同时解决这两件事。在 ROS2 生态里常用的 2D SLAM 方案包括slam_toolbox、cartographer3D 场景还会用到 LIO-SAM、FAST-LIO 等不过那些偏研究向入门阶段从slam_toolbox入手最合适。1.3 Nav2建完地图之后才能谈导航SLAM 解决的是“地图从哪来”Nav2 解决的是“有了地图之后怎么走”。Nav2 是 ROS2 官方维护的导航堆栈它把导航任务拆成了多个独立模块全局规划、局部规划、定位、行为树控制等。用户只需要在 RViz2 中给一个目标点Nav2 就会输出速度指令到机器人底盘驱动它安全地走过去。注意Nav2 本身不做建图它的定位能力来自 AMCL自适应蒙特卡洛定位。也就是说导航阶段需要一张提前建好的静态地图机器人在运行中通过激光雷达和里程计在这张已知地图上实时估计自己的位置。1.4 Stage 与 Ignition两种仿真的定位差异仿真环境的价值在于让开发者在没有真实硬件的情况下就能验证算法。但不同仿真器的侧重点差异很大Stage是一个轻量级 2D 仿真器通常配合 ROS 使用。它的核心优势是“快”没有复杂物理引擎和三维渲染适合快速验证 SLAM、Nav2、多机器人调度等上层算法。Ignition / Gazebo是三维物理仿真器支持刚体动力学、多种传感器模型、真实光照和碰撞检测。它的仿真效果更接近真实环境但资源消耗也更高适合验证传感器融合、机械结构、真实底盘特性等场景。对于入门来说先用 Stage 跑通建图和导航流程再切换到 3D 仿真环境是一种很务实的学习路径。2. 环境准备Ubuntu 22.04 ROS2 Humble 安装与避坑2.1 系统要求和安装源本文以Ubuntu 22.04 ROS2 Humble为例。ROS2 目前没有官方的 Windows 完整支持绝大多数开发还是在 Ubuntu 下进行。如果你用的是其他 Ubuntu 版本需要换成对应的 ROS2 发行版但整体流程一致。安装前先把系统语言环境设置为 UTF-8避免后续编译中文路径或其他编码问题sudo apt update sudo apt install locales sudo locale-gen en_US en_US.UTF-8 sudo update-locale LC_ALLen_US.UTF-8 LANGen_US.UTF-8 export LANGen_US.UTF-8然后添加 ROS2 软件源。这一步很关键如果没有添加源就急着执行apt install ros-humble-desktop大概率会报E: unable to locate package ros-humble-desktop。sudo apt install software-properties-common sudo add-apt-repository universe 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如果你在国内网络环境下访问官方源比较慢可以把packages.ros.org换成合适的镜像地址例如清华、阿里等镜像站这里就不展开了。2.2 安装 ROS2 Humble 和开发工具执行以下命令安装桌面版 ROS2sudo apt update sudo apt install ros-humble-desktop sudo apt install ros-dev-toolsros-humble-desktop包含 RViz2、常用传感器驱动、demo 等ros-dev-tools提供colcon、rosdep等编译工具。接着配置环境变量echo source /opt/ros/humble/setup.bash ~/.bashrc source ~/.bashrc再安装本文后续要用的功能包sudo apt install ros-humble-nav2-bringup sudo apt install ros-humble-slam-toolbox sudo apt install ros-humble-teleop-twist-keyboard sudo apt install ros-humble-stage-ros2 sudo apt install ros-humble-gazebo-ros-pkgsnav2-bringup提供 Nav2 的启动脚本和参数模板slam-toolbox用于 2D SLAM 建图teleop-twist-keyboard是键盘控制节点stage-ros2是 Stage 仿真器的 ROS2 桥接包gazebo-ros-pkgs用于后续 3D 仿真。2.3 验证环境是否可用打开终端输入ros2 --help如果出现 ROS2 命令行帮助信息说明环境变量配置成功。再执行ros2 pkg list | grep stage ros2 pkg list | grep slam_toolbox如果能看到stage_ros2和slam_toolbox说明关键功能包已经安装到位。2.4 创建工作空间后续所有自定义代码、launch 文件、参数文件都放在同一个工作空间里这样便于统一编译和管理。mkdir -p ~/ros2_nav_ws/src cd ~/ros2_nav_ws colcon build source install/setup.bash这里先创建空的src目录后面我们会往里添加自定义功能包。3. Stage 2D 仿真最快启动机器人“感知运动”3.1 Stage 是什么Stage 是一个基于 2D 平面地图的机器人仿真器在 ROS 生态里历史悠久。它用激光扫描、里程计等抽象模型模拟机器人不渲染真实物理效果非常适合快速验证导航、SLAM 等上层算法。使用 Stage 的好处非常明显启动快占用资源低。传感器模型简单容易理解。非常适合教学和算法验证。缺点同样明显没有真实的动力学模型和传感器噪声仿真结果和真机差距较大。所以 Stage 适合入门和逻辑验证真机部署前还是需要更复杂的仿真或直接做硬件测试。3.2 快速启动一个 Stage 世界stage_ros2安装后会自带一些世界文件这些文件以.world结尾描述了仿真环境中的地图、墙壁、障碍物和机器人模型。先用下面命令查看有哪些可用世界ls /opt/ros/humble/share/stage_ros2/worlds/启动 Stage 仿真节点让它加载其中一个世界ros2 run stage_ros2 stage_ros2 /opt/ros/humble/share/stage_ros2/worlds/cave.world正常运行后终端会显示 Stage 的图形界面窗口中可以看到一个二维地图和机器人模型。此时机器人已经在虚拟世界里了但它还没有任何输入命令所以会停在原地。打开一个新终端查看当前有哪些话题ros2 topic list通常可以看到/odom、/base_scan、/cmd_vel等话题。其中/base_scan是激光雷达扫描话题/odom是里程计话题/cmd_vel是速度指令话题。不同版本的stage_ros2发布的话题名称可能略有差异以ros2 topic list实际输出为准。如果发现名字不是base_scan可以通过remapping把它重映射成/scan便于后续 SLAM 和 Nav2 使用。3.3 在 RViz2 中查看传感器数据新开终端启动 RViz2ros2 run rviz2 rviz2在 RViz2 左侧点击Add选择By topic然后添加LaserScan话题选择/base_scan或/scanTF查看机器人坐标变换关系RobotModel如果有模型描述否则可以不加。如果激光数据能显示出来说明 Stage 仿真环境已经和 ROS2 打通了。此时你会看到机器人周围的墙壁轮廓这就是 SLAM 建图的数据来源。3.4 手动控制机器人移动SLAM 建图不是原地不动就能完成的我们需要控制机器人在环境中遍历让激光雷达扫描到各个角落。新开一个终端运行键盘控制节点ros2 run teleop_twist_keyboard teleop_twist_keyboard终端会显示按键说明i前进j左转l右转k停止,后退按住按键机器人就会在 Stage 世界中移动。此时回到 RViz2可以看到激光雷达扫描范围随机器人移动而变化。这个阶段可以多熟悉一下控制手感为接下来的建图做准备。4. SLAM 建图用 slam_toolbox 把环境画出来4.1 SLAM 原理简化版在演示建图之前先建立一个简单的认知框架。2D 激光 SLAM 的输入有三个核心来源激光雷达扫描数据、里程计数据、IMU 数据。激光雷达告诉机器人“周围障碍物在什么方向多远”里程计告诉机器人“我大概走了多远转了多少度”。slam_toolbox的处理思路是把每一帧激光扫描结果与之前的地图进行匹配通过优化机器人位姿来让扫描数据与地图尽可能对齐然后把新扫描到的障碍物添加到地图中。常用的技术包括扫描匹配、图优化、回环检测等。建图过程中有一个核心概念叫TF它负责把不同坐标系关联起来。SLAM 算法需要知道map、odom、base_link、laser这几个坐标系之间的变换关系。Stage 仿真器通常已经发布了机器人模型和传感器坐标系所以不需要我们单独维护。4.2 配置 slam_toolbox 参数先在工作空间中创建功能包cd ~/ros2_nav_ws/src ros2 pkg create stage_nav --build-type ament_python --dependencies rclpy创建config和launch目录mkdir -p stage_nav/config stage_nav/launch然后在config/slam_toolbox.yaml中写入建图参数。以下是常用配置核心参数都有注释# 文件~/ros2_nav_ws/src/stage_nav/config/slam_toolbox.yaml slam_toolbox: ros__parameters: # 坐标系设置 map_frame: map odom_frame: odom base_frame: base_footprint scan_topic: /scan mode: mapping # 激光扫描参数 minimum_travel_distance: 0.0 minimum_travel_heading: 0.0 scan_buffer_size: 10 scan_buffer_maximum_scan_distance: 10.0 link_match_minimum_response_fine: 0.1 link_scan_maximum_distance: 10.0 # 建图相关 use_scan_matching: true use_scan_barycenter: true minimum_travel_distance: 0.1 transform_timeout: 0.2 # 回环检测 loop_match_minimum_chain_size: 10 loop_match_maximum_variance_coarse: 3.0 loop_match_minimum_response_coarse: 0.35 loop_match_minimum_response_fine: 0.45 # 地图发布 map_update_interval: 5.0 resolution: 0.05 max_laser_range: 12.0注意base_frame要根据 Stage 仿真器中实际发布的 TF 来确定。如果仿真环境的机器人坐标系名是base_link就把这里改成base_link。不确定时可以运行ros2 run tf2_tools view_frames或ros2 topic echo /tf查看。4.3 写一个建图启动文件为了让启动过程更简洁我们写一个 launch 文件把键盘控制、slam_toolbox 和 RViz2 串起来# 文件~/ros2_nav_ws/src/stage_nav/launch/slam.launch.py import os from launch import LaunchDescription from launch.actions import DeclareLaunchArgument from launch.substitutions import LaunchConfiguration from launch_ros.actions import Node def generate_launch_description(): slam_params_file LaunchConfiguration(slam_params_file) use_sim_time LaunchConfiguration(use_sim_time) return LaunchDescription([ DeclareLaunchArgument( slam_params_file, default_valueos.path.join( get_package_share_directory(stage_nav), config, slam_toolbox.yaml ), descriptionslam_toolbox 参数文件路径 ), DeclareLaunchArgument( use_sim_time, default_valuetrue, description仿真环境是否使用模拟时间 ), Node( packageslam_toolbox, executableasync_slam_toolbox_node, nameslam_toolbox, parameters[slam_params_file], outputscreen ), Node( packagerviz2, executablerviz2, namerviz2, outputscreen ), ])为了让get_package_share_directory能正常工作记得在setup.py中把config目录加入data_files# 文件~/ros2_nav_ws/src/stage_nav/setup.py 修改 data_files import os from setuptools import setup package_name stage_nav data_files [ (share/ament_index/resource_index/packages, [resource/ package_name]), (share/ package_name, [package.xml]), (os.path.join(share, package_name, launch), [launch/slam.launch.py]), (os.path.join(share, package_name, config), [config/slam_toolbox.yaml]), ]然后回到工作空间编译cd ~/ros2_nav_ws colcon build --packages-select stage_nav source install/setup.bash4.4 开始建图并保存地图整个建图流程分为三步。第 1 步启动 Stage 仿真环境单独终端ros2 run stage_ros2 stage_ros2 /opt/ros/humble/share/stage_ros2/worlds/cave.world第 2 步启动 SLAM 和 RViz2单独终端cd ~/ros2_nav_ws source install/setup.bash ros2 launch stage_nav slam.launch.py第 3 步用键盘控制机器人移动ros2 run teleop_twist_keyboard teleop_twist_keyboard在 RViz2 中把 Fixed Frame 设为map添加Map显示话题选择/map。然后开始控制机器人缓慢移动尽量走完整个环境。建议沿房间边缘绕行中间再穿插几次这样回环检测能更好地修正累积误差。建图完成后保存地图cd ~/ros2_nav_ws mkdir -p maps ros2 run nav2_map_server map_saver_cli -f maps/test_map运行结束后maps目录下会生成两个文件test_map.pgm地图图像文件黑白像素表示占据状态。test_map.yaml地图元数据文件包含分辨率、原点、占据阈值等信息。打开test_map.yaml看一眼image: test_map.pgm mode: trinary resolution: 0.05 origin: [-10.0, -10.0, 0.0] negate: 0 occupied_thresh: 0.65 free_thresh: 0.25image指向地图图片路径resolution表示每个像素对应的物理尺寸origin是地图在世界坐标系中的原点偏移。Nav2 启动时需要加载这个文件。4.5 地图文件解读保存出的test_map.pgm是一张灰度图黑色代表被占据的区域白色代表自由区域灰色代表未知区域。test_map.yaml中的occupied_thresh和free_thresh用来决定灰度值如何映射到占据概率。在导航阶段AMCL 定位需要这张静态地图。如果地图建得不完整比如某面墙缺失、走廊没扫全就会导致后续导航时机器人无法精确定位甚至把障碍物识别成自由空间。因此建图阶段一定要耐心尽量让机器人爬完整片区域。5. Nav2 自主导航加载地图、定位、规划、跟线5.1 Nav2 架构快速认知Nav2 是一个模块化导航系统由多个生命周期节点组成map_server加载静态地图发布/map。amcl基于粒子滤波实现定位把激光数据与地图匹配输出/amcl_pose。planner_server执行全局路径规划负责从机器人当前位置到目标点的宏观路径。controller_server执行局部路径规划输出实时速度指令避开动态障碍。bt_navigator用行为树组织导航任务流程例如“先全局规划再局部跟随到达后停止”。behavior_server负责一些特殊动作例如旋转恢复、后退恢复等。这个架构的优点是清晰解耦每一层都可以独立替换和调试。入门阶段不需要修改太多内部实现只需要理解“地图、定位、规划、控制”这条主线。5.2 Nav2 参数文件核心配置Nav2 的完整参数文件很长一般几百行。对于初学者不建议从零编写而是使用nav2_bringup自带的参数模板再按实际机器人修改。先找到模板文件ros2 pkg prefix nav2_bringup ls $(ros2 pkg prefix nav2_bringup)/share/nav2_bringup/params/里面会有nav2_params.yaml文件把它复制到我们的工作空间cp $(ros2 pkg prefix nav2_bringup)/share/nav2_bringup/params/nav2_params.yaml ~/ros2_nav_ws/src/stage_nav/config/然后打开这个文件重点查看和修改以下几项# 修改 AMCL 帧名与 Stage 仿真保持一致 amcl: ros__parameters: use_sim_time: True base_frame_id: base_footprint odom_frame_id: odom scan_topic: /scan beam_skip_distance: 0.5 beam_skip_error_threshold: 0.9 beam_skip_threshold: 0.3如果 Stage 仿真中的机器人坐标系是base_link就把base_frame_id改成base_link。另外AMCL 需要知道初始位姿后续会在 RViz2 中手动指定。中段参数可以保持默认planner_server和controller_server的默认配置已经能在 Stage 仿真中跑通。后续如果导航路径不够平滑可以再调整controller_server的max_vel_x、accel_lim_x等参数。5.3 用 navigation_launch.py 启动导航建图完成后先关掉 slam_toolbox 和键盘控制节点但保留 Stage 仿真继续运行。然后新开一个终端启动导航cd ~/ros2_nav_ws source install/setup.bash ros2 launch nav2_bringup navigation_launch.py \ map:~/ros2_nav_ws/maps/test_map.yaml \ params_file:~/ros2_nav_ws/src/stage_nav/config/nav2_params.yaml \ use_sim_time:true这个启动文件会拉起 map_server、AMCL、planner_server、controller_server、bt_navigator 等节点但不会启动 SLAM因为它依赖的是一张已经保存好的静态地图。如果你想更省事也可以使用localization_launch.py它会把定位和导航一起启动适合直接基于已有地图跑导航的场景。启动完成后再单独打开 RViz2ros2 run rviz2 rviz25.4 在 RViz2 中设置目标点RViz2 默认不会直接显示“目标点”工具需要手动添加 Nav2 面板。在 RViz2 顶部菜单点击Panels→Add New Panel选择Nav2。这时左侧会出现一个 Nav2 面板。然后点击面板上方的Localize按钮在机器人实际位置附近点击鼠标给机器人一个初始位姿估计。这一步非常重要因为 AMCL 需要知道“机器人大概在哪”才能开始定位。初始化完成后RViz2 中应该能看到一条以机器人当前位置为中心扩散出来的粒子云。粒子逐渐收敛后就说明定位成功了。接着点击Nav2 Goal按钮在地图上选择一个目标点拖拽出方向后松开鼠标。Nav2 会自动规划路径并驱动 Stage 中的机器人向目标点移动。如果一切正常RViz2 中会显示全局路径一条从当前位置到目标点的绿色线条局部路径机器人附近的彩色轨迹机器人不断跟随路径移动整个过程中可以用键盘控制节点或让机器人自动运动观察 AMCL 的粒子是否一直稳定收敛。5.5 导航失败的常见原因导航看似简单实际跑起来容易踩坑。常见现象和原因如下机器人定位后粒子发散说明初始位姿给的偏了或者地图与真实环境不匹配。全局规划失败常见原因是地图不完整目标点落在未知区域或被无效占据格挡住。机器人走走停停局部规划器认为前方有障碍物但实际并没有。这种情况通常是激光雷达坐标系或代价地图膨胀半径设置有问题。机器人原地旋转可能是控制器参数中速度、加速度限制过小导致规划路径无法被跟踪。遇到这些情况不要急着改代码先检查 TF 是否完整、地图分辨率是否合理、激光数据是否正确投影到代价地图上。6. Ignition 3D 仿真从 2D 到 3D 雷达导航进阶6.1 从 Stage 到 Ignition变化在哪里Stage 解决了“逻辑链路是否通”的问题但真实机器人是生活在三维空间里的。底盘打滑、地形起伏、雷达高度、传感器噪声这些 Stage 都无法模拟。因此当需要验证更接近真机的效果时就需要使用 3D 仿真器。在 ROS2 生态中Ignition新版本已更名为 Gazebo是主流的 3D 仿真方案。它内置物理引擎可以模拟刚体碰撞、重力、摩擦力也支持多种传感器插件包括 2D 激光雷达、3D 激光雷达、IMU、相机、深度相机等。ROS2 Humble 环境下官方支持 Gazebo Classic通过gazebo_ros_pkgs桥接和 Ignition Fortress。如果你的系统是 Ubuntu 22.04安装命令通常是sudo apt install ros-humble-gazebo-ros-pkgs sudo apt install ros-humble-ign-ros2-control6.2 3D 雷达接入 Nav2PointCloud2 转 LaserScan很多实际机器人搭载的是 3D 激光雷达例如速腾聚创、禾赛等产品输出的是PointCloud2点云数据。但 Nav2 的 2D 代价地图通常需要 2DLaserScan。解决办法是用pointcloud_to_laserscan将点云投影成 2D 激光扫描数据。安装转换工具sudo apt install ros-humble-pointcloud-to-laserscan假设 3D 雷达发布的点云话题是/cloud_points则启动转换节点ros2 run pointcloud_to_laserscan pointcloud_to_laserscan_node --ros-args \ -p target_frame:base_link \ -p transform_tolerance:0.1 \ -p min_height:-0.3 \ -p max_height:0.3 \ -p angle_min:-3.14 \ -p angle_max:3.14 \ -p angle_increment:0.0087 \ -p scan_time:0.1 \ -p range_min:0.2 \ -p range_max:20.0 \ -p use_sim_time:true \ --remap cloud_in:/cloud_points参数说明target_frame转换目标坐标系通常设置为雷达安装所在的坐标系。min_height/max_height只保留这一高度区间内的点云点用于过滤地面和顶部噪声。angle_min/angle_max激光扫描角度范围3D 雷达可以设置成 360 度。range_min/range_max有效测量距离范围。转换完成后/scan话题会被发布出来SLAM 和 Nav2 的配置完全不用改直接订阅/scan即可。这也是很多 ROS2 工程中“3D 雷达 2D 导航”的组合方案。6.3 用 3D 雷达做 SLAM 和导航的注意事项3D 雷达转 2D 扫描虽然好用但需要注意几个问题第一高度裁剪要合理。如果min_height和max_height设置太窄可能把低矮障碍物漏掉太宽又可能把桌边、斜面误判为障碍物。通常以机器人底盘高度为参考保留雷达上方 10 到 30 厘米左右的点云。第二帧率问题。3D 雷达点云数据量比 2D 激光大很多转换节点的计算成本也高。如果点云发布频率太高建议先降采样或者在转换节点中合理设置scan_time。第三如果要直接做 3D SLAM就不能只靠 2D 的slam_toolbox需要切换到cartographer的 3D 模式或者使用LIO-SAM、FAST-LIO这样的 3D 激光惯性里程计算法。这也是从入门走向进阶的一个重要方向。7. 常见问题排查清单问题现象常见原因解决思路apt install ros-humble-desktop报错找不到软件包ROS2 软件源未添加或未执行 update先添加 ROS2 软件源再执行sudo apt updateROS2 命令提示找不到环境变量未加载手动执行source /opt/ros/humble/setup.bashStage 启动后 RViz2 看不到激光数据话题名称不一致用ros2 topic list查看实际话题名必要时 remap 成/scanslam_toolbox 启动后无地图输出坐标系不匹配或 scan 话题为空检查map_frame、odom_frame、base_frame与 TF 是否一致建图保存后地图缺一大块机器人没有遍历到该区域重新建图控制机器人走遍环境所有角落Nav2 启动后 AMCL 粒子发散初始位姿给错或地图坐标系异常在 RViz2 中重新执行 Localize给出准确初始位姿导航规划失败地图不完整或目标点落在未知区域检查地图边界的 free/unknown 分布避免目标点设置过边界机器人撞墙后不重启代价地图未正确叠加激光数据查看/scan是否正常、成本图层配置是否加载了传感器3D 雷达转 2D 后导航还是异常高度裁剪范围设置不合理调整min_height、max_height并用 RViz2 可视化转换结果如果你遇到类似现象优先按照表格中的思路去排查。不要一上来就怀疑算法有问题很多情况下都是坐标系、话题名这类基础配置出了问题。8. 最佳实践与工程建议8.1 工作空间与参数管理不要把你的参数文件写得越来越长、越来越乱。建议按照功能划分目录~/ros2_nav_ws/src/stage_nav/ ├── config/ │ ├── slam_toolbox.yaml │ └── nav2_params.yaml ├── launch/ │ ├── slam.launch.py │ └── nav.launch.py ├── maps/ │ └── test_map.yaml └── package.xml参数文件最好用 Git 管理每次修改都留下记录。尤其是 Nav2 参数改一个速度上限可能导致整个导航表现完全不同没有版本记录就很难回退。8.2 用 ros2 bag 保存数据调试 SLAM 和导航问题时最有效的工具是录制数据包ros2 bag record /scan /odom /tf /tf_static /map /cmd_vel -o nav_debug录下来的 bag 可以在之后离线重放配合 RViz2 反复分析。尤其适合“真机测试时出现问题但当时没有足够时间盯屏幕”的场景。8.3 仿真到真机的核心提醒仿真跑通只是第一步真机部署会暴露出大量新的问题传感器噪声比仿真大很多参数不能直接照搬。里程计可能打滑、漂移需要融合 IMU。底盘执行速度指令存在延迟控制器响应时间需要实测。定位丢失时必须有恢复策略例如behavior_server的旋转恢复。另外真机测试前务必做好安全准备急停开关、最低速度限制、障碍物检测冗余逻辑。不要认为 Nav2 是万能的它仍然可能出现“规划路径没问题但小车撞上突发障碍”的情况。8.4 继续深入的方向跑通 Stage Nav2 之后你其实已经掌握了 ROS2 机器人开发的一条主链路。接下来可以从这几个方向继续深入学习行为树理解 Nav2 导航任务的完整逻辑。深入学习cartographer对比它与slam_toolbox的建图效果。尝试自己编写差分底盘仿真模型把 Stage 换成 Ignition/Gazebo 中的 URDF 模型。研究 3D 激光 SLAM 和视觉 SLAM进入更高阶的感知领域。给真实机器人装上 Nav2进一步验证参数和传感器模型。ROS2 的学习曲线确实不缓但当你亲手看着虚拟小车在仿真环境中自己规划路径并避障时那种满足感会让你觉得前面的所有折腾都值得。接下来要做的很简单照着本文的步骤先把自己电脑上的 ROS2 环境搭好跑通一个 Stage 世界再建一张完整的地图最后让 Nav2 带着机器人在仿真里自由巡航。每一步都是下一步的基础。动手吧仿真环境都搭好了接下来就看你想让机器人在虚拟世界里走到哪里。