OnRobot RG2/RG6夹爪的两种控制模式全解析:Teach Mode与Compute Box的ROS实现差异对比

机器人抓取(二)—— ROS 控制 onrobot RG2 / RG6 机械手(第二代) 2. rg6机械手控制 rg6通信 控制指令发送 阅读详情

OnRobot RG2/RG6夹爪的两种控制模式深度解析:从Teach Mode到Compute Box的ROS集成实战

在机器人集成项目中,末端执行器的选择与控制策略往往是决定系统灵活性与可靠性的关键。OnRobot的RG2和RG6二指夹爪以其出色的自适应能力、宽行程和即插即用的设计,成为众多协作机器人应用中的热门选择。然而,许多开发者在初次接触这两款设备时,往往会遇到一个核心困惑:为何网络上找到的ROS控制代码在自己的RG6上无法运行?这背后隐藏的,正是OnRobot夹爪两代控制协议——Teach Mode与Compute Box——在底层架构上的根本性差异。

理解这两种模式的差异,不仅仅是解决“代码不工作”的问题,更是为项目选择正确技术路径、设计稳健控制系统的前提。本文将深入剖析这两种控制模式的技术原理、通信机制,并提供详尽的ROS驱动开发方案,帮助你在机器人集成项目中做出明智的决策。

1. 技术架构演进:从直接I/O到网络化智能控制

OnRobot夹爪的控制模式演变,反映了工业机器人末端工具从简单执行器向智能化、网络化发展的趋势。第一代RG2/RG6主要依赖Teach Mode,这是一种与机器人控制器深度绑定的直接控制方式。而第二代产品则引入了Compute Box,一个独立的外部处理单元,将夹爪的控制逻辑从机器人控制器中解耦出来。

1.1 Teach Mode:直接工具端口控制

在Teach Mode下,夹爪通过快换装置(Quick Changer)直接连接到机器人末端的工具端口。这种连接方式简单直接,物理上通常使用机器人的数字输出(DO)或工具输出(TO)端口来发送简单的开合指令。

核心通信原理:

  • 物理连接:夹爪的电源与控制信号线直接接入机器人控制柜的I/O端子板。
  • 控制信号:通常使用两个数字输出信号(如DO8和DO9)分别控制夹爪的“张开”和“闭合”动作。
  • 状态反馈:夹爪的抓取状态(如“已抓取”、“抓取失败”)通过数字输入(DI)端口返回给机器人控制器。

这种模式的优势在于极低的延迟和简单的配置。开发者无需额外的硬件,只需在机器人示教器上配置几个I/O点,就能实现基本的抓取控制。然而,其局限性也十分明显:控制粒度粗糙(通常只有开/合两种状态),无法实现精确的宽度或力控,且严重依赖于特定机器人品牌的I/O系统。

注意:许多早期开源项目和教程(包括一些在GitHub上广泛流传的代码)都是基于这种模式开发的。如果你的夹爪是较新的型号或采用了Compute Box配置,这些代码将无法直接使用。

1.2 Compute Box:网络化智能控制单元

Compute Box代表了OnRobot夹爪控制的第二代架构。它是一个独立的小型计算单元,通过以太网与机器人控制器通信,而夹爪本身则连接到Compute Box上。

系统架构对比:

特性Teach ModeCompute Box
物理连接夹爪直连机器人工具端口夹爪连接Compute Box,Compute Box通过网线连接机器人
通信接口机器人数字I/O(DO/DI)以太网(TCP/IP)
控制粒度二进制(开/合)连续(可指定宽度、力、速度)
编程接口机器人I/O指令URScript函数、WebLogic、REST API
部署灵活性低(依赖特定机器人I/O)高(支持多种机器人品牌)
功能丰富度基础开合高级功能(力控、宽度反馈、自动TCP计算)

Compute Box的核心价值在于功能解耦和智能化。它将复杂的夹爪控制逻辑(如PID控制、运动规划、状态监控)从机器人控制器中剥离,让机器人只需发送高级指令(如“以40N的力抓取到50mm宽度”),而具体的执行细节由Compute Box处理。这种架构不仅提升了控制精度,还通过标准网络协议增强了系统的可扩展性。

2. 深入Compute Box:协议、接口与限制

对于采用Compute Box的RG2/RG6夹爪,开发者主要可以通过三种方式进行控制:URScript函数、WebLogic编程以及直接的I/O映射。每种方式都有其适用场景和限制。

2.1 URScript函数:理想与现实的差距

OnRobot官方文档会提到一个名为rg_grip()的URScript函数,它看起来是控制夹爪最自然的方式:

# 示例:在UR示教器PolyScope中使用的URScript
rg_grip(rg_width=50, force=40, tool_index=0, blocking=True)

这个函数参数丰富,可以指定抓取宽度、目标抓取力,并支持阻塞模式等待抓取完成。然而,这里有一个至关重要的陷阱:rg_grip()函数是一个“非原生”的URScript函数。它是由OnRobot URCap在机器人示教器环境中注入的,并不存在于UR控制器(URControl)的原生函数库中。

这意味着,如果你尝试通过外部计算机的TCP Socket直接向机器人发送包含rg_grip()的URScript指令,控制器会返回一个“未知函数”的错误。UR+的技术支持确认了这一点:这些函数只在PolyScope脚本环境中可用。

绕过限制的尝试与结果:

  1. 通过Dashboard Server远程启动:理论上可行,但需要复杂的权限和会话管理,实操难度大。
  2. 复制函数定义一起发送:从示教器生成的.script文件中提取函数定义,随指令一起发送。遗憾的是,由于函数依赖PolyScope的运行时环境,这种方法通常也以失败告终。
# 一个常见的失败尝试:通过socket发送提取的函数定义
import socket
import time

HOST = "192.168.1.2"  # 机器人控制器IP
PORT = 30003          # 主客户端接口端口

