Skip to content

Implement auto vtol smooth transition state#11553

Draft
mart1npetroff wants to merge 6 commits into
iNavFlight:maintenance-10.xfrom
mart1npetroff:implement-auto-vtol-smooth-transition-state
Draft

Implement auto vtol smooth transition state#11553
mart1npetroff wants to merge 6 commits into
iNavFlight:maintenance-10.xfrom
mart1npetroff:implement-auto-vtol-smooth-transition-state

Conversation

@mart1npetroff
Copy link
Copy Markdown

No description provided.

…speed-first logic and dynamic scaling

- Introduce a common VTOL transition controller path used by:
  - manual MIXER TRANSITION (edge-triggered mode, optional via manual_vtol_transition_controller)
  - mission-authorized VTOL transition via nav_vtol_mission_transition_user_action
- Keep profile hot-switch safety boundaries intact:
  - no broad manual mixer switching in active waypoint navigation
  - switching remains authorized only through transition state handling
- Add airspeed-first completion behavior:
  - MC->FW threshold via vtol_transition_to_fw_min_airspeed_cm_s
  - FW->MC threshold via vtol_transition_to_mc_max_airspeed_cm_s
  - timer fallback only when pitot is unavailable/unhealthy
  - timeout/abort support via vtol_transition_airspeed_timeout_ms
- Add optional dynamic mixer scaling (vtol_transition_dynamic_mixer):
  - pusher contribution ramping
  - lift throttle scaling (vtol_transition_lift_end_percent)
  - MC authority scaling (vtol_transition_mc_authority_end_percent)
  - FW authority blend scaling (vtol_transition_fw_authority_start_percent)
- Fix transition scaling/progress details:
  - pusher ramp uses idle-to-target interpolation
  - FW->MC progress uses captured transition start airspeed for smooth deceleration-based ramp
- Improve transition abort/reset robustness:
  - clear transition/nav mission transition state on disarm/failsafe/abort paths
  - avoid blind mission resume after half-complete transition
- Add mission VTOL settings and behavior:
  - nav_vtol_mission_transition_user_action
  - nav_vtol_mission_transition_min_altitude_cm
  - nav_vtol_mission_transition_track_distance_cm
  - mission pause/resume around transition, straight-line MC->FW transition segment
- Update documentation:
  - MixerProfile.md, Navigation.md, VTOL.md
  - document unified controller, manual semantics, mission semantics, airspeed precedence, dynamic scaling, and CLI usage
…orm target (0=MC, 1=FW)

- document dependency on existing mixer profile switching infrastructure (two profiles + MIXER PROFILE 2 mode condition)
- update docs: MixerProfile.md, Navigation.md, VTOL.md with behavior, safety boundaries, tuning examples, and CLI reference
@Jetrell
Copy link
Copy Markdown

Jetrell commented May 13, 2026

Thanks for your VTOL contribution to INAV. They will be welcome improvements

I have a couple of questions.

I noticed you have an edge trigger for the transition switch, along with the legacy 3Pos manual method.
I'm wondering if this might be less intuitive for users who are familiar with the legacy 3Pos toggle switch ? Which could cause confusion for those used to the legacy method, but still want to use the airspeed/timer method.

I also noticed your addition of Dynamic Scaling. Of which I like the idea.
However it would seem the timer for the scaling is controlled by mixer_switch_trans_timer. Which would seem to indicate the scaling is ramped over that whole time period.
I thought this could be an issue.. In the example of the 'pusher contribution' on a 4 + 1. If the plane requires 80% throttle to gain a good MC to FW transition speed. And the mixer_switch_trans_timer was set to a reasonable value of 5s. It would mean that 80% throttle would not be reached until right before transition ended, if mixer_switch_trans_airspeed_cm_s wasn't met in that time period.
I would have thought it might be more intuitive for users to have another timer that could be set to a shorter period. To specifically overcome harsh motor startup torque reaction on larger tilt-rotors / 4+1's. Or the short transition instability that occurs between mixer changes, as the plane settles into that flight state.
While leaving mixer_switch_trans_timer as just a transition time backup for mixer_switch_trans_airspeed_cm_s ?

@mart1npetroff
Copy link
Copy Markdown
Author

mart1npetroff commented May 13, 2026

Great feedback, thank you.

On the 3-position manual method question:

I agree this can be confusing if not documented clearly, so I should clarify it better in the PR/docs. The intent is not to replace legacy behaviour. The edge-triggered manual controller is optional (manual_vtol_transition_controller), and legacy 3-position/manual behaviour remains available when that setting is OFF.

my intention is still to support practical 3-position switch workflow when manual_vtol_transition_controller = ON, not to remove it.
A typical setup can still be:

Position 1: MC
Position 2: Auto Transition
Position 3: FW
When manual_vtol_transition_controller = ON, position 2 is used as a trigger to start the AUTO transition sequence.
In real use, I can fly in MC, move the switch to Transition, let the controller complete the automatic transition, then move the switch to FW after completion. For FW->MC, I do the same in reverse order.

So the goal is to keep familiar switch ergonomics, while making transition execution more deterministic and safer.

On the dynamic scaling timer point: I agree this is a good observation.
Scaling follows airspeed progress when pitot is healthy/available, and falls back to timer-based progress when pitot is unavailable. In fallback cases, using only mixer_switch_trans_timer can make ramp-up too slow for some setups.

I propose an optional separate setting:

vtol_transition_scale_ramp_time_ms

with behavior:

0 (default): keep current behavior (backward compatible)

0: use this timer only for scaling ramp (pusher/lift/authority), while transition completion logic remains unchanged (airspeed-first; mixer_switch_trans_timer still acts as fallback completion timer when pitot is unavailable/unhealthy)
Example:

mixer_switch_trans_timer = 5000 ms
vtol_transition_scale_ramp_time_ms = 1200 ms
This gives:

scaling reaches target levels in about 1.2s (smoother motor startup / less torque step),
completion still waits for airspeed threshold when pitot is healthy,
if pitot is not available, completion fallback still uses the 5s transition timer.
If this direction makes sense to you, I can implement it in a follow-up patch after agreement.

When pitot is healthy/available, transition progress is airspeed-driven (not timer-driven).

  • MC -> FW:

    • progress = constrain(airspeed / to_fw_threshold, 0..1)
    • completion condition = airspeed >= to_fw_threshold
  • FW -> MC:

    • capture startAirspeed when transition starts
    • progress = constrain((startAirspeed - airspeed) / (startAirspeed - to_mc_threshold), 0..1)
    • completion condition = airspeed <= to_mc_threshold

Dynamic mixer scaling (vtol_transition_dynamic_mixer = ON) uses this progress:

  • MC -> FW:

    • pusher scale ramps 0 -> 1
    • lift scale ramps 1 -> vtol_transition_lift_end_percent
    • MC authority ramps 1 -> vtol_transition_mc_authority_end_percent
    • FW authority ramps vtol_transition_fw_authority_start_percent -> 1
  • FW -> MC:

    • pusher scale ramps 1 -> 0
    • lift scale ramps vtol_transition_lift_end_percent -> 1
    • MC authority ramps vtol_transition_mc_authority_end_percent -> 1
    • FW authority ramps 1 -> vtol_transition_fw_authority_start_percent

For transition/pusher motors (-2.0 < throttle < -1.0), output is interpolated from idle to target:

motor = idle + (target - idle) * pusherScale

where:

  • target = -mixerThrottle * 1000
  • idle = throttleRangeMin

@Jetrell
Copy link
Copy Markdown

Jetrell commented May 13, 2026

If this direction makes sense to you, I can implement it in a follow-up patch after agreement.

Position 1: MC
Position 2: Auto Transition
Position 3: FW

vtol_transition_scale_ramp_time_ms = 1200 ms

Yes I agree with both changes you have proposed.

Do you happen to have the RealFlight simulator software to test this with the SITL before an actual flight? I unfortunately don't have it.

…y/3-pos switch behavior

- add new mixer setting `vtol_transition_scale_ramp_time_ms` (default 0)
- keep backward compatibility:
  - `0` => scaling stays coupled to transition progress (existing behavior)
  - `>0` => pusher/lift/authority scaling uses time-based ramp
- keep transition completion logic unchanged:
  - airspeed-first when pitot is healthy/available
  - timer fallback via `mixer_switch_trans_timer` when pitot is unavailable/unhealthy
- wire new setting into mixer profile config/reset path
- update VTOL and MixerProfile docs:
  - explicitly state intent is not to replace legacy manual behavior
  - document 3-position workflow with edge-trigger controller
  - document new ramp timer semantics with practical examples
@mart1npetroff
Copy link
Copy Markdown
Author

Changes pushed and PR updated.

No I do not have RealFlight on my site right now but while ago I tested some scenarios with X-Plane and Alia 250 eVTOL.
I will provide update and hopfully videos after test flights.

One more question: Currently I'm using one of User Actions in WP (configurable) for target selection in mission. Do you think this is good approach or is it better to use bit 5 (which is currently reserved) from WP's p3 instead?

@Jetrell
Copy link
Copy Markdown

Jetrell commented May 13, 2026

Currently I'm using one of User Actions in WP (configurable) for target selection in mission. Do you think this is good approach or is it better to use bit 5 (which is currently reserved) from WP's p3 instead?

Using the configurable USER actions sounds fine. It allows users to configure them in the IPF to suit their requirements.

@github-actions
Copy link
Copy Markdown

Test firmware build ready — commit 8ab311a

Download firmware for PR #11553

234 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.

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.

2 participants