#!/usr/bin/env python3 """静默多档标定:1ms / 2ms / 4ms,每档先停环再设周期再开环,避免混拍。""" import json, os, subprocess, sys, time, urllib.request ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) LAB = os.path.join(ROOT, "lab", "skip_meter") BASE = "http://127.0.0.1:8090" def post(p, b=None): d = json.dumps(b or {}).encode() r = urllib.request.Request(BASE+p, data=d, headers={"Content-Type":"application/json"}) return json.loads(urllib.request.urlopen(r, timeout=8).read().decode()) def set_prio(level="RealTime"): p = int(subprocess.check_output(["powershell","-NoProfile","-Command","(Get-Process ecat_native).Id"], text=True).strip()) subprocess.check_output(["powershell","-NoProfile","-Command", f"$p=Get-Process -Id {p}; $p.PriorityClass='{level}'; $p.PriorityClass"], text=True) return p def set_period(ms): post("/api/motor/stop") time.sleep(0.2) r = post("/api/motor/period", {"period_ms": ms}) time.sleep(0.2) post("/api/motor/start") time.sleep(0.8) return r def meter(tag, secs=18): r = subprocess.run([sys.executable, os.path.join(ROOT,"scripts","skip_rate_meter.py"), "--tag", tag, "--secs", str(secs)], capture_output=True, text=True, encoding="utf-8", errors="replace") files = sorted([f for f in os.listdir(LAB) if f.startswith(tag+"_") and f.endswith(".json")]) return json.load(open(os.path.join(LAB, files[-1]), encoding="utf-8")) def main(): print("set RealTime") print("pid", set_prio("RealTime")) rows = [] for ms in (1.0, 2.0, 4.0): print(f"\n=== period {ms} ms ===") print(set_period(ms)) time.sleep(2.0) # settle data = meter(f"quiet_{ms:g}ms", 18) row = { "period_ms": ms, "late_per_s": data["late_per_s"], "skip_per_s": data["skip_per_s"], "late_frac_pct": data["late_frac_pct"], "achieved_hz": data["achieved_hz"], "n_late": data["n_late"], "send_stall_frac": data["send_stall_frac"], "rx_stall_frac": data["rx_stall_frac"], "work_p50": data["window_cyc_us"]["work"]["p50"], "rx_p50": data["window_cyc_us"]["rx"]["p50"], "send_p50": data["window_cyc_us"]["send"]["p50"], "work_p90": data["window_cyc_us"]["work"]["p90"], } rows.append(row) print(row) # restore 1ms as user default print("\nrestore period 1.0") print(set_period(1.0)) path = os.path.join(LAB, f"summary_quiet_periods_{int(time.time())}.json") json.dump(rows, open(path,"w",encoding="utf-8"), ensure_ascii=False, indent=2) print("WROTE", path) print(json.dumps(rows, ensure_ascii=False, indent=2)) if __name__ == "__main__": main()