news 2026/9/12 18:13:03

双臂机器人仿真搭建:ABBYuMi + ROS2 MoveIt2 Gazebo全流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
双臂机器人仿真搭建:ABBYuMi + ROS2 MoveIt2 Gazebo全流程

简介:本资源是面向ROS2开发者与机器人算法工程师的ABB YuMi双臂协作机器人MoveIt2完整集成方案,聚焦双臂运动规划、碰撞避障与Gazebo仿真验证等核心需求。压缩包共64个文件,含12个xacro宏定义文件(构建模块化URDF模型)、6个YAML配置文件(涵盖运动学参数、规划器设置与传感器参数)、9个Python脚本(含双臂协同抓取、路径规划与RViz可视化控制示例)、22个STL网格模型(支撑高保真Gazebo物理仿真),以及URDF主模型、SRDF语义描述、RViz配置与多份说明文档,总大小11.42MB。已有70人学习下载,资源结构清晰,以yumi_moveit_config和yumi_description两大功能包为核心,配套launch启动脚本、CMakeLists编译配置及LICENSE合规声明,开箱即用于ROS2 Humble环境。读者可直接复用URDF模型、调用现成MoveIt2配置、运行Gazebo双臂仿真,并基于示例代码快速开发自定义双臂协同任务。 前段时间一直在做双臂协作场景的仿真预研,把一台 ABBYuMi 搬进了 ROS2 Humble 环境里,整套东西从 URDF 模型到 MoveIt2 配置包,再到 Gazebo 仿真和运动规划示例,全都跑通之后,我决定把整个搭建过程整理成一篇可以照着复现的文章。

这个项目解决的问题其实很现实:真实 ABBYuMi 硬件价格高、调试周期长,而且双臂机器人涉及的运动规划、碰撞避免、双手协同等问题,直接在真机上试错成本太高。所以用 URDF 建模 + MoveIt2 配置 + Gazebo 仿真,把整条链路在软件里先跑通,是性价比最高的方案。适合正在学习 ROS2 运动规划的学生、准备上手双臂机器人的工程师,以及想在 Gazebo 里做双臂算法验证的研究者参考。

下面我会按实际搭建顺序,从项目拆解、URDF 建模、MoveIt2 配置、Gazebo 集成,到最后的踩坑记录,完整过一遍。

1. 项目整体拆解:为什么是 ABBYuMi + MoveIt2 + Gazebo

很多做机械臂开发的人第一次接触双臂机器人时,第一反应是“这不就是两个单臂一起控制吗”。实际动手以后才发现,双臂系统的复杂性远不是简单叠加。它会涉及两个机械臂之间的碰撞避免、共享基座的动力学耦合、协同任务的轨迹约束等问题。这个项目选 ABBYuMi 作为载体,恰恰是因为它在这些方面很有代表性。

1.1 项目核心需求解析

把标题拆开看,这个项目其实包含五个模块:

  • URDF 模型:机器人本体描述文件,包含运动学链路、几何外观、惯性参数、碰撞属性,是后续所有工作的基础。
  • MoveIt2 配置包:基于 URDF 自动生成的配置集,定义规划组、IK 求解器、规划器参数、预定义位姿等。
  • 运动规划示例:通过代码或 RViz 手动画目标点,让机械臂完成路径规划。
  • Gazebo 仿真环境:在 Gazebo 中加载 URDF 模型,让机器人具备物理属性,可以响应控制器指令运动。
  • ROS2 Humble 集成:以上所有模块在 ROS2 Humble 这个发行版下面协同工作。

这五个模块不是孤立的,它们之间的关系可以这样理解:URDF 是机器人的“身体描述”,MoveIt2 配置包是“大脑和运动神经系统”,Gazebo 是“虚拟训练场”,而 ROS2 Humble 是连接所有部分的“通信基站”。整个项目中,最难的不是某一个模块,而是让它们顺畅地协同工作。

1.2 为什么选 ABBYuMi 作为仿真对象

