Skip to content

Commit ae250bb

Browse files
committed
core/param/param_server: add PARAM_ERROR support
This adds support for the new PARAM_ERROR message which makes the param protocol more robust in case things go wrong. Instead of waiting for a timeout, we actually get an error.
1 parent ff1ec6c commit ae250bb

File tree

13 files changed

+406
-124
lines changed

13 files changed

+406
-124
lines changed

docs/en/cpp/api_reference/classmavsdk_1_1_param.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,14 @@ Value | Description
152152
<span id="classmavsdk_1_1_param_1afde69c8b60c41e2f21db148d211881dfa1119faf72ba0dfb23aeea644fed960ad"></span> `NoSystem` | No system connected.
153153
<span id="classmavsdk_1_1_param_1afde69c8b60c41e2f21db148d211881dfa1fc93bc695e2e3e1903029eb77228234"></span> `ParamValueTooLong` | [Param](classmavsdk_1_1_param.md) value too long (> 128).
154154
<span id="classmavsdk_1_1_param_1afde69c8b60c41e2f21db148d211881dfad7c8c85bf79bbe1b7188497c32c3b0ca"></span> `Failed` | Operation failed..
155+
<span id="classmavsdk_1_1_param_1afde69c8b60c41e2f21db148d211881dfac47c93cf49de211bba5d62d65225f128"></span> `DoesNotExist` | Parameter does not exist.
156+
<span id="classmavsdk_1_1_param_1afde69c8b60c41e2f21db148d211881dfaf3bd760221d37f5f1a973f094ea02478"></span> `ValueOutOfRange` | Parameter value does not fit within accepted range.
157+
<span id="classmavsdk_1_1_param_1afde69c8b60c41e2f21db148d211881dfa4b33a686be73bb172407d73b26356275"></span> `PermissionDenied` | Caller is not permitted to set the value of this parameter.
158+
<span id="classmavsdk_1_1_param_1afde69c8b60c41e2f21db148d211881dfab43f027b5acb9fb70fafef6a3de8e646"></span> `ComponentNotFound` | Unknown component specified.
159+
<span id="classmavsdk_1_1_param_1afde69c8b60c41e2f21db148d211881dfa131fb182a881796e7606ed6da27f1197"></span> `ReadOnly` | Parameter is read-only.
160+
<span id="classmavsdk_1_1_param_1afde69c8b60c41e2f21db148d211881dfa849c937b23fd724a14c4597eef61ce29"></span> `TypeUnsupported` | Parameter data type is not supported by flight stack.
161+
<span id="classmavsdk_1_1_param_1afde69c8b60c41e2f21db148d211881dfa2782c4707c245684aa95545098e1b70b"></span> `TypeMismatch` | Parameter type does not match expected type.
162+
<span id="classmavsdk_1_1_param_1afde69c8b60c41e2f21db148d211881dfa61d8b4448684ca1db22e9894cf995e0a"></span> `ReadFail` | Parameter exists but reading failed.
155163

156164
## Member Function Documentation
157165

proto

src/mavsdk/core/mavlink_parameter_client.cpp

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ MavlinkParameterClient::MavlinkParameterClient(
5656
MAVLINK_MSG_ID_PARAM_VALUE,
5757
[this](const mavlink_message_t& message) { process_param_value(message); },
5858
this);
59+
60+
// PARAM_ERROR is only for standard protocol (not extended)
61+
_message_handler.register_one(
62+
MAVLINK_MSG_ID_PARAM_ERROR,
63+
[this](const mavlink_message_t& message) { process_param_error(message); },
64+
this);
5965
}
6066
}
6167

@@ -1051,6 +1057,89 @@ void MavlinkParameterClient::process_param_ext_ack(const mavlink_message_t& mess
10511057
work->work_item_variant);
10521058
}
10531059

