Skip to content

Improve VTOL RTH approach timing and post-transition capture - #11871

Open
mart1npetroff wants to merge 3 commits into
iNavFlight:next-10.1from
mart1npetroff:fix-vtol-rth-fw-to-mc-approach
Open

mart1npetroff wants to merge 3 commits into
iNavFlight:next-10.1from
mart1npetroff:fix-vtol-rth-fw-to-mc-approach

Conversation

@mart1npetroff

Copy link
Copy Markdown
Contributor

Problem

During RTH, a fixed-wing VTOL can pass Home or SafeHome before FW-to-MC finishes. Returning toward the landing point immediately after the switch can require backward or sideways flight while the aircraft still carries forward speed, placing additional demands on yaw and attitude control.

This follows the VTOL auto-transition implementation in #11553.

Changes

  • Start an eligible RTH landing transition on the direct Home/SafeHome approach using trusted ground velocity projected toward the destination.
  • Estimate the start distance from closing speed multiplied by the source FW profile's mixer_switch_trans_timer (100 ms units), plus mixer_vtol_transition_scale_ramp_time_ms when dynamic mixing is enabled. Use nav_fw_loiter_radius as the minimum/fallback staging distance.
  • Require 300 ms of continuous start eligibility. Clear confirmation on navigation state changes, unusable position, and geozone route interruptions.
  • After successful navigation-owned FW-to-MC on the RTH approach, brake without pulling back toward the switch point, settle, face Home, then resume the approach. Near Home, use the configured landing heading.
  • Return to braking if horizontal motion or attitude becomes excessive during alignment. Recalculate the heading from the actual position and preserve RTH position timeout and flyaway checks.
  • Expose braking/alignment as a hold to the existing VTOL altitude protection while retaining RTH ownership of the position target. Clear capture when leaving its navigation state.
  • Document operation, timing examples, failsafe behavior, and limitations in docs/VTOL.md.

No new CLI settings or parameter-group changes are introduced. Early initiation requires an armed aircraft, RTH landing permission, source-profile mixer_automated_switch, and a supported MC target. Mission waypoint and manual transition initiation are unchanged. Existing airspeed confirmation, timer fallback, failure actions, and tailsitter restrictions continue to decide whether/how the transition completes. Failsafe landing delay still applies at Home.

For example, a 5 s switch timer plus a 1.2 s dynamic output ramp gives a 6.2 s planning budget. At 20 m/s closing speed, the calculated boundary is 124 m, provided the configured loiter radius is smaller.

Validation

On commit a36da3ebf, based on 2e8857e10:

  • 171/171 selected mixer-transition, navigation VTOL mission, and VTOL MC protection unit tests passed.
  • New tests cover closing-speed geometry, receding/cross-track movement, invalid estimates, timer/ramp budgets, staging fallback, arithmetic limits, short speed spikes, and millisecond rollover.
  • Release builds passed for MAMBAH743_2022B, MATEKF405MINI, and the 512 KB OMNIBUSF7NXT target.
  • git diff --check passed.
cmake --build build/unit-tests -j4
ctest --test-dir build/unit-tests/src/test -R 'MixerTransition|NavigationVtolMission|VtolMcProtection' --output-on-failure
cmake --build build-release --target MAMBAH743_2022B -j4
cmake --build build-release --target MATEKF405MINI OMNIBUSF7NXT -j4

Limits and Flight Validation

The start-distance calculation is a planning heuristic, not an airframe braking model. In airspeed-controlled operation, the fallback timer is not a measurement of actual transition duration. Gusts, aerodynamic response, and the subsequent MC stopping/alignment time can still produce overshoot.

During capture, altitude targeting follows current altitude with a zero climb/descent request rather than chasing the pre-transition altitude; ordinary RTH altitude management resumes afterward. Capture does not force completion by timeout when settle/heading conditions remain unsatisfied.

The new behavior has not yet been validated in an end-to-end SITL mission or real flight. The unit tests and builds above do not establish aerodynamic stability or guarantee stopping before Home.

Start landing transitions using closing speed and existing mixer timers, with a loiter-radius fallback and continuous confirmation. Brake and align after FW-to-MC before returning to Home, preserving VTOL altitude protection and RTH safety checks. Document limits and add focused regression tests.
@qodo-code-review

Copy link
Copy Markdown
Contributor

ⓘ Qodo reviews are paused because the subscription is no longer active. Ask your workspace admin to reactivate the subscription to resume reviews. Manage billing

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Improve VTOL RTH transition timing and post-switch capture

🐞 Bug fix 🧪 Tests 📝 Documentation 🕐 40+ Minutes

Grey Divider

AI Description

• Starts landing transitions early using destination closing speed and existing mixer timing.
• Brakes and aligns in multicopter mode before resuming the RTH approach.
• Adds safety-focused regression tests and operational documentation for timing and limitations.
Diagram

stateDiagram-v2
    direction TD
    [*] --> RTHApproach
    RTHApproach --> Confirming: eligible and inside boundary
    Confirming --> RTHApproach: route or state interrupted
    Confirming --> FWToMC: stable for 300 ms
    FWToMC --> Braking: successful MC switch
    Braking --> Aligning: motion settled
    Aligning --> Braking: motion or attitude excessive
    Aligning --> RTHResume: heading and settle stable
    RTHResume --> [*]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Fixed-distance transition trigger
  • ➕ Simpler eligibility logic and easier field tuning.
  • ➕ Independent of potentially noisy velocity estimates.
  • ➖ Cannot adapt to headwind, tailwind, or different approach speeds.
  • ➖ A single radius may transition too early or too late across airframes.
2. Calibrated airframe stopping model
  • ➕ Could account for measured transition and multicopter braking performance.
  • ➕ Offers a more accurate overshoot prediction than mixer timers alone.
  • ➖ Requires new configuration, calibration, and validation procedures.
  • ➖ Adds complexity and may create unsafe results when calibration becomes stale.

Recommendation: The PR's timer-based closing-speed heuristic is the best incremental approach because it adapts to actual ground motion, reuses existing mixer configuration, and retains the loiter-radius fallback. The post-switch braking and alignment state machine also handles prediction error without introducing new parameters; end-to-end SITL and representative flight validation should precede treating the heuristic as an assured stopping boundary.

Files changed (4) +403 / -7

Bug fix (2) +277 / -7
navigation.cAdd adaptive RTH transition triggering and multicopter capture +212/-7

Add adaptive RTH transition triggering and multicopter capture

• Integrates closing-speed-based FW-to-MC initiation into the direct RTH approach with continuous confirmation and reset conditions. Adds stop and alignment stages after a successful navigation-owned transition while preserving RTH position safety checks, altitude protection, and state ownership.

src/main/navigation/navigation.c

navigation_vtol_mc_protection_logic.hProvide RTH timing, geometry, and heading helpers +65/-0

Provide RTH timing, geometry, and heading helpers

• Adds helpers for transition time budgets, velocity projection toward Home, overflow-safe start-distance calculation, and post-switch heading selection. Defines confirmation duration and heading tolerance constants used by the RTH capture lifecycle.

src/main/navigation/navigation_vtol_mc_protection_logic.h

Tests (1) +72 / -0
vtol_mc_protection_logic_unittest.ccCover RTH transition prediction and capture edge cases +72/-0

Cover RTH transition prediction and capture edge cases

• Tests heading selection, timer and dynamic-ramp budgets, loiter-radius fallback, closing-speed geometry, invalid estimates, and arithmetic saturation. Also verifies speed-spike rejection, confirmation restart behavior, and millisecond rollover handling.

src/test/unit/vtol_mc_protection_logic_unittest.cc

Documentation (1) +54 / -0
VTOL.mdDocument early RTH transitions and post-switch capture +54/-0

Document early RTH transitions and post-switch capture

• Explains transition-boundary calculation, confirmation timing, fallback behavior, eligibility, and interactions with existing airspeed and failsafe controls. Documents the braking and alignment sequence, operational limitations, and a representative timing example.

docs/VTOL.md

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Sep 7, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Later missions cannot select airplane mode ✓ Resolved
Description
startRthVTOLTransitionCapture() sets the global navVtolFwToMcProtectionLatched flag even though
this transition selected multicopter mode specifically for the RTH landing approach. If the pilot
leaves RTH through position hold and then starts a waypoint mission, the latch survives and
prepareMissionVTOLTransition() silently skips every subsequent transition to fixed-wing mode until
navigation enters idle.
Code

src/main/navigation/navigation.c[R2608-2610]

+    // Once RTH has selected MC for the landing approach, do not let the normal
+    // long-distance RTH optimization immediately request MC->FW again.
+    navVtolFwToMcProtectionLatched = true;
Evidence
The new capture writes the protection latch at navigation.c[2599-2611], while the only resets are
IDLE entry and navigation initialization at navigation.c[1483-1492] and navigation.c[6837-6846].
Position-hold entry does not reset it at navigation.c[1533-1559], and mission preparation rejects
fixed-wing transition commands whenever it remains set at navigation.c[3007-3025].

src/main/navigation/navigation.c[2599-2611]
src/main/navigation/navigation.c[1483-1492]
src/main/navigation/navigation.c[1533-1559]
src/main/navigation/navigation.c[3007-3025]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The post-RTH-transition capture sets `navVtolFwToMcProtectionLatched`, a global protection latch also used to reject mission MC-to-FW transitions. Because position-hold and other non-idle mode changes do not clear it, a later waypoint mission can remain stuck in multicopter mode.
## Issue Context
The new latch is intended only to stop the long-distance RTH optimization from reversing the landing transition. Preserve the existing low-speed protection latch semantics while giving RTH landing suppression its own lifecycle, cleared when RTH ownership ends.
## Fix Focus Areas
- src/main/navigation/navigation.c[2599-2611]
- src/main/navigation/navigation.c[1924-1934]
- src/main/navigation/navigation.c[4243-4248]
- src/main/navigation/navigation.c[3021-3025]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can move or hide resolved findings to focus on what still needs action

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread src/main/navigation/navigation.c Outdated
@github-actions

github-actions Bot commented Sep 7, 2026 •

Copy link
Copy Markdown

RAM / Flash usage vs. base commit 01a7aa3 — commit 84c4598

Using the nearest available size baseline: this build contains base commit 29ec86e, which has no stored baseline yet, so the deltas also include what was merged to the base since 01a7aa3.

Target Flash Δ RAM Δ
MATEKF405 +2000 B (+0.28%) CCM: ±0 B (±0.00%)
RAM: +40 B (+0.04%)
MATEKF722 ±0 B (±0.00%) ITCM_RAM: ±0 B (±0.00%)
RAM: ±0 B (±0.00%)
TCM: ±0 B (±0.00%)
MATEKF765 +1368 B (+0.18%) DTCM_RAM: ±0 B (±0.00%)
SRAM1: +20 B (+0.02%)
MATEKH743 +1536 B (+0.19%) D2_RAM: ±0 B (±0.00%)
DTCM_RAM: ±0 B (±0.00%)
ITCM_RAM: -8 B (-0.05%)
RAM: +32 B (+0.02%)

See RAM/flash optimization guide for techniques to reduce usage.

@github-actions

github-actions Bot commented Sep 7, 2026 •

Copy link
Copy Markdown

Test firmware build ready — commit 84c4598

Download firmware for PR #11871

251 targets built. Find your board's .hex file by name on that page (e.g. MATEKF405SE.hex). Files are individually downloadable — no GitHub login required.

Development build for testing only. Use Full Chip Erase when flashing.

- Separate normal RTH landing MC selection from low-speed safety protection
- Clear RTH-only selection on mode exit without weakening safety protection
- Preserve switch synchronization when NAV ends during an active transition
- Retain SafeHome and RTH altitude plans throughout transitions and retries
- Keep brief position losses within RTH; abort safely on navigation sensor failure
- Block RC Home reset during navigation-owned transitions
- Add regression tests and document mode ownership and handback behavior
@sensei-hacker

Copy link
Copy Markdown
Member

Note: #11917 also modifies behavior around a VTOL mixer-profile switch (servo-speed carryover, building on #10986). Different bugs, but worth flight-testing together rather than assuming independence.

@Sibre3

Sibre3 commented Oct 2, 2026

Copy link
Copy Markdown

@mart1npetroff I'm interested to know if this is finished. Or has been SITL tested and in a stable state for a testing?
What branch is it part of?

@mart1npetroff

Copy link
Copy Markdown
Contributor Author

This was implemented based on a recommendation from @Jetrell, but I haven't had a chance to flight-test it yet.

At the moment, I'm actively working on and testing the Precision Landing PR: #11554, so most of my testing effort has been focused there.

I also haven't received any feedback from @Jetrell yet on whether he has tested this implementation.

Additionally, I haven't had time yet to look into @sensei-hacker's comment regarding the PR he mentioned.

As soon as I finish testing the PL logic — which I expect to happen within the next 1–2 weeks — I'll return to this PR and continue testing it, including flight testing.

@Jetrell

Jetrell commented Oct 2, 2026

Copy link
Copy Markdown

I haven't flight tested it yet. I've been busy with testing continuous fixes and changes to the INAV 10 release candidates.
But it is on my todo list.. I also wasn't sure where you were up to with it.

@sensei-hacker sensei-hacker added this to the 10.1 milestone Oct 3, 2026
Use the shared timer fallback for manual tailsitter FW-to-MC transitions and apply the airspeed timeout only when airspeed controls switching. Preserve the existing MC attitude capture and autonomous-transition restrictions.

Document source-profile timer selection and add regression tests for timer boundaries and airspeed precedence.
@Jetrell

Jetrell commented Oct 25, 2026 •

Copy link
Copy Markdown

@mart1npetroff I ran some tests last week with your last commit, using a tailsitter VTOL.
The auto transition timer makes it more reliable than airspeed on the first transition.

