fix(mavlink): support external gimbal manager on gimbal mode link

A gimbal with its own gimbal manager is typically connected to a MAVLink
instance in gimbal mode. That mode only handles a whitelist of incoming
messages and only streams a few messages, so the external gimbal manager
was never discovered there and would not have received any setpoints.

Accept GIMBAL_MANAGER_STATUS as well as COMMAND_ACK (for the
DO_GIMBAL_MANAGER_CONFIGURE that we send, otherwise it is retried until
it times out) and stream GIMBAL_MANAGER_SET_PITCHYAW in gimbal mode.

This also makes the check to not ingest the gimbal device information of
an external gimbal manager work on such a link, as that depends on
having seen its GIMBAL_MANAGER_STATUS.

While at it, ignore the status of gimbal managers of other systems, e.g.
forwarded from another vehicle. Only a manager on our vehicle is ours to
talk to.

Assisted-by: Claude:claude-fable-5-1
Signed-off-by: Julian Oes <julian@oes.ch>
This commit is contained in:
Julian Oes
2026-09-22 15:15:30 +12:00
parent fad6590345
commit 9ff48836eb
2 changed files with 15 additions and 1 deletions
+1
View File
@@ -1783,6 +1783,7 @@ constexpr StreamRateDefault streams_mode_gimbal[] = {
// Note: streams requiring low latency come first
{"AUTOPILOT_STATE_FOR_GIMBAL_DEVICE", 20.0f},
{"GIMBAL_DEVICE_SET_ATTITUDE", 20.0f},
{"GIMBAL_MANAGER_SET_PITCHYAW", 20.0f},
};
constexpr StreamRateDefault streams_mode_extvision[] = {
+14 -1
View File
@@ -489,6 +489,17 @@ void MavlinkReceiver::handle_messages_in_gimbal_mode(mavlink_message_t &msg)
handle_message_gimbal_device_attitude_status(&msg);
break;
case MAVLINK_MSG_ID_GIMBAL_MANAGER_STATUS:
// The component on this link might be an external gimbal manager.
handle_message_gimbal_manager_status(&msg);
break;
case MAVLINK_MSG_ID_COMMAND_ACK:
// Needed for the commands we send (e.g. DO_GIMBAL_MANAGER_CONFIGURE),
// otherwise they are retried until they time out.
handle_message_command_ack(&msg);
break;
case MAVLINK_MSG_ID_COMMAND_LONG: {
mavlink_command_long_t cmd;
mavlink_msg_command_long_decode(&msg, &cmd);
@@ -3711,7 +3722,9 @@ MavlinkReceiver::handle_message_gimbal_manager_status(mavlink_message_t *msg)
{
// Ignore our own gimbal manager: PX4 streams this itself from the autopilot
// component, and we only care about external gimbal managers here.
if (msg->sysid == mavlink_system.sysid && msg->compid == mavlink_system.compid) {
// Also ignore gimbal managers of other systems (e.g. forwarded from another
// vehicle), only a manager on our vehicle is ours to talk to.
if (msg->sysid != mavlink_system.sysid || msg->compid == mavlink_system.compid) {
return;
}