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

PARAM_VALUE_DATA #77

Open
wucke13 opened this issue Sep 9, 2020 · 9 comments
Open

PARAM_VALUE_DATA #77

wucke13 opened this issue Sep 9, 2020 · 9 comments

Comments

@wucke13
Copy link

wucke13 commented Sep 9, 2020

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?

@patrickelectric
Copy link
Member

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

@wucke13
Copy link
Author

wucke13 commented Sep 10, 2020

@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?

@patrickelectric
Copy link
Member

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.

@wucke13
Copy link
Author

wucke13 commented Sep 13, 2020

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?

@patrickelectric
Copy link
Member

patrickelectric commented Sep 13, 2020

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.

@wucke13
Copy link
Author

wucke13 commented Sep 14, 2020

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?

@patrickelectric
Copy link
Member

patrickelectric commented Sep 14, 2020

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

@wucke13
Copy link
Author

wucke13 commented Sep 18, 2020

Yes it does! Thank you!

@wucke13 wucke13 closed this as completed Sep 18, 2020
@wucke13
Copy link
Author

wucke13 commented Feb 4, 2021

@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 wucke13 reopened this Feb 4, 2021
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