Skip to content

autobailout: Add rate based vtol pitch prediction - #115

Draft
akshar-airbound wants to merge 15 commits into
pr-airbound-4575-rc6-fixesfrom
pr-autobailout-rate-based-angle-prediction
Draft

autobailout: Add rate based vtol pitch prediction#115
akshar-airbound wants to merge 15 commits into
pr-airbound-4575-rc6-fixesfrom
pr-autobailout-rate-based-angle-prediction

Conversation

@akshar-airbound

@akshar-airbound akshar-airbound commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

@akshar-airbound
akshar-airbound marked this pull request as draft June 17, 2026 12:48
@akshar-airbound akshar-airbound self-assigned this Jun 17, 2026
@greptile-apps

greptile-apps Bot commented Jun 17, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds rate-based VTOL pitch prediction to the autobailout Lua script — using the pitch PID's actual rate to project pitch 500 ms ahead and trigger autobailout early if the predicted angle would cross the parachute threshold. It also refactors the pitch-monitoring logic into named helper functions, removes two tunable landing-detect debounce parameters (hardcoding them to 1 s), and bumps the firmware version to rc4-fixes.

  • New prediction check (is_predicted_vtol_pitch_exceeding_parathreshold) fires autobailout on a single evaluation with no sustained-exceedance guard, unlike the existing is_vtol_pitch_exceeding_limit which requires exceedance for PIT_TOUT ms; a transient spike in the PID rate reading could cause an unintended mode switch.
  • AUTOB_DBG_EN default changed from 0 to 1, enabling continuous dataflash logging at ~20 Hz on all production aircraft by default.
  • is_vtol_flight is assigned without local on line 325 of the script, creating an implicit module-level global inconsistent with surrounding code style.

Confidence Score: 4/5

Mergeable with care — the C++ changes are mechanical cleanups, but the Lua autobailout script has a no-debounce prediction path that could trigger an unintended QLoiter switch on a single noisy PID rate sample, and debug logging is now always on in production builds.

The C++ side (hardcoding landing debounce to 1 s, removing the two AP_Param fields) is straightforward and low-risk. The Lua changes introduce a new prediction trigger that can fire on a single loop iteration with no duration guard, unlike every other pitch-monitoring check in the script that has a debounce timeout. While the threshold (~105° VTOL) is high enough to avoid most sensor noise, it introduces asymmetric safety logic worth validating in flight. The DBG_EN default-to-1 change will also fill dataflash faster on all deployed vehicles.

autobailout.lua — prediction trigger debounce logic and the DBG_EN default change; quadplane.cpp — check_land_complete disarmed-motor path (covered in a prior review thread).

Important Files Changed

Filename Overview
libraries/AP_HAL_ChibiOS/hwdef/Pixhawk6C-bdshot/scripts/autobailout.lua Core logic refactored into helper functions; adds rate-based VTOL pitch prediction for early autobailout; implicit global, missing debounce on prediction path, and DBG_EN default change need attention.
ArduPlane/quadplane.cpp Removes configurable relax/lower-limit debounce params (hardcodes 1000 ms); check_land_complete now returns false when motors disarmed, blocking QPOS_LAND_COMPLETE transition (flagged in prior review thread).
ArduPlane/quadplane.h Removes AP_Int16 fields for relax_debounce_ms and lower_limit_extra_ms to match the hardcoded constants in quadplane.cpp.
ArduPlane/version.h Version string bumped from rc3-fixes to rc4-fixes.
libraries/AP_HAL_ChibiOS/hwdef/Pixhawk6C-bdshot/defaults.parm Removes Q_LND_LLIM_MS and Q_LND_RELAX_MS default entries to align with their removal from quadplane.cpp.
libraries/AP_Scripting/docs/docs.lua Adds LuaLS annotations for qp_att_desired, qp_att_actual, qp_angle_rate, and qp_rate_pid_info; return-type annotations use multiple number returns but actual bindings return userdata tables with named fields.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[update loop] --> B[para_deploy]
    B -->|trigger_para_script| C[return early]
    B -->|no trigger| D{autobailout enabled?}
    D -->|no| C
    D -->|yes| E[get current_mode / actual_vtol_pitch_deg / actual_vtol_pitch_rate]
    E --> F[is_vtol_flight = in_vtol_flight]
    F --> G{autobailout_active?}
    G -->|no| H{is_vtol_pitch_exceeding_limit? pitch_timeout debounce}
    H -->|yes| I[trigger_autobailout set QLOITER]
    H -->|no| J{is_predicted_vtol_pitch_exceeding_parathreshold? NO debounce}
    J -->|yes| I
    J -->|no| K[continue monitoring]
    G -->|yes RECOVERY| L{current_mode == QLOITER?}
    L -->|no| M[manual override autobailout_active = false]
    L -->|yes| N{enough samples avg_err + peak_ang OK?}
    N -->|yes| O[restore pre_bailout_mode autobailout_active = false]
    N -->|no| P[keep collecting samples]
    style J fill:#ffddaa,stroke:#ff8800
    style I fill:#ffaaaa,stroke:#ff0000
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[update loop] --> B[para_deploy]
    B -->|trigger_para_script| C[return early]
    B -->|no trigger| D{autobailout enabled?}
    D -->|no| C
    D -->|yes| E[get current_mode / actual_vtol_pitch_deg / actual_vtol_pitch_rate]
    E --> F[is_vtol_flight = in_vtol_flight]
    F --> G{autobailout_active?}
    G -->|no| H{is_vtol_pitch_exceeding_limit? pitch_timeout debounce}
    H -->|yes| I[trigger_autobailout set QLOITER]
    H -->|no| J{is_predicted_vtol_pitch_exceeding_parathreshold? NO debounce}
    J -->|yes| I
    J -->|no| K[continue monitoring]
    G -->|yes RECOVERY| L{current_mode == QLOITER?}
    L -->|no| M[manual override autobailout_active = false]
    L -->|yes| N{enough samples avg_err + peak_ang OK?}
    N -->|yes| O[restore pre_bailout_mode autobailout_active = false]
    N -->|no| P[keep collecting samples]
    style J fill:#ffddaa,stroke:#ff8800
    style I fill:#ffaaaa,stroke:#ff0000
