Client-Interfaces – reading the cartesian coordinates (sometimes reffered to as matlab data).
Application Description:
This example shows the use of client-Interfaces (Also sometimes reffered to as Matlab data) on the Universal-Robots to read the robot position from external device.
The application uses the port 30003 on the Universal-Robots which is streaming data out containing informations about the robot status. These data might look like random unreadable data similar to data in a binary file, but thats because the way the data are formatted.
Below is a screen shoot of the dataflow streamed out from port 30003.
Port 30003 is part of the Client-Interfaces and an overview can be found at this link. Client-Interfaces document
A file containing more informations about these data called Client-Interface.xls can be found at this link Client-Interfaces document
In the file Client-Interface.xls at the tab RealTime_3.2 and overview of the data streamed out can be found and where each data can be found in the data stream.
Notice the data for cartesian coordinates shown in line 14 is of type double and has a size of 48 bytes.
Function description:
The aim is to read the Cartiseian coordinates of the tool (X, Y, Z, Rx, Ry, Rz).
(This is similar to reading these data from the MODBUS registers as described in this article MODBUS example of reading the Cartesian position data.)
In this case the cartesian coordinate data are read from a external host with Python code.
Program description:
The external host connects to port 30003 on the UR and continually reads the dataflow which the robot stream out and convert the raw data to readable data in mm.
Since the desired data is located some way down the list as shown in client-interfaces.xls document – therefore the previous data are read first, but not converted and shown.
This means blocks of 4 + 8 + 48 + 48 + 48 + 48 + 48 + 48 + 48 + 48 + 48 are read first, but not converted and not shown.
The next block of 48 bytes contain the data desired – and since the data consists of 6 values (each value therefore contain 8 bytes) then each value of 8 bytes are read one by one and printed out to the screen.
The data are formatted as double and therefore they are converted in human readable data. Some more informations about double can be found at this link Double-precision floating-point format.
Program code:
No program on UR.
Host program in Python code.
# Echo client program import socket import time import struct HOST = "192.168.0.9" # The remote host PORT_30003 = 30003 print "Starting Program" count = 0 home_status = 0 program_run = 0 while (True): if program_run == 0: try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(10) s.connect((HOST, PORT_30003)) time.sleep(1.00) print "" packet_1 = s.recv(4) packet_2 = s.recv(8) packet_3 = s.recv(48) packet_4 = s.recv(48) packet_5 = s.recv(48) packet_6 = s.recv(48) packet_7 = s.recv(48) packet_8 = s.recv(48) packet_9 = s.recv(48) packet_10 = s.recv(48) packet_11 = s.recv(48) packet_12 = s.recv(8) packet_12 = packet_12.encode("hex") #convert the data from \x hex notation to plain hex x = str(packet_12) x = struct.unpack('!d', packet_12.decode('hex'))[0] print "X = ", x * 1000 packet_13 = s.recv(8) packet_13 = packet_13.encode("hex") #convert the data from \x hex notation to plain hex y = str(packet_13) y = struct.unpack('!d', packet_13.decode('hex'))[0] print "Y = ", y * 1000 packet_14 = s.recv(8) packet_14 = packet_14.encode("hex") #convert the data from \x hex notation to plain hex z = str(packet_14) z = struct.unpack('!d', packet_14.decode('hex'))[0] print "Z = ", z * 1000 packet_15 = s.recv(8) packet_15 = packet_15.encode("hex") #convert the data from \x hex notation to plain hex Rx = str(packet_15) Rx = struct.unpack('!d', packet_15.decode('hex'))[0] print "Rx = ", Rx packet_16 = s.recv(8) packet_16 = packet_16.encode("hex") #convert the data from \x hex notation to plain hex Ry = str(packet_16) Ry = struct.unpack('!d', packet_16.decode('hex'))[0] print "Ry = ", Ry packet_17 = s.recv(8) packet_17 = packet_17.encode("hex") #convert the data from \x hex notation to plain hex Rz = str(packet_17) Rz = struct.unpack('!d', packet_17.decode('hex'))[0] print "Rz = ", Rz home_status = 1 program_run = 0 s.close() except socket.error as socketerror: print("Error: ", socketerror) print "Program finish"
Program run:
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 port 30003 and correspond with the actual values of the robot position. The X, Y, Z are in mm and Rx, Ry, Rz are in radians.
And this is also the position of the robot.
Notice: Data of a very small value is written as exponent of 10 – and a value of 10-05 is very small – and is virtual 0.
X = 0.0
Y = 300.0
Z = 300.0
Rx = 0.0
Ry = 3.14
Rz = 0.0
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.
Author:
By Zacobria Lars Skovsgaard
Accredited 2015-2018 Universal Robots support Centre and Forum.
Hi,
I am just start to use this method and I have got some problem about the display of coordinates.
For the initial state of the robot arm, the coordinates shown in terminal is that:
x=1.65
y=-255.46
z=1427.74
rx=0.0078
ry=-2.2247
rz=2.2256
After I wrote a C# program to get the coordinates, I found that the sign of rx and ry are just opposite to the terminal shown.
E.G. :
x=1.65
y=-255.46
z=1427.74
rx = -0.0078
ry = 2.2247
rz=2.2256
But this problem are not happen on any movements, only happens when the arm at home.
Is my program has some bugs?
Hi Dave
Thanks for the question.
This can be because the TCP has more revolutions – so the cordinates might be the same position, but different revolution.
Author:
By Zacobria Lars Skovsgaard
Accredited Universal Robots support Centre and Forum.
Also check out the CB3 forum
Tweet
Follow @zacobria
Thanks for answering my question first, and sorry for replying this so late.
I want to know is the coordinates of rx, ry and rz are correct or not, and how it moves to reach the target position. Because the problem still happening on my robot arm porgram.
I found some and it might related to rotation matrix, it there any easier way to understand this?
Or to calculate this? I want to know more about how it operates.
Thanks!
Hi Dave
That the result is different for the same position but at different revolution is normal.
I do not know how the coordinates are calculated. It might be related to euler axis.
https://en.wikipedia.org/wiki/Axis%E2%80%93angle_representation
Author:
By Zacobria Lars Skovsgaard
Accredited Universal Robots support Centre and Forum.
Also check out the CB3 forum
Tweet
Follow @zacobria
Thanks for the answer, I think it will be useful.
Hi
I have a problem so I ask you a question.
X,Y,Z Values are always correct but Rx,Ry,Rz values is sometimes incorrect.
Sometimes they come out right.
What should I do?
Hi James
Thanks for the question.
What makes you say that the values are incorrect ?
Author:
By Zacobria Lars Skovsgaard
Accredited Universal Robots support Centre and Forum.
Also check out the CB3 forum
Tweet
Follow @zacobria
After moving or moving to a pre-drive state, the values may be different.
XXX is Teaching Panel values, (XXX) is Socket Communication values.
If you are difficult to understand the situation,
Please let me know your email address and I’ll send you a screen capture.
1. Not Match
X : 396.727 mm (-396.73)
Y : 164.433 mm (-164.44)
Z : 321.268 mm (321.26)
Rx : -1.51309 (2.8177)
Ry : -0.0353791 (0.0659)
Rz : 1.59001 (-2.9610)
2. Match
X : 342.551 mm(342.56)
Y : 332.543 mm(-332.54)
Z : 450.941 mm(450.92)
Rx : 1.56851 (1.5685)
Ry : 0.507796 (0.5078)
Rz : 0.534485 (0.5344)
Hi James
Since the robot joints can turn 2 revolutions – (on UR3 the last joint can turn more than 2 revolutions) – then there are more values for the same pose because it depends which revolution of the joints is being used.
Author:
By Zacobria Lars Skovsgaard
Accredited Universal Robots support Centre and Forum.
Also check out the CB3 forum
Tweet
Follow @zacobria
I’m sorry. values has changed.
XXX is Socket Communication values, (XXX) is Teaching Panel values
Hi,
I am working on “Industrial Application of Force Sensing Robot Grippers”. I have finished working on my Gripper and I embed a Force sensor in it.
I need to write exactly the same program as yours in MATLAB, so that I can get the robot motion data and put them together with my sensor data (Program written in MATLAB too). I have been trying but not getting the same output as the one on the robot. I do not know if you guys know MATLAB and could help me out.
I am using Virtual environment (URSim 3.5.3) before I can finally take it to the UR5 robot in the lab practically.
MY MATLAB CODE AND RESULT SO FAR:
clear all
HOST = ‘192.168.56.101’;
PORT_30003 = 30003;
while (true)
s = tcpclient(HOST, PORT_30003);
disp(‘connected and starting program’);
disp(‘data received:’);
data = read(s, 80, ‘uint8’);
disp(data(56:61));
pause(1);
end
RESULT OBTAINED:
client
connected and starting program
data received:
116 68 45 24 0 0
connected and starting program
data recived:
116 68 45 24 0 0
connected and starting program
data recived:
116 68 45 24 0 0
Same continuously since the robot isn’t moved but is so different from the values in my robot.I do not know if the problem is with wrong use of datatype in the program because I just thought uint8 should be the right type to use.
Hi Umar Deyire Yusuf
Thanks for the question.
I am not familiar with Matlab programming, but maybe other on the Forum are.
Author:
By Zacobria Lars Skovsgaard
Accredited Universal Robots support Centre and Forum.
Also check out the CB3 forum
Tweet
Follow @zacobria
ok, but please can you explain what is happening at the conversion stage? around the decode and encode part….
Or recommend a friend of yours who knows MATLAB since you know it and can explain the tasks clearly. I can even pay some tokens for this.
Hi Umar Deyire Yusuf
As mentioned earlier – I am not familiar with Matlab programming so I am not sure what you mean ? – nor do I know about any for recomendation. Maybe consider to use another method as explained on the forum.
Author:
By Zacobria Lars Skovsgaard
Accredited Universal Robots support Centre and Forum.
Also check out the CB3 forum
Tweet
Follow @zacobria
Hi Umar Deyire Yusuf
I have no information about the conversion stage.
Author:
By Zacobria Lars Skovsgaard
Accredited Universal Robots support Centre and Forum.
Also check out the CB3 forum
Tweet
Follow @zacobria
Hi
This paper is about how to receive (X,Y,Z,Rx,Ry,Rz)data.
I want to know how to receive 6 joints data.Have example let me reference?
Thank you!!!
Hi
At this link is an example of sending joint data from the robot
http://www.zacobria.com/universal-robots-knowledge-base-tech-support-forum-hints-tips/knowledge-base/script-client-server/
>>>
Starting Program
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
Author:
By Zacobria Lars Skovsgaard
Accredited Universal Robots support Centre and Forum.
Also check out the CB3 forum
Tweet
Follow @zacobria
Hi all,
I have been trying to read global variable data streamed from port 30001, however, the my decoded data does not make sense and does not coincides with the client scheme. My code and result is as shown below:
overall_len = s.recv(4)
RobMessType = s.recv(1)
packet_1_len = s.recv(4)
packet_1_len = packet_1_len.encode(“hex”)
y = str(packet_1_len)
y = struct.unpack(‘!i’,packet_1_len.decode(‘hex’))[0]
print “Length: “, y
packet_1_MessType = s.recv(1)
y = str(packet_1_MessType)
packet_1_MessType = packet_1_MessType.encode(“hex”)
y = str(packet_1_MessType)
y = struct.unpack(‘!B’,packet_1_MessType.decode(‘hex’))[0]
print “Package Type: “, y
*************RESULTS***************
Length: -1
Package Type: 255
The scheme should follow the client interface documentation provided by UR which can be found in the following link:
https://www.universal-robots.com/how-tos-and-faqs/how-to/ur-how-tos/remote-control-via-tcpip-16496/
Hope to shed some light into this!
Thank you!
Hi Colin
Thanks for the question.
The data I need I read from port 30003 – there might be a difference in the port used-
Author:
By Zacobria Lars Skovsgaard
Accredited Universal Robots support Centre and Forum.
Also check out the CB3 forum
Tweet
Follow @zacobria
Hi Zacobria,
I understand and am aware that you are reading from port 30003, I was just wondering if you will have any ideas on how to deal with port 30001 and 2 too? I have been searching around forums and none gave me a concrete idea.
Not even from UR+ forum.
Thank you!
Hi Colin
The best information I have at hand is the presented in the example, but maybe others have more information.
Author:
By Zacobria Lars Skovsgaard
Accredited Universal Robots support Centre and Forum.
Also check out the CB3 forum
Tweet
Follow @zacobria
Hi again Lars,
I have found the following solution for the encoding and decoding part:
from codecs import encode, decode
packet_12 = encode(packet_12, “hex”)
packet_12 = decode(packet_12, “hex”)
x = struct.unpack(‘!d’, packet_12)[0]
print(“X = ” + str(x*1000))
Probably it’s due to the fact we are using different Python versions.
Best Regards,
Daniel
Hi Daniel
Thanks your information and contributions to the forum.
Yes it is very likely that the Python versions can be different – these examples are using Python version 2.7.
Author:
By Zacobria Lars Skovsgaard
Accredited Universal Robots support Centre and Forum.
Also check out the CB3 forum
Tweet
Follow @zacobria
Hi Lars,
When running the program, it stops at the line: packet_12 = packet_12.encode(“hex”);
Giving me the following error: AttributeError: ‘bytes’ object has no attribute ‘encode’;
The packet_12 has the following value: b’?\xd3X\x94\xbft\xc4\xa6′.
Would you kindly suggest a solution to this problem?
Thanks and Best Regards,
Daniel
Hi Daniel
Thanks for the question.
I just tested and the program runs fine here.
Which Python version are you using ?
Author:
By Zacobria Lars Skovsgaard
Accredited Universal Robots support Centre and Forum.
Also check out the CB3 forum
Tweet
Follow @zacobria
Hello Lars,
I am using Python 3.6. For your tutorials I only had to change the print statements into functions, add “.encode(‘utf8’)” at the end of each URScript command and import the codecs library for decoding and encoding the MATLAB data received from port 30003.
Besides these issues, everything else work fine!
Best Regards,
Daniel
Hello,
i found the solution. For package_x having 8 bytes for X position use:
string s1 = BitConverter.ToString(package_x).Replace(“-“, “”);
double d = BitConverter.Int64BitsToDouble(Int64.Parse(s1, System.Globalization.NumberStyles.HexNumber))*1000;
listBox2.Items.Add(d);
This will give you your answer. Cheers!
Hello Lars,
Can you post an example such as above but also showing the normal hex data from which you get the coordinates?
Hello Harsh
Thanks for the question.
Below is the result when I also print the hex value.
X hex = 3fb998d2ac9138b3
X = 99.9881430919
Y hex = 3fcfff958ad6c57b
Y = 249.987309258
Z hex = 3fd666df39d0154b
Z = 350.028807123
Rx hex = 40091ef16caa4dec
Rx = 3.14010891814
Ry hex = bf03f9b596597622
Ry = -3.81001034781e-05
Rz hex = 3f3d7e1d8386f851
Rz = 0.000450021939766
Author:
By Zacobria Lars Skovsgaard
Accredited Universal Robots support Centre and Forum.
Also check out the CB3 forum
Tweet
Follow @zacobria
hi zacobria.
As I can control the grades or radians of the wrist 1,2 and 3 through the socket connection.
for example. Send from the socket, wrist 3 move 30 degrees. Something like that, or what I need to be able to carry these movements?
Hello amaury
Thanks for the question.
Maybe this post can provide some hints.
http://www.zacobria.com/universal-robots-zacobria-forum-hints-tips-how-to/x-y-and-z-position/#comment-158044
And this article for sending move position through ethernet communication.
http://www.zacobria.com/universal-robots-knowledge-base-tech-support-forum-hints-tips/knowledge-base/script-from-host-to-robot-via-socket-connection/
Author:
By Zacobria Lars Skovsgaard
Accredited Universal Robots support Centre and Forum.
Also check out the CB3 forum
Tweet
Follow @zacobria
Hello, i sent data from a two dimensional matrix using a while loop in matlab, to the UR5 robot interface, but i only get the last element in the matrix, please how do i fix this. Thanks.
Hello Tolu
Thanks for the question.
Hard to say based on the few information for how the data is send to the robot, but maybe it is a timing issue – some informations at this link.
https://www.zacobria.com/universal-robots-knowledge-base-tech-support-forum-hints-tips/universal-robots-script-programming/
Author:
By Zacobria Lars Skovsgaard
Accredited Universal Robots support Centre and Forum.
Also check out the CB3 forum
Tweet
Follow @zacobria
I have some trouble with this example. I try to implement this in C# and don’t get the correct values for the TCP coordinates.
First, I cut out the relevant 48 Bytes from the 1060 Byte package (starting at 444). Then I use this function to convert it to double:
void SetTcpData(byte[] data)
{
TcpX = BitConverter.ToDouble(data, 0); //starting at index 0
}
Here is an example:
The actual data provided in the simulator:
TCP.X: -817.25 mm
The first 8 bytes of the relevant 48 bytes:
[0] 191 System.Byte
[1] 234 System.Byte
[2] 38 System.Byte
[3] 233 System.Byte
[4] 120 System.Byte
[5] 212 System.Byte
[6] 253 System.Byte
[7] 243 System.Byte
And the output:
TcpX = -5,33936027084844E+250
I have no idea what went wrong here. Do I use the wrong Converter method?
Hi Carl
Thanks for the question.
I have no experience in C programming, but maybe others on the forum have.
Author:
By Zacobria Lars Skovsgaard
Accredited Universal Robots support Centre and Forum.
Also check out the CB3 forum
Tweet
Follow @zacobria
Hi Carl,
I am getting the same problem as you. I don’t know what the solution is but it has nothing to do with you writing in C#. I think we are not getting the same packages from the controller as the example. i.e. we are not getting the robot state package.
Still looking into a solution.
Hi Saree
Which values do you get ?
And which values do you expect ?
What is the coordinates of the robot at time of collecting data ?
Is the robot moving ?
Author:
By Zacobria Lars Skovsgaard
Accredited Universal Robots support Centre and Forum.
Also check out the CB3 forum
Tweet
Follow @zacobria
Hey Saree,
We are receiving the same packages from the robot but C# hex to double conversion is not the right one. If you convert those 8 byte hex into double with online converter it displays the right value.
BitConverter.ToDouble(8_byte[],index) gives the wrong conversion.
Hey Carl,
Even i have the same problem. I converted the incoming data to hex and printed it but then at every click, the array values are changing, making no sense as the TCP position is constant.
Finally after lot of doodling I found the way to do it the right way.
Source: https://bytes.com/topic/c-sharp/answers/629092-convert-hex-double-2-0-a
string hex = “414BFCC90D2258ED”;
byte[] b = new byte[hex.Length / 2];
for (int i = (hex.Length – 2), j = 0; i >= 0; i -= 2, j++ )
{
b[j] = byte.Parse(hex.Substring(i, 2),
System.Globalization.NumberStyles.HexNumber);
}
double d = BitConverter.ToDouble(b, 0);
Hi Abhishek
Could you please help us with the parsing of the data being read from the robot. We are receiving 465 bytes of data, but the values for X,Y,Z,RX,RY,RZ don’t match with the values being displayed on the simulator. I believe there is something wrong with the way we are parsing it.
We are trying to read the data in LabVIEW.