Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connection to reverse interface dropped - UR5 #709

Closed
1 task done
zp2546265641 opened this issue Jul 12, 2024 · 21 comments · Fixed by #714
Closed
1 task done

Connection to reverse interface dropped - UR5 #709

zp2546265641 opened this issue Jul 12, 2024 · 21 comments · Fixed by #714
Labels
Solution proposed A solution has been proposed inside the issue. Waiting for user feedback.

Comments

@zp2546265641
Copy link

zp2546265641 commented Jul 12, 2024

Affected ROS Driver version(s)

i do not know which,i download recently from here

Used ROS distribution.

Noetic

Which combination of platform is the ROS driver running on.

Linux

How is the UR ROS Driver installed.

From binary packets

Which robot platform is the driver connected to.

Real robot

Robot SW / URSim version(s)

i do not know which

How is the ROS driver used.

Through the robot teach pendant using External Control URCap

Issue details

Summary

My computer is Ubuntu 20.04, ROS-Noetic, dual system, and 5.15.0-113Generic kernel. After I enabled urcap in the teach pendant, I established a connection with the real robot through the driver. I use the control cabinet io output to control the external air pump and drive ur5 to execute the trajectory planned by moveit at the same time, but the problem occurs. Once the io signal and the planned trajectory are running at the same time, urcap will be interrupted and the sending signal will prompt failure:

[ INFO] [1720767234.769926758]: Completed trajectory execution with status PREEMPTED ...
[ INFO] [1720767234.772389043]: Execution completed: PREEMPTED
[ INFO] [1720767237.051394741]: Robot requested program
[ INFO] [1720767237.051487070]: Sent program to robot
[ INFO] [1720767237.401967035]: Robot connected to reverse interface. Ready to receive control commands.
[ INFO] [1720767257.018619063]: Connection to reverse interface dropped.

But I don't use io signals, and the execution of the track alone can be successful, but sometimes it will be interrupted. I don't know where the problem lies?

Expected Behavior

At the same time, use the control cabinet io output to control the external air pressure pump and drive ur5 to execute the trajectory planned by moveit

Actual Behavior

The problem occurs. Once the io signal and the planned trajectory are running at the same time, urcap will be interrupted and the sending signal will prompt failure:
[ INFO] [1720767257.018619063]: Connection to reverse interface dropped.

Relevant log output

[ INFO] [1720767194.574030563]: Execution completed: FAILED
[ INFO] [1720767203.510599820]: Robot requested program
[ INFO] [1720767203.510698431]: Sent program to robot
[ INFO] [1720767203.881064833]: Robot connected to reverse interface. Ready to receive control commands.
[ INFO] [1720767204.136764422]: Connection to reverse interface dropped.
[ INFO] [1720767205.429355994]: Received request to compute Cartesian path
[ INFO] [1720767205.430741163]: Attempting to follow 31139 waypoints for link 'tool_ros' using a step of 0.010000 m and jump threshold 0.000000 (in global reference frame)
[ INFO] [1720767205.662247666]: Robot requested program
[ INFO] [1720767205.662335968]: Sent program to robot
[ INFO] [1720767206.017103343]: Robot connected to reverse interface. Ready to receive control commands.
[ INFO] [1720767206.092052969]: Computed Cartesian path with 31142 points (followed 100.000000% of requested trajectory)
[ INFO] [1720767206.335785831]: Execution request received
[ INFO] [1720767234.761974996]: Connection to reverse interface dropped.

Accept Public visibility

  • I agree to make this context public
@fmauch
Copy link
Collaborator

fmauch commented Jul 17, 2024

Without any further information I can only guess, but how are you controlling the IOs?

Once you are making any URScript calls on the robot, this will interrupt the external control program, as there can only be one program running at a time. Setting the IOs using the setIO service should not interrupt the motions.

@zp2546265641
Copy link
Author

zp2546265641 commented Jul 17, 2024 via email

@zp2546265641
Copy link
Author

Without any further information I can only guess, but how are you controlling the IOs?

Once you are making any URScript calls on the robot, this will interrupt the external control program, as there can only be one program running at a time. Setting the IOs using the setIO service should not interrupt the motions.

