Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Raw Command Throttle Value Decoding not Standard Compliant #68

Open
ampere-tobi opened this issue Apr 17, 2024 · 1 comment
Open

Raw Command Throttle Value Decoding not Standard Compliant #68

ampere-tobi opened this issue Apr 17, 2024 · 1 comment

Comments

@ampere-tobi
Copy link

ampere-tobi commented Apr 17, 2024

Hello,
im trying to decode raw throttle commands without using libcanard. The specification shows a clear way how multiple values, in this case 14bit are meant to be packed into the message. https://dronecan.github.io/Specification/figures/bit_encoding.png
However after some review of the actual traffic, there seems to be significant deviation. Only the first throttle value in a 4 channel single frame configuration is placed in compliance, to some extenend. The others are also packed, although needs shifting to fit together, in 14bit packages but have to be descattered by shifting bit pairs in an arbitrary pattern within said 14bit packets to retrieve the correct value.
Can anyone shine some light into the issue and whats the magic behind this weird encoding pattern.
Kind Regards Tobi

@bnickodemus
Copy link

Nobody explained it to me but it's not difficult to figure out.

e.g.
TX 15:27:29.608994 NFD 1404067F 13 5B 05 5F F3 C7 5D D3 .[._..]. 127 uavcan.equipment.esc.RawCommand
cmd: [5651, 5569, 4095, 7453]
interpret 0x135B055FF3C75D in binary, drop tail byte:
[00010011 010110] [11000001 010101] [11111111 001111] [00011101 011101]
5651 = 010110 00010011
5569 = 010101 11000001
4095 = 001111 11111111
7453 = 011101 00011101
The pattern should now be obvious.

//decode
uint32_t bit_ofs = 0;
uint8_t* payload_head = frame.data;
pool_counter = frame.data_len-1; // drop tail byte
uint8_t payload = pool_counter * 8 / 14; // bit_length is 14
for (int i = 0; i < payload; i++) // payload is 4 for a single frame transfer
{
memset(&storage, 0, sizeof(storage));
copyBitArray(&payload_head[0], bit_ofs, bit_length, (uint8_t*) &storage.bytes[0], 0);
storage.bytes[14 / 8U] = (uint8_t)(storage.bytes[14 / 8U] >> ((8U - (14 % 8U)) & 7U));
if (i == PcSettings.DroneCanMotorId)
{
pwm_dronecan = storage.s16;
break;
}
bit_ofs += 14;
}

For multi frame transfers, you need to wait until all bytes are received before you can decode.

Read the transport layer:
https://dronecan.github.io/Specification/4.1_CAN_bus_transport_layer/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants