做移动机器人的朋友应该都有这种感觉调机器人就像带小孩从会站到会走路第一步永远是让它在仿真里动起来。这篇文章围绕一个非常具体的目标展开用ROS2 Humble Gazebo Classic从零搭建一台能用键盘控制的差分AGV模型。整个过程不需要实车不需要硬件一台装着Ubuntu 22.04的电脑就能完成。你会发现当你在终端里按下“i”键小车缓缓往前开出那一下才算真正摸到了移动机器人开发的门槛。这篇教程适合三类人刚装完ROS2 Humble不知道下一步该干嘛的入门者被网上复杂车模吓住、只想快速验证导航算法的人以及准备把AGV搬上真实硬件、现在先用仿真把逻辑跑通的工程师。文章按时间线复盘我的完整搭建过程包括环境怎么装、模型怎么写、插件怎么配、按键怎么按还包含我踩过的一堆深坑。内容尽量保姆级但我不啰嗦文档里抄来的废话只讲实际有用的东西。1. 整体方案设计与思路拆解1.1 为什么偏偏选Humble Gazebo Classic先说版本选择。ROS2 Humble是Ubuntu 22.04的原生LTS版本官方支持周期长这意味着你现在学的这套东西放两三年后照样能跑不用频繁折腾升级。很多教程一上来就让你装最新版但做机器人开发最怕的不是版本旧而是依赖不兼容。Humble的生态现在非常成熟遇到问题网上随便一搜就有答案踩坑成本极低。Gazebo这块要单独说清楚Gazebo Classic也就是Gazebo 11和新的GazeboIgnition/Garden那一套完全是两个东西。新版本在物理引擎、传感器渲染上确实更好但SDK还在快速演进插件API说变就变。对于“搭一台差速AGV跑仿真”这个需求Gazebo Classic 11配合gazebo_ros_pkgs文档全、案例多、可参考资料丰富是性价比最高的选择。你如果是纯新手先把这套跑通熟悉了ROS2的套路之后再迁移到新版本也不迟。1.2 差分AGV是怎么动起来的差分驱动顾名思义就是靠左右两个独立驱动轮的转速差来实现前进、后退和转向。设左轮线速度是v_l右轮线速度是v_r轮距是d那么车体中心线速度v (v_l v_r) / 2角速度ω (v_r - v_l) / d。左轮快右轮慢就右转左轮慢右轮快就左转两个轮子等速反向就是原地旋转。这个模型之所以经典是因为它数学简单、控制直观而且和工厂里大量使用的AGV底盘结构一致。后面代码里要做的事情就是把键盘发出的Twist消息线速度v加角速度ω换算成左右轮的转速驱动Gazebo里的物理模型运动再反过来从轮子状态推算出里程计信息。这套换算逻辑由Gazebo的差速插件包办我们要做的就是把参数配对。1.3 从按键按下到小车前进的完整数据链路先把整条链路在脑子里过一遍后面操作才不会乱。第一步用Xacro格式的机器人描述文件定义车辆外观和物理属性发布到/robot_description话题第二步robot_state_publisher节点把URDF里的关节状态转换成TF坐标变换第三步Gazebo加载模型并挂载gazebo_ros_diff_drive插件这个插件订阅/cmd_vel话题驱动左右轮运动同时发布/odom里程计话题以及odom到base_footprint的TF变换第四步teleop_twist_keyboard节点读取键盘按键把按键映射成Twist消息发布到/cmd_vel。整条链路就是键盘 →/cmd_vel→ 差速插件 → 左右轮关节 → 物理世界 → 里程计反馈。四个节点各司其职缺一个环节车都动不起来。搞清楚这条链路之后后面每个节出现问题你都能迅速定位而不是瞎猜。2. 环境准备与工具安装2.1 系统环境要求我用的是一台普通的x86_64台式机Ubuntu 22.04.3 LTS内存16GB显卡是NVIDIA GTX 1080。实际上这套组合对硬件要求真不高Gazebo Classic即使只用CPU渲染也能跑只是画面差点。建议内存8GB以上、硬盘预留20GB就够了。最关键的约束是系统版本ROS2 Humble官方只支持Ubuntu 22.04你要是用20.04老老实实换系统或者装Foxy。别在版本上硬折腾我在群里见过太多人在20.04上强行编译Humble的包最后编译了一晚上都没跑通纯属浪费生命。2.2 ROS2 Humble完整安装我推荐真机安装而不是Docker。你后面要开多个终端互相通信真机安装的ROS2环境变量和网络配置都是现成的少一层容器网络的坑。当然如果你不想把系统搞乱用Docker跑ros:humble镜像也完全可行只是要记得用--networkhost并统一ROS_DOMAIN_ID。这里给一份真机安装的完整命令# 1. 设置编码 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 # 2. 添加ROS2软件源 sudo apt install software-properties-common curl sudo add-apt-repository universe 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 # 3. 安装 sudo apt update sudo apt install ros-humble-desktop python3-colcon-common-extensions安装完成后把环境变量写进.bashrc省得每次开终端都要手动sourceecho source /opt/ros/humble/setup.bash ~/.bashrc source ~/.bashrc ros2 --version如果能看到类似ros2 2.x.x的版本号说明ROS2本体已经装好了。这里我额外强调一下python3-colcon-common-extensions一定要装后面编译工作空间全靠它。2.3 Gazebo Classic安装与配套插件Gazebo Classic 11不需要单独安装装ros-humble-gazebo-ros-pkgs时会把它一并带上这是新手最容易搞混的地方sudo apt install ros-humble-gazebo-ros-pkgs这个包集合包含三块内容gazebo_ros负责启动和节点通信gazebo_plugins提供各种传感器和差速插件gazebo_ros2_control是ros2_control集成相关的支持。装完后验证一下gazebo --version ros2 pkg list | grep gazebo如果能同时看到gazebo_ros、gazebo_plugins这些包说明环境OK。别忘了把下面几个常用工具一起装上后面每一步都会用到sudo apt install ros-humble-teleop-twist-keyboard ros-humble-xacro ros-humble-rviz22.4 键盘控制工具说明teleop_twist_keyboard是ROS官方维护的轻量工具它把键盘按键映射成geometry_msgs/Twist消息发布到/cmd_vel话题。默认按键规则i前进、j左转、l右转、逗号后退、k刹车按住Shift或Ctrl可以切换档位。装好之后可以先单独跑起来测试一下半条链路ros2 run teleop_twist_keyboard teleop_twist_keyboard再开一个终端ros2 topic echo /cmd_vel按一下i应该能在终端里看到linear.x变成0.5。看到这个输出就说明键盘这半边链路已经通了后面只需要把模型和插件接上。3. 从零编写差分AGV模型URDF/Xacro3.1 创建工作空间与功能包所有代码都放在工作空间里管理。我习惯用~/agv_ws作为工作空间根目录mkdir -p ~/agv_ws/src cd ~/agv_ws colcon build然后创建机器人描述功能包。这里强调一下模型文件通常放在agv_description这类功能包里而不是和算法包混在一起这是ROS社区的惯例也方便以后复用cd ~/agv_ws/src ros2 pkg create agv_description --build-type ament_cmake --dependencies urdf xacro mkdir -p agv_description/urdf agv_description/launch agv_description/config进入agv_description/urdf目录新建agv.urdf.xacro文件。为什么用Xacro而不是直接写URDF因为URDF本身不支持变量和宏你要改一个轮子尺寸就得手动改五六处数字用Xacro可以定义属性统一管理还能用宏函数复用左右轮的定义代码量直接砍半。3.2 车身与轮子的连杆设计一个完整的仿真模型每个link都要有visual可视化外观、collision碰撞体和inertial惯性参数三部分。新手容易漏掉inertial结果Gazebo加载后模型在空中乱飘或者直接掉穿地面就是因为没有质量属性。车身我设计成长0.5米、宽0.35米、高0.1米的长方体驱动轮半径0.075米、宽度0.04米轮距0.25米。下面是完整的Xacro文件我加了注释帮助理解?xml version1.0? robot xmlns:xacrohttp://www.ros.org/wiki/xacro nameagv !-- 全局可调参数 -- xacro:property namebase_length value0.5/ xacro:property namebase_width value0.35/ xacro:property namebase_height value0.1/ xacro:property namewheel_radius value0.075/ xacro:property namewheel_width value0.04/ xacro:property namewheel_separation value0.25/ !-- 底盘与地面的参考系 -- link namebase_footprint/ !-- 车身主体 -- link namebase_link visual geometrybox size${base_length} ${base_width} ${base_height}//geometry material namebluecolor rgba0.2 0.4 0.8 1.0//material /visual collision geometrybox size${base_length} ${base_width} ${base_height}//geometry /collision inertial mass value5.0/ inertia ixx0.05 ixy0.0 ixz0.0 iyy0.08 iyz0.0 izz0.05/ /inertial /link joint namebase_footprint_joint typefixed parent linkbase_footprint/ child linkbase_link/ origin xyz0 0 ${base_height/2} rpy0 0 0/ /joint !-- 左驱动轮定义 -- link nameleft_wheel_link visual geometrycylinder radius${wheel_radius} length${wheel_width}//geometry origin xyz0 0 0 rpy${pi/2} 0 0/ material nameblackcolor rgba0.1 0.1 0.1 1.0//material /visual collision geometrycylinder radius${wheel_radius} length${wheel_width}//geometry origin xyz0 0 0 rpy${pi/2} 0 0/ /collision inertial mass value0.5/ inertia ixx0.0003 ixy0.0 ixz0.0 iyy0.0001 iyz0.0 izz0.0003/ /inertial /link joint nameleft_wheel_joint typecontinuous parent linkbase_link/ child linkleft_wheel_link/ origin xyz0 ${wheel_separation/2} -${base_height/2} rpy0 0 0/ axis xyz0 1 0/ /joint !-- 右驱动轮定义 -- link nameright_wheel_link visual geometrycylinder radius${wheel_radius} length${wheel_width}//geometry origin xyz0 0 0 rpy${pi/2} 0 0/ material nameblackcolor rgba0.1 0.1 0.1 1.0//material /visual collision geometrycylinder radius${wheel_radius} length${wheel_width}//geometry origin xyz0 0 0 rpy${pi/2} 0 0/ /collision inertial mass value0.5/ inertia ixx0.0003 ixy0.0 ixz0.0 iyy0.0001 iyz0.0 izz0.0003/ /inertial /link joint nameright_wheel_joint typecontinuous parent linkbase_link/ child linkright_wheel_link/ origin xyz0 ${-wheel_separation/2} -${base_height/2} rpy0 0 0/ axis xyz0 1 0/ /joint /robot3.3 关节类型和坐标系方向的关键细节这里有几个细节容易翻车我单独拎出来说。第一驱动轮关节类型必须用continuous不能用revolute。continuous代表无限旋转的关节适合轮子revolute带角度限制轮子转到限位就卡住了。这是我见过新手最频繁的报错来源之一。第二圆柱体模型的默认轴向是Z轴但轮子要绕Y轴旋转所以visual里的rpy${pi/2} 0 0这一句必不可少它把圆柱转平让轮子的转动轴和Y轴对齐。很多人模型加载出来轮子竖着插在地里就是少了这一步。第三左右轮joint的origin中y坐标一正一负分别是${wheel_separation/2}和${-wheel_separation/2}表示左右对称分布在车身两侧。如果两个轮子写成了同一个方向加载后你会看到两个轮子重叠在一起非常诡异。第四惯性矩阵数值不能瞎写。长方体的惯性矩公式是I (1/12) * m * (a² b²)可以按这个估算也可以用在线计算器算。数值太离谱的话仿真时小车会抖得像筛糠一样。我为了省事左右轮的代码是复制粘贴后改名字的。如果你想更优雅可以用Xacro的宏功能封装一个轮子宏调用两次就行。代码更简洁也更好维护。3.4 在Rviz中可视化检查模型模型写完之后先不要急着上Gazebo在Rviz里检查一遍会更高效。先把Xacro展开成URDF看有没有语法错误cd ~/agv_ws colcon build source install/setup.bash ros2 run xacro xacro src/agv_description/urdf/agv.urdf.xacro /tmp/agv.urdf然后启动robot_state_publisher并打开Rvizros2 run robot_state_publisher robot_state_publisher /tmp/agv.urdf rviz2在Rviz左侧面板添加RobotModelFixed Frame选择base_footprint。如果一切正常你应该能看到一个蓝色长方体和两个黑色轮子。这时候还可以检查一下TF树是否完整左下角Add添加TF显示应该能看到base_footprint和base_link等坐标系。提示Rviz里看到轮子方向不对、位置偏移一定要在这步改好再进Gazebo。在Rviz里改模型是秒级反馈进了Gazebo每次都要重新加载世界效率低得多。4. 给AGV注入“生命”Gazebo差速插件配置4.1 gazebo_ros_diff_drive插件解析模型静态展示没问题接下来就是让它在Gazebo里动起来。关键的魔法全在gazebo_ros_diff_drive插件里。在agv.urdf.xacro的robot标签内、所有link和joint之后加上下面的插件声明gazebo plugin filenamelibgazebo_ros_diff_drive.so namediff_drive_controller ros namespace//namespace remappingcmd_vel:cmd_vel/remapping remappingodom:odom/remapping /ros left_jointleft_wheel_joint/left_joint right_jointright_wheel_joint/right_joint wheel_separation0.25/wheel_separation wheel_diameter0.15/wheel_diameter max_wheel_torque20/max_wheel_torque max_wheel_acceleration1.0/max_wheel_acceleration publish_odomtrue/publish_odom update_rate30/update_rate publish_wheel_tftrue/publish_wheel_tf /plugin /gazebo逐个参数说清楚它们在干什么left_joint和right_joint必须和URDF里的关节名完全一致差一个字符插件就找不到轮子。wheel_separation是左右轮接地点的横向距离也就是之前定义的0.25米。这个值直接影响转弯半径的计算填错的话小车转向会特别诡异。wheel_diameter是轮子直径这里填0.15等于2 * wheel_radius。max_wheel_torque是最大轮力矩单位N·m。数值太小的话小车轮子会打滑或者推不动太大又容易起步太猛。max_wheel_acceleration控制轮子起步和刹车的加速度上限值越大响应越激进。新手阶段用1.0比较稳妥温和。update_rate是插件更新频率也就是里程计发布频率。设30Hz已经满足大部分需求太低里程计会一跳一跳的。publish_wheel_tf会发布轮子关节的TF方便你直接在Rviz里观察轮子转动。4.2 里程计与坐标变换配置Gazebo里的坐标变换有两层很多人容易混淆我在这里专门理一遍。robot_state_publisher负责发布base_footprint、base_link以及左右轮关节之间的TF这些是模型内部的静态/关节变换。差速插件负责发布odom到base_footprint的变换这是里程计层级的变换表示机器人相对世界原点走了多远、转了多少度。odom坐标系就是AGV的“世界参考”初始时和base_footprint重合随着小车运动不断偏移。你在Rviz里如果想观察小车真实运动轨迹要把Fixed Frame设置成odom。如果设置成base_footprint你会看到车没动、世界在动那是另一个视角初学者经常被搞晕。Rviz里还能验证轮子是否真的在转。把Fixed Frame保持odom添加TF显示然后给小车发送一个转动指令你会看到wheel_link的坐标系在持续旋转。4.3 启动Gazebo并加载模型把模型加载进Gazebo需要走一条固定的流程先启动Gazebo服务器和客户端再启动robot_state_publisher发布模型描述最后调用spawn_entity把模型生成到仿真世界里。这些步骤每次都手敲太麻烦我直接写了一个launch文件一次性搞定。在agv_description/launch目录下新建gazebo.launch.pyimport os from launch import LaunchDescription from launch.actions import IncludeLaunchDescription from launch.launch_description_sources import PythonLaunchDescriptionSource from launch_ros.actions import Node from ament_index_python.packages import get_package_share_directory import xacro def generate_launch_description(): pkg_gazebo_ros get_package_share_directory(gazebo_ros) pkg_description get_package_share_directory(agv_description) xacro_file os.path.join(pkg_description, urdf, agv.urdf.xacro) robot_description xacro.process_file(xacro_file).toxml() return LaunchDescription([ IncludeLaunchDescription( PythonLaunchDescriptionSource( os.path.join(pkg_gazebo_ros, launch, gazebo.launch.py) ), launch_arguments{verbose: true}.items(), ), Node( packagerobot_state_publisher, executablerobot_state_publisher, parameters[{robot_description: robot_description}], ), Node( packagegazebo_ros, executablespawn_entity.py, arguments[-topic, robot_description, -entity, agv], outputscreen, ), ])编译并启动cd ~/agv_ws colcon build source install/setup.bash ros2 launch agv_description gazebo.launch.py如果一切顺利Gazebo窗口会出现你的AGV车身稳稳地停在灰色地面上。注意观察一个细节小车应该自然下落几毫米然后稳稳站住如果它沉到地里或者弹到空中说明collision和inertial配置有问题。4.4 控制视角与状态查看模型加载后先用话题检查确认插件正常工作ros2 topic list应该能看到/cmd_vel、/odom、/robot_description、/clock等话题。/clock是Gazebo的仿真时钟ROS2仿真里时间同步全靠它。再看里程计有没有持续发布ros2 topic echo /odom --once这条命令会输出当前位姿。车没动的时候position.x和position.y都应该是0orientation的w是1。此时可以先用一个简单的命令行指令让小车动一下试试水ros2 topic pub --once /cmd_vel geometry_msgs/msg/Twist {linear: {x: 0.2}, angular: {z: 0.0}}如果车轮转动起来、小车向前移动说明插件工作正常。看到小车真的动起来说明最难的环节已经迈过去了。注意用top pub发一次指令后小车的速度会是0.2而不是自动归零因为速度指令是持续生效的。要停车就再发一个全零的Twist。这也是为什么后面用键盘控制时松开按键不代表停车必须按k键手动刹车。5. 键盘控制实操让AGV动起来5.1 启动仿真与键盘控制节点模型能动了接下来就把键盘接上。整个过程只需要两个终端。终端一启动仿真终端二启动键盘节点# 终端1 cd ~/agv_ws source install/setup.bash ros2 launch agv_description gazebo.launch.py # 终端2 source /opt/ros/humble/setup.bash # 如果还没写进.bashrc source ~/agv_ws/install/setup.bash ros2 run teleop_twist_keyboard teleop_twist_keyboard键盘节点启动后终端里会显示一张按键说明图写着“Control Your Robot!”之类的内容。这时候你的AGV已经处于待命状态按任意方向键就会动。这里提醒一个容易忽略的点如果终端2直接运行teleop_twist_keyboard时报错找不到命令多半是少source了/opt/ros/humble/setup.bash。而如果你的AGV话题不在默认域里还要确认两个终端的ROS_DOMAIN_ID一致否则键盘发的消息根本到不了Gazebo那边。5.2 teleop_twist_keyboard按键说明与参数调整键盘工具默认的键位是这样i/j/l/逗号分别对应前/左/右/后k是停车q/z是加速和减速档位u/o/m/句号是斜向运动。按住Shift会变成大幅度转向按住Ctrl会变成小步微调。默认线速度0.5 m/s、角速度1.0 rad/s对初学阶段偏快了一点。我建议在启动时把速度调低这样即使误操作也不至于瞬间冲出视野ros2 run teleop_twist_keyboard teleop_twist_keyboard --ros-args -p speed:0.25 -p turn:0.6speed对应线速度turn对应角速度。0.25 m/s的速度下小车从画面一端到另一端要好一会观察转向和里程计变化都从容很多。实际操作有个体验很微妙按i小车前进松开后发现它还在慢慢滑行。这不是bug而是因为teleop_twist_keyboard发送的是速度指令没有惯性消失的概念。想让它停住就按k或者再按一次反向键抵消。5.3 数据流验证与调试键盘控制跑通之后强烈建议做一次完整的数据流验证。我喜欢用rqt_graph看全貌rqt_graph图形化界面里能看到节点和话题的连线/teleop_twist_keyboard发布到/cmd_vel/gazebo节点订阅/cmd_vel并发布/odom/robot_state_publisher发布TF。如果哪根线断了画面里就能直观看到。接着开第三个终端验证里程计数据ros2 topic echo /odom让小车走直线你应该看到pose.pose.position.x持续增大。让小车转弯pose.pose.orientation.z和w会发生变化这是偏航角的四元数表示。如果走了直线但position.x没变或者转了90度但orientation没变化说明差速插件参数或者TF配置出问题了回第4节逐个排查。5.4 扩展方向加传感器和硬件接入键盘控制跑通只是第一步这个AGV模型最大的价值是后续扩展空间很大。想加传感器很简单。在Xacro里的base_link上挂一个激光雷达link再在gazebo标签里加gazebo_ros_ray_sensor插件就能发布/scan点云话题配合nav2跑自动导航。加相机就用gazebo_ros_camera插件发布/image_raw话题配合YOLO做视觉识别。这些插件的用法和差速插件类似都是“模型文件里加linkgazebo标签里加plugin”套路学会一个就全会了。如果你准备把仿真搬到真实硬件上现在流行的方案是micro-ROS ESP32。ESP32通过micro-ROS Agent和ROS2桥接订阅/cmd_vel驱动真实电机再把编码器数据发布成/odom。仿真里的逻辑全部复用只需要把Gazebo插件换成硬件驱动节点这也就是很多无人车团队“仿真先行”的开发方式。6. 常见问题与排查技巧实录6.1 Gazebo黑屏或者模型加载不出来黑屏最常见的两种情况一种是真的渲染失败一种只是加载慢。Gazebo首次启动需要加载大量模型资源卡在蓝屏或者灰屏半分钟是正常的耐心等等。如果一直黑屏判断是不是显卡驱动问题可以先试软件渲染export LIBGL_ALWAYS_SOFTWARE1模型加载不出来则要检查环境变量。Gazebo会在GAZEBO_MODEL_PATH里找模型如果你自己定义了mesh文件路径却忘了设置就会出现模型缺失。至少确认你source了工作空间echo $GAZEBO_MODEL_PATH如果这条命令为空说明你根本没source过install目录。launch文件里如果手动加载了模型排查顺序是Gazebo服务起来了没有 → robot_description话题有没有内容 → spawn_entity有没有报错。用ros2 topic echo /robot_description就能判断模型描述是否发布成功。6.2 轮子不动或者原地打转轮子不动先确认有没有成功订阅/cmd_velros2 topic info /cmd_vel -v-v参数会列出发布者和订阅者。发布者应该是/teleop_twist_keyboard订阅者应该是/gazebo。如果缺了订阅者说明插件没被加载去检查插件文件名、关节名拼写还有gazebo标签是不是放在了robot根节点下。原地打转或车轮方向相反十有八九是关节轴方向问题。URDF里左右轮joint的axis都是0 1 0也就是绕Y轴正方向旋转。如果右轮实际是倒转最简单的验证方法发布一个线速度为0、角速度为正的指令看车是左转还是右转反了就调换对应joint里axis的正负号或者把轮子link的origin旋转方向反过来。小车抖动像痉挛多半是惯性矩阵数值异常或者update_rate设得太高。检查inertial里的数值是不是数量级不对然后把update_rate从30降到20试试。6.3 键盘控制无响应经典排查顺序先用ros2 topic echo /cmd_vel确认键盘节点在发布再确认话题名拼写有没有对错。teleop_twist_keyboard默认发布到/cmd_vel但如果你在launch文件里改了命名空间或者重映射就会对不上。在两个节点都能正常启动的情况下剩下大概率是ROS_DOMAIN_ID不一致。ROS2在不同域里通信互相隔离两个终端的ROS_DOMAIN_ID必须一样。另一个隐蔽问题终端里运行键盘节点时如果shell焦点不在那个终端按键无效。这是老生常谈但总有人踩键盘输入只认当前获得焦点的终端窗口。6.4 速度指令发出去了但车不动如果/cmd_vel和/odom都有数据轮子却不动问题出在模型物理参数。最常见的是轮子悬空了collision几何没对齐轮子根本没接触地面但视觉上看不出来。解决方法是在Gazebo左侧世界面板里选中左右轮查看它们的碰撞体是否与地面接触或者把base_link的origin z坐标调低一点试试。还有一种情况是max_wheel_torque太小物理引擎算出来的轮力矩不足以推动车身。把力矩从20调到50加速度从1.0调到2.0多数情况能解决。这个参数在真实机器人上要对应电机选型但在仿真里大胆调节没问题。6.5 仿真卡顿和性能优化Gazebo Classic的物理引擎是单线程的负载高的时候掉帧很常见。我实测遇到卡顿优先把update_rate降下来、把max_wheel_acceleration调低效果立竿见影。如果还是卡可以直接关掉Gazebo的3D渲染窗口用Rviz查看小车状态Gazebo GUI只是调试用的不是必需品ros2 launch agv_description gazebo.launch.py gui:false配合rviz2使用性能和可视化体验反而更好。6.6 常见问题速查表现象可能原因处理办法Gazebo黑屏显卡驱动/软件渲染设置LIBGL_ALWAYS_SOFTWARE1模型不显示未source工作空间source install/setup.bash轮子不动插件未加载/关节名拼错检查plugin声明与topic info轮子反向旋转joint轴方向错误调换axis正负号键盘无响应焦点不对/话题名不匹配/域不一致检查终端焦点和topic信息车抖得厉害惯性矩阵异常/update_rate过高修正inertial数值降update_rate车穿透地面collision缺失或位置偏移检查collision几何与origin7. 一些写给新手的额外建议最后分享几点我自己的体会。第一个建议是要养成“单点验证”的调试习惯。无论哪一步出问题先判断是模型问题、话题问题还是插件问题用ros2 topic echo、rqt_graph这些工具看到数据再动手改不要凭感觉乱改参数。一次只改一个变量改完立刻验证这条原则能帮你省下大量瞎折腾的时间。第二个建议是这套仿真模型是你后续所有工作的地基。现在花点时间把URDF参数轮距、轮径、质量调得尽量贴近真实底盘后面做导航、做SLAM时就不用回头改模型。我自己的AGV就是从这一模一样的仿真模型起步最后跑通了导航和避障整个过程比直接上车调试顺畅太多。第三个建议是一定要自己动手敲一遍Xacro不要直接复制粘贴。URDF/Xacro的结构只有自己写过一遍才能理解树形层级关系以后无论是加传感器还是改底盘结构你都能一分钟定位到该改哪一行。反正代码总共就一百来行半小时就能敲完这笔投入绝对值。如果你在搭建过程中卡住了欢迎带着报错信息和我讨论。能看到小车在键盘控制下平稳移动你就算真正迈进了移动机器人开发的大门后面的路会越来越有趣。
阅读完成 · 觉得有帮助?