Negative value of current, rpm and position are wrongly read


Dynamixel SDK with Python

Control Environment

I’m using the dynamixel XM540-W270-T with U2D2 and Power board connected to windows 11, python with Dynamixel SDK.

Software Description

When I read the present current in python of the motor I get back the wrong value. Same for the speed and position.

Belowe you can see how I read the values:

dxl_present_current, dxl_comm_result, dxl_error = packetHandler.read2ByteTxRx(portHandler, MOTOR_ID, 126)

dxl_present_position, dxl_comm_result, dxl_error = packetHandler.read4ByteTxRx(portHandler, MOTOR_ID, 132)

dxl_present_rpm, dxl_comm_result, dxl_error = packetHandler.read4ByteTxRx(portHandler, MOTOR_ID, 128)

Issue Description

When the value are positive I receive the correct value, but if the value is negative (negative velocity, negative current or negative position (in extended position control mode)) the value that I get is completely wrong.
If I use the dynamixel wizard 2.0 I get the correct value in any case.
I think is a problem of the read2ByteTxRx and read4ByteTxRx function in the Dynamixel SDK library, I think they handle in the wrong way negative value.

How can I solve this problem?

As documented on the eManual page for the XM540-W270-T, negative values are represented using two’s compliment.

To read the correct values in your code you will need to process negative numbers according to this encoding method.

the dynamixel SDK library should not already handle these types of things? (Appear to be not the case)

Hey. I’m running in a similar issue I guess, not sure. I cannot take a twos compliment of a number that’s not binary and the current value I’m receiving are in the range of 65523. Did you end up figuring it out ?

The “integer” received from ROBOTIS hardware via DXL-SDK function calls such as read2ByteTxRx is already in its 2-complement format. So let’s say that we are dealing with a parameter being returned from the Control Table as a 16-bit integer using a 2-complement coding scheme, meaning that its “real” value is between -32768 and + 32767 (and not between 0 and 65535), for example, the Acc_X of the IMU in the Controller CM-550, see screen capture below:

So inside your Python/C/C++ code, a possible pseudo-code approach for conversion into “regular” positive or negative integers can be as follows:

if (Acc_X > 32767) // NEGATIVE VALUES for Acc_X
Acc_X = (65536 - Acc_X) * -1
else // POSITIVE VALUES for Acc_X so use it as received
Acc_X = Acc_X

so “65535” represents “-1” and “65523” represents “-13”. Also “99” represents “99”!

1 Like

Thanks a lot for a detailed response. I had tried this approach but the control table for the XC330M288T motor does not have these parameters so im not sure what range to use for the logic.
i will try this logic and get back .
Thanks a lot !!