Skip to content

airbound-develop: add 4575 rc8 fixes - #128

Open
akshar-airbound wants to merge 15 commits into
airbound-developfrom
pr-airbound-4575-rc8-fixes
Open

airbound-develop: add 4575 rc8 fixes#128
akshar-airbound wants to merge 15 commits into
airbound-developfrom
pr-airbound-4575-rc8-fixes

Conversation

@akshar-airbound

Copy link
Copy Markdown
Collaborator

No description provided.

vigneshm-debug and others added 15 commits June 16, 2026 12:39
- AP_Scripting: expose rate PID info to Lua via get_rate_pid_info(axis)
- Adds lua_get_rate_pid_info() binding returning a table of PID fields
(P, I, D, FF, target, actual, error) for roll (0), pitch (1), or yaw (2)
rate controllers. Used to compute control effort (|P + D + FF|) from Lua.
- Add get_attitude_control() public accessor to QuadPlane
- Add despitch, roll and yaw
…ed pitch (#111)

* Remove controller desaturation in control effort
* Add desaturation logic for Desired servo tilt
* Add logging for VH Power
* Add hard limit for pitch angle setpoint
* Add new parameters in default.param
* Add logging for the position controller demanded pitch
---------

Co-authored-by: Manuraj P M <[email protected]>
* introduced parameter LND_DET_TIM that controls how many milliseconds before disarm is detected
* add disarm watchdog and disable weathervane after touchdown
* Weathervane disable logic changed
* expose land detection timing as params Q_LND_RELAX_MS and Q_LND_LLIM_MS
---------

Co-authored-by: Stefard100 <[email protected]>
* Fix feedforward_scalar calculation when thrust angle error exceeds limits in AC_AttitudeControl.cpp
* add resume after autobailout
@greptile-apps

greptile-apps Bot commented Jul 13, 2026

Copy link
Copy Markdown

Greptile Summary

This PR bundles several rc8 fixes for the Airbound tailsitter platform: a feedforward-scalar formula correction in the attitude controller, a new configurable VTOL pitch clip (PIT_CLIP_MAX), refactored door-control and autobailout Lua scripts, new Lua scripting bindings for VTOL attitude/PID data, and updated PID defaults for the Pixhawk6C-bdshot target.

  • AC_AttitudeControl: Fixes the feedforward scalar formula in the 2T–3T thrust-error band (old formula produced 0 at entry and went negative, new formula correctly interpolates 1→0); adds PIT_CLIP_MAX to clamp pitch setpoint during non-transition VTOL flight.
  • AP_MotorsTailsitter: Removes the yaw headroom limiting block — pitch_thrust is no longer constrained and limit.yaw is never set, which breaks yaw PID anti-windup when tilt motors saturate.
  • Lua scripts: autobailout.lua gains rolling-window pitch monitoring, rate-prediction bailout, and auto-recovery to pre-bailout mode; ab_door_auto_control.lua replaces landing-latch logic with forward-transition-completion detection; four new Lua bindings expose VTOL attitude and PID state to scripts.

Confidence Score: 3/5

The attitude controller feedforward fix and pitch-clip additions look correct, but the removal of yaw headroom limiting in AP_MotorsTailsitter leaves the yaw PID without anti-windup protection when tilt motors saturate — this is an active flight-control regression.

The AP_MotorsTailsitter change silently drops limit.yaw signalling and removes the pitch_thrust constraint that guards tilt output range. In saturation scenarios the yaw integrator will wind up unchecked, producing sudden yaw kicks when motors come out of saturation. The rest of the PR — the feedforward scalar fix, PIT_CLIP_MAX, new Lua bindings, and the Lua script refactors — all look directionally correct, with the Lua issues being style and robustness notes rather than breaking defects.

libraries/AP_Motors/AP_MotorsTailsitter.cpp needs the yaw headroom limiting and limit.yaw signalling restored; libraries/AP_HAL_ChibiOS/hwdef/Pixhawk6C-bdshot/scripts/autobailout.lua has several minor cleanup items; libraries/AP_Scripting/docs/docs.lua needs @return annotations corrected to reflect table returns.

Important Files Changed

Filename Overview
libraries/AP_Motors/AP_MotorsTailsitter.cpp Removed yaw headroom limiting and limit.yaw flag — yaw PID anti-windup is now broken and pitch_thrust is no longer constrained before computing tilt outputs
libraries/AC_AttitudeControl/AC_AttitudeControl.cpp Fixes feedforward scalar formula (was producing 0 to negative in the 2T-3T error range) and adds configurable pitch clamping for VTOL modes when tailsitter is enabled
libraries/AP_HAL_ChibiOS/hwdef/Pixhawk6C-bdshot/scripts/autobailout.lua Major refactor adding rolling-window pitch monitoring, rate-based prediction, auto-recovery to pre-bailout mode — but leaks is_vtol_flight as a global and has residual implicit globals in para_deploy()
libraries/AP_HAL_ChibiOS/hwdef/Pixhawk6C-bdshot/scripts/ab_door_auto_control.lua Replaces landing-latch door logic with forward-transition-completion-based logic; backtransition_complete_time_ms is tracked but never consumed by the door control logic
libraries/AP_Scripting/lua_bindings.cpp Adds four new Lua bindings exposing VTOL attitude target, actual Euler angles, and PID info via table returns with null-checks in place
libraries/AP_Scripting/docs/docs.lua Documents new Lua bindings with @return annotations describing multiple number returns, but actual C implementations return single tables

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[attitude_controller_run_quat] --> B{ts_enabled and not in_transition?}
    B -- yes --> C[clamp pitch to PIT_CLIP_MAX]
    B -- no --> D[skip clamp]
    C --> E[thrust_heading_rotation_angles]
    D --> E
    E --> F{thrust_error_angle}
    F -- gt 3T --> G[use gyro.z, reset yaw I]
    F -- gt 2T --> H[feedforward_scalar 1 to 0]
    F -- else --> I[full feedforward]
    H --> J[ang_vel_body update]
    I --> J
    G --> J
    J --> K[AP_MotorsTailsitter]
    K --> L[tilt = pitch minus or plus yaw]
    L --> M[Tilt servo commands]
    subgraph Lua
        N[autobailout update] --> O{autobailout_active?}
        O -- no --> P[check pitch limits]
        P -- triggered --> Q[switch to QLoiter]
        O -- yes --> R{mode QLOITER?}
        R -- no --> S[Manual Override]
        R -- yes --> T{window stable?}
        T -- yes --> U[recover to pre_bailout_mode]
        T -- no --> V[keep monitoring]
    end
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[attitude_controller_run_quat] --> B{ts_enabled and not in_transition?}
    B -- yes --> C[clamp pitch to PIT_CLIP_MAX]
    B -- no --> D[skip clamp]
    C --> E[thrust_heading_rotation_angles]
    D --> E
    E --> F{thrust_error_angle}
    F -- gt 3T --> G[use gyro.z, reset yaw I]
    F -- gt 2T --> H[feedforward_scalar 1 to 0]
    F -- else --> I[full feedforward]
    H --> J[ang_vel_body update]
    I --> J
    G --> J
    J --> K[AP_MotorsTailsitter]
    K --> L[tilt = pitch minus or plus yaw]
    L --> M[Tilt servo commands]
    subgraph Lua
        N[autobailout update] --> O{autobailout_active?}
        O -- no --> P[check pitch limits]
        P -- triggered --> Q[switch to QLoiter]
        O -- yes --> R{mode QLOITER?}
        R -- no --> S[Manual Override]
        R -- yes --> T{window stable?}
        T -- yes --> U[recover to pre_bailout_mode]
        T -- no --> V[keep monitoring]
    end
Loading

Comments Outside Diff (3)

  1. libraries/AP_HAL_ChibiOS/hwdef/Pixhawk6C-bdshot/scripts/autobailout.lua, line 101-111 (link)

    P2 Backtransition delay timer starts in excluded modes

    in_vtol_flight() no longer filters out AUTOBAILOUT_EXCLUDE_MODES (that check was moved into is_vtol_pitch_exceeding_limit()), so backtransition_complete_time_ms is now set whenever the vehicle is in any non-transitioning VTOL mode, including QACRO. If the vehicle is in QACRO when a backtransition completes, the BTRN_DLY settle window starts counting immediately. Switching to a monitored mode shortly after means the delay is partially or fully elapsed and pitch monitoring activates sooner than intended.

  2. libraries/AP_HAL_ChibiOS/hwdef/Pixhawk6C-bdshot/scripts/ab_door_auto_control.lua, line 181-191 (link)

    P2 backtransition_complete_time_ms is set but never consumed in door logic

    The in_vtol_flight() function faithfully tracks backtransition_complete_time_ms, but nothing in the door-control script ever reads this value to enforce a settle delay before opening doors. The variable is effectively dead in this context. If a post-backtransition delay is not needed for door control, the tracking code can be removed to simplify the function; if it is needed, the delay check is currently missing.

  3. libraries/AP_HAL_ChibiOS/hwdef/Pixhawk6C-bdshot/scripts/autobailout.lua, line 159-166 (link)

    P2 Residual implicit globals in para_deploy()

    While para_threshold and now were correctly localized in this PR, several other variables in para_deploy() remain implicit globals: ahrs_pitch (line 159), para_ang_timeout (line 160), check_pitch (line 161), and para_time_diff (line 166). These will persist in the global table between calls and pollute the script namespace.

Reviews (1): Last reviewed commit: "Change version name to V4.5.7.5 - rc8-fi..." | Re-trigger Greptile

Comment on lines 212 to +214
// thrust vectoring
pitch_thrust = constrain_float(pitch_thrust, -1.0f, 1.0f);
float yaw_headroom = 1.0f - fabsf(pitch_thrust);
float yaw_thrust_limited = constrain_float(yaw_thrust, -yaw_headroom, yaw_headroom);
if (fabsf(yaw_thrust_limited) < fabsf(yaw_thrust)) {
limit.yaw = true;
}
_tilt_left = pitch_thrust - yaw_thrust_limited;
_tilt_right = pitch_thrust + yaw_thrust_limited;
_tilt_left = pitch_thrust - yaw_thrust;
_tilt_right = pitch_thrust + yaw_thrust;

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 Yaw anti-windup and saturation limiting removed

The old code constrained pitch_thrust to [-1, 1], computed yaw headroom as the remaining budget, clamped yaw_thrust to that headroom, and set limit.yaw = true when clamping occurred. All three of those guard rails are now gone.

The limit.yaw flag is read by AP_AttitudeControl to prevent integrator windup: when it stays false, the yaw-rate PID integrator keeps accumulating even though the tilt motors are physically saturated. Once the motors come out of saturation the accumulated I-term causes a sudden yaw kick. Additionally, pitch_thrust is assigned from _pitch_in + _pitch_in_ff without any range constraint, so _tilt_left/_tilt_right can now exceed [-1, 1] when feedforward is active, sending out-of-range commands to the tilt servos.

logger:write('AUTB', 'AvgErr,PeakAng,PitchDeg,QPit,QRateP', 'fffff', avg_err, peak_ang, pitch_deg, actual_vtol_pitch_deg, actual_vtol_pitch_rate)
end

is_vtol_flight = in_vtol_flight()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 is_vtol_flight assigned to global scope

is_vtol_flight = in_vtol_flight() is missing the local keyword, making it an implicit global. ArduPilot Lua scripts share the global environment, so this leaks state between iterations and could interact with other scripts that happen to use the same name. Consistent with the many other local fixes elsewhere in this PR, this line should also be declared local.

Comment on lines 1694 to +1720
function quadplane:tailsitter_in_vtol_transition() end

-- desc
---@return number -- roll_cd
---@return number -- pitch_cd
---@return number -- yaw_cd
function qp_att_desired() end

-- desc
---@return number -- roll_cd
---@return number -- pitch_cd
---@return number -- yaw_cd
function qp_att_actual() end

-- desc
---@return number -- roll_dps
---@return number -- pitch_dps
---@return number -- yaw_dps
function qp_angle_rate() end


--desc
---@param axis integer
---| '0' # Roll axis
---| '1' # Pitch axis
---| '2' # Yaw axis
---@return number -- P

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 @return annotations describe multiple return values but bindings return a table

qp_att_desired, qp_att_actual, qp_angle_rate, and qp_rate_pid_info are all annotated as returning multiple number values (e.g., ---@return number -- roll_cd), but the C implementations in lua_bindings.cpp all call lua_newtable and return a single table with named fields. Any script that follows the annotations and unpacks with local r, p, y = qp_att_desired() will receive the table in r and nil in p and y. The autobailout script already uses the correct table-access style (desired.pitch_cd), so the annotations should be updated to reflect the actual return type.

@akshar-airbound akshar-airbound changed the title Pr airbound 4575 rc8 fixes airbound-develop: add 4575 rc8 fixes Jul 13, 2026
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.

3 participants