feat(ecat): 启动后把 ecat_native 提到 RealTime;跳拍优化实验脚本与报告
- esp32_server: Popen 后外部 SetPriorityClass(RT/High),native 自设会被钳成 High - 入库 skip_* 标定/实验脚本与 REPORT_ecat_skip_opt_20260917 - 前端 WIP:layout/app/polling/boot_ecat/index - 不含 lab/skip_meter 原始采样与 preview 截图
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user