Universal-Robots Script Client-Server example.
This example focus on making a program on the UR robot that receives data from an external host e.g. a task server or a vision camera etc.
For this purpose a TCP socket connection over Ethernet will be used. A Universal-Robots can be a TCP Client and from a program open a socket connection towards a TCP server. I this case the socket connection is setup to receive 3 real data (floats) from the host.
The illustrations below shows the starting position of the robot and the intended target position. Notice the object is rotated 45 degrees and therefore the data send to the robot will reflect that belo in the response from the host. Here the host will be a program running on a PC, but it could as well have been a Vision camera replying with the data cordinates for the object.
It is important to understand the X, Y, Z, Rx, Ry, Rz representation in relation to the robot and this article describes some of this:
Read more about X, Y, Z positions for the UR robot
A robot pose can be represented as 6 numbers because Universal-Robot are 6 axis robots and a pose can have the format of p[X, Y, Z, Rx, Ry, Rz]. The small “p” in front is to defined the list as a pose.
Also below is a illustration that shows the X, Y, Z direction in relation to the UR robot tool-head.
Starting Pose – Notice where the Robotiq electrical gripper cable come out is the X direction and Y direction is towards the robot.
Intended target position for the robot – Notice the target object is rotated 45 degree.
This pose is 200mm offset to starting position in X direction and 50mm in Y direction and turned 45 degrees.
The UR robot is setup with the IP address of 192.168.0.9.
In the BeforeStart routine a variable var_1 is assigned an IP address and port to a corresponding Server. In this case there will be a PC with the IP address of 192.168.0.100 a Server program listening on Port 30000. Var_1 will be False if there is not Server listening or True if there is a Server listening.
And the robot is moving to is idle position which is Waypoint 1.
In the main program the program check if the was a ready Server to connect to. If not the Loop will just keep looping until there is a Server with an active port.
When the connection has been established the robot send a trigger string which can be freely defined, but must be what the Server expect – in this case in choosen to send a string “asking_for-data”.
Then the robot expect to receive a list 3 real data (floats) to put into variable var_2.
In this case the robot which is the client closes the socket connection, but it could also be left open if the server can handle that properly.
When the robot receives the list of data – the list actually contains 4 elements for example [3, 200, 50, 45]. The first element represents the number of data received – in this case 3 as expected and the there data are 200, 50, 45.
Therefore it is possible to check whether any data was received – so in this case it is checked that the first element of the list in variable 2 is different than 0 which means data has been received.
Each element is inserted into another list contained in var_3 which is a Pose with the format of [X, Y, Z, Rx, Ry, Rz] and in this mode the robot uses meter as measurements and therefore X and Y data are divided by 1000 whereas the angles are in radians so therefore the Rz data is converted from degrees to radians.
In order to move from the current position to the intended position based on the data received the function “pose_trans” is used. Therefore the current position is established and inserted into var_5.
Thereafter the current position is trans posed with the received data into var_4 which now contains the intended target position (pose). Var_4 is a variable waypoint.
Then the robot move in a linear move to this computed var_4 waypoint and wait 1 second before moving back to idle position Waypoint 1.
Host program in Python code.
A Server must be active to reply data to the robot and in this case a small Python server program is used. This example below is a Server that listen for incomming requests. The server runs on a PC with the IP addreess 188.8.131.52 and uses port 30000.
When a connection is received the server will monitor the data received and if the data is “asking_for_data” the server will reply with 200, 50, 45 back to the Client. These data is the offset the target item is away from the idle position of the robot.
# Echo client program import socket import time
HOST = "192.168.0.100" # The remote host PORT = 30000 # The same port as used by the server
print "Starting Program" count = 0 while (count < 1000):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind((HOST, PORT)) # Bind to the port s.listen(5) # Now wait for client connection. c, addr = s.accept() # Establish connection with client.
try: msg = c.recv(1024) print msg time.sleep(1) if msg == "asking_for_data": count = count + 1 print "The count is:", count time.sleep(0.5) print "" time.sleep(0.5) c.send("(200,50,45)"); print "Send 200, 50, 45"
except socket.error as socketerror: print count c.close() s.close()
print "Program finish"
When this robot program is executed and the server is active and responding with data – these data can be observed in the Variables tab as shown on the illustration below. And the robot moves to the offset position 200mm X, 50mm Y and turn the head 45 degrees. These data could as well has been from a vision camera.
It is also possible to reference to a new plane created in the Features menu under installation. Below is the first argument in the pose_trans command the Plane_1 – which beforehand needs to be created in the Features screen. In this way a new plane coordinate system is the reference. This is use full for example in a vision system where the Plane_1 has been set to the same area as the camera field of view.
It is also possible to send the position data over to the host via Client-Server connection.
The Polyscope program is modified to read the pose position and read the joint positions – and then send these variables over to the host.
Host program in Python code.
The python code on the host is also modified to read and print the data for the pose and joint positions.
# Echo client program import socket import time HOST = "192.168.0.100" # The remote host PORT = 30000 # The same port as used by the server print "Starting Program" count = 0 while (count < 1000): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind((HOST, PORT)) # Bind to the port s.listen(5) # Now wait for client connection. c, addr = s.accept() # Establish connection with client. try: msg = c.recv(1024) print "Pose Position = ", msg msg = c.recv(1024) print "Joint Positions = ", msg msg = c.recv(1024) print "Request = ", msg time.sleep(1) if msg == "asking_for_data": count = count + 1 print "The count is:", count time.sleep(0.5) print "" time.sleep(0.5) c.send("(200,50,45)"); print "Send 200, 50, 45" except socket.error as socketerror: print count c.close() s.close() print "Program finish"
The robot is in this position – Notice the X, Y, Z, Rx, Ry, Rz values in the Move screen.
Below is the printout on the screen with the X, Y, Z, Rx, Ry, Rz values when the Python program is executed. The values are collected from the Polyscope program variables “pose_position” and “joint_positions” and correspond with the actual values of the robot position. The X, Y, Z are in m and Rx, Ry, Rz are in radians.
Pose Position = p[2.39984e-06,0.299984,0.299999,-2.47874e-05,3.14002,-5.52232e-05]
Joint Positions = [-1.95426,-1.65715,1.71108,-1.62348,-1.55893,2.75828]
Request = asking_for_data
The count is: 1
Send 200, 50, 45
Notice that when the data has a very small value – then the exponent of 10 notation is used – for example in this case
X = 2.39984e-06,0.299984 (Which = 2.39 to the power of 10-6 – which is litteraly 0 (zero) because it is a very small value.
Y = 0.299984 (Which is in meter = 299.984mm (which is 300mm because the fractions is below 0.1mm which is the robots repeatability).)
Notice that the joint values are in Radians. In order to convert them to degress to compare them with the move screen these formulas can be used.
Formula for converting Radians to degrees on UR:
(Radian / Pi) x 180 = The Degree shown in the Move Screen.
Formula for converting degrees to Radians:
Pi x (The Degree shown in the Move Screen) / 180 = Radian
So when the J0 value is shown as -1.95426 radians the conversion to degrees is
(-1.95426 / pi) x 180 = -111.97 degrees as shown on the move screen.
Disclaimer: While the Zacobria Pte. Ltd. believes that information and guidance provided is correct, parties must rely upon their skill and judgement when making use of them. Zacobria Pte. Ltd. assumes no liability for loss or damage caused by error or omission, whether such an error or omission is the result of negligence or any other cause. Where reference is made to legislation it is not to be considered as legal advice. Any and all such liability is disclaimed.
If you need specific advice (for example, medical, legal, financial or risk management), please seek a professional who is licensed or knowledgeable in that area.
By Zacobria Lars Skovsgaard
Accredited Universal Robots support Centre and Forum.