Skip to content

Require nav_fw_launch_accel for throw launch detection - #11911

Open
Raffi1202 wants to merge 2 commits into
iNavFlight:maintenance-10.xfrom
Raffi1202:fix/throw-launch-threshold
Open

Raffi1202 wants to merge 2 commits into
iNavFlight:maintenance-10.xfrom
Raffi1202:fix/throw-launch-threshold

Conversation

@Raffi1202

@Raffi1202 Raffi1202 commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Problem

Fixes #10995. On INAV 8.0.1 (SpeedyBee F405 Wing) the reporter armed in launch mode, raised the throttle and held the aircraft still in his hands. Launch mode triggered on its own and the motor spun up to launch throttle. His DVR showed GPS ground speed briefly reading 11 km/h with 6 satellites, a positioning error.

Cause

src/main/navigation/navigation_fw_launch.c:426 on maintenance-10.x. The throw path isForwardLaunched needs only isGPSHeadingValid(), groundSpeed > nav_fw_launch_velocity and imuMeasuredAccelBF.x > 0. imuMeasuredAccelBF is the raw body-frame accelerometer including gravity, so an aircraft held nose-up reads a permanently positive x. isGPSHeadingValid() (src/main/io/gps.c:673) is true with a fix, 6 satellites and 300 cm/s. A GPS speed glitch above 300 cm/s for 40 ms (nav_fw_launch_detect_time) was therefore enough. nav_fw_launch_accel, described as the "threshold for bungee launch or throw launch", was not used on this path.

Change

WAIT_DETECTION now records the time at which imuMeasuredAccelBF.x last exceeded nav_fw_launch_accel. The throw path requires that this happened within the last 1000 ms (THROW_LAUNCH_ACCEL_HOLD_TIME) instead of x > 0, because the throw's acceleration peak is over before the GPS speed follows (@breadoven in the issue). The timestamp is cleared when it expires, when the throttle drops low in WAIT_DETECTION, and in resetFixedWingLaunchController(). Bungee and swing detection and all defaults are unchanged.

Test

Not run on hardware or SITL. Cause verified by reading navigation_fw_launch.c:426 and gps.c:673 on maintenance-10.x; Qodo's two findings on this PR (stale timestamp after signed-delta overflow, timestamp surviving a throttle-low abort) are addressed by commit 4888b74.

Flash / RAM

Not measured yet. The upstream firmware CI has not been released for this PR, so no size report exists.

Docs

No documentation change needed: docs/Settings.md already describes nav_fw_launch_accel as the "Forward acceleration threshold for bungee launch or throw launch"; the code now matches that text.

Throw launch detection only asked for any positive forward acceleration.
That is satisfied by normal accelerometer noise and permanently satisfied
while the aircraft is simply held nose up, so a short GPS ground speed
glitch was enough to start the launch with the aircraft still in the
pilot's hands and spin up the motor to launch throttle.

Require the forward acceleration to have exceeded nav_fw_launch_accel, as
the setting description already promises. The acceleration peak of a throw
is over before the GPS speed follows, so a peak seen shortly before still
counts. Bungee and swing launch detection are unchanged, defaults are
unchanged.

Fixes iNavFlight#10995
@Raffi1202
Raffi1202 marked this pull request as ready for review September 11, 2026 15:46
@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

Require recent acceleration peak for GPS throw launch detection

🐞 Bug fix 🕐 10-20 Minutes

Grey Divider

AI Description

• Requires a recent configured acceleration peak before GPS-based throw launch detection.
• Remembers qualifying acceleration for one second to accommodate GPS speed latency.
• Leaves bungee, swing, and default launch thresholds unchanged.
Diagram

graph TD
    A["Forward accel"] --> B{"Above threshold?"} -->|Yes| C["One-second memory"] --> D{"GPS valid and fast?"} -->|Yes| E["Launch detected"]
    G["GPS heading speed"] --> D
    B -->|No| F["Wait detection"]
    D -->|No| F
Loading
High-Level Assessment

The timestamped acceleration latch is the appropriate approach because the throw acceleration peak precedes GPS speed confirmation. A simultaneous acceleration-and-GPS condition would likely miss genuine throws, while changing GPS validity rules would affect unrelated navigation behavior. The bounded one-second memory localizes the fix without changing bungee, swing, or default thresholds.

Files changed (1) +12 / -1

Bug fix (1) +12 / -1
navigation_fw_launch.cGate GPS throw detection on a recent acceleration peak +12/-1

Gate GPS throw detection on a recent acceleration peak

• Records when forward acceleration last exceeds nav_fw_launch_accel and accepts that peak for one second while GPS speed catches up. GPS-based throw detection now uses this remembered threshold crossing instead of any positive acceleration, and controller reset clears the timestamp.

src/main/navigation/navigation_fw_launch.c

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

qodo-free-for-open-source-projects Bot commented Sep 11, 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. Old jolts become valid after 36 minutes ✓ Resolved 🐞 Bug ≡ Correctness
Description
wasForwardAccelerationHigh treats every negative result from cmpTimeUs as less than the
one-second limit, while forwardAccelHighTimeUs is retained after its intended window expires. Once
a launch wait continues roughly 35.8 minutes beyond an earlier acceleration event, signed-delta
overflow makes that stale event qualify again and GPS speed can complete detection.
Code

src/main/navigation/navigation_fw_launch.c[431]

+    const bool wasForwardAccelerationHigh = (forwardAccelHighTimeUs != 0) && (cmpTimeUs(currentTimeUs, forwardAccelHighTimeUs) < MS2US(THROW_LAUNCH_ACCEL_HOLD_TIME));
Evidence
The repository documents that timeDelta_t is signed 32-bit and overflows at about 35 minutes, and
cmpTimeUs casts the timestamp subtraction to that type. The new condition has only an upper-bound
comparison, so a negative overflowed delta passes; because the timestamp is otherwise cleared only
during full controller reset, launch mode can retain it for that long.

src/main/common/time.h[27-30]
src/main/common/time.h[40-46]
src/main/common/time.h[63-64]
src/main/navigation/navigation_fw_launch.c[426-435]
src/main/navigation/navigation_fw_launch.c[572-583]
src/main/navigation/navigation_fw_launch.c[601-610]

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 remembered acceleration timestamp is never expired, and the signed 32-bit comparison becomes negative after about 35 minutes, causing an old event to satisfy the one-second recency check.
## Fix Focus Areas
- src/main/navigation/navigation_fw_launch.c[426-435]
- src/main/common/time.h[27-30]
- src/main/common/time.h[63-64]
## Recommended Fix
Explicitly clear the remembered timestamp once its one-second window expires and require the computed delta to be nonnegative before accepting it as recent. Keep expiry evaluation running on every detection cycle so the timestamp cannot survive until signed-delta overflow.

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



Remediation recommended

2. An aborted attempt can still launch ✓ Resolved 🐞 Bug ≡ Correctness
Description
fwLaunchState_FW_LAUNCH_STATE_WAIT_DETECTION records forwardAccelHighTimeUs but does not clear
it when low throttle returns the controller to WAIT_THROTTLE. When the pilot raises throttle again
within one second, the previous attempt's acceleration can combine with qualifying GPS speed and
enter detection without a new throw.
Code

src/main/navigation/navigation_fw_launch.c[R426-427]

+    if (isForwardAccelerationHigh) {
+        forwardAccelHighTimeUs = currentTimeUs;
Evidence
The added assignment stores the acceleration timestamp globally, while the state table sends a
low-throttle event from detection back to throttle waiting and the throttle-wait handler can
immediately return to detection. Only full launch initialization calls the reset function that
clears the timestamp, so this normal retry path retains it and line 435 consumes it with GPS speed.

src/main/navigation/navigation_fw_launch.c[168-174]
src/main/navigation/navigation_fw_launch.c[337-356]
src/main/navigation/navigation_fw_launch.c[416-435]
src/main/navigation/navigation_fw_launch.c[601-610]
src/main/navigation/navigation.c[3409-3416]

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

## Issue description
A throttle-low transition aborts detection and returns the controller to `WAIT_THROTTLE`, but the newly added acceleration timestamp survives that transition and remains usable by the next attempt.
## Fix Focus Areas
- src/main/navigation/navigation_fw_launch.c[416-431]
## Recommended Fix
Clear `forwardAccelHighTimeUs` when low throttle exits `WAIT_DETECTION`, ensuring every newly armed detection attempt requires its own acceleration event.

ⓘ 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 switch off images and animations for a plain-text comment

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread src/main/navigation/navigation_fw_launch.c
Comment thread src/main/navigation/navigation_fw_launch.c Outdated
@sensei-hacker sensei-hacker added this to the 10.0 milestone Sep 20, 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.

2 participants