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

UR5与AG95机械臂抓取实战:MoveIt配置与ROS集成全解析

简介针对UR5机械臂与AG95夹爪的抓取任务这份Python结合ROS与Moveit实现的项目源码适合机器人方向学生、ROS初学者以及需要完成机械臂抓取课程设计或期末大作业的开发者涵盖运动规划、夹爪控制与位姿设定等核心环节。资源共34个文件压缩包9.33MB以launch启动文件与py脚本为核心配合19张过程示意图、坐标系说明图及配置文件完整呈现了从环境配置到执行给定位姿抓取的实现链路。已有239人学习下载。项目包含详细代码注释与文档解析标注了关键知识点新手也能较快理解部署流程。通过launch文件可快速启动Moveit仿真结合go_grasp.py等脚本完成机械臂运动规划、夹爪控制与位姿抓取验证同时提供坐标系示意图等辅助资料便于对照理解坐标变换与DH参数原理。资料结构清晰便于直接复用与二次开发可用于课程演示、答辩展示及工程设计参考。 做机器人抓取这个事圈子里一直有句话方案看着都简单一到真机全完蛋。UR5 加 AG95 这套组合在实验室和工业现场都很常见但真正能把“给一个目标位姿让机械臂自己规划、自己抓”这条链路跑通并且稳定复现的项目源码和文档其实没想象中那么多。很多新手拿到工程文件后卡在 MoveIt 配置、坐标系标定、夹爪控制这些环节上一个晚上就耗进去了。这个项目正好补上了这个缺口它不光是给了一段能跑的 Python 代码还把 UR5 和 AG95 的联合建模、MoveIt 规划、抓取流程完整串了起来适合正在做毕设、搞科研验证、或者刚接触机械臂开发的工程师作为参考底板。我拿到这套项目资料后完整过了一遍源码和配套文档又按自己的理解在仿真环境和真机上做了验证。这篇文章不打算照着 Readme 念一遍而是把整个项目的设计思路、核心代码模块、实操中的坑和排查方法全部拆开讲清楚。你会知道为什么这个项目要用 Python 而不是 C 写控制逻辑MoveIt 的规划组该怎么配AG95 夹爪怎么和 UR5 统一到同一个 TF 树里以及真机调试时最容易在哪里翻车。1. 项目整体思路与设计拆分1.1 抓取任务的核心链路在拆代码之前得先把抓取这个任务的本质搞清楚。所谓“执行给定位姿的抓取”落到系统层面其实就是一条数据流一个目标物体的位姿通常由视觉系统给出或者人为指定→ 经过坐标变换转到机械臂基座坐标系 → 调用逆运动学求解出关节角 → 用 MoveIt 做无碰撞规划 → 下发轨迹给 UR5 执行 → 到位后控制 AG95 夹爪闭合。听起来不复杂但这里面的每一个箭头都是一个独立的工程模块。这套项目的高明之处在于它把每个模块都做成了可以单独调试的单元。比如你可以先把目标位姿写死只调 MoveIt 的规划也可以先不连真机在 RViz 里拖拽 IK 目标点看运动学求解效果等整个流程在仿真里跑顺了再切换到真机模式。这种“分层解耦”的思路是这套源码里最值得学习的地方。1.2 技术选型背后的考量先说 Python 和 C 的选择。UR 机械臂原生的 ur_robot_driver 和 MoveIt 底层都是 C那为什么项目控制代码要用 Python原因很简单开发效率和生态。Python 的 rospy 接口封装了 ROS 的消息和服务通信写一个 MoveIt 运动规划客户端Python 也就四五十行代码C 要写两倍不止。而且 Python 在数据处理和视觉对接上有天然优势如果你后续要接相机做视觉抓取用 Python 写图像处理和控制逻辑的衔接会顺畅很多。ROS 版本选型上这个项目默认用的是 ROS Melodic 配 Ubuntu 18.04或者 ROS Noetic 配 Ubuntu 20.04。UR5 的驱动和 MoveIt 在这两个版本上验证得最充分。如果你用的是更新的 Ubuntu 版本那大概率要装 ROS 2到时候驱动、TF、控制器这一套都得换不建议新手一上来就折腾。环境安装如果卡住了可以试试鱼香 ROS 的一键安装脚本我自己在干净系统上装 MoveIt 环境时用它省了不少事但装完之后还是要自己过一遍环境变量和依赖别全指望脚本。2. 环境搭建与工具链准备2.1 从零到能跑 MoveIt 的最小环境这个项目对环境的依赖不算轻但也不至于劝退。核心依赖是四块ROS 基础环境、MoveIt、UR5 的驱动包、AG95 的夹爪驱动或模拟。安装顺序建议是先装 ROS再装 MoveIt最后再装机械臂和夹爪相关的包。ROS 安装这块我强烈建议直接看官方 wiki 或者鱼香ROS一键安装的文档。这里补一个我踩过多次的教训不要用 pip 去装 rospkg 之类的 Python 包来试图“补全”ROS 环境ROS 的 Python 库必须和系统自带的 Python 版本严格匹配Melodic 对应 Python 2.7Noetic 对应 Python 3.8。混用 Python 环境会引发一堆莫名其妙的问题比如 import rospy 直接报错、tf 消息解析异常等。MoveIt 安装通常是一条命令的事比如 Noetic 下是sudo apt install ros-noetic-moveit。但要注意如果打算用 MoveIt Setup Assistant 重新生成配置需要额外装ros-noetic-moveit-setup-assistant这个包。很多教程默认你已经有了实际没有这个细节挺坑的。UR5 相关包用sudo apt install ros-noetic-ur-client-library ros-noetic-ur-robot-driver等命令安装即可。2.2 工作空间与源码编译项目源码拿到手之后第一步是建一个 catkin 工作空间把项目文件夹放进去编译。常见的结构是这样mkdir -p ~/ur5_ag95_ws/src cd ~/ur5_ag95_ws/src # 把项目源码解压或 clone 到这里 cd ~/ur5_ag95_ws catkin_make source devel/setup.bash编译过程如果报错优先看是不是缺依赖。用rosdep install --from-paths src --ignore-src -r -y可以自动检查并安装 ROS 层面的依赖。这条命令我几乎每次拿到新工程都会跑一遍能筛掉八成以上的编译报错。如果卡在某个包上也别硬刚直接看报错信息里缺的是哪个库单独 apt 装对应包就行。源码里如果有 Python 脚本记得检查一下可执行权限有时候明明代码没写错但rosrun就是找不到文件十有八九是没chmod x。3. UR5 与 AG95 的模型构建与 MoveIt 配置3.1 URDF/Xacro 模型把两个机器人拼成一个系统这套项目最核心的技术细节之一是把 UR5 和 AG95 整合进同一个 URDF 模型。UR5 官方提供了 xacro 格式的 URDF 文件但它默认的末端是空的需要自己挂载工具。AG95 是夹爪它的 URDF 可以从官方仓库找到但坐标系的定义不一定和 UR5 的 tool0 对齐。这里面有个关键概念在 URDF 里夹爪不是独立存在的它必须通过一个 joint 挂载到 UR5 的末端 link 上。项目的 xacro 文件里通常会有类似下面这一段link nameag95_base_link inertial origin xyz0 0 0 rpy0 0 0/ mass value0.5/ inertia ixx0.001 ixy0 ixz0 iyy0.001 iyz0 izz0.001/ /inertial visual geometry mesh filenamepackage://ur5_ag95_description/meshes/ag95_base.stl/ /geometry origin xyz0 0 0 rpy0 0 0/ /visual collision geometry mesh filenamepackage://ur5_ag95_description/meshes/ag95_base.stl/ /geometry /collision /link joint nametool0_to_ag95_base typefixed parent linktool0/ child linkag95_base_link/ origin xyz0 0 0.05 rpy0 0 0/ /joint这段代码的意思是说把 AG95 的基座通过一个固定关节连到 UR5 的 tool0 上并且做了 5 厘米的平移偏置。这里最需要注意的是origin里的 xyz 和 rpy 值它们必须和夹爪在真实机械臂上安装的位置、姿态完全一致。如果夹爪安装时歪了或者偏了这里没改那后面机械臂再怎么规划控制夹爪的中心点都不对。我自己在调类似项目时通常会在 RViz 里把模型调出来和真机摆拍的姿态对比一下用目测加尺量的方式先大致对齐再在运动过程中微调。3.2 MoveIt Setup Assistant 与规划组配置URDF 模型弄好之后下一步就是用 MoveIt Setup Assistant 来生成 MoveIt 配置文件。这条流程在官网文档里有标准教程但这个项目里有几个值得注意的点。第一规划组的划分。arm_group规划组需要包含从base_link到tool0或ag95_base_link的所有关节。AG95 的夹爪关节通常有两个手指关节要单独划一个规划组比如叫gripper_group。这样在 MoveIt 的 Motion Planning 面板里你可以单独测试机械臂运动也可以控制夹爪张合。如果两个规划组不分开MoveIt 会把夹爪的关节也当成机械臂的关节去规划经常导致规划出来的轨迹怪怪的夹爪还没到位就开始乱动手指。第二自碰撞矩阵ACM的生成。MoveIt 在配置时会让机器人自动检测哪些 link 之间永远不会碰撞生成一张禁用碰撞检测的矩阵。这里建议保留默认的采样密度但如果夹爪的 mesh 模型比较精细可以适当增大采样密度让碰撞检测更准确。代价是每次规划的耗时变长真机上如果规划频率不高问题不大。第三运动学求解器。UR5 有解析解配置时选 KDL 或者 UR 的专用解析 IK 插件都可以。推荐优先选 UR 专属的 kinematic solver速度和成功率都比 KDL 好不少。如果你发现同样的目标位姿KDL 经常求不出解而 UR 解析器一秒出结果就是这个原因。3.3 AG95 夹爪的 ROS 集成方式AG95 是电爪控制方式有串口、Modbus RTU 等几种。在 ROS 里集成夹爪有两种常见方案一种是把夹爪当成独立的 ROS 节点通过串口和夹爪通信用 std_msgs/Float64 之类的消息控制开合另一种是把夹爪的关节状态通过 joint_states 话题发布到 ROS 里让 MoveIt 也能看到夹爪的实时位置。这套项目的文档里推荐的是第一种即把 AG95 的控制封装成一个独立的 service 或者 action server收到夹爪开合指令后再通过串口发给夹爪。这么设计的好处是夹爪逻辑和 MoveIt 规划解耦夹爪的驱动代码出问题了不会影响机械臂的规划模块。代码结构上通常会有gripper_controller.py这样单独的文件里面封装了open()、close()、set_width()等方法底层的串口通信用了 pyserial 库。如果你还没买 AG95只是用仿真验证那就在仿真里用 Gazebo 的夹爪插件接口设计得和真机节点一致就行后续切换到真机只需要改底层通信函数。4. 抓取流程核心代码实现拆解4.1 位姿获取与 TF 坐标变换抓取流程的第一步是拿到目标物体的位姿。在这个项目里目标位姿的来源有几种从话题订阅比如相机识别结果、从文件读取、或者直接硬编码在 launch 参数里。无论来源是哪拿到的位姿通常需要转换到机械臂基座坐标系下。这里就涉及到 TF 树的理解。UR5 的 TF 树一般是base_link→ ... →tool0→ag95_base_link。如果视觉相机安装在别的位置比如桌面旁边那么目标位姿最初是在camera_link坐标系下的必须通过tf2工具转换到base_link坐标系下才能给 MoveIt 用。代码里通常是这么处理的import rospy import tf2_ros from geometry_msgs.msg import PoseStamped tf_buffer tf2_ros.Buffer() tf_listener tf2_ros.TransformListener(tf_buffer) def transform_pose(input_pose, target_frame): try: transform tf_buffer.lookup_transform( target_frame, input_pose.header.frame_id, rospy.Time(0), rospy.Duration(1.0) ) # 手动做坐标变换 ... except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException) as e: rospy.logerr(fTF transform failed: {e}) return None这里有一个容易翻车的细节TF 的 lookup_transform 用的是 rospy.Time(0) 还是当前时间戳。在仿真环境里用当前时间戳一般没问题但在真机上相机图像处理有延迟如果用当前时间去查 TF可能查不到未来时刻的变换会报 ExtrapolationException。稳妥的做法是用rospy.Time(0)拿最近一帧的变换或者直接在图像处理节点里记录好时间戳再把时间戳传给 TF 查询。4.2 MoveIt 运动规划与执行MoveIt 在 Python 里的使用逻辑非常清晰核心就三步设置目标位姿→规划→执行。项目源码中这一段是核心import moveit_commander import rospy from geometry_msgs.msg import PoseStamped moveit_commander.roscpp_initialize(sys.argv) robot moveit_commander.RobotCommander() scene moveit_commander.PlanningSceneInterface() arm_group moveit_commander.MoveGroupCommander(arm_group) arm_group.set_pose_reference_frame(base_link) # 设置目标位姿 target_pose PoseStamped() target_pose.header.frame_id base_link target_pose.pose.position.x 0.4 target_pose.pose.position.y 0.1 target_pose.pose.position.z 0.3 target_pose.pose.orientation.x 0.0 target_pose.pose.orientation.y 0.0 target_pose.pose.orientation.z 0.0 target_pose.pose.orientation.w 1.0 arm_group.set_pose_target(target_pose, end_effector_linkag95_base_link) plan arm_group.plan() arm_group.execute(plan, waitTrue)有几个地方值得专门说一下。set_pose_reference_frame决定了你给的目标位姿是在哪个坐标系下解释的。一般用base_link如果你用了别的坐标系必须先确保 TF 树完整。end_effector_link参数非常关键它告诉 MoveIt 你要把目标位姿给到哪个 link。这里可以填tool0也可以填ag95_base_link差别在于最终夹爪尖端的位置会差一个固定的偏置。如果你视觉识别出来的是夹爪中心要到达的位置那应该填ag95_base_link或者更精确的ag95_finger_link。plan()返回的结果里包含trajectory和planning_time。如果plan()失败最常见原因是运动学无解或者碰撞检测到路径上有障碍。项目源码里通常会对失败情况做重试比如随机调整目标位姿的微小偏移或者换一个规划算法再试一次。这个重试逻辑在实际使用中非常重要尤其是在复杂场景里一次规划成功率可能只有 70%加上两三次重试就能到 95% 以上。4.3 AG95 夹爪控制与抓取完成判断机械臂运动到抓取位姿后接下来就是控制 AG95 闭合。在项目代码里这个动作通常是一个简单的 service 调用from std_srvs.srv import Trigger rospy.wait_for_service(/gripper/close) try: close_gripper rospy.ServiceProxy(/gripper/close, Trigger) resp close_gripper() if resp.success: rospy.loginfo(Gripper closed successfully) except rospy.ServiceException as e: rospy.logerr(fGripper close failed: {e})真实的抓取逻辑不能只发一个关闭指令就完事。你需要判断夹爪是否真的抓到了东西。AG95 这类电爪通常能反馈电流或者位置误差如果夹爪到达目标宽度但电流异常升高说明可能卡住了如果闭合过程中位置误差一直很大说明夹爪可能没接触物体或者物体滑落了。这个项目源码里虽然没有做复杂的力控但提供了一个简单的超时和电流阈值判断。比如给夹爪 3 秒时间完成闭合如果电流超过某个阈值认为已经夹紧可以进入提拉阶段。这个阈值怎么定需要根据实际场景调整。我自己的经验是先空爪闭合测一下正常电流再夹一个目标物体测一下夹紧电流取中间值或者比空爪电流高 20% 左右的值作为阈值比较靠谱。5. 真机调试中的常见问题与排查技巧5.1 MoveIt 规划失败的排查清单规划失败是抓取流程里最频繁遇到的问题报错信息五花八门但根因就那么几类。我整理了一个排查顺序按优先级从高到低排列运动学无解目标位姿离机械臂工作空间太远或者姿态不可达。先检查目标点在 RViz 里是不是显示在可达范围内把机械臂手动拖到目标点附近看 IK 能不能解。如果是夹爪姿态的问题尝试调整目标姿态的欧拉角很多时候只是手抓的姿态太奇葩稍微换个角度就解出来了。碰撞检测误报URDF 里的碰撞 mesh 和视觉模型存在偏差导致实际不碰但检测为碰撞。把 PlanningScene 里的障碍物物体删掉或者屏蔽试一次。如果删了就能规划那就是场景建模的问题需要把碰撞体调整得比实际物体稍微小一点留出余量。规划时间太短MoveIt 默认的规划时间限制是 5 秒但复杂场景可能需要 10 秒甚至更长。在 MoveIt 配置文件里把planning_time_limit调大一点或者用arm_group.set_planning_time(10.0)改单次规划的时间。约束设置错误如果你在 MoveIt 里设置了路径约束例如保持末端水平那规划成功率会大幅降低。检查一下是否误开了约束。5.2 坐标系与 TF 的问题坐标系问题是最隐蔽的坑因为代码不报错但机械臂就是抓偏了。最常见的现象是机械臂规划的末端位姿在 RViz 里看起来是对的但真机执行后发现夹爪和目标点差了固定的几厘米。这时候基本上可以确定是某个环节的坐标系偏置错了。排查方法是在机械臂停在某个姿态时手动查一下当前ag95_base_link在base_link下的坐标。对比一下从 URDF 模型里推算出的理论值看看偏差是不是一个常数。如果是常数那就去查 URDF 里tool0_to_ag95_base这个关节的 origin 值八成是那里的 xyz 和实际安装尺寸对不上。还有一种情况是视觉系统的标定参数有问题相机外参不准会导致目标位姿本身就有偏差这种就要重新做手眼标定不是代码能调回来的。5.3 仿真正常但真机抖动或失控很多人在仿真里跑得好好的一到真机就出问题机械臂抖动、轨迹顿挫甚至触发急停。这个问题的根源多半是控制频率和 MoveIt 轨迹平滑度不匹配。UR5 官方驱动默认的控制频率是 500Hz但 MoveIt 规划出来的轨迹点之间间隔可能是 50ms 甚至 100ms直接下发会有明显卡顿。解决方法是开启驱动里的轨迹插值功能让驱动自动在轨迹点之间做平滑过渡。另外真机上建议把速度和加速度缩放因子设小一点比如arm_group.set_max_velocity_scaling_factor(0.3)、set_max_acceleration_scaling_factor(0.3)不要让机械臂全力猛冲尤其是第一次跑真机的时候。AG95 夹爪还有一个容易忽略的点很多电爪在启动时需要先进行位置归零校准否则反馈的宽度值会漂移。在项目启动脚本里最好加一步夹爪初始化动作——先完全张开再回到零点确保后续控制的准确性。6. 实操心得与项目扩展方向跑完整个项目后我最大的感受是这套源码的价值不在于一次抓取有多成功而在于把 ROSMoveIt 机械臂开发的标准流程完整地走了一遍。从 URDF 建模到 MoveIt 配置从 TF 坐标变换到运动规划从夹爪控制到真机调试每一个环节都有对应的代码和文档。你只要认真跟一遍基本上就把 MoveIt 的开发套路吃透了。从项目源码出发后续有几个很自然的扩展方向。第一是接入视觉识别用相机做目标检测和位姿估计把人工指定的目标位姿替换成实时识别的结果这就变成了完整的视觉抓取系统。第二是加入物体姿态估计的细化比如用点云配准算法ICP来优化目标物体的精确位姿能明显提高抓取精度。第三是把抓取流程封装成行为树或者状态机让系统的状态切换更可靠比如抓取失败时进入重试策略这部分工程价值很大。最后分享一个我自己调试这类项目的小习惯不管是在仿真还是真机我都习惯先把目标位姿设成一个非常保守的位置比如桌子正上方 10 厘米先验证整个流程能不能跑通再逐步逼近真实抓取点。这样一旦出问题可以快速判断是规划问题、坐标问题还是夹爪问题。这套项目的源码结构其实也是按这个思路组织的每个模块都能独立测试善用这个特性你可以省下大量调试时间。本文还有配套的精品资源点击获取
分享:

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

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