# 从示教器脚本中复制的rg_grip函数定义(通常无效)
function_definition = """
def rg_grip(rg_width=0.0, force=0.0, tool_index=0, blocking=False, depth_compensation=False, popupmsg=True):
  # ... 冗长的函数体 ...
end
"""

grip_command = """
sec myProgram()
  rg_grip(50, 40, 0, True)
end
"""

full_script = function_definition + grip_command

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))
sock.send(full_script.encode())
time.sleep(0.1)
sock.close()

2.2 WebLogic与I/O映射:可靠的“曲线救国”方案

既然直接调用高级函数行不通,最稳定可靠的方法是利用Compute Box的WebLogic编程功能,将其配置为监听机器人控制器的特定数字输出(DO),并据此执行预定义的夹爪动作。

配置流程概述:

  1. 物理连接:使用网线将Compute Box、机器人控制柜和上位机(如运行ROS的Jetson)连接到同一网络交换机。
  2. 访问Web界面:在浏览器中输入Compute Box的默认IP(通常是192.168.1.1),登录OnRobot的WebLogic配置界面。
  3. 逻辑编程:在WebLogic中创建简单的逻辑程序,例如:
    • 当 DI0(映射自机器人DO6)变为高电平 -> 执行 “夹爪闭合”动作。
    • 当 DI1(映射自机器人DO7)变为高电平 -> 执行 “夹爪张开”动作。
  4. 状态反馈:同样可以配置Compute Box的数字输出(DO)来反馈夹爪状态(如DO1表示“抓取成功”),并将其连接回机器人的数字输入(DI)。

完成上述配置后,控制夹爪就简化为控制机器人的几个DO信号。虽然这牺牲了部分高级功能(如精确宽度控制),但获得了极高的可靠性和兼容性。

3. ROS驱动开发实战:为两种模式构建稳健接口

基于以上分析,我们可以为两种控制模式分别设计ROS驱动。下面的实战指南将帮助你快速搭建可用的控制节点。

3.1 Teach Mode下的ROS驱动实现

对于Teach Mode,驱动逻辑相对简单,核心是通过ROS服务或话题调用UR机器人的set_io服务来翻转特定的DO引脚。

首先,创建一个ROS功能包,并编写夹爪控制类:

#!/usr/bin/env python
# 文件:ur_rg_gripper/scripts/gripper_teach_mode.py

import rospy
from ur_msgs.srv import SetIO, SetIORequest
from ur_msgs.msg import IOStates
from std_msgs.msg import String

class TeachModeGripper:
    """
    Teach Mode下的RG2/RG6夹爪控制类。
    假设夹爪通过DO8(张开)和DO9(闭合)控制,DI0用于抓取检测。
    """
    def __init__(self):
        # 等待UR硬件的set_io服务就绪
        rospy.wait_for_service('/ur_hardware_interface/set_io')
        self.set_io_srv = rospy.ServiceProxy('/ur_hardware_interface/set_io', SetIO)

        # 引脚定义(根据实际接线调整)
        self.pin_open = 8   # DO8 控制张开
        self.pin_close = 9  # DO9 控制闭合
        self.pin_detect = 0 # DI0 用于抓取检测

        rospy.loginfo("Teach Mode Gripper driver initialized.")

    def _set_output(self, pin, state):
        """设置单个数字输出引脚的状态"""
        try:
            # UR的set_io服务参数:fun (1=digital out), pin, state
            req = SetIORequest()
            req.fun = 1
            req.pin = pin
            req.state = state
            resp = self.set_io_srv(req)
            return resp.success
        except rospy.ServiceException as e:
            rospy.logerr("Service call failed: %s", e)
            return False

    def open(self):
        """张开夹爪:置位DO8,复位DO9"""
        self._set_output(self.pin_close, 0)  # 确保闭合信号为低
        rospy.sleep(0.05)  # 短暂延时,确保信号稳定
        success = self._set_output(self.pin_open, 1)
        if success:
            rospy.loginfo("Gripper open command sent.")
        return success

    def close(self):
        """闭合夹爪:置位DO9,复位DO8"""
        self._set_output(self.pin_open, 0)   # 确保张开信号为低
        rospy.sleep(0.05)
        success = self._set_output(self.pin_close, 1)
        if success:
            rospy.loginfo("Gripper close command sent.")
        return success

    def stop(self):
        """停止夹爪:同时复位DO8和DO9"""
        self._set_output(self.pin_open, 0)
        self._set_output(self.pin_close, 0)
        rospy.loginfo("Gripper stop command sent.")

    def is_grasped(self):
        """读取抓取检测状态(DI0)"""
        try:
            # 订阅IO状态话题
            io_states = rospy.wait_for_message('/ur_hardware_interface/io_states', IOStates, timeout=1.0)
            # 假设DI0是digital_in_states列表的第一个元素(需根据实际确认)
            return io_states.digital_in_states[self.pin_detect].state
        except (rospy.ROSException, IndexError) as e:
            rospy.logwarn("Failed to read gripper state: %s", e)
            return False

if __name__ == '__main__':
    rospy.init_node('rg_gripper_teach_mode')
    gripper = TeachModeGripper()

    # 示例:创建一个服务或话题接口来控制夹爪
    # 这里简化为一个接收字符串命令的话题订阅者
    def command_callback(msg):
        if msg.data == "open":
            gripper.open()
        elif msg.data == "close":
            gripper.close()
        elif msg.data == "stop":
            gripper.stop()
        elif msg.data == "status":
            state = "GRASPED" if gripper.is_grasped() else "OPEN"
            rospy.loginfo("Gripper state: %s", state)

    sub = rospy.Subscriber('/gripper/command', String, command_callback)
    rospy.loginfo("Teach Mode Gripper node ready. Listening to /gripper/command")
    rospy.spin()

