Writing a value in a RTDE INPUT_DOUBLE_REGISTER and reading it back with another RTDE client leads to lost precision.
For exemple, the value 556.044 which is represent by the double precision value 556.043999999999982719600666314 is read back with the value 556.04400634765625, which is the most accurate representation with a float precision.
Is there a way to pass a double precision value from one RTDE client to another one without lost of precision ?
From the documentation it seems that it should be a double register. Is it in the [0…23] or the [24…47] region?
It is in the [24…47] region.
You can reproduce the lost of precision using the UR RTDE Python library to write in a double register and display the value in Polyscope.
Are you seeing this when you read with other clients too?
The URScript number variable type (and therefore the variable window in Polyscope?) only supports int or float so that would explain why you’re not seeing the full double precision there?
@ajp In my application, I write in INPUT_DOUBLE_REGISTER_24 with a first RTDE client and read INPUT_DOUBLE_REGISTER_24 with a second RTDE client.
My application is in C++ and I verify with Wireshark that the data package send by the first RTDE client is in double precision and that the value received by the second RTDE client from RTDE server is in float precision.
I also reproduce the double precision lost with a Python example using the UR RTDE library rtde-2.3.6.
The example use only one RTDE client writing in INPUT_DOUBLE_REGISTER_24 and reading it back.
here is the output:
inputs : 556.0440000000000 outputs : 556.0440063476562
The output correspond to the most accurate representation of the input with a float precision.
Here is the Python program
#!/usr/bin/env python import sys sys.path.append('..') import rtde.rtde as rtde import rtde.rtde_config as rtde_config ROBOT_HOST = '10.20.22.10' ROBOT_PORT = 30004 config_filename = 'doublePrecisionLost.xml' conf = rtde_config.ConfigFile(config_filename) output_names, output_types = conf.get_recipe('output') input_names, input_types = conf.get_recipe('input') con = rtde.RTDE(ROBOT_HOST, ROBOT_PORT) con.connect() # setup recipes con.send_output_setup(output_names, output_types) inputs = con.send_input_setup(input_names, input_types) #start data synchronization if not con.send_start(): sys.exit() inputs.input_double_register_24 = 556.044 print("inputs : %.13f"%inputs.input_double_register_24) con.send(inputs) outputs = con.receive() print("outputs : %.13f"%outputs.input_double_register_24) con.send_pause() con.disconnect()
and the configuration file
<?xml version="1.0"?> <rtde_config> <recipe key="output"> <field name="input_double_register_24" type="DOUBLE"/> </recipe> <recipe key="input"> <field name="input_double_register_24" type="DOUBLE"/> </recipe> </rtde_config>
Google is telling me to expect accuracy of 7 decimal places from a float and 15 from a double… in which case this would be correct?
I also tried to get value of register from real robot (UR3, SW3.12.1).
It is same thing in the [0…23] region too.
To eleminates printing format issue or type casting of the possible explanations, I use Wireshark to look at the network RTDE raw data.
The raw data of my register value send to RTDE server is in double precision.
The 64 bits of raw data receive from RTDE server of the same register value should be exactly the same.
I found out that half the bits are actually clear to 0.
So the RTDE server clearly reduce the precision of my value
A good explanation to me is that the RTDE server casted the double precision value to a float.
@jbm Could you validate with your developper team that the problem described in this post about precision losted in RTDE float register is a real issue ?
Internally GP registers are stored as single precision values, so bug is confirmed Thank you for reporting.
Could you elaborate impact on robot operation? Internally UR controller operates mostly on single precision values so gp register will be truncated when used in calculations anyway. Is this a problem in practice?
@mmi Thanks for the answer.
We use the RTDE to exchange data between a deamon and an external device. Since other URCaps could write on RTDE registers, we validate data with a keep alive signal and CRC. At first, CRC failed du to this bug. We escaped this issue by casting our values to single precision.
We were also thinking to send 2 single precision value on 1 RTDE register to reduce nombre of used register.
Do you know if the bug is planned to be fixed ?
I’ll add your use case to bug description. It’s in backlog now waiting for prioritization.