拓冰建站拓冰建站
首页 / 资讯中心 / 正文

ROS2仿真到真机实战:激光雷达SLAM与导航开发

开篇先说实话很多人在学习 ROS2 的时候都会遇到一个很典型的断层——仿真里跑得好好的机器人一放到真机上就各种“不听话”要么是话题对不上要么是驱动没启动要么是传感器数据一上来就刷屏把节点卡死。这篇文章就是围绕“仿真 真机”这条完整链路来写的从零开始搭建 Ubuntu ROS2 环境用 VSCode 做远程开发在 Gazebo 里搭建带激光雷达的机器人仿真环境再把同一个思路移植到真机上实现传感器数据读取、速度控制、SLAM 建图与导航。无论你是准备入门 ROS2 的学生还是已经在做机器人项目、想系统梳理一遍开发流程的工程师这篇文章都能提供一套可以参考的落地路径。1. ROS2 仿真与真机的整体认知1.1 什么是 ROS2它解决什么问题ROS2Robot Operating System 2是机器人领域的分布式通信框架它不是传统意义上的操作系统而是运行在 Linux 等系统之上的一套中间件。它负责解决机器人的核心问题多个模块之间如何通信。一个完整的机器人通常包含传感器模块激光雷达、IMU、摄像头、编码器决策模块SLAM、导航、路径规划、运动控制执行模块电机驱动、底盘控制板如果没有统一的通信框架每个模块都要自己写一套数据交换协议模块之间耦合严重代码也很难复用。ROS2 通过“话题Topic”“服务Service”“动作Action”三种通信方式把各个模块解耦每个模块只负责发布和订阅消息整个系统的可维护性大幅度提升。同时ROS2 在 ROS1 的基础上改进了实时性、多机通信、安全性等底层设计更适合现代机器人产品落地。目前很多高校实验室、创业团队和开源机器人项目都已经全面转向 ROS2。1.2 仿真与真机的核心差异很多人第一次从仿真切到真机时最常见的困惑是“仿真里明明能跑为什么真机上就是不行”这里需要先明确一个概念仿真和真机的差异不在于“代码能不能跑”而在于“环境感知和执行反馈完全不同”。对比项仿真环境真机环境传感器数据理想化数据噪声小有噪声、有遮挡、有延迟底盘控制直接调用仿真接口即可需要驱动层涉及串口/通信协议时间同步仿真时间可控系统时间受硬件性能影响地图环境重新加载模型即可需要真实建图、保存、匹配安全风险程序崩溃无影响可能撞墙、损坏设备所以聪明的做法不是“仿真一套代码、真机一套代码”而是从架构上把代码分成几层驱动层负责读取真实传感器数据或从仿真环境接收模拟数据。算法层SLAM、定位、导航、避障这一层不关心数据来自仿真还是真机。控制层接收速度指令输出到底盘。只要接口统一算法层可以完全不修改切换的只是驱动层的数据来源。这也是“仿真 真机”实战中最重要的一条设计原则。1.3 一套代码从仿真到真机的关键设计要做到一套代码兼容仿真和真机核心是统一话题接口。比如激光雷达数据统一发到/scan里程计数据统一发到/odom速度指令统一订阅/cmd_vel仿真环境下Gazebo 插件会发布/scan和/odom我们通过cmd_vel控制仿真底盘真机环境下激光雷达驱动节点发布/scan底盘驱动节点读取/odom并订阅/cmd_vel。对上层导航算法来说它看到的接口是完全一致的。后面整个实战过程都会围绕这个思路来展开。2. 环境准备与版本说明2.1 操作系统与 ROS2 版本选型ROS2 目前主要有几个常用发行版Foxy Fitzroy支持 Ubuntu 20.04早期稳定版本Galactic Geochelone过渡版本支持 Ubuntu 20.04Humble Hawksbill支持 Ubuntu 22.04长期支持版本社区资料较多Iron Irwini较新的非 LTS 版本Jazzy Jalisco支持 Ubuntu 24.04较新版本以 2025 年的生态来看如果你使用的是 Ubuntu 22.04Humble 是比较稳妥的选择如果使用 Ubuntu 24.04可以关注 Jazzy。版本需要根据你的实际系统和项目依赖来定本文示例以“Ubuntu 22.04 ROS2 Humble”为常见环境但重点不在某个版本而在于搭建流程和调试思路。2.2 ROS2 安装方式官方 apt 与鱼香ROSROS2 的安装通常有两种方式方式一官方 apt 源安装先配置 apt 源再安装核心组件。大致流程如下sudo apt update sudo apt install software-properties-common sudo add-apt-repository universe sudo apt update sudo apt install ros-humble-desktop安装完成后需要 source 环境echo source /opt/ros/humble/setup.bash ~/.bashrc source ~/.bashrc方式二使用鱼香ROS一键安装如果你在下载和配置源时经常遇到网络超时、依赖解析失败可以使用鱼香ROS提供的一键安装脚本。它会自动完成换源、依赖安装、ROS2 安装和环境变量配置。wget http://fishros.com/install -O fishros . fishros执行后会出现一个交互菜单选择对应选项即可。这种方式对新手比较友好能省去不少环境配置的坑。但需要注意一键脚本会修改系统源和安装较多依赖建议在专用虚拟机或开发机上执行避免影响其他开发环境。2.3 工作空间与示例项目结构安装完成后建议先建立一个标准的工作空间。之后所有代码都在这个目录里管理。mkdir -p ~/ros2_ws/src cd ~/ros2_ws colcon build source install/setup.bashsrc目录下放功能包colcon build是 ROS2 的编译工具。如果提示找不到colcon可以先安装sudo apt install python3-colcon-common-extensions3. 远程开发环境搭建3.1 为什么推荐远程开发机器人项目的开发环境通常和运行环境是分开的。你的日常电脑可能是 Windows 或 macOS而机器人本体运行的是 Ubuntu上面挂着激光雷达、底盘驱动和一堆 ROS2 节点。如果每次都跑到机器人主机上插显示器、接键盘开发效率极低。远程开发的核心思路是代码放在机器人主机Ubuntu上本地 IDE 通过 SSH 远程打开代码编译、运行、看日志都在远程主机上执行这样既保证代码运行环境和机器人一致又保留了本地 IDE 的编辑体验。3.2 VSCode Remote-SSH 连接 Ubuntu推荐使用 VSCode 的 Remote-SSH 插件操作很简单在 VSCode 扩展市场安装 “Remote - SSH”。在本地命令行执行ssh ubuntu用户名机器人IP地址确认 SSH 能连通。在 VSCode 中按CtrlShiftP输入 “Remote-SSH: Connect to Host”选择或添加 SSH 主机。连接成功后左侧资源管理器会显示远程主机的文件系统直接打开~/ros2_ws即可。连接之后VSCode 会自动在远程主机上安装一个“远程服务器”本地安装的插件需要重新选择“在 SSH 主机中安装”比如 Python 插件、CMake 插件、ROS 插件等。这里有一个小技巧如果你的机器人主机和开发电脑在同一个局域网内直接使用局域网 IP 连接如果跨网络就需要配置端口转发或使用内网穿透工具实际项目中更推荐的还是局域网直连稳定且延迟低。3.3 远程可视化rviz2 与 Gazebo 图形界面远程开发时经常遇到一个问题机器人主机上启动了rviz2但在本地看不到图形界面。解决办法有以下几种方法一本地安装 rviz2订阅机器人主机的 ROS2 话题在本地电脑也安装对应版本的 ROS2然后配置ROS_DOMAIN_ID和 DDS 发现机制让本地rviz2作为第二台 ROS2 设备接入机器人系统。方法二使用 X11 转发在 SSH 命令中增加-X参数ssh -X 用户名机器人IP然后在远程终端启动rviz2图形界面会转发到本地。这种方式对网络要求较高通常需要局域网环境。方法三使用 VNC 或远程桌面在机器人主机上安装 VNC 服务通过 VNC viewer 连接到机器人桌面直接操作完整的 Linux 图形界面。适合可视化组件较多、转发性能不足的场景。我个人的习惯是日常开发用 VSCode Remote-SSH调试和可视化用 VNC两者不冲突。4. 仿真环境搭建与传感器仿真4.1 创建 ROS2 工作空间与功能包仿真环境的起点是创建一个机器人功能包后面所有模型、启动文件、节点都放在这个包里。cd ~/ros2_ws/src ros2 pkg create robot_sim --build-type ament_python这条命令会生成一个标准的 Python 功能包包含package.xml、setup.py、setup.cfg和robot_sim目录。为了让目录结构更清晰我们再手动创建几个子目录cd ~/ros2_ws/src/robot_sim mkdir -p urdf launch configurdf存放机器人模型文件launch存放 launch 启动文件config存放 rviz 配置、参数文件4.2 使用 Xacro 描述机器人模型Xacro 是 ROS 中常用的一种“宏定义 参数化”的 URDF 扩展格式。简单说URDF 文件里要写的重复 XML 片段可以用 Xacro 简化。下面是一个最简单的两轮差速底盘描述包含一个车体和一个二维激光雷达!-- 文件路径~/ros2_ws/src/robot_sim/urdf/robot.xacro -- ?xml version1.0? robot namerobot_base xmlns:xacrohttp://www.ros.org/wiki/xacro xacro:macro namerobot_base_macro !-- 车体 -- link namebase_link inertial mass value2.0/ inertia ixx0.01 ixy0.0 ixz0.0 iyy0.01 iyz0.0 izz0.01/ /inertial visual geometry box size0.4 0.3 0.1/ /geometry material nameblue/ /visual collision geometry box size0.4 0.3 0.1/ /geometry /collision /link !-- 激光雷达 -- link namelaser_link visual geometry cylinder radius0.05 length0.05/ /geometry /visual /link !-- 雷达固定在车体上方 -- joint namelaser_joint typefixed parent linkbase_link/ child linklaser_link/ origin xyz0 0 0.15 rpy0 0 0/ /joint /xacro:macro xacro:robot_base_macro/ /robot这个文件定义了机器人模型的两个刚体和一个关节base_link是底盘中心laser_link是雷达安装位置两个刚体通过laser_joint固定连接。4.3 在 Gazebo 中加载机器人并添加激光雷达要让 Gazebo 加载这个模型并且在仿真中产生激光雷达数据需要在 launch 文件里做几件事启动 Gazebo 空世界把机器人模型加载到参数服务器调用 Gazebo 的 spawn 服务把模型生成到仿真世界中给模型添加传感器插件常用的传感器插件是gazebo_plugins中的GaussianNoise激光插件。为了演示我们直接使用一个对新手友好的 libgazebo_ros2_laser 插件。修改robot.xacro在laser_link中加入传感器描述!-- 文件路径~/ros2_ws/src/robot_sim/urdf/robot.xacro 中 laser_link 部分增加 -- gazebo referencelaser_link sensor typeray namelaser_sensor pose0 0 0 0 0 0/pose visualizetrue/visualize update_rate10/update_rate ray scan horizontal samples360/samples resolution1/resolution min_angle0.0/min_angle max_angle6.283185307/max_angle /horizontal /scan range min0.12/min max10.0/max resolution0.01/resolution /range /ray plugin namelaser_controller filenamelibgazebo_ros2_ray_sensor.so ros remapping~/out:scan/remapping /ros output_typesensor_msgs/msg/LaserScan/output_type /plugin /sensor /gazebo这段配置的作用是把仿真雷达数据发布到/scan话题扫描角度从 0 到 2π即 360 度每圈采样 360 个点探测距离 0.12 米到 10 米。这些参数可以按实际需求调整。4.4 启动仿真并查看 /scan 话题接下来写一个 launch 文件把系统一次性拉起来。# 文件路径~/ros2_ws/src/robot_sim/launch/sim.launch.py import os from launch import LaunchDescription from launch.actions import ExecuteProcess from launch_ros.actions import Node from ament_index_python.packages import get_package_share_directory def generate_launch_description(): pkg_share get_package_share_directory(robot_sim) urdf_path os.path.join(pkg_share, urdf, robot.xacro) return LaunchDescription([ ExecuteProcess( cmd[gazebo, --verbose, -s, libgazebo_ros_factory.so], outputscreen ), Node( packagerobot_state_publisher, executablerobot_state_publisher, parameters[{robot_description: open( urdf_path, r).read()}], outputscreen ), Node( packagegazebo_ros, executablespawn_entity.py, arguments[-entity, robot_base, -x, 0, -y, 0, -z, 0.1], outputscreen ) ])启动之前先编译安装功能包cd ~/ros2_ws colcon build --packages-select robot_sim source install/setup.bash然后启动仿真ros2 launch robot_sim sim.launch.py在另一个终端查看话题列表ros2 topic list如果配置正确能看到/scan话题。打印几帧数据ros2 topic echo /scan --once如果一切正常你会看到range数组和angle_min、angle_max等字段说明仿真激光雷达已经在工作。5. 真机落地实操从传感器到节点5.1 真机硬件选型与接线从仿真迈向真机第一步是明确硬件。这里以最常见的“树莓派/工控机 差速底盘 二维激光雷达”组合为例。主控树莓派 4B 或者带有 Ubuntu 系统的工控机底盘带编码器的两轮差速底盘支持通过串口或 CAN 接收速度指令激光雷达常见的低成本二维激光雷达例如 RPLIDAR A1、A2 或其他 360 度扫描雷达具体型号需要以你手上的设备为准电源为保证稳定供电建议主控和底盘驱动分开供电共地连接接线时要注意雷达的 USB 转串口线插在主控上底盘控制板的通信线也接在主控上通信接口不要混插。很多新手遇到的“数据读不到”最后查出来的原因往往是 USB 端口权限问题。USB 端口权限可以这样解决sudo usermod -aG dialout $USER需要重新登录终端让用户组生效。5.2 激光雷达驱动与数据读取不同品牌的雷达驱动节点各不相同但最终目标是一致的把原始测距数据封装成sensor_msgs/msg/LaserScan消息发布到/scan话题。以常见的 RPLIDAR 系列为例ROS2 社区中已经有对应的驱动包sudo apt install ros-humble-rplidar-ros启动雷达驱动ros2 run rplidar_ros rplidar_composition然后验证数据ros2 topic echo /scan --once如果你的雷达不是 RPLIDAR也没关系思路是一样的找官方或社区提供的 ROS2 驱动包编译安装启动驱动节点确认/scan有数据这里要注意不同雷达的帧率、扫描频率、测距范围可能不同。比如有的雷达是 5Hz有的可以达到 10Hz 以上这些参数会影响后续 SLAM 和导航的效果建议在驱动配置中统一确认。5.3 订阅 /scan 并发布速度指令有了雷达数据之后下一步是写一个节点把底层底盘控制起来。底盘控制通常使用geometry_msgs/msg/Twist消息发布到/cmd_vel。Twist消息包含线速度和角速度底盘收到后会解析成左右轮差速。下面是一个最简单的控制节点示例让机器人原地旋转实现一个自动避障的雏形# 文件路径~/ros2_ws/src/robot_sim/robot_sim/avoidance.py import rclpy from rclpy.node import Node from sensor_msgs.msg import LaserScan from geometry_msgs.msg import Twist class AvoidanceNode(Node): def __init__(self): super().__init__(avoidance_node) self.publisher self.create_publisher(Twist, /cmd_vel, 10) self.subscription self.create_subscription( LaserScan, /scan, self.scan_callback, 10) self.subscription self.min_distance 0.5 def scan_callback(self, msg): # 取前方一定角度范围内的最小距离 front_ranges list(msg.ranges[0:30]) list(msg.ranges[-30:]) valid_ranges [r for r in front_ranges if r 0.0] if len(valid_ranges) 0: return min_range min(valid_ranges) cmd Twist() if min_range self.min_distance: cmd.angular.z 0.5 cmd.linear.x 0.0 else: cmd.linear.x 0.2 cmd.angular.z 0.0 self.publisher.publish(cmd) def main(argsNone): rclpy.init(argsargs) node AvoidanceNode() rclpy.spin(node) node.destroy_node() rclpy.shutdown() if __name__ __main__: main()这段代码的逻辑是读取/scan数据取机器人前方 30 度范围内的最小距离如果小于 0.5 米就原地旋转否则前进。实际项目中避障算法会更复杂但这个示例能帮你快速验证“传感器 - 算法 - 底盘”的完整链路。5.4 仿真与真机的切换策略前面的模拟节点接收的是仿真雷达数据现在你的雷达是真实雷达但代码不需要改动因为话题接口是一样的。唯一需要注意的驱动差异是数据来源谁是发布者谁接收仿真雷达Gazebo 激光插件avoidance / SLAM / Nav2真机雷达rplidar_ros 驱动节点avoidance / SLAM / Nav2因此要做的只是在真机上启动雷达驱动节点而不是 Gazebo。启动避障节点时它的算法逻辑和话题接口完全复用。这个设计思路就是前面反复强调的“驱动层隔离”。工程结构上建议把不同平台的启动文件分开launch/ ├── sim.launch.py # 仿真启动 ├── real.launch.py # 真机启动 └── common.launch.py # 算法节点启动common.launch.py只启动避障、SLAM、导航这类不关心数据来源的节点sim.launch.py和real.launch.py只负责启动数据源。这样切换平台时只需要选择不同的 launch 文件。6. 基于激光雷达的定位与导航初探6.1 激光雷达 SLAM 的基本流程当底盘可以接收速度指令、雷达能发布/scan数据后就可以进入机器人最核心的应用——SLAM 建图。SLAM 这个过程可以通俗理解为机器人一边移动一边把激光雷达扫描到的环境特征拼接起来同时估算自己在地图中的位置。常见的 2D SLAM 工具有slam_toolboxROS2 社区常用适合二维激光雷达建图配置简单CartographerGoogle 开源适合复杂环境但安装和调参门槛较高GMapping早期方案目前在新项目中较少使用对于入门和中小型室内机器人我比较推荐slam_toolbox因为它参数较少、文档清晰且对 ROS2 支持良好。6.2 使用 slam_toolbox 构建地图安装sudo apt install ros-humble-slam-toolbox启动 SLAM 节点时需要提供激光雷达话题、里程计话题和机器人坐标系关系。最简单的启动方式是在命令行直接传参数ros2 run slam_toolbox async_slam_toolbox_node \ --ros-args \ -p use_sim_time:false \ -p scan_topic:/scan \ -p odom_frame:odom \ -p base_frame:base_link \ -p map_frame:map如果你在仿真中测试需要把use_sim_time改为true让节点使用仿真时间。启动 SLAM 之后通过 rviz2 可以直观地看到地图构建过程rviz2在 rviz2 中手动添加Map显示话题选择/map就能看到激光雷达扫描出来的环境地图。此时需要控制机器人移动让雷达覆盖整个空间。手动控制可以用下面这样的命令ros2 topic pub /cmd_vel geometry_msgs/msg/Twist \ {linear: {x: 0.2, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 0.1}}移动过程中地图会一点点扩展。当建图完成后保存地图ros2 run nav2_map_server map_saver_cli -f ~/map这会生成map.pgm和map.yaml两个文件分别是地图图片和地图描述文件。6.3 使用 Nav2 做导航概念性说明有了地图下一步就是导航。ROS2 中常用的是 Nav2 导航栈。Nav2 的工作流程可以简化成三步接收目标点来自手动指定或上层调度结合地图和传感器数据做全局路径规划发布/cmd_vel控制底盘移动同时避障启动 Nav2 之前需要准备几个参数文件地图文件、代价地图参数、规划器参数、控制器参数。这些参数文件官方模板都有直接使用并修改关键项即可。ros2 launch nav2_bringup bringup_launch.py \ map:~/map.yaml在实际运行中Nav2 需要/scan、/odom、/tf等话题。如果你的底盘驱动没有发布可靠的里程计定位效果会大打折扣。这是 Nav2 落地中最容易失败的环节建议在接入 Nav2 之前先确认odom和tf的稳定性。导航是一个比较大的话题这篇文章里先不做过度展开。建议先把 SLAM 建图和底层控制跑通再逐步研究 Nav2 的参数调整。7. 常见问题与排查思路在实际动手过程中几乎每个人都会遇到几个“正常但很头疼”的问题。下面整理了一些高频问题按排查顺序给出思路。问题现象常见原因解决思路ros2命令找不到环境变量未 source执行source /opt/ros/humble/setup.bash并添加到.bashrccolcon build报错找不到包依赖包未安装检查package.xml中的depend逐个安装缺失依赖仿真中/scan没有数据模型没加载或插件配置错误检查 Gazebo 中是否生成了模型查看启动日志中的插件报错真机雷达 USB 读不到数据权限不足或驱动不对添加用户到dialout组重新插拔 USB确认设备节点是ttyUSB0还是ttyACM0tf找不到坐标变换缺失 static transform publisher在 launch 中增加robot_state_publisher或手动发布odom - base_linkSLAM 地图偏移严重里程计不准或时间不同步检查use_sim_time参数真机需要标定轮距和编码器VSCode Remote-SSH 连接慢DNS 回退或服务配置问题在 SSH 配置中设置ServerAliveInterval 60关闭本地代理变量Nav2 导航不走直线控制器参数不合适调整controller_server的 PID 参数检查速度限制和加速度限制除了表格里的问题我再补充几个实战中非常关键的排查要点。第一个是“先看话题再看参数”。无论遇到什么功能异常先确认话题有没有数据、频率是否正常ros2 topic hz /scan ros2 topic info /scanros2 topic hz会持续打印话题发布频率。如果频率是 0说明发布端有问题如果频率突然变成 0大概率是节点崩溃或通信中断。第二个是“多看日志少猜原因”。ROS2 的日志通常可以通过RMW_IMPLEMENTATION和RCUTILS_LOG_LEVEL调整。默认的 error 和 warn 级别已经能暴露大部分问题。启动节点时加上--verbose或查看终端输出比盲目改参数更有效。第三个是“仿真和真机分别保存配置”。前面提到use_sim_time这个参数仿真中必须设置为true真机通常设置为false。如果不注意真机上的 Nav2 会一直等待仿真时间表现就是“地图不动、机器人不动、话题无输出”排查很久才发现只是时间源的问题。8. 最佳实践与工程建议8.1 工程命名与目录规范ROS2 功能包命名建议使用小写字母和下划线不要使用大写。功能包和节点名称要有含义例如robot_base_driver、laser_scan_filter、nav_goal_publisher。虽然 ROS2 对命名没有强制约束但清晰的命名能减少沟通成本。目录结构建议按职责划分src/ ├── robot_base_driver/ # 底盘驱动 ├── robot_lidar/ # 雷达驱动 ├── robot_sim/ # 仿真模型与启动文件 ├── robot_navigation/ # 导航相关节点 └── robot_msgs/ # 自定义消息8.2 参数管理不要把所有配置硬编码在源码里。传感器的波特率、底盘的最大速度、雷达的最小测量距离、SLAM 地图的参数都应该放到 YAML 参数文件中。在 launch 文件中加载参数Node( packagerobot_navigation, executablenav_goal_publisher.py, parameters[os.path.join(pkg_share, config, nav_params.yaml)] )参数文件的分支管理也很重要。如果同一个功能包要运行在多台机器人上建议把设备独有参数放在独立 YAML 文件中不修改公共模板。8.3 日志与调试真机调试过程中ros2 topic echo和rqt_graph是两个非常好用的工具。rqt_graph可以用图形化的方式显示节点和话题之间的关系特别适合在启动多个节点之后检查通信链路是否完整。rqt_graph如果界面比较混乱可以选择只看/scan、/cmd_vel、/odom这几个关键话题快速定位“谁发布了、谁订阅了、链路有没有断”。8.4 安全与生产环境注意事项真机调试安全永远排在第一位。第一次跑真机时建议把底盘架起来让轮子悬空先验证速度指令是否正确再落地测试。使用手动急停开关一旦发现机器人异常移动立即切断底盘电源。激光雷达属于光学传感器避免阳光直射防止传感器损坏。编写代码时对底盘速度做限幅尤其是第一次测试时线速度不要超过 0.2m/s。涉及地图覆盖或系统参数修改时先备份原文件和原地图。8.5 代码可维护性尽量把节点逻辑拆小。一个节点只做一件事比如雷达驱动节点只负责读雷达、发布/scan底盘驱动节点只负责读里程计、订阅速度指令避障节点只做逻辑判断不关心底层数据来源导航节点只接收目标点输出速度指令节点之间用话题解耦后续替换任何一个模块都不影响其他节点。9. 从入门到落地的学习建议到这里你已经完整走了一遍“环境搭建 - 远程开发 - 仿真建模 - 真机驱动 - 激光雷达应用”的流程。这篇文章中你可以直接复用的部分包括ROS2 环境安装和问题处理思路VSCode Remote-SSH 远程开发配置思路一个带激光雷达的仿真机器人模型一个能完成避障的 Python 节点一套仿真与真机共用的代码结构下一步可以继续学习的方向我建议按顺序推进先把自己的底盘驱动彻底摸清楚包括里程计消息、TF 变换。在真机上跑通手动控制确认cmd_vel - 底盘 - 编码器 - odom闭环。用 slam_toolbox 在真实环境建一张图先不用追求精度重点是流程。研究 Nav2 导航参数逐项理解代价地图、路径规划、控制器的作用。逐步引入更复杂的传感器比如 IMU、摄像头做多传感器融合。在动手过程中建议把“用真机验证仿真逻辑”当作默认习惯。仿真能帮你快速验证算法思路但最终所有问题都会在真机上暴露。每次都先在仿真里跑通流程再上真机可以大幅缩短调试周期并降低设备损坏的风险。希望这篇文章能帮你少走一些弯路。如果你在配置或调试过程中遇到其他问题欢迎在评论区留下具体现象和日志信息我会根据实际情况继续补充和更新。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门