#! /usr/bin/python3
import rospy
import moveit_commander
import sys
from geometry_msgs.msg import Pose
from moveit_msgs.msg import RobotTrajectory
from trajectory_msgs.msg import JointTrajectory, JointTrajectoryPoint
from waypoints.wangge import wangge_waypoints
from waypoints.transformtomove import transform_waypoints
from decimal import Decimal, getcontext, ROUND_HALF_UP
from std_msgs.msg import String
from threading import Thread

def convert_pose_to_float(pose):
pose.position.x = float(pose.position.x)
pose.position.y = float(pose.position.y)
pose.position.z = float(pose.position.z)
pose.orientation.x = float(pose.orientation.x)
pose.orientation.y = float(pose.orientation.y)
pose.orientation.z = float(pose.orientation.z)
pose.orientation.w = float(pose.orientation.w)
return pose

def set_digital_io(num, state):

urscript_pub = rospy.Publisher('/ur_hardware_interface/script_command', String, queue_size=1)
# rospy.sleep(0.1)
set_digital_output = f"set_standard_digital_out({num}, {state})"
urscript_pub.publish(set_digital_output)

def set_analog_io(channel,voltage):

urscript_pub = rospy.Publisher('/ur_hardware_interface/script_command', String, queue_size=1)
# rospy.sleep(0.5)

set_analog_output = f"set_analog_out({channel}, {voltage})"
urscript_pub.publish(set_analog_output)

def open_pressure_system():
rospy.loginfo("Opening pressure system...")
set_digital_io(7,True)
rospy.sleep(0.5)
set_analog_io(1,0.45)

def close_pressure_system():
rospy.loginfo("Closing pressure system...")
set_digital_io(7,True)
rospy.sleep(0.5)
set_analog_io(1,0)

def main():
rospy.init_node('moveit_half_circle_trajectory', anonymous=True)

moveit_commander.roscpp_initialize(sys.argv)

arm_group = moveit_commander.MoveGroupCommander("manipulator")

arm_group.set_pose_reference_frame('base_link')  

getcontext().prec = 6 

start_pose = Pose()
start_pose.position.x = 0
start_pose.position.y = 0
start_pose.position.z = 0

x_step = 0.002
y_step = 0.0007 
z_step = 0.00025 
max_x=0.02     
max_y = 0.03   
layers = 25    
waypoints = wangge_waypoints(start_pose, x_step, y_step, z_step, max_x, max_y, layers)
current_pose = Pose()
current_pose.position.x = -0.584560013612115
current_pose.position.y = 0.1852676617287722
current_pose.position.z = 0.09429066717218944
current_pose.orientation.x = -1.543974106769655e-05
current_pose.orientation.y = 0.9999999987211352
current_pose.orientation.z = -2.686163405775284e-05
current_pose.orientation.w = 3.9972452882626775e-05
# print(current_pose)

transformed_waypoints = transform_waypoints(current_pose, waypoints)


transformed_waypoints_float = [convert_pose_to_float(pose) for pose in transformed_waypoints]


(plan, fraction) = arm_group.compute_cartesian_path(
                                    transformed_waypoints_float, 
                                    0.01,        # eef_step
                                    0.0)         # jump_threshold

if plan:
    rospy.loginfo("Plan computed successfully!")

    # Create a thread to open the pressure system
    # pressure_thread = Thread(target=open_pressure_system)
    open_pressure_system()
    # Execute the path with a longer wait time
    execution_success = arm_group.execute(plan, wait=True)

    if execution_success:
        rospy.loginfo("executing and will open the pressure...!")
        # Start the pressure system thread
        # pressure_thread.start()
        # pressure_thread.join()  # Wait for the pressure system to fully open

        # Close the pressure system after successful execution
        # close_pressure_system()
    else:
        rospy.logerr("Trajectory execution failed or timed out.")
    close_pressure_system()
else:
    rospy.logerr("Failed to compute path")

moveit_commander.roscpp_shutdown()
rospy.signal_shutdown("Task completed")

if name == 'main':
try:
main()
except rospy.ROSInterruptException:
pass

@zp2546265641
Copy link
Author

Without any further information I can only guess, but how are you controlling the IOs?

Once you are making any URScript calls on the robot, this will interrupt the external control program, as there can only be one program running at a time. Setting the IOs using the setIO service should not interrupt the motions.

i send the URscript command, and then excute the moveit trajectory

@zp2546265641
Copy link
Author

Without any further information I can only guess, but how are you controlling the IOs?

Once you are making any URScript calls on the robot, this will interrupt the external control program, as there can only be one program running at a time. Setting the IOs using the setIO service should not interrupt the motions.

oh! maybe i know! After i excute the trajectory, i send the ioscript, which will interrupt the external control program? but how can i send the two command meanwhile. is there some ways to solve the problem? Thanks! (or i misunderstand your meaning?)

@fmauch
Copy link
Collaborator

fmauch commented Jul 17, 2024

This is exactly the problem. As written above, you could use the setIO service. This will not interrupt your running program. You can simply change your code by changing the two functions:

from ur_msgs.srv import SetIO, SetIORequest

class URInterface:
    def __init__():
        self.set_io_client = rospy.ServiceProxy('/ur_hardware_interface/set_io', SetIO)

    def set_digital_io(self, num, state):
        self.set_io_client(SetIORequest.FUN_SET_DIGITAL_OUT, num, state)

    def set_analog_io(self, channel, voltage):
        self.set_io_client(SetIORequest.FUN_SET_ANALOG_OUT, channel, voltage

    def close_pressure_system(self):
        rospy.loginfo("Closing pressure system...")
        self.set_digital_io(7, True)
        rospy.sleep(0.5)
        self.set_analog_io(1,0)

    def open_pressure_system(self):
        rospy.loginfo("Opening pressure system...")
        self.set_digital_io(7, True)
        rospy.sleep(0.5)
        self.set_analog_io(1,0.45)

Then, in your main():

ur_interface = URInterface()
#...
ur_interface.open_pressure_system()
#...
ur_interface.close_pressure_system()

Note: All code is untested.

@fmauch fmauch added the Solution proposed A solution has been proposed inside the issue. Waiting for user feedback. label Jul 17, 2024
@zp2546265641
Copy link
Author

This is exactly the problem. As written above, you could use the setIO service. This will not interrupt your running program. You can simply change your code by changing the two functions:

from ur_msgs.srv import SetIO, SetIORequest

class URInterface:
    def __init__():
        self.set_io_client = rospy.ServiceProxy('/ur_hardware_interface/set_io', SetIO)

    def set_digital_io(self, num, state):
        self.set_io_client(SetIORequest.FUN_SET_DIGITAL_OUT, num, state)

    def set_analog_io(self, channel, voltage):
        self.set_io_client(SetIORequest.FUN_SET_ANALOG_OUT, channel, voltage

    def close_pressure_system(self):
        rospy.loginfo("Closing pressure system...")
        self.set_digital_io(7, True)
        rospy.sleep(0.5)
        self.set_analog_io(1,0)

    def open_pressure_system(self):
        rospy.loginfo("Opening pressure system...")
        self.set_digital_io(7, True)
        rospy.sleep(0.5)
        self.set_analog_io(1,0.45)

Then, in your main():

ur_interface = URInterface()
#...
ur_interface.open_pressure_system()
#...
ur_interface.close_pressure_system()

Note: All code is untested.
nice great! thanks very much! it can excute meanwhile! but i meet a new problem! when my trajectory excute over, and then it excute the ur_interface.close_pressure_system(). However, the close program didn't work as we expect.
In addition, I also found a phenomenon that the analog_out 1 in the teach pendant originally displayed voltage units, but after executing my program to turn on the air pressure, it became current units. Later, it was useless for me to run it separately to set the air pressure io to 0v, and it was useless to set it in the teach pendant. Only by turning off the digital output in the teach pendant can it be reset.

@zp2546265641
Copy link
Author

This is exactly the problem. As written above, you could use the setIO service. This will not interrupt your running program. You can simply change your code by changing the two functions:

from ur_msgs.srv import SetIO, SetIORequest

class URInterface:
    def __init__():
        self.set_io_client = rospy.ServiceProxy('/ur_hardware_interface/set_io', SetIO)

    def set_digital_io(self, num, state):
        self.set_io_client(SetIORequest.FUN_SET_DIGITAL_OUT, num, state)

    def set_analog_io(self, channel, voltage):
        self.set_io_client(SetIORequest.FUN_SET_ANALOG_OUT, channel, voltage

    def close_pressure_system(self):
        rospy.loginfo("Closing pressure system...")
        self.set_digital_io(7, True)
        rospy.sleep(0.5)
        self.set_analog_io(1,0)

    def open_pressure_system(self):
        rospy.loginfo("Opening pressure system...")
        self.set_digital_io(7, True)
        rospy.sleep(0.5)
        self.set_analog_io(1,0.45)

Then, in your main():

ur_interface = URInterface()
#...
ur_interface.open_pressure_system()
#...
ur_interface.close_pressure_system()

Note: All code is untested.

In fact, every time I send a command to control io, whether it is closed or opened, what is actually controlled is the current, not the voltage. My proportional valve only supports voltage signals.What improvements should I make to my program to ensure that the signal sent out controls the voltage instead of the current?

@urrsk
Copy link
Member

urrsk commented Jul 18, 2024

@zp2546265641 Have you tried to set the analog output type through the teach pendant?
image

Remember to save the installation afterwards to keep this setting after a power cycle

@zp2546265641
Copy link
Author

@zp2546265641 Have you tried to set the analog output type through the teach pendant? image

Remember to save the installation afterwards to keep this setting after a power cycle
Yes, I tried. However, when I try to set the analog output command in TP, it also interrupts the external control. Right now, I can only use the SetIO, SetIORequest commands to achieve real-time control of IO and trajectory execution. But it can only control the current. Then in TP, I convert the current back to voltage, but as soon as I run the program, it automatically becomes current, but my proportional valve only supports voltage signals. However, my job is that when I execute my trajectory at the same time, I need to open the proportional valve.

@fmauch
Copy link
Collaborator

fmauch commented Jul 19, 2024

The problem basically comes from our current implementation:

https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/613b2f9f81ed888c2fac9463963d6dc9d07ba762/src/rtde/rtde_writer.cpp#L226-L227

As a hotfix you could build the client library from source and change line 227 to uint8_t output_type = 1; then it would always be voltage.


Edit: My advice was wrong. Since the type is a bit-mask, providing 1 might not help you. I'll have a solution together soon....

@fmauch
Copy link
Collaborator

fmauch commented Jul 19, 2024

I've put together a set of pull requests:

@zp2546265641 If you could try that out and give some feedback, that would be great!

Please note: When building the client library from source, we suggest removing the installed apt package (sudo apt remove ros-noetic-ur-client-library)

@zp2546265641
Copy link
Author

I've put together a set of pull requests:

@zp2546265641 If you could try that out and give some feedback, that would be great!

Please note: When building the client library from source, we suggest removing the installed apt package (sudo apt remove ros-noetic-ur-client-library)

Thanks for your help, I'll try it later. And i will give you feedback here!

@zp2546265641
Copy link
Author

I've put together a set of pull requests:

@zp2546265641 If you could try that out and give some feedback, that would be great!

Please note: When building the client library from source, we suggest removing the installed apt package (sudo apt remove ros-noetic-ur-client-library)
Hello, my hero. I have installed the source code and compiled it successfully. How can I use the improved service to create a ServiceProxy to control the voltage signal? Sorry, I don't understand this part of the program thoroughly.

@zp2546265641
Copy link
Author

I've put together a set of pull requests:

@zp2546265641 If you could try that out and give some feedback, that would be great!

Please note: When building the client library from source, we suggest removing the installed apt package (sudo apt remove ros-noetic-ur-client-library)

hello, i write it as followed:
class URInterface:
def init(self):
self.set_io_client = rospy.ServiceProxy('/ur_hardware_interface/set_io', SetIO)
self.set_analog_output_client = rospy.ServiceProxy('/ur_hardware_interface/set_io', SetAnalogOutput)

def set_digital_io(self, num, state):
    request = SetIORequest()
    request.fun = SetIORequest.FUN_SET_DIGITAL_OUT
    request.pin = num
    request.state = state
    self.set_io_client(request)
    # self.set_io_client(SetIORequest.FUN_SET_DIGITAL_OUT, num, state)

def set_analog_io(self, channel, voltage):
    request = SetAnalogOutputRequest()
    request.data.pin = channel
    request.data.domain = ur_msgs.msg.Analog.VOLTAGE  # 设置电压, 电流为CURRENT
    request.data.state = voltage
    # self.set_io_client(SetIORequest.FUN_SET_ANALOG_OUT, channel, voltage)
    self.set_analog_output_client(request)

def close_pressure_system(self):
    rospy.loginfo("Closing pressure system...")
    self.set_analog_io(1,0)

def open_pressure_system(self):
    rospy.loginfo("Opening pressure system...")
    self.set_digital_io(7, True)
    rospy.sleep(0.5)
    self.set_analog_io(1, 0.2)

if name == 'main':
try:
ur_interface = URInterface()
# ur_interface.close_pressure_system()
ur_interface.open_pressure_system()
except rospy.ROSInterruptException:
pass
but error:
[ERROR] [1721475813.497080870]: client wants service /ur_hardware_interface/set_io to have md5sum eb3840e5f3632fc236409b92a9250f5b, but it has f539fc0b1a42859fb186a5aaba22d4b0. Dropping connection.

@fmauch
Copy link
Collaborator

fmauch commented Jul 22, 2024

I've added another service, I didn't modify the existing one. Therefore you should do

self.set_analog_output_client = rospy.ServiceProxy('/ur_hardware_interface/set_analog_output', SetAnalogOutput)

@zp2546265641
Copy link
Author

/ur_hardware_interface/set_analog_output

rospy.service.ServiceException: service [/ur_hardware_interface/set_analog_output] unavailable
maybe the launch file i need to download again, and i have a question where do you add the new service about /ur_hardware_interface/set_analog_output?
and now i just change the ur_client_library and ur_msgs, and then rosservice list:
^^^^^^^^^
/ur_hardware_interface/dashboard/unlock_protective_stop
/ur_hardware_interface/get_loggers
/ur_hardware_interface/hand_back_control
/ur_hardware_interface/set_io
/ur_hardware_interface/set_logger_level
/ur_hardware_interface/set_payload
/ur_hardware_interface/set_speed_slider
/ur_hardware_interface/ur_robot_state_helper/get_loggers
/ur_hardware_interface/ur_robot_state_helper/set_logger_level
/ur_hardware_interface/zero_ftsensor
^^^^^^^^

@zp2546265641
Copy link
Author

I've added another service, I didn't modify the existing one. Therefore you should do

self.set_analog_output_client = rospy.ServiceProxy('/ur_hardware_interface/set_analog_output', SetAnalogOutput)

Sorry, that's my fault. I only updated ur_client_library and ur_msgs, but forgot to update the driver package, which led to the current problem. I will try again.

@zp2546265641
Copy link
Author

I've put together a set of pull requests:

@zp2546265641 If you could try that out and give some feedback, that would be great!

Please note: When building the client library from source, we suggest removing the installed apt package (sudo apt remove ros-noetic-ur-client-library)
Hello, the test results are perfect. I installed the wrong package before, which caused the problem. However, I want to ask whether I need to use the RL kernel under the current driver package? Because the RL kernel and the Nvidia driver are incompatible, the RL kernel and the Nvidia driver cannot exist at the same time.

@zp2546265641
Copy link
Author

I've added another service, I didn't modify the existing one. Therefore you should do

self.set_analog_output_client = rospy.ServiceProxy('/ur_hardware_interface/set_analog_output', SetAnalogOutput)

Finally, my hero, I have a basic question, that is, the terminal velocity of the robot is the percentage of the slider in TP multiplied by the 0.2 in self.arm_group.set_max_velocity_scaling_factor(0.2) that I set. Is this the maximum speed of the robot? Or is it not affected by TP and is based on the 0.2 I set here. In addition, I would like to ask if there is any way to get the terminal velocity of the robot. Thank you very much, you are really awesome.

@zp2546265641
Copy link
Author

I've added another service, I didn't modify the existing one. Therefore you should do

self.set_analog_output_client = rospy.ServiceProxy('/ur_hardware_interface/set_analog_output', SetAnalogOutput)

Finally, my hero, I have a basic question, that is, the terminal velocity of the robot is the percentage of the slider in TP multiplied by the 0.2 in self.arm_group.set_max_velocity_scaling_factor(0.2) that I set. Is this the maximum speed of the robot? Or is it not affected by TP and is based on the 0.2 I set here. In addition, I would like to ask if there is any way to get the terminal velocity of the robot. Thank you very much, you are really awesome.

I found that the maximum speed set by the py script is actually the higher the speed set by TP, the higher the actual running speed is. It seems that the py setting does not play any role.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Solution proposed A solution has been proposed inside the issue. Waiting for user feedback.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants