Commit Graph

3 Commits

Author SHA1 Message Date
a3f14710a4 re(flight): clean pitch sweep -- magnitudes agree, the interpolation law does not
Fresh flight, row pinning CONFIDENT (margin 0.413), one sweep and nothing before
it. axis_probe now REFUSES to measure on a WEAK pin (ALLOW_WEAK_PIN=1 overrides)
since it is a precondition, not a warning: roll is immune to the up/right
labelling but pitch and yaw are not.

Clock x1.26. Binned by speed, both in game units, against the linear
interpolation of AV_PitchPlus_Min 150 (at MinimumVelocity 100) to _Max 70 (at
MaximumVelocity 1200):

    speed ~435   measured 100.8   predicted 125.6
    speed ~572            113.8             115.7
    speed ~709            126.3             105.7
    speed ~846             83.1              95.7
    speed ~983             72.7              85.8

Supported: the magnitudes (73-126 measured vs 86-126 predicted) and a falling
high-speed end. NOT supported: the interpolation law. Scatter is +-25%, the two
fastest bins hold 1 and 2 windows (the first moments before the speed bled), and
the slowest bin misses in the wrong direction.

The flaw is structural, not statistical: a sweep DRIVEN by the speed bleeding
cannot dwell at either extreme, which is exactly where the law is most testable.

What would settle it: hold a settled throttle and pitch for ~1 SECOND, so speed
barely moves inside the burst and each burst gives one honest (speed, rate) point;
repeat at LT / neutral / RT for three clean points at known speeds. Recorded as
the next design rather than attempted as a fifth variation of the same sweep.
2026-08-13 23:12:50 +00:00
dfa769420d re(flight): axis probe pins the rows and checks liveness; fly_stage waits, not sleeps
Both fixes the previous run's caveats asked for, plus one the run itself forced.

axis_probe.py now:
 - PINS which non-forward row is up and which is right, by comparing world-Y
   across the rows in level flight, and says CONFIDENT or WEAK. entities2
   measures row 2 = forward against velocity, but the other two were labelled by
   the D3D convention, and yaw/pitch SWAP if that is wrong -- so the previous
   run's last two columns were named on an assumption.
 - checks the craft is ALIVE between inputs, and ABORTS with a message instead of
   reporting the clean zeros a destroyed craft produces. The first run ended on
   GAME OVER and only said so afterwards.
 - measures the UNKNOWN inputs (rx, ry, LB, RB) first while the craft is healthy,
   keeping the established lx/ly as controls at the end.

fly_stage.sh now WAITS for the stage load instead of sleeping a fixed guess. The
fixed sleeps worked until they didn't: one load ran long, the script pressed START
into a black screen, and every later step went to nothing while the screenshots
recorded a plausible-looking sequence. It now polls for a non-black frame and
aborts with a pointer to the log if the load hangs (PhysicalHeap::Release
failures) rather than continuing blind.

The probe itself did not run this iteration -- the stage load hung -- so there is
no new axis data, and none is claimed.
2026-08-13 22:22:19 +00:00
5f3c618b51 re(flight): axis probe -- lx is roll, ly drives one clean axis, rest not trustworthy
New probe (axis_probe.py) decomposes every held input into all THREE rotation
components at once, instead of measuring one axis at a time through a non-forward
matrix row -- the flaw that once made roll and pitch produce identical numbers.
For previous rows (f,u,w): roll = atan2(u.w_old, u.u_old), and forward's rotation
toward each of the other two rows gives the remaining pair.

Stage 02, file pad, full deflection on exactly one channel at a time:

    lx+   roll 209.8   b 0.9    c 10.1     deg/wall-s
    ly+   roll   0.0   b 154.1  c  0.0
    rx+   roll   0.0   b 0.0    c  0.0
    ry+   roll 161.1   b 87.0   c 37.1
    LB/RB all zero

What this supports: lx = ROLL, cleanly (~0 on both other channels), agreeing with
the independent roll measurement. ly drives ONE axis, cleanly.

What it does NOT support, and I am not claiming:
 - WHICH axis ly drives. entities2 measures row 2 = forward against velocity, but
   rows 0 and 1 are labelled up/right by the D3D convention rather than by
   evidence, and yaw/pitch SWAP if that is wrong. Roll is immune (rotation of
   either non-forward row in their shared plane is roll either way).
 - anything about rx/ry/LB/RB. The run ended on GAME OVER: full-deflection spin in
   a live combat mission gets the craft destroyed, and the only symptom is "0
   player candidates" AFTERWARDS, so late rows may be post-death. rx+ reading all
   zeros and ry+ reading mixed are exactly what a dying craft would produce.

So "yaw: no input found" is NOT resolved. Both gaps are now written into the
probe's header with what would fix them: a liveness check between inputs, and
pinning up-vs-right against world Y.
2026-08-13 22:10:23 +00:00