android: fix head-gesture axis bias, add sensitivity slider - #1
Draft
ohuc wants to merge 2 commits into
Draft
Conversation
…sign WIP) Snapshot of the main checkout's uncommitted changes so the head-gesture rework in the next commit is a clean, cherry-pickable delta on top of the exact state the app is currently built from. Not authored in this branch. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The nod/shake detector produced seemingly random yes/no results. Four compounding bugs biased it toward whichever axis happened to get primed: - peakIntervals/movementSpeedIntervals were shared between the vertical and horizontal axes, so incidental motion on one axis corrupted the other's rhythm score. - Extremes were recorded with buffer.size-1 as their index, which saturates at 99 once the 100-sample ring fills; chronological sorting and the peak/trough alternation check then operated on scrambled data. - Peaks/troughs never expired, so a stray early movement (glancing at the ringing phone) permanently primed an axis for the whole call. - No DC-baseline handling: the accel pair carries a posture-dependent offset, so fixed abs-value thresholds favoured whichever axis rested further from zero and broke sign-alternation scoring. Rework: strictly per-axis state (peaks, rhythm, direction) behind one lock; an 8-sample baseline warmup plus slow EMA so all thresholds apply to a centered signal; extremes pruned outside a 2.6 s gesture window; alternation checked on chronological peak/trough types. Detection thresholds now derive from a user-tunable sensitivity preference (head_gesture_sensitivity, 0..1, default 0.5 ~= previous behaviour), exposed as a slider on the Head Tracking screen and read at every startDetection() so the in-app gesture test reflects it immediately. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Head gestures (nod = answer, shake = decline) gave seemingly random results. This reworks the detector and adds a user-facing sensitivity slider.
Why it was 'randomly biased'
Four compounding bugs in
GestureDetector.kt:peakIntervals/movementSpeedIntervalswere shared between the vertical and horizontal axes, so motion on one axis corrupted the other's rhythm score.buffer.size - 1as their index, which pins at 99 once the 100-sample ring fills; the chronological sort and peak/trough alternation check then ran on scrambled data (i.e. detection quality degraded the longer the phone rang).The rework
Sensitivity slider
New pref
head_gesture_sensitivity(0..1, default 0.5 ≈ historical thresholds), surfaced on the Head Tracking screen. It interpolates the peak threshold (550→150), full-score amplitude (950→350) and audio-feedback threshold (900→300). Read at everystartDetection(), so 'Test Head Gestures' picks changes up immediately.Testing
:app:compileFossDebugKotlinand fullassembleFossDebugbuild green.adb logcat -s GestureDetectorshows per-axis confidence. TheGCAPcapture broadcast is still in place for offline tuning if the endpoints need refinement.🤖 Generated with Claude Code