Claude: Abweichungen bei 3 Kameras zählen

This commit is contained in:
chk
2026-06-03 06:34:26 +02:00
parent 6964f19b28
commit 5c71c00fb4
1397 changed files with 11773 additions and 11317 deletions

View File

@@ -26,6 +26,7 @@ import itertools
import json
import random
import re
import shutil
import subprocess
import sys
from pathlib import Path
@@ -101,7 +102,10 @@ def main() -> None:
ap.add_argument("--seed", type=int, default=42)
ap.add_argument("--robot", default=str(ROOT / "data" / "robot" / "robot.json"))
ap.add_argument("--force", action="store_true",
help="Existierende robot_state.json überschreiben")
help="Vorhandene robot_state.json neu rechnen (Pipeline erneut laufen)")
ap.add_argument("--clean", action="store_true",
help="Zwischenergebnisse vorher löschen und komplett neu rechnen. "
"Mit --scenes nur diese Szenen, ohne --scenes alles (inkl. Ergebnisdateien).")
ap.add_argument("--out", default=str(RESULTS_DIR / "camera_study.json"))
ap.add_argument("--csv", default=str(RESULTS_DIR / "camera_study.csv"))
args = ap.parse_args()
@@ -110,6 +114,7 @@ def main() -> None:
RESULTS_DIR.mkdir(parents=True, exist_ok=True)
sim_dir = ROOT / "data" / "simulation"
study_root = ROOT / "data" / "camera_study"
scenes = discover_scenes(sim_dir)
if args.scenes:
want = {s if s.startswith("Scene") else f"Scene{s}" for s in args.scenes}
@@ -118,6 +123,25 @@ def main() -> None:
print("[ERROR] Keine Szenen mit pose.json und render_*.png gefunden.")
sys.exit(1)
# --clean: Zwischenergebnisse (und bei vollem Reset auch die Aggregat-Dateien) entfernen.
if args.clean:
if args.scenes:
for s in scenes:
d = study_root / s
if d.exists():
shutil.rmtree(d)
print(f"[CLEAN] entfernt {d}")
else:
if study_root.exists():
shutil.rmtree(study_root)
print(f"[CLEAN] entfernt {study_root}")
for f in (Path(args.out), Path(args.csv)):
if f.exists():
f.unlink()
print(f"[CLEAN] entfernt {f}")
# Nach dem Löschen muss die Pipeline zwangsläufig neu laufen.
args.force = True
print(f"[INFO] Szenen: {scenes}")
print(f"[INFO] Seed={args.seed} Samples/k={args.samples}\n")
@@ -168,32 +192,51 @@ def main() -> None:
"max_abs_deg": s.get("max_abs_deg"),
"mean_abs_mm": s.get("mean_abs_mm"),
"max_abs_mm": s.get("max_abs_mm"),
"wrist_error_mm": s.get("wrist_error_mm"),
"finger_error_mm": s.get("finger_error_mm"),
"n_unobservable": s.get("n_unobservable"),
}
all_results.append(row)
errs.append(row["mean_abs_deg"] or 0.0)
fe = row["finger_error_mm"]
fe_str = f" finger={fe:.2f}mm" if fe is not None else ""
print(f" {label}: mean={row['mean_abs_deg']:.3f}° max={row['max_abs_deg']:.3f}°{fe_str}")
we, fe = row["wrist_error_mm"], row["finger_error_mm"]
we_str = f"{we:.2f}mm" if we is not None else "n/a"
fe_str = f"{fe:.2f}mm" if fe is not None else "n/a"
print(f" {label}: mean={row['mean_abs_deg']:.3f}° "
f"wrist={we_str} finger={fe_str} unobs={row['n_unobservable']}")
if errs:
print(f" k={k} Zusammenfassung: mean={mean(errs):.3f}° "
f"min={min(errs):.3f}° max={max(errs):.3f}°")
# Ergebnisse schreiben
Path(args.out).write_text(json.dumps(all_results, indent=2), encoding="utf-8")
# Ergebnisse schreiben — andere Szenen erhalten (mergen statt überschreiben),
# damit ein Lauf über einzelne Szenen die übrigen nicht aus der Aggregat-Datei kippt.
out_path = Path(args.out)
processed = set(scenes)
merged: list[dict] = []
if out_path.exists():
try:
existing = json.loads(out_path.read_text(encoding="utf-8"))
merged = [r for r in existing if r.get("scene") not in processed]
except (json.JSONDecodeError, OSError):
merged = []
merged.extend(all_results)
merged.sort(key=lambda r: (r["scene"], r["k"], r["subset"]))
out_path.write_text(json.dumps(merged, indent=2), encoding="utf-8")
with open(args.csv, "w", encoding="utf-8") as f:
f.write("scene,k,subset,mean_abs_deg,max_abs_deg,mean_abs_mm,max_abs_mm,finger_error_mm\n")
for r in all_results:
f.write("scene,k,subset,mean_abs_deg,max_abs_deg,mean_abs_mm,max_abs_mm,"
"wrist_error_mm,finger_error_mm,n_unobservable\n")
for r in merged:
f.write(f"{r['scene']},{r['k']},{r['subset']},"
f"{r['mean_abs_deg'] or ''},"
f"{r['max_abs_deg'] or ''},"
f"{r['mean_abs_mm'] or ''},"
f"{r['max_abs_mm'] or ''},"
f"{r['finger_error_mm'] or ''}\n")
f"{r['wrist_error_mm'] if r['wrist_error_mm'] is not None else ''},"
f"{r['finger_error_mm'] if r['finger_error_mm'] is not None else ''},"
f"{r['n_unobservable'] if r['n_unobservable'] is not None else ''}\n")
print(f"\n[DONE] {len(all_results)} Ergebnisse -> {args.out}")
print(f"\n[DONE] {len(all_results)} neu, {len(merged)} gesamt -> {args.out}")
if __name__ == "__main__":