关键点说明:

  • 信号互锁:在open和close方法中,先复位另一个控制信号,再置位目标信号,这是一种简单的软件互锁,防止两个矛盾信号同时有效。
  • 延时:在信号切换间加入短暂延时(如50ms),确保机器人控制器有足够时间处理前一个指令,避免信号冲突。
  • 状态读取:通过订阅/ur_hardware_interface/io_states话题来获取夹爪的抓取反馈。你需要根据实际接线确认DI引脚编号。

3.2 Compute Box模式下的ROS驱动实现

对于Compute Box模式,我们需要通过UR的I/O接口来间接控制夹爪。假设已按照2.2节配置好WebLogic,将机器人的DO6和DO7映射到了夹爪的开合动作。

#!/usr/bin/env python
# 文件:ur_rg_gripper/scripts/gripper_compute_box.py

import rospy
import threading
import time
from ur_msgs.srv import SetIO
from ur_msgs.msg import IOStates
from std_msgs.msg import String, Bool

class ComputeBoxGripper:
    """
    Compute Box模式下的RG2/RG6夹爪控制类。
    通过控制UR的DO6和DO7来触发Compute Box中预定义的动作。
    """
    def __init__(self, do_open=6, do_close=7, di_detect=0):
        rospy.wait_for_service('/ur_hardware_interface/set_io')
        self.set_io = rospy.ServiceProxy('/ur_hardware_interface/set_io', SetIO)

        # I/O引脚映射(根据WebLogic配置)
        self.do_open = do_open    # 触发张开动作的DO引脚
        self.do_close = do_close  # 触发闭合动作的DO引脚
        self.di_detect = di_detect # 抓取状态反馈的DI引脚

        # 力模式选择(假设DO7同时用于选择力档位,0=低力,1=高力)
        self.do_force_mode = do_close  # 与闭合引脚复用,或使用其他引脚

        # 动作执行标志,防止重复触发
        self.action_in_progress = False
        self.action_lock = threading.Lock()

        rospy.loginfo("Compute Box Gripper driver initialized. Open: DO%d, Close: DO%d", do_open, do_close)

    def _pulse_output(self, pin, duration=0.5):
        """
        发送一个脉冲信号到指定DO引脚。
        这是与WebLogic配合的常见模式:一个上升沿触发一个动作。
        """
        with self.action_lock:
            if self.action_in_progress:
                rospy.logwarn("An action is already in progress. Ignoring new command.")
                return False
            self.action_in_progress = True

        try:
            # 置高电平
            self.set_io(1, pin, 1)
            rospy.sleep(duration)  # 保持信号一段时间,确保Compute Box检测到
            # 置低电平
            self.set_io(1, pin, 0)
            rospy.sleep(0.1)  # 短暂延时,确保信号稳定复位

            with self.action_lock:
                self.action_in_progress = False
            return True
        except rospy.ServiceException as e:
            rospy.logerr("Failed to set digital output %d: %s", pin, e)
            with self.action_lock:
                self.action_in_progress = False
            return False

    def open(self, low_force=True):
        """
        张开夹爪。
        :param low_force: 布尔值,True表示使用低力模式张开(如果支持)。
        """
        # 首先设置力模式(如果需要)
        force_state = 0 if low_force else 1
        self.set_io(1, self.do_force_mode, force_state)
        rospy.sleep(0.05)

        # 触发张开动作
        success = self._pulse_output(self.do_open, duration=0.3)
        if success:
            rospy.loginfo("Gripper open command sent (force mode: %s).", "low" if low_force else "high")
        return success

    def close(self, low_force=False):
        """
        闭合夹爪。
        :param low_force: 布尔值,True表示使用低力模式闭合。
        """
        # 设置力模式
        force_state = 0 if low_force else 1
        self.set_io(1, self.do_force_mode, force_state)
        rospy.sleep(0.05)

        # 触发闭合动作
        success = self._pulse_output(self.do_close, duration=0.3)
        if success:
            rospy.loginfo("Gripper close command sent (force mode: %s).", "low" if low_force else "high")
        return success

    def is_grasped(self):
        """读取抓取检测状态"""
        try:
            io_states = rospy.wait_for_message('/ur_hardware_interface/io_states', IOStates, timeout=0.5)
            # 确保索引有效
            if self.di_detect < len(io_states.digital_in_states):
                return io_states.digital_in_states[self.di_detect].state
            else:
                rospy.logerr("DI pin %d index out of range.", self.di_detect)
                return False
        except rospy.ROSException as e:
            rospy.logwarn("Timeout reading IO states: %s", e)
            return False

    def wait_for_grasp(self, timeout=5.0):
        """
        阻塞等待,直到检测到抓取成功或超时。
        :param timeout: 超时时间(秒)
        :return: True if grasped, False if timeout
        """
        start_time = rospy.Time.now()
        rate = rospy.Rate(10)  # 10 Hz
        while (rospy.Time.now() - start_time).to_sec() < timeout:
            if self.is_grasped():
                return True
            rate.sleep()
        rospy.logwarn("Grasp detection timeout after %.1f seconds.", timeout)
        return False

# 主节点示例
if __name__ == '__main__':
    rospy.init_node('rg_gripper_compute_box')
    gripper = ComputeBoxGripper(do_open=6, do_close=7, di_detect=0)

    # 创建Action Server或简单的Service/Subscriber
    # 这里使用一个简单的命令话题
    def command_callback(msg):
        cmd = msg.data.lower()
        if cmd == "open":
            gripper.open(low_force=True)
        elif cmd == "close_soft":
            gripper.close(low_force=True)
        elif cmd == "close_hard":
            gripper.close(low_force=False)
        elif cmd == "check_grasp":
            if gripper.wait_for_grasp(timeout=3.0):
                rospy.loginfo("Grasp successful.")
            else:
                rospy.logwarn("Grasp failed or not detected.")
        else:
            rospy.logwarn("Unknown command: %s", msg.data)

    sub = rospy.Subscriber('/gripper/command', String, command_callback, queue_size=10)

    # 可选:发布夹爪状态话题
    pub = rospy.Publisher('/gripper/is_grasped', Bool, queue_size=10)
    rate = rospy.Rate(2)  # 2 Hz
    while not rospy.is_shutdown():
        pub.publish(gripper.is_grasped())
        rate.sleep()

实现细节与优化:

  • 脉冲触发:_pulse_output方法模拟了一个按钮按下再释放的过程,这是触发WebLogic中边沿检测逻辑的可靠方式。
  • 动作锁:使用threading.Lock和action_in_progress标志防止命令重叠发送,避免夹爪因快速连续指令而出现不可预测的行为。
  • 力模式选择:示例中假设DO7既用于触发闭合动作,也用于选择力档位。在实际WebLogic配置中,你可能需要单独的DO引脚来控制力模式。
  • 状态监控:除了简单的is_grasped查询,还提供了wait_for_grasp方法,这在需要确认抓取成功后再进行下一步操作的自动化流程中非常有用。

3.3 创建统一的ROS功能包与Launch文件

为了让驱动更易于使用,我们可以创建一个统一的功能包,根据参数动态选择控制模式。

功能包结构:

ur_rg_gripper/
├── CMakeLists.txt
├── package.xml
├── launch/
│   └── gripper_bringup.launch
├── scripts/
│   ├── gripper_teach_mode.py
│   ├── gripper_compute_box.py
│   └── gripper_node.py  # 统一入口节点
└── config/
    └── gripper_params.yaml

统一的启动节点 (gripper_node.py):

#!/usr/bin/env python
import rospy
import sys
from std_msgs.msg import String

def main():
    rospy.init_node('rg_gripper_node')
    
    # 从参数服务器读取配置
    control_mode = rospy.get_param('~control_mode', 'compute_box')  # 或 'teach_mode'
    robot_ip = rospy.get_param('~robot_ip', '192.168.1.2')
    
    rospy.loginfo("Starting RG Gripper node in %s mode...", control_mode)
    
    if control_mode == 'teach_mode':
        from gripper_teach_mode import TeachModeGripper
        gripper = TeachModeGripper()
        rospy.loginfo("Teach Mode driver loaded.")
    elif control_mode == 'compute_box':
        from gripper_compute_box import ComputeBoxGripper
        # 从参数服务器读取引脚配置
        do_open = rospy.get_param('~do_open_pin', 6)
        do_close = rospy.get_param('~do_close_pin', 7)
        di_detect = rospy.get_param('~di_detect_pin', 0)
        gripper = ComputeBoxGripper(do_open, do_close, di_detect)
        rospy.loginfo("Compute Box driver loaded with pins: open(DO%d), close(DO%d), detect(DI%d)", 
                      do_open, do_close, di_detect)
    else:
        rospy.logerr("Unknown control mode: %s. Must be 'teach_mode' or 'compute_box'.", control_mode)
        sys.exit(1)
    
    # 公共命令接口
    def command_callback(msg):
        # 这里可以解析更复杂的命令,例如JSON或自定义消息
        cmd_parts = msg.data.split()
        if not cmd_parts:
            return
            
        action = cmd_parts[0]
        if action == "open":
            force = "low" if len(cmd_parts) > 1 and cmd_parts[1] == "soft" else "high"
            gripper.open(low_force=(force=="low"))
        elif action == "close":
            force = "low" if len(cmd_parts) > 1 and cmd_parts[1] == "soft" else "high"
            gripper.close(low_force=(force=="low"))
        elif action == "stop":
            if hasattr(gripper, 'stop'):
                gripper.stop()
        elif action == "status":
            grasped = gripper.is_grasped()
            rospy.loginfo("Gripper status: %s", "GRASPED" if grasped else "OPEN/IDLE")
        else:
            rospy.logwarn("Unknown command: %s", action)
    
    sub = rospy.Subscriber('~command', String, command_callback, queue_size=10)
    rospy.loginfo("RG Gripper node ready. Listening to ~command topic.")
    rospy.spin()

if __name__ == '__main__':
    main()

Launch文件示例 (gripper_bringup.launch):

<launch>
  <!-- 公共参数 -->
  <arg name="robot_ip" default="192.168.1.2" doc="UR机器人控制器IP地址"/>
  <arg name="control_mode" default="compute_box" doc="控制模式: teach_mode 或 compute_box"/>
  
  <!-- 启动UR机器人驱动 (假设已安装 universal_robot 和 ur_robot_driver) -->
  <include file="$(find ur_robot_driver)/launch/ur5_bringup.launch">
    <arg name="robot_ip" value="$(arg robot_ip)"/>
    <arg name="kinematics_config" value="$(find ur_description)/config/ur5_calibration.yaml"/>
  </include>
  
  <!-- 启动夹爪节点,根据模式传入不同参数 -->
  <node name="rg_gripper" pkg="ur_rg_gripper" type="gripper_node.py" output="screen">
    <param name="control_mode" value="$(arg control_mode)"/>
    <param name="robot_ip" value="$(arg robot_ip)"/>
    
    <!-- Compute Box模式下的特定参数 -->
    <param if="$(eval control_mode == 'compute_box')" name="do_open_pin" value="6"/>
    <param if="$(eval control_mode == 'compute_box')" name="do_close_pin" value="7"/>
    <param if="$(eval control_mode == 'compute_box')" name="di_detect_pin" value="0"/>
    
    <!-- Teach Mode模式下的特定参数 -->
    <param if="$(eval control_mode == 'teach_mode')" name="do_open_pin" value="8"/>
    <param if="$(eval control_mode == 'teach_mode')" name="do_close_pin" value="9"/>
    <param if="$(eval control_mode == 'teach_mode')" name="di_detect_pin" value="0"/>
    
    <remap from="~command" to="/gripper/command"/>
  </node>
  
  <!-- 可选:启动一个简单的测试界面 -->
  <node name="gripper_test_gui" pkg="rqt_ez_publisher" type="rqt_ez_publisher" if="false">
    <param name="description" value="RG Gripper Test Interface"/>
  </node>
