#!/usr/bin/env python3
"""log25_runs_table.py — 2026-11-09 に撮ったお手本 (record_teach_demo.py) 27 本を 1 本 1 行の表にする
(LOG463・フィジカルAI研究室 Log#25).

読むだけ:
  runs/run_pick_place/run_0001_20261109_*/run_0001_20261109_*.json   (試行 JSON: 人の y/n・区間ごとの到達・ブロックの位置)
  runs/run_pick_place/run_0001_20261109_*/recording/states.csv       (段階の時刻・読んだ角度・爪の命令)
  runs/run_pick_place/run_0001_20261109_*/recording/currents.csv     (爪と肩の電流. 依頼 121)
  lab/Log25/grasp_depth.csv   (pi05/grasp_depth.py --csv の出力. 閉じる直前と閉じて 1.0 秒後のはみ出し・爪の値)
書く: このファイルと同じフォルダの runs_table.csv だけ.

判定 (使う/外す) の決まり:
  1. PICK の区間 (ブロックの上 → つかむ姿勢) が 5 秒より長くかかった本は「爪がブロックに乗った」として外す
     (普段は 1.9〜2.2 秒. 乗った本は到達の許容 3.0° に入るまで, 到達待ちの上限 8 秒近くかかった)
  2. 閉じて 1.0 秒後のはみ出しが 24px を超えた本は「浅い」として外す (grasp_depth.py の線. LOG460・依頼 117)
  3. 教え直す前の記録 (drag_v2_20221013_144348.json) で撮った本は, 位置 1 の比べる相手として残すが学習には使わない

Mac で動かすとき:  python3 log25_runs_table.py
(パスは R2R2R_DATA で変えられる. 既定 /Volumes/KIOXIA/r2r2r-data)
"""
import csv, json, os, statistics
from pathlib import Path

DATA = Path(os.environ.get("R2R2R_DATA", "/Volumes/KIOXIA/r2r2r-data"))
RUNS = DATA / "runs/run_pick_place"
HERE = Path(os.environ.get("LOG25_DIR", DATA / "lab/Log25"))
TEACH_POS = {"drag_v2_20221013_144348.json": 1, "drag_v2_20261109_094222.json": 1,
             "drag_v2_20221013_230205.json": 2}
SNAG_SEC = 5.0
LINE_PX = 24.0


def main():
    gd = {r["run"]: r for r in csv.DictReader(open(HERE / "grasp_depth.csv"))}
    rows = []
    for p in sorted(x for x in RUNS.glob("run_0001_20261109_*") if x.is_dir()):
        s = p.name
        tj = json.load(open(p / f"{s}.json"))
        teach = tj["teach"]["file"]
        seg = [g for g in tj["segments"] if g.get("to_name") == "PICK"][0]
        st = list(csv.DictReader(open(p / "recording/states.csv")))
        t_pick = [float(r["ts"]) for r in st if r["event_type"] == "stage" and r["stage"] == "PICK"][0]
        t_close = [float(r["ts"]) for r in st if r["event_type"] == "gripper_cmd" and r["gripper_state"] == "1"][0]
        cur = list(csv.DictReader(open(p / "recording/currents.csv")))
        sh = [int(r["r2_69"]) for r in cur if t_pick < float(r["ts"]) < t_close and r["r2_69"]]
        g = gd[s]
        after = float(g["after_px"]) if g["after_px"] else float("nan")
        arr = seg["arrival_actual"]
        if seg["segment_elapsed_sec"] > SNAG_SEC:
            use, reason = "外す", "爪がブロックに乗った (PICK の区間 %.1f 秒)" % seg["segment_elapsed_sec"]
        elif not (after <= LINE_PX):
            use, reason = "外す", "浅い (閉じて 1.0 秒後 %.1fpx > %gpx)" % (after, LINE_PX)
        else:
            use, reason = "使う", ""
        if teach == "drag_v2_20221013_144348.json":
            use, reason = "外す", (reason + " / " if reason else "") + "教え直す前の記録"
        rows.append(dict(
            run=s, position=TEACH_POS.get(teach, ""), teach=teach,
            pick=tj["judgments"]["pick"]["verdict"], place=tj["judgments"]["place"]["verdict"],
            before_px=g["before_px"], after_px=g["after_px"], hand_suspect=g["hand_suspect"],
            grip_max=g["grip_current_max"], grip_median=g["grip_current_median"],
            pick_segment_sec=seg["segment_elapsed_sec"], pick_to_close_sec=round(t_close - t_pick, 2),
            pick_arrival_max_delta_deg=seg["arrival_max_delta_deg"],
            j1_arrived=arr[1], j2_arrived=arr[2], j4_arrived=arr[4],
            shoulder_lo_during_pick="/".join(map(str, sorted(set(sh)))),
            block_dist_from_base_mm=tj["positions_before_replay"].get("block_dist_from_base_mm"),
            block_moved_mm=tj["block_move_check"].get("dist_mm"),
            use=use, reason=reason))
    with open(HERE / "runs_table.csv", "w", newline="") as f:
        w = csv.DictWriter(f, fieldnames=list(rows[0]))
        w.writeheader(); w.writerows(rows)
    for r in rows:
        print(",".join(str(v) for v in r.values()))
    for pos in (1, 2):
        u = [r for r in rows if r["position"] == pos and r["use"] == "使う"]
        print(f"位置{pos}: 使う {len(u)} 本 / 撮った {sum(1 for r in rows if r['position'] == pos)} 本")


if __name__ == "__main__":
    main()