ABBYuMi 是典型的双臂协作机器人,14 个自由度,单臂 7 轴。它的工业场景非常明确:小件装配、插拔线束、精密操作。这些场景天然需要双臂配合,单个机械臂很难完成。

在仿真中做 ABBYuMi 还有一个好处:它的 URDF 描述相对规范,公开资料里能找到接近真实参数的模型。相比自己从零画一个双臂模型,直接基于 YuMi 的模型做配置,能把精力集中在 MoveIt2 和 Gazebo 集成这些更核心的问题上。

我用这个词直接搜的是“ABBYuMi”,虽然是 ABB 的简化叫法,但社区资料里都能对上,不会混淆。也有一些人用“YuMi”称呼,项目里统一写 ABBYuMi 就行。

1.3 技术选型:为什么是 MoveIt2 + Gazebo,而不是其他方案

双臂运动规划有很多技术栈组合,最常用的是下面这几种对比:

技术组合优势劣势适用场景
MoveIt2 + Gazebo ClassicROS2 原生支持好,教程多,生态成熟仿真物理精度一般绝大多数 ROS2 机器人项目
MoveIt2 + MuJoCo物理仿真速度快,接触稳定ROS2 集成需要额外适配层强化学习、高速仿真
MoveIt1 + Gazebo (ROS1)老项目资料最多ROS1 已停止维护维护旧工程
CoppeliaSim + MoveIt 桥接自带丰富模型和传感仿真授权与社区资源受限教学、轻量验证

这个项目选 MoveIt2 + Gazebo,核心原因是 ROS2 Humble 是当前长期支持版本,生态最成熟,遇到问题搜资料最容易。而且 ros2_control 已经深度集成到 Gazebo Classic 中,可以直接用 gazebo_ros2_control 插件把控制器管线跑通。MuJoCo 虽然物理仿真更稳,但为了完整覆盖 MoveIt2 的规划链路和 RViz 可视化,Gazebo 是更稳妥的选择。

2. 环境准备与 URDF 模型解析:打好双臂仿真的地基

在碰 MoveIt2 之前,先把环境搭好。一个干净的 ROS2 Humble 环境能省掉后面大部分烦恼。

2.1 ROS2 Humble + Gazebo 环境搭建

我用的是 Ubuntu 22.04 + ROS2 Humble。安装 ROS2 Humble 桌面版:

sudo apt update sudo apt install ros-humble-desktop python3-rosdep sudo rosdep init rosdep update echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc source ~/.bashrc

Gazebo 相关的包单独装:

sudo apt install ros-humble-gazebo-ros-pkgs ros-humble-gazebo-ros2-control

这里有个容易踩的坑:ROS2 Humble 对应的是 Gazebo Classic 11,不是 Gazebo Fortress(gz sim)。虽然 Fortress 功能更新,但 MoveIt2 集成教程和 ros2_control 插件适配目前还是以 Gazebo Classic 为主。装完确认一下:

gazebo --version

如果看到 Gazebo multi-robot simulator, version 11.x,说明环境没问题。

还需要安装 MoveIt2:

sudo apt install ros-humble-moveit

安装完成后,建议建一个工作空间,把所有自定义包放进去:

mkdir -p ~/yumi_ws/src cd ~/yumi_ws colcon build

2.2 YuMi 双臂机器人的 URDF 结构拆解

ABBYuMi 的 URDF 结构比较规整,整棵坐标树大致是:

  • base_link:机器人基座,固定在世界坐标系
  • base:基座上的固定连杆
  • link_1~link_7(左臂)
  • link_1~link_7(右臂)
  • gripper相关连杆(左右各一个)

左右臂的关节命名一般带_left_right后缀,比如yumi_joint_1_lyumi_joint_1_r。实际模型里可能名称会略微不同,但命名规则基本是这样。在配置 MoveIt2 规划组之前,必须先确认关节名称,因为后面所有配置都依赖这些字符串。

URDF 文件通常用 xacro 宏来写,因为左右臂高度对称,用一个宏批量生成两个臂的连杆和关节,能避免重复代码。一个典型的 xacro 定义大概长这样:

<xacro:macro name="yumi_arm" params="prefix"> <link name="${prefix}link_1"> <visual> <geometry> <mesh filename="package://yumi_description/meshes/${prefix}link_1.stl"/> </geometry> </visual> <collision> <geometry> <mesh filename="package://yumi_description/meshes/${prefix}link_1.stl"/> </geometry> </collision> </link> <joint name="${prefix}joint_1" type="revolute"> <parent link="base"/> <child link="${prefix}link_1"/> <origin xyz="... " rpy="..."/> <axis xyz="0 0 1"/> <limit lower="-2.96" upper="2.96" effort="20" velocity="1.5"/> </joint> </xacro:macro>

调用时直接:

<xacro:yumi_arm prefix="yumi_"/>

这样左侧就是yumi_joint_1yumi_link_1,右侧同理加后缀。用宏封装的好处是:如果想要更换手臂尺寸或关节限位,只需改一处。

2.3 URDF 改造成符合 MoveIt2 和 Gazebo 要求的格式

很多人从网上下载一个 URDF 直接跑 MoveIt2,结果各种报错。原因是 MoveIt2 和 Gazebo 对 URDF 的要求比普通可视化展示严格得多。

第一,每个连杆必须有<collision><inertial>标签。没有惯性参数,Gazebo 里机器人会直接坍缩或者飘起来;没有碰撞参数,MoveIt2 无法做碰撞检测。如果找不到准确的惯性数据,最简单的方法是用 mesh 体积等量估算:

<inertial> <mass value="1.2"/> <inertia ixx="0.01" ixy="0" ixz="0" iyy="0.01" iyz="0" izz="0.01"/> </inertial>

第二,必须在 URDF 里加入ros2_control标签,否则 Gazebo 无法通过 ros2_control 接口控制关节:

<ros2_control name="GazeboSystem" type="system"> <hardware> <plugin>gazebo_ros2_control/GazeboSystem</plugin> </hardware> <joint name="yumi_joint_1_l"> <command_interface name="position"> <param name="min">-2.96</param> <param name="max">2.96</param> </command_interface> <state_interface name="position"/> <state_interface name="velocity"/> </joint> <!-- 其他关节依此类推,左右臂全部写全 --> </ros2_control>

第三,坐标系的命名要统一。MoveIt2 默认需要world坐标系或者base_link作为规划参考系。如果 URDF 里没有 world 链接,可以在 launch 文件里加一个虚拟 joint 把 base_link 固定到 world 上。

写完之后做自检:

cd ~/yumi_ws/src/yumi_description/urdf xacro yumi.urdf.xacro > yumi.urdf check_urdf yumi.urdf

check_urdf会输出整棵运动学树,仔细检查左右臂是否对称、parent/child 关系是否正确。这一步发现问题修复成本最低,等进了 MoveIt2 再发现问题,排查难度会翻倍。

3. MoveIt2 配置包生成与运动规划:把“大脑”装给机器人

URDF 只是描述机器人的“身体”,MoveIt2 配置包则是让这台机器人“会动”的关键。手动写 MoveIt2 配置包会让人怀疑人生,幸好有 moveit_setup_assistant 这个交互工具。

3.1 用 moveit_setup_assistant 一键生成配置包

在刚才建好的工作空间里,先创建一个目录存放模型文件,然后启动配置助手:

mkdir -p ~/yumi_ws/src/yumi_description/urdf cp yumi.urdf ~/yumi_ws/src/yumi_description/urdf/ cd ~/yumi_ws colcon build source install/setup.bash ros2 launch moveit_setup_assistant setup_assistant.launch.py

打开界面后,选择“Create New MoveIt Configuration Package”,加载写好的 yumi.urdf 文件。接下来是重点,几个关键步骤:

Self-Collision 矩阵:点击生成碰撞矩阵,MoveIt2 会自动计算哪些连杆对不可能碰撞,生成 SRDF 里的 disabled collision 矩阵。双臂机器人这一步特别重要,因为左右臂之间的很多碰撞关系是固定的,生成后不需要每次规划都检测,能大幅提升规划速度。