</launch>

使用方式:

# 启动Compute Box模式(默认)
roslaunch ur_rg_gripper gripper_bringup.launch robot_ip:=192.168.1.2 control_mode:=compute_box

# 启动Teach Mode模式
roslaunch ur_rg_gripper gripper_bringup.launch robot_ip:=192.168.1.2 control_mode:=teach_mode

# 发送控制命令
rostopic pub /gripper/command std_msgs/String "open"
rostopic pub /gripper/command std_msgs/String "close soft"  # 软抓取
rostopic pub /gripper/command std_msgs/String "close"       # 正常力抓取

4. 项目选型指南与高级集成策略

了解了两种模式的技术细节和实现方法后,如何在具体项目中做出选择?以下是一些实用的决策因素和高级集成技巧。

4.1 模式选择决策矩阵

考虑因素推荐 Teach Mode推荐 Compute Box
项目阶段原型验证、快速Demo生产环境、长期部署
功能需求仅需基本开合需要力控、宽度反馈、多夹爪协同
控制精度低(二进制控制)高(模拟量控制)
系统复杂度简单,接线少中等,需额外硬件(Compute Box)
网络架构无特殊要求需要稳定的局域网
预算限制成本敏感(无需Compute Box)预算允许
未来扩展功能固定可能通过软件升级增加新功能
多品牌兼容依赖特定机器人I/O通过标准网络协议,兼容性更好

个人经验分享:在早期的实验室原型中,我通常选择Teach Mode,因为它能让我在几分钟内就让夹爪动起来。但在部署到实际产线时,Compute Box提供的状态反馈和更精细的控制能力,能显著减少调试时间和提高抓取成功率。特别是当处理易碎或形状不规则的物体时,力控功能几乎是必不可少的。

4.2 高级集成:与MoveIt!和感知系统协同工作

无论选择哪种控制模式,最终目标都是将夹爪控制无缝集成到更大的机器人系统中。以下是如何与MoveIt!运动规划框架和视觉感知系统协同工作的思路。

与MoveIt!的集成:

  1. 在URDF中添加夹爪模型:为夹爪创建URDF文件,描述其视觉、碰撞属性以及与机器人末端的连接关节。
  2. 配置夹爪控制器:在MoveIt!配置中,将夹爪定义为一个“规划组”,即使它只有简单的开合状态。这允许MoveIt!在规划时考虑夹爪的碰撞体积。
  3. 动作服务器封装:将基础的夹爪控制服务封装成FollowJointTrajectory动作接口,这样MoveIt!就可以像控制机器人关节一样发送夹爪控制指令。
# 示例:夹爪的简化控制器配置 (gripper_controllers.yaml)
gripper_controller:
  type: position_controllers/JointTrajectoryController
  joints: [rg2_finger_joint]
  constraints:
    goal_time: 0.5
  state_publish_rate: 50
  action_monitor_rate: 50

与视觉系统的协同: 在抓取任务中,夹爪控制需要与视觉系统的输出紧密结合。一个典型的流程是:

  1. 视觉系统检测目标物体,并发布其位姿(geometry_msgs/PoseStamped)。
  2. 运动规划器接收位姿,规划机器人运动轨迹,并移动到预抓取位置。
  3. 发送夹爪张开指令。
  4. 机器人运动到抓取位置。
  5. 发送夹爪闭合指令,并等待抓取确认信号。
  6. 执行后续操作(如移栽、放置)。
# 简化的抓取流程伪代码
def execute_grasp(object_pose):
    # 1. 移动到预抓取位置(物体上方10cm)
    pre_grasp_pose = adjust_pose(object_pose, z_offset=0.1)
    move_to_pose(pre_grasp_pose)
    
    # 2. 张开夹爪
    gripper.open()
    rospy.sleep(0.5)  # 等待完全张开
    
    # 3. 移动到抓取位置
    move_to_pose(object_pose)
    
    # 4. 闭合夹爪(使用软抓取模式防止损坏物体)
    gripper.close(low_force=True)
    
    # 5. 等待抓取确认(超时2秒)
    if gripper.wait_for_grasp(timeout=2.0):
        rospy.loginfo("物体抓取成功,开始移栽...")
        # 执行后续动作
        lift_object()
        move_to_drop_location()
        gripper.open()  # 释放物体
        return True
    else:
        rospy.logwarn("抓取失败,物体可能丢失或滑脱。")
        # 执行恢复或重试策略
        gripper.open()
        return False

4.3 故障排除与性能优化

在实际部署中,你可能会遇到一些常见问题。以下是一些排查思路和优化建议:

常见问题:

  • 信号无响应:首先检查物理连接。对于Teach Mode,确认I/O线缆是否正确连接到指定的工具端口;对于Compute Box,确认网络连接和IP配置。使用机器人示教器手动触发DO信号,看夹爪是否有反应。
  • 抓取检测误报:调整夹爪的力控参数(如果Compute Box支持),或检查DI反馈信号的去抖设置。有时物体太轻或表面太光滑会导致检测不稳定。
  • 动作执行缓慢:检查WebLogic中的动作延时设置,或尝试增加ROS驱动中_pulse_output的duration参数。网络延迟也可能是一个因素。

性能优化技巧:

  • 并行化状态检查:在wait_for_grasp这类阻塞调用中,使用rospy.Rate进行轮询,而不是简单的sleep,以便能及时响应取消请求。
  • 添加超时与重试机制:任何与硬件交互的操作都应包含超时逻辑。对于关键操作(如抓取),实现有限次数的自动重试。
  • 日志与诊断:在驱动中增加详细的调试日志,记录每个I/O操作和时间戳。这在与间歇性故障斗争时非常有用。
  • 参数服务器配置:将所有硬件相关的参数(如引脚编号、IP地址、超时时间)存储在ROS参数服务器或YAML配置文件中,这样无需修改代码就能适应不同的部署环境。

一个实用的调试技巧:在开发初期,创建一个简单的测试脚本,按顺序触发所有可能的夹爪动作,并记录每个动作前后的I/O状态。这能帮你快速验证硬件连接和逻辑配置是否正确。

# 快速诊断脚本示例
def diagnostic_test(gripper):
    print("=== 开始夹爪诊断测试 ===")
    
    print("1. 测试张开动作...")
    if gripper.open():
        print("  张开指令发送成功")
        rospy.sleep(1.0)
    else:
        print("  张开指令失败!")
    
    print("2. 检查张开状态...")
    print("  抓取检测状态:", "触发" if gripper.is_grasped() else "未触发")
    
    print("3. 测试闭合动作(软抓取)...")
    if gripper.close(low_force=True):
        print("  软闭合指令发送成功")
        rospy.sleep(1.0)
    else:
        print("  闭合指令失败!")
    
    print("4. 检查闭合后状态...")
    if gripper.wait_for_grasp(timeout=2.0):
        print("  抓取检测成功")
    else:
        print("  抓取检测超时")
    
    print("5. 再次张开...")
    gripper.open()
    rospy.sleep(1.0)
    
    print("=== 诊断测试完成 ===")

从Teach Mode的直接了当,到Compute Box的灵活强大,OnRobot RG2/RG6夹爪的两种控制模式为不同场景下的机器人集成提供了多样化的选择。对于追求快速验证和简单控制的场景,Teach Mode通过最少的配置让你迅速看到结果;而对于需要精密控制、状态反馈和未来扩展的生产环境,Compute Box带来的网络化、智能化优势则不可替代。

在ROS中实现这两种模式的驱动,核心在于理解其底层通信机制:前者是直接的I/O操控,后者是通过I/O触发的网络化逻辑。本文提供的代码框架和集成建议,都是在实际项目中反复打磨过的。特别是Compute Box模式下通过WebLogic配置和脉冲触发的方式,虽然绕过了URScript函数的限制,但却是目前最稳定可靠的解决方案。

最后,无论选择哪种模式,充分的测试和日志记录都是成功集成的关键。建议在部署前,用类似上面的诊断脚本对夹爪的所有功能进行完整验证,确保每个信号、每个状态都按预期工作。毕竟,在机器人集成的世界里,细节决定成败。

强化学习UR机械臂仿真环境搭建(二) - 为UR3机械臂添加OnRobot RG2夹爪 为UR3机械臂添加OnRobot RG2夹爪下载OnRobot RG2的描述文件修改ur3.urdf.xacro文件 本文在强化学习UR机械臂仿真环境搭建(一) - 为UR3机械臂添加robotiq ft300力传感器的基础上,继续添加OnRobot RG2夹爪。 OnRobot官方并没有提供ros package,在github上有一份使用RG2的仓库, sharathrjtr / ur10_rg2_ros ,这份代码的外观部分设计的很好,但是物理参数并没有实际贴切。 下载OnRobot RG2的描述文 阅读详情

相关推荐

在UR3上添加Onrobot_RG2手爪

在UR3上添加Onrobot_RG2手爪: 参考资料:ros+ur机械臂+robotiq ft300+onrobot rg2+gazebo+rviz联合仿真—单纯夹爪按上并不能动 但是,博主文中使用的RG2功能包来源是https://github.com/sharathrjtr/ur10_rg2_ros,我运行之后,无法在rviz软件joint_state_publisher_gui界面,对手爪进行滑动控制。本文重新下载RG2的功能包,达到可以控制的程度,效果图片如下: 加载步骤: 例如: 1. 下载on

weixin_43463140的博客 947

ROS:UR10e配置Onrobot RG2夹爪(gazebo环境)

里面加上了gazebo的一些配置,在加载完ur(ur10e)描述文件后面加上夹爪描述文件就可以了。运行结果是已经在ur10e上装上rg2夹爪,但是会有抖动现象,具体解决方法可以看我的下一篇博客。已经配置好了rviz环境下的RG2夹爪,模拟真是物理环境还需要在gazebo中配置夹爪。中的宏函数来包含ur(ur10e)的描述文件,在gazebo中打开rg2是通过以下命令。,打开ur10e是通过。,在这个文件中调用了。

Tunny_one 1145

ROS下kinect2、ur5标定-内外参、配准、手眼标定

本文是对近期工作的一个总结,上段时间已经完成了Kinect2驱动、ROS依赖包的安装,以及ur5机器人的URDF、驱动安装等。而且分步走通了物体位姿识别、MoveIt!点云信息导入、实物机器人联动等功能,现在准备将相机获得的信息与机器人位置标定到一起去。由于我用的是Kinect2,在手眼标定之前需要对Kinect2的彩色相机和深度相机进行配准,这样出来的RGB-D图精度才能高一些,否则彩色图与深度...

SUJI的博客 1万+

ROS:UR10e配置Onrobot RG2夹爪(rviz环境)

ur10e配置rg2夹爪

Tunny_one 1393

国央企创新负责人如何通过平台提升技术需求挖掘与资源配置的精准性?.docx

国央企创新负责人如何通过平台提升技术需求挖掘与资源配置的精准性?

两路半桥LLC谐振变换器软开关Simulink仿真(模拟谐振参数不同、分裂电容)

内容概要:本文介绍了“两路半桥LLC谐振变换器软开关Simulink仿真”资源包,重点在于基于Simulink平台对两路半桥LLC谐振变换器进行高精度建模与动态仿真,特别考虑了谐振参数不一致及分裂电容等非理想工况对系统性能的影响。该仿真模型不仅涵盖了主电路拓扑、软开关实现机制与谐振网络设计,还深入分析了不同参数配置下系统的启动特性、稳态效率、动态响应及软开关条件的满足情况。通过参数扫描与对比仿真,帮助用户掌握LLC变换器的关键设计要素与优化方法,具备较强的工程指导价值和科研教学意义。; 适合人群:电力电子、电气工程及其自动化等相关专业的高校师生,以及从事高频开关电源、新能源变换器、车载充电机等领域的研发工程师和技术人员。; 使用场景及目标:① 掌握两路并联半桥LLC谐振变换器的建模与仿真方法;② 理解软开关技术在提升变换器效率与降低EMI方面的关键作用;③ 分析谐振参数偏差与分裂电容结构对系统均流特性、增益曲线及软开关范围的影响;④ 支持科研项目中的拓扑验证、控制策略开发与故障工况分析; 阅读建议:建议结合Simulink仿真模型与配套说明文档进行学习,重点关注谐振腔参数设置、驱动时序设计及软开关波形观测;可通过调整谐振电感、电容值或引入参数失配,观察系统行为变化,深入理解LLC变换器的稳定边界与优化设计原则。

ros+ur机械臂+robotiq ft300+onrobot rg2+gazebo+rviz联合仿真---单纯夹爪按上并不能动

ros+ur机械臂+robotiq ft300+onrobot rg2+gazebo+rviz联合仿真 仿真环境 Ubuntu18.04 ros-melodic ur3 robotiq ft300 onrobot rg2 安装功能包 第一次需要安装功能包,安装完成后下一次运行可以省略此步 ur有工能包,直接从github上下载即可。 cd catkin_ws/src git clone -b melodic-devel https://github.com/ros-industrial/universal

求知小鸟 5303

双向全桥CLLC谐振变换器仿真模型(Simulink仿真实现)

内容概要:本文系统介绍了双向全桥CLLC谐振变换器的Simulink仿真模型,重点阐述了变频控制、闭环仿真及其与多种电力电子拓扑(如维也纳整流器、DAB变换器、图腾柱PFC等)的联合仿真设计。资源包涵盖2.5kW双向全桥LLC、V2G电动汽车充放电系统、三相PFC、多相交错LLC等多种变换器的仿真案例,并深入展示了三电平VIENNA整流器在双闭环PI控制与SVPWM调制策略下,结合上下电容电压差值补偿实现中点电位平衡的先进控制方法。通过仿真验证,该策略不仅有效维持了800V直流母线电压的稳定,还在动态工况下显著提升了电容电压的均衡度,同时保持了较低的输入电流THD,充分体现了SVPWM与中点平衡控制协同优化的技术优势。; 适合人群:具备电力电子与自动控制理论基础,从事新能源发电、电动汽车、工业电源、微电网等领域的研究生、工程师及科研人员。; 使用场景及目标:① 学习并构建高频谐振变换器(如LLC、CLLC)的Simulink仿真模型,掌握其变频与混合控制策略;② 深入理解并应用中点电位平衡、双闭环PI控制、SVPWM调制等核心技术于VIENNA等三电平变换器中;③ 复现高水平期刊论文中的控制算法,服务于科研项目申报、学术论文撰写或工程产品开发。; 阅读建议:该资源为综合性仿真资料库,建议使用者结合自身研究方向(如电动汽车充电、新能源并网)选择对应案例进行精学,重点关注控制策略的设计逻辑、仿真参数的整定方法以及SVPWM与中点平衡的协同机制,并充分利用附带的计算书和参考文献深化理解,以实现从仿真模型到实际工程应用的顺利转化。

UR5机械臂+OnRobot RG6夹爪实战:从Compute Box模式到ROS控制的完整避坑指南

本文详细介绍了UR5机械臂与OnRobot RG6夹爪的工业级ROS集成实战,重点解析了第二代RG6夹爪的Compute Box控制模式及其与ROS的深度集成方案。通过硬件配置、WebLogic监听、ROS功能包开发等步骤,帮助开发者解决集成过程中的技术挑战,实现高效稳定的自动化抓取系统。

lake5的博客 909

全桥LLC谐振(变频+移相混合控制)变换器闭环仿真模型(Simulink仿真实现)

全桥LLC谐振(变频+移相混合控制)变换器闭环仿真模型(Simulink仿真实现)

用废旧汽车电池DIY家用UPS:手把手教你低成本搭建Wi-Fi不断电系统

本文详细介绍了如何利用废旧汽车电池DIY低成本家用UPS系统,确保Wi-Fi设备在断电时持续供电。通过精选材料、电路搭建和安全防护,实现高效稳定的电源转换与智能切换,成本仅为市售UPS的三分之一。特别适合家庭办公和远程工作者提升网络供电可靠性。

weixin_29200485的博客 468

OnRobot:协作机器人领域的先锋 Enrico Krog Iversen 与丹麦成长基金 (Danish Growth Fund) 强强联手,踌躇满志地打造全新机器人臂端工具合资企业

战略收购和技术创新将促进公司的长足发展,并解决协作机器人臂端工具市场供不应求的局面。全新的 OnRobot 创立伊始便一举并购了三家跨国企业,其目标是在日新月异的全球市场中成为世界领先的业界翘楚,进一步奠定丹麦在协作机器人领域的强大地位丹麦欧登塞--(美国商业资讯)--协作机器人行业首屈一指的先锋企业 Universal Robots 前任首席执行官EnricoKrog Iversen 携手丹麦成...

美国商业资讯的博客 646

Welch 方法详解:一种经典而实用的功率谱密度估计方法

在信号处理领域,谱分析是用于分析信号频率内容的强大工具。Welch方法是现代谱分析中一种广泛使用的功率谱密度估计技术,由Peter D. Welch在1967年提出。它通过对信号进行分段、加窗和平均化处理,提供了一种平滑且稳定的频谱估计方法。Welch方法通过将信号分成多个重叠的段,每段应用窗函数,然后计算每段的周期图,最后对所有周期图进行平均化,得到平滑的功率谱密度估计。welch_psd函数接收信号x、采样频率fs、每段的样本数N、重叠样本数overlap和窗函数类型window。

DuHz的博客 7067

urx驱动ur3和onrobot rg2

