BT410 Phase 5.3.2: DRIVABLE mech -- authentic control interpretation + locomotion

The mech now drives from the authentic control chain (faithful route). Verified
headlessly: full throttle -> walks straight at top speed (30 u/s) along heading;
throttle+turn -> walks a circle (radius = speed/turnRate); neutral -> holds pose;
zero Fail.

MechControlsMapper::InterpretControls (mechmppr.cpp @004afd10) -- installed as the
mapper's per-frame Performance (roster slot 0, ticks before the mech):
- speedDemand = topSpeed*throttle*fwdScale (reverse inverts); soft stick (square)
  / pedal (cube) response; Basic=stick turn, Std/Vet=pedal turn; speed clamped
  while turning hard. Reads owner stride via Mech accessors.
- BT_FORCE_THROTTLE/BT_FORCE_TURN dev hooks for headless verification.

Mech::Simulate drive -- consumes the mapper demands:
- accelerate currentBodySpeed toward speedDemand (maxBodyAcceleration);
- authTurnRate = lerp(walkingTurnRate, runningTurnRate) by ground speed + over-run
  falloff (mech4.cpp master-perf @0x4aa3d3);
- integrate heading via Quaternion::Add(prevPose, (0,turn*rate*dt,0));
- facing = world -Z basis (GetFromAxis(Z_Axis)); worldLinearVelocity = facing*spd;
- integrate position (increment-1 core).

MECH.HPP: 9 named locomotion members out of reservedState (now [211]) --
walking/runningTurnRate, reverse/walkStrideLength, reverseSpeedMax,
forwardThrottleScale, maxBodyAcceleration, body/currentBodySpeed. BRING-UP
DEFAULTS (authentic values come from the model resource + LoadLocomotionClips --
next refinement).

Deferred: gait-clip-exact advance + leg anim (needs animation subsystem/renderer),
model-resource sourcing, terrain drop, torso/free-look aim, telemetry filters.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-21 14:46:30 -05:00
co-authored by Claude Fable 5
parent 859529d6f2
commit ebf0d8c23f
6 changed files with 398 additions and 12 deletions
@@ -0,0 +1,45 @@
# MECHMPPR.CPP / .HPP — reconstruction notes
`MechControlsMapper` (: Subsystem) is the mech's control-input subsystem,
installed at roster slot 0 via `Mech::SetMappingSubsystem`. It publishes the
control-input attributes (StickPosition..PilotArray, IDs 30x16) that the
streamed control mappings bind to, and — as of Phase 5.3 — interprets those raw
inputs into the locomotion/aim demands the mech drive consumes.
## Reconstructed
- The attribute table + AttributeIndex + shared-data statics (earlier wave).
- The ctor: primes the published inputs to neutral and (Phase 5.3) installs
`InterpretControls` as the per-frame Performance.
- `InterpretControls(Scalar)` — the per-frame control interpretation
(mechmppr.cpp @004afd10, authentic demand math):
- throttle → forward speed: `speedDemand = topSpeed · throttle · fwdScale`
(reverse thrust inverts and drops the forward scale). `topSpeed`/`walkSpeed`
are read from the owner via `Mech::GetReverseStrideLength()/GetWalkStrideLength()`.
- soft response: square the stick yaw (sign preserved), cube the pedals.
- Basic mode: stick yaw = `turnDemand`; Standard/Veteran: pedals = `turnDemand`.
- speed clamp while turning hard (`max_turn` ramps topSpeed → walkSpeed by
|turnDemand|); VeteranMode has no clamp.
- Demand accessors `GetSpeedDemand()/GetTurnDemand()` (read by `Mech::Simulate`).
- `GetMech()` = `(Mech *)GetEntity()`.
The mapper ticks in the engine's `Entity::PerformAndWatch` roster walk (slot 0),
which runs BEFORE the mech's own Performance (`Simulation::PerformAndWatch` at
the tail), so the demands are same-frame — no input latency.
## DEV hook (headless verification)
`BT_FORCE_THROTTLE` / `BT_FORCE_TURN` override the pushed raw inputs (the RIO/
keyboard aren't present in the headless smoke test), so the demand math + mech
drive are exercisable without hardware. `BT_MECH_LOG` prints a 1 Hz `[mppr]`
demand trace. Verified: `throttle=1.0` → speedDemand=30; `throttle=0.3,turn=1.0`
→ the mech walks a circle; neutral → 0. See MECH.NOTES.md (Phase 5.3 inc 2).
## Deferred (the aiming wave)
The torso/free-look half of the authentic InterpretControls is not yet
reconstructed: the torso analog axes (`Torso::SetAnalogElevationAxis/
SetAnalogTwistAxis`), HUD free-aim slew (`HUD::SetFreeAimSlew`), the recenter
command, and the look/eyepoint commit (`BTCommitLookState`). These are the
aiming/camera surface, separate from locomotion; they come with the
Torso/HUD/eyepoint wave.