规划组设置:这是双臂机器人配置中最重要的部分。我设置了四个规划组:

规划组名包含关节用途
left_armyumi_joint_1_l ~ yumi_joint_7_l左臂独立控制
right_armyumi_joint_1_r ~ yumi_joint_7_r右臂独立控制
both_arms左右臂全部 14 个关节双臂协同规划
left_gripper / right_gripper夹爪关节夹爪控制

规划组的设置有讲究。如果只设置一个 both_arms 组,控制左臂时会把右臂也卷进来,规划效率低;如果只设置单个臂,双臂协同规划就没法做。这里全部设置,后续按场景选择。

预定义位姿:设置 home、zero、ready 等常用位姿。双臂机器人建议至少设置 home(两侧手臂自然下垂)和 ready(两侧手臂前伸准备操作)两个,调试时能省大量时间。

ROS2 Control:在配置助手里可以选择启用 ros2_control,它会自动生成 controllers.yaml 模板,后续在 Gazebo 里会用得上。

全部配置完成后,点击 Generate Package,选择输出目录,一般生成到 src 下。包名字可以叫yumi_moveit_config

生成后编译验证:

cd ~/yumi_ws colcon build source install/setup.bash ros2 launch yumi_moveit_config demo.launch.py

能顺利打开 RViz 并看到 YuMi 模型,说明配置包基本可用。

3.2 规划组与 IK 求解器配置:影响双臂稳定性的关键

MoveIt2 配置包生成后,有几处需要手动微调。

kinematics.yaml文件里默认的 IK 求解器是 KDL。KDL 对单臂效果不错,但双臂 14 自由度场景下,IK 求解速度会明显变慢,有时候还会出现奇异位形问题。我的建议是安装 TRAC-IK 替代:

sudo apt install ros-humble-trac-ik

然后在 kinematics.yaml 中修改:

left_arm: kinematics_solver: trac_ik_kinematics_plugin/TRAC_IKKinematicsPlugin kinematics_solver_search_resolution: 0.005 kinematics_solver_timeout: 0.05 kinematics_solver_attempts: 3 right_arm: kinematics_solver: trac_ik_kinematics_plugin/TRAC_IKKinematicsPlugin kinematics_solver_search_resolution: 0.005 kinematics_solver_timeout: 0.05 kinematics_solver_attempts: 3 both_arms: kinematics_solver: trac_ik_kinematics_plugin/TRAC_IKKinematicsPlugin kinematics_solver_search_resolution: 0.005 kinematics_solver_timeout: 0.05 kinematics_solver_attempts: 3

TRAC-IK 在双臂场景下的求解成功率明显高于 KDL,尤其是靠近工作空间边界的位置。

ompl_planning.yaml里可以调整各规划器的参数。默认用的 RRTConnect 对 14 自由度来说效率尚可,但如果觉得规划抖动大,可以改用 LBKPIECE 或设定更长的规划时间。我调试时降低了规划器的最大迭代次数,用允许略长一点的时间换更平滑的路径。

3.3 运动规划示例:用 MoveGroupInterface 写一个双臂规划程序

配置包只是基础,真正干活的是运动规划节点。我用 MoveGroupInterface 写了一个简单示例,实现左右臂同时运动到目标姿态:

#include <moveit/move_group_interface/move_group_interface.h> #include <rclcpp/rclcpp.hpp> int main(int argc, char* argv[]) { rclcpp::init(argc, argv); auto node = std::make_shared<rclcpp::Node>("yumi_dual_arm_plan"); moveit::planning_interface::MoveGroupInterface move_group_left(node, "left_arm"); moveit::planning_interface::MoveGroupInterface move_group_right(node, "right_arm"); move_group_left.setPlannerId("RRTConnect"); move_group_right.setPlannerId("RRTConnect"); move_group_left.setPlanningTime(5.0); move_group_right.setPlanningTime(5.0); // 设置目标位姿 geometry_msgs::msg::Pose target_pose_left; target_pose_left.position.x = 0.3; target_pose_left.position.y = 0.2; target_pose_left.position.z = 0.4; target_pose_left.orientation.w = 1.0; move_group_left.setPoseTarget(target_pose_left); geometry_msgs::msg::Pose target_pose_right; target_pose_right.position.x = 0.3; target_pose_right.position.y = -0.2; target_pose_right.position.z = 0.4; target_pose_right.orientation.w = 1.0; move_group_right.setPoseTarget(target_pose_right); // 分别规划 moveit::planning_interface::MoveGroupInterface::Plan plan_left; moveit::planning_interface::MoveGroupInterface::Plan plan_right; bool ok_left = (move_group_left.plan(plan_left) == moveit::core::MoveItErrorCode::SUCCESS); bool ok_right = (move_group_right.plan(plan_right) == moveit::core::MoveItErrorCode::SUCCESS); if (ok_left && ok_right) { move_group_left.execute(plan_left); move_group_right.execute(plan_right); } rclcpp::shutdown(); return 0; }

编译方式和普通 ROS2 包一样,在 CMakeLists 里链接相应库。这个示例的关键点是两个 MoveGroupInterface 实例在同一个节点里分别控制两个规划组,这样能保证两条轨迹在时间上尽量同步,双臂协同效果更好。

如果要做真正的双臂协同(比如双手搬一块板),规划组要选both_arms,然后把目标位姿设到某个物体坐标系上,让 MoveIt2 同时规划 14 个关节。这种方式规划时间更长,但轨迹天然满足双臂之间的约束。

4. Gazebo 仿真环境集成:让机器人真正“动起来”

MoveIt2 在 RViz 里的规划只是“理论轨迹”,要让机器人真正按轨迹运动,必须接入 Gazebo 物理仿真。这也是很多人卡住的环节,MoveIt2 规划好了但 Gazebo 里机器人就是不动,或者动得完全不对。

4.1 MoveIt2 和 Gazebo 是如何“结合”的

