Autopilot Status Flags: AUTOPILOT_STOP[6] duplicates [7], the 100 failure sentinel collides with a real statusValue, and the decimal code cannot be annotated as flags
Summary
Four things about the autopilot "Status Flags" slots, found while regenerating the configurator's debug tables from the annotations (betaflight/betaflight-configurator#5520). All on master f5fb2717b8, all in flight/autopilot_multirotor.c unless noted.
They are grouped here because they share one root cause: statusValue is a hand-rolled decimal-additive code, not a bit field, and the failure paths overwrite it with sentinel numbers drawn from the same number line.
1. DEBUG_AUTOPILOT_STOP[6] and [7] are the same value
DEBUG_SET(DEBUG_AUTOPILOT_STOP, 6, statusValue + (ap.isPosHoldBraking ? 1 : 0)); //!< Status Flags
DEBUG_SET(DEBUG_AUTOPILOT_STOP, 7, statusValue + (ap.isPosHoldBraking ? 1 : 0)); //!< Status FlagsByte-identical expressions, identical label. The duplication repeats on both failure paths — L565-L566 (both 100) and L1010-L1011 (both 200) — so it is systematic rather than a one-line slip.
One of the mode's eight slots is spent on a copy. It reads like [7] was meant to hold something else and never got it.
2. DEBUG_AUTOPILOT_PID[7] mirrors those two, except on one path
DEBUG_AUTOPILOT_PID[7] is written with the same expression and the same sentinels (100 at L564, 200 at L1009, the normal value at L1194) — but the sensors-not-OK path in pos_hold_multirotor.c#L152 writes 333 to DEBUG_AUTOPILOT_PID[7] only:
// 333 traps the sensors-not-OK path
DEBUG_SET(DEBUG_AUTOPILOT_PID, 7, 333); //!< Status FlagsSo the three slots agree everywhere except there, where AUTOPILOT_STOP[6]/[7] keep whatever they held last. Anyone reading an AUTOPILOT_STOP log has no way to see the sensor dropout that an AUTOPILOT_PID log shows plainly, which rather defeats the point of duplicating the field into that mode.
3. The 100 sentinel collides with a legitimate statusValue
int statusValue = 0;
if (ap.navActive) statusValue += 10;
if (anchorOff) statusValue += 20;
if (abortNavRequested) statusValue += 100;
if (isPositionHeld) statusValue += 3; // plus 1, ie 4, if stopping
if (ap.sticksActive) statusValue += 5;abortNavRequested alone gives exactly 100 — the same number handlepositionControlFailure() writes as its sentinel. The two states are indistinguishable in a log.
200 and 333 are safely outside the 0..139 range the expression can produce, so only 100 is affected.
4. The code cannot be annotated, so the configurator shows a bare number
//!< Status Flags carries a label but no shape, because none fits: the value is neither a bit field (so [flags:...] is out) nor a small dense enumeration (so [enum:...] is out). It is decodable by hand — each contribution lands in its own decimal digit — but the configurator and blackbox viewer can only render, say, 133 and leave the user to work out navActive + anchorOff + isPositionHeld + braking.
The same applies to DEBUG_POSITION_NAV[7], (anchorOff ? 10 : 0) + (buildupClamped ? 1 : 0) at L1212 — two booleans that would be a two-bit field in any other debug mode.
Suggested fix
Make statusValue an actual bit field:
uint16_t statusFlags = 0;
if (ap.navActive) statusFlags |= AP_STATUS_NAV_ACTIVE;
if (anchorOff) statusFlags |= AP_STATUS_ANCHOR_OFF;
if (abortNavRequested) statusFlags |= AP_STATUS_ABORT_NAV;
if (isPositionHeld) statusFlags |= AP_STATUS_POSITION_HELD;
if (ap.sticksActive) statusFlags |= AP_STATUS_STICKS_ACTIVE;
if (ap.isPosHoldBraking) statusFlags |= AP_STATUS_BRAKING;That makes the annotation express it directly —
DEBUG_SET(DEBUG_AUTOPILOT_PID, 7, statusFlags); //!< Status Flags [flags:Nav Active|Anchor Off|Abort Nav|Position Held|Sticks Active|Braking]— and the configurator will decode each bit by name instead of printing a total. DEBUG_POSITION_NAV[7] wants the same treatment with [flags:Anchor Off|Buildup Clamped].
The failure states then need bits of their own (AP_STATUS_CONTROL_FAILURE, AP_STATUS_FORCE_PITCH_FORWARD, AP_STATUS_SENSORS_NOT_OK) rather than sentinel totals, which removes the 100 collision and lets a failure frame keep showing the rest of the state instead of erasing it.
And DEBUG_AUTOPILOT_STOP[7] should either get a distinct quantity or be dropped, rather than duplicating [6].
Related: #15598 (boolean/enum metadata for debug fields), #15691, #15594, #15610.
Source: betaflight/betaflight