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

UR5+AG95机械臂抓取实战:从MoveIt配置到Python控制完整指南

简介基于Python、ROS与MoveIt实现的UR5机械臂配合AG95夹爪抓取项目面向机器人方向课程设计、期末大作业及ROS入门学习者解决给定位姿下机械臂运动规划与夹爪抓取的问题。资源为zip压缩包共34个文件涵盖Python脚本、launch启动文件、yaml/tf配置文件、README及多张运行截图/坐标系示意图便于对照环境部署与效果验证。包体约9.33MB结构紧凑。该项目包含完整源码与文档解析关键代码带注释即使新手也能按说明跑通抓取流程适用于仿真与实机迁移。已有239人学习或下载可作为期末大作业、课程设计的高分参考方案。 搞机械臂抓取这件事很多朋友问我要过现成的Demo参考。UR5配合AG95夹爪是我用过几套协作机器人组合里开发周期和效果平衡得比较好的方案。这套组合最常见的落地场景就是让机械臂运动到指定坐标点张开夹爪、闭合夹爪完成“给定位姿的抓取”这个动作。听起来很简单但真正从零搭起来涉及的环节不少——机器人模型描述、MoveIt运动规划、坐标系标定、夹爪控制通讯每一环都有坑等着你。这篇文章我把这套项目从架构到实操完整拆解一遍内容包括为什么选ROSMoveIt、URDF和SRDF怎么配置、Python端抓取程序怎么写、以及真机调试时最常踩的坑。如果你正准备做UR5的抓取项目或者手里有一台机械臂但不知道从哪下手这篇文章可以帮你省下至少两周的摸索时间。1. 项目逻辑与方案选型拆解1.1 为什么是UR5AG95这套组合先说硬件。UR5是优傲家的六轴协作机械臂负载5公斤重复定位精度±0.03mm工作半径850mm。放在桌面级别的抓取场景里它的尺寸和精度都很合适。更关键的是UR5的关节结构设计——它的腕部关节有比较灵活的姿态调整空间在靠近目标点做末端姿态微调时不像某些四轴机械臂那样受限严重。配合AG95这个两指电动夹爪整套系统的抓取负载和指面行程都能覆盖常见的小型工件搬运任务。AG95是OnRobot家的电爪夹持力可以调节最大夹持力能达到40N左右。它跟UR5的配合方式很灵活既可以通过UR的Tool法兰直接供电通讯也可以使用独立的Modbus RTU接口控制。在我们的项目里用的走的是RS485转Modbus的通讯方案这样夹爪控制和机械臂运动控制是两条独立的链路调试时可以分别排查问题不会一个地方坏了全瘫。1.2 为什么选用ROSMoveIt作为控制框架自己写逆运动学解算听上去很“硬核”但实际做抓取项目时完全没必要。MoveIt是ROS生态里做运动规划的事实标准它把机器人的URDF模型、运动学插件、碰撞检测、规划器全集成好了。你要做的只是把UR5的模型导进去生成MoveIt配置包然后通过move_group这个节点对外提供规划服务。选MoveIt还有一个非常现实的原因它内置了OMPL库的多种运动规划算法比如RRTConnect、PRM、BITStar这些。在机械臂从初始位姿运动到抓取位姿的过程中MoveIt会自动规划一条无碰撞的路径。如果你自己写规划算法光是碰撞检测和路径平滑就够你折腾一两个月。MoveIt虽然也有不少学习门槛但它是社区维护的标准工具遇到问题搜得到答案这是自研方案没法比的。至于Python端的开发说实话Python在实时控制层面并不占优势真正的底层关节控制还是靠UR的控制器和URScript脚本。Python扮演的角色更像是一个“指挥官”——利用move_group的Python接口设置目标位姿、发起规划请求、接收规划结果、下发执行指令。这也是ROS体系里最典型的开发模式顶层逻辑用Python快速迭代底层执行交给C和硬件控制器。1.3 整体架构流程整个项目的运行流程可以概括为启动UR5的驱动节点建立上位机与机械臂控制器的通讯让MoveIt能拿到当前关节状态和机器人模型。启动MoveIt的move_group节点加载URDF模型、SRDF配置和运动学插件。通过Python脚本调用move_group提供的服务接口把“给定位姿”传给move_group做运动规划。规划器算出各关节的运动轨迹经过碰撞检测确认安全后发布到话题上驱动节点将轨迹转换为URScript指令下发给机械臂执行。机械臂运动到目标位姿后Python脚本通过Modbus向AG95夹爪发送闭合指令完成抓取。这套架构的好处在于每个环节都是解耦的。哪一步出了问题可以直接在对应的节点和话题上排查不需要从头到尾翻代码。2. 核心配置与关键细节解析2.1 从URDF到MoveIt配置包项目的第一步是准备UR5和AG95的URDF模型。UR5官方提供了标准URDF文件但通常需要做一些修改——主要是加上AG95夹爪的模型并把夹爪的坐标系挂到UR5末端法兰坐标系tool0下面。这里有个非常关键的细节UR5的标准URDF里从base_link到tool0的坐标变换是用宏定义方式生成的xacro文件里通过$(find ur_description)这样的路径引用模型文件。你在添加AG95时需要新建一个launch文件通过xacro:include同时引入UR5和AG95的URDF再用一个joint把两者连接起来。连接方式一般定义成固定关节typefixed原点偏移根据AG95安装法兰的实际尺寸来填。假设AG95的安装面到夹爪抓取中心点的距离实测是118mm那么URDF里可以这样定义joint nametool0_ag95_joint typefixed parent linktool0/ child linkag95_base_link/ origin xyz0 0 0.118 rpy0 0 0/ /joint这个118mm如果填错了后果很严重——MoveIt规划出来的抓取位姿是基于夹爪坐标系的如果坐标系不对机械臂末端到达的位置就是错的甚至可能直接撞到工件或者工作台。所以这个偏移值一定要拿尺子量不要照抄别人的数据。2.2 MoveIt Setup Assistant的配置要点URDF准备好之后用MoveIt Setup Assistant生成配置包。启动命令是roslaunch moveit_setup_assistant setup_assistant.launch加载URDF文件后你会进入配置向导界面。有几个地方需要特别注意第一是定义规划组。建议把UR5的六个关节设一个规划组命名比如arm_group类型选Kinematic Chain规划组的基座链选base_link到wrist_3_link。AG95夹爪的指节也要规划但不需要做逆解用Planning Group里General类型即可或者直接把夹爪关节加进一个独立规划组用来控制开合。如果你希望夹爪在规划时不被当作障碍物还需要在规划组的配置里设置允许碰撞的矩阵否则MoveIt会把夹爪自身模型之间的碰撞判定为规划失败。第二是定义预定义位姿。在Setup Assistant里可以设置一个“home”位姿和“pregrasp”位姿后续通过Python脚本按名字调用会方便很多。第三是运动学插件选择。UR5默认用KDL做逆解但KDL在某些奇异位形下会解不出来。建议在配置文件里加上TRAC-IK插件解算成功率和速度都更好。具体的做法是在kinematics.yaml里修改插件名称这个文件在MoveIt配置包的config目录下。2.3 坐标系规划从base_link到grasp_frame抓取项目最容易出问题的地方就是坐标系规划不清晰。整个系统的坐标系至少涉及这几个base_linkUR5的基座坐标系MoveIt规划的参考系默认是它。tool0UR5末端法兰坐标系。ag95_grasp_frame夹爪抓取中心坐标系也就是你期望工件被抓取时所在的参考坐标系。MoveIt规划时你发送的目标位姿如果是相对于base_link的那么Python代码里就要用planning_frame指定的坐标系。通常在MoveIt配置包里planning_frame默认就是base_link。这意味着你给代码传入的目标位姿是相对于机械臂基座的位置和姿态。这里我建议在项目里统一维护一个坐标变换的模块把所有抓取点都定义在工件的世界坐标系下再通过静态坐标变换发布器把工件坐标系与base_link关联起来。比如你有一个视觉系统输出抓取点的坐标那视觉坐标系和base_link之间的变换就需要通过标定得到发布成static_transform_publisher这样MoveIt才能正确规划。3. 实操过程与核心环节实现3.1 驱动层启动机器人驱动MoveIt整个系统的启动流程我建议分步启动不要一上来就一个launch全部拉起来出了问题不好排查。第一步启动UR5的驱动。现在主流的做法是用ros_control配合ur_robot_driver这个包。UR5的控制器通过TCP与上位机通讯需要确保上位机和机械臂的网线连通并且设置了正确的静态IP。UR5控制器的默认IP一般是192.168.1.x段具体以你们现场网络规划为准。启动驱动的命令大概是roslaunch ur_robot_driver ur5_bringup.launch robot_ip:192.168.1.10UR5新版本的控制柜还需要安装对应的URCap外部脚本驱动启动前要在示教器上确认URCap已经加载否则驱动节点会一直等待和机械臂的通讯握手。第二步启动MoveIt配置包roslaunch ur5_ag95_moveit_config moveit_planning_execution.launch这个launch会同时启动move_group节点、规划器的配置、以及RViz可视化界面。我强烈建议保留RViz因为在做真机抓取之前先用RViz里的虚拟机械臂把轨迹模拟一遍能发现很多潜在问题——比如轨迹通过不可达区域、末端朝向不合理、机械臂撞到工作台面等。3.2 Python端抓取程序设计核心的抓取逻辑代码思路很清晰就是初始化MoveGroupCommander设置目标位姿规划执行控制夹爪。下面是一段关键代码#!/usr/bin/env python # -*- coding: utf-8 -*- import rospy import sys import copy import moveit_commander import moveit_msgs.msg import geometry_msgs.msg from math import pi from std_msgs.msg import String from moveit_commander.conversions import pose_to_list def main(): moveit_commander.roscpp_initialize(sys.argv) rospy.init_node(ur5_ag95_pick_node, anonymousTrue) robot moveit_commander.RobotCommander() scene moveit_commander.PlanningSceneInterface() group moveit_commander.MoveGroupCommander(arm_group) # 设置规划参考坐标系和允许的误差 group.set_planning_reference_frame(base_link) group.set_goal_position_tolerance(0.001) group.set_goal_orientation_tolerance(0.01) group.set_planning_time(5.0) # 先运动到home位姿 group.set_named_target(home) plan_home group.plan() group.execute(plan_home, waitTrue) rospy.sleep(1) # 设置目标位姿这里的坐标值以实际抓取点为准 target_pose geometry_msgs.msg.Pose() target_pose.position.x 0.35 target_pose.position.y 0.0 target_pose.position.z 0.25 target_pose.orientation.x 1.0 target_pose.orientation.y 0.0 target_pose.orientation.z 0.0 target_pose.orientation.w 0.0 group.set_pose_target(target_pose) # 规划并执行 success, plan, planning_time, error_code group.plan() if success: rospy.loginfo(plan success, time: %.2f, planning_time) group.execute(plan, waitTrue) else: rospy.logerr(plan failed, error code: %s, error_code) moveit_commander.roscpp_shutdown() sys.exit(1) rospy.sleep(1) # 控制AG95闭合夹爪 # 通过Modbus RTU发送闭合指令功能码和寄存器地址以AG95手册为准 import serial ser serial.Serial( port/dev/ttyUSB0, baudrate115200, bytesizeserial.EIGHTBITS, parityserial.PARITY_NONE, stopbitsserial.STOPBITS_ONE, timeout0.5 ) # AG95闭合指令示例0x09 0x10 0x03 0xE8 0x00 0x01 0x02 0x00 0x64 CRC cmd bytes([0x09, 0x10, 0x03, 0xE8, 0x00, 0x01, 0x02, 0x00, 0x64, 0xC4, 0x0B]) ser.write(cmd) ser.close() rospy.sleep(1) # 夹爪闭合后回到home位姿 group.set_named_target(home) plan_home2 group.plan() group.execute(plan_home2, waitTrue) moveit_commander.roscpp_shutdown() if __name__ __main__: main()代码本身不复杂但有几点想说group.plan()返回的success一定要判断不要盲目执行。实际调试中规划失败的场景非常多——目标点在工作空间之外、姿态约束过于苛刻、或者规划时间不够。如果规划失败还继续执行机械臂会保持原地不动而你完全不知道发生了什么。set_goal_position_tolerance和set_goal_orientation_tolerance这两个参数也值得注意。真机执行时MoveIt规划的轨迹最终会有跟踪误差如果你把容差设得太严苛比如0.0001机械臂稍微差一点点就会被认为是执行失败。我一般调到0.001和0.01对抓取场景足够用了。夹爪的控制方式上面代码用的是直接通过串口发Modbus RTU指令。实际项目里OnRobot提供了一套完整的ROS驱动可以更快地集成但底层原理一致。如果没有现成的ROS驱动包直接用串口发指令是最快能跑通的方式。3.3 给定位姿的标定与验证很多人拿到项目后直接就把视觉系统给出的坐标填到目标位姿里结果机械臂跑过去偏得离谱。这中间缺了一个环节坐标系的标定与验证。要做到“给定位姿的抓取”首先要确定“给定位姿”是在哪个坐标系下定义的。如果是视觉引导抓取那视觉系统输出的目标点坐标通常是在相机坐标系下的你需要通过标定板求相机到机械臂基座的变换矩阵。标定的方法有现成的手眼标定工具比如使用easy_handeye这个包。操作流程大概是将标定板固定在机械臂末端用相机识别标定板得到相机坐标系到标定板坐标系的变换然后记录当前机械臂末端在base_link下的位姿通过多组数据求解出相机到机械臂基座的固定变换。这整个过程如果手做可能需要半天时间但一次性标定好后续换抓取点就不用重新标了。如果你没有视觉系统只是手动指定一些固定位置的抓取点那最简单的验证方式是先把机械臂手动示教到目标位置在示教器上记录当前的TCP位姿把它作为代码里的目标位姿。这样你可以确保这个位姿是可达的而且坐标系关系不会出错。4. 常见问题与排查技巧实录4.1 规划失败问题可能不在规划器实际调试时最常遇到的就是MoveIt规划失败。常见原因有三个按优先级排查第一目标点不在机械臂工作空间内。UR5的工作半径虽然标称850mm但末端姿态不同实际可达范围变化很大。尤其是末端朝下俯仰90度的抓取姿态工作空间会明显缩小。排查方法是把目标位姿放到RViz里看虚拟机械臂能不能手动拖动到那个位置。第二路径规划过程中存在碰撞。MoveIt默认会加载整个场景的碰撞检测。如果你的工作台上放着工装夹具而URDF模型里没有建模MoveIt会认为那里是空的规划出来的轨迹可能直接穿过工装。反过来也一样——如果你建模了但实际位置有偏差MoveIt可能觉得有碰撞就不敢规划。处理方式是视情况给PlanningScene添加碰撞物体或在允许的情况下设置忽略碰撞矩阵。第三姿态约束过于苛刻。比如你要求末端必须严格垂直于台面roll和pitch都精确为零这会让逆解变得非常困难。解决办法是放开一点容差或者调整夹爪的安装角度让姿态约束更温和。4.2 夹爪控制失灵大多是通讯问题AG95的控制问题我调试时最常遇到的就是串口打开失败和通讯超时。串口打开失败的常见原因是权限问题运行用户不在dialout组里写入不了/dev/ttyUSB0。解决办法是sudo usermod -a -G dialout $USER还有一种情况是USB转串口模块不稳定建议换用质量好一点的FTDI芯片的转接器CH340在长时间高频率通讯下偶尔会掉线。Modbus通讯超时的话先检查CRC校验是否正确、波特率是否匹配、以及AG95的拨码地址是否和代码里的一致。AG95出厂默认地址通常是0x09如果你改了拨码需要同步修改指令里的从站地址字段。4.3 真机抖动或轨迹“飞”出去这是一个仿真转真机很经典的问题。MoveIt规划出来的关节轨迹在仿真环境里跑得非常顺滑但到了真机上机械臂抖动甚至在某些点位轨迹会出现明显的“甩出去”的视觉冲击。这通常不是因为规划器出了错而是因为速度和加速度缩放比例没设置好。UR5的控制器在接收MoveIt轨迹后会按控制器允许的最大速度和加速度来执行。MoveIt默认生成的速度/加速度缩放比例是1.0也就是按极限跑。我的习惯是把速度缩放设为0.2左右加速度缩放设为0.1左右真机运行会平滑得多group.set_max_velocity_scaling_factor(0.2) group.set_max_acceleration_scaling_factor(0.1)这样牺牲一点节拍时间但对设备的安全、机械臂寿命和调试阶段的体验都有明显的好处。等整个流程跑稳定了再逐步把缩放系数调大。4.4 批量抓取时位姿漂移如果你的程序是循环抓取多个工件有时候会发现每次机械臂回到同一个位置时末端实际落点都不一样误差越来越大。这通常不是MoveIt的问题而是坐标系源头的误差被一路累积放大。最常见的情况是视觉系统给出目标工件坐标的精度不够或者视觉坐标系与base_link的标定矩阵有误差。在批量抓取前我建议先用一个固定位置的工件反复测试确认机械臂每次都能到达同一个可重复的抓取位置确认无误后再切换到视觉引导模式。如果固定位置都很稳定但视觉引导每次都偏问题就基本锁定在视觉标定上需要重新做手眼标定。最后再分享一个我的个人习惯每次做抓取实验前先手动操纵示教器把机械臂移到几个关键点位确认实际空间中没有干涉和遮挡然后再开始跑程序。这个习惯帮我避免了好几次撞机和飞车。另外建议在Python程序里加一个“预抓取位姿”的中间点——先让机械臂从一个安全高度运动到目标点正上方再垂直下降抓取这样做比让机械臂从任意方向直接逼近目标点要安全得多。UR5的协作机器人特性虽然让它的人机交互相对安全但该保守的地方还是保守一些为好。本文还有配套的精品资源点击获取
分享:

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

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