autobailout: Add rate based vtol pitch prediction - #115
Conversation
Greptile SummaryThis 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.
Confidence Score: 4/5Mergeable 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
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
%%{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
Reviews (4): Last reviewed commit: "Fixed gcs print" | Re-trigger Greptile |
c05a999 to
0010880
Compare
| if (!motors->armed()) { | ||
| poscontrol.set_state(QPOS_LAND_COMPLETE); | ||
| return true; | ||
| return false; | ||
| } |
There was a problem hiding this comment.
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.
|
Want your agent to iterate on Greptile's feedback? Try greploops. |
… (40 in AHRS angle FW Frame) Enabled Autobailout logging by default
Fix backtransition time population bug
7109901 to
2303a16
Compare
https://app.notion.com/p/airbound/Add-pitch-angle-prediction-in-autobailout-script-38121adf4be9802781d9fe294e987660
https://app.notion.com/p/airbound/Find-AUTOB_BTRN_DLY-and-AUTOB_PRED_INT-based-on-log-analysis-38a21adf4be9800599f8d3c818b59510