ROBOTIS-GIT / DynamixelSDK

ROBOTIS Dynamixel SDK (Protocol1.0/2.0)
http://emanual.robotis.com/docs/en/software/dynamixel/dynamixel_sdk/overview/
Apache License 2.0
454 stars 405 forks source link

groupSyncRead Question #475

Open swiz23 opened 3 years ago

swiz23 commented 3 years ago

I noticed that the return type for groupSyncRead is a uint32_t as shown below.

https://github.com/ROBOTIS-GIT/DynamixelSDK/blob/6ae113ab5a2b1133ee081c8d110be62a098c051c/c%2B%2B/src/dynamixel_sdk/group_sync_read.cpp#L177

So, what happens if I want to read a register that has a different type? For example, many registers are only 1 or 2 bytes long. Similarly, even those that are 4 bytes long have values that are not necessarily unsigned (for example, Present Position or Present Velocity can have signed values).

To give a concrete example, negative PWMs will show up as 65,506 for example instead of -29 or something. How should I deal with this?

ROBOTIS-Will commented 3 years ago

Hi @swiz23, Thank you for the inquiry. Depending on the length of requested data, the switch - case will handle the byte assembly in unsigned value. As you already know some data from DYNAMIXEL allows negative values while some don't. Since SDK provides lower level implementation using DYNAMIXEL, it is recommended to provide features such as handling 2's complement from customers' applications. Thank you.

swiz23 commented 3 years ago

I don't have much experience handling 2's complement, but I'll research it. But that aside, let's say I know I'm reading a 4 byte register. But one of the 4 byte registers can have negative values, and one of them is always positive or 0. How should that be handled? I realize that this is a probably a straightforward question, but I'm a bit (no pun intended) new to this stuff :)

ROBOTIS-Will commented 3 years ago

Not sure if I understand you correctly because each control table data does not mix a method to represent its data. When representing a negative value with 2's complement, proceeding bits will be 1. For example, representing -29 in 2's complement with uint8_t will be 1110 0011, while uint16_t representation will look like 1111 1111 1110 0011

If you are collecting multiple data from sync read, you need to use correct data type for negative / non-negative values like signed or unsigned. For example, reading 4 byte Goal Position (116) and 2byte Realtime Tick(120) with sync read, int32_t can be used for the Goal Position and uint16_t can be used for the Realtime Tick.

swiz23 commented 3 years ago

Is there a table somewhere that specifies what type to use when accessing each register?

Like, for the Model Number (2 Bytes), should i use int16_t or uint16_t? Or, should I just assume that if the register never goes negative, I can use an unsigned integer of the correct size?

From what you're saying, casting a present position register value from a uint32_t to an int32_t seems to solve the 2's complement issue, right?

ROBOTIS-Will commented 3 years ago

You can refer to the DYNAMIXEL eManual. In the Control Table section, you can see the size of each data and its range for selecting a proper data type. https://emanual.robotis.com/docs/en/dxl/x/xm430-w210/#control-table-of-eeprom-area

For the negative value, int32_t will only display a very large number, so you should properly convert the value using 2's complement conversion. Thanks.

swiz23 commented 3 years ago

Thanks!

For the negative value, int32_t will only display a very large number, so you should properly convert the value using 2's complement conversion.

Wait, since int32_t is signed, then won't it properly display the correct negative value?

ROBOTIS-Will commented 3 years ago

@swiz23 oh, I'm sorry about that, I was confused with a python case #442 . int32_t will correctly display the signed value.