Loading

Reviews (4): Last reviewed commit: "Fixed gcs print" | Re-trigger Greptile

Comment thread libraries/AP_HAL_ChibiOS/hwdef/Pixhawk6C-bdshot/scripts/autobailout.lua Outdated
Comment thread libraries/AP_HAL_ChibiOS/hwdef/Pixhawk6C-bdshot/scripts/autobailout.lua Outdated
Comment thread libraries/AP_HAL_ChibiOS/hwdef/Pixhawk6C-bdshot/scripts/autobailout.lua Outdated
@akshar-airbound akshar-airbound changed the title Add rate based vtol pitch prediction autobailout: Add rate based vtol pitch prediction Jun 18, 2026
@akshar-airbound
akshar-airbound marked this pull request as ready for review June 18, 2026 10:43
@akshar-airbound
akshar-airbound force-pushed the pr-autobailout-rate-based-angle-prediction branch from c05a999 to 0010880 Compare June 23, 2026 12:50
Comment thread libraries/AP_HAL_ChibiOS/hwdef/Pixhawk6C-bdshot/scripts/autobailout.lua Outdated
Comment thread ArduPlane/quadplane.cpp
Comment on lines 3631 to 3633
if (!motors->armed()) {
poscontrol.set_state(QPOS_LAND_COMPLETE);
return true;
return false;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Disarmed-motor check now blocks land-complete detection permanently

Previously, if motors disarmed during QPOS_LAND_FINAL (e.g. via the disarm watchdog or a manual kill), the function immediately declared land complete and advanced the state machine. The new code instead returns false, which means execution never reaches the land_detector() call that sets QPOS_LAND_COMPLETE. Because this early return fires on every subsequent call while motors remain disarmed, the state machine is permanently stuck in QPOS_LAND_FINAL — there is no other code path that sets QPOS_LAND_COMPLETE under these conditions. If the intent is to let land_detector() run its normal logic even after disarming, the return false needs to be removed so control falls through to the land_detector() check below.

@akshar-airbound
akshar-airbound marked this pull request as draft June 24, 2026 11:12
@akshar-airbound
akshar-airbound changed the base branch from pr-airbound-4575-rc3-fixes to pr-airbound-4575-rc4-fixes June 24, 2026 11:14
@greptile-apps

greptile-apps Bot commented Jun 24, 2026

Copy link
Copy Markdown

Want your agent to iterate on Greptile's feedback? Try greploops.

@akshar-airbound
akshar-airbound changed the base branch from pr-airbound-4575-rc4-fixes to pr-airbound-4575-rc5-fixes June 26, 2026 08:38
@akshar-airbound
akshar-airbound changed the base branch from pr-airbound-4575-rc5-fixes to pr-airbound-4575-rc6-fixes July 1, 2026 09:45
@akshar-airbound
akshar-airbound force-pushed the pr-autobailout-rate-based-angle-prediction branch from 7109901 to 2303a16 Compare July 1, 2026 09:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant