# -*- coding: utf-8 -*- """Decode obs_samples.txt (openocd mrw words, V0.1.2 layout) into quantities.""" import struct import sys def f(w): return struct.unpack("> (8 * byte)) & 0xFF path = sys.argv[1] if len(sys.argv) > 1 else "obs_samples.txt" rows = [] for ln in open(path, encoding="utf-8"): parts = ln.split() if len(parts) != 11 or not parts[0].isdigit(): continue v = parts rows.append({ "t": int(v[0]) / 1000.0, "stash_T": f(v[1]), "stash_I": f(v[2]), "fault": u8(v[3], 0), "prev": f(v[4]), "integ": f(v[5]), "duty": u8(v[6], 1), "ramp": f(v[7]), "tgt": f(v[8]), "en": u8(v[9], 0), "temp": f(v[10]), }) if not rows: print("no rows") sys.exit(1) t0 = rows[0]["t"] print(f"{'t':>7} {'temp':>7} {'tgt':>6} {'ramp':>7} {'duty%':>5} {'integ':>8} {'prev':>7} {'fl':>3} {'en'}") for r in rows: print(f"{r['t']-t0:7.1f} {r['temp']:7.2f} {r['tgt']:6.1f} {r['ramp']:7.2f} " f"{r['duty']*5:5d} {r['integ']:8.2f} {r['prev']:7.2f} {r['fault']:3d} {r['en']}") print("\n-- events (duty/fault/integ-zero 变化) --") last = None for r in rows: key = (r["fault"], r["duty"], r["integ"] == 0.0) if last is not None and key != last[0]: print(f"t={r['t']-t0:7.1f}s fault={r['fault']} duty={r['duty']*5}% integ={r['integ']:.2f} " f"temp={r['temp']:.2f}") last = (key, r) n_fault = sum(1 for r in rows if r["fault"] > 0) temps = [r["temp"] for r in rows] ints = [r["integ"] for r in rows if r["en"]] print(f"\nsamples={len(rows)} fault_beats={n_fault} temp[{min(temps):.2f},{max(temps):.2f}] " f"integ[{min(ints) if ints else 0:.1f},{max(ints) if ints else 0:.1f}] (en 段)")