Locomotion: wire the AUTHENTIC per-mech turn-rate lerp (task #64b)
The master-perf disasm (0x4aa3d3-0x4aa4ff) computes the yaw rate as lerp(walkingTurnRate@0x574, runningTurnRate@0x578) by ground speed, not a constant. Wired it into the drive, replacing the bring-up constant kDriveTurnRate: - walkingTurnRate/runningTurnRate are now REAL named members. The ctor's `Wword(0x15d)/(0x15e) = model->...TurnRate * DegreesToRadians` writes were NO-OPS -- Wword() returns a shared static scratch cell, so the rates were silently discarded. Now stored + read by name. - The drive (mech4.cpp) computes authTurnRate: base = walkingTurnRate; above reverseSpeedMax(0x538) lerp walk->run across [walkStride 0x534 .. topSpeed 0x34c] with an over-run falloff runningTurnRate/t^2; clamp >=0; zeroed in the death/limbo/airborne leg states (1/2/3) or when deathAnimationLatched(0x650) is set. Falls back to kDriveTurnRate if the model gave no rates. The lerp is a RUN-speed refinement -- below reverseSpeedMax (walk / turn-in-place) the rate is the constant walkTR base; runningTurnRate < walkingTurnRate (a running mech is less maneuverable). Verified headless (DEV mech, BT_TURN_LOG): walkTR 1.309 rad/s (75 deg/s), runTR 0.873 (50 deg/s), turn-in-place + walk yaw at walkTR, no crash. [T1 logic / T2 runtime] Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
35c30bda67
commit
a83995a755
+15
-9
@@ -129,15 +129,21 @@ real logic. `animationClips[4]` = the `trn`/`trni` clip (loaders 13767/13971). P
|
||||
was the body channel leaking out-of-phase joints into the rendered skeleton every walk cycle (mj=1);
|
||||
fixed at the source by `AdvanceBodyAnimation(dt, mj=0)` (see two-channel section). With mj=0 the
|
||||
authentic cut renders cleanly.
|
||||
- **Turn rate (disasm 0x4aa3d3–0x4aa4ff) [T1]:** `spd = |linearSpeed|`; base `turnRate =
|
||||
walkingTurnRate`(mech+0x574, rad/s). If `spd ≥ reverseSpeedMax`(0x538): `t = (spd − walkStride
|
||||
0x534)/(topSpeed 0x34c − walkStride)`; `turnRate = t≤1 ? lerp(walkingTurnRate, runningTurnRate
|
||||
0x578, t) : runningTurnRate/t²` (over-run falloff). `turnRate = max(0, turnRate)`. Then
|
||||
`angularVelocity`(0x1d4) `= turnDemand(mapper+0x12c) × turnRate`, ZEROED if legState∈{1,2,3} or
|
||||
latch 0x650 set. ⚠ **Not yet wired into the port** — the bring-up drive still yaws at the constant
|
||||
`kDriveTurnRate` (mech4.cpp:2618/2628/3062); `walkingTurnRate`/`runningTurnRate` are stored
|
||||
(mech.cpp:1334-5, Wword(0x15d)/(0x15e)→0x574/0x578, deg→rad) but only the ANIMATION dispatcher is
|
||||
wired. Wiring the rate lerp is the next locomotion polish item.
|
||||
- **Turn rate (disasm 0x4aa3d3–0x4aa4ff) [T1] — WIRED (task #64b):** `spd = |linearSpeed|`; base
|
||||
`turnRate = walkingTurnRate`(mech+0x574, rad/s). If `spd ≥ reverseSpeedMax`(0x538): `t = (spd −
|
||||
walkStride 0x534)/(topSpeed=reverseStrideLength 0x34c − walkStride)`; `turnRate = t≤1 ?
|
||||
lerp(walkingTurnRate, runningTurnRate 0x578, t) : runningTurnRate/t²` (over-run falloff). `turnRate =
|
||||
max(0, turnRate)`. Then yaw `= turnDemand(mapper+0x12c) × turnRate`, ZEROED if legState∈{1,2,3} or
|
||||
the death latch (`deathAnimationLatched`@0x650) is set. **Note the lerp is a RUN-speed refinement**
|
||||
— below `reverseSpeedMax` (walk / turn-in-place) turnRate is the constant walkTR base; the walk→run
|
||||
interpolation only engages above it, and `runningTurnRate < walkingTurnRate` (a running mech is less
|
||||
maneuverable). Port: `walkingTurnRate`/`runningTurnRate` are now REAL named members (mech.hpp, set
|
||||
from the model deg→rad at mech.cpp:1334-5 — the old `Wword(0x15d/0x15e)` writes were no-ops into a
|
||||
static scratch bank, so the values were silently discarded). The drive (mech4.cpp ~2617) computes
|
||||
`authTurnRate` per the formula and yaws by it instead of the bring-up constant `kDriveTurnRate`
|
||||
(kept as the fallback when a model supplies no rates). Diagnostic: `BT_TURN_LOG` → `[turnrate]`.
|
||||
Verified headless (DEV mech): walkTR 1.309 rad/s (75°/s), runTR 0.873 (50°/s); turn-in-place + walk
|
||||
yaw at walkTR, no crash. [T1 logic / T2 runtime]
|
||||
- **Entry** (leg Standing case, disasm 0x4aa505 [T1]): arm trn when TURNING (`|angVel|>1e-4`, port
|
||||
proxy = turnDemand deadband ±0.05) AND `0 ≤ spd ≤ standSpeed` (the FULL sub-walk range — CORRECTS the
|
||||
`0.25·standSpeed` stand-in) AND `turnCapable`(hasCrashSet@0x588). **LOCKSTEP: arms BOTH channels the
|
||||
|
||||
Reference in New Issue
Block a user