How to process package from robot controller

Hi,

I am using SocketTest3 to connect to robot controller and I receive these output/package from robot controller.

can someone tell how to process these data/package from port 30001,30002,30003 and 30004

I have a hard time try to understand Real-Time Data Exchange (RTDE) Guide - 22229

would be a great help if someone could explain to me

thanks

these are what i get from each port



Hi.
You should read it at a byte stream.
maybe this link helps. Link_ Remote Control Via TCP/IP - 16496

hi

can you give some example for me ? i also confused about this .

You can use the Struct library in python to unpack the byte stream, using the information in this excel sheet to tell you which info can be found where.

You may want to consider using the RTDE instead of the other client interfaces, that way you can customise the stream to only include the information you want, so you don’t need to sift through the whole lot.

Here’s a python example getting some basic positional info from the client interface stream. You’d probably want to step through the packet contents in a bit more of an organised manner, but this should give a rough idea of how to process the data:

#!/usr/bin/env python
# encoding: utf=8

""" 
#UR Controller Client Interface Datastream Reader
# For software version 3.x
#
# Datastream info found here: https://s3-eu-west-1.amazonaws.com/ur-support-site/16496/Client_Interface.xlsx
# Struct library used to extract data, info found here: https://docs.python.org/2/library/struct.html
"""

import socket, struct

def main():

	#Establish connection to controller
	HOST = '127.0.0.1'
	PORT = 30002

	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
	s.connect((HOST, PORT))

	while 1:
		#Loop forever, receive 4096 bytes of data (enough to store any packet)
		data = s.recv(4096)
		#initialise i to keep track of position in packet
		i = 0
		if data:
			#Print title to screen
			print '*******'
			print 'UR Controller Primary Client Interface Reader' 
			print '*******'
			#extract packet length, timestamp and packet type from start of packet and print to screen
			packlen =  (struct.unpack('!i', data[0:4]))[0]
			timestamp = (struct.unpack('!Q', data[10:18]))[0]
			packtype = (struct.unpack('!b', data[4]))[0] 
			print 'packet length: ' + str(packlen)
			print 'timestamp: ' + str(timestamp)
			print 'packet type: ' + str(packtype)
			print '*******'

			if packtype == 16:
				#if packet type is Robot State, loop until reached end of packet
				while i+5 < packlen:

					#extract length and type of message and print if desired
					msglen = (struct.unpack('!i', data[5+i:9+i]))[0] 
					msgtype = (struct.unpack('!b', data[9+i]))[0] 
		
					#print 'packet length: ' + str(msglen)
					#print 'message type: ' + str(msgtype)
					#print '*******'

					if msgtype == 1:
						#if message is joint data, create a list to store angles
						angle = [0]*6
						j = 0
						while j < 6:
							#cycle through joints and extract only current joint angle (double precision)  then print to screen
							#bytes 10 to 18 contain the j0 angle, each joint's data is 41 bytes long (so we skip j*41 each time)
							angle[j] = (struct.unpack('!d', data[10+i+(j*41):18+i+(j*41)]))[0]
							print 'Joint ' + str(j) + ' angle : ' + str(angle[j])
							j = j + 1
							 
						print '*******'
	
					elif msgtype == 4:
						#if message type is cartesian data, extract doubles for 6DOF pos of TCP and print to sc    reen
						x =  (struct.unpack('!d', data[10+i:18+i]))[0]
						y =  (struct.unpack('!d', data[18+i:26+i]))[0]
						z =  (struct.unpack('!d', data[26+i:34+i]))[0]
						rx =  (struct.unpack('!d', data[34+i:42+i]))[0]
						ry =  (struct.unpack('!d', data[42+i:50+i]))[0]
						rz =  (struct.unpack('!d', data[50+i:58+i]))[0]

						print 'X:  ' + str(x)
						print 'Y:  ' + str(y)
						print 'Z:  ' + str(z)
						print 'RX: ' + str(rx)
						print 'RY: ' + str(ry)
						print 'RZ: ' + str(rz)
						print '*******\n'
					#increment i by the length of the message so move onto next message in packet
					i = msglen + i

if    __name__ == '__main__':
    import sys
    main()
1 Like

hi , thank you for your kindly help. do you have this example in Java? maybe that would be easier to understand。 i have try many methods in Java , but it doesnt work as my expectation…

here is my code to read datas From ur Server .BUT the result : str is worry and is char disorder…

public static final String IP = “127.0.0.1”;
public static final int PORT = 30003;

while(true){

                dis = new DataInputStream(client.getInputStream());  
                BufferedReader inFromServer = new BufferedReader(new InputStreamReader(client.getInputStream()));
                //String receive = String.valueOf(dis.readChar());//;/dis.readUTF(); //String.valueOf(dis.readChar()); //Integer.toString(dis.read(result)); //dis.readUTF();                  
                String receive = inFromServer.readLine();   	              
                ByteBuffer bb3 = Charset.forName("GBK").encode(receive);
                byte [] b   = bb3.array() ;          
                ByteBuffer bb4= ByteBuffer.wrap(b);
                String str = Charset.forName("GBK").decode(bb4).toString();
               
                if(receive != null)
                {
	                serverMessageTextField.setText(" receive: \n" + str);
                }                  
            }

Perhaps this will help?

You could also check out the getRobotData sample URCap in the samples topic, this implements a Java class that reads the Realtime Client message.

2 Likes

yes i have already found than example, thank you very much!

Hello,
I am also looking for same example. I want to get a date and time from controller. I am using datetime() function from the python library. Can you please help me with this

Hi,

Jacob made an sample on github, that might be useful to you !

Thank you for your reply …
Actually I had gone through this urcap.
But my problem is, How we can extract the real date and time through python socket communication?
With this URCAP we can able to write script in polyscope.
Same thing I want to do it from PC.
I tried to send script functions through socket communication but not able to get answer.

Thank you for posting this example – this is just what I’m looking for. When I run this I get the error below (using Python 3, and UR v 5.9.1). Any ideas on what I need to do to address this?

Thank you!

*******
UR Controller Primary Client Interface Reader
*******
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-25-d074676857c5> in <module>()
     89 if    __name__ == '__main__':
     90     import sys
---> 91     main()

<ipython-input-25-d074676857c5> in main()
     37                         packlen = (struct.unpack('!i', data[0:4]))[0]
     38                         timestamp = (struct.unpack('!Q', data[10:18]))[0]
---> 39                         packtype = (struct.unpack('!b', data[4]))[0]
     40                         print('packet length: ' + str(packlen))
     41                         print('timestamp: ' + str(timestamp))

TypeError: a bytes-like object is required, not 'int'

There was a change at some point that changed the syntax of that command. This worked for me:

packtype = (struct.unpack('!b', data[4:5]))[0]
1 Like

That did it – thank you!

Hi,

Do you know in which order the joint information is sent? I mean which joint go first, second, third… I see that in your code you identify each joint with the number, i would like to identify each joint with its name: Base, Shoulder, Elbow, Wirst1, Wirst2, Wirst3. This is the order that Polyscope shows the joint information in Move tab, but i don’t know if it is the same order in which the information is sent.

Thank you for your time!

Yes within the joint data package in the robot state message on primary and secondary interfaces, the joint data will be in the order you specify in your post.

image

1 Like

Thank you! Another quick question, could you confirm me if the units in which the values are sent are:

  • Voltage: V.
  • Intensity/current: A.
  • Temperature: ºC.

Currently I’m working with ursim and I receive some of these values as 0, so I can not get an idea of their units.

Thank you!

Greetings,

Similar to the code you posted above, I’d like to extract the joint velocity data; I assume this is qd_actual". Is there a way to extract this, similar to how you extracted the angle data? Could we just replace the angle byte values here with the correct bytes (i.e. replacing 10 and 18 with the correct byte values)?

Something like:

            velocity[j] = (struct.unpack('!d', data[10+i+(j*41):18+i+(j*41)]))[0]
            print('Joint ' + str(j) + ' velocity : ' + str(velocity[j]))

Thank you!

Yes that’s correct in principle. This code is quite old though so something else may have changed in the format of the output stream, the 41 bytes for joint data packet might not be correct anymore. I’d confirm it still works with joint angles before adjusting it to get velocities.

I can confirm that the code is working for the joint angles, but I’m not sure which bytes to use for the velocities. Do you know or is that documented somewhere? The RTDE guide lists that detail (https://s3-eu-west-1.amazonaws.com/ur-support-site/16496/ClientInterfaces_Realtime.pdf – page 2), but I don’t see a similar guide for the Primary interface.

Edit: Alternatively, is there a Python-RTDE example showing how to get joint angles/velocity? I’m not set on the Primary interface.

Thank you!