MP: FIX walk+turn peer skip -- incremental heading integration + scalar yaw mirror (task #50)
The user-keyboard regime (steering WHILE walking) fired BOTH dense record streams at once and exposed the last divergence: our peer heading used the engine Mover::DeadReckon slerp-toward-projection, whose angular projection reads the SHARED lastUpdate/nextUpdate timebase. The dense type-0 pose stream resets that timebase every frame while walking while RESTORING a stale orientation (the authentic case-0 strip, verified against FUN_004a1232 case 0) -- so the angular target barely advances from a stale base and the slerp DRAGS the heading back every frame. Measured: peer yaw advancing at ~40% rate with half the frames stepping BACKWARD. Pure-spin and pure-walk tests never showed it (single stream) -- why autonomous looked smooth while keyboard play skipped. AUTHENTIC FIX (decomp FUN_004ab1c8 -> FUN_004ab188/FUN_00409f58): the original replicant integrates its heading INCREMENTALLY from the CURRENT pose -- exact rotation of (replicated yaw rate * dt) composed on each frame -- and re-anchors on type-4 receipt. It never slerps toward a projected angular target. - mech4.cpp peer branch: save heading, let DeadReckon own LINEAR only, then integrate heading incrementally (ReconQuatIntegrate); on angSyncLatch (new type-4) re-anchor to updateOrigin. - mech.hpp/mech.cpp: angSyncLatch member (angular analog of poseSyncLatch), armed by ReadUpdateRecord case 4. - SCALAR peer-yaw mirror (angMirrorYaw/Rate/Time, re-based in the type-4 writer): replaces the quaternion projectedOrigin mirror for the ANGLE deadband -- the old one was recomputed each frame by the master's own reckoner from timing it does not control and false-fired in pi-waves (measured maxAng~=pi bursts -> periodic resync floods). - Dense-rot type-4 send REMOVED (was masking the old crude projection; not authentic; churned the shared horizon). Orientation now rides the sparse angle/velocity deadband resyncs exactly as the binary's. Verified live-autonomous: - pure spin: 59/59 perfectly regular peer yaw steps; master resyncs 0/s with mirror drift ~5e-7 (records near-silent, authentic sparse model). - walk+turn circle (the user regime): peer sim yaw monotonic at exactly the master's rate (0.00556/frame @ 0.327 rad/s), no backward steps, no stalls. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
b7be95b584
commit
d78e77bf84
@@ -915,6 +915,10 @@ Mech::Mech(
|
||||
Wword(0xe6) = 0;
|
||||
poseSyncLatch = 0; // @0x77c (was absorbed Wword(0x1df))
|
||||
heatLevelSnapshot = 0; // @0x780 (type-7 deadband baseline)
|
||||
angMirrorYaw = 0.0f; // scalar peer-yaw mirror (port addition)
|
||||
angMirrorRate = 0.0f;
|
||||
angMirrorValid = 0;
|
||||
angSyncLatch = 0; // peer heading re-anchor (type-4 receive)
|
||||
Wword(0xfe) = Wword(0xfc) = Wword(0x105) = 0;
|
||||
mechName.Copy(&DAT_004e0f8c); // FUN_00408e90(this+0xd8,"")
|
||||
Wword(0x160) = Wword(0x15f) = 0;
|
||||
@@ -1893,6 +1897,7 @@ void
|
||||
}
|
||||
}
|
||||
bodyTargetSpeed = record->speedDemand; // rec+0x28
|
||||
angSyncLatch = 1; // arm the peer heading re-anchor
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2114,6 +2119,15 @@ void
|
||||
// master perf; the writer-side re-base is the coherent reconstruction.)
|
||||
projectedOrigin.angularPosition = localOrigin.angularPosition;
|
||||
projectedVelocity.angularMotion = localVelocity.angularMotion;
|
||||
// SCALAR peer-yaw mirror re-base (see mech.hpp): what the peer will now
|
||||
// extrapolate -- this yaw, at this rate, from this moment.
|
||||
{
|
||||
YawPitchRoll _my; _my = localOrigin.angularPosition;
|
||||
angMirrorYaw = (Scalar)_my.yaw;
|
||||
angMirrorRate = (Scalar)localVelocity.angularMotion.y;
|
||||
angMirrorTime = lastPerformance;
|
||||
angMirrorValid = 1;
|
||||
}
|
||||
record->speedDemand = speedDemand; // rec+0x28
|
||||
bodyTargetSpeed = speedDemand;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user