先理解整个数据流。MoveIt2 运动规划完成后,把轨迹发送给执行器。在 Gazebo 场景里,执行器不是硬件,而是 ros2_control 的控制器。整条链路如下:

  1. MoveIt2 规划出一条轨迹
  2. MoveIt2 把轨迹发送到 FollowJointTrajectory 控制器(话题通常是/controller_manager/node_names或者具体的/yumi_arm_controller/follow_joint_trajectory
  3. ros2_control 的 JointTrajectoryController 拆解轨迹,按控制周期下发关节位置
  4. gazebo_ros2_control 插件把位置指令转换成物理仿真里的关节驱动力矩
  5. 仿真模型通过/joint_states发布实际关节状态
  6. MoveIt2 订阅关节状态,更新机器人当前位姿

用一句话概括:MoveIt2 负责“想”,Gazebo 负责“做”,ros2_control 是负责传递动作的“神经”。

这个通信链条里最常出问题的是控制器名字不匹配。MoveIt2 默认发送到/follow_joint_trajectory,但实际控制器可能叫/yumi_arm_controller/follow_joint_trajectory,不匹配就导致 MoveIt2 规划完轨迹却没人执行。

4.2 ros2_control 控制器配置

在生成 MoveIt2 配置包时,如果勾选了 ROS2 Control 选项,会有一个 controllers.yaml 模板。实际使用时要根据 URDF 里的关节名称做修改:

controller_manager: ros__parameters: update_rate: 100 use_sim_time: true yumi_arm_controller: type: joint_trajectory_controller/JointTrajectoryController joint_state_broadcaster: type: joint_state_broadcaster/JointStateBroadcaster yumi_arm_controller: ros__parameters: joints: - yumi_joint_1_l - yumi_joint_2_l - yumi_joint_3_l - yumi_joint_4_l - yumi_joint_5_l - yumi_joint_6_l - yumi_joint_7_l - yumi_joint_1_r - yumi_joint_2_r - yumi_joint_3_r - yumi_joint_4_r - yumi_joint_5_r - yumi_joint_6_r - yumi_joint_7_r

注意双臂机器人这里要一次把所有关节都写上,不能只写一条手臂。否则另一条手臂会失去控制。

在 Gazebo 的 world 文件或者 launch 文件里,需要加载 ros2_control 插件。一般情况下 launch 文件会处理这些。一个标准的 Gazebo + MoveIt2 联合启动顺序是:

  1. 启动 Gazebo 服务端并加载模型
  2. 启动 controller_manager 并加载 controllers
  3. 启动 MoveIt2 move_group
  4. 启动 RViz 可视化

4.3 启动文件整合

我习惯把启动逻辑写在一个 launch 文件里,按顺序串起来:

import launch import launch_ros.actions from launch.actions import ExecuteProcess from launch_ros.actions import Node def generate_launch_description(): return launch.LaunchDescription([ # 1. 启动 Gazebo ExecuteProcess( cmd=['gazebo', '--verbose', '-s', 'libgazebo_ros_init.so', '-s', 'libgazebo_ros_factory.so'], output='screen' ), # 2. 加载机器人模型到 Gazebo Node( package='gazebo_ros', executable='spawn_entity.py', arguments=['-entity', 'yumi', '-file', 'yumi.urdf'], output='screen' ), # 3. 启动 controller_manager Node( package='controller_manager', executable='ros2_control_node', parameters=['config/controllers.yaml'], output='screen' ), # 4. 激活控制器 ExecuteProcess( cmd=['ros2', 'control', 'load_controller', '--set-state', 'active', 'joint_state_broadcaster'], output='screen' ), ExecuteProcess( cmd=['ros2', 'control', 'load_controller', '--set-state', 'active', 'yumi_arm_controller'], output='screen' ), # 5. 启动 MoveIt2 move_group Node( package='yumi_moveit_config', executable='move_group', output='screen' ), # 6. 启动 RViz Node( package='rviz2', executable='rviz2', arguments=['-d', 'config/moveit.rviz'], output='screen' ), ])

实际调试时,我不会直接一次性全启动,而是先启动前四步,确认 Gazebo 里机器人正常加载、控制器 active,再启动 move_group 和 RViz。这样出了问题能快速定位是控制链路的问题还是规划链路的问题。

4.4 在 Gazebo 中验证双臂轨迹执行

全部启动后,用命令行发一条轨迹测试:

ros2 topic pub -1 /yumi_arm_controller/joint_trajectory trajectory_msgs/msg/JointTrajectory \ "{joint_names: [yumi_joint_1_l, yumi_joint_2_l, yumi_joint_3_l, yumi_joint_4_l, yumi_joint_5_l, yumi_joint_6_l, yumi_joint_7_l, yumi_joint_1_r, yumi_joint_2_r, yumi_joint_3_r, yumi_joint_4_r, yumi_joint_5_r, yumi_joint_6_r, yumi_joint_7_r], points: [{positions: [0.1, 0.2, 0.3, 0.0, 0.5, 0.0, 0.1, -0.1, -0.2, -0.3, 0.0, 0.5, 0.0, -0.1], time_from_start: {sec: 3}}]}"

如果机器人在 Gazebo 里按预期轨迹运动,说明整条控制链路是通的。这时候再回到 MoveIt2 的 RViz 界面,拖动手柄设置目标,点 Plan & Execute,不出意外就能看到双臂在 Gazebo 里执行规划好的动作。

这里有一个细节需要留意:Gazebo 里的关节响应默认是纯位置控制,如果 PID 参数调得不好,动作会比较“肉”,跟手速度跟不上 MoveIt2 的轨迹点下发速度。出现这种情况时,调节gazebo_ros2_control插件中的 PID 参数,通常先把比例增益调大,再微调微分项。实测下来,双臂仿真对 PID 比单臂更敏感,因为两条手臂同时运动时,基座会有轻微反作用力,PID 不当会导致末端轨迹出现肉眼可见的偏差。

5. 常见问题与排查技巧实录

做这个项目时踩了不少坑,我把典型问题整理出来,按现象、原因、解决方案的方式列在下面,基本都是可以直接照做的。

5.1 MoveIt2 规划失败,提示 “No Solution Found”

现象:RViz 里点 Plan,状态栏提示规划失败。

排查思路

  • 先看目标是否在可达空间内。双臂机器人的工作空间不是简单的两个球体相加,左右臂协同时会互相挤压活动范围,特别是靠近身体中线的位置。
  • 检查 allowed_planning_time,默认 5 秒对双臂场景略短,建议调大到 10 秒。
  • 检查碰撞矩阵。如果两条手臂默认位姿就在碰撞状态,MoveIt2 会认为初始状态不合法,任何规划都失败。

解决方案:先手动把机器人拖到一个无碰撞的初始位姿,重新 Set Start State,再规划;或者修改ompl_planning.yaml,增大max_goal_samplesmax_planning_time

5.2 Gazebo 里机器人“散架”或关节不受控

现象:模型加载后,手臂乱甩、下垂、抖动,或者完全不动。

原因:绝大多数是惯性参数缺失或 PID 参数不合理。URDF 里如果没有<inertial>,Gazebo 内部的物理引擎会用默认值,这个默认值对双臂这种长悬臂结构非常不友好,重力作用下关节直接发飘。

解决方案

  • 给每个连杆补全<inertial>参数,质量设置要尽量接近真实值,xacro 宏最好把惯性参数也参数化。
  • 调高控制器 PID 的比例增益,在gazebo_ros2_control插件参数里找到gains配置:
gazebo_ros2_control: ros__parameters: gains: yumi_joint_1_l: {p: 100.0, i: 0.5, d: 1.0} yumi_joint_2_l: {p: 100.0, i: 0.5, d: 1.0} # 其他关节按需调整

可以先每个关节统一设置一个较大 P 值,观察稳定性,再逐个调试。

5.3 Gazebo 和 MoveIt2 的通信不上,执行轨迹没反应

现象:MoveIt2 RViz 里看着规划成功,也提示执行了,但 Gazebo 里机器人纹丝不动。

原因:这是 MoveIt2 + Gazebo 集成最常见的坑,90% 的情况是控制器话题名不匹配。

排查方法

ros2 topic list | grep trajectory

我看一下实际话题名。如果看到/yumi_arm_controller/follow_joint_trajectory,说明控制器名字是 yumi_arm_controller,此时需要让 MoveIt2 知道用这个控制器执行轨迹。检查 MoveIt2 配置包中的 move_group 节点参数,一般会有一个trajectory_execution的配置文件,确保里面的controller_names列表和实际控制器名字一致。

还有一种情况是 use_sim_time 没有设置为 true。Gazebo 发布的是仿真时钟,如果不启用 use_sim_time,MoveIt2 和 ros2_control 会各自使用系统时钟,导致时间不同步,轨迹执行状态永远对不上。所有节点都要设置:

ros__parameters: use_sim_time: true

5.4 双臂规划时一条手臂动,另一条手臂不动

现象:用 both_arms 规划组做双臂规划,执行时只有一条手臂在动。

原因:controllers.yaml 里关节列表只写了部分关节,或者 joint_state_broadcaster 没有发布全部关节状态。

解决方案:确认 controllers.yaml 中joints列表包含全部 14 个关节,同时检查 Gazebo 启动时关节状态话题,确认左右臂关节都在更新。还有一种可能是 SRDF 中定义的规划组遗漏了某个关节,回到 moveit_setup_assistant 检查规划组包含的关节列表。

5.5 常见问题速查表

为了方便快速定位,我把问题整理成速查表:

现象大概率原因首要排查步骤
RViz 里模型显示为空白URDF 加载失败或 mesh 路径错误检查 xacro 生成的 URDF,确认 mesh 路径是 package 绝对引用
Gazebo 里模型下沉或反弹惯性参数为 0 或接触参数错误逐个连杆补 inertials,调整 contact 参数
规划很慢碰撞矩阵没有生成在 moveit_setup_assistant 重新生成 Self-Collision 矩阵
控制器一直 inactivecontroller_manager 没加载资源检查 URDF 的 ros2_control 标签和 controllers.yaml 是否匹配
move_group 启动报错SRDF 与 URDF 不匹配重新用 moveit_setup_assistant 生成配置包
Gazebo 仿真速度很慢物理步长太小或模型面数太多调大 max_step_size,简化 mesh 面数

做双臂仿真的体验和单臂差别很大。单臂出现问题,直接看运动学就能定位;双臂则要考虑两条手臂之间的相互影响,很多时候左臂规划失败,原因出在右臂的位姿上。我在实际调试中体会到,仿真环境下这种问题还算好处理,如果是在真机上,排查成本会高得多。

最后分享一个我自己的小小经验:每次调整 URDF 或者控制参数后,不要急着跑完整链路,先单独验证两步。第一步用check_urdf确认模型结构正确,第二步直接给关节发位置指令验证控制器能响应。这两步都通了,再把 MoveIt2 加进来做规划执行。分段验证看起来繁琐,但能帮你把问题隔绝在最小范围内。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/4 15:42:02

广联达校招笔试复盘:C++指针与数据结构重难点解析

每年九月一到&#xff0c;校招笔试的通知就像秋天的落叶一样密集。我印象里2018年那一轮广联达的笔试&#xff0c;整体难度不算顶尖&#xff0c;但题量大、覆盖面广、细节抠得深&#xff0c;尤其C指针和数据结构那两块&#xff0c;刷掉的人不在少数。广联达是建筑信息化领域的头…

作者头像 李华
网站建设 2026/9/4 23:16:46

Kimi K3部署揭秘:16张B200与8张AMD大显存卡背后的显存与量化逻辑

Kimi K3 在部署圈里被反复讨论&#xff0c;不是因为它的推理效果&#xff0c;而是因为显存需求太夸张&#xff1a;网上流传的部署方案里&#xff0c;16 张 NVIDIA B200 才能按较高精度跑起来&#xff0c;8 张 AMD 大显存加速卡却可以在更低精度下把同一模型装进显存。这个对比很…

作者头像 李华
网站建设 2026/8/31 16:18:05

基于Qt与C语言的前视声纳数据处理与图像显示实现详解

简介&#xff1a;本资源是一款面向海洋探测、水下工程及声纳信号处理领域的专业软件开发套件&#xff0c;适用于具备C语言基础与Qt开发经验的中高级工程师和科研人员&#xff0c;解决前视声纳数据实时可视化、噪声抑制、图像增强、几何校正及多格式信号解析等核心预处理难题。压…

作者头像 李华
网站建设 2026/9/4 14:33:10

Stone Soup AI:从最小系统开始的AI工程化协作范式

开头的强判断&#xff1a;AI 应用开发最大的成本已经不再是模型能力&#xff0c;而是把零散能力组织成可复用系统的工程成本。Stone Soup AI&#xff08;2024&#xff09;这个标题看起来很像一个社区项目&#xff0c;但把它放到 2024 年 AI 工程化的大背景里&#xff0c;它更像…

作者头像 李华
网站建设 2026/9/5 17:23:26

千问App办公收费背后:大模型商业化与AI成本控制策略

最近有一个问题频繁出现在各个技术交流群和评论区&#xff1a;千问App里越来越多的办公能力开始收费了。有的功能可以直接用&#xff0c;有的功能必须先升级&#xff0c;升级之后还会区分普通会员和高级权益。很多个人开发者的第一反应是“又一个免费工具开始割韭菜了”。但如果…

作者头像 李华
网站建设 2026/9/6 3:04:05

多模态图像生成揭秘:从风景照到AI艺术大片的图生图实战

最近 AI 绘画的话题热度一直很高&#xff0c;身边很多朋友在尝试同一个玩法&#xff1a;把手机里随手拍的普通风景照发给豆包&#xff0c;几秒钟之后就能得到一张风格完全不同的“艺术大片”。有人把白天过曝的街景变成了赛博朋克风格的海报&#xff0c;也有人把阴天灰蒙蒙的山…

作者头像 李华