UniversalRobots / Universal_Robots_ROS_Driver

Universal Robots ROS driver supporting CB3 and e-Series
Apache License 2.0
747 stars 401 forks source link

The way to control Onrobot RG2 gripper (UR5e and QC-R v3 Qiuck Changer) #611

Closed pkowalsk1 closed 1 year ago

pkowalsk1 commented 1 year ago

Summary

I am trying to control the Onrobot RG2 gripper on the UR5e. It is attached to the robot using the QC-R v3 Quick Changer so it is possible to control the operation of the gripper with the eight-pinned connector (adjacent to the tool flange on Wrist # 3). URcap was supplied with the gripper, so it can be easily controlled from the UR GUI and URScript. I can also control the ur5e with ROS driver and Moveit!

  1. As far as I know, if I want to control the gripper with ROS, I should either use the ROS driver provided by the manufacturer (which I couldn't find) or publish the URScript on topic /ur_hardware_interface/script_command. Are there other methods or have I missed something?

  2. I found ROS packages that use Modbus/TCP (i.e onrobot) but it's not possible to use them with this RS485/IO connection, right?

  3. I tried to publish set_digital_out(0, True) at /ur_hardware_interface/script_command topic and it was successful. It is possible to use rg_grip() function in URscript and it works very well, however when I publish this function it has no effect. I tried:

How do you think I can control the gripper in the best way?

Versions

Issue details

I launched ur_robot_driver/launch/ur5e_bringup.launch with this configuration:

<include file="$(find ur_robot_driver)/launch/ur5e_bringup.launch">
  <arg name="robot_ip" value="$(arg robot_ip)" />
  <arg name="tf_prefix" value="$(arg tf_prefix)" />
  <arg name="controller_config_file" value="$(arg controller_config_file)" />
  <arg name="robot_description_file" value="$(arg robot_description_file)" />
  <arg name="kinematics_config" value="$(arg kinematics_config)" />
  <arg name="use_tool_communication" value="True" />
  <arg name="tool_device_name" value="/dev/ttyTool" />
  <arg name="tool_voltage" value="24" />
  <arg name="tool_baud_rate" value="1000000" />
  <arg name="tool_rx_idle_chars" value="2.0" />
  <arg name="tool_tx_idle_chars" value="4.0" />
  <arg name="headless_mode" value="true" />
</include>

Use Case and Setup

UR5e with Onrobot RG2 gripper mounted on Panther robot. Gripper is attached to the robot arm using the QC-R v3 Quick Changer so it is possible to control the operation of the gripper with the eight-pinned connector (adjacent to the tool flange on Wrist # 3).

fmauch commented 1 year ago

When using an e-Series robot the robot has to be in remote_control mode in order to accept custom script commands.

As a workaround you can execute some script when an output is set. I don't quite remember, but out of my head a TP program such as this could work:

image

Basically, in a separate thread you wait for an input to be set and then execute some script code. It's a workaround, but it can work rather reliable.

Alternatively, since you seem to be familiar with URScript already, you could extend the relatively new script command interface to inject a custom command. See the corresponding commit.

ericahellscythe commented 1 year ago

Hi have you managed to get control of the OnRobot tools remotely using your computer? I am in the exact same situation as you. Writing a TP program to run a script works but that is not what I want. I tried to run a python program to control the RG2 but it failed. But if I were to run the program to control other stuff (i.e changing of I/O or moving of joints), it works.

import socket
import time

HOST = "192.168.10.11"
PORT = 30002

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))

#====================== Works =======================

s.send(("set_digital_out(0, True)"+"\n").encode('utf8'))
time.sleep(1)
data = s.recv(1024)

#==================================================

# ============= OnRobot Script does not work =============

f = open("/home/zhy/ur10_project/src/simple_program/scripts/test.script", "rb")
l = f.read(1024)

while (l):
    s.send(l)
    l = f.read(1024)

#==================================================

My test.script: rg_grip(rg_Width+30, 20, rg_index_get())

Is there a way to control OnRobot products without using the compute box? Have been finding resources for this issue but I just can't find any or make it work. Any help is appreciated.

pkowalsk1 commented 1 year ago

Hi, I'm just finishing up a temporary solution. With the help of @fmauch's suggestion I concluded that the fastest and most stable way to do it is as follows:

analog_out_0, analog_out_1, and digital_out_0 of the UR robot are used to handle the control. They are not connected to anything - only allow the exchange of information between two devices. ROS driver running on an external unit can change the state of the IO using the /ur_hardware_interface/set_io service. In the first step, the state of the analog_out_0 pin is determined, then (as a confirmation) the high state of digital_out_0 is determined. UR robot computer waits for a high state and when it occurs uses the command rg_width() with get_standard_analog_out(0) as a width argument. After that, the digital_out_0 is set to a low state. The odd multiplication and subtraction on the picture are due to the need to map the 0.004-0.02mA range to 0-102mm.

In another thread, the UR robot computer sets the analog_out_1 state, and the ROS driver on the external computer side reads the intensity on the pin and maps it to the joint state (0.004 to 0.02 mA ➝ -0.44 to 1.0 rad). It is important that the robot is in remote control mode.

You can check out my solution:

I also attempted to write a URscript that would communicate over the socket with Python node. This solution works quite well, however, I encountered problems with closing and opening sockets. This makes the solution very unstable and often communication cannot be established. It seems to me that the problem is in the timeout of the socket_read_ascii_float() function, but trying with other values also ended in failure. And this is where my question comes in. Is there any way to check from the script whether a given socket is open? I searched for the answer on the Universal Robots forum, but without success. I will be very grateful for any hint on how to call a stable communication of this type.

EDIT: I also forgot to add that after switching to external control () I lost the ability to execute any command using /ur_hardware_interface/script_command. Even set_digital_out(0, True). Is this normal behavior?

ericahellscythe commented 1 year ago

So I created the same UR program as you. But when I called the rosservice:

rosservice call /ur_hardware_interface/set_io "fun: 1 pin: 0 state: 1.0"

The teach pendent gives me an error: RG Grip command returned with an error. Please be sure that the required width is between the limits. Program halted.

Which line in the UR program am I suppose to edit? Is it line 5? How do I tell what's the required width to change to? And may I check with you if your last part of your line 8 script is just tool_index=0 and the other insignificant arguments?

Thanks

pkowalsk1 commented 1 year ago

Hi,

Sorry for the delay, but we now have the latest stable and tested version of the ROS 2 driver for the OnRobot RG2 gripper, which uses the MODBUS protocol. You can find the Docker configuration for this gripper in ur-onrobot-rg2-docker repository, and the integration with the UR5e Docker configuration in ur-docker repo. This allows you to launch ROS 2 nodes from the ur_onrobot_rg2_ros repository.

Regarding the issue you mentioned with width limits, I encountered a similar problem in the past when the tool ID was incorrect. However, all the grippers in our office had the same ID, which was set to 0.

github-actions[bot] commented 1 year ago

This issue has not been updated for a long time. If no further updates are added, this will be closed automatically. Comment on the issue to prevent automatic closing.