Using these settings.

# master 
vtol_transition_to_fw_min_airspeed_cm_s = 1111
vtol_autotransition_always = ON

# mixer_profile
mixer_profile 1

set platform_type = AIRPLANE
set model_preview_type = 26
set mixer_control_profile_linking = ON
set mixer_vtol_manualswitch_autotransition_controller = ON

# mixer_profile
mixer_profile 2

set platform_type = TRICOPTER
set model_preview_type = 1
set mixer_control_profile_linking = ON
set mixer_switch_trans_timer = 35
set mixer_vtol_manualswitch_autotransition_controller = ON
set tailsitter_orientation_offset = ON
set transition_pid_mmix_multiplier_roll = 900

I have some recommendations from my testing. That will really help Tailsitter implementation. Because they are inherently far more unstable than a conventional VTOL, due to vertical pitch and yaw being controlled by air deflections rather than motor thrust.

The biggest failure point of a tailsitter, is if the plane looses vertical stabilization control when descending in VTOL mode.
This can easily occur if the throttle is lowered a little too quickly. Causing the upward airflow on the elevons or elevator/ailerons, to push the airframe in the opposite direction to which the control output is commanding it to move.
This will stall the propeller airflow over the surfaces. And cause the tailsitter to fall-out of the hover, predominately on the pitch axis.
The problem this leads to, is the i-term has a lot of accumulated error by this point So it flicks the plane ground-wards at what ever the hover throttle is set too.

If you are quick. It can be caught again. By pulsing the throttle above hover throttle for a moment, to provide a burst of prop airflow over the control surfaces. Or switching back to mixer profile 1 as a last attempt to prevent a crash, when it is too far gone (more that 45degs from vertical)... However switching back also means it has to auto transition. Which isn't ideal when vtol_autotransition_always = ON, if the plane happens to fall on to its top side.

This is certainly a place for vtol_mc_protection_mode = NAV_AND_STABILIZED. But it will require its own variant. With a few checks specific to tailsitters.

  • Check vertical speed before allowing ALTHOLD or POSHOLD to be activated. (same as with other VTOL platforms).
  • Constantly check pitch angle and i-term windup on the pitch axis, and compare the manual hover throttle to nav_mc_hover_thr setpoint.. If pitch angle reduces more than 45° below vertical, and i-term error has reached 100% of pid_iterm_limit_percent and the throttle is below the nav_mc_hover_thr setpoint + 2%.
    • Then override manual throttle with nav_mc_hover_thr and increase (pulse) the throttle above nav_mc_hover_thr by 20% until the nose becomes vertical again. Then instantly lower the throttle back to the hover throttle setpoint. And hand manual throttle control back to the pilot once the vertical velocity has stabilized.
    • If that fails due to bad wind conditions or a poor tailsitter type airframe. Then allow for a bailout, by allowing the tailsitter to auto transition back to FW mixer profile 1, WITHOUT the transition timer.. This will allow FW recovery.
  • For a Tailsitter. Both the vtol_transition_authority_min_percent settings need to be applied differently to the way they work for conventional VTOLs.. For a tailsiter during MC to FW transition at the 45° FC board angle. It requires all the mixer profile 2 (MC) gains to be lowered as the airspeed rises or the timer progresses, both the motors and especially the pitch and yaw servos. Because Tailsitters require a LOT of P and I gain to provide good hover stability in the MC profile.
    And it also requires the mixer profile 2 gains for the motors and servos to be attenuated during FW to MC transition, until the forward airspeed has reduce to below around 30km/h, to prevent oscillations. This would still be the case if FW to MC transition has no timer allocation A 3DGround speed check would even be better than nothing.

I have also found in testing, that auto throttle altitude control modes (ALTHOLD and POSHOLD) help considerably on all VTOL platform types.. However, if the user has them active, They lockout transition switching from example MC to FW.
I understand this is for safety. But that safety is only because the code doesn't provide the means to automatically switch out of POSHOLD or ALTHOLD, if the user starts a transition..
If that was added, with an OSD system message to tell the user to turn off that nav mode switch. it would make bailout much easier for Tailsitters, or even conventional VTOL's if control loss, due to strong winds occurred.. As it is. You have to switch out of POSHOLD, then move the transition switch.
I have added such a feature to my setup for testing.. I would have crashed my Tailsitter many times.

These are only recommendations. But I thought it best to inform you. So you know of these short comings, with a remedy, which is similar to what AP does, if you choose to make improvements.
Thanks for all your work so far.

@sensei-hacker
sensei-hacker changed the base branch from maintenance-10.x to next-10.1 October 28, 2026 03:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants