Universal Robots Forum

Decode return value

import socket
import time
import sys

HOST = '169.254.63.28'
PORT = 30002

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.settimeout(1)
s.connect((HOST, PORT))
s.send(("get_actual_tcp_pose()"+"\n").encode('utf8'))
message = (s.recv(1024).decode('utf8'))
print(message)

this is the return value:

b’\x00\x00\x007\x14\xff\xff\xff\xff\xff\xff\xff\xff\xfe\x03\tURControl\x05\x0b\x00\x00\x00\x05\x00\x00\x00\x0015-10-2021, 08:11:44\x00\x00\x00\x18\x14\xff\xff\xff\xff\xff\xff\xff\xff\xfe\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x01’

Obviously there is a timestamp in it, but I couldn’t decode the rest of it so far.

UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0xff in position 5: invalid start byte

hey thanks, so this works quite well

import socket
import struct
import time

HOST = '169.254.63.28'
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 True:
                data = s.recv(4096)
                i = 0
                package_length = (struct.unpack('!i', data[0:4]))[0]
                package_type = (struct.unpack('!B', data[4:5]))[0]
                print("PKG TYPE: " + str(package_type))
                if package_type == 16:
                    while i + 5 < package_length:
                        message_length = (struct.unpack('!i', data[5 + i:9 + i]))[0]
                        message_type = (struct.unpack('!B', data[9:10]))[0]
                        print("MSG TYPE: " + str(message_type))
                        if message_type == 0:
                            sub_package = data[5:i + message_length]
                            is_program_running = struct.unpack('!?', sub_package[18:19])[0]
                            is_protective_stop = struct.unpack('!?', sub_package[17:18])[0]
                            is_robot_on = struct.unpack('!?', sub_package[15:16])[0]
                            time.sleep(0.5)
                            print('PWR ON/STOP/PROG RUN : ' + str(is_robot_on) + '/' + str(is_protective_stop) + '/' + str(is_program_running))
                            break
                        i = message_length + i

I would like to receive other data as well, but I am stuck. This is from another (edited) example but doesn’t return any coordinates. Even when the packettype is 16

#!/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 = '169.254.63.28'
	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:5]))[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:10]))[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
					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))
					#increment i by the length of the message so move onto next message in packet
					i = msglen + i

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