modes: make available modes user selectable with a registration option

Some modes should only be run within the context of a mode executor and the user should not be able
to select them in the GCS. With this change, the external component registration request can be
used to set if a mode is selectable or not.
This commit is contained in:
Michael Schaeuble
2025-11-24 10:13:53 +01:00
committed by Beat Küng
parent 276cab8d3c
commit a2299b02c8
9 changed files with 155 additions and 3 deletions
+1
View File
@@ -232,6 +232,7 @@ void ModeManagement::checkNewRegistrations(UpdateRequest &update_request)
static_assert(sizeof(request.name) == sizeof(reply.name), "size mismatch");
memcpy(reply.name, request.name, sizeof(request.name));
reply.request_id = request.request_id;
reply.not_user_selectable = request.not_user_selectable;
reply.px4_ros2_api_version = register_ext_component_request_s::LATEST_PX4_ROS2_API_VERSION;
// validate
@@ -38,6 +38,7 @@
#include <uORB/topics/register_ext_component_reply.h>
#include <lib/modes/standard_modes.hpp>
#include <lib/modes/ui.hpp>
#include <limits.h>
class MavlinkStreamAvailableModes : public MavlinkStream
{
@@ -71,6 +72,8 @@ private:
char name[sizeof(register_ext_component_reply_s::name)] {};
};
ExternalModeName *_external_mode_names{nullptr};
uint8_t _not_user_selectable_mask{0};
static_assert(MAX_NUM_EXTERNAL_MODES <= (sizeof(_not_user_selectable_mask) * CHAR_BIT), "Mask too small");
uORB::Subscription _vehicle_status_sub{ORB_ID(vehicle_status)};
uORB::Subscription _register_ext_component_reply_sub{ORB_ID(register_ext_component_reply)};
@@ -116,6 +119,10 @@ private:
} else if (_external_mode_names) {
strncpy(available_modes.mode_name, _external_mode_names[external_mode_index].name, sizeof(available_modes.mode_name));
available_modes.mode_name[sizeof(available_modes.mode_name) - 1] = '\0';
if ((_not_user_selectable_mask & (1 << external_mode_index)) > 0) {
available_modes.properties |= MAV_MODE_PROPERTY_NOT_USER_SELECTABLE;
}
}
} else { // Internal
@@ -205,6 +212,13 @@ private:
if (_external_mode_names && mode_index < MAX_NUM_EXTERNAL_MODES) {
memcpy(_external_mode_names[mode_index].name, reply.name, sizeof(ExternalModeName::name));
if (reply.not_user_selectable) {
_not_user_selectable_mask |= (1 << mode_index);
} else {
_not_user_selectable_mask &= ~(1 << mode_index);
}
}
dynamic_update = true;