1060+
void MavlinkParameterClient::process_param_error(const mavlink_message_t& message)
1061+
{
1062+
mavlink_param_error_t param_error;
1063+
mavlink_msg_param_error_decode(&message, &param_error);
1064+
const auto safe_param_id = extract_safe_param_id(param_error.param_id);
1065+
1066+
if (_parameter_debugging) {
1067+
LogDebug() << "process param_error: " << safe_param_id
1068+
<< " error code: " << (int)param_error.error;
1069+
}
1070+
1071+
// See comments on process_param_value for use of unique_ptr
1072+
auto work_queue_guard = std::make_unique<LockedQueue<WorkItem>::Guard>(_work_queue);
1073+
auto work = work_queue_guard->get_front();
1074+
if (!work) {
1075+
return;
1076+
}
1077+
if (!work->already_requested) {
1078+
return;
1079+
}
1080+
1081+
// Map MAV_PARAM_ERROR to Result
1082+
auto map_param_error_to_result = [](uint8_t error_code) -> Result {
1083+
switch (error_code) {
1084+
case 1: // MAV_PARAM_ERROR_DOES_NOT_EXIST
1085+
return Result::DoesNotExist;
1086+
case 2: // MAV_PARAM_ERROR_VALUE_OUT_OF_RANGE
1087+
return Result::ValueOutOfRange;
1088+
case 3: // MAV_PARAM_ERROR_PERMISSION_DENIED
1089+
return Result::PermissionDenied;
1090+
case 4: // MAV_PARAM_ERROR_COMPONENT_NOT_FOUND
1091+
return Result::ComponentNotFound;
1092+
case 5: // MAV_PARAM_ERROR_READ_ONLY
1093+
return Result::ReadOnly;
1094+
case 6: // MAV_PARAM_ERROR_TYPE_UNSUPPORTED
1095+
return Result::TypeUnsupported;
1096+
case 7: // MAV_PARAM_ERROR_TYPE_MISMATCH
1097+
return Result::TypeMismatch;
1098+
case 8: // MAV_PARAM_ERROR_READ_FAIL
1099+
return Result::ReadFail;
1100+
default:
1101+
return Result::UnknownError;
1102+
}
1103+
};
1104+
1105+
std::visit(
1106+
overloaded{
1107+
[&](WorkItemSet& item) {
1108+
if (item.param_name != safe_param_id) {
1109+
// No match, let's just return the borrowed work item.
1110+
return;
1111+
}
1112+
_timeout_handler.remove(_timeout_cookie);
1113+
work_queue_guard->pop_front();
1114+
if (item.callback) {
1115+
auto callback = item.callback;
1116+
auto result = map_param_error_to_result(param_error.error);
1117+
work_queue_guard.reset();
1118+
callback(result);
1119+
}
1120+
},
1121+
[&](WorkItemGet& item) {
1122+
if (!validate_id_or_index(
1123+
item.param_identifier,
1124+
safe_param_id,
1125+
static_cast<int16_t>(param_error.param_index))) {
1126+
LogWarn() << "Got unexpected PARAM_ERROR on work item";
1127+
// No match, let's just return the borrowed work item.
1128+
return;
1129+
}
1130+
_timeout_handler.remove(_timeout_cookie);
1131+
work_queue_guard->pop_front();
1132+
if (item.callback) {
1133+
auto callback = item.callback;
1134+
auto result = map_param_error_to_result(param_error.error);
1135+
work_queue_guard.reset();
1136+
callback(result, ParamValue{});
1137+
}
1138+
},
1139+
[&](WorkItemGetAll&) { LogWarn() << "Unexpected PARAM_ERROR response for GetAll."; }},
1140+
work->work_item_variant);
1141+
}
1142+
10541143
void MavlinkParameterClient::receive_timeout()
10551144
{
10561145
// See comments on process_param_value for use of unique_ptr

src/mavsdk/core/mavlink_parameter_client.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ class MavlinkParameterClient : public MavlinkParameterSubscription {
5858
StringTypeUnsupported,
5959
InconsistentData,
6060
UnknownError,
61+
DoesNotExist,
62+
ValueOutOfRange,
63+
PermissionDenied,
64+
ComponentNotFound,
65+
ReadOnly,
66+
TypeUnsupported,
67+
TypeMismatch,
68+
ReadFail,
6169
};
6270

6371
Result set_param(const std::string& name, const ParamValue& value);
@@ -187,6 +195,7 @@ class MavlinkParameterClient : public MavlinkParameterSubscription {
187195
void process_param_value(const mavlink_message_t& message);
188196
void process_param_ext_value(const mavlink_message_t& message);
189197
void process_param_ext_ack(const mavlink_message_t& message);
198+
void process_param_error(const mavlink_message_t& message);
190199
void receive_timeout();
191200

192201
bool send_set_param_message(WorkItemSet& work_item);

0 commit comments

Comments
 (0)