Glass lever: port the pod-build GAIT DETENT to the PadRIO throttle slew

Human re-test on the fresh build: zero-stop OK, but the lever could PARK inside
the walk/run hysteresis band (walkStrideLength@0x534 .. reverseSpeedMax@0x538)
where the gait SM has no stable state -- walk<->run hunt, EngineShiftFwd/Rev
retriggering ("mixed walk/run mode + repeated acceleration sample").  The
pod-build keyboard lever already snaps out of the band to the NEARER edge at
key-rest (mech4.cpp GAIT DETENT); the PadRIO slew channel lacked it.

Faithful port, not an invention: mech4.cpp publishes the band in lever units
every driven frame (gBTGaitDetentLo/Hi seam, same guards + the same +0.002
engage margin); L4PADRIO Poll() applies the identical nearer-edge snap to the
Throttle channel when the slew rests (no slew key held, no pad slew axis
deflected).  Sweeping through the band while held stays continuous (the
authentic moving lever, one authentic shift).

Verified (DEV.EGG glass, graduated parks each ~0.10 of the sweep,
BT_GAIT_TRACE+BT_MPPR_TRACE): band [0.358026,0.50388) = demand 22.02-30.87;
in-band parks snap both directions (0.4137->lo, 0.465126->hi); no at-rest
sample in the band; exactly ONE walk->run clip (state 10) up and ONE run->walk
(state 14) down across the whole sweep; zero-stop unaffected; pod build
rebuilt + BT_AUTODRIVE smoke clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-20 10:57:34 -05:00
co-authored by Claude Fable 5
parent 1535e3e48d
commit 6ad1e074cc
5 changed files with 121 additions and 1 deletions
+28
View File
@@ -278,6 +278,34 @@ HEAD. One diagnostic enrichment landed: the `BT_MPPR_TRACE` `[mppr-c]` line now
**Lesson (procedural):** after landing an engine/input commit, REBUILD every live build dir
before relaunching — a stale `build-glass` exe reproduces "the whole keymap is broken" exactly.
### 2026-07-20 (later still) — human re-test: GAIT DETENT ported to the PadRIO lever [T2]
**Report (fresh build):** zero-stop confirmed working, but "OUR detent is still missing — it
goes into that mixed walk/run mode and repeats the acceleration sample." That is the documented
gait DEAD BAND (locomotion.md [T1]): the SM has no stable state for a demand in
(`walkStrideLength`@0x534, `reverseSpeedMax`@0x538) — parked there it cycles 7→10→14→7 forever,
retriggering EngineShiftFwd/Rev each swing. The pod-build keyboard lever carries an
accommodation (mech4.cpp "GAIT DETENT": at KEY-REST, snap the lever out of the band to the
NEARER edge; sweeping through while held stays continuous) — the PadRIO slew channel had no
such protection, so the glass lever could park in-band.
**Port (faithful copy, not an invention):** mech4.cpp publishes the band in lever units every
driven frame through a new seam (`gBTGaitDetentLo/Hi`, same guards + the same +0.002 engage
margin; hi<=lo = unknown); `L4PADRIO.cpp Poll()` applies the IDENTICAL nearer-edge snap to the
Throttle channel when the slew is at rest (no slew key held, no pad slew axis deflected) —
same rule, same log tag, gated `BT_GAIT_TRACE`. The rest decision uses PadRIO's own held-state
(the lever's owner on glass), not gBTDrive.keyFwd/Back.
**Verified (build-glass, DEV.EGG solo, graduated UP-taps parking the lever every ~0.10 across
0..1, BT_GAIT_TRACE+BT_MPPR_TRACE):** band [0.358026, 0.50388) = demand 22.02→30.87 (the
locomotion.md Blackhawk numbers); park at 0.4137 → snapped DOWN to 0.358026, park at 0.465126 →
snapped UP to 0.50388 (both nearer-edge directions); rest-position histogram shows NO at-rest
sample inside the band; gait states: ONE walk→run clip (state 10, once) on the whole ascending
sweep, ONE run→walk (state 14, once) descending, normal 6↔7 / 12↔13 cycling between — the
accel/shift sample can fire only once per real transition. Zero-stop unaffected (thr=0 rest,
state 0). Pod build rebuilt + BT_AUTODRIVE smoke clean (the seam publish is a pure global
write on the pod path).
## 2026-07-18 — Merge origin/master (commit f889e24): btinput meets PadRIO
Master's 33-commit run landed (D1 relay/operator-console line, CONTROLS.MAP+XInput binding