rust-mavlink icon indicating copy to clipboard operation
rust-mavlink copied to clipboard

PARAM_VALUE_DATA

Open wucke13 opened this issue 4 years ago • 9 comments

How are the different types in MavParamType encoded in PARAM_VALUE_DATA?

Especially, how is a UINT64 put to the PARAM_VALUE_DATA.param_value field, which is only f32?

wucke13 avatar Sep 09 '20 19:09 wucke13

Hi @wucke13, PARAM_VALUE does not support uint64, only float32, you can check it here: https://mavlink.io/en/messages/common.html#PARAM_VALUE

patrickelectric avatar Sep 10 '20 01:09 patrickelectric

@patrickelectric Thank you for the fast response, though that does not answer my question fully. E.g., if I want to write 13 aka 0xd to a variable which is uint, not float, what do I write to said f32? 13.0?

wucke13 avatar Sep 10 '20 08:09 wucke13

Can you explain which parameter are you talking about ? Take in mind that you are right now talking about the mavlink specification and not the mavlink rust library, since the specification says that the parameter is a float 32 value.

patrickelectric avatar Sep 10 '20 16:09 patrickelectric

I don't really see the point in speaking about one parameter in particular, but here you go. ARMING_CHECK seems to be a bitmask. How is this represented in rust-mavlink?

wucke13 avatar Sep 13 '20 14:09 wucke13

The information is encoded as a bitmask, but the true value of ARMING_CHECK is an int that is casted to float. And this is not how rust-mavlink deals with the value, that's how the mavlink protocol is defined. E.g: Barometer + Compass will result in 0b0000'0000'0000'0110, that's equal to 6 (int), that is casted to float as 6.0; As a side note, all parameters are casted to float, as I said, this is how the mavlink protocol works, think that any value will be in the backend an int number if the information is a bitmask, hexadecimal and etc.

patrickelectric avatar Sep 13 '20 18:09 patrickelectric

Ok, thank you for the detailed explanation! Then only one question is left on my side: what meaning does param_type have in this setting? Can it be arbitrarily, because the FC know what type a parameter is anyways?

wucke13 avatar Sep 14 '20 11:09 wucke13

it's only important for the GCS, the flight controller will probably ignore this field. Please close the issue if that answers your question.

patrickelectric avatar Sep 14 '20 12:09 patrickelectric

Yes it does! Thank you!

wucke13 avatar Sep 18 '20 14:09 wucke13

@patrickelectric After carefully reading the mavlink specs section about the parameter protocol, I'm inclined to believe that this statement is wrong:

The information is encoded as a bitmask, but the true value of ARMING_CHECK is an int that is casted to float. And this is not how rust-mavlink deals with the value, that's how the mavlink protocol is defined.

What I understand from reading it is, that the correct way per mavlink spec would be to cast (in the sense of CPP's static_cast, so rather convert than) an int to a float (e.g 13i16 -> 13.0f32).

Doing this is indeed incompatible with the mavlink spec (even though Ardupilot does it like that). The correct way would be similar of what in CPP is referred to as a reinterprete_cast (and maybe some zero padding, if the encoded types size is smaller than the 4 bytes of an f32). Despite the mavlink spec's claim that the param_value is of type f32, it actually is a 4 byte payload, which might contain the bytewise repesentation of an u16, an i32 or whatever else is mentioned in the MAV_PARAM_TYPE enum.

The current mavlink-rs API does not reflect this. And AFAIK in safe Rust it is not even possible to directly store some arbitrary bytes in the memory region which makes up a f32. I think this should be fixed in the API, possibly using the rust enum + union approach, e.g. making MavParamType's variants take one value of the respective type plus some From & Into magic for it, while getting rid of the raw param_value field. As an alternative, param_value could be of type [u8; 4], and we leave it up to the user to populate it with something like 13f32.to_ne_bytes() and so on.

What I do not understand so far is how values with more than 4 bytes are to be represented in MAVLink.

wucke13 avatar Feb 04 '21 17:02 wucke13