Gyro: BT_GYRO_TRACE per-frame integrator trace -- oscillation verified vs authored constants (task #56)
25-hit MP autofire trace: kick -> damped oscillation -> settle, peaks well inside clamps, no NaN/drift; measured Y:X frequency ratio 7.75x matches sqrt(springK.y/springK.x) exactly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
8af278a3f5
commit
1ace2e3cb4
@@ -0,0 +1,56 @@
|
||||
import re, sys
|
||||
import matplotlib
|
||||
matplotlib.use("Agg")
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
frames, eyes, bodies = [], [], []
|
||||
hits = [] # (frame_at_hit, t, p, y, v)
|
||||
last_f = None
|
||||
for line in open("../content/gtrace_a.log", encoding="utf-8", errors="replace"):
|
||||
m = re.match(r"\[gtrace\] g=\S+ f=(\d+) eye=(\S+) (\S+) (\S+) body=(\S+) (\S+) (\S+)", line)
|
||||
if m:
|
||||
last_f = int(m.group(1))
|
||||
frames.append(last_f)
|
||||
eyes.append(tuple(float(m.group(i)) for i in (2,3,4)))
|
||||
bodies.append(tuple(float(m.group(i)) for i in (5,6,7)))
|
||||
continue
|
||||
m = re.match(r"\[gtrace\] g=\S+ HIT t=(\S+) p=(\S+) y=(\S+) v=(\S+)", line)
|
||||
if m:
|
||||
hits.append((last_f, *[float(m.group(i)) for i in (1,2,3,4)]))
|
||||
|
||||
print(f"trace frames: {len(frames)}, hits: {len(hits)}")
|
||||
print(f"frame range: {frames[0]}..{frames[-1]}")
|
||||
|
||||
# stats per volley: peak |eye|, settle
|
||||
import math
|
||||
mag = [math.sqrt(e[0]**2+e[1]**2+e[2]**2) for e in eyes]
|
||||
peak = max(mag); print(f"peak |eyePos| = {peak:.4f} u (clamp legal range +-0.1/0.15 per axis)")
|
||||
peakY = max(abs(e[1]) for e in eyes); peakX = max(abs(e[0]) for e in eyes); peakZ = max(abs(e[2]) for e in eyes)
|
||||
print(f"peak per-axis |x|={peakX:.4f} |y|={peakY:.4f} |z|={peakZ:.4f}")
|
||||
bad = [e for e in eyes if any(x != x for x in e)]
|
||||
print(f"NaN frames: {len(bad)}")
|
||||
|
||||
# oscillation period of Y (zero crossings) in the first big volley
|
||||
ys = [e[1] for e in eyes]
|
||||
cross = [frames[i] for i in range(1,len(ys)) if ys[i-1]*ys[i] < 0 and frames[i]-frames[i-1] == 1]
|
||||
if len(cross) > 3:
|
||||
gaps = [b-a for a,b in zip(cross, cross[1:]) if b-a < 30]
|
||||
if gaps: print(f"Y half-period ~{sum(gaps)/len(gaps):.1f} frames (full period ~{2*sum(gaps)/len(gaps):.1f})")
|
||||
|
||||
# settle check: gap in frames = eye at rest (below 1e-9 magnitude threshold not logged)
|
||||
gapct = sum(1 for a,b in zip(frames, frames[1:]) if b-a > 5)
|
||||
print(f"rest gaps (>5 frames unlogged = settled to ~0): {gapct}")
|
||||
|
||||
fig, ax = plt.subplots(2, 1, figsize=(16, 8), sharex=True)
|
||||
ax[0].plot(frames, [e[0] for e in eyes], '.', ms=2, label='eye X (lateral)')
|
||||
ax[0].plot(frames, [e[1] for e in eyes], '.', ms=2, label='eye Y (vert)')
|
||||
ax[0].plot(frames, [e[2] for e in eyes], '.', ms=2, label='eye Z (fore/aft)')
|
||||
for h in [h for h in hits if h[0] is not None]: ax[0].axvline(h[0], color='r', alpha=.25, lw=.8)
|
||||
ax[0].legend(); ax[0].set_ylabel('eyePosition (u)'); ax[0].set_title('Gyro eye spring — red lines = hits received')
|
||||
ax[1].plot(frames, [b[0] for b in bodies], '.', ms=2, label='body X (pitch)')
|
||||
ax[1].plot(frames, [b[1] for b in bodies], '.', ms=2, label='body Y')
|
||||
ax[1].plot(frames, [b[2] for b in bodies], '.', ms=2, label='body Z (roll)')
|
||||
for h in [h for h in hits if h[0] is not None]: ax[1].axvline(h[0], color='r', alpha=.25, lw=.8)
|
||||
ax[1].legend(); ax[1].set_ylabel('bodyOrientation (rad)'); ax[1].set_xlabel('frame')
|
||||
plt.tight_layout(); plt.savefig("GYRO_TRACE.png", dpi=90)
|
||||
print("wrote GYRO_TRACE.png")
|
||||
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
cd /c/git/bt411/content || exit 1
|
||||
rm -f gtrace_a.log gtrace_b.log
|
||||
BT_LOG=gtrace_a.log BT_AFFINITY=0x1 BT_GYRO_LOG=1 BT_GYRO_TRACE=1 BT_START_INSIDE=1 ../build/Debug/btl4.exe -egg MP.EGG -net 1501 &
|
||||
sleep 2
|
||||
BT_LOG=gtrace_b.log BT_AFFINITY=0x2 BT_AUTOFIRE=1 ../build/Debug/btl4.exe -egg MP.EGG -net 1601 &
|
||||
sleep 8
|
||||
exec python ../tools/btconsole.py MP.EGG 127.0.0.1:1501 127.0.0.1:1601
|
||||
Reference in New Issue
Block a user