FEATURED · 精选文章

ROS2 URDF导入Gazebo:从静态模型到物理驱动全解析

发布时间 / 2026/9/1 3:30:54
来源 / 创域科博编辑部
栏目 / 资讯中心
ROS2 URDF导入Gazebo:从静态模型到物理驱动全解析 很多初学者第一次接触 ROS2 URDF 时会遇到一个非常典型的分水岭在 Rviz2 里机器人模型展示得很漂亮关节树、TF 都没有问题但同一份 URDF 放进 Gazebo要么模型直接消失要么一启动就掉进地面要么轮子悬空、机器人纹丝不动。这不是某一行配置写错了而是很多人没有意识到URDF 进 Rviz 和 URDF 进 Gazebo 根本是两回事。从 ROS2 的角度看URDF 只是机器人的运动学描述它负责告诉系统这个机器人有哪些刚体、哪些关节、坐标系怎么连接、外观长什么样。而 Gazebo 是物理仿真器它需要知道这个机器人每个刚体有多重、质心在哪、碰撞体是什么、关节是否带驱动、与地面接触时摩擦系数是多少。这些信息在 Rviz 里统统不重要但缺了它们Gazebo 里的机器人就是一堆没有重量的“空壳”。这篇文章以 Ubuntu 22.04 ROS2 Humble 为例从零手写一个最小差速底盘 URDF逐步讲解如何正确导入 Gazebo并让它具备物理属性、能够通过 ros2_control 驱动。读完你应该能判断自己的 URDF 在 Gazebo 里为什么散架、为什么不动以及如何用最小配置跑通一个完整仿真流程。1. 这篇文章真正要解决的问题很多人把 URDF 建模想简单了在 CSDN 和各类技术群里最常见的一个问题是为什么我的 URDF 在 Rviz2 里一切正常但用spawn_entity.py放到 Gazebo 后要么没有反应要么机器人直接掉进地里这个问题的本质是 URDF 里缺少 Gazebo 需要的三个核心信息每个 link 的collision 碰撞体。每个 link 的inertial 惯性属性。每个运动关节对应的驱动接口以及 Gazebo 插件。如果你只是用visual标签画了一个boxGazebo 能显示这个盒子但它不认为这是一个可参与碰撞的刚体自然会被重力“穿透”到地面以下。更隐蔽的问题是即使你补了collision却给了一个不合理的惯性矩阵机器人启动后依然会出现剧烈抖动、弹飞、翻滚等怪异现象。这篇文章不会用一个现成的机器人模型包直接跑而是带你从语法层面理解每一行 URDF 的作用再用最小例子验证。这样的好处是以后你无论拿到的是从 SolidWorks 导出的 URDF还是从 xacro 拼出来的复杂机器人都知道问题出在哪个环节。读完本文你会获得三样东西一套能跑通“URDF - Gazebo 生成机器人”的最小工程。对 collision、inertial、ros2_control 之间关系的清晰理解。一张常见问题排查表覆盖用户平时遇到最多的几个故障。2. 理解 URDF、Gazebo 与物理仿真的关系2.1 URDF 只描述“长什么样”不描述“怎么物理运动”URDF 的英文全称是 Unified Robot Description Format也就是统一机器人描述格式。它本质是一个 XML 文件用link和joint描述机器人。link表示机器人的一个刚体比如底盘、左轮、右轮、机械臂的连杆。joint表示两个 link 之间的连接关系比如左轮和底盘之间的旋转关节。每个link可以有visual和collision两个几何描述。关键点来了visual只负责显示决定你在 Rviz2 或 Gazebo 里看到什么。collision负责参与物理碰撞计算决定机器人会不会被地面挡住会不会撞到障碍物。inertial决定这个 link 的质量、质心位置、惯性张量Gazebo 计算重力、加速度、反作用力全靠它。很多从 SolidWorks 导出的 URDFvisual非常完整但collision和inertial要么没有要么是导出的默认值。所以这类模型放到 Rviz2 里完美放到 Gazebo 里立刻出问题。2.2 Gazebo 需要什么collision、inertial 与 pluginGazebo 不是一个简单的 3D 渲染器它内置了物理引擎默认使用 ODE。物理引擎要计算每个刚体之间的碰撞和约束所以它不会直接使用visual网格而是用collision指定的简化几何体。这是因为精细的 STL 网格做碰撞检测计算量太大通常会用圆柱、长方体、球体来近似。另外每个刚体必须有质量。如果某个link没有指定inertialGazebo 在加载模型时会认为它的质量趋近于零。一个质量为零的刚体在物理引擎中数值不稳定于是就会出现机器人“莫名其妙飞出去”或者“陷入地面”的情况。Gazebo 还需要插件来感知机器人。URDF 里的gazebo扩展标签可以加载两方面内容给机器人添加传感器比如 IMU、Camera、Lidar。给机器人添加系统插件比如gazebo_ros2_control让 ROS2 控制器能与 Gazebo 中的关节驱动接口互通。这也就解释了另一个常见问题为什么我在 Gazebo 里用ros2 topic pub /cmd_vel发速度机器人完全不动。因为机器人根本没有加载驱动插件关节只是运动学上允许旋转但物理上没有电机或驱动器在响应指令。2.3 xacro 是工程化标配手写一个 10 行的 URDF 还能接受但真实机器人可能包含几十个 link、上百个 joint。如果直接在 URDF 里写死坐标和角度后续想调整轴距、轮径、质量就要全文搜索替换非常痛苦。xacroXML Macros是为解决这个问题而生的。它允许你在 URDF 中使用变量、数学表达式、宏和条件语句。比如轮距和轮径可以定义为变量关节坐标用表达式计算重复出现的传感器结构可以用宏复用。在本文第 4 节我会先手写纯 URDF因为它最直观能帮助你理解每个标签。但到了第 8 节我会建议你尽快切到 xacro 工程化写法。3. 环境准备与版本选择3.1 ROS2 发行版与 Gazebo 的搭配不同 ROS2 发行版对应不同的 Ubuntu 版本和 Gazebo 版本。这里以最常用的组合为例组件本文推荐备注Ubuntu22.04长期支持版本ROS2Humble对应 Ubuntu 22.04资料最丰富GazeboGazebo Classic 11ros-humble-gazebo-ros-pkgs默认依赖Rviz2随 ROS2 附带用于显示 TF 和模型验证阶段使用如果你用的是 Ubuntu 24.04 ROS2 JazzyGazebo Classic 的默认安装方式已经不同本文的方案可能需要微调。但核心思路是一致的先确认 ROS2 版本、再安装对应的 gazebo_ros 集成包。3.2 安装常用工具包在开始之前确保已经安装好 ROS2 Humble。如果没有请先完成基础安装。# 基础依赖如果已经装过 desktop可以跳过 sudo apt install ros-humble-desktop # Gazebo 相关 sudo apt install ros-humble-gazebo-ros-pkgs # ros2_control 相关 sudo apt install ros-humble-ros2-control ros-humble-ros2-controllers # URDF 校验工具 sudo apt install liburdfdom-tools # 后续会用到的工作区依赖 sudo apt install python3-colcon-common-extensions安装完成后验证一下环境source /opt/ros/humble/setup.bash ros2 pkg list | grep gazebo ros2 pkg list | grep ros2_control如果能看到一组gazebo_ros、gazebo_ros2_control相关包说明安装成功。接下来创建你的工作区mkdir -p ~/robot_ws/src cd ~/robot_ws colcon build source install/setup.bash下面的示例都会以robot_ws作为项目根目录。4. 用手写一个最小 URDF 机器人模型4.1 目标与关节设计我们做一个最简单的轮式差速底盘包含三个 linkbase_link底盘本体。wheel_left_link左轮。wheel_right_link右轮。两个 joint 都是continuous类型轴方向朝 Y 轴轮子绕 Y 轴旋转。这样当左右轮同向旋转时机器人沿 X 方向前进左右轮差速时机器人转向。坐标系约定X 轴机器人前进方向。Y 轴机器人左侧。Z 轴机器人上方。底盘尺寸长 0.4 米X 方向。宽 0.3 米Y 方向。高 0.1 米Z 方向。轮子半径 0.1 米宽度 0.05 米。左右轮距离底盘中线的偏移量是 0.2 米和 -0.2 米。4.2 URDF 文件细节创建文件~/robot_ws/src/robot_bringup/urdf/simple_robot.urdf?xml version1.0? robot namesimple_robot !-- 底盘 -- link namebase_link visual origin xyz0 0 0 rpy0 0 0/ geometry box size0.4 0.3 0.1/ /geometry material nameblue color rgba0.2 0.2 0.8 1.0/ /material /visual collision origin xyz0 0 0 rpy0 0 0/ geometry box size0.4 0.3 0.1/ /geometry /collision inertial mass value2.0/ origin xyz0 0 0 rpy0 0 0/ inertia ixx0.025 ixy0.0 ixz0.0 iyy0.035 iyz0.0 izz0.025/ /inertial /link !-- 左轮 -- link namewheel_left_link visual origin xyz0 0 0 rpy0 0 0/ geometry cylinder radius0.1 length0.05/ /geometry material namegray color rgba0.3 0.3 0.3 1.0/ /material /visual collision origin xyz0 0 0 rpy0 0 0/ geometry cylinder radius0.1 length0.05/ /geometry /collision inertial mass value0.5/ origin xyz0 0 0 rpy0 0 0/ inertia ixx0.001 ixy0.0 ixz0.0 iyy0.001 iyz0.0 izz0.001/ /inertial /link !-- 右轮 -- link namewheel_right_link visual origin xyz0 0 0 rpy0 0 0/ geometry cylinder radius0.1 length0.05/ /geometry material namegray color rgba0.3 0.3 0.3 1.0/ /material /visual collision origin xyz0 0 0 rpy0 0 0/ geometry cylinder radius0.1 length0.05/ /geometry /collision inertial mass value0.5/ origin xyz0 0 0 rpy0 0 0/ inertia ixx0.001 ixy0.0 ixz0.0 iyy0.001 iyz0.0 izz0.001/ /inertial /link !-- 左轮关节 -- joint namewheel_left_joint typecontinuous parent linkbase_link/ child linkwheel_left_link/ origin xyz0 0.2 0 rpy0 0 0/ axis xyz0 1 0/ /joint !-- 右轮关节 -- joint namewheel_right_joint typecontinuous parent linkbase_link/ child linkwheel_right_link/ origin xyz0 -0.2 0 rpy0 0 0/ axis xyz0 1 0/ /joint /robot你可能注意到我给每个inertial都加了一组惯性张量。这里的数值不是随意写的而是用长方体、圆柱体近似公式估算出来的。比如底盘是一个0.4 x 0.3 x 0.1、质量 2kg 的长方体ixx (1/12) * m * (wy^2 wz^2) iyy (1/12) * m * (wx^2 wz^2) izz (1/12) * m * (wx^2 wy^2)这里 wx、wy、wz 分别是长、宽、高。实际项目中不需要精确到小数点后若干位但至少要让数量级合理。零矩阵或缺失 inertial 都会导致物理引擎数值异常。4.3 校验 URDF 文件先检查语法是否正确。cd ~/robot_ws/src/robot_bringup/urdf check_urdf simple_robot.urdf如果一切正常会输出类似robot name is: simple_robot ---------- Successfully Parsed XML --------------- root Link: base_link has 2 child(ren) child(1): wheel_left_link child(2): wheel_right_link还可以生成结构图urdf_to_graphiz simple_robot.urdf这会生成simple_robot.pdf可以直观看到关节树结构。到这里URDF 文件本身已经没问题了。但如果你直接拿这个文件去 Gazebo会发现模型能显示但轮子是悬空的、机器人不会动。所以继续往下看导入 Gazebo 的完整流程。5. 将 URDF 导入 Gazebo 的完整流程5.1 准备 launch 文件在 ROS2 中推荐用 launch 文件把多个节点组织起来。我们需要做三件事启动 Gazebo 仿真环境。启动robot_state_publisher把 URDF 里的关节树发布为 TF。通过spawn_entity.py把机器人模型生成到 Gazebo 场景中。创建一个 Python launch 文件~/robot_ws/src/robot_bringup/launch/gazebo.launch.pyimport os from launch import LaunchDescription from launch.actions import IncludeLaunchDescription from launch.launch_description_sources import PythonLaunchDescriptionSource from ament_index_python.packages import get_package_share_directory from launch_ros.actions import Node def generate_launch_description(): # 获取 gazebo_ros 包路径 pkg_gazebo_ros get_package_share_directory(gazebo_ros) # 获取当前包路径 pkg_robot get_package_share_directory(robot_bringup) # URDF 文件路径 urdf_path os.path.join(pkg_robot, urdf, simple_robot.urdf) with open(urdf_path, r) as f: robot_description f.read() # 启动 Gazebo 空世界 gazebo_launch IncludeLaunchDescription( PythonLaunchDescriptionSource( os.path.join(pkg_gazebo_ros, launch, gazebo.launch.py) ) ) # robot_state_publisher 发布 TF 和 robot_description robot_state_publisher Node( packagerobot_state_publisher, executablerobot_state_publisher, parameters[{robot_description: robot_description}], outputscreen ) # 将机器人 spawn 到 Gazebo 场景 spawn_entity Node( packagegazebo_ros, executablespawn_entity.py, arguments[-topic, robot_description, -entity, simple_robot], outputscreen ) return LaunchDescription([ gazebo_launch, robot_state_publisher, spawn_entity, ])注意这个 launch 文件里spawn_entity.py监听的 topic 是robot_description和robot_state_publisher发布的robot_description正好匹配。这个细节非常关键很多新手会改成文件名或者自定义 topic反而导致模型一直生成不成功。5.2 启动 Gazebo 并生成机器人首先创建包的配置文件否则 colcon 构建时找不到 launch 和 urdf 目录。~/robot_ws/src/robot_bringup/package.xml和CMakeLists.txt都需要配置好。最简单的方式是先用ros2 pkg create创建包然后手动添加目录。这里假设你已经有了一个名为robot_bringup的 ament_cmake 包。如果没有可以执行cd ~/robot_ws/src ros2 pkg create robot_bringup --build-type ament_cmake mkdir -p robot_bringup/urdf robot_bringup/launch还需要在CMakeLists.txt中安装这些目录install(DIRECTORY urdf launch DESTINATION share/${PROJECT_NAME})然后构建cd ~/robot_ws colcon build --packages-select robot_bringup source install/setup.bash启动ros2 launch robot_bringup gazebo.launch.py如果一切正常Gazebo Classic 窗口会打开世界中央出现一个蓝色底盘和两个灰色轮子。5.3 验证模型是否成功生成在另一个终端里执行ros2 node list ros2 topic echo /robot_description --once/robot_description消息内容就是完整 URDF 文本说明robot_state_publisher已经发布成功。还可以打开 Rviz2 看 TFrviz2添加 TF 显示和 RobotModel 显示Global Options 里的 Fixed Frame 设置为base_link。此时你会发现一个问题虽然模型在 Gazebo 里能显示但机器人并没有按照我们的预期“运动”而且很可能整个车体一直悬浮在生成时的位置轮子也不跟着转动。这是因为我们还没有给关节加载任何驱动插件。6. 给 Gazebo 里的机器人加物理驱动从静态模型到可运动6.1 为什么 Gazebo 里机器人不会动spawn_entity.py成功加载模型只代表 URDF 被解析成了 Gazebo 世界里的实体。如果你在 URDF 中没有添加gazebo插件Gazebo 不会自动把 ROS2 的/cmd_vel话题和轮子关节绑定。想让机器人真正跑起来一种常见方案是使用gazebo_ros2_control插件配合 ros2_control 架构。这套架构把“硬件抽象”和“控制器”分离开。Gazebo 负责模拟硬件ros2_control 负责运行控制器两者通过插件通信。6.2 用 ros2_control DiffDriveController 驱动差速底盘首先在原来的 URDF 末尾追加以下内容。在/robot之前加上ros2_control nameGazeboSystem typesystem hardware plugingazebo_ros2_control/GazeboSystem/plugin /hardware joint namewheel_left_joint command_interface namevelocity/ state_interface nameposition/ state_interface namevelocity/ /joint joint namewheel_right_joint command_interface namevelocity/ state_interface nameposition/ state_interface namevelocity/ /joint /ros2_control gazebo plugin namegazebo_ros2_control filenamelibgazebo_ros2_control.so parameters$(find robot_bringup)/config/controllers.yaml/parameters /plugin /gazebo然后创建控制器配置文件~/robot_ws/src/robot_bringup/config/controllers.yamlcontroller_manager: ros__parameters: update_rate: 100 joint_state_broadcaster: type: joint_state_broadcaster/JointStateBroadcaster diff_drive_controller: type: diff_drive_controller/DiffDriveController diff_drive_controller: ros__parameters: left_wheel_names: [wheel_left_joint] right_wheel_names: [wheel_right_joint] wheel_separation: 0.4 wheels_per_side: 1 wheel_radius: 0.1 command_interfaces: - velocity state_interfaces: - position - velocity这里的wheel_separation是左右轮在 Y 方向的距离也就是 0.2 加 0.2等于 0.4 米。wheel_radius是轮子半径 0.1 米。这些参数必须和 URDF 里的几何信息一致否则控制器计算出的线速度和角速度会不准。构建并重新启动cd ~/robot_ws colcon build --packages-select robot_bringup source install/setup.bash ros2 launch robot_bringup gazebo.launch.py启动后控制器管理器会加载但默认情况下控制器不是 active 状态。打开新终端加载并激活控制器ros2 control load_controller joint_state_broadcaster --set-state active ros2 control load_controller diff_drive_controller --set-state active执行完这两条命令后可以用以下命令查看控制器状态ros2 control list_controllers如果看到diff_drive_controller的状态是active说明驱动链路已经打通。6.3 通过 topic 控制机器人现在向cmd_vel发布速度指令机器人应该会做出反应。ros2 topic pub /diff_drive_controller/cmd_vel geometry_msgs/msg/Twist {linear: {x: 0.2}, angular: {z: 0.0}} -r 10此时 Gazebo 里的机器人会开始沿 X 方向前进Rviz2 里也能看到轮子关节转动。如果希望转向可以发布带角速度的 Twistros2 topic pub /diff_drive_controller/cmd_vel geometry_msgs/msg/Twist {linear: {x: 0.1}, angular: {z: 0.3}} -r 10这里的/diff_drive_controller/cmd_vel是 ros2_control 根据控制器名称生成的默认话题。如果你在controllers.yaml中给控制器加了namespace话题名会相应变化排查时要先ros2 topic list确认。到这里你已经完成了一个完整的流程手写 URDF、导入 Gazebo、补全物理属性、加载 ros2_control、通过话题控制机器人运动。7. 常见问题与排查思路问题现象可能原因排查方式解决方案Gazebo 打开后模型没有出现spawn_entity 没有拿到 robot_description执行ros2 topic echo /robot_description --once确认消息内容检查 launch 中 topic 是否匹配URDF 文件路径是否正确模型出现后立刻掉进地面地面下的模型本身没有 collision或碰撞体未覆盖支撑部分检查每个 link 是否有collision并确认模型初始高度合理为所有 link 补全 collision或调整初始 spawn 高度模型持续抖动、弹飞inertial 缺失或数值不合理collision 几何体之间互相穿插查看 Gazebo 终端是否出现物理引擎警告为每个 link 设置合理质量和惯性张量缩小碰撞体到合适位置机器人所有部分在 Rviz2 中显示为红色材质路径或 mesh 文件路径错误查看robot_state_publisher日志和 urdf 中 mesh 的路径使用package://包名/meshes/xxx.stl的路径格式确认文件已安装到 share 目录发布 /cmd_vel 但没有反应控制器未加载或未激活执行ros2 control list_controllers查看状态执行ros2 control load_controller diff_drive_controller --set-state activejoint_state_broadcaster 加载失败控制器类型拼写错误或控制器配置缺失查看 launch 终端里 controller_manager 的日志检查 controllers.yaml 中type字段是否与 ros2_controllers 中的类名一致轮子转向错误或速度方向相反joint 的 axis 方向定义错误在 Rviz2 中观察轮子旋转轴检查 URDF 中axis是0 1 0还是0 -1 0或者调整 diff_drive_controller 里左右轮名字顺序从 SolidWorks/SolidWorks to URDF 导出的模型尺寸异常长度单位不统一常见的是 mm 和 m 混在一起用check_urdf查看 link 的 origin 和 geometry比较尺寸导出时统一按米导出或导入后在 URDF 中整体调整 scaleMoveIt2 配置 URDF 时卡死URDF 缺少多个关键 link 或 joint 的命名规律导致 MoveIt Setup Assistant 无法解析用check_urdf确认关节树完整性再交给 MoveIt 向导先保证 URDF 能被robot_state_publisher正常解析再使用 MoveIt Setup Assistant上面这些问题中最隐蔽的是“模型抖动/弹飞”。很多人看到这个现象会以为是 Gazebo 物理引擎的 bug实际上大概率是因为某个 link 的质量写得太小比如 0.001kg而碰撞体又很大导致物理引擎在极短时间步长内计算出了巨大加速度。遇到这种问题时优先检查 inertial。8. 最佳实践与工程建议8.1 从 CAD 工具导出 URDF 的陷阱SolidWorks 导出 URDF 是很多人进入机器人仿真的第一步但导出结果通常需要做很多修正。常见问题包括坐标系不一致CAD 模型里的原点未必在关节中心导出后每个 link 的 origin 里带了一堆偏移。单位不统一SolidWorks 默认用 mmROS 和 Gazebo 使用 m导出后容易出现数值放大 1000 倍的怪异情况。网格过于精细一个机械臂的 STL 文件可能有好几百 MB直接加载到 Gazebo 会让仿真变卡。实际项目中建议在 CAD 导出阶段就清理模型只保留外观外表面、把非关键零件合并成一个 mesh、由 CAD 工程师在装配体中约束好坐标系。导出后再用check_urdf逐个检查 joint 轴和原点。从其他工具转模型也是类似思路。比如用 Fusion 360 或 Onshape 生成 URDF 时一定要在导出后重新检查单位、材质路径和碰撞体。不要认为“导出的就是标准答案”。8.2 材质与比例问题在 URDF 中material的color值在 Rviz2 和 Gazebo 中的表现不一定完全一致。尤其是使用 STL 网格时如果 STL 文件本身没有颜色信息Gazebo 可能显示为统一的灰色而 Rviz2 可能会用 URDF 中定义的材质上色。更好的做法是用 xacro 统一管理 mesh 路径和材质名称。将 STL/DAE 文件放在包的meshes目录下通过package://robot_bringup/meshes/xxx.stl引用而不是写绝对路径。如果你需要 Gazebo 中的视觉材质更真实可以使用gazebo referencelink_name加material子标签但一般教学场景下用简单颜色就够。8.3 与 MoveIt2、导航栈衔接时要注意什么当你从“模型导入”走向“机械臂规划”或“自主导航”时基础设施还是同一个 URDF但需要额外注意几个层次。导航栈Nav2通常只关心base_link、odom、laser_link这些 TF 和传感器数据不关心你的 URDF 是否华丽。如果你把模型导入 Gazebo 是为了跑导航重点应放在激光雷达/IMU 插件和 TF 树上。MoveIt2 需要 URDF 提供完整的运动学链并且需要 SRDF 文件描述规划组、虚拟关节、碰撞免撞对。在 Gazebo 中结合 MoveIt2 时控制器类型通常是JointGroupCommandController或专门的 MoveIt 控制器而不是本文的 diff_drive_controller。一个常见误区是以为 MoveIt2 能直接控制 Gazebo 中的机械臂关节。实际上MoveIt2 通过控制器接口下发目标而 Gazebo 中的关节是否执行目标取决于 ros2_control 是否加载了对应控制器。所以如果你在配置 MoveIt2 时卡住不要先怀疑 MoveIt2先回到 “URDF 能否被 robot_state_publisher 正常解析” 和 “ros2_control 能否加载控制器” 这两个基础环节。8.4 工程结构建议对于真实项目建议从一开始就按下面的目录组织robot_bringup/ ├── CMakeLists.txt ├── package.xml ├── config/ │ ├── controllers.yaml │ └── robot_control.yaml ├── launch/ │ ├── gazebo.launch.py │ ├── rviz.launch.py │ └── display.launch.py ├── meshes/ │ ├── chassis.stl │ └── wheel.stl ├── urdf/ │ ├── robot.urdf.xacro │ ├── robot.gazebo.xacro │ ├── robot.ros2_control.xacro │ └── common_materials.xacro把 URDF 拆分成robot.urdf.xacro、robot.gazebo.xacro、robot.ros2_control.xacro再通过 xacro include 组合是 ROS2 社区比较成熟的做法。这样传感器配置、控制器配置、机械结构配置各归各的文件后期维护更清晰。命名规范方面建议所有 link 都以_link结尾所有 joint 都以_joint结尾。比如laser_link、arm_link1、arm_joint1。这看起来是小事但在使用 MoveIt2、Nav2 和 ros2_control 时命名混乱会成为排查问题的重大障碍。8.5 遇到问题时的调试顺序最后给一个通用的调试顺序能覆盖大部分 Gazebo 相关故障先确认 URDF 语法check_urdf。再确认模型在 Rviz2 中是否正确看 visual、TF、关节树。再确认 Gazebo 是否能加载模型看终端有没有 red/warning 输出。再确认物理属性每个 link 是否有 collision、inertial。再确认控制器状态ros2 control list_controllers是否是 active。最后确认话题通信ros2 topic echo /diff_drive_controller/cmd_vel。这个顺序是从“静态显示层”逐步深入到“动态驱动层”的。很多人第一反应是去改控制代码结果最后发现是 URDF 里缺了一个 collision白折腾一晚上。9. 跑通之后下一步建议现在你已经有了一个能在 Gazebo 里落地、能被/cmd_vel驱动的差速底盘。下一步可以考虑按这个方向继续深入把这个最小机器人换成自己的真实机器人模型注意从 CAD 导出后重新补全 collision 和 inertial。把simple_robot.urdf改写成 xacro加入轮距、轮径、质量变量。在底盘上添加 laser link配置 Gazebo 的 Laser 插件为 Nav2 导航做准备。把差速控制器换成更接近真实产品的控制器配置比如加入 pid_gains。如果你正在做的是机械臂不妨先把 MoveIt2 那套工具链放到后面优先确保 ros2_control 能直接控制每一个关节。Gazebo 里能看到滑块动起来、关节跟着转再去接 MoveIt2 的规划与执行思路会清晰很多。很多人的第一台机器人在 Gazebo 里跑不起来不是 URDF 语法问题而是把物理属性和驱动配置当成了可有可无的装饰。URDF 能把模型画出来Gazebo 才是把模型“逼真”起来的地方。先跑通本文的最小模型再去叠加传感器、导航和 MoveIt是更稳妥的路线。收藏这篇文章等下次模型在 Gazebo 里炸飞、掉地底、不动时回来对照排查表会比重新翻半天文档高效得多。
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