Controls: the .CTL positional-id off-by-one -- CONFIRMED live and FIXED (step 2a)

The streamed L4 mapping resource carries the binary's positional attribute ids
(stick=3, throttle=4) but MechControlsMapper chained from Subsystem::NextAttributeID
== 2 -- every streamed record resolved ONE MEMBER LATE (attr 4 -> pedalsPosition,
verified via the new permanent BT_CTRLMAP_LOG diagnostic in CreateStreamedMappings).
A latent real-pod bug: the serial RIO throttle would drive the pedals member; the
dev keyboard bridge masked it. Fix per the mechweap/mech attrPad idiom: ids pinned
to the binary numbering, id-2 gap padded, static_assert-locked. Torso + weapon
chains verified already aligned. Regression: BT_FORCE_THROTTLE headless walk clean
(speedDemand=61.501 through authentic InterpretControls, gait cycles, no faults).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-17 21:59:51 -05:00
co-authored by Claude Fable 5
parent 3f49915d76
commit b26e8205e3
7 changed files with 113 additions and 24 deletions
+10 -3
View File
@@ -5,7 +5,7 @@ status: living
source_sections: "plan 2026-07-17; CMakeLists.txt gates; BT412 prior art (reference only)"
related_topics: [pod-hardware, build-and-run, multiplayer, gauges-hud]
key_terms: [PadRIO, miniconsole, glass-cockpit]
open_questions: [".CTL positional-attribute off-by-one — audit pending (step 2a)"]
open_questions: []
---
# Glass Cockpit — the desktop developer layer
@@ -39,8 +39,15 @@ copied from them.
## Status
- **Step 1 (gates + scaffolding): IN PROGRESS 2026-07-17.** CMake options + defines land with
this file; gated `target_sources` blocks are added as each TU lands.
- **Step 1 (gates + scaffolding): DONE 2026-07-17.** CMake options + defines; 3-config
configure matrix + negative test + defaults build verified.
- **Step 2a (.CTL id audit): DONE 2026-07-17 [T2].** The streamed `.CTL` positional ids landed
every `MechControlsMapper` record ONE MEMBER LATE (our chain starts at 2, the binary's at 3)
— a latent REAL-POD bug (RIO throttle would drive pedalsPosition), masked on dev boxes by the
keyboard bridge. Fixed ungated: ids pinned to binary numbering + id-2 pad + static_assert
locks (`mechmppr.hpp/.cpp`); torso/weapon chains were already aligned. Permanent env-gated
diagnostic: `BT_CTRLMAP_LOG=1` dumps every streamed record's resolved member offset
(`L4CTRL.cpp CreateStreamedMappings`). Full evidence: `docs/GLASS_COCKPIT.md` §2a.
- Step 2 (PadRIO + displays): pending. Secondary displays reuse the EXISTING dev-gauge modes
(dock-bottom `BT_DEV_GAUGES=1`, combined separate window `BT_DEV_GAUGES_WINDOW=1`, overlay
inset `BT_DEV_GAUGES_DOCK=1` — see [[gauges-hud]] + `docs/GAUGE_COMPOSITE.md`); NO new MFD
+6
View File
@@ -43,6 +43,12 @@ The authentic pod throttle path — traced 2026-07 (task #50 throttle-fidelity q
0x11d-1 = 0x11c, name "ThrottlePosition" @0050f28f). Reverse = record [2]: `Button Throttle1
(0x3F, on the throttle handle) → attr 6 ReverseThrust@0x124`. Turn = pedals value-bound in the
ctor (manager+0x44/+0x64 → mapper+0x1b4/+0x1b8).
**Step-2a fix (2026-07-17) [T2]:** these ids are POSITIONAL (`Find(id)` = `index[id-1]`) and
our `MechControlsMapper` chain started one low (`Subsystem::NextAttributeID`==2 vs the
binary's 3) — every streamed record landed one member late (a real-pod landmine: the RIO
throttle scalar drove `pedalsPosition`). Ids are now PINNED to the binary numbering with an
id-2 pad + `static_assert` locks (`mechmppr.hpp/.cpp`); audit tool `BT_CTRLMAP_LOG=1`.
Details: `docs/GLASS_COCKPIT.md` §2a; see [[glass-cockpit]].
4. **Interpretation:** `L4MechControlsMapper::InterpretControls` @004d196c applies the ONLY software
detent — snap to 1.0 when |t1.0| ≤ 0.05 — then `MechControlsMapper::InterpretControls` @004afd10
computes `speedDemand@0x128 = maxSpeed(mech+0x34c) × throttlePosition(0x11c) × scale(mech+0x5c0)`