urx驱动ur3和onrobot rg2 1.安装urx pip install urx github链接: https://github.com/Mofeywalker/python-urx 注意:一定要查看urx下的gripper是否安装了,如果没有安装的话,克隆参考问下的github文件 Python的库安装位置如下图,在home的隐藏文件下,ctrl+h可以查看隐藏文件。 2.连接电脑 2.1设置ployscope的ip地址 首先用一根网线连接ur机械臂控制柜和电脑。 下一步是确保正确配置您的硬

求知小鸟 4152

esp32c6 开发实战:低功耗蓝牙(BLE)开发

蓝牙栈在此程序流程中已经启动并运行,但是应用程序的功能尚未定义。功能的定义是通过响应事件来实现的,当其他设备尝试读取或写入参数以及建立连接时就会触发事件回调函数处理。BT控制器在控制器端实现主机控制器接口(HCI),链路层(LL)和物理层(PHY)。BT控制器对用户应用程序不可见,并处理BLE堆栈的较低层。蓝牙堆栈(Bluedroid stack)定义了经典蓝牙(BT Classic)和低功耗蓝牙(BLE)的通用定义和API。的判断)等对于启动低功耗蓝牙来说不重要的代码,函数初始化和启用BT控制器。

月入鱼饵的博客 2742

MATLAB库函数unwrap(相位解卷绕)的C语言实现

什么是相位解卷绕 Q = unwrap(P) Q = unwrap(P) corrects the radian phase angles in a vector P by adding multiples of ±2π when absolute jumps between consecutive elements of P are greater than or equal to the default jump tolerance of π radians. If P is a matrix, unw

业精于勤,荒于嬉 4248

可在rviz中开合的onrobot-rg2夹爪模型

可运动的onrobot-rg2夹爪模型 我在做ur3视觉抓取项目的时候,由于实验室所用的夹爪是onrobot-rg2,网上暂时没有可以运动的onrobot-rg2夹爪模型,所以我自己制作了能够在中rviz进行仿真,控制夹爪张合的urdf模型。我没有在Gazebo中进行运动控制,只是进行了显示。rviz仿真的具体效果如动图所示。 Gazebo中的具体效果如图所示。 需要此项目文件的可以去我的github下载,链接在这里????,有什么问题的可以一起交流,共同进步。 ...

AIRMAN12306的博客 1224

4、分布式发电系统中用于改善电能质量的有源、无源和混合滤波器

本文探讨了分布式发电系统中,尤其是光伏(PV)系统运行过程中引入的电能质量问题,并分析了有源滤波器、无源滤波器及混合滤波器在改善电能质量方面的应用。文章详细介绍了光伏系统的建模、最大功率点跟踪(MPPT)技术,以及谐波、电压波动等技术问题,同时对各类滤波器的拓扑结构和控制方法进行了系统性总结。通过仿真实例比较了不同滤波器在减少谐波方面的效果,为实际工程应用提供了参考依据。

transformer2023的博客 92

带有onrobot_rg2夹爪的ur3机械臂在pybullet中的仿真

Simulation of ur3 with onrobot_rg2 by pybullet import pybullet as p import pybullet_data as pd // connect to engine servers physicsClient = p.connect(p.GUI) // add search path for loadURDF p.setAdditionalSearchPath(pd.getDataPath()) p.connect(p.GUI)用来启动仿真

AIRMAN12306的博客 4054

gem5-gpu教程01 部署(实测可跑通)

这将GPGPU-Sim更新为与gem5-gpu兼容的最新版本。此版本是已知可用于gem5 gpu的最新版本。

qq_20388971的博客 1406

RT-DETR改进策略【模型轻量化】| 替换骨干网络为 2024轻量化网络MoblieNetV4:移动生态系统的通用模型

本文记录的是基于MobileNet V4的RT-DETR目标检测轻量化改进方法研究。通过整合UIBMobile MQA以及优化的NAS策略能够在在不降低性能指标的前提下,降低计算成本。本文配置了原论文中和五种模型,以满足不同的需求。

Limiiiing的博客 1924

ROS-kinetic下与UR3机械臂通讯

1.安装ROS-kinectic http://wiki.ros.org/kinetic/Installation/Ubuntu 2.创建工程catkin_src 3.安装universal_robot https://github.com/ros-industrial/universal_robot 4.安装ur_modern_diver(我用的机械臂软件版本是3.3.4.310...

SpengTAN的博客 1471

华为OD机试:查找接口成功率最优时间段 (C/C++/Py/Java/JS/GO)

华为OD机试双机位C卷 查找接口成功率最优时间段,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解。

qq_45776114的博客 4687

UR10 RG2机械臂手臂+RealsenseZR300 机器人手眼标定 系列第四篇

参考文章了链接: https://blog.youkuaiyun.com/zhang970187013/article/details/81098175 https://github.com/IFL-CAMP/easy_handeye/tree/master https://blog.youkuaiyun.com/sinat_23853639/article/details/80276848 跑了一个星期参考文章...

weixin_40799950的博客 1万+

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

UR机械臂+RG2机械手控制 学习及实际控制 系列第三篇-1

1.机械臂UR的控制包括两种,一种是通过终端控制 比较笨重不方便,用于测试使用,另一种是通过ros例程包,订阅位置信息控制机械臂的移动,moveit自动规划机械臂的路径,并躲过设置好的盒子(box) 手部RG2机械手的控制一种是通过终端的程序,在大终端中创建空程序 、结构、RG2、命令、带宽。 2.步骤 #roslaunch ur_control ur10_control.launch r...

weixin_40799950的博客 1万+

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

上一篇: MacBook Air M3实战:用LoRA微调Qwen2.5-1.5B模型的保姆级避坑指南
下一篇: 新手必看:如何用DoWhy在IHDP数据集上跑通第一个因果推断案例(附完整代码)
随身带U盘
博客等级 码龄4年 30粉丝 1526原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值