Hi, I have already asked this question here (universal robot - Port Accessibility Issues for Gripper Communication on a UR10e Using Sockets and URCaps - Robotics Stack Exchange )
but I think this is the more appropriate forum for my problem.
I’m having trouble controlling a Robotiq EPick Gripper that’s connected to a Universal Robot UR10e.
I followed this guide: Guides — ur_rtde 1.6.0 documentation
Option 3 explains how to communicate directly with the Robotiq URCap through port 63352 using a socket connection. Option 2 talks to the gripper via a serial port mapped from port 54321 of the RS485 URCap running on the robot. However, neither option is working.
The minimal example for Option 3 is not returning from the connect function and Option 2 is failing with the following error:
Modbus Error: No communication with the instrument (no answer)
You can find both scripts below.
Communication through the RTDE interface is working, but I need to control the robot via the ros2 driver during gripper actions, so Option 1 is not applicable.
When I tested the ports with Telnet, I found that they are not exposed by the UR controller.I also looked for settings that could hide the ports, but I couldn’t find any. It is also not possible to connect via SSH or SFTP, even though the settings are enabled in Polyscope.
Any help would be much appreciated.
Option 3
import socket
ROBOT_IP = '192.168.2.2'
PORT = 63351
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((ROBOT_IP, PORT))
Option 2
import minimalmodbus
import serial
import time
def control_epick_gripper(port, slave_address, command, value=None):
"""Controls a Robotiq ePick gripper over Modbus RTU.
Args:
port (str): Serial port (e.g., '/dev/ttyUSB0' or 'COM3').
slave_address (int): Modbus slave address of the gripper.
command (str): Command to send (e.g., 'activate', 'grip', 'release', 'set_position').
value (int, optional): Value for commands that require it (e.g., position, force).
"""
try:
instrument = minimalmodbus.Instrument(port, slave_address)
instrument.serial.baudrate = 115200 # ePick default baudrate
instrument.serial.bytesize = 8
instrument.serial.parity = serial.PARITY_NONE
instrument.serial.stopbits = 1
instrument.serial.timeout = 1 # Adjust as needed
if command == "activate":
# Activation: Set the "Action Request" register (address 0x03E8) to 1.
instrument.write_register(1000, 1) # 0x03E8 = 1000
print("Activating gripper...")
time.sleep(1) # Important: Wait for activation to complete
elif command == "grip":
# Grip: Set the "Action Request" register (address 0x03E8) to 3.
instrument.write_register(1000, 3) # 0x03E8 = 1000
print("Gripping...")
elif command == "release":
# Release: Set the "Action Request" register (address 0x03E8) to 2.
instrument.write_register(1000, 2) # 0x03E8 = 1000
print("Releasing...")
elif command == "set_position":
if value is not None:
# Set Position: Write the desired position to the "Target Position" register (address 0x03E9).
instrument.write_register(1001, value) # 0x03E9 = 1001
print(f"Setting position to: {value}")
else:
print("Error: 'set_position' command requires a value.")
return
elif command == "get_status":
# Read the "Gripper Status" register (address 0x03E8)
status = instrument.read_register(1000)
print(f"Gripper Status: {status}")
return status # return status for further processing if needed
else:
print(f"Unknown command: {command}")
except minimalmodbus.ModbusException as e:
print(f"Modbus Error: {e}")
except serial.SerialException as e:
print(f"Serial Port Error: {e}")
except Exception as e:
print(f"An unexpected error occurred: {e}")
if __name__ == "__main__":
PORT = "/tmp/ttyUR" # Replace with your serial port
SLAVE_ADDRESS = 9 # Default ePick slave address
# Example Usage
control_epick_gripper(PORT, SLAVE_ADDRESS, "activate")
control_epick_gripper(PORT, SLAVE_ADDRESS, "grip")
time.sleep(2) # Hold grip for 2 seconds
control_epick_gripper(PORT, SLAVE_ADDRESS, "release")
control_epick_gripper(
PORT, SLAVE_ADDRESS, "set_position", 100
) # Set position to 100 (adjust as needed)
control_epick_gripper(PORT, SLAVE_ADDRESS, "get_status")