mavlink / MAVSDK

API and library for MAVLink compatible systems written in C++17
https://mavsdk.mavlink.io
BSD 3-Clause "New" or "Revised" License
633 stars 508 forks source link

Getting UINT16 param from ArduPilot doesn't work #2396

Closed pavloblindnology closed 1 month ago

pavloblindnology commented 1 month ago

Cannot read any param from ArduPilot other than float and int32 - say RC1_MIN (int16). Aftere debugging I can see that the problem is in mavlink_parameter_client::get_param_async_typesafe function. Before it parameter is succesfully read. But checking its type (int16_t vs int32_t) doesn't pass here https://github.com/mavlink/MAVSDK/blob/b4160bb0ceab38db13113d24f0ede087b8804f1f/src/mavsdk/core/mavlink_parameter_client.cpp#L280

julianoes commented 1 month ago

Does ArduPilot use uint16 params? Could you help me reproduce the issue?

pavloblindnology commented 1 month ago

Does ArduPilot use uint16 params? Could you help me reproduce the issue?

No, AP supports only int8, int16, int32 and float params. To reproduce the bug just try to read any int16 param (say RC1_MIN) with any get_param_int method (say mavsdk::Param::get_param_int).

I've fixed this by specializing template method MavlinkParameterClient::get_param_async_typesafe like this

template<>
void MavlinkParameterClient::get_param_async_typesafe(
    const std::string& name, const GetParamTypesafeCallback<int32_t> callback, const void* cookie)
{
    // We need to delay the type checking until we get a response from the server.
    GetParamAnyCallback callback_future_result = [callback](Result result, ParamValue value) {
        if (result == Result::Success) {
            if (value.is<int32_t>()) {
                callback(Result::Success, value.get<int32_t>());
            } else if (value.is<int16_t>()) {
                callback(Result::Success, value.get<int16_t>());
            } else if (value.is<int8_t>()) {
                callback(Result::Success, value.get<int8_t>());
            } else {
                callback(Result::WrongType, {});
            }
        } else {
            callback(result, {});
        }
    };
    get_param_async(name, callback_future_result, cookie);
}
julianoes commented 1 month ago

Given you have code to fix it @pavloblindnology, do you want to create a pull request to contribute it? That would be great.

pavloblindnology commented 1 month ago

Sure, why not. If it looks plausible to you.

pavloblindnology commented 1 month ago

@julianoes Access denied while pushing PR branch.

JonasVautherin commented 1 month ago

@pavloblindnology: you need to create a fork, push your branch to your fork, and open a PR to this repo 👍

pavloblindnology commented 1 month ago

@JonasVautherin Please note that I also created backport v2.12 PR #2401.