---
title: "フィジカルAI研究室を作る Log#26 | 偏りなく学ばせるため、mechArm 270 のお手本を5か所10本に"
slug: even-ten-demos-per-spot-mecharm-270-reteaching
date: 2026-11-09
day: 479
meta_description: "mechArm 270 の位置3・4は、教えたつかむ姿勢そのものが原因だった。ゲームパッドで教え直し肩だけで下ろす形にすると深くつかめ、Physical Intelligence の π0.5 のお手本が5か所10本ずつそろった。"
tags: [フィジカルAI研究室, mechArm 270, π0.5, Physical Intelligence, 模倣学習, お手本, ゲームパッド, つかみの深さ, データセット, Claude Code]
series: "フィジカルAI研究室"
---

小型ロボットアーム mechArm 270 のお手本を置き場所ごとにそろえるには、位置3と位置4の教えた姿勢を作り直す必要がありました。位置3は姿勢そのものが浅く、位置4は手前の爪がブロックの真上に来る向きでした。ゲームパッドで教え直し、ブロックの上からは肩（j1）だけで下ろす形にすると、どちらも深くつかめるようになりました。Physical Intelligence の [π0.5](https://www.pi.website/blog/pi05)（ロボット用の AI のモデル）に学ばせるお手本が、5か所すべてで10本ずつ、合わせて50本そろいました。

この回でやったことで、次のことが変わりました。

- 良くなること：学習データの置き場所の偏りがなくなった。前のデータ（21本）は半分以上が位置5で、位置1は0本だった。新しいデータ `mecharm_redblock_box_deep_even10_v1` は、位置1〜5 がどれも10本で、全部が深くつかんだ本
- もたらされること：教えた姿勢が悪い位置を、1本目の深さと下ろす時間で見つけて、その場で直せるようになった。位置3は9本、位置4は3本撮ったところで止めて教え直した
- 時間：位置3と位置4の撮影は、12:07〜13:11 の約1時間（教え直し2回を含む）。ゲームパッドでの教え直しは、位置3が約4分、位置4が約3分。撮り終えてから学習データにまとめるまでは、Claude Code への依頼で7分だった（13:16〜13:23）

困ったのは、位置3の元の記録で撮った9本が、全部浅かったことです。つかめて箱にも入るのに、閉じて1秒後のはみ出しは28.7〜47.7px で、線の24px をどれも超えていました。印どおりに置いた1本目でも42.5px でした。位置4は逆に、1本目から爪がブロックの上に乗り、空で閉じました。

**位置3も位置4も、置き方ではなく、教えた記録のつかむ姿勢が原因でした。** 置き方を直しても変わらないので、姿勢のほうを作り直しています。位置4では、最初に下ろし方だけを変えて試し、外しています（下の表の13:00）。

【画像】LOG479_01_pos3_old_vs_new.jpg 位置3 の閉じて1秒後の上カメラ。左は元の教えた記録で、ブロックが爪先からはみ出している（42.5px）。右はゲームパッドで教え直した記録で、ブロックが爪の奥まで入っている（2.7px）

やったことの全体は次のとおりです。

| 時刻 | やったこと | 結果 |
|---|---|---|
| 12:07〜12:18 | 位置3を元の記録で9本撮った | 9本ともつかめたが、全部浅い（28.7〜47.7px） |
| 12:21〜12:25 | 位置3のつかむ姿勢をゲームパッドで作り直した | 肩 63.1°→68.2°・肘 13.3°→8.4°・手首 −59.8°→−66.5°。ブロックの上は肩だけ25°上げた姿勢 |
| 12:36〜12:49 | 新しい記録で位置3を12本撮った | 使える9本・線をわずかに超えた2本・爪が乗った1本 |
| 12:52〜12:58 | 位置4を元の記録で撮り、下ろし方だけ変えて撮った | 3本とも爪がブロックに乗り、空で閉じた |
| 13:01〜13:03 | 位置4をゲームパッドで教え直した | 根元の向き j0 を 3.2° 戻し、手前の爪がブロックから外れた |
| 13:05〜13:11 | 新しい記録で位置4を5本撮った | 5本とも深い（1.6〜10.0px）・下ろすのに約1.1秒 |
| 13:16〜13:23 | 今の深いデータとまとめ、位置ごとに10本にそろえた | 50本・7,128コマ。データの点検6項目に合格 |

【図解】LOG479_demo_versions.html

次は、このデータで π0.5 を [Runpod](https://www.runpod.io/) で学習し直し、置き場所ごとの成功の差が縮むかを実機で確かめます。

GPU を買うか借りるかの判断は、Runpod で実際に借りて学習させた費用をもとに、別のページにまとめています。

【バナー】gpu-buy-or-rent

この回の作業は、Claude（手順と数字の確かめを一緒に進めた AI）と進めました。アームとゲームパッドの操作と、目で見た判断はこちらで行い、本数を数える表の直しと学習データのまとめは [Claude Code](https://claude.com/claude-code)（プログラムを書く AI）に依頼箱を通して頼んでいます。ここから下は、依頼文と報告・コード・端末の出力・測定データを全量で載せた作業ログです。数字は記録から数えたもので、見込みのものは見込みと書いています。鍵（アクセストークンなど）は、どこにも載せていません。


## 作業ログ ― 位置3と位置4を教え直し、5か所を10本ずつにそろえるまで

### この回で使う言葉

| 言葉 | 意味 |
|---|---|
| お手本 | π0.5 に学ばせるための、人が用意した動きの記録。このシリーズでは、教えた姿勢をアームに再生させ、上カメラの映像と関節の角度を記録したものを使う |
| 教えた記録 | 教えた姿勢を残した JSON のファイル（drag_v2_….json）。再生のときに使うのは、ブロックの上・つかむ・箱の上・置くの4つの姿勢だけ |
| 位置1〜5 | ブロックを置く5か所。2026-10-19（LOG352）に、それぞれ教えた記録を作った |
| はみ出し（px） | 爪を閉じて1秒後に、ブロックが爪先の青い印からどれだけはみ出しているかを、上カメラの画で測った量（pi05/grasp_depth.py）。24px（約9mm）を超えたら浅いとして外す。マイナスはブロックが印より奥にあること |
| 下ろす時間 | ブロックの上の姿勢から、つかむ姿勢に着くまでの時間。普段は約1.1秒。爪がブロックの上に乗ると、着いたと判定されるまで6〜9秒かかる（LOG463） |
| 爪が乗る | 下ろすときに、爪の先がブロックの上の角に当たり、そのまま下りられなくなること |
| ゲームパッド | 市販の PS4 型のコントローラー。十字キーで関節を1つずつ動かし、×で爪を閉じ、○で開く（tools/gamepad_teleop.py。LOG419・LOG446） |
| 重ねて置く（camera_align.py） | 上カメラのライブ映像に、前に撮った1コマを半透明で重ねる画面。重なったブロックに実物を合わせると、同じ場所に置ける（pi05/camera_align.py） |
| 依頼箱 | Claude Code への依頼をファイルで置くと、Mac の見張り係が順番に渡して実行させる仕組み |

[mechArm 270](https://www.elephantrobotics.com/) は Elephant Robotics の小型の6軸アームで、中に Raspberry Pi が入っています。[π0.5](https://www.pi.website/blog/pi05) は、カメラの画と指示の言葉から、次の関節の動きを出すロボット用のモデルです。お手本の本数を位置ごとにそろえるのは、SO-101 で π0.5 を学習した例（LOG443）で、タスクごとの本数の偏りがそのまま失敗の形になっていたためです（2026-11-07 に決めた）。


## 位置3の元の記録で撮った9本は、つかめたが全部浅かった

手順書（pi05/DEEP_DEMOS.md）の決まりでは、各位置の1本目を撮ったら深さを測り、24px を超えたらその位置は撮り続けずに止めます。この日は1本目を測る前に9本続けて撮ってしまい、あとからまとめて測りました。

| run | 閉じる直前 | 閉じて1秒後 | 爪の値（中央） | measure からのブロックのずれ |
|---|---|---|---|---|
| 120818 | 67.0px | 42.5px | 832 | 0.47mm（印どおり） |
| 121128 | 54.9px | 32.4px | 777 | 27.2mm |
| 121224 | 65.4px | 39.3px | 802 | 8.3mm |
| 121320 | 56.4px | 35.9px | 801 | 4.9mm |
| 121416 | 51.5px | 28.7px | 773 | 14.7mm |
| 121511 | 61.3px | 40.4px | 809 | 5mm 未満（WARN なし） |
| 121605 | 61.3px | 39.1px | 789 | 14.1mm |
| 121659 | 65.2px | 47.7px | 718 | 4.8mm |
| 121815 | 57.6px | 32.0px | 762 | 11.7mm |

印どおりに置いた1本目（120818）でも42.5px でした。置くたびにずれは大きくなっていますが、ずれの小さい本（121320 の4.9mm で35.9px）も浅いので、どの本でも浅さは変わりません。爪の値は9本とも700〜800台で、つかめてはいます。浅くつかんだまま箱まで運べていた、ということです。下ろす時間は9本とも1.06〜1.21秒で、爪は乗っていません。

元の位置3のつかむ姿勢は、肩 63.1°・肘 13.3°・手首 −59.8° でした。


## 位置3のつかむ姿勢を、ゲームパッドで作り直した

位置1（LOG463）と同じやり方です。ブロックを印に置き、ゲームパッドで根元を回して爪の間にブロックを入れ、肘と手首で下げて奥まで入れてから×で閉じます。閉じたまま十字キーの上で肩を上げて止め、その姿勢をブロックの上の姿勢にしました。

| 姿勢 | j0 | 肩 j1 | 肘 j2 | j3 | 手首 j4 | j5 |
|---|---|---|---|---|---|---|
| 元のブロックの上 | −28.12 | 57.21 | 19.86 | −3.60 | −71.80 | −27.50 |
| 元のつかむ | −27.68 | 63.10 | 13.27 | −8.26 | −59.76 | −27.33 |
| 新しいつかむ（×で閉じたあと最初に読んだ角度・seq 224） | −25.48 | 68.20 | 8.43 | −1.58 | −66.53 | −30.14 |
| 新しいブロックの上（肩を上げて止めた角度・seq 233） | −25.48 | 43.06 | 8.52 | −1.58 | −66.53 | −30.14 |

新しい記録では、ブロックの上からつかむまでの間に、肩が25.1°動くだけです。元の記録は、下ろすあいだに手首が12°、肘が6.6°動いていました。

教えた記録は、元の記録の APPROACH_PICK と PICK の範囲だけを差し替えて作り、箱の側の2つの姿勢はそのまま使っています。再生は Pi から教えた記録を取ってくるので、作ったファイルは scp で Pi の drag_teaching/ に送りました。

### 新しい位置3の記録の作り方（mecharm_calibration/teach_poses_20261109/make_teach_pos3_20261109.py）

```python
#!/usr/bin/env python3
"""make_teach_pos3_20261109.py — 位置3 の教えた記録 drag_v2_20221013_231249.json の「ブロックの上」と「つかむ」の姿勢だけを,
ゲームパッドで作り直した姿勢に差し替えた新しい教えた記録 drag_v2_20261109_123000.json を作る (2026-11-09 12:30).
作り方は位置1 の lab/Log25/make_teach_v2_20261109.py と同じ (再生が使う 4 つの姿勢のうち, PICK 側の 2 つの範囲を全部そろえる).
  APPROACH_PICK : phase APPROACH_PICK (idx 146〜194) を全部「ブロックの上」に
  PICK          : PICK phase (idx 195〜285. close の印は idx 214) を全部「つかむ」に
箱の側の 2 つ (APPROACH_PLACE・PLACE) と, phases・gripper_events・key_log・positions はそのまま.

姿勢は tools/gamepad_teleop.py の記録 runs/experiments/gamepad_teleop/teleop_20261109_122141/log.jsonl の実測から取った:
  つかむ      = 爪を閉じた (seq 219 の ×) あと, 最初に読んだ角度 (seq 224 の measured_before)
  ブロックの上 = つかんだまま j1 を十字キーの上で上げて止めた角度 (seq 233 の measured_after_halt)
理由: 位置3 の元の教えた PICK が浅かった (2026-11-09 の 9 本が閉じて 1 秒後 28.7〜47.7px. 印どおりに置いた 120818 でも 42.5px)
"""
import json, copy
src = "runs/run_pick_place/run_0001_20261109_120818/teach/drag_v2_20221013_231249.json"
d = json.load(open(src)); n = copy.deepcopy(d)
pick = [-25.48, 68.20, 8.43, -1.58, -66.53, -30.14]   # teleop_20261109_122141 で爪を閉じたあとの実測 (seq 224)
appr = [-25.48, 43.06, 8.52, -1.58, -66.53, -30.14]   # 同じ記録で j1 を上げて止めた実測 (seq 233)
for i in range(146, 195): n['angles'][i] = list(appr)
for i in range(195, 286): n['angles'][i] = list(pick)
n['recorded_at'] = "2026-11-09T12:30:00"
n['derived_from'] = {"teach": "drag_v2_20221013_231249.json", "replaced": {"APPROACH_PICK idx 146-194": appr, "PICK idx 195-285": pick},
 "source": "runs/experiments/gamepad_teleop/teleop_20261109_122141/log.jsonl (seq 224 の閉じたあとの実測・seq 233 の持ち上げ後の実測)",
 "reason": "位置3の教えた PICK が浅かった (2026-11-09 の 9 本が 28.7〜47.7px)。ゲームパッドで奥までつかむ姿勢を作り直した。箱側の 2 姿勢は元のまま"}
out = "mecharm_calibration/teach_poses_20261109/drag_v2_20261109_123000.json"
json.dump(n, open(out, "w"), ensure_ascii=False, indent=1); print(out)
```

### ゲームパッドの記録（runs/experiments/gamepad_teleop/teleop_20261109_122141/meta.json）

```json
{
  "run_stem": "teleop_20261109_122141",
  "started_at": "2026-11-09T12:21:41",
  "execute": true,
  "argv": [
    "tools/gamepad_teleop.py",
    "--execute"
  ],
  "controllers": [
    {
      "name": "PS4 Controller",
      "guid": "03008fe54c050000cc09000000016800",
      "instance_id": 0,
      "axes": 6,
      "buttons": 16,
      "hats": 0,
      "connected_at": "2026-11-09T12:21:46"
    }
  ],
  "python": "3.12.12 | packaged by conda-forge | (main, Oct 22 2025, 23:34:53) [Clang 19.1.7 ]",
  "pygame": "2.6.1",
  "sdl": "2.28.4",
  "platform": "macOS-26.6.2-arm64-arm-64bit",
  "start_pose": [
    -0.43,
    1.49,
    1.75,
    0.08,
    -0.26,
    -30.23
  ],
  "guards": {
    "J1_MAX_DEG": 90.87,
    "range": "physical_limits (no base window. 2026-11-03)",
    "J4_SAFE": [
      -90.0,
      60.0
    ],
    "JOINT_LIMITS": [
      [
        -156.0,
        161.0
      ],
      [
        -79.0,
        123.0
      ],
      [
        -177.0,
        177.0
      ],
      [
        -156.0,
        162.0
      ],
      [
        -118.0,
        118.0
      ],
      [
        -177.0,
        178.0
      ]
    ],
    "window": {
      "lo": [
        -156.0,
        -79.0,
        -177.0,
        -156.0,
        -90.0,
        -177.0
      ],
      "hi": [
        161.0,
        90.87,
        177.0,
        162.0,
        60.0,
        178.0
      ]
    },
    "home_bypasses_range_check": true
  },
  "motion": {
    "speed": 20,
    "step_fine_deg": 1.0,
    "step_coarse_deg": 2.0,
    "reach_tol_deg": 3.0,
    "reach_timeout_min_sec": 8.0,
    "poll_sec": 0.3,
    "gripper_sleep_sec": 0.8,
    "grip_close_value": 20,
    "send_wait": 0.0,
    "home": [
      0.0,
      0.0,
      0.0,
      0.0,
      0.0,
      -30.0
    ],
    "home_hold_sec": 1.0,
    "trigger_stop_above": 0.0,
    "hold_start_sec": 0.4,
    "hold_interval_sec": 0.1,
    "hold_ahead_deg": 15.0,
    "hold_stall_sec": 1.5,
    "ignored_check_sec": 0.5,
    "ignored_max_resends": 3,
    "j0_left_sign": -1.0,
    "up_sign": -1.0,
    "select_order": [
      1,
      2,
      3,
      4,
      5
    ]
  },
  "button_map": {
    "0": "cross",
    "1": "circle",
    "2": "square",
    "3": "triangle",
    "4": "share",
    "5": "home",
    "6": "options",
    "7": "l3",
    "8": "r3",
    "9": "l1",
    "10": "r1",
    "11": "dpad_up",
    "12": "dpad_down",
    "13": "dpad_left",
    "14": "dpad_right",
    "15": "touchpad"
  },
  "git": {
    "commit": "23ed9141636c183562da3fe515d0fb0b374530d5",
    "script_status": "clean"
  },
  "script_copy": "gamepad_teleop.py",
  "script_sha256": "d211064093ab547bb9dac15dfaa53c49c8de77f1ce1b22cf58442fde253dd259",
  "ended_at": "2026-11-09T12:25:16",
  "end_reason": "ctrl_c",
  "n_sent": 88
}
```

### ゲームパッドの記録（runs/experiments/gamepad_teleop/teleop_20261109_122141/log.jsonl）

```json
{"seq": 1, "t": "2026-11-09T12:21:48.643", "t_unix": 1794194508.643, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -15.0, "hold_id": 1, "hold_n": 1, "held_sec": 0.413, "accepted": true, "measured_before": [-0.43, 1.49, 1.75, 0.08, -0.26, -30.23], "start_source": "hold", "cmd_gap_deg": 0.0, "hold_lead_deg": 0.0, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-15.43, 1.49, 1.75, 0.08, -0.26, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194508.6583831, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 2, "t": "2026-11-09T12:21:48.743", "t_unix": 1794194508.744, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -15.0, "hold_id": 1, "hold_n": 2, "held_sec": 0.513, "accepted": true, "measured_before": [-0.43, 1.49, 1.75, 0.08, -0.26, -30.23], "start_source": "hold", "cmd_gap_deg": 0.0, "hold_lead_deg": 15.0, "sent": false, "why": "lead_ok", "hold_remaining_deg": 15.0, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 3, "t": "2026-11-09T12:21:48.844", "t_unix": 1794194508.844, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -15.0, "hold_id": 1, "hold_n": 3, "held_sec": 0.614, "accepted": true, "measured_before": [-1.23, 1.49, 1.75, 0.08, -0.26, -30.23], "start_source": "hold", "cmd_gap_deg": 0.0, "hold_lead_deg": 14.2, "sent": false, "why": "lead_ok", "hold_remaining_deg": 14.2, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 4, "t": "2026-11-09T12:21:48.946", "t_unix": 1794194508.946, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -15.0, "hold_id": 1, "hold_n": 4, "held_sec": 0.716, "accepted": true, "measured_before": [-6.24, 1.49, 1.75, 0.08, -0.26, -30.23], "start_source": "hold", "cmd_gap_deg": 0.0, "hold_lead_deg": 9.19, "sent": false, "why": "lead_ok", "hold_remaining_deg": 9.19, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 5, "t": "2026-11-09T12:21:49.059", "t_unix": 1794194509.06, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -15.0, "hold_id": 1, "hold_n": 5, "held_sec": 0.83, "accepted": true, "measured_before": [-9.93, 1.49, 1.75, 0.08, -0.26, -30.23], "start_source": "hold", "cmd_gap_deg": 0.0, "hold_lead_deg": 5.5, "sent": false, "why": "lead_ok", "hold_remaining_deg": 5.5, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 6, "t": "2026-11-09T12:21:49.161", "t_unix": 1794194509.162, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -15.0, "hold_id": 1, "hold_n": 6, "held_sec": 0.932, "accepted": true, "released_during_job": true, "measured_before": [-14.94, 1.49, 1.75, 0.08, -0.26, -30.23], "start_source": "hold", "cmd_gap_deg": 0.0, "hold_lead_deg": 0.49, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-29.94, 1.49, 1.75, 0.08, -0.26, -30.23], "sent": false, "why": "halted_before_send", "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 7, "t": "2026-11-09T12:21:49.461", "t_unix": 1794194509.461, "button": null, "button_name": null, "kind": "halt", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 1, "halt_joint": 0, "measured_at_request": [-9.93, 1.49, 1.75, 0.08, -0.26, -30.23], "t_halt": 1794194509.461175, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-15.64, 2.54, 2.54, 0.08, 1.23, -30.23], "moved_after_request_deg": [-5.71, 1.05, 0.79, 0.0, 1.49, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 8, "t": "2026-11-09T12:21:49.977", "t_unix": 1794194509.978, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -1.0, "hold_id": 2, "hold_n": 0, "accepted": true, "measured_before": [-15.64, 2.72, 2.81, 0.08, 1.49, -30.23], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 1.75, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-16.64, 1.49, 1.75, 0.08, -0.26, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194510.0127418, "measured_before_send": [-15.64, 2.72, 2.81, 0.08, 1.49, -30.23], "resends": [], "reached": true, "reached_angles": [-17.05, 1.49, 1.93, 0.08, 1.49, -30.23], "reach_err": 1.75, "elapsed_sec": 0.24, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 9, "t": "2026-11-09T12:21:50.476", "t_unix": 1794194510.476, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -1.0, "hold_id": 3, "hold_n": 0, "accepted": true, "measured_before": [-16.43, 1.49, 1.93, 0.08, 1.49, -30.23], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 1.75, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-17.64, 1.49, 1.75, 0.08, -0.26, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194510.5166268, "measured_before_send": [-16.43, 1.49, 1.93, 0.08, 1.49, -30.23], "resends": [0.34, 0.67], "reached": false, "not_moved": true, "reached_angles": [-16.43, 1.49, 1.93, 0.08, 1.49, -30.23], "reach_err": 1.75, "elapsed_sec": 0.98, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 10, "t": "2026-11-09T12:21:51.589", "t_unix": 1794194511.589, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -15.0, "hold_id": 4, "hold_n": 1, "held_sec": 0.881, "accepted": true, "measured_before": [-16.43, 1.49, 1.93, 0.08, 1.49, -30.23], "start_source": "hold", "cmd_gap_deg": 1.75, "hold_lead_deg": 1.21, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-31.43, 1.49, 1.75, 0.08, -0.26, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194511.6145658, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 11, "t": "2026-11-09T12:21:51.674", "t_unix": 1794194511.674, "button": null, "button_name": null, "kind": "halt", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 4, "halt_joint": 0, "measured_at_request": [-16.43, 1.49, 1.93, 0.08, 1.49, -30.23], "t_halt": 1794194511.6741362, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-17.31, 2.1, 2.37, 0.08, 2.19, -30.23], "moved_after_request_deg": [-0.88, 0.61, 0.44, 0.0, 0.7, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 12, "t": "2026-11-09T12:21:52.742", "t_unix": 1794194512.742, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -15.0, "hold_id": 5, "hold_n": 1, "held_sec": 0.401, "accepted": true, "measured_before": [-16.69, 2.46, 2.9, 0.08, 3.07, -30.23], "start_source": "mixed", "cmd_gap_deg": 3.33, "hold_lead_deg": 0.62, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-31.69, 1.49, 1.75, 0.08, -0.26, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194512.763106, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 13, "t": "2026-11-09T12:21:52.857", "t_unix": 1794194512.858, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -15.0, "hold_id": 5, "hold_n": 2, "held_sec": 0.517, "accepted": true, "measured_before": [-21.44, 1.58, 1.84, 0.08, 2.46, -30.23], "start_source": "hold", "cmd_gap_deg": 2.72, "hold_lead_deg": 10.25, "sent": false, "why": "lead_ok", "hold_remaining_deg": 10.25, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 14, "t": "2026-11-09T12:21:53.026", "t_unix": 1794194513.026, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -15.0, "hold_id": 5, "hold_n": 3, "held_sec": 0.685, "accepted": true, "measured_before": [-22.85, 1.58, 1.84, 0.08, 2.46, -30.23], "start_source": "hold", "cmd_gap_deg": 2.72, "hold_lead_deg": 8.84, "sent": false, "why": "lead_ok", "hold_remaining_deg": 8.84, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 15, "t": "2026-11-09T12:21:53.092", "t_unix": 1794194513.093, "button": null, "button_name": null, "kind": "halt", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 5, "halt_joint": 0, "measured_at_request": [-22.85, 1.58, 1.84, 0.08, 2.46, -30.23], "t_halt": 1794194513.092845, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-30.32, 1.58, 1.84, 0.08, 2.46, -30.23], "moved_after_request_deg": [-7.47, 0.0, 0.0, 0.0, 0.0, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 16, "t": "2026-11-09T12:21:54.076", "t_unix": 1794194514.077, "button": 14, "button_name": "dpad_right", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": 1.0, "hold_id": 6, "hold_n": 0, "accepted": true, "measured_before": [-29.97, 1.58, 1.84, 0.0, 2.46, -30.32], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 2.72, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-29.32, 1.49, 1.75, 0.08, -0.26, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194514.104296, "measured_before_send": [-29.97, 1.58, 1.84, 0.0, 2.46, -30.32], "resends": [], "reached": true, "reached_angles": [-29.09, 1.58, 1.84, 0.0, 1.66, -30.32], "reach_err": 1.92, "elapsed_sec": 0.99, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 17, "t": "2026-11-09T12:21:55.124", "t_unix": 1794194515.124, "button": 14, "button_name": "dpad_right", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": 1.0, "hold_id": 8, "hold_n": 0, "accepted": true, "measured_before": [-29.09, 1.58, 1.84, 0.0, 1.66, -30.32], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 1.92, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-28.32, 1.49, 1.75, 0.08, -0.26, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194515.1649961, "measured_before_send": [-29.09, 1.58, 1.84, 0.0, 1.66, -30.32], "resends": [], "reached": true, "reached_angles": [-28.74, 1.58, 1.84, 0.0, 1.66, -30.32], "reach_err": 1.92, "elapsed_sec": 0.16, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 18, "t": "2026-11-09T12:21:55.372", "t_unix": 1794194515.373, "button": 14, "button_name": "dpad_right", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": 1.0, "hold_id": 9, "hold_n": 0, "accepted": true, "measured_before": [-28.38, 1.58, 1.84, 0.0, 1.66, -30.32], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 1.92, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-27.32, 1.49, 1.75, 0.08, -0.26, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194515.4087942, "measured_before_send": [-28.03, 1.58, 1.84, 0.0, 1.66, -30.32], "resends": [], "reached": true, "reached_angles": [-27.33, 1.58, 1.84, 0.0, 1.66, -30.32], "reach_err": 1.92, "elapsed_sec": 0.29, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 19, "t": "2026-11-09T12:21:55.990", "t_unix": 1794194515.99, "button": 14, "button_name": "dpad_right", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": 1.0, "hold_id": 10, "hold_n": 0, "accepted": true, "measured_before": [-27.07, 1.58, 1.84, 0.0, 1.66, -30.32], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 1.92, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-26.32, 1.49, 1.75, 0.08, -0.26, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194516.012195, "measured_before_send": [-27.07, 1.58, 1.84, 0.0, 1.66, -30.32], "resends": [0.34, 0.68], "reached": false, "not_moved": true, "reached_angles": [-27.07, 1.58, 1.84, 0.0, 0.52, -30.32], "reach_err": 0.78, "elapsed_sec": 0.99, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 20, "t": "2026-11-09T12:21:57.127", "t_unix": 1794194517.127, "button": 14, "button_name": "dpad_right", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": 1.0, "hold_id": 11, "hold_n": 0, "accepted": true, "measured_before": [-27.07, 1.58, 1.84, 0.0, 0.52, -30.32], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 0.78, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 1.49, 1.75, 0.08, -0.26, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194517.169888, "measured_before_send": [-27.07, 1.58, 1.84, 0.0, 0.52, -30.32], "resends": [0.41, 0.74], "reached": false, "not_moved": true, "reached_angles": [-27.07, 1.58, 1.84, 0.0, 0.52, -30.32], "reach_err": 1.75, "elapsed_sec": 1.04, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 21, "t": "2026-11-09T12:21:59.449", "t_unix": 1794194519.45, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 2, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 22, "t": "2026-11-09T12:22:00.481", "t_unix": 1794194520.481, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -15.0, "hold_id": 12, "hold_n": 1, "held_sec": 0.401, "accepted": true, "measured_before": [-27.07, 1.58, 1.84, 0.0, 0.52, -30.32], "start_source": "hold", "cmd_gap_deg": 1.75, "hold_lead_deg": 0.09, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 1.49, -13.16, 0.08, -0.26, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194520.498799, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 23, "t": "2026-11-09T12:22:00.582", "t_unix": 1794194520.582, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -15.0, "hold_id": 12, "hold_n": 2, "held_sec": 0.502, "accepted": true, "measured_before": [-27.07, 1.58, 1.84, 0.0, 0.52, -30.32], "start_source": "hold", "cmd_gap_deg": 1.75, "hold_lead_deg": 15.0, "sent": false, "why": "lead_ok", "hold_remaining_deg": 15.0, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 24, "t": "2026-11-09T12:22:00.682", "t_unix": 1794194520.683, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -15.0, "hold_id": 12, "hold_n": 3, "held_sec": 0.602, "accepted": true, "measured_before": [-25.57, 1.58, 1.05, 0.0, 0.52, -30.32], "start_source": "hold", "cmd_gap_deg": 0.78, "hold_lead_deg": 14.21, "sent": false, "why": "lead_ok", "hold_remaining_deg": 14.21, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 25, "t": "2026-11-09T12:22:00.784", "t_unix": 1794194520.784, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -15.0, "hold_id": 12, "hold_n": 4, "held_sec": 0.703, "accepted": true, "measured_before": [-25.13, 1.58, -3.25, 0.0, 0.52, -30.32], "start_source": "hold", "cmd_gap_deg": 0.78, "hold_lead_deg": 9.91, "sent": false, "why": "lead_ok", "hold_remaining_deg": 9.91, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 26, "t": "2026-11-09T12:22:00.884", "t_unix": 1794194520.885, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -15.0, "hold_id": 12, "hold_n": 5, "held_sec": 0.804, "accepted": true, "measured_before": [-25.57, 1.58, -7.47, 0.0, 0.52, -30.32], "start_source": "hold", "cmd_gap_deg": 0.78, "hold_lead_deg": 5.69, "sent": false, "why": "lead_ok", "hold_remaining_deg": 5.69, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 27, "t": "2026-11-09T12:22:01.000", "t_unix": 1794194521.001, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -15.0, "hold_id": 12, "hold_n": 6, "held_sec": 0.92, "accepted": true, "released_during_job": true, "measured_before": [-24.96, 1.58, -11.42, 0.0, 0.43, -30.32], "start_source": "hold", "cmd_gap_deg": 0.69, "hold_lead_deg": 1.74, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 1.49, -26.42, 0.08, -0.26, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194521.0291681, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 28, "t": "2026-11-09T12:22:01.149", "t_unix": 1794194521.15, "button": null, "button_name": null, "kind": "halt", "selected_joint": 2, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 12, "halt_joint": 2, "measured_at_request": [-25.57, 1.58, -7.47, 0.0, 0.52, -30.32], "t_halt": 1794194521.150008, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 29, "t": "2026-11-09T12:22:03.980", "t_unix": 1794194523.981, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 3, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 30, "t": "2026-11-09T12:22:04.229", "t_unix": 1794194524.23, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 4, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 31, "t": "2026-11-09T12:22:05.344", "t_unix": 1794194525.345, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 13, "hold_n": 1, "held_sec": 0.401, "accepted": true, "released_during_job": true, "measured_before": [-24.96, 1.49, -25.04, 0.0, 0.0, -30.23], "start_source": "hold", "cmd_gap_deg": 1.38, "hold_lead_deg": 0.26, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 1.49, -26.42, 0.08, -15.0, -30.23], "sent": false, "why": "halted_before_send", "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 33, "t": "2026-11-09T12:22:11.995", "t_unix": 1794194531.995, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 5, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 34, "t": "2026-11-09T12:22:12.230", "t_unix": 1794194532.23, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 32, "t": "2026-11-09T12:22:10.631", "t_unix": 1794194530.631, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -1.0, "hold_id": 15, "hold_n": 0, "accepted": true, "measured_before": [-24.96, 1.49, -25.04, 0.0, 0.0, -30.23], "start_source": "measured", "others_from_measured": [], "cmd_gap_deg": 1.38, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 1.49, -26.42, 0.08, -1.0, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194530.668591, "measured_before_send": [-24.96, 1.49, -25.04, 0.0, 0.0, -30.23], "resends": [7.1, 7.49], "reached": false, "not_moved": true, "reached_angles": [-25.04, 1.49, -25.04, 0.0, 0.0, -30.23], "reach_err": 1.38, "elapsed_sec": 7.86, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 35, "t": "2026-11-09T12:22:18.673", "t_unix": 1794194538.673, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 1.0, "hold_id": 18, "hold_n": 0, "accepted": true, "measured_before": [-25.04, 1.49, -25.04, 0.0, 0.0, -30.23], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 1.38, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 2.49, -26.42, 0.08, -1.0, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194538.71261, "measured_before_send": [-25.04, 1.49, -25.04, 0.0, 0.0, -30.23], "resends": [], "reached": true, "reached_angles": [-25.04, 2.81, -25.04, 0.0, -1.58, -30.23], "reach_err": 1.38, "elapsed_sec": 0.16, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 36, "t": "2026-11-09T12:22:20.110", "t_unix": 1794194540.11, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 19, "hold_n": 1, "held_sec": 0.402, "accepted": true, "measured_before": [-25.04, 3.42, -25.04, 0.0, -1.58, -30.23], "start_source": "hold", "cmd_gap_deg": 1.38, "hold_lead_deg": 0.93, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 18.42, -26.42, 0.08, -1.0, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194540.1209779, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 37, "t": "2026-11-09T12:22:20.226", "t_unix": 1794194540.227, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 19, "hold_n": 2, "held_sec": 0.518, "accepted": true, "measured_before": [-25.04, 3.69, -25.04, 0.0, -1.58, -30.23], "start_source": "hold", "cmd_gap_deg": 1.38, "hold_lead_deg": 14.73, "sent": false, "why": "lead_ok", "hold_remaining_deg": 14.73, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 38, "t": "2026-11-09T12:22:20.327", "t_unix": 1794194540.327, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 19, "hold_n": 3, "held_sec": 0.619, "accepted": true, "measured_before": [-25.04, 5.97, -25.04, 0.0, -1.58, -30.23], "start_source": "hold", "cmd_gap_deg": 1.38, "hold_lead_deg": 12.45, "sent": false, "why": "lead_ok", "hold_remaining_deg": 12.45, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 39, "t": "2026-11-09T12:22:20.442", "t_unix": 1794194540.443, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 19, "hold_n": 4, "held_sec": 0.734, "accepted": true, "measured_before": [-25.04, 11.6, -25.04, 0.0, -1.58, -30.23], "start_source": "hold", "cmd_gap_deg": 1.38, "hold_lead_deg": 6.82, "sent": false, "why": "lead_ok", "hold_remaining_deg": 6.82, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 40, "t": "2026-11-09T12:22:20.559", "t_unix": 1794194540.56, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 19, "hold_n": 5, "held_sec": 0.851, "accepted": true, "released_during_job": true, "measured_before": [-25.04, 19.59, -25.04, 0.0, -1.58, -30.23], "start_source": "hold", "cmd_gap_deg": 1.38, "hold_lead_deg": 1.17, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 34.59, -26.42, 0.08, -1.0, -30.23], "sent": false, "why": "halted_before_send", "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 41, "t": "2026-11-09T12:22:24.315", "t_unix": 1794194544.315, "button": null, "button_name": null, "kind": "halt", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 19, "halt_joint": 1, "measured_at_request": [-25.04, 11.6, -25.04, 0.0, -1.58, -30.23], "t_halt": 1794194544.3170612, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-25.04, 20.83, -23.99, 0.08, 0.08, -30.23], "moved_after_request_deg": [0.0, 9.23, 1.05, 0.08, 1.66, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 42, "t": "2026-11-09T12:22:24.500", "t_unix": 1794194544.5, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 1.0, "hold_id": 20, "hold_n": 0, "accepted": true, "measured_before": [-25.04, 20.83, -23.99, 0.08, 0.08, -30.23], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 2.43, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 21.83, -26.42, 0.08, -1.0, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194544.540629, "measured_before_send": [-25.04, 20.83, -23.99, 0.08, 0.08, -30.23], "resends": [], "reached": false, "settled": true, "reached_angles": [-25.04, 22.93, -24.52, 0.08, 0.17, -30.23], "reach_err": 1.9, "elapsed_sec": 0.59, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 43, "t": "2026-11-09T12:22:25.184", "t_unix": 1794194545.184, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 21, "hold_n": 1, "held_sec": 1.799, "accepted": true, "measured_before": [-25.04, 22.93, -24.52, 0.08, 0.17, -30.23], "start_source": "hold", "cmd_gap_deg": 1.9, "hold_lead_deg": 1.1, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 37.93, -26.42, 0.08, -1.0, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194545.2021298, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 44, "t": "2026-11-09T12:22:25.285", "t_unix": 1794194545.285, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 21, "hold_n": 2, "held_sec": 1.9, "accepted": true, "measured_before": [-25.04, 23.02, -24.52, 0.08, 0.17, -30.23], "start_source": "hold", "cmd_gap_deg": 1.9, "hold_lead_deg": 14.91, "sent": false, "why": "lead_ok", "hold_remaining_deg": 14.91, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 45, "t": "2026-11-09T12:22:25.401", "t_unix": 1794194545.401, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 21, "hold_n": 3, "held_sec": 2.016, "accepted": true, "measured_before": [-25.04, 25.57, -24.52, 0.08, 0.17, -30.23], "start_source": "hold", "cmd_gap_deg": 1.9, "hold_lead_deg": 12.36, "sent": false, "why": "lead_ok", "hold_remaining_deg": 12.36, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 46, "t": "2026-11-09T12:22:25.501", "t_unix": 1794194545.502, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 21, "hold_n": 4, "held_sec": 2.117, "accepted": true, "measured_before": [-25.04, 29.79, -24.52, 0.08, 0.26, -30.23], "start_source": "hold", "cmd_gap_deg": 1.9, "hold_lead_deg": 8.14, "sent": false, "why": "lead_ok", "hold_remaining_deg": 8.14, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 47, "t": "2026-11-09T12:22:25.604", "t_unix": 1794194545.604, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 21, "hold_n": 5, "held_sec": 2.219, "accepted": true, "released_during_job": true, "measured_before": [-25.04, 34.54, -24.52, 0.08, 0.26, -30.23], "start_source": "hold", "cmd_gap_deg": 1.9, "hold_lead_deg": 3.39, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 49.54, -26.42, 0.08, -1.0, -30.23], "sent": false, "why": "halted_before_send", "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 48, "t": "2026-11-09T12:22:25.672", "t_unix": 1794194545.672, "button": null, "button_name": null, "kind": "halt", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 21, "halt_joint": 1, "measured_at_request": [-25.04, 29.79, -24.52, 0.08, 0.26, -30.23], "t_halt": 1794194545.672288, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-25.04, 39.81, -23.55, 0.08, 1.84, -30.23], "moved_after_request_deg": [0.0, 10.02, 0.97, 0.0, 1.58, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 49, "t": "2026-11-09T12:22:27.935", "t_unix": 1794194547.935, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 2, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 50, "t": "2026-11-09T12:22:28.198", "t_unix": 1794194548.198, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 3, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 51, "t": "2026-11-09T12:22:28.696", "t_unix": 1794194548.696, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 4, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 52, "t": "2026-11-09T12:22:29.693", "t_unix": 1794194549.693, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 22, "hold_n": 1, "held_sec": 0.4, "accepted": true, "measured_before": [-25.04, 39.9, -23.55, 0.08, 1.84, -30.23], "start_source": "hold", "cmd_gap_deg": 2.87, "hold_lead_deg": 2.84, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 39.81, -26.42, 0.08, -13.16, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194549.7120378, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 53, "t": "2026-11-09T12:22:29.793", "t_unix": 1794194549.793, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 22, "hold_n": 2, "held_sec": 0.5, "accepted": true, "measured_before": [-25.04, 39.9, -23.55, 0.08, 0.52, -30.23], "start_source": "hold", "cmd_gap_deg": 2.87, "hold_lead_deg": 13.68, "sent": false, "why": "lead_ok", "hold_remaining_deg": 13.68, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 54, "t": "2026-11-09T12:22:29.893", "t_unix": 1794194549.893, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 22, "hold_n": 3, "held_sec": 0.6, "accepted": true, "measured_before": [-25.04, 39.9, -23.55, 0.08, -2.1, -30.23], "start_source": "hold", "cmd_gap_deg": 2.87, "hold_lead_deg": 11.06, "sent": false, "why": "lead_ok", "hold_remaining_deg": 11.06, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 55, "t": "2026-11-09T12:22:30.010", "t_unix": 1794194550.01, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 22, "hold_n": 4, "held_sec": 0.717, "accepted": true, "measured_before": [-25.04, 39.9, -23.55, 0.08, -7.11, -30.23], "start_source": "hold", "cmd_gap_deg": 2.87, "hold_lead_deg": 6.05, "sent": false, "why": "lead_ok", "hold_remaining_deg": 6.05, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 56, "t": "2026-11-09T12:22:30.126", "t_unix": 1794194550.127, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 22, "hold_n": 5, "held_sec": 0.834, "accepted": true, "measured_before": [-25.04, 39.9, -24.52, 0.08, -11.33, -30.23], "start_source": "hold", "cmd_gap_deg": 1.9, "hold_lead_deg": 1.83, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 39.81, -26.42, 0.08, -26.33, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194550.142946, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 57, "t": "2026-11-09T12:22:30.310", "t_unix": 1794194550.31, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 22, "hold_n": 6, "held_sec": 1.017, "accepted": true, "measured_before": [-25.04, 39.9, -24.52, 0.08, -13.44, -30.23], "start_source": "hold", "cmd_gap_deg": 1.9, "hold_lead_deg": 12.89, "sent": false, "why": "lead_ok", "hold_remaining_deg": 12.89, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 58, "t": "2026-11-09T12:22:30.410", "t_unix": 1794194550.41, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 22, "hold_n": 7, "held_sec": 1.117, "accepted": true, "measured_before": [-25.04, 39.9, -24.52, 0.08, -17.66, -30.23], "start_source": "hold", "cmd_gap_deg": 1.9, "hold_lead_deg": 8.67, "sent": false, "why": "lead_ok", "hold_remaining_deg": 8.67, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 59, "t": "2026-11-09T12:22:30.526", "t_unix": 1794194550.527, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 22, "hold_n": 8, "held_sec": 1.234, "accepted": true, "measured_before": [-25.04, 39.9, -24.52, 0.08, -23.11, -30.23], "start_source": "hold", "cmd_gap_deg": 1.9, "hold_lead_deg": 3.22, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 39.81, -26.42, 0.08, -38.11, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194550.552851, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 60, "t": "2026-11-09T12:22:30.639", "t_unix": 1794194550.64, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 22, "hold_n": 9, "held_sec": 1.347, "accepted": true, "measured_before": [-25.04, 39.9, -24.52, 0.08, -25.04, -30.23], "start_source": "hold", "cmd_gap_deg": 1.9, "hold_lead_deg": 13.07, "sent": false, "why": "lead_ok", "hold_remaining_deg": 13.07, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 61, "t": "2026-11-09T12:22:30.753", "t_unix": 1794194550.754, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 22, "hold_n": 10, "held_sec": 1.461, "accepted": true, "measured_before": [-25.04, 39.9, -24.52, 0.08, -31.11, -30.23], "start_source": "hold", "cmd_gap_deg": 1.9, "hold_lead_deg": 7.0, "sent": false, "why": "lead_ok", "hold_remaining_deg": 7.0, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 62, "t": "2026-11-09T12:22:30.920", "t_unix": 1794194550.921, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 22, "hold_n": 11, "held_sec": 1.628, "accepted": true, "measured_before": [-25.04, 39.9, -24.52, 0.08, -32.95, -30.23], "start_source": "hold", "cmd_gap_deg": 1.9, "hold_lead_deg": 5.16, "sent": false, "why": "lead_ok", "hold_remaining_deg": 5.16, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 63, "t": "2026-11-09T12:22:31.036", "t_unix": 1794194551.036, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 22, "hold_n": 12, "held_sec": 1.743, "accepted": true, "measured_before": [-25.04, 39.9, -24.52, 0.08, -36.82, -30.23], "start_source": "hold", "cmd_gap_deg": 1.9, "hold_lead_deg": 1.29, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 39.81, -26.42, 0.08, -51.82, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194551.184761, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 64, "t": "2026-11-09T12:22:31.268", "t_unix": 1794194551.268, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 22, "hold_n": 13, "held_sec": 1.975, "accepted": true, "released_during_job": true, "measured_before": [-25.04, 39.9, -24.52, 0.08, -36.91, -30.23], "start_source": "hold", "cmd_gap_deg": 1.9, "hold_lead_deg": 14.91, "sent": false, "why": "lead_ok", "hold_remaining_deg": 14.91, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 65, "t": "2026-11-09T12:22:31.337", "t_unix": 1794194551.337, "button": null, "button_name": null, "kind": "halt", "selected_joint": 4, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 22, "halt_joint": 4, "measured_at_request": [-25.04, 39.9, -24.52, 0.08, -36.82, -30.23], "t_halt": 1794194551.3371992, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-25.04, 41.22, -23.64, 0.08, -36.65, -30.23], "moved_after_request_deg": [0.0, 1.32, 0.88, 0.0, 0.17, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 66, "t": "2026-11-09T12:22:32.950", "t_unix": 1794194552.95, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 5, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 67, "t": "2026-11-09T12:22:33.136", "t_unix": 1794194553.136, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 68, "t": "2026-11-09T12:22:34.285", "t_unix": 1794194554.285, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -1.0, "hold_id": 23, "hold_n": 0, "accepted": true, "measured_before": [-25.04, 41.22, -23.46, 0.08, -36.29, -30.23], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 2.96, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 38.81, -26.42, 0.08, -36.65, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194554.3146482, "measured_before_send": [-25.04, 41.22, -23.46, 0.08, -36.29, -30.23], "resends": [0.33, 0.67], "reached": false, "not_moved": true, "reached_angles": [-25.04, 41.22, -23.46, 0.08, -36.38, -30.23], "reach_err": 2.96, "elapsed_sec": 0.98, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 69, "t": "2026-11-09T12:22:35.385", "t_unix": 1794194555.385, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 24, "hold_n": 1, "held_sec": 0.7, "accepted": true, "measured_before": [-25.04, 41.22, -23.46, 0.08, -36.38, -30.23], "start_source": "hold", "cmd_gap_deg": 2.96, "hold_lead_deg": 2.41, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 56.22, -26.42, 0.08, -36.65, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194555.404702, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 70, "t": "2026-11-09T12:22:35.501", "t_unix": 1794194555.502, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 24, "hold_n": 2, "held_sec": 0.817, "accepted": true, "measured_before": [-25.04, 41.22, -23.46, 0.17, -37.79, -30.23], "start_source": "hold", "cmd_gap_deg": 2.96, "hold_lead_deg": 15.0, "sent": false, "why": "lead_ok", "hold_remaining_deg": 15.0, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 71, "t": "2026-11-09T12:22:35.618", "t_unix": 1794194555.618, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 24, "hold_n": 3, "held_sec": 0.933, "accepted": true, "measured_before": [-25.04, 42.71, -23.46, 0.17, -37.79, -30.23], "start_source": "hold", "cmd_gap_deg": 2.96, "hold_lead_deg": 13.51, "sent": false, "why": "lead_ok", "hold_remaining_deg": 13.51, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 72, "t": "2026-11-09T12:22:35.718", "t_unix": 1794194555.718, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 24, "hold_n": 4, "held_sec": 1.033, "accepted": true, "measured_before": [-25.04, 46.75, -23.46, 0.17, -37.79, -30.23], "start_source": "hold", "cmd_gap_deg": 2.96, "hold_lead_deg": 9.47, "sent": false, "why": "lead_ok", "hold_remaining_deg": 9.47, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 73, "t": "2026-11-09T12:22:35.835", "t_unix": 1794194555.835, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 24, "hold_n": 5, "held_sec": 1.15, "accepted": true, "released_during_job": true, "measured_before": [-25.04, 51.76, -25.13, 0.08, -41.04, -30.23], "start_source": "mixed", "cmd_gap_deg": 4.39, "hold_lead_deg": 4.46, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 66.76, -26.42, 0.08, -36.65, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194555.859048, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 74, "t": "2026-11-09T12:22:35.999", "t_unix": 1794194556.0, "button": null, "button_name": null, "kind": "halt", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 24, "halt_joint": 1, "measured_at_request": [-25.04, 46.75, -23.46, 0.17, -37.79, -30.23], "t_halt": 1794194555.999962, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-25.04, 58.88, -24.34, 0.08, -39.46, -30.23], "moved_after_request_deg": [0.0, 12.13, -0.88, -0.09, -1.67, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 75, "t": "2026-11-09T12:22:38.176", "t_unix": 1794194558.176, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 2, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 76, "t": "2026-11-09T12:22:39.505", "t_unix": 1794194559.506, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": 15.0, "hold_id": 25, "hold_n": 1, "held_sec": 0.417, "accepted": true, "measured_before": [-25.04, 58.97, -23.99, 0.17, -39.28, -30.23], "start_source": "hold", "cmd_gap_deg": 2.63, "hold_lead_deg": 2.43, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 58.88, -8.99, 0.08, -36.65, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194559.52779, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 77, "t": "2026-11-09T12:22:39.655", "t_unix": 1794194559.656, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": 15.0, "hold_id": 25, "hold_n": 2, "held_sec": 0.566, "accepted": true, "measured_before": [-25.04, 58.97, -23.99, 0.17, -39.37, -30.23], "start_source": "hold", "cmd_gap_deg": 2.72, "hold_lead_deg": 15.0, "sent": false, "why": "lead_ok", "hold_remaining_deg": 15.0, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 78, "t": "2026-11-09T12:22:39.755", "t_unix": 1794194559.756, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": 15.0, "hold_id": 25, "hold_n": 3, "held_sec": 0.667, "accepted": true, "measured_before": [-25.04, 58.97, -23.11, 0.17, -39.72, -30.23], "start_source": "mixed", "cmd_gap_deg": 3.07, "hold_lead_deg": 14.12, "sent": false, "why": "lead_ok", "hold_remaining_deg": 14.12, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 79, "t": "2026-11-09T12:22:39.871", "t_unix": 1794194559.871, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": 15.0, "hold_id": 25, "hold_n": 4, "held_sec": 0.782, "accepted": true, "released_during_job": true, "measured_before": [-25.04, 58.97, -12.65, 0.17, -40.25, -30.23], "start_source": "mixed", "cmd_gap_deg": 3.6, "hold_lead_deg": 3.66, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 58.88, 2.35, 0.08, -36.65, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194560.0172129, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 80, "t": "2026-11-09T12:22:40.054", "t_unix": 1794194560.055, "button": null, "button_name": null, "kind": "halt", "selected_joint": 2, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 25, "halt_joint": 2, "measured_at_request": [-25.04, 58.97, -23.11, 0.17, -39.72, -30.23], "t_halt": 1794194560.054611, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-25.04, 58.97, -8.17, 0.17, -40.25, -30.23], "moved_after_request_deg": [0.0, 0.0, 14.94, 0.0, -0.53, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 81, "t": "2026-11-09T12:22:42.122", "t_unix": 1794194562.122, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": 15.0, "hold_id": 26, "hold_n": 1, "held_sec": 0.416, "accepted": true, "measured_before": [-25.04, 58.97, -8.17, 0.17, -40.25, -30.23], "start_source": "mixed", "cmd_gap_deg": 3.6, "hold_lead_deg": 0.0, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 58.88, 6.83, 0.08, -36.65, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194562.134165, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 82, "t": "2026-11-09T12:22:42.222", "t_unix": 1794194562.222, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": 15.0, "hold_id": 26, "hold_n": 2, "held_sec": 0.517, "accepted": true, "measured_before": [-25.04, 58.97, -8.17, 0.08, -40.25, -30.23], "start_source": "mixed", "cmd_gap_deg": 3.6, "hold_lead_deg": 15.0, "sent": false, "why": "lead_ok", "hold_remaining_deg": 15.0, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 83, "t": "2026-11-09T12:22:42.324", "t_unix": 1794194562.325, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": 15.0, "hold_id": 26, "hold_n": 3, "held_sec": 0.619, "accepted": true, "measured_before": [-25.04, 58.97, -7.11, 0.08, -40.6, -30.23], "start_source": "mixed", "cmd_gap_deg": 3.95, "hold_lead_deg": 13.94, "sent": false, "why": "lead_ok", "hold_remaining_deg": 13.94, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 84, "t": "2026-11-09T12:22:42.391", "t_unix": 1794194562.392, "button": null, "button_name": null, "kind": "halt", "selected_joint": 2, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 26, "halt_joint": 2, "measured_at_request": [-25.04, 58.97, -7.11, 0.08, -40.6, -30.23], "t_halt": 1794194562.391832, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-25.04, 60.38, -2.81, 0.17, -39.02, -30.23], "moved_after_request_deg": [0.0, 1.41, 4.3, 0.09, 1.58, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 85, "t": "2026-11-09T12:22:50.247", "t_unix": 1794194570.247, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 3, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 86, "t": "2026-11-09T12:22:50.445", "t_unix": 1794194570.445, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 4, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 87, "t": "2026-11-09T12:22:50.717", "t_unix": 1794194570.717, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 5, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 88, "t": "2026-11-09T12:22:51.182", "t_unix": 1794194571.182, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 89, "t": "2026-11-09T12:22:55.342", "t_unix": 1794194575.343, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -1.0, "hold_id": 27, "hold_n": 0, "accepted": true, "measured_before": [-25.04, 60.38, -2.81, 0.17, -40.95, -30.23], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 4.3, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 57.88, -2.81, 0.08, -36.65, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194575.40472, "measured_before_send": [-25.04, 60.38, -2.81, 0.17, -40.95, -30.23], "resends": [0.35, 0.69], "reached": false, "not_moved": true, "reached_angles": [-25.04, 60.38, -2.81, 0.17, -40.95, -30.23], "reach_err": 4.3, "elapsed_sec": 1.02, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 90, "t": "2026-11-09T12:22:56.950", "t_unix": 1794194576.95, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 28, "hold_n": 1, "held_sec": 0.402, "accepted": true, "measured_before": [-25.04, 60.38, -2.81, 0.17, -40.95, -30.23], "start_source": "mixed", "cmd_gap_deg": 4.3, "hold_lead_deg": 2.5, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 45.38, -2.81, 0.08, -36.65, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194576.9677088, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 91, "t": "2026-11-09T12:22:57.117", "t_unix": 1794194577.117, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 28, "hold_n": 2, "held_sec": 0.569, "accepted": true, "measured_before": [-25.04, 54.05, -0.35, 0.17, -40.95, -30.23], "start_source": "mixed", "cmd_gap_deg": 4.3, "hold_lead_deg": 8.67, "sent": false, "why": "lead_ok", "hold_remaining_deg": 8.67, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 92, "t": "2026-11-09T12:22:57.283", "t_unix": 1794194577.284, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 28, "hold_n": 3, "held_sec": 0.735, "accepted": true, "measured_before": [-25.04, 51.94, -0.35, 0.17, -40.95, -30.23], "start_source": "mixed", "cmd_gap_deg": 4.3, "hold_lead_deg": 6.56, "sent": false, "why": "lead_ok", "hold_remaining_deg": 6.56, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 93, "t": "2026-11-09T12:22:57.334", "t_unix": 1794194577.335, "button": null, "button_name": null, "kind": "halt", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 28, "halt_joint": 1, "measured_at_request": [-25.04, 51.94, -0.35, 0.17, -40.95, -30.23], "t_halt": 1794194577.33469, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-25.04, 50.0, 0.08, 0.26, -39.63, -30.14], "moved_after_request_deg": [0.0, -1.94, 0.43, 0.09, 1.32, 0.09], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 94, "t": "2026-11-09T12:22:59.052", "t_unix": 1794194579.052, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 2, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 95, "t": "2026-11-09T12:23:00.201", "t_unix": 1794194580.202, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": 15.0, "hold_id": 29, "hold_n": 1, "held_sec": 0.4, "accepted": true, "measured_before": [-25.04, 50.09, 0.43, 0.26, -39.19, -30.23], "start_source": "hold", "cmd_gap_deg": 2.54, "hold_lead_deg": 3.24, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 50.0, 15.43, 0.08, -36.65, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194580.222341, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 96, "t": "2026-11-09T12:23:00.318", "t_unix": 1794194580.318, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": 15.0, "hold_id": 29, "hold_n": 2, "held_sec": 0.517, "accepted": true, "measured_before": [-25.04, 49.48, 0.43, 0.26, -39.19, -30.23], "start_source": "hold", "cmd_gap_deg": 2.54, "hold_lead_deg": 15.0, "sent": false, "why": "lead_ok", "hold_remaining_deg": 15.0, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 97, "t": "2026-11-09T12:23:00.420", "t_unix": 1794194580.42, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": 15.0, "hold_id": 29, "hold_n": 3, "held_sec": 0.619, "accepted": true, "measured_before": [-25.04, 49.48, 0.43, 0.26, -40.16, -30.23], "start_source": "mixed", "cmd_gap_deg": 3.51, "hold_lead_deg": 15.0, "sent": false, "why": "lead_ok", "hold_remaining_deg": 15.0, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 98, "t": "2026-11-09T12:23:00.521", "t_unix": 1794194580.521, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": 15.0, "hold_id": 29, "hold_n": 4, "held_sec": 0.719, "accepted": true, "released_during_job": true, "measured_before": [-25.04, 49.48, 0.43, 0.26, -40.34, -30.23], "start_source": "mixed", "cmd_gap_deg": 3.69, "hold_lead_deg": 15.0, "command": [-25.32, 50.0, 15.43, 0.08, -36.65, -30.23], "hold_resend": true, "sent": false, "why": "halted_before_send", "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 99, "t": "2026-11-09T12:23:00.588", "t_unix": 1794194580.589, "button": null, "button_name": null, "kind": "halt", "selected_joint": 2, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 29, "halt_joint": 2, "measured_at_request": [-25.04, 49.48, 0.43, 0.26, -40.16, -30.23], "t_halt": 1794194580.5887349, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-25.04, 49.13, 9.75, 0.26, -38.58, -30.23], "moved_after_request_deg": [0.0, -0.35, 9.32, 0.0, 1.58, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 100, "t": "2026-11-09T12:23:07.218", "t_unix": 1794194587.218, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": 1.0, "hold_id": 30, "hold_n": 0, "accepted": true, "measured_before": [-25.04, 49.13, 9.75, 0.26, -39.63, -30.23], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 2.98, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 50.0, 10.75, 0.08, -36.65, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194587.248559, "measured_before_send": [-25.04, 49.13, 9.75, 0.26, -39.63, -30.23], "resends": [], "reached": true, "reached_angles": [-25.04, 47.81, 10.72, 0.26, -41.92, -30.23], "reach_err": 5.27, "elapsed_sec": 0.16, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 101, "t": "2026-11-09T12:23:09.956", "t_unix": 1794194589.956, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": 15.0, "hold_id": 31, "hold_n": 1, "held_sec": 0.411, "accepted": true, "measured_before": [-25.04, 47.81, 11.25, 0.26, -42.01, -30.23], "start_source": "mixed", "cmd_gap_deg": 5.36, "hold_lead_deg": 0.5, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 50.0, 26.25, 0.08, -36.65, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194589.972919, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 102, "t": "2026-11-09T12:23:10.056", "t_unix": 1794194590.057, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": 15.0, "hold_id": 31, "hold_n": 2, "held_sec": 0.512, "accepted": true, "measured_before": [-25.04, 47.81, 11.25, 0.26, -42.01, -30.23], "start_source": "mixed", "cmd_gap_deg": 5.36, "hold_lead_deg": 15.0, "sent": false, "why": "lead_ok", "hold_remaining_deg": 15.0, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 103, "t": "2026-11-09T12:23:10.172", "t_unix": 1794194590.173, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": 15.0, "hold_id": 31, "hold_n": 3, "held_sec": 0.627, "accepted": true, "released_during_job": true, "measured_before": [-25.04, 47.81, 18.1, 0.26, -42.01, -30.23], "start_source": "mixed", "cmd_gap_deg": 5.36, "hold_lead_deg": 8.15, "sent": false, "why": "lead_ok", "hold_remaining_deg": 8.15, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 104, "t": "2026-11-09T12:23:10.324", "t_unix": 1794194590.325, "button": null, "button_name": null, "kind": "halt", "selected_joint": 2, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 31, "halt_joint": 2, "measured_at_request": [-25.04, 47.81, 11.25, 0.26, -42.01, -30.23], "t_halt": 1794194590.324917, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-25.04, 48.42, 21.35, 0.08, -42.27, -30.58], "moved_after_request_deg": [0.0, 0.61, 10.1, -0.18, -0.26, -0.35], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 105, "t": "2026-11-09T12:23:13.871", "t_unix": 1794194593.872, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 3, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 106, "t": "2026-11-09T12:23:15.018", "t_unix": 1794194595.019, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 4, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 107, "t": "2026-11-09T12:23:15.150", "t_unix": 1794194595.151, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 5, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 108, "t": "2026-11-09T12:23:15.385", "t_unix": 1794194595.385, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 109, "t": "2026-11-09T12:23:16.635", "t_unix": 1794194596.635, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 32, "hold_n": 1, "held_sec": 0.402, "accepted": true, "measured_before": [-25.04, 48.42, 21.35, 0.08, -42.27, -30.67], "start_source": "mixed", "cmd_gap_deg": 5.62, "hold_lead_deg": 1.58, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 33.42, 21.35, 0.08, -36.65, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194596.653588, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 110, "t": "2026-11-09T12:23:16.735", "t_unix": 1794194596.736, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 32, "hold_n": 2, "held_sec": 0.503, "accepted": true, "measured_before": [-25.04, 48.07, 21.35, 0.08, -42.01, -30.49], "start_source": "mixed", "cmd_gap_deg": 5.36, "hold_lead_deg": 14.65, "sent": false, "why": "lead_ok", "hold_remaining_deg": 14.65, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 111, "t": "2026-11-09T12:23:16.851", "t_unix": 1794194596.852, "button": null, "button_name": null, "kind": "halt", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 32, "halt_joint": 1, "measured_at_request": [-25.04, 48.07, 21.35, 0.08, -42.01, -30.49], "t_halt": 1794194596.851743, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-25.04, 44.38, 24.6, 0.08, -39.37, -30.58], "moved_after_request_deg": [0.0, -3.69, 3.25, 0.0, 2.64, -0.09], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 112, "t": "2026-11-09T12:23:18.094", "t_unix": 1794194598.094, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 33, "hold_n": 1, "held_sec": 0.4, "accepted": true, "measured_before": [-25.04, 44.47, 24.6, 0.0, -39.28, -30.76], "start_source": "mixed", "cmd_gap_deg": 3.25, "hold_lead_deg": 0.09, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 59.47, 21.35, 0.08, -36.65, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194598.112295, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 113, "t": "2026-11-09T12:23:18.262", "t_unix": 1794194598.263, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 33, "hold_n": 2, "held_sec": 0.569, "accepted": true, "measured_before": [-25.04, 42.36, 24.6, 0.08, -39.55, -30.67], "start_source": "mixed", "cmd_gap_deg": 3.25, "hold_lead_deg": 17.11, "sent": false, "why": "lead_ok", "hold_remaining_deg": 17.11, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 114, "t": "2026-11-09T12:23:18.364", "t_unix": 1794194598.365, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 33, "hold_n": 3, "held_sec": 0.671, "accepted": true, "released_during_job": true, "measured_before": [-25.04, 44.38, 24.6, 0.17, -39.72, -30.58], "start_source": "mixed", "cmd_gap_deg": 3.25, "hold_lead_deg": 15.09, "sent": false, "why": "lead_ok", "hold_remaining_deg": 15.09, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 115, "t": "2026-11-09T12:23:18.397", "t_unix": 1794194598.398, "button": null, "button_name": null, "kind": "halt", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 33, "halt_joint": 1, "measured_at_request": [-25.04, 42.36, 24.6, 0.08, -39.55, -30.67], "t_halt": 1794194598.397731, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-25.04, 47.54, 24.34, -0.08, -43.5, -30.76], "moved_after_request_deg": [0.0, 5.18, -0.26, -0.16, -3.95, -0.09], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 116, "t": "2026-11-09T12:23:20.046", "t_unix": 1794194600.046, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 2, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 117, "t": "2026-11-09T12:23:21.612", "t_unix": 1794194601.613, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -15.0, "hold_id": 34, "hold_n": 1, "held_sec": 0.415, "accepted": true, "released_during_job": true, "measured_before": [-25.04, 47.63, 24.34, -0.08, -43.5, -30.76], "start_source": "mixed", "cmd_gap_deg": 6.85, "hold_lead_deg": 2.99, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 47.54, 9.34, 0.08, -36.65, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194601.629225, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 118, "t": "2026-11-09T12:23:21.663", "t_unix": 1794194601.663, "button": null, "button_name": null, "kind": "halt", "selected_joint": 2, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "released_while_sending", "hold_id": 34, "halt_joint": 2, "measured_at_request": [-25.04, 47.63, 24.34, -0.08, -43.5, -30.76], "t_halt": 1794194601.663625, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-25.04, 48.16, 24.34, -0.08, -44.64, -30.76], "moved_after_request_deg": [0.0, 0.53, 0.0, 0.0, -1.14, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 119, "t": "2026-11-09T12:23:22.646", "t_unix": 1794194602.647, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -15.0, "hold_id": 35, "hold_n": 1, "held_sec": 0.401, "accepted": true, "measured_before": [-25.04, 48.16, 24.34, -0.08, -44.64, -30.76], "start_source": "mixed", "cmd_gap_deg": 7.99, "hold_lead_deg": 0.0, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 47.54, 9.34, 0.08, -36.65, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194602.6651678, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 120, "t": "2026-11-09T12:23:22.762", "t_unix": 1794194602.762, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -15.0, "hold_id": 35, "hold_n": 2, "held_sec": 0.517, "accepted": true, "measured_before": [-25.04, 48.6, 24.25, -0.08, -44.56, -30.76], "start_source": "mixed", "cmd_gap_deg": 7.91, "hold_lead_deg": 14.91, "sent": false, "why": "lead_ok", "hold_remaining_deg": 14.91, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 121, "t": "2026-11-09T12:23:22.878", "t_unix": 1794194602.878, "button": null, "button_name": null, "kind": "halt", "selected_joint": 2, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 35, "halt_joint": 2, "measured_at_request": [-25.04, 48.6, 24.25, -0.08, -44.56, -30.76], "t_halt": 1794194602.878379, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-25.04, 50.18, 18.01, 0.08, -41.13, -30.76], "moved_after_request_deg": [0.0, 1.58, -6.24, 0.16, 3.43, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 122, "t": "2026-11-09T12:23:23.793", "t_unix": 1794194603.794, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -15.0, "hold_id": 36, "hold_n": 1, "held_sec": 0.401, "accepted": true, "measured_before": [-25.04, 50.18, 18.01, 0.08, -41.13, -30.76], "start_source": "mixed", "cmd_gap_deg": 4.48, "hold_lead_deg": 0.0, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 47.54, 3.01, 0.08, -36.65, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194603.814003, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 123, "t": "2026-11-09T12:23:23.909", "t_unix": 1794194603.909, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -15.0, "hold_id": 36, "hold_n": 2, "held_sec": 0.517, "accepted": true, "measured_before": [-25.04, 50.18, 17.75, 0.08, -40.95, -30.76], "start_source": "mixed", "cmd_gap_deg": 4.3, "hold_lead_deg": 14.74, "sent": false, "why": "lead_ok", "hold_remaining_deg": 14.74, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 124, "t": "2026-11-09T12:23:24.010", "t_unix": 1794194604.01, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -15.0, "hold_id": 36, "hold_n": 3, "held_sec": 0.618, "accepted": true, "measured_before": [-25.04, 50.44, 17.75, 0.08, -39.72, -30.58], "start_source": "mixed", "cmd_gap_deg": 3.07, "hold_lead_deg": 14.74, "sent": false, "why": "lead_ok", "hold_remaining_deg": 14.74, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 125, "t": "2026-11-09T12:23:24.112", "t_unix": 1794194604.112, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -15.0, "hold_id": 36, "hold_n": 4, "held_sec": 0.72, "accepted": true, "released_during_job": true, "measured_before": [-25.04, 50.53, 17.75, 0.08, -39.72, -30.58], "start_source": "mixed", "cmd_gap_deg": 3.07, "hold_lead_deg": 14.74, "command": [-25.32, 47.54, 3.01, 0.08, -36.65, -30.23], "hold_resend": true, "sent": true, "reached": null, "no_check": true, "t_send": 1794194604.17397, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 126, "t": "2026-11-09T12:23:24.212", "t_unix": 1794194604.212, "button": null, "button_name": null, "kind": "halt", "selected_joint": 2, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 36, "halt_joint": 2, "measured_at_request": [-25.04, 50.44, 17.75, 0.08, -39.72, -30.58], "t_halt": 1794194604.212405, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-25.04, 51.67, 6.32, 0.26, -38.4, -30.58], "moved_after_request_deg": [0.0, 1.23, -11.43, 0.18, 1.32, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 127, "t": "2026-11-09T12:23:27.847", "t_unix": 1794194607.848, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 3, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 128, "t": "2026-11-09T12:23:28.048", "t_unix": 1794194608.048, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 4, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 129, "t": "2026-11-09T12:23:28.265", "t_unix": 1794194608.265, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 5, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 130, "t": "2026-11-09T12:23:28.846", "t_unix": 1794194608.847, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 131, "t": "2026-11-09T12:23:30.593", "t_unix": 1794194610.594, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 1.0, "hold_id": 37, "hold_n": 0, "accepted": true, "measured_before": [-25.04, 51.76, 6.94, 0.26, -38.32, -30.58], "start_source": "measured", "others_from_measured": [], "cmd_gap_deg": 4.22, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 52.76, 6.32, 0.08, -36.65, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194610.624683, "measured_before_send": [-25.04, 51.76, 6.94, 0.26, -38.32, -30.58], "resends": [], "reached": false, "settled": true, "reached_angles": [-25.04, 53.87, 4.21, 0.26, -41.92, -30.58], "reach_err": 5.27, "elapsed_sec": 0.66, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 132, "t": "2026-11-09T12:23:32.206", "t_unix": 1794194612.206, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 38, "hold_n": 1, "held_sec": 0.415, "accepted": true, "measured_before": [-25.04, 53.87, 4.21, 0.26, -41.92, -30.58], "start_source": "mixed", "cmd_gap_deg": 5.27, "hold_lead_deg": 1.11, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 38.87, 6.32, 0.08, -36.65, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194612.229109, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 133, "t": "2026-11-09T12:23:32.321", "t_unix": 1794194612.321, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 38, "hold_n": 2, "held_sec": 0.53, "accepted": true, "measured_before": [-25.04, 52.11, 4.21, 0.26, -41.92, -30.58], "start_source": "mixed", "cmd_gap_deg": 5.27, "hold_lead_deg": 13.24, "sent": false, "why": "lead_ok", "hold_remaining_deg": 13.24, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 134, "t": "2026-11-09T12:23:32.505", "t_unix": 1794194612.506, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 38, "hold_n": 3, "held_sec": 0.715, "accepted": true, "released_during_job": true, "measured_before": [-25.04, 43.5, 4.21, 0.26, -41.92, -30.58], "start_source": "mixed", "cmd_gap_deg": 5.27, "hold_lead_deg": 4.63, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 28.5, 6.32, 0.08, -36.65, -30.23], "sent": false, "why": "halted_before_send", "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 135, "t": "2026-11-09T12:23:32.655", "t_unix": 1794194612.656, "button": null, "button_name": null, "kind": "halt", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 38, "halt_joint": 1, "measured_at_request": [-25.04, 52.11, 4.21, 0.26, -41.92, -30.58], "t_halt": 1794194612.655926, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-25.04, 42.62, 4.65, 0.26, -40.86, -30.58], "moved_after_request_deg": [0.0, -9.49, 0.44, 0.0, 1.06, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 136, "t": "2026-11-09T12:23:33.456", "t_unix": 1794194613.456, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 39, "hold_n": 1, "held_sec": 0.416, "accepted": true, "measured_before": [-25.04, 42.89, 5.0, 0.26, -40.16, -30.58], "start_source": "mixed", "cmd_gap_deg": 3.51, "hold_lead_deg": 0.27, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 57.89, 6.32, 0.08, -36.65, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194613.467372, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 137, "t": "2026-11-09T12:23:33.558", "t_unix": 1794194613.558, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 39, "hold_n": 2, "held_sec": 0.518, "accepted": true, "measured_before": [-25.04, 42.62, 5.0, 0.26, -40.16, -30.58], "start_source": "mixed", "cmd_gap_deg": 3.51, "hold_lead_deg": 15.27, "sent": false, "why": "lead_ok", "hold_remaining_deg": 15.27, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 138, "t": "2026-11-09T12:23:33.673", "t_unix": 1794194613.674, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 39, "hold_n": 3, "held_sec": 0.634, "accepted": true, "released_during_job": true, "measured_before": [-25.04, 48.86, 4.92, 0.26, -40.16, -30.58], "start_source": "mixed", "cmd_gap_deg": 3.51, "hold_lead_deg": 9.03, "sent": false, "why": "lead_ok", "hold_remaining_deg": 9.03, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 139, "t": "2026-11-09T12:23:33.824", "t_unix": 1794194613.824, "button": null, "button_name": null, "kind": "halt", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 39, "halt_joint": 1, "measured_at_request": [-25.04, 42.62, 5.0, 0.26, -40.16, -30.58], "t_halt": 1794194613.824299, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-25.04, 52.47, 5.62, 0.26, -38.49, -30.58], "moved_after_request_deg": [0.0, 9.85, 0.62, 0.0, 1.67, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 140, "t": "2026-11-09T12:23:34.656", "t_unix": 1794194614.656, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 1.0, "hold_id": 40, "hold_n": 0, "accepted": true, "measured_before": [-25.04, 52.47, 5.62, 0.26, -38.49, -30.58], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 1.84, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 53.47, 6.32, 0.08, -36.65, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194614.696648, "measured_before_send": [-25.04, 52.47, 5.62, 0.26, -38.49, -30.58], "resends": [], "reached": true, "reached_angles": [-25.04, 53.61, 5.53, 0.26, -39.19, -30.58], "reach_err": 2.54, "elapsed_sec": 0.09, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 141, "t": "2026-11-09T12:23:35.483", "t_unix": 1794194615.483, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 1.0, "hold_id": 41, "hold_n": 0, "accepted": true, "measured_before": [-25.04, 54.66, 4.65, 0.26, -39.28, -30.58], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 2.63, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 54.47, 6.32, 0.08, -36.65, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194615.510457, "measured_before_send": [-25.04, 54.66, 4.65, 0.26, -39.28, -30.58], "resends": [], "reached": false, "settled": true, "reached_angles": [-25.04, 55.63, 4.65, 0.26, -39.55, -30.58], "reach_err": 2.9, "elapsed_sec": 0.35, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 142, "t": "2026-11-09T12:23:36.183", "t_unix": 1794194616.184, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 1.0, "hold_id": 42, "hold_n": 0, "accepted": true, "measured_before": [-25.04, 55.63, 4.65, 0.26, -39.55, -30.58], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 2.9, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 55.47, 6.32, 0.08, -36.65, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194616.2205381, "measured_before_send": [-25.04, 55.63, 4.65, 0.26, -39.55, -30.58], "resends": [], "reached": true, "reached_angles": [-25.04, 55.63, 4.65, 0.26, -39.55, -30.58], "reach_err": 2.9, "elapsed_sec": 0.02, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 143, "t": "2026-11-09T12:23:37.101", "t_unix": 1794194617.102, "button": 10, "button_name": "r1", "kind": "modifier", "selected_joint": 1, "step_deg": 2.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 144, "t": "2026-11-09T12:23:37.539", "t_unix": 1794194617.54, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 2.0, "execute": true, "joint": 1, "delta": 2.0, "hold_id": 43, "hold_n": 0, "accepted": true, "measured_before": [-25.04, 56.6, 4.57, 0.26, -39.9, -30.49], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 3.25, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 57.47, 6.32, 0.08, -36.65, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194617.582269, "measured_before_send": [-25.04, 56.6, 4.57, 0.26, -39.9, -30.49], "resends": [], "reached": true, "reached_angles": [-25.04, 57.74, 4.57, 0.26, -40.51, -30.49], "reach_err": 3.86, "elapsed_sec": 0.09, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 145, "t": "2026-11-09T12:23:45.698", "t_unix": 1794194625.698, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 2, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 146, "t": "2026-11-09T12:23:47.227", "t_unix": 1794194627.227, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -1.0, "hold_id": 44, "hold_n": 0, "accepted": true, "measured_before": [-25.04, 58.53, 4.57, 0.17, -40.78, -30.23], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 4.13, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 57.47, 5.32, 0.08, -36.65, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194627.263983, "measured_before_send": [-25.04, 58.53, 4.57, 0.17, -40.78, -30.23], "resends": [], "reached": true, "reached_angles": [-25.04, 58.53, 4.83, 0.17, -40.86, -30.23], "reach_err": 4.21, "elapsed_sec": 0.15, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 147, "t": "2026-11-09T12:23:48.513", "t_unix": 1794194628.513, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -1.0, "hold_id": 45, "hold_n": 0, "accepted": true, "measured_before": [-25.04, 58.53, 5.71, 0.0, -42.09, -30.23], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 5.44, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 57.47, 4.32, 0.08, -36.65, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194628.540591, "measured_before_send": [-25.04, 58.53, 5.71, 0.0, -42.09, -30.23], "resends": [0.34, 0.74], "reached": false, "not_moved": true, "reached_angles": [-25.04, 58.53, 5.71, 0.0, -42.09, -30.23], "reach_err": 5.44, "elapsed_sec": 1.05, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 148, "t": "2026-11-09T12:23:50.089", "t_unix": 1794194630.09, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": 1.0, "hold_id": 46, "hold_n": 0, "accepted": true, "measured_before": [-25.04, 58.53, 5.71, 0.0, -42.09, -30.23], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 5.44, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 57.47, 5.32, 0.08, -36.65, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194630.1175308, "measured_before_send": [-25.04, 58.53, 5.71, 0.0, -42.09, -30.23], "resends": [], "reached": true, "reached_angles": [-25.04, 58.53, 5.71, 0.0, -42.09, -30.23], "reach_err": 5.44, "elapsed_sec": 0.01, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 149, "t": "2026-11-09T12:23:50.992", "t_unix": 1794194630.993, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": 1.0, "hold_id": 47, "hold_n": 0, "accepted": true, "measured_before": [-25.04, 58.53, 5.71, 0.0, -42.09, -30.23], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 5.44, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 57.47, 6.32, 0.08, -36.65, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194631.020546, "measured_before_send": [-25.04, 58.53, 5.71, 0.0, -42.09, -30.23], "resends": [], "reached": true, "reached_angles": [-25.04, 58.53, 6.06, 0.0, -42.09, -30.23], "reach_err": 5.44, "elapsed_sec": 0.16, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 150, "t": "2026-11-09T12:23:52.044", "t_unix": 1794194632.045, "button": 10, "button_name": "r1", "kind": "modifier", "selected_joint": 2, "step_deg": 2.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 151, "t": "2026-11-09T12:23:52.196", "t_unix": 1794194632.196, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 2.0, "execute": true, "joint": 2, "delta": 2.0, "hold_id": 48, "hold_n": 0, "accepted": true, "measured_before": [-25.04, 58.53, 6.15, -0.17, -42.27, -30.23], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 5.62, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 57.47, 8.32, 0.08, -36.65, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194632.267117, "measured_before_send": [-25.04, 58.53, 6.15, -0.17, -42.27, -30.23], "resends": [], "reached": true, "reached_angles": [-25.04, 58.53, 7.99, -0.17, -43.85, -30.23], "reach_err": 7.2, "elapsed_sec": 0.09, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 152, "t": "2026-11-09T12:23:54.044", "t_unix": 1794194634.044, "button": 10, "button_name": "r1", "kind": "modifier", "selected_joint": 2, "step_deg": 2.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 153, "t": "2026-11-09T12:23:54.346", "t_unix": 1794194634.346, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 2.0, "execute": true, "joint": 2, "delta": 15.0, "hold_id": 49, "hold_n": 1, "held_sec": 0.403, "accepted": true, "released_during_job": true, "measured_before": [-25.04, 58.53, 7.99, -0.17, -43.85, -30.23], "start_source": "mixed", "cmd_gap_deg": 7.2, "hold_lead_deg": 0.33, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 57.47, 22.99, 0.08, -36.65, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194634.364392, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 154, "t": "2026-11-09T12:23:54.397", "t_unix": 1794194634.398, "button": null, "button_name": null, "kind": "halt", "selected_joint": 2, "step_deg": 2.0, "execute": true, "accepted": true, "halt_reason": "released_while_sending", "hold_id": 49, "halt_joint": 2, "measured_at_request": [-25.04, 58.53, 7.99, -0.17, -43.85, -30.23], "t_halt": 1794194634.397904, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-25.04, 59.06, 7.99, -0.17, -44.47, -30.41], "moved_after_request_deg": [0.0, 0.53, 0.0, 0.0, -0.62, -0.18], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 155, "t": "2026-11-09T12:23:55.398", "t_unix": 1794194635.398, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 2.0, "execute": true, "joint": 2, "delta": 2.0, "hold_id": 50, "hold_n": 0, "accepted": true, "measured_before": [-25.04, 59.15, 7.99, -0.17, -44.73, -30.49], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 8.08, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 57.47, 9.99, 0.08, -36.65, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194635.440337, "measured_before_send": [-25.04, 59.15, 7.99, -0.17, -44.73, -30.49], "resends": [], "reached": false, "settled": true, "reached_angles": [-25.04, 58.62, 9.05, -0.35, -44.12, -30.58], "reach_err": 7.47, "elapsed_sec": 0.46, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 156, "t": "2026-11-09T12:23:57.827", "t_unix": 1794194637.828, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 3, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 157, "t": "2026-11-09T12:23:58.543", "t_unix": 1794194638.544, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 3, "step_deg": 1.0, "execute": true, "joint": 3, "delta": -1.0, "hold_id": 51, "hold_n": 0, "accepted": true, "measured_before": [-25.04, 58.62, 9.05, -0.43, -43.85, -30.49], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 7.2, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 57.47, 9.99, -0.92, -36.65, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194638.576569, "measured_before_send": [-25.04, 58.62, 9.05, -0.43, -43.85, -30.49], "resends": [], "reached": true, "reached_angles": [-25.04, 58.62, 9.05, -0.43, -43.85, -30.49], "reach_err": 7.2, "elapsed_sec": 0.02, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 158, "t": "2026-11-09T12:23:59.727", "t_unix": 1794194639.727, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 3, "step_deg": 1.0, "execute": true, "joint": 3, "delta": -1.0, "hold_id": 52, "hold_n": 0, "accepted": true, "measured_before": [-25.04, 58.27, 9.05, -0.43, -43.24, -30.49], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 6.59, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 57.47, 9.99, -1.92, -36.65, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194639.756565, "measured_before_send": [-25.04, 58.27, 9.05, -0.43, -43.15, -30.49], "resends": [], "reached": false, "settled": true, "reached_angles": [-25.31, 58.27, 9.05, -1.23, -43.15, -30.41], "reach_err": 6.5, "elapsed_sec": 0.45, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 159, "t": "2026-11-09T12:24:01.694", "t_unix": 1794194641.694, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 4, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 160, "t": "2026-11-09T12:24:03.194", "t_unix": 1794194643.194, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -1.0, "hold_id": 53, "hold_n": 0, "accepted": true, "measured_before": [-25.4, 58.18, 9.05, -1.4, -42.62, -30.32], "start_source": "measured", "others_from_measured": [], "cmd_gap_deg": 5.97, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 57.47, 9.99, -1.92, -43.62, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194643.2245078, "measured_before_send": [-25.4, 58.18, 9.05, -1.4, -42.62, -30.32], "resends": [0.35, 0.69], "reached": false, "not_moved": true, "reached_angles": [-25.4, 58.18, 9.05, -1.4, -42.62, -30.32], "reach_err": 1.0, "elapsed_sec": 1.0, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 161, "t": "2026-11-09T12:24:04.345", "t_unix": 1794194644.345, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 54, "hold_n": 1, "held_sec": 0.416, "accepted": true, "released_during_job": true, "measured_before": [-25.4, 58.18, 9.05, -1.4, -42.62, -30.32], "start_source": "hold", "cmd_gap_deg": 0.94, "hold_lead_deg": 1.0, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 57.47, 9.99, -1.92, -57.62, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194644.358019, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 162, "t": "2026-11-09T12:24:04.395", "t_unix": 1794194644.396, "button": null, "button_name": null, "kind": "halt", "selected_joint": 4, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "released_while_sending", "hold_id": 54, "halt_joint": 4, "measured_at_request": [-25.4, 58.18, 9.05, -1.4, -42.62, -30.32], "t_halt": 1794194644.396076, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-25.4, 58.35, 9.05, -1.4, -43.76, -30.32], "moved_after_request_deg": [0.0, 0.17, 0.0, 0.0, -1.14, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 163, "t": "2026-11-09T12:24:05.528", "t_unix": 1794194645.528, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 55, "hold_n": 1, "held_sec": 0.401, "accepted": true, "measured_before": [-25.4, 58.62, 9.05, -1.31, -43.76, -30.32], "start_source": "hold", "cmd_gap_deg": 1.15, "hold_lead_deg": 0.0, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 57.47, 9.99, -1.92, -58.76, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194645.543982, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 164, "t": "2026-11-09T12:24:05.697", "t_unix": 1794194645.697, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 55, "hold_n": 2, "held_sec": 0.57, "accepted": true, "measured_before": [-25.4, 58.53, 9.14, -1.31, -44.82, -30.32], "start_source": "hold", "cmd_gap_deg": 1.06, "hold_lead_deg": 13.94, "sent": false, "why": "lead_ok", "hold_remaining_deg": 13.94, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 165, "t": "2026-11-09T12:24:05.747", "t_unix": 1794194645.747, "button": null, "button_name": null, "kind": "halt", "selected_joint": 4, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 55, "halt_joint": 4, "measured_at_request": [-25.4, 58.53, 9.14, -1.31, -44.82, -30.32], "t_halt": 1794194645.747324, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-25.4, 59.23, 9.84, -1.23, -47.28, -30.41], "moved_after_request_deg": [0.0, 0.7, 0.7, 0.08, -2.46, -0.09], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 166, "t": "2026-11-09T12:24:06.450", "t_unix": 1794194646.45, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -1.0, "hold_id": 56, "hold_n": 0, "accepted": true, "measured_before": [-25.4, 59.23, 9.84, -1.23, -47.37, -30.41], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 1.76, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 57.47, 9.99, -1.92, -48.28, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194646.488446, "measured_before_send": [-25.4, 59.23, 9.84, -1.23, -47.37, -30.41], "resends": [0.33, 0.67], "reached": false, "not_moved": true, "reached_angles": [-25.4, 59.15, 9.84, -1.23, -47.37, -30.41], "reach_err": 1.68, "elapsed_sec": 0.99, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 168, "t": "2026-11-09T12:24:07.849", "t_unix": 1794194647.85, "button": 10, "button_name": "r1", "kind": "modifier", "selected_joint": 4, "step_deg": 2.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 167, "t": "2026-11-09T12:24:07.517", "t_unix": 1794194647.518, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -1.0, "hold_id": 57, "hold_n": 0, "accepted": true, "measured_before": [-25.4, 59.15, 9.84, -1.23, -47.37, -30.41], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 1.68, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 57.47, 9.99, -1.92, -49.28, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194647.5686002, "measured_before_send": [-25.4, 59.15, 9.84, -1.23, -47.37, -30.41], "resends": [], "reached": false, "settled": true, "reached_angles": [-25.4, 59.15, 9.84, -1.31, -47.72, -30.41], "reach_err": 1.68, "elapsed_sec": 0.38, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 169, "t": "2026-11-09T12:24:08.397", "t_unix": 1794194648.397, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 2.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 58, "hold_n": 1, "held_sec": 0.415, "accepted": true, "measured_before": [-25.4, 59.15, 9.84, -1.31, -47.81, -30.41], "start_source": "hold", "cmd_gap_deg": 1.68, "hold_lead_deg": 1.47, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 57.47, 9.99, -1.92, -62.81, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194648.408792, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 170, "t": "2026-11-09T12:24:08.497", "t_unix": 1794194648.497, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 2.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 58, "hold_n": 2, "held_sec": 0.515, "accepted": true, "released_during_job": true, "measured_before": [-25.4, 59.15, 9.93, -1.31, -50.09, -30.41], "start_source": "hold", "cmd_gap_deg": 1.68, "hold_lead_deg": 12.72, "sent": false, "why": "lead_ok", "hold_remaining_deg": 12.72, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 171, "t": "2026-11-09T12:24:08.647", "t_unix": 1794194648.648, "button": null, "button_name": null, "kind": "halt", "selected_joint": 4, "step_deg": 2.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 58, "halt_joint": 4, "measured_at_request": [-25.4, 59.15, 9.84, -1.31, -47.81, -30.41], "t_halt": 1794194648.648076, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-25.4, 60.29, 10.01, -1.23, -51.76, -30.41], "moved_after_request_deg": [0.0, 1.14, 0.17, 0.08, -3.95, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 172, "t": "2026-11-09T12:24:09.687", "t_unix": 1794194649.687, "button": 10, "button_name": "r1", "kind": "modifier", "selected_joint": 4, "step_deg": 2.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 173, "t": "2026-11-09T12:24:10.089", "t_unix": 1794194650.09, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 2.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 59, "hold_n": 1, "held_sec": 0.402, "accepted": true, "measured_before": [-25.4, 60.38, 10.01, -1.23, -51.41, -30.41], "start_source": "hold", "cmd_gap_deg": 2.91, "hold_lead_deg": 0.35, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 57.47, 9.99, -1.92, -66.41, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194650.1060102, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 174, "t": "2026-11-09T12:24:10.189", "t_unix": 1794194650.19, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 2.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 59, "hold_n": 2, "held_sec": 0.503, "accepted": true, "measured_before": [-25.4, 60.38, 10.01, -1.23, -51.5, -30.41], "start_source": "hold", "cmd_gap_deg": 2.91, "hold_lead_deg": 14.91, "sent": false, "why": "lead_ok", "hold_remaining_deg": 14.91, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 175, "t": "2026-11-09T12:24:10.289", "t_unix": 1794194650.29, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 2.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 59, "hold_n": 3, "held_sec": 0.603, "accepted": true, "measured_before": [-25.4, 60.2, 10.01, -1.23, -57.39, -30.41], "start_source": "hold", "cmd_gap_deg": 2.73, "hold_lead_deg": 9.02, "sent": false, "why": "lead_ok", "hold_remaining_deg": 9.02, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 176, "t": "2026-11-09T12:24:10.405", "t_unix": 1794194650.406, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 2.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 59, "hold_n": 4, "held_sec": 0.719, "accepted": true, "released_during_job": true, "measured_before": [-25.4, 60.02, 10.01, -1.23, -61.96, -30.41], "start_source": "hold", "cmd_gap_deg": 2.55, "hold_lead_deg": 4.45, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 57.47, 9.99, -1.92, -76.96, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194650.438175, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 177, "t": "2026-11-09T12:24:10.471", "t_unix": 1794194650.471, "button": null, "button_name": null, "kind": "halt", "selected_joint": 4, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 59, "halt_joint": 4, "measured_at_request": [-25.4, 60.2, 10.01, -1.23, -57.39, -30.41], "t_halt": 1794194650.471367, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-25.4, 61.25, 10.01, -1.23, -62.05, -30.41], "moved_after_request_deg": [0.0, 1.05, 0.0, 0.0, -4.66, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 178, "t": "2026-11-09T12:24:14.032", "t_unix": 1794194654.032, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 5, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 179, "t": "2026-11-09T12:24:14.183", "t_unix": 1794194654.183, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 180, "t": "2026-11-09T12:24:15.646", "t_unix": 1794194655.647, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 1.0, "hold_id": 60, "hold_n": 0, "accepted": true, "measured_before": [-25.4, 61.25, 10.01, -1.23, -62.13, -30.41], "start_source": "measured", "others_from_measured": [], "cmd_gap_deg": 3.78, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 62.25, 9.99, -1.92, -62.05, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194655.6805398, "measured_before_send": [-25.4, 61.25, 10.01, -1.23, -62.13, -30.41], "resends": [], "reached": false, "settled": true, "reached_angles": [-25.4, 63.45, 10.01, -1.14, -66.0, -30.41], "reach_err": 3.95, "elapsed_sec": 0.62, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 181, "t": "2026-11-09T12:24:17.035", "t_unix": 1794194657.036, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 1.0, "hold_id": 61, "hold_n": 0, "accepted": true, "measured_before": [-25.4, 63.45, 10.01, -1.23, -66.0, -30.41], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 3.95, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 63.25, 9.99, -1.92, -62.05, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194657.0644622, "measured_before_send": [-25.4, 63.45, 10.01, -1.23, -66.0, -30.41], "resends": [], "reached": true, "reached_angles": [-25.4, 63.45, 10.01, -1.23, -66.0, -30.41], "reach_err": 3.95, "elapsed_sec": 0.02, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 182, "t": "2026-11-09T12:24:18.182", "t_unix": 1794194658.183, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 62, "hold_n": 1, "held_sec": 0.402, "accepted": true, "measured_before": [-25.4, 64.24, 10.01, -1.31, -66.0, -30.41], "start_source": "mixed", "cmd_gap_deg": 3.95, "hold_lead_deg": 0.99, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 79.24, 9.99, -1.92, -62.05, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194658.2042, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 183, "t": "2026-11-09T12:24:18.362", "t_unix": 1794194658.363, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 62, "hold_n": 2, "held_sec": 0.582, "accepted": true, "measured_before": [-25.4, 66.09, 10.01, -1.31, -66.0, -30.41], "start_source": "mixed", "cmd_gap_deg": 3.95, "hold_lead_deg": 13.15, "sent": false, "why": "lead_ok", "hold_remaining_deg": 13.15, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 184, "t": "2026-11-09T12:24:18.446", "t_unix": 1794194658.447, "button": null, "button_name": null, "kind": "halt", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 62, "halt_joint": 1, "measured_at_request": [-25.4, 66.09, 10.01, -1.31, -66.0, -30.41], "t_halt": 1794194658.446831, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-25.4, 70.22, 10.01, -1.4, -67.93, -30.05], "moved_after_request_deg": [0.0, 4.13, 0.0, -0.09, -1.93, 0.36], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 185, "t": "2026-11-09T12:24:19.833", "t_unix": 1794194659.834, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -1.0, "hold_id": 63, "hold_n": 0, "accepted": true, "measured_before": [-25.4, 70.22, 10.01, -1.4, -67.93, -29.97], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 5.88, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 69.22, 9.99, -1.92, -62.05, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194659.862689, "measured_before_send": [-25.4, 70.22, 10.01, -1.4, -67.93, -29.97], "resends": [0.4, 0.74], "reached": false, "not_moved": true, "reached_angles": [-25.4, 70.22, 10.01, -1.4, -67.85, -29.97], "reach_err": 5.8, "elapsed_sec": 1.05, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 186, "t": "2026-11-09T12:24:20.949", "t_unix": 1794194660.95, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -1.0, "hold_id": 64, "hold_n": 0, "accepted": true, "measured_before": [-25.4, 70.22, 10.01, -1.4, -67.85, -29.97], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 5.8, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 68.22, 9.99, -1.92, -62.05, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194660.9885619, "measured_before_send": [-25.4, 70.22, 10.01, -1.4, -67.85, -29.97], "resends": [0.4, 0.81], "reached": false, "not_moved": true, "reached_angles": [-25.4, 70.04, 10.01, -1.4, -67.58, -29.97], "reach_err": 5.53, "elapsed_sec": 1.25, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 187, "t": "2026-11-09T12:24:22.282", "t_unix": 1794194662.283, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -1.0, "hold_id": 65, "hold_n": 0, "accepted": true, "measured_before": [-25.4, 70.04, 10.01, -1.4, -67.58, -29.97], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 5.53, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 67.22, 9.99, -1.92, -62.05, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194662.3205981, "measured_before_send": [-25.4, 70.04, 10.01, -1.4, -67.58, -29.97], "resends": [], "reached": false, "settled": true, "reached_angles": [-25.4, 68.9, 10.01, -1.4, -65.83, -30.05], "reach_err": 3.78, "elapsed_sec": 0.3, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 188, "t": "2026-11-09T12:24:22.769", "t_unix": 1794194662.769, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 66, "hold_n": 1, "held_sec": 0.536, "accepted": true, "measured_before": [-25.4, 68.9, 10.01, -1.4, -65.83, -30.05], "start_source": "mixed", "cmd_gap_deg": 3.78, "hold_lead_deg": 1.68, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 53.9, 9.99, -1.92, -62.05, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194662.7887502, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 189, "t": "2026-11-09T12:24:22.871", "t_unix": 1794194662.872, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 66, "hold_n": 2, "held_sec": 0.638, "accepted": true, "measured_before": [-25.4, 68.81, 10.01, -1.4, -65.83, -30.05], "start_source": "mixed", "cmd_gap_deg": 3.78, "hold_lead_deg": 14.91, "sent": false, "why": "lead_ok", "hold_remaining_deg": 14.91, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 190, "t": "2026-11-09T12:24:22.973", "t_unix": 1794194662.974, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 66, "hold_n": 3, "held_sec": 0.74, "accepted": true, "measured_before": [-25.4, 66.88, 10.01, -1.31, -64.07, -30.14], "start_source": "hold", "cmd_gap_deg": 2.02, "hold_lead_deg": 12.98, "sent": false, "why": "lead_ok", "hold_remaining_deg": 12.98, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 191, "t": "2026-11-09T12:24:23.089", "t_unix": 1794194663.09, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 66, "hold_n": 4, "held_sec": 0.856, "accepted": true, "released_during_job": true, "measured_before": [-25.4, 61.61, 10.01, -1.31, -63.98, -30.14], "start_source": "hold", "cmd_gap_deg": 1.93, "hold_lead_deg": 7.71, "sent": false, "why": "lead_ok", "hold_remaining_deg": 7.71, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 192, "t": "2026-11-09T12:24:23.156", "t_unix": 1794194663.157, "button": null, "button_name": null, "kind": "halt", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 66, "halt_joint": 1, "measured_at_request": [-25.4, 66.88, 10.01, -1.31, -64.07, -30.14], "t_halt": 1794194663.156965, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-25.4, 59.58, 10.01, -1.23, -62.22, -30.14], "moved_after_request_deg": [0.0, -7.3, 0.0, 0.08, 1.85, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 193, "t": "2026-11-09T12:24:24.076", "t_unix": 1794194664.076, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 1.0, "hold_id": 67, "hold_n": 0, "accepted": true, "measured_before": [-25.4, 59.58, 10.01, -1.23, -62.22, -30.14], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 0.69, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 60.58, 9.99, -1.92, -62.05, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194664.116527, "measured_before_send": [-25.4, 59.58, 10.01, -1.23, -62.22, -30.14], "resends": [], "reached": false, "settled": true, "reached_angles": [-25.4, 61.78, 10.01, -1.23, -64.33, -30.14], "reach_err": 2.28, "elapsed_sec": 0.65, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 194, "t": "2026-11-09T12:24:25.144", "t_unix": 1794194665.144, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 1.0, "hold_id": 68, "hold_n": 0, "accepted": true, "measured_before": [-25.4, 61.78, 10.01, -1.23, -64.33, -30.14], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 2.28, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 61.58, 9.99, -1.92, -62.05, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194665.1768, "measured_before_send": [-25.4, 61.78, 10.01, -1.23, -64.33, -30.14], "resends": [], "reached": true, "reached_angles": [-25.4, 61.78, 10.01, -1.23, -64.33, -30.14], "reach_err": 2.28, "elapsed_sec": 0.02, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 195, "t": "2026-11-09T12:24:25.981", "t_unix": 1794194665.982, "button": 10, "button_name": "r1", "kind": "modifier", "selected_joint": 1, "step_deg": 2.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 196, "t": "2026-11-09T12:24:26.546", "t_unix": 1794194666.546, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 2.0, "execute": true, "joint": 1, "delta": 2.0, "hold_id": 69, "hold_n": 0, "accepted": true, "measured_before": [-25.4, 62.66, 10.1, -1.31, -64.42, -30.14], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 2.37, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 63.58, 9.99, -1.92, -62.05, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194666.5765362, "measured_before_send": [-25.4, 62.66, 10.1, -1.31, -64.42, -30.14], "resends": [], "reached": true, "reached_angles": [-25.4, 64.07, 10.1, -1.31, -65.12, -30.14], "reach_err": 3.07, "elapsed_sec": 0.09, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 197, "t": "2026-11-09T12:24:27.317", "t_unix": 1794194667.318, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 2.0, "execute": true, "joint": 1, "delta": 2.0, "hold_id": 70, "hold_n": 0, "accepted": true, "measured_before": [-25.4, 64.77, 10.1, -1.31, -65.12, -30.14], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 3.07, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 65.58, 9.99, -1.92, -62.05, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194667.3565729, "measured_before_send": [-25.4, 64.77, 10.1, -1.31, -65.12, -30.14], "resends": [], "reached": false, "settled": true, "reached_angles": [-25.4, 66.62, 10.1, -1.4, -65.56, -30.14], "reach_err": 3.51, "elapsed_sec": 0.44, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 198, "t": "2026-11-09T12:24:29.844", "t_unix": 1794194669.844, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 2, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 199, "t": "2026-11-09T12:24:32.364", "t_unix": 1794194672.365, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": 1.0, "hold_id": 71, "hold_n": 0, "accepted": true, "measured_before": [-25.4, 66.7, 10.1, -1.58, -65.56, -30.23], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 3.51, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 65.58, 10.99, -1.92, -62.05, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194672.3964758, "measured_before_send": [-25.4, 66.7, 10.1, -1.58, -65.56, -30.23], "resends": [], "reached": true, "reached_angles": [-25.4, 66.7, 11.07, -1.58, -66.0, -30.23], "reach_err": 3.95, "elapsed_sec": 0.16, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 200, "t": "2026-11-09T12:24:33.746", "t_unix": 1794194673.747, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -1.0, "hold_id": 72, "hold_n": 0, "accepted": true, "measured_before": [-25.4, 66.7, 11.33, -1.58, -66.0, -30.23], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 3.95, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 65.58, 9.99, -1.92, -62.05, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194673.77653, "measured_before_send": [-25.4, 66.7, 11.33, -1.58, -66.0, -30.23], "resends": [0.34, 0.68], "reached": false, "not_moved": true, "reached_angles": [-25.4, 66.7, 11.25, -1.58, -63.8, -30.14], "reach_err": 1.75, "elapsed_sec": 1.11, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 201, "t": "2026-11-09T12:24:34.935", "t_unix": 1794194674.935, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -15.0, "hold_id": 73, "hold_n": 1, "held_sec": 0.516, "accepted": true, "released_during_job": true, "measured_before": [-25.4, 66.7, 11.25, -1.58, -63.72, -30.14], "start_source": "hold", "cmd_gap_deg": 1.67, "hold_lead_deg": 1.26, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 65.58, -3.75, -1.92, -62.05, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194674.953089, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 202, "t": "2026-11-09T12:24:35.102", "t_unix": 1794194675.103, "button": null, "button_name": null, "kind": "halt", "selected_joint": 2, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "released_while_sending", "hold_id": 73, "halt_joint": 2, "measured_at_request": [-25.4, 66.7, 11.25, -1.58, -63.72, -30.14], "t_halt": 1794194675.103009, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-25.4, 67.41, 9.31, -1.66, -62.05, -30.05], "moved_after_request_deg": [0.0, 0.71, -1.94, -0.08, 1.67, 0.09], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 203, "t": "2026-11-09T12:24:36.069", "t_unix": 1794194676.069, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -15.0, "hold_id": 74, "hold_n": 1, "held_sec": 0.416, "accepted": true, "measured_before": [-25.4, 67.41, 9.31, -1.66, -62.05, -29.97], "start_source": "hold", "cmd_gap_deg": 1.83, "hold_lead_deg": 0.0, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 65.58, -5.69, -1.92, -62.05, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194676.0954409, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 204, "t": "2026-11-09T12:24:36.186", "t_unix": 1794194676.186, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -15.0, "hold_id": 74, "hold_n": 2, "held_sec": 0.532, "accepted": true, "measured_before": [-25.4, 67.32, 9.31, -1.66, -62.05, -29.97], "start_source": "hold", "cmd_gap_deg": 1.74, "hold_lead_deg": 15.0, "sent": false, "why": "lead_ok", "hold_remaining_deg": 15.0, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 205, "t": "2026-11-09T12:24:36.301", "t_unix": 1794194676.301, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -15.0, "hold_id": 74, "hold_n": 3, "held_sec": 0.647, "accepted": true, "measured_before": [-25.4, 67.32, 9.31, -1.66, -59.94, -30.14], "start_source": "hold", "cmd_gap_deg": 2.11, "hold_lead_deg": 15.0, "sent": false, "why": "lead_ok", "hold_remaining_deg": 15.0, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 206, "t": "2026-11-09T12:24:36.401", "t_unix": 1794194676.402, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -15.0, "hold_id": 74, "hold_n": 4, "held_sec": 0.748, "accepted": true, "released_during_job": true, "measured_before": [-25.4, 67.32, 9.31, -1.66, -57.91, -30.14], "start_source": "mixed", "cmd_gap_deg": 4.14, "hold_lead_deg": 15.0, "command": [-25.32, 65.58, -5.69, -1.92, -62.05, -30.23], "hold_resend": true, "sent": false, "why": "halted_before_send", "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 207, "t": "2026-11-09T12:24:36.469", "t_unix": 1794194676.47, "button": null, "button_name": null, "kind": "halt", "selected_joint": 2, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 74, "halt_joint": 2, "measured_at_request": [-25.4, 67.32, 9.31, -1.66, -59.94, -30.14], "t_halt": 1794194676.469652, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-25.4, 68.37, -1.93, -1.49, -53.34, -30.14], "moved_after_request_deg": [0.0, 1.05, -11.24, 0.17, 6.6, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 208, "t": "2026-11-09T12:24:39.485", "t_unix": 1794194679.486, "button": 0, "button_name": "cross", "kind": "grip_close", "selected_joint": 2, "step_deg": 1.0, "execute": true, "grip_cmd": 1, "accepted": true, "measured_before": null, "sent": true, "reached": null, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 209, "t": "2026-11-09T12:24:42.342", "t_unix": 1794194682.342, "button": 1, "button_name": "circle", "kind": "grip_open", "selected_joint": 2, "step_deg": 1.0, "execute": true, "grip_cmd": 0, "accepted": true, "measured_before": null, "sent": true, "reached": null, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 210, "t": "2026-11-09T12:24:47.287", "t_unix": 1794194687.287, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -1.0, "hold_id": 75, "hold_n": 0, "accepted": true, "measured_before": [-25.48, 68.46, -1.49, -1.66, -50.71, -30.14], "start_source": "command", "others_from_measured": [4], "cmd_gap_deg": 11.34, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 65.58, -2.93, -1.92, -50.71, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194687.32775, "measured_before_send": [-25.48, 68.46, -1.49, -1.66, -50.71, -30.14], "resends": [], "reached": false, "settled": true, "reached_angles": [-25.48, 68.2, -1.84, -1.4, -63.19, -30.14], "reach_err": 12.48, "elapsed_sec": 0.53, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 211, "t": "2026-11-09T12:24:48.647", "t_unix": 1794194688.648, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": 1.0, "hold_id": 76, "hold_n": 0, "accepted": true, "measured_before": [-25.48, 68.2, -1.84, -1.4, -63.19, -30.14], "start_source": "command", "others_from_measured": [4], "cmd_gap_deg": 12.48, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 65.58, -1.93, -1.92, -63.19, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194688.696636, "measured_before_send": [-25.48, 68.2, -1.84, -1.4, -63.19, -30.14], "resends": [], "reached": true, "reached_angles": [-25.48, 68.2, -1.84, -1.4, -63.19, -30.14], "reach_err": 2.62, "elapsed_sec": 0.02, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 212, "t": "2026-11-09T12:24:49.652", "t_unix": 1794194689.652, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": 1.0, "hold_id": 77, "hold_n": 0, "accepted": true, "measured_before": [-25.48, 68.2, -1.84, -1.4, -63.19, -30.14], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 2.62, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 65.58, -0.93, -1.92, -63.19, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194689.68875, "measured_before_send": [-25.48, 68.2, -1.84, -1.4, -63.19, -30.14], "resends": [], "reached": true, "reached_angles": [-25.48, 68.2, -1.05, -1.4, -64.07, -30.14], "reach_err": 2.62, "elapsed_sec": 0.02, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 213, "t": "2026-11-09T12:24:50.198", "t_unix": 1794194690.199, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": 1.0, "hold_id": 78, "hold_n": 0, "accepted": true, "measured_before": [-25.48, 68.2, -0.35, -1.4, -64.16, -30.14], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 2.62, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 65.58, 0.07, -1.92, -63.19, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194690.244836, "measured_before_send": [-25.48, 68.2, -0.35, -1.4, -64.16, -30.14], "resends": [], "reached": true, "reached_angles": [-25.48, 68.2, -0.08, -1.4, -64.16, -30.14], "reach_err": 2.62, "elapsed_sec": 0.02, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 214, "t": "2026-11-09T12:24:50.841", "t_unix": 1794194690.842, "button": 10, "button_name": "r1", "kind": "modifier", "selected_joint": 2, "step_deg": 2.0, "execute": true, "accepted": true, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 215, "t": "2026-11-09T12:24:51.297", "t_unix": 1794194691.297, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 2.0, "execute": true, "joint": 2, "delta": 2.0, "hold_id": 79, "hold_n": 0, "accepted": true, "measured_before": [-25.48, 68.2, 0.61, -1.4, -64.16, -30.14], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 2.62, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 65.58, 2.07, -1.92, -63.19, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194691.3327858, "measured_before_send": [-25.48, 68.2, 0.61, -1.4, -64.16, -30.14], "resends": [], "reached": true, "reached_angles": [-25.48, 68.2, 2.19, -1.4, -65.21, -30.14], "reach_err": 2.62, "elapsed_sec": 0.16, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 216, "t": "2026-11-09T12:24:52.023", "t_unix": 1794194692.023, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 2.0, "execute": true, "joint": 2, "delta": 2.0, "hold_id": 80, "hold_n": 0, "accepted": true, "measured_before": [-25.48, 68.2, 2.63, -1.4, -65.21, -30.14], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 2.62, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 65.58, 4.07, -1.92, -63.19, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194692.0583491, "measured_before_send": [-25.48, 68.2, 2.63, -1.4, -65.21, -30.14], "resends": [], "reached": true, "reached_angles": [-25.48, 68.2, 4.13, -1.4, -65.56, -30.14], "reach_err": 2.62, "elapsed_sec": 0.16, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 217, "t": "2026-11-09T12:24:52.810", "t_unix": 1794194692.81, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 2.0, "execute": true, "joint": 2, "delta": 2.0, "hold_id": 81, "hold_n": 0, "accepted": true, "measured_before": [-25.48, 68.2, 4.65, -1.4, -65.56, -30.14], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 2.62, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 65.58, 6.07, -1.92, -63.19, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194692.84878, "measured_before_send": [-25.48, 68.2, 4.65, -1.4, -65.56, -30.14], "resends": [], "reached": true, "reached_angles": [-25.48, 68.2, 6.32, -1.4, -65.83, -30.14], "reach_err": 2.64, "elapsed_sec": 0.09, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 218, "t": "2026-11-09T12:24:53.590", "t_unix": 1794194693.591, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 2.0, "execute": true, "joint": 2, "delta": 2.0, "hold_id": 82, "hold_n": 0, "accepted": true, "measured_before": [-25.48, 68.2, 6.5, -1.4, -65.83, -30.14], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 2.64, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 65.58, 8.07, -1.92, -63.19, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794194693.6288, "measured_before_send": [-25.48, 68.2, 6.5, -1.4, -65.83, -30.14], "resends": [], "reached": true, "reached_angles": [-25.48, 68.2, 7.82, -1.4, -66.0, -30.14], "reach_err": 2.81, "elapsed_sec": 0.01, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 219, "t": "2026-11-09T12:24:55.252", "t_unix": 1794194695.252, "button": 0, "button_name": "cross", "kind": "grip_close", "selected_joint": 2, "step_deg": 1.0, "execute": true, "grip_cmd": 1, "accepted": true, "measured_before": null, "sent": true, "reached": null, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 220, "t": "2026-11-09T12:25:00.947", "t_unix": 1794194700.948, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 3, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 221, "t": "2026-11-09T12:25:01.390", "t_unix": 1794194701.391, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 4, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 222, "t": "2026-11-09T12:25:01.796", "t_unix": 1794194701.797, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 5, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 223, "t": "2026-11-09T12:25:02.249", "t_unix": 1794194702.249, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 224, "t": "2026-11-09T12:25:03.529", "t_unix": 1794194703.53, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 83, "hold_n": 1, "held_sec": 0.403, "accepted": true, "measured_before": [-25.48, 68.2, 8.43, -1.58, -66.53, -30.14], "start_source": "mixed", "cmd_gap_deg": 3.34, "hold_lead_deg": 2.62, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 53.2, 8.07, -1.92, -63.19, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194703.542926, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 225, "t": "2026-11-09T12:25:03.630", "t_unix": 1794194703.63, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 83, "hold_n": 2, "held_sec": 0.504, "accepted": true, "measured_before": [-25.48, 68.02, 8.43, -1.58, -66.53, -30.14], "start_source": "mixed", "cmd_gap_deg": 3.34, "hold_lead_deg": 14.82, "sent": false, "why": "lead_ok", "hold_remaining_deg": 14.82, "reached": null, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 226, "t": "2026-11-09T12:25:03.731", "t_unix": 1794194703.732, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 83, "hold_n": 3, "held_sec": 0.605, "accepted": true, "measured_before": [-25.48, 65.65, 8.43, -1.58, -66.53, -30.14], "start_source": "mixed", "cmd_gap_deg": 3.34, "hold_lead_deg": 12.45, "sent": false, "why": "lead_ok", "hold_remaining_deg": 12.45, "reached": null, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 227, "t": "2026-11-09T12:25:03.832", "t_unix": 1794194703.833, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 83, "hold_n": 4, "held_sec": 0.706, "accepted": true, "measured_before": [-25.48, 61.17, 8.43, -1.58, -66.53, -30.14], "start_source": "mixed", "cmd_gap_deg": 3.34, "hold_lead_deg": 7.97, "sent": false, "why": "lead_ok", "hold_remaining_deg": 7.97, "reached": null, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 228, "t": "2026-11-09T12:25:03.934", "t_unix": 1794194703.934, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 83, "hold_n": 5, "held_sec": 0.807, "accepted": true, "measured_before": [-25.48, 61.17, 8.43, -1.58, -66.53, -30.14], "start_source": "mixed", "cmd_gap_deg": 3.34, "hold_lead_deg": 7.97, "command": [-25.32, 53.2, 8.07, -1.92, -63.19, -30.23], "hold_resend": true, "sent": true, "reached": null, "no_check": true, "t_send": 1794194703.994532, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 229, "t": "2026-11-09T12:25:04.052", "t_unix": 1794194704.053, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 83, "hold_n": 6, "held_sec": 0.926, "accepted": true, "measured_before": [-25.48, 55.54, 8.43, -1.49, -66.53, -30.14], "start_source": "mixed", "cmd_gap_deg": 3.34, "hold_lead_deg": 2.34, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-25.32, 40.54, 8.07, -1.92, -63.19, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794194704.062813, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 230, "t": "2026-11-09T12:25:04.168", "t_unix": 1794194704.168, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 83, "hold_n": 7, "held_sec": 1.041, "accepted": true, "measured_before": [-25.48, 55.45, 8.52, -1.58, -66.53, -30.14], "start_source": "mixed", "cmd_gap_deg": 3.34, "hold_lead_deg": 14.91, "sent": false, "why": "lead_ok", "hold_remaining_deg": 14.91, "reached": null, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 231, "t": "2026-11-09T12:25:04.284", "t_unix": 1794194704.284, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 83, "hold_n": 8, "held_sec": 1.157, "accepted": true, "measured_before": [-25.48, 51.85, 8.52, -1.58, -66.53, -30.14], "start_source": "mixed", "cmd_gap_deg": 3.34, "hold_lead_deg": 11.31, "sent": false, "why": "lead_ok", "hold_remaining_deg": 11.31, "reached": null, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 232, "t": "2026-11-09T12:25:04.385", "t_unix": 1794194704.386, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 83, "hold_n": 9, "held_sec": 1.259, "accepted": true, "measured_before": [-25.48, 47.19, 8.52, -1.58, -66.53, -30.14], "start_source": "mixed", "cmd_gap_deg": 3.34, "hold_lead_deg": 6.65, "sent": false, "why": "lead_ok", "hold_remaining_deg": 6.65, "reached": null, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 233, "t": "2026-11-09T12:25:04.435", "t_unix": 1794194704.436, "button": null, "button_name": null, "kind": "halt", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 83, "halt_joint": 1, "measured_at_request": [-25.48, 47.19, 8.52, -1.58, -66.53, -30.14], "t_halt": 1794194704.435889, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-25.48, 43.06, 8.52, -1.58, -66.53, -30.14], "moved_after_request_deg": [0.0, -4.13, 0.0, 0.0, 0.0, 0.0], "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 234, "t": "2026-11-09T12:25:10.265", "t_unix": 1794194710.265, "button": 1, "button_name": "circle", "kind": "grip_open", "selected_joint": 1, "step_deg": 1.0, "execute": true, "grip_cmd": 0, "accepted": true, "measured_before": null, "sent": true, "reached": null, "grip_state": "open", "stopped": false, "stop_reason": null}
```


## 測る仕組みが、アームの赤いケーブルをブロックと取り違えた

教え直したあと、ブロックの位置を測る measure が、ブロックではなくアームの根元の赤いケーブルを拾うようになりました（根元から約73mm。120mm 以内は WARN が出る）。

【画像】LOG479_02_measure_cable.jpg measure の確認画像。赤い丸がアームの根元のケーブルに付いていて、左下のブロックは拾われていない

この見つけ方は、画の中のいちばん広い赤を選びます。12:07 の measure ではブロックの赤が広く（約3,200画素）、ケーブル（細切れで1つ約500）より勝っていました。この日の途中からブロックの赤が小さく写るようになり、ケーブルが選ばれたようです。照明とカメラは変えておらず、マットと白い箱の色の数値も12:07 から同じでした。ブロックの赤が小さく写るようになった理由は、確かめられていません。Claude は途中で、ケーブルの通り方や、ブロックの面・照り返しのせいだと説明しましたが、どれも確かめていない推測でした。

ただ、手順書にはもともと、measure の位置は根元のケーブルを拾うことがあって当てにならない、置けたかは印と画で人が見る、と書いてありました（LOG352 で分かったこと）。教えた記録の再生は関節の角度をそのまま流すだけで、measure の位置は使いません。本数も teach/ のファイル名で数えるので、measure の値は撮影に効きません。WARN が出たまま撮影を続けています。


## 前に撮った本の1コマ目を重ねて、ブロックを同じ場所に置いた

置くたびにブロックの位置がずれるので、一番深かった本（124117・2.7px）の上カメラの1コマ目を、ライブ映像に半透明で重ねて置くことにしました。pi05/camera_align.py は、学習データの1本目を重ねて上カメラの写り方を合わせる画面です。この本はまだ学習データになっていないので、1コマ目だけを入れたフォルダ（align_ref/）を作って渡しました。

```
python3 pi05/camera_align.py --raw-dir /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/align_ref
```

【画像】LOG479_03_pos3_align.jpg 位置3 の最初のコマにブロックの枠を重ねた図。緑は深くつかめた本、赤は線をわずかに超えた本。赤の2本は、どちらも画面の下（手前）に4〜7mm ずれていた

- ねらい：置く位置のずれで深さが変わるのをなくし、教えた記録の良し悪しだけを見られるようにする
- 変わったこと：置き場所を合わせる前の位置3は8本中6本が線の内側（線をわずかに超えた2本は手前にずれていた）。深かった本の位置を画像で見て置いた124438 と、重ねて置いた124817・124920 の3本は、−2.1・−0.6・2.2px で、どれもいちばん深い側だった（この間の124530 は爪が乗った）
- 見込める効果：置き場所ごとのお手本の位置がそろい、π0.5 が学ぶブロックの位置のばらつきが、教えた5か所のまわりに集まる（学習の結果では、まだ確かめていない）

位置4も、新しい記録の1本目（130542）ができてからは、同じように重ねて置きました。

### 重ねる元の画のフォルダの説明（mecharm_calibration/teach_poses_20261109/align_ref/README.md）

```text
camera_align.py の --raw-dir に渡す、位置合わせ用の基準画像だけのフォルダ（2026-11-09）。
run_0001_20261109_124117（位置3を教え直した記録で一番深かった本・閉じて1秒後 2.7px）の上カメラ top.mp4 の1コマ目。
episode.npz は camera_align.py がフォルダを見つけるための空の印で、学習には使わない。
run_0001_20261109_130542 は、位置4をゲームパッドで教え直した記録（drag_v2_20261109_130300.json）の1本目（閉じて1秒後 5.4px・PICK の区間 1.09秒）。--episode 130542 で選ぶ。
```


## 新しい記録で撮った位置3の12本

| run | 閉じて1秒後 | 下ろす時間 | 判定 |
|---|---|---|---|
| 123655 | 25.9px | 1.07秒 | 浅い（線をわずかに超えた） |
| 123756 | 21.8px | 1.07秒 | 深いが、10本にそろえるとき外した |
| 123848 | 9.5px | 1.08秒 | 使う |
| 123940 | 25.6px | 1.07秒 | 浅い（線をわずかに超えた） |
| 124032 | 20.4px | 1.07秒 | 使う |
| 124117 | 2.7px | 1.07秒 | 使う |
| 124207 | 18.1px | 1.06秒 | 使う |
| 124256 | 4.5px | 1.10秒 | 使う |
| 124438 | −2.1px | 1.08秒 | 使う（深かった本の位置を画像で見て置いた） |
| 124530 | — | 6.57秒 | 外す（爪が乗り、空で閉じた。画像で見て置いた） |
| 124817 | −0.6px | 1.72秒 | 使う（重ねて置いた） |
| 124920 | 2.2px | 1.07秒 | 使う（重ねて置いた） |

元の記録の9本の中央が39.1px だったのに対して、使えた9本の中央は4.5px でした。肩を25°上げた位置から弧を描いて下ろす形でしたが、下ろす時間はほぼ1.1秒にそろい、爪が乗ったのは12本中1本でした。


## 位置4は、手前の爪がブロックの真上に来ていた

位置4は、前に撮った5本（10/19）がどれも深かったので、元の記録のまま撮りました。ところが1本目（125209）から、下ろすのに7.2秒かかり、爪がブロックに乗って空で閉じました。

Claude は最初、元の記録の下ろし方に原因があると見ました。下ろすあいだに手首が −78.0° から −59.2° へ19°、肘が 22.7° から 13.7° へ動き、爪先が振れながら下りてくる形です。そこで、ブロックの上の姿勢だけを、つかむ姿勢から肩だけ20°上げた姿勢に差し替えました（13:00 の記録）。

| 姿勢 | j0 | 肩 j1 | 肘 j2 | j3 | 手首 j4 | j5 |
|---|---|---|---|---|---|---|
| 元のブロックの上 | −59.94 | 54.31 | 22.67 | 1.49 | −78.04 | −32.34 |
| 13:00 のブロックの上（肩だけ20°上げた） | −62.05 | 41.69 | 13.71 | 0.87 | −59.15 | −32.34 |
| 元のつかむ（13:00 も同じ） | −62.05 | 61.69 | 13.71 | 0.87 | −59.15 | −32.34 |

この差し替えた記録で撮るつもりの1本（125607）は、撮るときに打った行が元のファイル名のままで、元の記録で撮られていました。13:00 の記録で撮った125825 も、下ろすのに6.6秒かかり、爪が乗りました。**下ろし方ではなく、根元の向き（j0）がずれていて、手前の爪がブロックの真上に来ていたのが原因でした。** 上カメラで下ろす区間を並べると、10/19 の本も、ブロックは2本の爪の間ではなく手前の爪の下にありました。10/19 は、爪が乗ったあとにブロックが押されて傾き、4.0秒で入っていただけでした。

【画像】LOG479_04_pos4_descent.jpg 位置4 の下ろす区間の上カメラ5コマを3段に並べた。上は13:00 の記録（125825）、中は10/19 の本（193825）、下は教え直した記録（130542）。上と中は手前の爪がブロックの上に重なっている。下はブロックが2本の爪の間に入っている

そこで位置4も、ゲームパッドで教え直しました。根元を 3.2° 戻してブロックを爪の間に入れ、奥まで下げて閉じています。

| 姿勢 | j0 | 肩 j1 | 肘 j2 | j3 | 手首 j4 | j5 |
|---|---|---|---|---|---|---|
| 新しいつかむ（×で閉じたあと最初に読んだ角度・seq 127） | −58.88 | 61.87 | 9.31 | 0.08 | −54.05 | −30.14 |
| 持ち上げて止めた実測（seq 135） | −58.71 | 41.74 | 7.20 | 0.70 | −59.67 | −30.23 |
| 新しいブロックの上（つかむ姿勢の肩だけ41.74°に） | −58.88 | 41.74 | 9.31 | 0.08 | −54.05 | −30.14 |

持ち上げた実測では、つかんだブロックの重さで手首が −59.7° まで下がっていました。そのまま使うと下ろすときに手首が5.6°動くので、肩以外はつかむ姿勢と同じにしています。位置3と同じく、下ろすときは肩だけが動く形です。

- ねらい：位置4で爪がブロックに乗るのをなくし、深いお手本を撮れるようにする
- 変わったこと：下ろす時間は、元の記録と13:00 の記録の3本が6.6〜7.2秒（3本とも爪が乗った）。教え直した記録の5本は1.07〜1.66秒で、はみ出しは1.6〜10.0px
- 見込める効果：位置4のお手本が、ブロックを押して傾けてからつかむ動きを含まなくなる。π0.5 がその動きをまねることがなくなる見込み（学習の結果では、まだ確かめていない）

### 13:00 に作った位置4の記録の作り方（使わなかった版・make_teach_pos4_20261109.py）

```python
#!/usr/bin/env python3
"""make_teach_pos4_20261109.py — 位置4 の教えた記録 drag_v2_20221013_232345.json の「ブロックの上」の姿勢だけを差し替えた
新しい教えた記録 drag_v2_20261109_130000.json を作る (2026-11-09 13:00).
つかむ姿勢 (PICK) は元のまま. 箱の側の 2 つ・phases・gripper_events・key_log・positions もそのまま.

理由: 2026-11-09 12:52 の位置4 の 1 本目 (run_0001_20261109_125209) で, 下ろす区間 (ブロックの上 → つかむ) が 7.2 秒かかり,
爪がブロックに乗って空で閉じた (n/n). 元の記録は下ろすあいだに 手首 j4 が −78.0° → −59.2° (19°)・肘 j2 が 22.7° → 13.7° 動き,
爪先が振れながら下りる. 10/19 の位置4 でも同じ区間が 4.0 秒かかっていた (ぎりぎり).
位置3 を教え直した記録 (drag_v2_20261109_123000.json) は下ろす区間が j1 だけの動きで, 11 本とも 1.07〜1.72 秒だった
(爪が乗った 124530 の 1 本を除く).
そこで位置4 も「ブロックの上」を つかむ姿勢から j1 だけ 20° 上げた姿勢にして, 下ろす区間を j1 だけの動きにする.
  ブロックの上 = PICK の close の印 (idx 223) の姿勢の j1 を 61.69 → 41.69 にしたもの (ほかの関節は PICK と同じ)
  APPROACH_PICK phase (idx 123〜197) を全部この姿勢にそろえる
"""
import json, copy
src = "runs/run_pick_place/run_0001_20261109_125209/teach/drag_v2_20221013_232345.json"
d = json.load(open(src)); n = copy.deepcopy(d)
pick = d['angles'][223]
appr = list(pick); appr[1] = round(pick[1] - 20.0, 2)
for i in range(123, 198): n['angles'][i] = list(appr)
n['recorded_at'] = "2026-11-09T13:00:00"
n['derived_from'] = {"teach": "drag_v2_20221013_232345.json", "replaced": {"APPROACH_PICK idx 123-197": appr},
 "pick_kept": pick,
 "reason": "位置4 の下ろす区間で手首と肘が振れ, 爪がブロックに乗った (run_0001_20261109_125209 で 7.2 秒・空で閉じた)。ブロックの上を PICK から j1 だけ 20° 上げた姿勢にし, 下ろす区間を j1 だけの動きにした。PICK と箱側は元のまま"}
out = "mecharm_calibration/teach_poses_20261109/drag_v2_20261109_130000.json"
json.dump(n, open(out, "w"), ensure_ascii=False, indent=1); print(out, "appr", appr, "pick", pick)
```

### 教え直した位置4の記録の作り方（make_teach_pos4_v2_20261109.py）

```python
#!/usr/bin/env python3
"""make_teach_pos4_v2_20261109.py — 位置4 の教えた記録 drag_v2_20221013_232345.json の「ブロックの上」と「つかむ」の姿勢を,
ゲームパッドで作り直した姿勢に差し替えた新しい教えた記録 drag_v2_20261109_130300.json を作る (2026-11-09 13:03).
作り方は位置1 (lab/Log25/make_teach_v2_20261109.py)・位置3 (make_teach_pos3_20261109.py) と同じ.
  APPROACH_PICK : phase APPROACH_PICK (idx 123〜197) を全部「ブロックの上」に
  PICK          : PICK phase (idx 198〜303. close の印は idx 223) を全部「つかむ」に
箱の側の 2 つ (APPROACH_PLACE・PLACE) と, phases・gripper_events・key_log・positions はそのまま.

理由: 位置4 の元の記録は j0 = −62.05° で, ブロックが 2 本の爪の間ではなく手前の爪の真下に来ていた.
下ろす区間で爪がブロックに乗り, 今日の 125209・125607・125825 は 6.6〜7.2 秒かかって空で閉じた (10/19 の 193825 も 4.0 秒).
13:00 の差し替え (drag_v2_20261109_130000.json. ブロックの上を j1 だけ上げた形) でも直らなかったので使わない.

姿勢は tools/gamepad_teleop.py の記録 runs/experiments/gamepad_teleop/teleop_20261109_130126/log.jsonl の実測から取った:
  つかむ      = 爪を閉じた (seq 122 の ×) あと, 最初に読んだ角度 (seq 127 の measured_before). j0 は −62.05 → −58.88
  ブロックの上 = つかむ姿勢の j1 を, つかんだまま十字キーの上で上げて止めた角度 (seq 135 の measured_after_halt) の j1 = 41.74 にしたもの.
                 持ち上げた実測は手首 j4 が −59.67 (つかむときは −54.05) で, つかんだ重さで手首が下がっていた. 下ろす区間を
                 j1 だけの動きにするため (位置3 で 1.1 秒前後で下りた形), j1 以外は つかむ姿勢と同じにした
"""
import json, copy
src = "runs/run_pick_place/run_0001_20261109_125209/teach/drag_v2_20221013_232345.json"
d = json.load(open(src)); n = copy.deepcopy(d)
pick = [-58.88, 61.87, 9.31, 0.08, -54.05, -30.14]   # teleop_20261109_130126 で爪を閉じたあとの実測 (seq 127)
appr = list(pick); appr[1] = 41.74                   # 同じ記録で j1 を上げて止めた実測 (seq 135) の j1
for i in range(123, 198): n['angles'][i] = list(appr)
for i in range(198, 304): n['angles'][i] = list(pick)
n['recorded_at'] = "2026-11-09T13:03:00"
n['derived_from'] = {"teach": "drag_v2_20221013_232345.json", "replaced": {"APPROACH_PICK idx 123-197": appr, "PICK idx 198-303": pick},
 "source": "runs/experiments/gamepad_teleop/teleop_20261109_130126/log.jsonl (seq 127 の閉じたあとの実測・seq 135 の持ち上げ後の j1)",
 "reason": "位置4 の元の j0 では手前の爪がブロックの真上に来て乗った (125209・125607・125825)。ゲームパッドで j0 を合わせ直し, 奥までつかむ姿勢を作った。下ろす区間は j1 だけ。箱側の 2 姿勢は元のまま"}
out = "mecharm_calibration/teach_poses_20261109/drag_v2_20261109_130300.json"
json.dump(n, open(out, "w"), ensure_ascii=False, indent=1); print(out, appr, pick)
```

### ゲームパッドの記録（runs/experiments/gamepad_teleop/teleop_20261109_130126/meta.json）

```json
{
  "run_stem": "teleop_20261109_130126",
  "started_at": "2026-11-09T13:01:26",
  "execute": true,
  "argv": [
    "tools/gamepad_teleop.py",
    "--execute"
  ],
  "controllers": [
    {
      "name": "PS4 Controller",
      "guid": "03008fe54c050000cc09000000016800",
      "instance_id": 0,
      "axes": 6,
      "buttons": 16,
      "hats": 0,
      "connected_at": "2026-11-09T13:01:32"
    }
  ],
  "python": "3.12.12 | packaged by conda-forge | (main, Oct 22 2025, 23:34:53) [Clang 19.1.7 ]",
  "pygame": "2.6.1",
  "sdl": "2.28.4",
  "platform": "macOS-26.6.2-arm64-arm-64bit",
  "start_pose": [
    -0.43,
    1.58,
    2.19,
    -0.26,
    -0.26,
    -30.23
  ],
  "guards": {
    "J1_MAX_DEG": 90.87,
    "range": "physical_limits (no base window. 2026-11-03)",
    "J4_SAFE": [
      -90.0,
      60.0
    ],
    "JOINT_LIMITS": [
      [
        -156.0,
        161.0
      ],
      [
        -79.0,
        123.0
      ],
      [
        -177.0,
        177.0
      ],
      [
        -156.0,
        162.0
      ],
      [
        -118.0,
        118.0
      ],
      [
        -177.0,
        178.0
      ]
    ],
    "window": {
      "lo": [
        -156.0,
        -79.0,
        -177.0,
        -156.0,
        -90.0,
        -177.0
      ],
      "hi": [
        161.0,
        90.87,
        177.0,
        162.0,
        60.0,
        178.0
      ]
    },
    "home_bypasses_range_check": true
  },
  "motion": {
    "speed": 20,
    "step_fine_deg": 1.0,
    "step_coarse_deg": 2.0,
    "reach_tol_deg": 3.0,
    "reach_timeout_min_sec": 8.0,
    "poll_sec": 0.3,
    "gripper_sleep_sec": 0.8,
    "grip_close_value": 20,
    "send_wait": 0.0,
    "home": [
      0.0,
      0.0,
      0.0,
      0.0,
      0.0,
      -30.0
    ],
    "home_hold_sec": 1.0,
    "trigger_stop_above": 0.0,
    "hold_start_sec": 0.4,
    "hold_interval_sec": 0.1,
    "hold_ahead_deg": 15.0,
    "hold_stall_sec": 1.5,
    "ignored_check_sec": 0.5,
    "ignored_max_resends": 3,
    "j0_left_sign": -1.0,
    "up_sign": -1.0,
    "select_order": [
      1,
      2,
      3,
      4,
      5
    ]
  },
  "button_map": {
    "0": "cross",
    "1": "circle",
    "2": "square",
    "3": "triangle",
    "4": "share",
    "5": "home",
    "6": "options",
    "7": "l3",
    "8": "r3",
    "9": "l1",
    "10": "r1",
    "11": "dpad_up",
    "12": "dpad_down",
    "13": "dpad_left",
    "14": "dpad_right",
    "15": "touchpad"
  },
  "git": {
    "commit": "bac9ab7650627fd5d0ca2adcd391613741710ac5",
    "script_status": "clean"
  },
  "script_copy": "gamepad_teleop.py",
  "script_sha256": "d211064093ab547bb9dac15dfaa53c49c8de77f1ce1b22cf58442fde253dd259",
  "ended_at": "2026-11-09T13:03:45",
  "end_reason": "ctrl_c",
  "n_sent": 54
}
```

### ゲームパッドの記録（runs/experiments/gamepad_teleop/teleop_20261109_130126/log.jsonl）

```json
{"seq": 1, "t": "2026-11-09T13:01:34.823", "t_unix": 1794196894.823, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -15.0, "hold_id": 1, "hold_n": 1, "held_sec": 0.405, "accepted": true, "measured_before": [-0.43, 1.58, 2.19, -0.26, -0.26, -30.23], "start_source": "hold", "cmd_gap_deg": 0.0, "hold_lead_deg": 0.0, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-15.43, 1.58, 2.19, -0.26, -0.26, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794196894.8359108, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 2, "t": "2026-11-09T13:01:34.995", "t_unix": 1794196894.996, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -15.0, "hold_id": 1, "hold_n": 2, "held_sec": 0.577, "accepted": true, "measured_before": [-0.43, 1.58, 2.19, -0.26, -0.26, -30.23], "start_source": "hold", "cmd_gap_deg": 0.0, "hold_lead_deg": 15.0, "sent": false, "why": "lead_ok", "hold_remaining_deg": 15.0, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 3, "t": "2026-11-09T13:01:35.097", "t_unix": 1794196895.098, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -15.0, "hold_id": 1, "hold_n": 3, "held_sec": 0.68, "accepted": true, "measured_before": [-4.04, 1.58, 2.19, -0.26, -0.26, -30.23], "start_source": "hold", "cmd_gap_deg": 0.0, "hold_lead_deg": 11.39, "sent": false, "why": "lead_ok", "hold_remaining_deg": 11.39, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 4, "t": "2026-11-09T13:01:35.198", "t_unix": 1794196895.199, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -15.0, "hold_id": 1, "hold_n": 4, "held_sec": 0.781, "accepted": true, "measured_before": [-7.55, 1.58, 2.19, -0.26, -0.26, -30.23], "start_source": "hold", "cmd_gap_deg": 0.0, "hold_lead_deg": 7.88, "sent": false, "why": "lead_ok", "hold_remaining_deg": 7.88, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 5, "t": "2026-11-09T13:01:35.302", "t_unix": 1794196895.303, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -15.0, "hold_id": 1, "hold_n": 5, "held_sec": 0.885, "accepted": true, "measured_before": [-12.91, 1.58, 2.19, -0.26, -0.26, -30.23], "start_source": "hold", "cmd_gap_deg": 0.0, "hold_lead_deg": 2.52, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-27.91, 1.58, 2.19, -0.26, -0.26, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794196895.3645818, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 6, "t": "2026-11-09T13:01:35.427", "t_unix": 1794196895.428, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -15.0, "hold_id": 1, "hold_n": 6, "held_sec": 1.01, "accepted": true, "measured_before": [-27.68, 1.58, 2.19, -0.17, -0.26, -30.23], "start_source": "hold", "cmd_gap_deg": 0.09, "hold_lead_deg": 0.23, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-42.68, 1.58, 2.19, -0.26, -0.26, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794196895.934576, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 7, "t": "2026-11-09T13:01:35.984", "t_unix": 1794196895.985, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -15.0, "hold_id": 1, "hold_n": 7, "held_sec": 1.567, "accepted": true, "measured_before": [-28.82, 1.58, 2.19, -0.17, -0.26, -30.23], "start_source": "hold", "cmd_gap_deg": 0.09, "hold_lead_deg": 13.86, "sent": false, "why": "lead_ok", "hold_remaining_deg": 13.86, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 8, "t": "2026-11-09T13:01:36.152", "t_unix": 1794196896.152, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -15.0, "hold_id": 1, "hold_n": 8, "held_sec": 1.734, "accepted": true, "measured_before": [-30.41, 1.58, 2.19, -0.17, -0.26, -30.23], "start_source": "hold", "cmd_gap_deg": 0.09, "hold_lead_deg": 12.27, "sent": false, "why": "lead_ok", "hold_remaining_deg": 12.27, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 9, "t": "2026-11-09T13:01:36.253", "t_unix": 1794196896.254, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -15.0, "hold_id": 1, "hold_n": 9, "held_sec": 1.836, "accepted": true, "measured_before": [-34.1, 1.58, 2.19, -0.17, -0.26, -30.23], "start_source": "hold", "cmd_gap_deg": 0.09, "hold_lead_deg": 8.58, "sent": false, "why": "lead_ok", "hold_remaining_deg": 8.58, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 10, "t": "2026-11-09T13:01:36.356", "t_unix": 1794196896.356, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -15.0, "hold_id": 1, "hold_n": 10, "held_sec": 1.938, "accepted": true, "measured_before": [-38.93, 1.58, 2.19, -0.17, -0.26, -30.23], "start_source": "hold", "cmd_gap_deg": 0.09, "hold_lead_deg": 3.75, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-53.93, 1.58, 2.19, -0.26, -0.26, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794196896.3809931, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 11, "t": "2026-11-09T13:01:36.457", "t_unix": 1794196896.458, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -15.0, "hold_id": 1, "hold_n": 11, "held_sec": 2.04, "accepted": true, "measured_before": [-42.18, 1.58, 2.19, -0.17, -0.26, -30.23], "start_source": "hold", "cmd_gap_deg": 0.09, "hold_lead_deg": 11.75, "sent": false, "why": "lead_ok", "hold_remaining_deg": 11.75, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 12, "t": "2026-11-09T13:01:36.559", "t_unix": 1794196896.559, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -15.0, "hold_id": 1, "hold_n": 12, "held_sec": 2.141, "accepted": true, "measured_before": [-42.45, 1.58, 2.19, -0.17, -0.26, -30.23], "start_source": "hold", "cmd_gap_deg": 0.09, "hold_lead_deg": 11.48, "sent": false, "why": "lead_ok", "hold_remaining_deg": 11.48, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 13, "t": "2026-11-09T13:01:36.661", "t_unix": 1794196896.661, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -15.0, "hold_id": 1, "hold_n": 13, "held_sec": 2.243, "accepted": true, "measured_before": [-45.35, 1.58, 2.19, -0.17, -0.26, -30.23], "start_source": "hold", "cmd_gap_deg": 0.09, "hold_lead_deg": 8.58, "sent": false, "why": "lead_ok", "hold_remaining_deg": 8.58, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 14, "t": "2026-11-09T13:01:36.778", "t_unix": 1794196896.778, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -15.0, "hold_id": 1, "hold_n": 14, "held_sec": 2.36, "accepted": true, "measured_before": [-49.13, 1.58, 2.19, -0.17, -0.26, -30.23], "start_source": "hold", "cmd_gap_deg": 0.09, "hold_lead_deg": 4.8, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-64.13, 1.58, 2.19, -0.26, -0.26, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794196896.806756, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 15, "t": "2026-11-09T13:01:36.880", "t_unix": 1794196896.88, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -15.0, "hold_id": 1, "hold_n": 15, "held_sec": 2.462, "accepted": true, "measured_before": [-53.7, 1.58, 2.19, -0.17, -0.26, -30.23], "start_source": "hold", "cmd_gap_deg": 0.09, "hold_lead_deg": 10.43, "sent": false, "why": "lead_ok", "hold_remaining_deg": 10.43, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 16, "t": "2026-11-09T13:01:36.983", "t_unix": 1794196896.983, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -15.0, "hold_id": 1, "hold_n": 16, "held_sec": 2.565, "accepted": true, "measured_before": [-54.22, 1.58, 2.19, -0.17, -0.26, -30.23], "start_source": "hold", "cmd_gap_deg": 0.09, "hold_lead_deg": 9.91, "sent": false, "why": "lead_ok", "hold_remaining_deg": 9.91, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 17, "t": "2026-11-09T13:01:37.034", "t_unix": 1794196897.034, "button": null, "button_name": null, "kind": "halt", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 1, "halt_joint": 0, "measured_at_request": [-54.22, 1.58, 2.19, -0.17, -0.26, -30.23], "t_halt": 1794196897.034179, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-53.87, 2.81, 3.16, -0.17, 1.4, -30.23], "moved_after_request_deg": [0.35, 1.23, 0.97, 0.0, 1.66, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 18, "t": "2026-11-09T13:01:38.409", "t_unix": 1794196898.409, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 0, "delta": -1.0, "hold_id": 2, "hold_n": 0, "accepted": true, "measured_before": [-54.22, 2.81, 3.25, -0.17, 1.49, -30.23], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 1.75, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-54.87, 1.58, 2.19, -0.26, -0.26, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794196898.4484742, "measured_before_send": [-54.22, 2.81, 3.25, -0.17, 1.49, -30.23], "resends": [], "reached": true, "reached_angles": [-54.4, 1.58, 2.02, -0.17, 1.49, -30.23], "reach_err": 1.75, "elapsed_sec": 0.16, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 19, "t": "2026-11-09T13:01:39.088", "t_unix": 1794196899.088, "button": 10, "button_name": "r1", "kind": "modifier", "selected_joint": 1, "step_deg": 2.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 20, "t": "2026-11-09T13:01:39.630", "t_unix": 1794196899.631, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 2.0, "execute": true, "joint": 0, "delta": -2.0, "hold_id": 3, "hold_n": 0, "accepted": true, "measured_before": [-54.84, 1.58, 2.02, -0.17, 1.49, -30.23], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 1.75, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-56.87, 1.58, 2.19, -0.26, -0.26, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794196899.668187, "measured_before_send": [-54.84, 1.58, 2.02, -0.17, 1.49, -30.23], "resends": [], "reached": true, "reached_angles": [-56.77, 1.58, 2.02, -0.17, 1.49, -30.23], "reach_err": 1.75, "elapsed_sec": 0.24, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 21, "t": "2026-11-09T13:01:40.483", "t_unix": 1794196900.483, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 2.0, "execute": true, "joint": 0, "delta": -2.0, "hold_id": 4, "hold_n": 0, "accepted": true, "measured_before": [-57.12, 1.58, 2.02, -0.17, 1.49, -30.32], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 1.75, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-58.87, 1.58, 2.19, -0.26, -0.26, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794196900.5203998, "measured_before_send": [-57.12, 1.58, 2.02, -0.17, 1.49, -30.32], "resends": [], "reached": true, "reached_angles": [-58.97, 1.58, 2.02, -0.17, 1.49, -30.32], "reach_err": 1.75, "elapsed_sec": 0.32, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 22, "t": "2026-11-09T13:01:41.485", "t_unix": 1794196901.485, "button": 13, "button_name": "dpad_left", "kind": "move", "selected_joint": 1, "step_deg": 2.0, "execute": true, "joint": 0, "delta": -2.0, "hold_id": 5, "hold_n": 0, "accepted": true, "measured_before": [-58.71, 1.58, 2.02, -0.17, 1.4, -30.32], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 1.66, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-60.87, 1.58, 2.19, -0.26, -0.26, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794196901.516441, "measured_before_send": [-58.71, 1.58, 2.02, -0.17, 1.4, -30.32], "resends": [], "reached": true, "reached_angles": [-61.08, 1.58, 2.02, -0.17, 1.4, -30.32], "reach_err": 1.66, "elapsed_sec": 0.16, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 23, "t": "2026-11-09T13:01:45.583", "t_unix": 1794196905.583, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 2, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 24, "t": "2026-11-09T13:01:45.804", "t_unix": 1794196905.804, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 3, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 25, "t": "2026-11-09T13:01:46.039", "t_unix": 1794196906.04, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 4, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 26, "t": "2026-11-09T13:01:47.301", "t_unix": 1794196907.301, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 6, "hold_n": 1, "held_sec": 0.409, "accepted": true, "measured_before": [-60.99, 1.58, 2.02, -0.17, 0.52, -30.32], "start_source": "hold", "cmd_gap_deg": 0.17, "hold_lead_deg": 0.78, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-60.87, 1.58, 2.19, -0.26, -14.48, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794196907.324977, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 27, "t": "2026-11-09T13:01:47.419", "t_unix": 1794196907.419, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 6, "hold_n": 2, "held_sec": 0.527, "accepted": true, "measured_before": [-60.99, 1.58, 2.02, -0.17, 0.26, -30.32], "start_source": "hold", "cmd_gap_deg": 0.17, "hold_lead_deg": 14.74, "sent": false, "why": "lead_ok", "hold_remaining_deg": 14.74, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 28, "t": "2026-11-09T13:01:47.520", "t_unix": 1794196907.521, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 6, "hold_n": 3, "held_sec": 0.628, "accepted": true, "measured_before": [-60.99, 1.58, 2.02, -0.17, 0.26, -30.32], "start_source": "hold", "cmd_gap_deg": 0.17, "hold_lead_deg": 14.74, "sent": false, "why": "lead_ok", "hold_remaining_deg": 14.74, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 29, "t": "2026-11-09T13:01:47.623", "t_unix": 1794196907.623, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 6, "hold_n": 4, "held_sec": 0.731, "accepted": true, "measured_before": [-60.99, 1.58, 2.02, -0.17, -7.03, -30.32], "start_source": "hold", "cmd_gap_deg": 0.17, "hold_lead_deg": 7.45, "sent": false, "why": "lead_ok", "hold_remaining_deg": 7.45, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 30, "t": "2026-11-09T13:01:47.725", "t_unix": 1794196907.725, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 6, "hold_n": 5, "held_sec": 0.832, "accepted": true, "measured_before": [-60.99, 1.58, 2.02, -0.17, -12.3, -30.32], "start_source": "hold", "cmd_gap_deg": 0.17, "hold_lead_deg": 2.18, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-60.87, 1.58, 2.19, -0.26, -27.3, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794196907.752935, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 31, "t": "2026-11-09T13:01:47.894", "t_unix": 1794196907.894, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 6, "hold_n": 6, "held_sec": 1.002, "accepted": true, "measured_before": [-60.99, 1.58, 2.02, -0.17, -14.15, -30.32], "start_source": "hold", "cmd_gap_deg": 0.17, "hold_lead_deg": 13.15, "sent": false, "why": "lead_ok", "hold_remaining_deg": 13.15, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 32, "t": "2026-11-09T13:01:47.995", "t_unix": 1794196907.996, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 6, "hold_n": 7, "held_sec": 1.103, "accepted": true, "measured_before": [-60.99, 1.58, 2.02, -0.17, -16.69, -30.32], "start_source": "hold", "cmd_gap_deg": 0.17, "hold_lead_deg": 10.61, "sent": false, "why": "lead_ok", "hold_remaining_deg": 10.61, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 33, "t": "2026-11-09T13:01:48.097", "t_unix": 1794196908.098, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 6, "hold_n": 8, "held_sec": 1.205, "accepted": true, "measured_before": [-60.99, 1.58, 2.02, -0.17, -21.18, -30.32], "start_source": "hold", "cmd_gap_deg": 0.17, "hold_lead_deg": 6.12, "sent": false, "why": "lead_ok", "hold_remaining_deg": 6.12, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 34, "t": "2026-11-09T13:01:48.200", "t_unix": 1794196908.201, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 6, "hold_n": 9, "held_sec": 1.308, "accepted": true, "measured_before": [-60.99, 1.58, 2.02, -0.17, -25.04, -30.32], "start_source": "hold", "cmd_gap_deg": 0.17, "hold_lead_deg": 2.26, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-60.87, 1.58, 2.19, -0.26, -40.04, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794196908.259516, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 35, "t": "2026-11-09T13:01:48.420", "t_unix": 1794196908.42, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 6, "hold_n": 10, "held_sec": 1.528, "accepted": true, "measured_before": [-60.99, 1.58, 2.02, -0.17, -28.3, -30.32], "start_source": "hold", "cmd_gap_deg": 0.17, "hold_lead_deg": 11.74, "sent": false, "why": "lead_ok", "hold_remaining_deg": 11.74, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 36, "t": "2026-11-09T13:01:48.522", "t_unix": 1794196908.522, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 6, "hold_n": 11, "held_sec": 1.63, "accepted": true, "measured_before": [-60.99, 1.58, 2.02, -0.17, -28.3, -30.32], "start_source": "hold", "cmd_gap_deg": 0.17, "hold_lead_deg": 11.74, "sent": false, "why": "lead_ok", "hold_remaining_deg": 11.74, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 37, "t": "2026-11-09T13:01:48.623", "t_unix": 1794196908.624, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 6, "hold_n": 12, "held_sec": 1.731, "accepted": true, "released_during_job": true, "measured_before": [-60.9, 1.58, 2.02, -0.17, -36.47, -30.32], "start_source": "hold", "cmd_gap_deg": 0.17, "hold_lead_deg": 3.57, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-60.87, 1.58, 2.19, -0.26, -51.47, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794196908.682928, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 38, "t": "2026-11-09T13:01:48.728", "t_unix": 1794196908.729, "button": null, "button_name": null, "kind": "halt", "selected_joint": 4, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 6, "halt_joint": 4, "measured_at_request": [-60.99, 1.58, 2.02, -0.17, -28.3, -30.32], "t_halt": 1794196908.729759, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-60.73, 2.46, 2.81, -0.17, -38.58, -30.32], "moved_after_request_deg": [0.26, 0.88, 0.79, 0.0, -10.28, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 39, "t": "2026-11-09T13:01:49.441", "t_unix": 1794196909.442, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 5, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 40, "t": "2026-11-09T13:01:49.696", "t_unix": 1794196909.697, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 41, "t": "2026-11-09T13:01:51.418", "t_unix": 1794196911.418, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 7, "hold_n": 1, "held_sec": 0.402, "accepted": true, "measured_before": [-60.82, 2.63, 2.98, -0.17, -38.49, -30.32], "start_source": "hold", "cmd_gap_deg": 0.79, "hold_lead_deg": 1.05, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-60.87, 17.63, 2.19, -0.26, -38.58, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794196911.434195, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 42, "t": "2026-11-09T13:01:51.518", "t_unix": 1794196911.519, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 7, "hold_n": 2, "held_sec": 0.502, "accepted": true, "measured_before": [-60.82, 2.1, 2.98, -0.17, -38.49, -30.32], "start_source": "hold", "cmd_gap_deg": 0.79, "hold_lead_deg": 15.53, "sent": false, "why": "lead_ok", "hold_remaining_deg": 15.53, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 44, "t": "2026-11-09T13:01:58.136", "t_unix": 1794196918.136, "button": 10, "button_name": "r1", "kind": "modifier", "selected_joint": 1, "step_deg": 2.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 45, "t": "2026-11-09T13:01:58.781", "t_unix": 1794196918.782, "button": 10, "button_name": "r1", "kind": "modifier", "selected_joint": 1, "step_deg": 2.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 43, "t": "2026-11-09T13:01:51.635", "t_unix": 1794196911.635, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 7, "hold_n": 3, "held_sec": 0.619, "accepted": true, "released_during_job": true, "measured_before": [-60.99, 18.63, 1.75, -0.08, -39.63, -30.32], "start_source": "hold", "cmd_gap_deg": 1.05, "hold_lead_deg": 1.0, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-60.87, 33.63, 2.19, -0.26, -38.58, -30.23], "sent": false, "why": "halted_before_send", "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 46, "t": "2026-11-09T13:01:59.188", "t_unix": 1794196919.188, "button": null, "button_name": null, "kind": "halt", "selected_joint": 1, "step_deg": 2.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 7, "halt_joint": 1, "measured_at_request": [-60.82, 2.1, 2.98, -0.17, -38.49, -30.32], "t_halt": 1794196919.188724, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-60.82, 20.21, 2.81, -0.08, -37.7, -30.32], "moved_after_request_deg": [0.0, 18.11, -0.17, 0.09, 0.79, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 47, "t": "2026-11-09T13:01:59.340", "t_unix": 1794196919.341, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 2.0, "execute": true, "joint": 1, "delta": 1.0, "hold_id": 9, "hold_n": 0, "accepted": true, "measured_before": [-60.82, 20.21, 2.9, -0.08, -37.61, -30.32], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 0.97, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-60.87, 21.21, 2.19, -0.26, -38.58, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794196919.38027, "measured_before_send": [-60.99, 20.21, 2.9, -0.08, -37.61, -30.32], "resends": [], "reached": false, "settled": true, "reached_angles": [-61.08, 22.41, 1.84, -0.08, -37.79, -30.32], "reach_err": 1.2, "elapsed_sec": 0.58, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 48, "t": "2026-11-09T13:02:00.006", "t_unix": 1794196920.006, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 2.0, "execute": true, "joint": 1, "delta": 2.0, "hold_id": 10, "hold_n": 0, "accepted": true, "measured_before": [-61.08, 22.41, 1.84, -0.08, -37.79, -30.32], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 1.2, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-60.87, 23.21, 2.19, -0.26, -38.58, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794196920.044725, "measured_before_send": [-61.08, 22.41, 1.84, -0.08, -37.79, -30.32], "resends": [], "reached": false, "settled": true, "reached_angles": [-61.17, 24.43, 1.75, 0.0, -37.96, -30.32], "reach_err": 1.22, "elapsed_sec": 0.46, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 49, "t": "2026-11-09T13:02:00.647", "t_unix": 1794196920.648, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 11, "hold_n": 1, "held_sec": 0.404, "accepted": true, "measured_before": [-61.17, 24.43, 1.75, 0.0, -37.96, -30.32], "start_source": "hold", "cmd_gap_deg": 0.62, "hold_lead_deg": 1.22, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-60.87, 39.43, 2.19, -0.26, -38.58, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794196920.6727219, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 50, "t": "2026-11-09T13:02:00.749", "t_unix": 1794196920.75, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 11, "hold_n": 2, "held_sec": 0.506, "accepted": true, "measured_before": [-61.17, 24.43, 1.75, 0.0, -37.96, -30.32], "start_source": "hold", "cmd_gap_deg": 0.62, "hold_lead_deg": 15.0, "sent": false, "why": "lead_ok", "hold_remaining_deg": 15.0, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 51, "t": "2026-11-09T13:02:00.849", "t_unix": 1794196920.849, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 11, "hold_n": 3, "held_sec": 0.606, "accepted": true, "measured_before": [-60.99, 26.36, 1.75, 0.0, -38.14, -30.32], "start_source": "hold", "cmd_gap_deg": 0.44, "hold_lead_deg": 13.07, "sent": false, "why": "lead_ok", "hold_remaining_deg": 13.07, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 52, "t": "2026-11-09T13:02:00.951", "t_unix": 1794196920.951, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 11, "hold_n": 4, "held_sec": 0.708, "accepted": true, "measured_before": [-61.08, 30.32, 1.75, 0.0, -38.14, -30.32], "start_source": "hold", "cmd_gap_deg": 0.44, "hold_lead_deg": 9.11, "sent": false, "why": "lead_ok", "hold_remaining_deg": 9.11, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 53, "t": "2026-11-09T13:02:01.052", "t_unix": 1794196921.053, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 11, "hold_n": 5, "held_sec": 0.81, "accepted": true, "measured_before": [-61.08, 35.15, 1.75, 0.0, -38.14, -30.32], "start_source": "hold", "cmd_gap_deg": 0.44, "hold_lead_deg": 4.28, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-60.87, 50.15, 2.19, -0.26, -38.58, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794196921.083068, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 54, "t": "2026-11-09T13:02:01.134", "t_unix": 1794196921.135, "button": null, "button_name": null, "kind": "halt", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 11, "halt_joint": 1, "measured_at_request": [-61.08, 35.15, 1.75, 0.0, -38.14, -30.32], "t_halt": 1794196921.134926, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-61.08, 40.69, 2.54, 0.0, -36.56, -30.32], "moved_after_request_deg": [0.0, 5.54, 0.79, 0.0, 1.58, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 55, "t": "2026-11-09T13:02:04.100", "t_unix": 1794196924.101, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 2, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 56, "t": "2026-11-09T13:02:05.652", "t_unix": 1794196925.652, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": 15.0, "hold_id": 12, "hold_n": 1, "held_sec": 0.407, "accepted": true, "measured_before": [-61.08, 40.69, 2.63, 0.0, -36.65, -30.32], "start_source": "hold", "cmd_gap_deg": 1.93, "hold_lead_deg": 0.44, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-60.87, 40.69, 17.63, -0.26, -38.58, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794196925.6696289, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 57, "t": "2026-11-09T13:02:05.755", "t_unix": 1794196925.755, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": 15.0, "hold_id": 12, "hold_n": 2, "held_sec": 0.51, "accepted": true, "measured_before": [-61.08, 40.69, 2.63, 0.0, -37.7, -30.32], "start_source": "hold", "cmd_gap_deg": 0.88, "hold_lead_deg": 15.0, "sent": false, "why": "lead_ok", "hold_remaining_deg": 15.0, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 58, "t": "2026-11-09T13:02:05.840", "t_unix": 1794196925.84, "button": null, "button_name": null, "kind": "halt", "selected_joint": 2, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 12, "halt_joint": 2, "measured_at_request": [-61.08, 40.69, 2.63, 0.0, -37.7, -30.32], "t_halt": 1794196925.840249, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-61.08, 41.92, 3.33, 0.17, -37.79, -30.32], "moved_after_request_deg": [0.0, 1.23, 0.7, 0.17, -0.09, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 59, "t": "2026-11-09T13:02:06.837", "t_unix": 1794196926.837, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": 15.0, "hold_id": 13, "hold_n": 1, "held_sec": 0.405, "accepted": true, "measured_before": [-61.17, 41.92, 3.42, 0.17, -37.52, -30.32], "start_source": "hold", "cmd_gap_deg": 1.23, "hold_lead_deg": 0.09, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-60.87, 40.69, 18.42, -0.26, -38.58, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794196926.8569548, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 60, "t": "2026-11-09T13:02:06.938", "t_unix": 1794196926.939, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": 15.0, "hold_id": 13, "hold_n": 2, "held_sec": 0.506, "accepted": true, "measured_before": [-61.17, 41.92, 3.42, 0.17, -37.52, -30.32], "start_source": "hold", "cmd_gap_deg": 1.23, "hold_lead_deg": 15.0, "sent": false, "why": "lead_ok", "hold_remaining_deg": 15.0, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 61, "t": "2026-11-09T13:02:07.041", "t_unix": 1794196927.042, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": 15.0, "hold_id": 13, "hold_n": 3, "held_sec": 0.609, "accepted": true, "released_during_job": true, "measured_before": [-61.17, 41.66, 18.8, 0.17, -38.05, -30.05], "start_source": "hold", "cmd_gap_deg": 0.97, "hold_lead_deg": 0.38, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-60.87, 40.69, 33.8, -0.26, -38.58, -30.23], "sent": false, "why": "halted_before_send", "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 62, "t": "2026-11-09T13:02:07.478", "t_unix": 1794196927.478, "button": null, "button_name": null, "kind": "halt", "selected_joint": 2, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 13, "halt_joint": 2, "measured_at_request": [-61.17, 41.92, 3.42, 0.17, -37.52, -30.32], "t_halt": 1794196927.478507, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-60.82, 42.45, 18.89, 0.35, -37.96, -29.61], "moved_after_request_deg": [0.35, 0.53, 15.47, 0.18, -0.44, 0.71], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 63, "t": "2026-11-09T13:02:09.683", "t_unix": 1794196929.684, "button": 14, "button_name": "dpad_right", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 0, "delta": 1.0, "hold_id": 14, "hold_n": 0, "accepted": true, "measured_before": [-60.82, 42.53, 18.89, 0.52, -37.96, -29.35], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 1.84, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-59.87, 40.69, 18.89, -0.26, -38.58, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794196929.717174, "measured_before_send": [-60.82, 42.53, 18.89, 0.52, -37.96, -29.35], "resends": [], "reached": true, "reached_angles": [-60.2, 41.3, 18.89, 0.7, -38.23, -29.61], "reach_err": 0.96, "elapsed_sec": 0.17, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 64, "t": "2026-11-09T13:02:10.907", "t_unix": 1794196930.907, "button": 14, "button_name": "dpad_right", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 0, "delta": 1.0, "hold_id": 15, "hold_n": 0, "accepted": true, "measured_before": [-60.11, 41.3, 18.89, 0.35, -38.32, -29.61], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 0.62, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-58.87, 40.69, 18.89, -0.26, -38.58, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794196930.9444978, "measured_before_send": [-60.11, 41.3, 18.89, 0.35, -38.32, -29.61], "resends": [], "reached": true, "reached_angles": [-58.53, 41.3, 18.89, 0.52, -38.32, -29.61], "reach_err": 0.78, "elapsed_sec": 0.16, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 65, "t": "2026-11-09T13:02:21.145", "t_unix": 1794196941.146, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 3, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 66, "t": "2026-11-09T13:02:21.381", "t_unix": 1794196941.382, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 4, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 67, "t": "2026-11-09T13:02:22.042", "t_unix": 1794196942.043, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -1.0, "hold_id": 16, "hold_n": 0, "accepted": true, "measured_before": [-58.88, 41.3, 18.89, 0.17, -39.55, -30.05], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 0.97, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-58.87, 40.69, 18.89, -0.26, -39.58, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794196942.0804758, "measured_before_send": [-58.88, 41.3, 18.89, 0.17, -39.55, -30.05], "resends": [], "reached": true, "reached_angles": [-58.88, 41.3, 18.89, 0.17, -39.63, -30.05], "reach_err": 0.61, "elapsed_sec": 0.02, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 68, "t": "2026-11-09T13:02:23.043", "t_unix": 1794196943.043, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -1.0, "hold_id": 17, "hold_n": 0, "accepted": true, "measured_before": [-58.88, 41.3, 18.89, 0.17, -39.72, -30.05], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 0.61, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-58.87, 40.69, 18.89, -0.26, -40.58, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794196943.068856, "measured_before_send": [-58.88, 41.3, 18.89, 0.17, -39.72, -30.05], "resends": [], "reached": true, "reached_angles": [-58.88, 41.3, 18.89, 0.17, -40.69, -30.05], "reach_err": 0.61, "elapsed_sec": 0.08, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 69, "t": "2026-11-09T13:02:24.008", "t_unix": 1794196944.009, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 18, "hold_n": 1, "held_sec": 0.405, "accepted": true, "measured_before": [-58.88, 41.3, 18.89, 0.17, -41.83, -30.05], "start_source": "hold", "cmd_gap_deg": 0.61, "hold_lead_deg": 1.25, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-58.87, 40.69, 18.89, -0.26, -56.83, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794196944.0288692, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 70, "t": "2026-11-09T13:02:24.110", "t_unix": 1794196944.111, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 18, "hold_n": 2, "held_sec": 0.507, "accepted": true, "released_during_job": true, "measured_before": [-58.88, 41.3, 18.89, 0.17, -44.29, -30.05], "start_source": "hold", "cmd_gap_deg": 0.61, "hold_lead_deg": 12.54, "sent": false, "why": "lead_ok", "hold_remaining_deg": 12.54, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 71, "t": "2026-11-09T13:02:24.281", "t_unix": 1794196944.281, "button": null, "button_name": null, "kind": "halt", "selected_joint": 4, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 18, "halt_joint": 4, "measured_at_request": [-58.88, 41.3, 18.89, 0.17, -41.83, -30.05], "t_halt": 1794196944.281562, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-58.79, 42.45, 18.89, 0.26, -45.7, -29.97], "moved_after_request_deg": [0.09, 1.15, 0.0, 0.09, -3.87, 0.08], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 72, "t": "2026-11-09T13:02:25.399", "t_unix": 1794196945.4, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 19, "hold_n": 1, "held_sec": 0.406, "accepted": true, "measured_before": [-58.88, 42.45, 18.89, 0.35, -45.61, -29.97], "start_source": "hold", "cmd_gap_deg": 1.76, "hold_lead_deg": 0.09, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-58.87, 40.69, 18.89, -0.26, -60.61, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794196945.422994, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 73, "t": "2026-11-09T13:02:25.503", "t_unix": 1794196945.504, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 19, "hold_n": 2, "held_sec": 0.51, "accepted": true, "measured_before": [-58.88, 42.45, 18.89, 0.35, -45.79, -29.97], "start_source": "hold", "cmd_gap_deg": 1.76, "hold_lead_deg": 14.82, "sent": false, "why": "lead_ok", "hold_remaining_deg": 14.82, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 74, "t": "2026-11-09T13:02:25.603", "t_unix": 1794196945.604, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 19, "hold_n": 3, "held_sec": 0.61, "accepted": true, "measured_before": [-58.88, 41.48, 18.89, 0.35, -48.42, -30.05], "start_source": "hold", "cmd_gap_deg": 0.79, "hold_lead_deg": 12.19, "sent": false, "why": "lead_ok", "hold_remaining_deg": 12.19, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 75, "t": "2026-11-09T13:02:25.705", "t_unix": 1794196945.705, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 19, "hold_n": 4, "held_sec": 0.712, "accepted": true, "released_during_job": true, "measured_before": [-58.88, 41.48, 18.89, 0.35, -52.29, -30.05], "start_source": "hold", "cmd_gap_deg": 0.79, "hold_lead_deg": 8.32, "sent": false, "why": "lead_ok", "hold_remaining_deg": 8.32, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 76, "t": "2026-11-09T13:02:25.757", "t_unix": 1794196945.757, "button": null, "button_name": null, "kind": "halt", "selected_joint": 4, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 19, "halt_joint": 4, "measured_at_request": [-58.88, 41.48, 18.89, 0.35, -48.42, -30.05], "t_halt": 1794196945.7574651, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-58.88, 41.48, 18.89, 0.35, -56.77, -30.05], "moved_after_request_deg": [0.0, 0.0, 0.0, 0.0, -8.35, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 77, "t": "2026-11-09T13:02:27.755", "t_unix": 1794196947.755, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 5, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 78, "t": "2026-11-09T13:02:27.941", "t_unix": 1794196947.942, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 79, "t": "2026-11-09T13:02:33.131", "t_unix": 1794196953.132, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 2, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 80, "t": "2026-11-09T13:02:33.350", "t_unix": 1794196953.351, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 3, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 81, "t": "2026-11-09T13:02:33.588", "t_unix": 1794196953.589, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 4, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 82, "t": "2026-11-09T13:02:34.694", "t_unix": 1794196954.695, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 20, "hold_n": 1, "held_sec": 0.408, "accepted": true, "measured_before": [-58.88, 41.13, 18.89, -0.52, -25.83, -30.32], "start_source": "hold", "cmd_gap_deg": 0.44, "hold_lead_deg": 30.94, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-58.87, 40.69, 18.89, -0.26, -40.83, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794196954.707328, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 83, "t": "2026-11-09T13:02:34.795", "t_unix": 1794196954.796, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 20, "hold_n": 2, "held_sec": 0.509, "accepted": true, "measured_before": [-58.88, 41.13, 18.89, -0.52, -26.27, -30.32], "start_source": "hold", "cmd_gap_deg": 0.44, "hold_lead_deg": 14.56, "sent": false, "why": "lead_ok", "hold_remaining_deg": 14.56, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 84, "t": "2026-11-09T13:02:34.898", "t_unix": 1794196954.898, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 20, "hold_n": 3, "held_sec": 0.612, "accepted": true, "measured_before": [-58.88, 41.13, 18.89, -0.52, -37.35, -30.32], "start_source": "hold", "cmd_gap_deg": 0.44, "hold_lead_deg": 3.48, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-58.87, 40.69, 18.89, -0.26, -52.35, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794196954.958737, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 85, "t": "2026-11-09T13:02:35.016", "t_unix": 1794196955.017, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 20, "hold_n": 4, "held_sec": 0.73, "accepted": true, "measured_before": [-58.88, 41.13, 18.89, -0.26, -54.58, -30.23], "start_source": "hold", "cmd_gap_deg": 0.44, "hold_lead_deg": 2.23, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-58.87, 40.69, 18.89, -0.26, -69.58, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794196955.158292, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 86, "t": "2026-11-09T13:02:35.219", "t_unix": 1794196955.22, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 20, "hold_n": 5, "held_sec": 0.933, "accepted": true, "measured_before": [-58.88, 41.13, 18.89, -0.08, -47.1, -30.23], "start_source": "hold", "cmd_gap_deg": 0.44, "hold_lead_deg": 22.48, "sent": false, "why": "lead_ok", "hold_remaining_deg": 22.48, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 87, "t": "2026-11-09T13:02:35.323", "t_unix": 1794196955.323, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 20, "hold_n": 6, "held_sec": 1.036, "accepted": true, "measured_before": [-58.88, 41.13, 18.89, -0.08, -42.09, -30.23], "start_source": "hold", "cmd_gap_deg": 0.44, "hold_lead_deg": 27.49, "sent": false, "why": "lead_ok", "hold_remaining_deg": 27.49, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 88, "t": "2026-11-09T13:02:35.423", "t_unix": 1794196955.423, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 20, "hold_n": 7, "held_sec": 1.137, "accepted": true, "measured_before": [-58.88, 41.13, 18.89, -0.08, -42.09, -30.23], "start_source": "hold", "cmd_gap_deg": 0.44, "hold_lead_deg": 27.49, "sent": false, "why": "lead_ok", "hold_remaining_deg": 27.49, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 89, "t": "2026-11-09T13:02:35.526", "t_unix": 1794196955.526, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 20, "hold_n": 8, "held_sec": 1.24, "accepted": true, "measured_before": [-58.88, 41.13, 18.89, -0.08, -44.56, -30.23], "start_source": "hold", "cmd_gap_deg": 0.44, "hold_lead_deg": 25.02, "sent": false, "why": "lead_ok", "hold_remaining_deg": 25.02, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 90, "t": "2026-11-09T13:02:35.628", "t_unix": 1794196955.629, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 20, "hold_n": 9, "held_sec": 1.342, "accepted": true, "measured_before": [-58.88, 41.13, 18.89, -0.08, -49.39, -30.23], "start_source": "hold", "cmd_gap_deg": 0.44, "hold_lead_deg": 20.19, "sent": false, "why": "lead_ok", "hold_remaining_deg": 20.19, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 91, "t": "2026-11-09T13:02:35.730", "t_unix": 1794196955.731, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 20, "hold_n": 10, "held_sec": 1.444, "accepted": true, "released_during_job": true, "measured_before": [-58.88, 41.13, 18.89, -0.08, -51.24, -30.23], "start_source": "hold", "cmd_gap_deg": 0.44, "hold_lead_deg": 18.34, "sent": false, "why": "lead_ok", "hold_remaining_deg": 18.34, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 92, "t": "2026-11-09T13:02:35.765", "t_unix": 1794196955.765, "button": null, "button_name": null, "kind": "halt", "selected_joint": 4, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 20, "halt_joint": 4, "measured_at_request": [-58.88, 41.13, 18.89, -0.08, -49.39, -30.23], "t_halt": 1794196955.765749, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-58.88, 42.53, 18.89, 0.0, -49.39, -30.23], "moved_after_request_deg": [0.0, 1.4, 0.0, 0.08, 0.0, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 93, "t": "2026-11-09T13:02:36.695", "t_unix": 1794196956.696, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 21, "hold_n": 1, "held_sec": 0.406, "accepted": true, "measured_before": [-58.88, 42.53, 18.89, 0.08, -49.39, -30.23], "start_source": "hold", "cmd_gap_deg": 1.84, "hold_lead_deg": 0.0, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-58.87, 40.69, 18.89, -0.26, -64.39, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794196956.7243578, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 94, "t": "2026-11-09T13:02:36.816", "t_unix": 1794196956.817, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 21, "hold_n": 2, "held_sec": 0.527, "accepted": true, "measured_before": [-58.88, 42.53, 18.89, 0.08, -49.48, -30.23], "start_source": "hold", "cmd_gap_deg": 1.84, "hold_lead_deg": 14.91, "sent": false, "why": "lead_ok", "hold_remaining_deg": 14.91, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 95, "t": "2026-11-09T13:02:36.920", "t_unix": 1794196956.92, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 21, "hold_n": 3, "held_sec": 0.63, "accepted": true, "measured_before": [-58.88, 41.48, 18.89, 0.08, -52.99, -30.23], "start_source": "hold", "cmd_gap_deg": 0.79, "hold_lead_deg": 11.4, "sent": false, "why": "lead_ok", "hold_remaining_deg": 11.4, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 96, "t": "2026-11-09T13:02:37.022", "t_unix": 1794196957.023, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 21, "hold_n": 4, "held_sec": 0.733, "accepted": true, "measured_before": [-58.88, 41.39, 18.89, 0.08, -56.95, -30.23], "start_source": "hold", "cmd_gap_deg": 0.7, "hold_lead_deg": 7.44, "sent": false, "why": "lead_ok", "hold_remaining_deg": 7.44, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 97, "t": "2026-11-09T13:02:37.123", "t_unix": 1794196957.124, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 21, "hold_n": 5, "held_sec": 0.834, "accepted": true, "released_during_job": true, "measured_before": [-58.88, 41.39, 18.89, 0.08, -60.73, -30.23], "start_source": "hold", "cmd_gap_deg": 0.7, "hold_lead_deg": 3.66, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-58.87, 40.69, 18.89, -0.26, -75.73, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794196957.158101, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 98, "t": "2026-11-09T13:02:37.243", "t_unix": 1794196957.243, "button": null, "button_name": null, "kind": "halt", "selected_joint": 4, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 21, "halt_joint": 4, "measured_at_request": [-58.88, 41.39, 18.89, 0.08, -56.95, -30.23], "t_halt": 1794196957.243553, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-58.79, 42.53, 18.89, 0.17, -60.02, -30.23], "moved_after_request_deg": [0.09, 1.14, 0.0, 0.09, -3.07, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 99, "t": "2026-11-09T13:02:38.936", "t_unix": 1794196958.937, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 5, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 100, "t": "2026-11-09T13:02:39.106", "t_unix": 1794196959.107, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 101, "t": "2026-11-09T13:02:40.140", "t_unix": 1794196960.14, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 22, "hold_n": 1, "held_sec": 0.407, "accepted": true, "measured_before": [-58.88, 42.53, 18.89, 0.26, -59.94, -30.23], "start_source": "hold", "cmd_gap_deg": 0.52, "hold_lead_deg": 1.84, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-58.87, 57.53, 18.89, -0.26, -60.02, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794196960.156632, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 102, "t": "2026-11-09T13:02:40.241", "t_unix": 1794196960.241, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 22, "hold_n": 2, "held_sec": 0.508, "accepted": true, "measured_before": [-58.88, 42.53, 18.89, 0.26, -61.08, -30.23], "start_source": "hold", "cmd_gap_deg": 1.06, "hold_lead_deg": 15.0, "sent": false, "why": "lead_ok", "hold_remaining_deg": 15.0, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 103, "t": "2026-11-09T13:02:40.343", "t_unix": 1794196960.344, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 22, "hold_n": 3, "held_sec": 0.61, "accepted": true, "measured_before": [-58.88, 42.89, 18.89, 0.26, -64.16, -30.23], "start_source": "mixed", "cmd_gap_deg": 4.14, "hold_lead_deg": 14.64, "sent": false, "why": "lead_ok", "hold_remaining_deg": 14.64, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 104, "t": "2026-11-09T13:02:40.447", "t_unix": 1794196960.448, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 22, "hold_n": 4, "held_sec": 0.714, "accepted": true, "measured_before": [-58.88, 47.1, 18.89, 0.26, -64.24, -30.23], "start_source": "mixed", "cmd_gap_deg": 4.22, "hold_lead_deg": 10.43, "sent": false, "why": "lead_ok", "hold_remaining_deg": 10.43, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 105, "t": "2026-11-09T13:02:40.499", "t_unix": 1794196960.499, "button": null, "button_name": null, "kind": "halt", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 22, "halt_joint": 1, "measured_at_request": [-58.88, 47.1, 18.89, 0.26, -64.24, -30.23], "t_halt": 1794196960.499446, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-58.88, 52.64, 18.89, 0.26, -64.24, -30.23], "moved_after_request_deg": [0.0, 5.54, 0.0, 0.0, 0.0, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 106, "t": "2026-11-09T13:02:41.632", "t_unix": 1794196961.632, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 23, "hold_n": 1, "held_sec": 0.407, "accepted": true, "measured_before": [-58.88, 52.64, 18.89, 0.26, -64.24, -30.23], "start_source": "mixed", "cmd_gap_deg": 4.22, "hold_lead_deg": 0.0, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-58.87, 67.64, 18.89, -0.26, -60.02, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794196961.649493, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 107, "t": "2026-11-09T13:02:41.735", "t_unix": 1794196961.735, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 15.0, "hold_id": 23, "hold_n": 2, "held_sec": 0.51, "accepted": true, "measured_before": [-58.88, 53.7, 18.89, 0.35, -64.33, -30.23], "start_source": "mixed", "cmd_gap_deg": 4.31, "hold_lead_deg": 13.94, "sent": false, "why": "lead_ok", "hold_remaining_deg": 13.94, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 108, "t": "2026-11-09T13:02:41.786", "t_unix": 1794196961.787, "button": null, "button_name": null, "kind": "halt", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 23, "halt_joint": 1, "measured_at_request": [-58.88, 53.7, 18.89, 0.35, -64.33, -30.23], "t_halt": 1794196961.788436, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-58.88, 56.68, 18.89, 0.35, -62.66, -30.23], "moved_after_request_deg": [0.0, 2.98, 0.0, 0.0, 1.67, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 109, "t": "2026-11-09T13:02:43.096", "t_unix": 1794196963.097, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 1.0, "hold_id": 24, "hold_n": 0, "accepted": true, "measured_before": [-58.88, 56.68, 18.89, 0.43, -62.66, -30.23], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 2.64, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-58.87, 57.68, 18.89, -0.26, -60.02, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794196963.150398, "measured_before_send": [-58.88, 56.68, 18.89, 0.43, -62.66, -30.23], "resends": [], "reached": true, "reached_angles": [-58.88, 58.0, 18.89, 0.43, -63.28, -30.23], "reach_err": 3.26, "elapsed_sec": 0.1, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 110, "t": "2026-11-09T13:02:44.608", "t_unix": 1794196964.608, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": 1.0, "hold_id": 25, "hold_n": 0, "accepted": true, "measured_before": [-58.88, 58.71, 18.89, 0.52, -63.28, -30.23], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 3.26, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-58.87, 58.68, 18.89, -0.26, -60.02, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794196964.6489139, "measured_before_send": [-58.88, 58.71, 18.89, 0.52, -63.28, -30.23], "resends": [], "reached": true, "reached_angles": [-58.88, 58.71, 18.89, 0.52, -63.28, -30.23], "reach_err": 3.26, "elapsed_sec": 0.02, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 111, "t": "2026-11-09T13:02:46.495", "t_unix": 1794196966.496, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 2, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 112, "t": "2026-11-09T13:02:48.254", "t_unix": 1794196968.254, "button": 12, "button_name": "dpad_down", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": 1.0, "hold_id": 26, "hold_n": 0, "accepted": true, "measured_before": [-58.88, 59.67, 18.89, 0.43, -64.51, -30.23], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 4.49, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-58.87, 58.68, 19.89, -0.26, -60.02, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794196968.2922199, "measured_before_send": [-58.88, 59.67, 18.89, 0.43, -64.51, -30.23], "resends": [], "reached": true, "reached_angles": [-58.88, 59.67, 20.3, 0.35, -65.56, -30.23], "reach_err": 5.54, "elapsed_sec": 0.15, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 113, "t": "2026-11-09T13:02:49.765", "t_unix": 1794196969.765, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -1.0, "hold_id": 27, "hold_n": 0, "accepted": true, "measured_before": [-58.88, 59.67, 20.39, 0.35, -65.56, -30.23], "start_source": "command", "others_from_measured": [], "cmd_gap_deg": 5.54, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-58.87, 58.68, 18.89, -0.26, -60.02, -30.23], "sent": true, "timeout_sec": 8.0, "t_send": 1794196969.796552, "measured_before_send": [-58.88, 59.67, 20.39, 0.35, -65.56, -30.23], "resends": [0.34, 0.69], "reached": false, "not_moved": true, "reached_angles": [-58.88, 59.67, 20.21, 0.35, -65.56, -30.23], "reach_err": 5.54, "elapsed_sec": 1.01, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 114, "t": "2026-11-09T13:02:51.005", "t_unix": 1794196971.005, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -15.0, "hold_id": 28, "hold_n": 1, "held_sec": 0.407, "accepted": true, "measured_before": [-58.88, 59.67, 20.21, 0.35, -65.56, -30.23], "start_source": "mixed", "cmd_gap_deg": 5.54, "hold_lead_deg": 1.32, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-58.87, 58.68, 5.21, -0.26, -60.02, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794196971.0245109, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 115, "t": "2026-11-09T13:02:51.107", "t_unix": 1794196971.108, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -15.0, "hold_id": 28, "hold_n": 2, "held_sec": 0.509, "accepted": true, "released_during_job": true, "measured_before": [-58.88, 59.67, 20.21, 0.35, -65.56, -30.23], "start_source": "mixed", "cmd_gap_deg": 5.54, "hold_lead_deg": 15.0, "sent": false, "why": "lead_ok", "hold_remaining_deg": 15.0, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 116, "t": "2026-11-09T13:02:51.141", "t_unix": 1794196971.142, "button": null, "button_name": null, "kind": "halt", "selected_joint": 2, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 28, "halt_joint": 2, "measured_at_request": [-58.88, 59.67, 20.21, 0.35, -65.56, -30.23], "t_halt": 1794196971.14297, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-58.97, 60.73, 20.12, 0.26, -64.24, -30.32], "moved_after_request_deg": [-0.09, 1.06, -0.09, -0.09, 1.32, -0.09], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 117, "t": "2026-11-09T13:02:52.306", "t_unix": 1794196972.307, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -15.0, "hold_id": 29, "hold_n": 1, "held_sec": 0.403, "accepted": true, "measured_before": [-58.88, 60.82, 20.12, 0.35, -63.89, -30.32], "start_source": "mixed", "cmd_gap_deg": 3.87, "hold_lead_deg": 0.0, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-58.87, 58.68, 5.12, -0.26, -60.02, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794196972.329056, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 118, "t": "2026-11-09T13:02:52.422", "t_unix": 1794196972.423, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -15.0, "hold_id": 29, "hold_n": 2, "held_sec": 0.52, "accepted": true, "measured_before": [-58.88, 60.82, 20.12, 0.35, -63.89, -30.32], "start_source": "mixed", "cmd_gap_deg": 3.87, "hold_lead_deg": 15.0, "sent": false, "why": "lead_ok", "hold_remaining_deg": 15.0, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 119, "t": "2026-11-09T13:02:52.524", "t_unix": 1794196972.525, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -15.0, "hold_id": 29, "hold_n": 3, "held_sec": 0.622, "accepted": true, "measured_before": [-58.88, 60.82, 20.12, 0.35, -61.52, -30.32], "start_source": "hold", "cmd_gap_deg": 2.14, "hold_lead_deg": 15.0, "sent": false, "why": "lead_ok", "hold_remaining_deg": 15.0, "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 120, "t": "2026-11-09T13:02:52.627", "t_unix": 1794196972.628, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 2, "step_deg": 1.0, "execute": true, "joint": 2, "delta": -15.0, "hold_id": 29, "hold_n": 4, "held_sec": 0.724, "accepted": true, "released_during_job": true, "measured_before": [-58.88, 60.82, 20.12, 0.35, -58.44, -30.32], "start_source": "hold", "cmd_gap_deg": 2.14, "hold_lead_deg": 15.0, "command": [-58.87, 58.68, 5.12, -0.26, -60.02, -30.23], "hold_resend": true, "sent": false, "why": "halted_before_send", "reached": null, "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 121, "t": "2026-11-09T13:02:52.694", "t_unix": 1794196972.694, "button": null, "button_name": null, "kind": "halt", "selected_joint": 2, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 29, "halt_joint": 2, "measured_at_request": [-58.88, 60.82, 20.12, 0.35, -61.52, -30.32], "t_halt": 1794196972.694428, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-58.88, 61.87, 9.05, 0.43, -53.43, -30.32], "moved_after_request_deg": [0.0, 1.05, -11.07, 0.08, 8.09, 0.0], "grip_state": "unknown", "stopped": false, "stop_reason": null}
{"seq": 122, "t": "2026-11-09T13:02:55.405", "t_unix": 1794196975.406, "button": 0, "button_name": "cross", "kind": "grip_close", "selected_joint": 2, "step_deg": 1.0, "execute": true, "grip_cmd": 1, "accepted": true, "measured_before": null, "sent": true, "reached": null, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 123, "t": "2026-11-09T13:03:00.840", "t_unix": 1794196980.841, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 3, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 124, "t": "2026-11-09T13:03:01.130", "t_unix": 1794196981.13, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 4, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 125, "t": "2026-11-09T13:03:01.542", "t_unix": 1794196981.542, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 5, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 126, "t": "2026-11-09T13:03:01.998", "t_unix": 1794196981.998, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 127, "t": "2026-11-09T13:03:03.250", "t_unix": 1794196983.251, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 30, "hold_n": 1, "held_sec": 0.407, "accepted": true, "measured_before": [-58.88, 61.87, 9.31, 0.08, -54.05, -30.14], "start_source": "mixed", "cmd_gap_deg": 5.97, "hold_lead_deg": 3.19, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-58.87, 46.87, 9.05, -0.26, -60.02, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794196983.271498, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 128, "t": "2026-11-09T13:03:03.353", "t_unix": 1794196983.353, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 30, "hold_n": 2, "held_sec": 0.51, "accepted": true, "measured_before": [-58.88, 61.08, 9.31, 0.08, -53.78, -30.23], "start_source": "mixed", "cmd_gap_deg": 6.24, "hold_lead_deg": 14.21, "sent": false, "why": "lead_ok", "hold_remaining_deg": 14.21, "reached": null, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 129, "t": "2026-11-09T13:03:03.454", "t_unix": 1794196983.454, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 30, "hold_n": 3, "held_sec": 0.61, "accepted": true, "measured_before": [-58.88, 59.58, 9.31, 0.08, -57.3, -30.32], "start_source": "hold", "cmd_gap_deg": 2.72, "hold_lead_deg": 12.71, "sent": false, "why": "lead_ok", "hold_remaining_deg": 12.71, "reached": null, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 130, "t": "2026-11-09T13:03:03.556", "t_unix": 1794196983.557, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 30, "hold_n": 4, "held_sec": 0.713, "accepted": true, "measured_before": [-58.97, 54.58, 9.31, 0.08, -60.9, -30.23], "start_source": "hold", "cmd_gap_deg": 0.88, "hold_lead_deg": 7.71, "sent": false, "why": "lead_ok", "hold_remaining_deg": 7.71, "reached": null, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 131, "t": "2026-11-09T13:03:03.658", "t_unix": 1794196983.659, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 30, "hold_n": 5, "held_sec": 0.815, "accepted": true, "measured_before": [-58.97, 54.58, 9.31, 0.08, -60.9, -30.23], "start_source": "hold", "cmd_gap_deg": 0.88, "hold_lead_deg": 7.71, "command": [-58.87, 46.87, 9.05, -0.26, -60.02, -30.23], "hold_resend": true, "sent": true, "reached": null, "no_check": true, "t_send": 1794196983.7192042, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 132, "t": "2026-11-09T13:03:03.776", "t_unix": 1794196983.777, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 30, "hold_n": 6, "held_sec": 0.933, "accepted": true, "measured_before": [-58.97, 49.3, 7.03, 0.61, -60.9, -30.23], "start_source": "hold", "cmd_gap_deg": 2.02, "hold_lead_deg": 2.43, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [-58.87, 34.3, 9.05, -0.26, -60.02, -30.23], "sent": true, "reached": null, "no_check": true, "t_send": 1794196983.798432, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 133, "t": "2026-11-09T13:03:03.878", "t_unix": 1794196983.878, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 30, "hold_n": 7, "held_sec": 1.035, "accepted": true, "measured_before": [-58.88, 49.21, 7.03, 0.61, -60.9, -30.23], "start_source": "hold", "cmd_gap_deg": 2.02, "hold_lead_deg": 14.91, "sent": false, "why": "lead_ok", "hold_remaining_deg": 14.91, "reached": null, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 134, "t": "2026-11-09T13:03:03.992", "t_unix": 1794196983.993, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 1, "step_deg": 1.0, "execute": true, "joint": 1, "delta": -15.0, "hold_id": 30, "hold_n": 8, "held_sec": 1.149, "accepted": true, "measured_before": [-58.97, 45.87, 7.03, 0.7, -60.9, -30.23], "start_source": "hold", "cmd_gap_deg": 2.02, "hold_lead_deg": 11.57, "sent": false, "why": "lead_ok", "hold_remaining_deg": 11.57, "reached": null, "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 135, "t": "2026-11-09T13:03:04.096", "t_unix": 1794196984.097, "button": null, "button_name": null, "kind": "halt", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 30, "halt_joint": 1, "measured_at_request": [-58.97, 45.87, 7.03, 0.7, -60.9, -30.23], "t_halt": 1794196984.0974238, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-58.71, 41.74, 7.2, 0.7, -59.67, -30.23], "moved_after_request_deg": [0.26, -4.13, 0.17, 0.0, 1.23, 0.0], "grip_state": "closed", "stopped": false, "stop_reason": null}
{"seq": 136, "t": "2026-11-09T13:03:08.994", "t_unix": 1794196988.994, "button": 1, "button_name": "circle", "kind": "grip_open", "selected_joint": 1, "step_deg": 1.0, "execute": true, "grip_cmd": 0, "accepted": true, "measured_before": null, "sent": true, "reached": null, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 137, "t": "2026-11-09T13:03:15.446", "t_unix": 1794196995.447, "button": 5, "button_name": "home", "kind": "home", "selected_joint": 1, "step_deg": 1.0, "execute": true, "held_sec": 1.005, "accepted": true, "measured_before": [-58.71, 42.09, 7.91, 0.87, -60.2, -30.23], "command": [0.0, 0.0, 0.0, 0.0, 0.0, -30.0], "range_check": "skipped_for_home", "sent": true, "timeout_sec": 11.03, "t_send": 1794196995.485761, "measured_before_send": [-58.71, 42.09, 7.91, 0.87, -60.2, -30.23], "resends": [], "reached": true, "reached_angles": [-0.35, 1.49, 2.1, -0.08, 0.61, -30.32], "reach_err": 2.1, "elapsed_sec": 2.12, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 139, "t": "2026-11-09T13:03:21.491", "t_unix": 1794197001.492, "button": 5, "button_name": "home", "kind": "home", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": false, "reason": "busy", "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 140, "t": "2026-11-09T13:03:24.433", "t_unix": 1794197004.434, "button": 5, "button_name": "home", "kind": "home", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": false, "reason": "busy", "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 141, "t": "2026-11-09T13:03:25.505", "t_unix": 1794197005.506, "button": 5, "button_name": "home", "kind": "home", "selected_joint": 1, "step_deg": 1.0, "execute": true, "accepted": false, "reason": "busy", "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 142, "t": "2026-11-09T13:03:26.588", "t_unix": 1794197006.589, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 2, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 143, "t": "2026-11-09T13:03:27.047", "t_unix": 1794197007.047, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 3, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 144, "t": "2026-11-09T13:03:27.465", "t_unix": 1794197007.465, "button": 3, "button_name": "triangle", "kind": "select_joint", "selected_joint": 4, "step_deg": 1.0, "execute": true, "accepted": true, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 138, "t": "2026-11-09T13:03:20.405", "t_unix": 1794197000.406, "button": 5, "button_name": "home", "kind": "home", "selected_joint": 1, "step_deg": 1.0, "execute": true, "held_sec": 1.0, "accepted": true, "measured_before": [-0.43, 1.49, 2.1, -0.08, 55.72, -30.32], "command": [0.0, 0.0, 0.0, 0.0, 0.0, -30.0], "range_check": "skipped_for_home", "sent": true, "timeout_sec": 10.38, "t_send": 1794197000.436464, "measured_before_send": [-0.43, 1.49, 2.1, -0.08, 55.89, -30.32], "resends": [], "reached": false, "reached_angles": [-0.43, 1.49, 2.1, -0.17, 53.34, -30.23], "reach_err": 53.34, "elapsed_sec": 10.41, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 145, "t": "2026-11-09T13:03:30.929", "t_unix": 1794197010.929, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -1.0, "hold_id": 31, "hold_n": 0, "accepted": true, "measured_before": [-0.43, 1.49, 2.1, -0.17, 53.34, -30.23], "start_source": "measured", "others_from_measured": [], "cmd_gap_deg": 53.34, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [0.0, 0.0, 0.0, 0.0, 52.34, -30.0], "sent": true, "timeout_sec": 8.0, "t_send": 1794197010.96034, "measured_before_send": [-0.43, 1.49, 2.1, -0.17, 53.34, -30.23], "resends": [], "reached": true, "reached_angles": [-0.43, 1.49, 2.1, -0.17, 51.94, -30.23], "reach_err": 2.1, "elapsed_sec": 1.42, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 146, "t": "2026-11-09T13:03:32.703", "t_unix": 1794197012.703, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 32, "hold_n": 1, "held_sec": 0.406, "accepted": true, "measured_before": [-0.43, 1.49, 2.1, -0.17, 51.94, -30.23], "start_source": "hold", "cmd_gap_deg": 2.1, "hold_lead_deg": 0.4, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [0.0, 0.0, 0.0, 0.0, 36.94, -30.0], "sent": true, "reached": null, "no_check": true, "t_send": 1794197012.724732, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 147, "t": "2026-11-09T13:03:32.889", "t_unix": 1794197012.89, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 32, "hold_n": 2, "held_sec": 0.592, "accepted": true, "measured_before": [-0.43, 1.49, 2.1, -0.17, 45.17, -30.23], "start_source": "hold", "cmd_gap_deg": 2.1, "hold_lead_deg": 8.23, "sent": false, "why": "lead_ok", "hold_remaining_deg": 8.23, "reached": null, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 148, "t": "2026-11-09T13:03:33.077", "t_unix": 1794197013.078, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 32, "hold_n": 3, "held_sec": 0.78, "accepted": true, "measured_before": [-0.43, 1.49, 2.1, -0.17, 43.5, -30.23], "start_source": "hold", "cmd_gap_deg": 2.1, "hold_lead_deg": 6.56, "sent": false, "why": "lead_ok", "hold_remaining_deg": 6.56, "reached": null, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 149, "t": "2026-11-09T13:03:33.179", "t_unix": 1794197013.179, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 32, "hold_n": 4, "held_sec": 0.882, "accepted": true, "measured_before": [-0.43, 1.49, 2.1, -0.17, 39.81, -30.23], "start_source": "hold", "cmd_gap_deg": 2.1, "hold_lead_deg": 2.87, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [0.0, 0.0, 0.0, 0.0, 24.81, -30.0], "sent": true, "reached": null, "no_check": true, "t_send": 1794197013.2072809, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 150, "t": "2026-11-09T13:03:33.364", "t_unix": 1794197013.365, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 32, "hold_n": 5, "held_sec": 1.068, "accepted": true, "measured_before": [-0.43, 1.49, 2.1, -0.17, 37.79, -30.23], "start_source": "hold", "cmd_gap_deg": 2.1, "hold_lead_deg": 12.98, "sent": false, "why": "lead_ok", "hold_remaining_deg": 12.98, "reached": null, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 151, "t": "2026-11-09T13:03:33.465", "t_unix": 1794197013.465, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 32, "hold_n": 6, "held_sec": 1.168, "accepted": true, "measured_before": [-0.43, 1.49, 2.1, -0.17, 37.79, -30.23], "start_source": "hold", "cmd_gap_deg": 2.1, "hold_lead_deg": 12.98, "sent": false, "why": "lead_ok", "hold_remaining_deg": 12.98, "reached": null, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 152, "t": "2026-11-09T13:03:33.567", "t_unix": 1794197013.568, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 32, "hold_n": 7, "held_sec": 1.271, "accepted": true, "measured_before": [-0.43, 1.49, 2.1, -0.17, 37.79, -30.23], "start_source": "hold", "cmd_gap_deg": 2.1, "hold_lead_deg": 12.98, "sent": false, "why": "lead_ok", "hold_remaining_deg": 12.98, "reached": null, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 153, "t": "2026-11-09T13:03:33.671", "t_unix": 1794197013.671, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 32, "hold_n": 8, "held_sec": 1.374, "accepted": true, "measured_before": [-0.43, 1.49, 2.1, -0.17, 37.79, -30.23], "start_source": "hold", "cmd_gap_deg": 2.1, "hold_lead_deg": 12.98, "command": [0.0, 0.0, 0.0, 0.0, 24.81, -30.0], "hold_resend": true, "sent": true, "reached": null, "no_check": true, "t_send": 1794197013.7304928, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 154, "t": "2026-11-09T13:03:33.790", "t_unix": 1794197013.79, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 32, "hold_n": 9, "held_sec": 1.493, "accepted": true, "measured_before": [-0.43, 1.49, 2.1, -0.17, 26.63, -30.23], "start_source": "hold", "cmd_gap_deg": 2.1, "hold_lead_deg": 1.82, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [0.0, 0.0, 0.0, 0.0, 11.63, -30.0], "sent": true, "reached": null, "no_check": true, "t_send": 1794197013.810026, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 155, "t": "2026-11-09T13:03:33.892", "t_unix": 1794197013.892, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 32, "hold_n": 10, "held_sec": 1.595, "accepted": true, "measured_before": [-0.43, 1.49, 2.1, -0.17, 22.67, -30.23], "start_source": "hold", "cmd_gap_deg": 2.1, "hold_lead_deg": 11.04, "sent": false, "why": "lead_ok", "hold_remaining_deg": 11.04, "reached": null, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 156, "t": "2026-11-09T13:03:34.060", "t_unix": 1794197014.061, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 32, "hold_n": 11, "held_sec": 1.764, "accepted": true, "measured_before": [-0.43, 1.49, 2.1, -0.17, 21.0, -30.23], "start_source": "hold", "cmd_gap_deg": 2.1, "hold_lead_deg": 9.37, "sent": false, "why": "lead_ok", "hold_remaining_deg": 9.37, "reached": null, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 157, "t": "2026-11-09T13:03:34.161", "t_unix": 1794197014.162, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 32, "hold_n": 12, "held_sec": 1.865, "accepted": true, "measured_before": [-0.43, 1.49, 2.1, -0.17, 16.52, -30.23], "start_source": "hold", "cmd_gap_deg": 2.1, "hold_lead_deg": 4.89, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [0.0, 0.0, 0.0, 0.0, 1.52, -30.0], "sent": true, "reached": null, "no_check": true, "t_send": 1794197014.194612, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 158, "t": "2026-11-09T13:03:34.264", "t_unix": 1794197014.264, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 32, "hold_n": 13, "held_sec": 1.967, "accepted": true, "measured_before": [-0.43, 1.49, 2.1, -0.17, 13.62, -30.23], "start_source": "hold", "cmd_gap_deg": 2.1, "hold_lead_deg": 12.1, "sent": false, "why": "lead_ok", "hold_remaining_deg": 12.1, "reached": null, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 159, "t": "2026-11-09T13:03:34.364", "t_unix": 1794197014.365, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 32, "hold_n": 14, "held_sec": 2.067, "accepted": true, "measured_before": [-0.43, 1.49, 2.1, -0.17, 13.62, -30.23], "start_source": "hold", "cmd_gap_deg": 2.1, "hold_lead_deg": 12.1, "sent": false, "why": "lead_ok", "hold_remaining_deg": 12.1, "reached": null, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 160, "t": "2026-11-09T13:03:34.466", "t_unix": 1794197014.466, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 32, "hold_n": 15, "held_sec": 2.169, "accepted": true, "measured_before": [-0.43, 1.49, 2.1, -0.17, 13.62, -30.23], "start_source": "hold", "cmd_gap_deg": 2.1, "hold_lead_deg": 12.1, "sent": false, "why": "lead_ok", "hold_remaining_deg": 12.1, "reached": null, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 161, "t": "2026-11-09T13:03:34.568", "t_unix": 1794197014.569, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 32, "hold_n": 16, "held_sec": 2.271, "accepted": true, "measured_before": [-0.43, 1.49, 2.1, -0.17, 13.62, -30.23], "start_source": "hold", "cmd_gap_deg": 2.1, "hold_lead_deg": 12.1, "command": [0.0, 0.0, 0.0, 0.0, 1.52, -30.0], "hold_resend": true, "sent": true, "reached": null, "no_check": true, "t_send": 1794197014.590187, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 162, "t": "2026-11-09T13:03:34.670", "t_unix": 1794197014.67, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 32, "hold_n": 17, "held_sec": 2.373, "accepted": true, "measured_before": [-0.43, 1.49, 2.1, -0.17, 13.62, -30.23], "start_source": "hold", "cmd_gap_deg": 2.1, "hold_lead_deg": 12.1, "sent": false, "why": "lead_ok", "hold_remaining_deg": 12.1, "reached": null, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 163, "t": "2026-11-09T13:03:34.771", "t_unix": 1794197014.772, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 32, "hold_n": 18, "held_sec": 2.475, "accepted": true, "measured_before": [-0.43, 1.49, 2.1, -0.17, 5.71, -30.23], "start_source": "hold", "cmd_gap_deg": 2.1, "hold_lead_deg": 4.19, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [0.0, 0.0, 0.0, 0.0, -9.29, -30.0], "sent": true, "reached": null, "no_check": true, "t_send": 1794197014.9326751, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 164, "t": "2026-11-09T13:03:34.992", "t_unix": 1794197014.993, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 32, "hold_n": 19, "held_sec": 2.696, "accepted": true, "measured_before": [-0.43, 1.49, 2.1, -0.17, 3.6, -30.23], "start_source": "hold", "cmd_gap_deg": 2.1, "hold_lead_deg": 12.89, "sent": false, "why": "lead_ok", "hold_remaining_deg": 12.89, "reached": null, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 165, "t": "2026-11-09T13:03:35.095", "t_unix": 1794197015.095, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 32, "hold_n": 20, "held_sec": 2.798, "accepted": true, "measured_before": [-0.43, 1.49, 2.1, -0.17, 3.33, -30.23], "start_source": "hold", "cmd_gap_deg": 2.1, "hold_lead_deg": 12.62, "sent": false, "why": "lead_ok", "hold_remaining_deg": 12.62, "reached": null, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 166, "t": "2026-11-09T13:03:35.199", "t_unix": 1794197015.199, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 32, "hold_n": 21, "held_sec": 2.902, "accepted": true, "measured_before": [-0.43, 1.49, 2.1, -0.17, 0.87, -30.23], "start_source": "hold", "cmd_gap_deg": 2.1, "hold_lead_deg": 10.16, "sent": false, "why": "lead_ok", "hold_remaining_deg": 10.16, "reached": null, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 167, "t": "2026-11-09T13:03:35.299", "t_unix": 1794197015.3, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 32, "hold_n": 22, "held_sec": 3.003, "accepted": true, "measured_before": [-0.43, 1.49, 2.1, -0.17, -3.86, -30.23], "start_source": "hold", "cmd_gap_deg": 2.1, "hold_lead_deg": 5.43, "sent": false, "why": "lead_ok", "hold_remaining_deg": 5.43, "reached": null, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 168, "t": "2026-11-09T13:03:35.402", "t_unix": 1794197015.402, "button": 11, "button_name": "dpad_up", "kind": "move", "selected_joint": 4, "step_deg": 1.0, "execute": true, "joint": 4, "delta": -15.0, "hold_id": 32, "hold_n": 23, "held_sec": 3.105, "accepted": true, "released_during_job": true, "measured_before": [-0.43, 1.49, 2.1, -0.17, -7.11, -30.23], "start_source": "hold", "cmd_gap_deg": 2.1, "hold_lead_deg": 2.18, "clip": [], "refused": [], "limit_ja": "", "limit_ascii": "", "command": [0.0, 0.0, 0.0, 0.0, -22.11, -30.0], "sent": true, "reached": null, "no_check": true, "t_send": 1794197015.430717, "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 169, "t": "2026-11-09T13:03:35.555", "t_unix": 1794197015.555, "button": null, "button_name": null, "kind": "halt", "selected_joint": 4, "step_deg": 1.0, "execute": true, "accepted": true, "halt_reason": "release", "hold_id": 32, "halt_joint": 4, "measured_at_request": [-0.43, 1.49, 2.1, -0.17, -3.86, -30.23], "t_halt": 1794197015.555469, "halt": "stop", "halt_result": {"jog_stop": null, "stop": null}, "measured_after_halt": [-0.43, 2.37, 2.9, -0.17, -6.94, -30.23], "moved_after_request_deg": [0.0, 0.88, 0.8, 0.0, -3.08, 0.0], "grip_state": "open", "stopped": false, "stop_reason": null}
{"seq": 170, "t": "2026-11-09T13:03:37.656", "t_unix": 1794197017.656, "button": 5, "button_name": "home", "kind": "home", "selected_joint": 4, "step_deg": 1.0, "execute": true, "held_sec": 1.015, "accepted": true, "measured_before": [-0.43, 2.54, 3.07, -0.17, -6.76, -30.23], "command": [0.0, 0.0, 0.0, 0.0, 0.0, -30.0], "range_check": "skipped_for_home", "sent": true, "timeout_sec": 8.0, "t_send": 1794197017.696251, "measured_before_send": [-0.43, 2.54, 3.07, -0.17, -6.76, -30.23], "resends": [], "reached": true, "reached_angles": [-0.43, 1.49, 1.84, -0.17, -2.9, -30.23], "reach_err": 2.9, "elapsed_sec": 0.37, "grip_state": "open", "stopped": false, "stop_reason": null}
```


## 位置3と位置4の29本の表（lab/Log26/runs_table.csv から）

12:00 以降に撮った本を、教えた記録の版ごとにまとめると次のとおりです。

| 位置 | 教えた記録 | 本数 | 使う | 浅い | 爪が乗った | 10本にそろえるため外した |
|---|---|---|---|---|---|---|
| 3 | 元の記録（drag_v2_20221013_231249） | 9 | 0 | 9 | 0 | 0 |
| 3 | 教え直し（drag_v2_20261109_123000） | 12 | 8 | 2 | 1 | 1 |
| 4 | 元の記録（drag_v2_20221013_232345） | 2 | 0 | 0 | 2 | 0 |
| 4 | ブロックの上だけ差し替え（drag_v2_20261109_130000） | 1 | 0 | 0 | 1 | 0 |
| 4 | 教え直し（drag_v2_20261109_130300） | 5 | 5 | 0 | 0 | 0 |

### runs_table.csv（全量）

```csv
run,position,teach,teach_version,pick,place,before_px,after_px,after_gap_px,hand_suspect,grip_max,grip_median,pick_segment_sec,pick_arrival_max_delta_deg,j0_arrived,j1_arrived,j2_arrived,j4_arrived,use,reason
run_0001_20261109_120818,3,drag_v2_20221013_231249.json,元の記録,yes,yes,67.0,42.5,99.2,False,852,832,1.088,1.93,-27.33,63.63,14.15,-61.69,外す,浅い (閉じて 1.0 秒後 42.5px > 24px)
run_0001_20261109_121128,3,drag_v2_20221013_231249.json,元の記録,yes,yes,54.9,32.4,99.4,False,1023,777,1.076,1.85,-27.33,63.72,13.97,-61.61,外す,浅い (閉じて 1.0 秒後 32.4px > 24px)
run_0001_20261109_121224,3,drag_v2_20221013_231249.json,元の記録,yes,yes,65.4,39.3,99.2,False,832,802,1.071,1.93,-28.03,63.72,13.97,-61.69,外す,浅い (閉じて 1.0 秒後 39.3px > 24px)
run_0001_20261109_121320,3,drag_v2_20221013_231249.json,元の記録,yes,yes,56.4,35.9,99.4,False,830,801,1.064,1.85,-27.59,63.72,13.97,-61.61,外す,浅い (閉じて 1.0 秒後 35.9px > 24px)
run_0001_20261109_121416,3,drag_v2_20221013_231249.json,元の記録,yes,yes,51.5,28.7,99.3,False,1022,773,1.067,1.85,-27.59,63.72,13.97,-61.61,外す,浅い (閉じて 1.0 秒後 28.7px > 24px)
run_0001_20261109_121511,3,drag_v2_20221013_231249.json,元の記録,yes,yes,61.3,40.4,99.0,False,836,809,1.097,1.85,-27.33,63.72,13.97,-61.61,外す,浅い (閉じて 1.0 秒後 40.4px > 24px)
run_0001_20261109_121605,3,drag_v2_20221013_231249.json,元の記録,yes,yes,61.3,39.1,99.2,False,815,789,1.067,1.93,-27.59,63.72,14.06,-61.69,外す,浅い (閉じて 1.0 秒後 39.1px > 24px)
run_0001_20261109_121659,3,drag_v2_20221013_231249.json,元の記録,yes,yes,65.2,47.7,98.9,False,734,718,1.205,1.85,-27.59,63.63,14.06,-61.61,外す,浅い (閉じて 1.0 秒後 47.7px > 24px)
run_0001_20261109_121815,3,drag_v2_20221013_231249.json,元の記録,yes,yes,57.6,32.0,99.1,False,1023,762,1.07,1.85,-27.59,63.72,13.97,-61.61,外す,浅い (閉じて 1.0 秒後 32.0px > 24px)
run_0001_20261109_123655,3,drag_v2_20261109_123000.json,教え直し 12:30,yes,yes,53.9,25.9,100.0,False,872,863,1.069,0.88,-25.75,69.08,9.05,-66.26,外す,浅い (閉じて 1.0 秒後 25.9px > 24px)
run_0001_20261109_123756,3,drag_v2_20261109_123000.json,教え直し 12:30,yes,yes,44.5,21.8,99.9,False,859,850,1.068,0.88,-25.48,69.08,9.05,-66.26,外す,"位置3 を 10 本にそろえるため, いちばん浅い本を外した (依頼131)"
run_0001_20261109_123848,3,drag_v2_20261109_123000.json,教え直し 12:30,yes,yes,41.2,9.5,99.7,False,823,813,1.077,1.23,-25.83,69.43,9.05,-67.58,使う,
run_0001_20261109_123940,3,drag_v2_20261109_123000.json,教え直し 12:30,yes,yes,51.8,25.6,99.7,False,862,851,1.066,0.88,-25.57,69.08,9.05,-66.26,外す,浅い (閉じて 1.0 秒後 25.6px > 24px)
run_0001_20261109_124032,3,drag_v2_20261109_123000.json,教え直し 12:30,yes,yes,48.6,20.4,99.6,False,851,841,1.067,0.88,-25.31,69.08,9.05,-66.26,使う,
run_0001_20261109_124117,3,drag_v2_20261109_123000.json,教え直し 12:30,yes,yes,30.3,2.7,99.8,False,814,808,1.073,1.05,-25.66,69.25,9.05,-67.58,使う,
run_0001_20261109_124207,3,drag_v2_20261109_123000.json,教え直し 12:30,yes,yes,44.4,18.1,99.8,False,851,843,1.064,0.88,-25.57,69.08,9.05,-66.26,使う,
run_0001_20261109_124256,3,drag_v2_20261109_123000.json,教え直し 12:30,yes,yes,38.7,4.5,99.8,False,817,807,1.097,0.88,-25.48,69.08,9.05,-66.26,使う,
run_0001_20261109_124438,3,drag_v2_20261109_123000.json,教え直し 12:30,yes,yes,27.2,-2.1,99.6,False,817,811,1.081,0.88,-25.4,69.08,9.05,-66.26,使う,
run_0001_20261109_124530,3,drag_v2_20261109_123000.json,教え直し 12:30,no,no,-1.5,-38.2,73.7,False,34,14,6.568,2.72,-25.75,67.93,8.17,-69.25,外す,爪がブロックに乗った (PICK の区間 6.57 秒)
run_0001_20261109_124817,3,drag_v2_20261109_123000.json,教え直し 12:30,yes,yes,28.0,-0.6,99.7,False,820,810,1.715,1.14,-25.48,69.34,9.05,-67.23,使う,
run_0001_20261109_124920,3,drag_v2_20261109_123000.json,教え直し 12:30,yes,yes,27.7,2.2,99.5,False,813,807,1.067,1.23,-25.57,69.25,9.05,-67.76,使う,
run_0001_20261109_125209,4,drag_v2_20221013_232345.json,元の記録,no,no,9.2,-25.3,73.2,False,59,14,7.216,2.9,-61.61,61.25,13.09,-62.05,外す,爪がブロックに乗った (PICK の区間 7.22 秒)
run_0001_20261109_125607,4,drag_v2_20221013_232345.json,元の記録,no,no,11.4,3.1,97.3,False,1022,781,6.66,2.98,-61.61,61.34,13.27,-62.13,外す,爪がブロックに乗った (PICK の区間 6.66 秒)
run_0001_20261109_125825,4,drag_v2_20261109_130000.json,ブロックの上だけ差し替え 13:00,no,no,-3.5,-35.7,69.8,False,34,8,6.619,2.98,-61.61,61.17,12.74,-62.13,外す,爪がブロックに乗った (PICK の区間 6.62 秒)
run_0001_20261109_130542,4,drag_v2_20261109_130300.json,教え直し 13:03,yes,yes,38.7,5.4,98.7,False,875,854,1.086,1.23,-59.23,62.66,9.93,-55.28,使う,
run_0001_20261109_130723,4,drag_v2_20261109_130300.json,教え直し 13:03,yes,yes,35.0,3.8,98.4,False,869,850,1.067,1.14,-59.15,62.57,10.01,-55.19,使う,
run_0001_20261109_130824,4,drag_v2_20261109_130300.json,教え直し 13:03,yes,yes,36.7,1.6,98.9,False,820,806,1.659,1.14,-59.23,62.66,10.01,-55.19,使う,
run_0001_20261109_130929,4,drag_v2_20261109_130300.json,教え直し 13:03,yes,yes,41.5,10.0,98.5,False,856,843,1.08,1.14,-59.23,62.57,10.01,-55.19,使う,
run_0001_20261109_131103,4,drag_v2_20261109_130300.json,教え直し 13:03,yes,yes,33.4,3.6,98.4,False,862,841,1.066,1.23,-59.23,62.66,10.01,-55.28,使う,
```

### 表を作るコード（lab/Log26/log26_runs_table.py）

```python
#!/usr/bin/env python3
"""log26_runs_table.py — 2026-11-09 の 12:00 以降に撮った位置3・位置4 のお手本を 1 本 1 行の表 runs_table.csv にする
(LOG479・フィジカルAI研究室 Log#26).

読むだけ:
  runs/run_pick_place/run_0001_20261109_{12,13}*/run_0001_*.json   (試行 JSON: 人の y/n・区間ごとの到達)
  runs/run_pick_place/run_0001_20261109_{12,13}*/teach/*.json      (どの教えた記録で撮ったか)
  runs/run_pick_place/run_0001_20261109_{12,13}*/recording/       (grasp_depth.py・grip_current.py が読む)
書く: このファイルと同じフォルダの runs_table.csv だけ.

判定 (使う/外す) の決まり (lab/Log25/log25_runs_table.py と同じ):
  1. PICK の区間 (ブロックの上 → つかむ姿勢) が 5 秒より長くかかった本は「爪がブロックに乗った」として外す
  2. 閉じて 1.0 秒後のはみ出しが 24px を超えた本は「浅い」として外す (pi05/grasp_depth.py の線)
  3. 人の判定でつかめなかった (n) 本は外す
  4. 位置3 の元の記録 (drag_v2_20221013_231249.json) で撮った本は 9 本とも浅かった. 比べる相手として残すが学習には使わない
  5. 位置3 の 123756 は浅くはないが, 依頼131 で位置3 を 10 本にそろえるとき (その位置でいちばん浅い本) として外した

Mac で動かすとき:  cd ~/r2r2r-scripts && python3 /Volumes/KIOXIA/r2r2r-data/lab/Log26/log26_runs_table.py
(パスは R2R2R_DATA・R2R2R_SCRIPTS で変えられる)
"""
import csv, json, os, sys
from pathlib import Path

DATA = Path(os.environ.get("R2R2R_DATA", "/Volumes/KIOXIA/r2r2r-data"))
SCRIPTS = Path(os.environ.get("R2R2R_SCRIPTS", Path.home() / "r2r2r-scripts"))
sys.path.insert(0, str(SCRIPTS / "pi05"))
import grasp_depth as gd    # noqa: E402
import grip_current as gc   # noqa: E402

RUNS = DATA / "runs/run_pick_place"
HERE = Path(__file__).resolve().parent
TEACH = {
    "drag_v2_20221013_231249.json": (3, "元の記録"),
    "drag_v2_20261109_123000.json": (3, "教え直し 12:30"),
    "drag_v2_20221013_232345.json": (4, "元の記録"),
    "drag_v2_20261109_130000.json": (4, "ブロックの上だけ差し替え 13:00"),
    "drag_v2_20261109_130300.json": (4, "教え直し 13:03"),
}
SNAG_SEC = 5.0
LINE_PX = 24.0
EVEN10_DROP = {"run_0001_20261109_123756"}   # 依頼131 の pi05/excludes/deep_even10_v1.json


def main():
    rows = []
    for p in sorted(x for x in RUNS.glob("run_0001_20261109_*") if x.is_dir()):
        if p.name < "run_0001_20261109_120000":
            continue
        tf = sorted(q.name for q in (p / "teach").glob("*.json"))
        if not tf or tf[0] not in TEACH:
            continue
        pos, ver = TEACH[tf[0]]
        tj = json.load(open(p / f"{p.name}.json"))
        seg = [g for g in tj["segments"] if g.get("to_name") == "PICK"][0]
        j = tj.get("judgments") or {}
        pick = (j.get("pick") or {}).get("verdict")
        place = (j.get("place") or {}).get("verdict")
        m = gd.measure_run(p, max_protrude_px=LINE_PX)
        g = gc.summarize(p)
        sec = float(seg["segment_elapsed_sec"])
        after = m.get("after_px")
        if sec > SNAG_SEC:
            use, why = "外す", "爪がブロックに乗った (PICK の区間 %.2f 秒)" % sec
        elif pick != "yes":
            use, why = "外す", "つかめなかった (人の判定 n)"
        elif after is not None and after > LINE_PX:
            use, why = "外す", "浅い (閉じて 1.0 秒後 %.1fpx > 24px)" % after
        elif tf[0] == "drag_v2_20221013_231249.json":
            use, why = "外す", "元の記録 (浅い)"
        elif p.name in EVEN10_DROP:
            use, why = "外す", "位置3 を 10 本にそろえるため, いちばん浅い本を外した (依頼131)"
        else:
            use, why = "使う", ""
        a = seg.get("arrival_actual") or [None] * 6
        rows.append({
            "run": p.name, "position": pos, "teach": tf[0], "teach_version": ver,
            "pick": pick, "place": place,
            "before_px": m.get("before_px"), "after_px": after, "after_gap_px": m.get("after_gap_px"),
            "hand_suspect": m.get("hand_suspect"),
            "grip_max": g.get("max"), "grip_median": g.get("median"),
            "pick_segment_sec": sec, "pick_arrival_max_delta_deg": seg.get("arrival_max_delta_deg"),
            "j0_arrived": a[0], "j1_arrived": a[1], "j2_arrived": a[2], "j4_arrived": a[4],
            "use": use, "reason": why,
        })
    out = HERE / "runs_table.csv"
    with open(out, "w", newline="") as f:
        w = csv.DictWriter(f, fieldnames=list(rows[0].keys()))
        w.writeheader()
        w.writerows(rows)
    print(out, len(rows), "本")
    for r in rows:
        print(r["run"][-6:], r["position"], r["teach_version"], r["pick"], r["after_px"], r["pick_segment_sec"], r["grip_median"], r["use"], r["reason"])


if __name__ == "__main__":
    main()
```

### 記事の画像を作るコード（lab/Log26/make_images.py）

```python
#!/usr/bin/env python3
"""make_images.py — LOG479 (フィジカルAI研究室 Log#26) の記事の画像を作る. 元の記録は読むだけ.
書き出し先: 第1引数のフォルダ (既定は iCloud の フィジカルAI研究室を作る/LOG479_images/)
  LOG479_01_pos3_old_vs_new.jpg  位置3 の閉じて 1.0 秒後の上カメラ. 左: 元の記録 (120818・42.5px), 右: 教え直し (124117・2.7px)
  LOG479_03_pos3_align.jpg       位置3 の最初のコマにブロックの枠を重ねた図 (緑: 深かった本, 赤: 浅かった本)
  LOG479_04_pos4_descent.jpg     位置4 の下ろす区間の上カメラ 5 コマ × 3 段 (125825 差し替え版・193825 10/19・130542 教え直し)
  LOG479_02_measure_cable.jpg    measure の確認画像 (measure_20261109_123559.jpg) を 1280 幅に縮めたもの
"""
import bisect, csv, json, sys
from pathlib import Path
import cv2
import numpy as np

DATA = Path("/Volumes/KIOXIA/r2r2r-data")
OUT = Path(sys.argv[1]) if len(sys.argv) > 1 else Path.home() / "Library/Mobile Documents/com~apple~CloudDocs/デスクトップ/ADAPT DESIGN/じぶんの/PixelstoMotors/デジタルツイン学習R2R2R/フィジカルAI研究室を作る/LOG479_images"
if len(sys.argv) > 2:
    DATA = Path(sys.argv[2])
RUNS = DATA / "runs/run_pick_place"
OUT.mkdir(parents=True, exist_ok=True)


def frame_at(run, t):
    ts = [float(r["capture_ts"]) for r in csv.DictReader(open(RUNS / run / "recording/top_frame_log.csv"))]
    cap = cv2.VideoCapture(str(RUNS / run / "recording/top.mp4"))
    cap.set(cv2.CAP_PROP_POS_FRAMES, min(bisect.bisect_left(ts, t), len(ts) - 1))
    ok, f = cap.read()
    cap.release()
    return f


def stage_t(run, name):
    st = list(csv.DictReader(open(RUNS / run / "recording/states.csv")))
    return [float(r["ts"]) for r in st if r["event_type"] == "stage" and r["stage"] == name][0]


def label(img, text):
    cv2.rectangle(img, (0, 0), (img.shape[1], 34), (20, 20, 20), -1)
    cv2.putText(img, text, (10, 24), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (240, 240, 240), 2, cv2.LINE_AA)
    return img


# 1. 位置3: 元の記録と教え直しの, 閉じて 1.0 秒後 (grasp_depth.py が測るコマ)
sys.path.insert(0, str(Path.home() / "r2r2r-scripts/pi05"))
import grasp_depth as gd  # noqa: E402
tiles = []
for run, txt in [("run_0001_20261109_120818", "old teach  42.5px"), ("run_0001_20261109_124117", "re-taught  2.7px")]:
    m = gd.measure_run(RUNS / run)
    cap = cv2.VideoCapture(str(RUNS / run / "recording/top.mp4"))
    cap.set(cv2.CAP_PROP_POS_FRAMES, m["frame_after"])
    ok, f = cap.read()
    cap.release()
    cx, cy = m["center_px"]
    c = f[max(0, cy - 260):cy + 260, max(0, cx - 330):cx + 330].copy()
    tiles.append(label(cv2.resize(c, (660, 520)), txt))
cv2.imwrite(str(OUT / "LOG479_01_pos3_old_vs_new.jpg"), np.hstack(tiles), [cv2.IMWRITE_JPEG_QUALITY, 90])

# 2. measure の確認画像 (ケーブルを拾った回)
f = cv2.imread(str(DATA / "mecharm_calibration/teach_poses_20261109/measure_20261109_123559.jpg"))
cv2.imwrite(str(OUT / "LOG479_02_measure_cable.jpg"), cv2.resize(f, (1280, 720)), [cv2.IMWRITE_JPEG_QUALITY, 90])

# 3. 位置3 の置き場所 (最初のコマのブロックの枠)
runs = {"124117": ("deep 2.7", (0, 200, 0)), "124256": ("deep 4.5", (0, 200, 0)), "123848": ("deep 9.5", (0, 200, 0)),
        "123655": ("shallow 25.9", (0, 0, 255)), "123940": ("shallow 25.6", (0, 0, 255))}
base = None
for k, (r, (txt, col)) in enumerate(runs.items()):
    cap = cv2.VideoCapture(str(RUNS / f"run_0001_20261109_{r}/recording/top.mp4"))
    ok, f = cap.read()
    cap.release()
    if base is None:
        base = f.copy()
    hsv = cv2.cvtColor(f, cv2.COLOR_BGR2HSV)
    m = cv2.inRange(hsv, (0, 40, 80), (12, 255, 255)) | cv2.inRange(hsv, (158, 40, 80), (180, 255, 255))
    m[:500, :] = 0   # 根元とケーブルを除く
    m = cv2.morphologyEx(m, cv2.MORPH_OPEN, np.ones((5, 5), np.uint8))
    cs, _ = cv2.findContours(m, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    rect = cv2.minAreaRect(max(cs, key=cv2.contourArea))
    cv2.drawContours(base, [cv2.boxPoints(rect).astype(int)], 0, col, 2)
    cx, cy = map(int, rect[0])
    cv2.putText(base, f"{r} {txt}", (cx + 60, cy - 40 + 20 * k), cv2.FONT_HERSHEY_SIMPLEX, 0.6, col, 2)
crop = cv2.resize(base[480:900, 420:1000], None, fx=1.6, fy=1.6)
cv2.imwrite(str(OUT / "LOG479_03_pos3_align.jpg"), crop, [cv2.IMWRITE_JPEG_QUALITY, 90])

# 4. 位置4 の下ろす区間 (PICK の段階の 0.5 秒前から, 段階の終わりの 2 秒前まで)
rows = []
for run, txt in [("run_0001_20261109_125825", "125825 (13:00) "), ("run_0001_20261019_193825", "193825 (10/19) "),
                 ("run_0001_20261109_130542", "130542 (13:03) ")]:
    tp, tl = stage_t(run, "PICK"), stage_t(run, "APPROACH_PICK_LIFT")
    row = []
    for t in [tp - 0.5] + list(np.linspace(tp + 0.5, max(tp + 0.6, tl - 2.0), 4)):
        f = frame_at(run, t)
        c = cv2.resize(f[100:700, 300:1000], None, fx=0.5, fy=0.5)
        cv2.putText(c, f"{txt}{t - tp:+.1f}s", (5, 20), 0, 0.6, (0, 255, 255), 2)
        row.append(c)
    rows.append(np.hstack(row))
cv2.imwrite(str(OUT / "LOG479_04_pos4_descent.jpg"), np.vstack(rows), [cv2.IMWRITE_JPEG_QUALITY, 90])
print("ok", sorted(p.name for p in OUT.glob("LOG479_*")))
```

### サムネイルの元データを書き出したコード（lab/Log26/extract_log479_thumb.py）

```python
import json, csv, glob, os, sys
R = lambda v: round(float(v), 1)
o = json.load(open(sys.argv[1]))
# LOG479: 2026-11-09 12:00 以降の位置3・位置4 のお手本 29 本。下ろし始め（PICK の段階に入った時刻）から閉じたあと 1.5 秒までの手首 j4 を、時間（PICK の段階に入った時刻を0）で
#  [t, j4, つかんでいるか] の点にする。new = ゲームパッドで教え直した記録（下ろす間は j1 だけが動き、手首は動かない）
LOG479_NEW = {'drag_v2_20261109_123000.json', 'drag_v2_20261109_130300.json'}
def log479_runs(root='runs/run_pick_place'):
    out = {3: [], 4: []}
    for d in sorted(glob.glob(root + '/run_0001_20261109_1[23]*')):
        s = os.path.basename(d)
        tf = sorted(os.path.basename(x) for x in glob.glob(d + '/teach/*.json'))
        pos = {'drag_v2_20221013_231249.json': 3, 'drag_v2_20261109_123000.json': 3, 'drag_v2_20221013_232345.json': 4,
               'drag_v2_20261109_130000.json': 4, 'drag_v2_20261109_130300.json': 4}.get(tf[0] if tf else '')
        if pos is None:
            continue
        st = list(csv.DictReader(open(d + '/recording/states.csv')))
        t0 = [float(r['ts']) for r in st if r['event_type'] == 'stage' and r['stage'] == 'PICK'][0]
        tc = [float(r['ts']) for r in st if r['event_type'] == 'gripper_cmd' and r['gripper_state'] == '1'][0]
        pts = [[round(float(r['ts']) - t0, 2), R(r['j4']), 1 if float(r['ts']) >= tc else 0]
               for r in st if r['event_type'] == 'actual' and t0 <= float(r['ts']) <= tc + 1.5]
        out[pos].append({'run': s, 'snag': tf[0] in LOG479_NEW, 'p': pts})
    return out
o['LOG479'] = log479_runs()
json.dump(o, open(sys.argv[1], 'w'), separators=(',', ':'))
print({k: len(v) for k, v in o['LOG479'].items()})
```


## 依頼128〜130：教え直した記録を、本数を数える表に足した

位置ごとの本数は、pi05/count_by_position.py が試行フォルダの teach/ にある教えた記録のファイル名で決めます。教え直した記録のファイル名を表（TEACH_FILES）に足さないと、新しい本が「分からない」に数えられます。位置1・3（依頼128）、位置4の13:00 の版（依頼129）、位置4の教え直し（依頼130）を、Claude Code に順に足してもらいました。元の記録の行は、前に撮った本の数え方が変わらないように残しています。

### count_by_position.py の変わったところ（df54374 → 5ae9f10）

```diff
diff --git a/pi05/count_by_position.py b/pi05/count_by_position.py
index 08c9299..6513877 100644
--- a/pi05/count_by_position.py
+++ b/pi05/count_by_position.py
@@ -64,9 +64,13 @@ DEFAULT_TARGET = 10
 # LOG352 の README の表 (runs/experiments/record_teach_demo/20261019_LOG352/README.md)
 TEACH_FILES = {
     "drag_v2_20221013_144348.json": 1,
+    "drag_v2_20261109_094222.json": 1,     # 位置 1 を教え直した記録 (DEEP_DEMOS 2-1・LOG463)
     "drag_v2_20221013_230205.json": 2,
     "drag_v2_20221013_231249.json": 3,
+    "drag_v2_20261109_123000.json": 3,     # 位置 3 を教え直した記録 (DEEP_DEMOS 2-1・2026-11-09)
     "drag_v2_20221013_232345.json": 4,
+    "drag_v2_20261109_130000.json": 4,     # 位置 4 のブロックの上を差し替えた記録 (2026-11-09)
+    "drag_v2_20261109_130300.json": 4,     # 位置 4 をゲームパッドで教え直した記録 (DEEP_DEMOS 2-1・2026-11-09)
     "drag_v2_20221013_233323.json": 5,
 }
 # 教えた位置のブロックの中心 (マットの上の mm). 決め方は頭の説明
```

### 依頼128〜131 の commit の一覧

```text
8d9a4de 位置 1 (drag_v2_20261109_094222.json・LOG463) と位置 3 (drag_v2_20261109_123000.json) を教え直した記録を count_by_position.py の TEACH_FILES に足す. 同じ位置の 2 つのファイルが teach/ にあっても位置が 1 つになることのテストを足す (同じ位置が 2 つになったので既存テストの一時フォルダ名をファイル名で分ける). 2026-11-09 の 48 本で分からない 0 (依頼 128)

 pi05/count_by_position.py      |  2 ++
 pi05/test_count_by_position.py | 18 +++++++++++++++++-
 2 files changed, 19 insertions(+), 1 deletion(-)
bac9ab7 位置 4 のブロックの上を差し替えた記録 (drag_v2_20261109_130000.json・make_teach_pos4_20261109.py) を count_by_position.py の TEACH_FILES に足す. 元の記録と両方が teach/ にあっても位置 4 になることを test_same_position_two_files に足す. 2026-11-09 の 50 本で分からない 0 (依頼 129)

 pi05/count_by_position.py      | 1 +
 pi05/test_count_by_position.py | 5 +++--
 2 files changed, 4 insertions(+), 2 deletions(-)
5ae9f10 位置 4 をゲームパッドで教え直した記録 (drag_v2_20261109_130300.json・make_teach_pos4_v2_20261109.py) を count_by_position.py の TEACH_FILES に 130000 の次に足す (130000 は 125825 の数え方を変えないため残す). 元の記録・130000 のどちらと teach/ にあっても位置 4 になることを test_pos4_gamepad_file に足す (依頼 130)

 pi05/count_by_position.py      |  1 +
 pi05/test_count_by_position.py | 11 +++++++++++
 2 files changed, 12 insertions(+)
50f71f3 位置ごとの本数を 10 本にそろえるために外す 2 本 (位置 3 の run_0001_20261109_123756 21.8px・位置 5 の pi05_20261101_190854 21.4px. 閉じて 1.0 秒後のはみ出しがその位置でいちばん大きい本) を pi05/excludes/deep_even10_v1.json に理由と値と一緒に置く. 今の deep 20 本と 2026-11-09 の深いお手本 31 本 (mecharm_redblock_box_teach_pos1to4_deep_v1) から mecharm_redblock_box_deep_even10_v1 (50 本・位置 1〜5 が各 10 本) を作るのに使った (依頼 131)

 pi05/excludes/deep_even10_v1.json | 66 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)
```

### 依頼128 の依頼文（依頼箱/済み/20261109_128_位置1を教え直した記録をTEACH_FILESに足す.md）

```markdown
---
作業フォルダ: /Users/shimazueiichi/r2r2r-scripts
上限時間: 30
---
# 依頼128：位置1と位置3を教え直した記録を count_by_position.py の TEACH_FILES に足す

LOG463（2026-11-09）で位置1のつかむ姿勢をゲームパッドで教え直し、新しい教えた記録 drag_v2_20261109_094222.json（/Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/）で位置1を10本撮った。
pi05/DEEP_DEMOS.md の 2-1 の 5（エイイチの決め 2026-11-08：教え直したら足す）のとおり、TEACH_FILES に位置1として1行足す。
同じ日の 12:30 に位置3も同じ形で教え直した（drag_v2_20261109_123000.json・同じフォルダ・作ったコードは make_teach_pos3_20261109.py）。これも位置3として1行足す。足さないと今日の位置1の本が「分からない」に数えられる。
実機は動かさない。エイイチは見ていない。

## やること
1. pi05/count_by_position.py の TEACH_FILES に `"drag_v2_20261109_094222.json": 1,     # 位置 1 を教え直した記録 (DEEP_DEMOS 2-1・LOG463)` を、`"drag_v2_20221013_144348.json": 1,` の次の行に足す。`"drag_v2_20261109_123000.json": 3,     # 位置 3 を教え直した記録 (DEEP_DEMOS 2-1・2026-11-09)` を `"drag_v2_20221013_231249.json": 3,` の次の行に足す。元の行は消さない。ほかは変えない
2. teach_position() が同じ位置を指す2つのファイルを正しく扱うこと（集合なので1つになる）を、pi05/test_count_by_position.py に1件足して確かめ、テストを全部通す
3. 読むだけの確かめ：2026-11-09 の run（runs/run_pick_place/run_0001_20261109_*）の teach/ の中のファイル名を一覧し、count_by_position の teach_position() で位置を出す。位置ごとの本数と「分からない」の数を報告に（11:00 までの本は lab/Log25/runs_table.csv の位置と合うか。12:00 以降の本は teach/ のファイル名どおりか）
4. 変えた2ファイルだけを指定して git add・commit（git add . は使わない）

## 報告
claude_code_reports/20261109_128.txt に：git diff、テストの結果、3 の表（run・teach のファイル・出た位置・runs_table.csv の位置）、commit の番号。
**報告の最後の1行は必ず次のどれか**：「判定：合格」／「判定：止めた（決めてほしいことあり）」／「判定：失敗」
```

### 依頼128 の報告（r2r2r-scripts/claude_code_reports/20261109_128.txt）

```text
依頼128 報告（2026-11-09）

■ やったこと
1. pi05/count_by_position.py の TEACH_FILES に 2 行を足した（位置 1: drag_v2_20261109_094222.json は 144348 の次、位置 3: drag_v2_20261109_123000.json は 231249 の次。元の行は残した）
2. pi05/test_count_by_position.py に test_same_position_two_files を 1 件足した（元の記録と教え直した記録が teach/ に両方あっても位置 1・3 になる。位置が違う 2 つなら「分からない」のまま）
   補足: 既存の test_teach_file_mapping は一時フォルダ名が t{位置} だったため、同じ位置が 2 つになると同じフォルダを 2 回作って落ちる。フォルダ名をファイル名で分ける 1 行だけ直した（確かめる中身は同じ）
3. 2026-11-09 の run を読むだけで確かめた（KIOXIA は書いていない。実機は動かしていない）
4. 2 ファイルを指定して git add・commit

■ git diff
diff --git a/pi05/count_by_position.py b/pi05/count_by_position.py
index 08c9299..488c828 100644
--- a/pi05/count_by_position.py
+++ b/pi05/count_by_position.py
@@ -64,8 +64,10 @@ DEFAULT_TARGET = 10
 # LOG352 の README の表 (runs/experiments/record_teach_demo/20261019_LOG352/README.md)
 TEACH_FILES = {
     "drag_v2_20221013_144348.json": 1,
+    "drag_v2_20261109_094222.json": 1,     # 位置 1 を教え直した記録 (DEEP_DEMOS 2-1・LOG463)
     "drag_v2_20221013_230205.json": 2,
     "drag_v2_20221013_231249.json": 3,
+    "drag_v2_20261109_123000.json": 3,     # 位置 3 を教え直した記録 (DEEP_DEMOS 2-1・2026-11-09)
     "drag_v2_20221013_232345.json": 4,
     "drag_v2_20221013_233323.json": 5,
 }
diff --git a/pi05/test_count_by_position.py b/pi05/test_count_by_position.py
index 852e35b..e7dce75 100644
--- a/pi05/test_count_by_position.py
+++ b/pi05/test_count_by_position.py
@@ -89,7 +89,7 @@ class TestPosition(unittest.TestCase):
 
     def test_teach_file_mapping(self):
         for f, pos in cbp.TEACH_FILES.items():
-            d = self.root / f"t{pos}"
+            d = self.root / f"t{pos}_{Path(f).stem}"   # 同じ位置のファイルが 2 つあるので名前で分ける
             write_teach_run(d, f)
             self.assertEqual(cbp.teach_position(d)[0], pos)
         write_teach_run(self.root / "none", None)
@@ -98,6 +98,22 @@ class TestPosition(unittest.TestCase):
         self.assertEqual(cbp.teach_position(self.root / "other")[0], cbp.UNKNOWN)
         self.assertEqual(cbp.teach_position(self.root / "missing")[0], cbp.UNKNOWN)
 
+    def test_same_position_two_files(self):
+        # 位置 1・3 は教え直した記録と元の記録の 2 つ. 両方が teach/ にあっても集合で 1 つになり位置 1・3
+        for pos, (old, new) in {1: ("drag_v2_20221013_144348.json", "drag_v2_20261109_094222.json"),
+                                3: ("drag_v2_20221013_231249.json", "drag_v2_20261109_123000.json")}.items():
+            self.assertEqual(cbp.TEACH_FILES[old], pos)
+            self.assertEqual(cbp.TEACH_FILES[new], pos)
+            d = self.root / f"both{pos}"
+            write_teach_run(d, old)
+            (d / "teach" / new).write_text("{}")
+            self.assertEqual(cbp.teach_position(d), (pos, f"teach/{old}"))
+        # 違う位置の 2 つなら「分からない」のまま
+        d = self.root / "mixed"
+        write_teach_run(d, "drag_v2_20261109_094222.json")
+        (d / "teach" / "drag_v2_20261109_123000.json").write_text("{}")
+        self.assertEqual(cbp.teach_position(d)[0], cbp.UNKNOWN)
+
     def test_nearest_and_line(self):
         for pos, mm in cbp.TEACH_REF_MM.items():
             self.assertEqual(cbp.nearest_position(mm)[0], pos)

■ テストの結果（python3 pi05/test_count_by_position.py -v）
test_count_merged (__main__.TestCount.test_count_merged) ... ok
test_merge_readme_table_and_same_data (__main__.TestCount.test_merge_readme_table_and_same_data) ... ok
test_merge_survives_count_error (__main__.TestCount.test_merge_survives_count_error) ... ok
test_block_from_video (__main__.TestPosition.test_block_from_video) ... ok
test_block_not_found (__main__.TestPosition.test_block_not_found) ... ok
test_nearest_and_line (__main__.TestPosition.test_nearest_and_line) ... ok
test_same_position_two_files (__main__.TestPosition.test_same_position_two_files) ... ok
test_teach_file_mapping (__main__.TestPosition.test_teach_file_mapping) ... ok

----------------------------------------------------------------------
Ran 8 tests in 1.358s

OK

■ 3 の表（run | teach/ のファイル | 出た位置 | runs_table.csv の位置）
run_0001_20261109_093045 | drag_v2_20221013_144348.json | 1 | 1
run_0001_20261109_094839 | drag_v2_20261109_094222.json | 1 | 1
run_0001_20261109_095308 | drag_v2_20261109_094222.json | 1 | 1
run_0001_20261109_095452 | drag_v2_20261109_094222.json | 1 | 1
run_0001_20261109_095630 | drag_v2_20261109_094222.json | 1 | 1
run_0001_20261109_095810 | drag_v2_20261109_094222.json | 1 | 1
run_0001_20261109_095948 | drag_v2_20261109_094222.json | 1 | 1
run_0001_20261109_100126 | drag_v2_20261109_094222.json | 1 | 1
run_0001_20261109_100307 | drag_v2_20261109_094222.json | 1 | 1
run_0001_20261109_100444 | drag_v2_20261109_094222.json | 1 | 1
run_0001_20261109_100716 | drag_v2_20261109_094222.json | 1 | 1
run_0001_20261109_100852 | drag_v2_20261109_094222.json | 1 | 1
run_0001_20261109_101023 | drag_v2_20261109_094222.json | 1 | 1
run_0001_20261109_101157 | drag_v2_20261109_094222.json | 1 | 1
run_0001_20261109_101434 | drag_v2_20261109_094222.json | 1 | 1
run_0001_20261109_101615 | drag_v2_20261109_094222.json | 1 | 1
run_0001_20261109_102109 | drag_v2_20221013_230205.json | 2 | 2
run_0001_20261109_102248 | drag_v2_20221013_230205.json | 2 | 2
run_0001_20261109_102431 | drag_v2_20221013_230205.json | 2 | 2
run_0001_20261109_102715 | drag_v2_20261109_094222.json | 1 | 1
run_0001_20261109_102903 | drag_v2_20261109_094222.json | 1 | 1
run_0001_20261109_103049 | drag_v2_20261109_094222.json | 1 | 1
run_0001_20261109_103504 | drag_v2_20221013_230205.json | 2 | 2
run_0001_20261109_103804 | drag_v2_20221013_230205.json | 2 | 2
run_0001_20261109_103943 | drag_v2_20221013_230205.json | 2 | 2
run_0001_20261109_104110 | drag_v2_20221013_230205.json | 2 | 2
run_0001_20261109_104517 | drag_v2_20221013_230205.json | 2 | 2
run_0001_20261109_120818 | drag_v2_20221013_231249.json | 3 | （表になし）
run_0001_20261109_121128 | drag_v2_20221013_231249.json | 3 | （表になし）
run_0001_20261109_121224 | drag_v2_20221013_231249.json | 3 | （表になし）
run_0001_20261109_121320 | drag_v2_20221013_231249.json | 3 | （表になし）
run_0001_20261109_121416 | drag_v2_20221013_231249.json | 3 | （表になし）
run_0001_20261109_121511 | drag_v2_20221013_231249.json | 3 | （表になし）
run_0001_20261109_121605 | drag_v2_20221013_231249.json | 3 | （表になし）
run_0001_20261109_121659 | drag_v2_20221013_231249.json | 3 | （表になし）
run_0001_20261109_121815 | drag_v2_20221013_231249.json | 3 | （表になし）
run_0001_20261109_123655 | drag_v2_20261109_123000.json | 3 | （表になし）
run_0001_20261109_123756 | drag_v2_20261109_123000.json | 3 | （表になし）
run_0001_20261109_123848 | drag_v2_20261109_123000.json | 3 | （表になし）
run_0001_20261109_123940 | drag_v2_20261109_123000.json | 3 | （表になし）
run_0001_20261109_124032 | drag_v2_20261109_123000.json | 3 | （表になし）
run_0001_20261109_124117 | drag_v2_20261109_123000.json | 3 | （表になし）
run_0001_20261109_124207 | drag_v2_20261109_123000.json | 3 | （表になし）
run_0001_20261109_124256 | drag_v2_20261109_123000.json | 3 | （表になし）
run_0001_20261109_124438 | drag_v2_20261109_123000.json | 3 | （表になし）
run_0001_20261109_124530 | drag_v2_20261109_123000.json | 3 | （表になし）
run_0001_20261109_124817 | drag_v2_20261109_123000.json | 3 | （表になし）
run_0001_20261109_124920 | drag_v2_20261109_123000.json | 3 | （表になし）

位置ごとの本数（48 本）: 位置1 19 本, 位置2 8 本, 位置3 21 本 ／分からない 0 本
11:00 までの本（runs_table.csv にある 27 本）: 出た位置と表の位置が合う 27/27。表の teach 列と teach/ のファイル名も 27/27 で一致
12:00 以降の本（21 本, 表になし）: 120818〜121815 の 9 本は drag_v2_20221013_231249.json → 位置 3、123655〜124920 の 12 本は drag_v2_20261109_123000.json → 位置 3。teach/ のファイル名どおり
内訳: 位置 1 は元の記録 1 本（093045, 表では「外す」）＋教え直した記録 18 本。位置 3 は元の記録 9 本＋教え直した記録 12 本

■ commit
8d9a4de

■ 決めてほしいこと
なし

判定：合格
```

### 依頼129 の依頼文（依頼箱/済み/20261109_129_位置4を差し替えた記録をTEACH_FILESに足す.md）

```markdown
---
作業フォルダ: /Users/shimazueiichi/r2r2r-scripts
上限時間: 30
---
# 依頼129：位置4を差し替えた記録を count_by_position.py の TEACH_FILES に足す

依頼128 で位置1・3 の教え直した記録を TEACH_FILES に足した。同じ日の 13:00 に、位置4 の教えた記録の「ブロックの上」だけを差し替えた新しい記録 drag_v2_20261109_130000.json を作った（/Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/・作ったコードは make_teach_pos4_20261109.py。理由はコードの頭）。これも位置4 として足す。
実機は動かさない。エイイチは見ていない。

## やること
1. pi05/count_by_position.py の TEACH_FILES に `"drag_v2_20261109_130000.json": 4,     # 位置 4 のブロックの上を差し替えた記録 (2026-11-09)` を `"drag_v2_20221013_232345.json": 4,` の次の行に足す。ほかは変えない
2. 依頼128 で足したテストと同じ形で位置4 の1件を足し、テストを全部通す
3. 読むだけの確かめ：2026-11-09 の run の teach/ のファイル名から位置を出し、位置ごとの本数と「分からない」の数を報告に
4. 変えた2ファイルだけを指定して git add・commit（git add . は使わない）

## 報告
claude_code_reports/20261109_129.txt に：git diff、テストの結果、3 の表、commit の番号。
**報告の最後の1行は必ず次のどれか**：「判定：合格」／「判定：止めた（決めてほしいことあり）」／「判定：失敗」
```

### 依頼129 の報告（r2r2r-scripts/claude_code_reports/20261109_129.txt）

```text
依頼129：位置4を差し替えた記録を count_by_position.py の TEACH_FILES に足す

■ やったこと
1. pi05/count_by_position.py の TEACH_FILES に "drag_v2_20261109_130000.json": 4 を drag_v2_20221013_232345.json の次の行に足した（ほかは変えていない）
2. pi05/test_count_by_position.py の test_same_position_two_files（依頼128 で足したテスト）に位置4 の 1 件（元の 232345 と差し替えた 130000）を足した。コメントを「位置 1・3・4」に直した
3. 2026-11-09 の run を読むだけで確かめた（KIOXIA は書いていない。実機は動かしていない）
4. 2 ファイルを指定して git add・commit

■ git diff
diff --git a/pi05/count_by_position.py b/pi05/count_by_position.py
index 488c828..6c97123 100644
--- a/pi05/count_by_position.py
+++ b/pi05/count_by_position.py
@@ -69,6 +69,7 @@ TEACH_FILES = {
     "drag_v2_20221013_231249.json": 3,
     "drag_v2_20261109_123000.json": 3,     # 位置 3 を教え直した記録 (DEEP_DEMOS 2-1・2026-11-09)
     "drag_v2_20221013_232345.json": 4,
+    "drag_v2_20261109_130000.json": 4,     # 位置 4 のブロックの上を差し替えた記録 (2026-11-09)
     "drag_v2_20221013_233323.json": 5,
 }
 # 教えた位置のブロックの中心 (マットの上の mm). 決め方は頭の説明
diff --git a/pi05/test_count_by_position.py b/pi05/test_count_by_position.py
index e7dce75..3d94a0d 100644
--- a/pi05/test_count_by_position.py
+++ b/pi05/test_count_by_position.py
@@ -99,9 +99,10 @@ class TestPosition(unittest.TestCase):
         self.assertEqual(cbp.teach_position(self.root / "missing")[0], cbp.UNKNOWN)
 
     def test_same_position_two_files(self):
-        # 位置 1・3 は教え直した記録と元の記録の 2 つ. 両方が teach/ にあっても集合で 1 つになり位置 1・3
+        # 位置 1・3・4 は教え直した (差し替えた) 記録と元の記録の 2 つ. 両方が teach/ にあっても集合で 1 つになり位置 1・3・4
         for pos, (old, new) in {1: ("drag_v2_20221013_144348.json", "drag_v2_20261109_094222.json"),
-                                3: ("drag_v2_20221013_231249.json", "drag_v2_20261109_123000.json")}.items():
+                                3: ("drag_v2_20221013_231249.json", "drag_v2_20261109_123000.json"),
+                                4: ("drag_v2_20221013_232345.json", "drag_v2_20261109_130000.json")}.items():
             self.assertEqual(cbp.TEACH_FILES[old], pos)
             self.assertEqual(cbp.TEACH_FILES[new], pos)
             d = self.root / f"both{pos}"

■ テストの結果（python3 pi05/test_count_by_position.py -v）
test_count_merged (__main__.TestCount.test_count_merged) ... ok
test_merge_readme_table_and_same_data (__main__.TestCount.test_merge_readme_table_and_same_data) ... ok
test_merge_survives_count_error (__main__.TestCount.test_merge_survives_count_error) ... ok
test_block_from_video (__main__.TestPosition.test_block_from_video) ... ok
test_block_not_found (__main__.TestPosition.test_block_not_found) ... ok
test_nearest_and_line (__main__.TestPosition.test_nearest_and_line) ... ok
test_same_position_two_files (__main__.TestPosition.test_same_position_two_files) ... ok
test_teach_file_mapping (__main__.TestPosition.test_teach_file_mapping) ... ok

----------------------------------------------------------------------
Ran 8 tests in 1.310s

OK

■ 3 の表（run | teach/ のファイル | 出た位置）
run_0001_20261109_093045 | drag_v2_20221013_144348.json | 1
run_0001_20261109_094839 | drag_v2_20261109_094222.json | 1
run_0001_20261109_095308 | drag_v2_20261109_094222.json | 1
run_0001_20261109_095452 | drag_v2_20261109_094222.json | 1
run_0001_20261109_095630 | drag_v2_20261109_094222.json | 1
run_0001_20261109_095810 | drag_v2_20261109_094222.json | 1
run_0001_20261109_095948 | drag_v2_20261109_094222.json | 1
run_0001_20261109_100126 | drag_v2_20261109_094222.json | 1
run_0001_20261109_100307 | drag_v2_20261109_094222.json | 1
run_0001_20261109_100444 | drag_v2_20261109_094222.json | 1
run_0001_20261109_100716 | drag_v2_20261109_094222.json | 1
run_0001_20261109_100852 | drag_v2_20261109_094222.json | 1
run_0001_20261109_101023 | drag_v2_20261109_094222.json | 1
run_0001_20261109_101157 | drag_v2_20261109_094222.json | 1
run_0001_20261109_101434 | drag_v2_20261109_094222.json | 1
run_0001_20261109_101615 | drag_v2_20261109_094222.json | 1
run_0001_20261109_102109 | drag_v2_20221013_230205.json | 2
run_0001_20261109_102248 | drag_v2_20221013_230205.json | 2
run_0001_20261109_102431 | drag_v2_20221013_230205.json | 2
run_0001_20261109_102715 | drag_v2_20261109_094222.json | 1
run_0001_20261109_102903 | drag_v2_20261109_094222.json | 1
run_0001_20261109_103049 | drag_v2_20261109_094222.json | 1
run_0001_20261109_103504 | drag_v2_20221013_230205.json | 2
run_0001_20261109_103804 | drag_v2_20221013_230205.json | 2
run_0001_20261109_103943 | drag_v2_20221013_230205.json | 2
run_0001_20261109_104110 | drag_v2_20221013_230205.json | 2
run_0001_20261109_104517 | drag_v2_20221013_230205.json | 2
run_0001_20261109_120818 | drag_v2_20221013_231249.json | 3
run_0001_20261109_121128 | drag_v2_20221013_231249.json | 3
run_0001_20261109_121224 | drag_v2_20221013_231249.json | 3
run_0001_20261109_121320 | drag_v2_20221013_231249.json | 3
run_0001_20261109_121416 | drag_v2_20221013_231249.json | 3
run_0001_20261109_121511 | drag_v2_20221013_231249.json | 3
run_0001_20261109_121605 | drag_v2_20221013_231249.json | 3
run_0001_20261109_121659 | drag_v2_20221013_231249.json | 3
run_0001_20261109_121815 | drag_v2_20221013_231249.json | 3
run_0001_20261109_123655 | drag_v2_20261109_123000.json | 3
run_0001_20261109_123756 | drag_v2_20261109_123000.json | 3
run_0001_20261109_123848 | drag_v2_20261109_123000.json | 3
run_0001_20261109_123940 | drag_v2_20261109_123000.json | 3
run_0001_20261109_124032 | drag_v2_20261109_123000.json | 3
run_0001_20261109_124117 | drag_v2_20261109_123000.json | 3
run_0001_20261109_124207 | drag_v2_20261109_123000.json | 3
run_0001_20261109_124256 | drag_v2_20261109_123000.json | 3
run_0001_20261109_124438 | drag_v2_20261109_123000.json | 3
run_0001_20261109_124530 | drag_v2_20261109_123000.json | 3
run_0001_20261109_124817 | drag_v2_20261109_123000.json | 3
run_0001_20261109_124920 | drag_v2_20261109_123000.json | 3
run_0001_20261109_125209 | drag_v2_20221013_232345.json | 4
run_0001_20261109_125607 | drag_v2_20221013_232345.json | 4

位置ごとの本数（50 本）: 位置1 19 本, 位置2 8 本, 位置3 21 本, 位置4 2 本 ／分からない 0 本
内訳: 位置 4 の 2 本（125209・125607）は元の記録 drag_v2_20221013_232345.json → 位置 4。差し替えた記録 drag_v2_20261109_130000.json を teach/ に持つ run はまだない（作られた 13:00 より後の run がない）
依頼128 の時点の 48 本は出た位置が同じ（位置1 19・位置2 8・位置3 21）

■ commit
bac9ab7

■ 決めてほしいこと
なし

判定：合格
```

### 依頼130 の依頼文（依頼箱/済み/20261109_130_位置4を教え直した記録をTEACH_FILESに足す.md）

```markdown
---
作業フォルダ: /Users/shimazueiichi/r2r2r-scripts
上限時間: 30
---
# 依頼130：位置4をゲームパッドで教え直した記録を count_by_position.py の TEACH_FILES に足す

依頼129 で足した drag_v2_20261109_130000.json（位置4 のブロックの上だけを差し替えた記録）は、爪がブロックに乗る件が直らなかった（run_0001_20261109_125825 の1本だけで使うのをやめた）。
13:03 に位置4 をゲームパッドで教え直した drag_v2_20261109_130300.json を作った（/Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/・作ったコードは make_teach_pos4_v2_20261109.py）。これも位置4 として足す。130000 の行は消さない（125825 の数え方が変わらないように）。
実機は動かさない。エイイチは見ていない。

## やること
1. pi05/count_by_position.py の TEACH_FILES に `"drag_v2_20261109_130300.json": 4,     # 位置 4 をゲームパッドで教え直した記録 (DEEP_DEMOS 2-1・2026-11-09)` を、130000 の行の次に足す。ほかは変えない
2. 依頼129 と同じ形でテストを1件足し、テストを全部通す
3. 変えた2ファイルだけを指定して git add・commit（git add . は使わない）

## 報告
claude_code_reports/20261109_130.txt に：git diff、テストの結果、commit の番号。
**報告の最後の1行は必ず次のどれか**：「判定：合格」／「判定：止めた（決めてほしいことあり）」／「判定：失敗」
```

### 依頼130 の報告（r2r2r-scripts/claude_code_reports/20261109_130.txt）

```text
依頼130 報告：位置4をゲームパッドで教え直した記録を TEACH_FILES に足す

■ git diff
diff --git a/pi05/count_by_position.py b/pi05/count_by_position.py
index 6c97123..6513877 100644
--- a/pi05/count_by_position.py
+++ b/pi05/count_by_position.py
@@ -70,6 +70,7 @@ TEACH_FILES = {
     "drag_v2_20261109_123000.json": 3,     # 位置 3 を教え直した記録 (DEEP_DEMOS 2-1・2026-11-09)
     "drag_v2_20221013_232345.json": 4,
     "drag_v2_20261109_130000.json": 4,     # 位置 4 のブロックの上を差し替えた記録 (2026-11-09)
+    "drag_v2_20261109_130300.json": 4,     # 位置 4 をゲームパッドで教え直した記録 (DEEP_DEMOS 2-1・2026-11-09)
     "drag_v2_20221013_233323.json": 5,
 }
 # 教えた位置のブロックの中心 (マットの上の mm). 決め方は頭の説明
diff --git a/pi05/test_count_by_position.py b/pi05/test_count_by_position.py
index 3d94a0d..162f6f5 100644
--- a/pi05/test_count_by_position.py
+++ b/pi05/test_count_by_position.py
@@ -115,6 +115,17 @@ class TestPosition(unittest.TestCase):
         (d / "teach" / "drag_v2_20261109_123000.json").write_text("{}")
         self.assertEqual(cbp.teach_position(d)[0], cbp.UNKNOWN)
 
+    def test_pos4_gamepad_file(self):
+        # 位置 4 をゲームパッドで教え直した 130300 も位置 4. 元の記録・差し替えた 130000 のどちらと teach/ にあっても位置 4
+        new = "drag_v2_20261109_130300.json"
+        self.assertEqual(cbp.TEACH_FILES[new], 4)
+        self.assertEqual(cbp.TEACH_FILES["drag_v2_20261109_130000.json"], 4)
+        for old in ("drag_v2_20221013_232345.json", "drag_v2_20261109_130000.json"):
+            d = self.root / f"pos4_{old}"
+            write_teach_run(d, old)
+            (d / "teach" / new).write_text("{}")
+            self.assertEqual(cbp.teach_position(d), (4, f"teach/{old}"))
+
     def test_nearest_and_line(self):
         for pos, mm in cbp.TEACH_REF_MM.items():
             self.assertEqual(cbp.nearest_position(mm)[0], pos)

■ テストの結果 (pi05/test_*.py をファイルごとに実行)
test_count_by_position.py: Ran 9 tests in 1.305s OK  (2s)
test_diag_joint_hold.py: Ran 24 tests in 0.337s OK  (0s)
test_gap_fill.py: Ran 7 tests in 0.001s OK  (0s)
test_grasp_depth.py: Ran 12 tests in 5.365s OK  (6s)
test_hf_upload_ckpt.py: Ran 10 tests in 0.031s OK  (0s)
test_merge_and_config.py: Ran 27 tests in 2.737s OK  (3s)
test_pad_build.py: Ran 3 tests in 0.852s OK  (1s)
test_pad_correction.py: Ran 4 tests in 16.504s OK  (17s)
test_recorder_currents.py: Ran 15 tests in 37.900s OK  (39s)
test_recorder_rpc.py: Ran 4 tests in 16.055s OK  (16s)
test_rewind_correct.py: Ran 69 tests in 66.718s OK  (67s)
test_teach_currents.py: 90 秒の上限で止まったので上限 550 秒で再実行 → Ran 23 tests in 197.656s OK
test_trim_hold.py: Ran 5 tests in 0.241s OK  (1s)

合計 212 件 すべて OK (失敗 0)

■ commit
5ae9f10 (pi05/count_by_position.py・pi05/test_count_by_position.py の 2 ファイルだけを指定して add)
130000 の行は消していない。実機は動かしていない。

判定：合格
```

### 本数を数えるコード（r2r2r-scripts/pi05/count_by_position.py・依頼130 のあとの全体）

```python
#!/usr/bin/env python3
"""count_by_position.py — 学習データの本数を, ブロックの置き場所 (LOG352 の教えた位置 1〜5) ごとに数える (2026-11-07 依頼 118).

エイイチの決め (2026-11-07): 置き場所ごとの本数をそろえる. 目安は各位置 10 本.
撮り足す本数を決めるときと, merge_raw_episodes.py でデータセットを作り終えたときの README の表に使う.

入力 (どちらでも. いくつでも):
  データセット名            datasets/{名前}/raw_episodes を数える
  raw_episodes のフォルダ   そのフォルダを数える (ひとつ上の index.json があれば外した本も数える)

位置の決め方:
  教えた動き (run_pick_place の run):
    試行フォルダの teach/ にある教えた記録のファイル名で決める (LOG352 の README の表と同じ対応. TEACH_FILES).
    teach/ がない・表にないファイル名なら「分からない」.
  補正入り (pi05_policy の run. meta.json の source が pi05_policy で始まる):
    上カメラ (recording/top.mp4) の最初のコマでマットの四隅を見つけ, マットの上の mm に直す対応を作る
    (依頼 107 twin_prep と同じ. visual_servo_pick の四隅 (±310, −89)・(±310, 361) mm).
    爪を閉じる命令 (いちばん初め) より前のコマを 3 つおきに見て, ブロックらしい赤 (twin_prep.red_candidates と同じ.
    根元から 120mm 以内・細長い・埋まりの少ない赤は外す) がいちばん大きく写ったコマの中心を, ブロックの位置とする
    (HOME の最初のコマでは爪の下に半分隠れていることがあるため).
    その位置から TEACH_REF_MM のいちばん近い位置を選び, 離れが MAX_DIST_MM (30mm) を超えたら「分からない」.
    四隅・ブロックが見つからないときも「分からない」(理由を残す).
  TEACH_REF_MM: 同じ見つけ方を LOG352 で採った 19 本 (10/19) にかけた値の位置ごとの中央値.
    位置 1 は 183454 の 1 本だけ (爪の陰で赤が小さく写る. 866px). 位置 2 は 191257 が見つからず 4 本,
    位置 3 は 192539 が見つからず 3 本. 位置 4 から 46mm ずらして置いた 193729 は (237.4, 52.6) で, 位置 4 から 48mm
    (使わない試行. この線なら「分からない」になる).
    教えた位置どうしのいちばん近い間は位置 1〜2 の 63mm. 線 30mm はその半分より少し下.
    座標はマットの上の mm (visual_servo_pick の向き). 依頼 107 C の Unity の値 (T1〜T5) とは原点・向きが違う.

外した本・手の本 (データセットの index.json があるとき):
  merge_raw_episodes.py の index.json の excluded / build_*_episodes.py の index.json の used=false の本を,
  同じ決め方で位置に割り当て, 「浅くて外した」(grasp_depth.shallow か理由が「浅い」「shallow」で始まる) と
  「手で外した」(hand_in_frame か grasp_depth.hand_suspect) を数える.
  データに入っている本の「手が写っていそう」は index に値があるときだけ数える (--measure-depth を付けると
  grasp_depth.py で 1 本ずつ測る. 遅い).

  python3 pi05/count_by_position.py mecharm_redblock_box_teach_v1_trim2_corr_v5_deep
  python3 pi05/count_by_position.py A B --target 10 --json out.json

読むだけ (記録・データセットには何も書かない. --json のファイルだけ書く).
"""
import argparse
import contextlib
import json
import math
import sys
from pathlib import Path

import cv2
import numpy as np

_HERE = Path(__file__).resolve()
sys.path.insert(0, str(_HERE.parent))
sys.path.insert(0, str(_HERE.parent.parent))   # mat_corner_detection.py (r2r2r-scripts の直下)

import grasp_depth as gd  # noqa: E402

DATA_ROOT = Path("/Volumes/KIOXIA/r2r2r-data")
RUN_SUBDIRS = ("run_pick_place", "pi05_policy")
POSITIONS = (1, 2, 3, 4, 5)
UNKNOWN = "unknown"
DEFAULT_TARGET = 10

# LOG352 の README の表 (runs/experiments/record_teach_demo/20261019_LOG352/README.md)
TEACH_FILES = {
    "drag_v2_20221013_144348.json": 1,
    "drag_v2_20261109_094222.json": 1,     # 位置 1 を教え直した記録 (DEEP_DEMOS 2-1・LOG463)
    "drag_v2_20221013_230205.json": 2,
    "drag_v2_20221013_231249.json": 3,
    "drag_v2_20261109_123000.json": 3,     # 位置 3 を教え直した記録 (DEEP_DEMOS 2-1・2026-11-09)
    "drag_v2_20221013_232345.json": 4,
    "drag_v2_20261109_130000.json": 4,     # 位置 4 のブロックの上を差し替えた記録 (2026-11-09)
    "drag_v2_20261109_130300.json": 4,     # 位置 4 をゲームパッドで教え直した記録 (DEEP_DEMOS 2-1・2026-11-09)
    "drag_v2_20221013_233323.json": 5,
}
# 教えた位置のブロックの中心 (マットの上の mm). 決め方は頭の説明
TEACH_REF_MM = {
    1: (182.7, 188.8),
    2: (215.5, 242.2),
    3: (123.6, 235.6),
    4: (240.8, 101.3),
    5: (-48.8, 246.4),
}
MAX_DIST_MM = 30.0
MAT_CORNERS_MM = [[310, -89], [-310, -89], [-310, 361], [310, 361]]   # visual_servo_pick と同じ (twin_prep)
BLOCK_MIN_DIST_FROM_BASE_MM = 120.0                                   # record_teach_demo と同じ (twin_prep)
FRAME_STEP = 3


# ---------------------------------------------------------------- 位置を決める
def teach_position(run_dir):
    """教えた動きの run: teach/ の教えた記録のファイル名から. 戻り値 (位置 or UNKNOWN, 根拠の文字)."""
    tdir = Path(run_dir) / "teach"
    files = sorted(p.name for p in tdir.glob("[!.]*.json")) if tdir.is_dir() else []
    if not files:
        return UNKNOWN, "teach/ に教えた記録がない"
    pos = {TEACH_FILES[f] for f in files if f in TEACH_FILES}
    if len(pos) != 1:
        return UNKNOWN, f"teach/ のファイルが表と合わない: {', '.join(files)}"
    return pos.pop(), f"teach/{files[0]}"


def nearest_position(mm, max_dist=MAX_DIST_MM):
    """ブロックの位置 (mm) → (位置 or UNKNOWN, いちばん近い位置, 離れ mm)."""
    p, d = min(((k, math.hypot(mm[0] - v[0], mm[1] - v[1])) for k, v in TEACH_REF_MM.items()), key=lambda x: x[1])
    return (p if d <= max_dist else UNKNOWN), p, round(d, 1)


def _px_to_mm(H, x, y):
    r = cv2.perspectiveTransform(np.array([[[float(x), float(y)]]], np.float32), H)
    return float(r[0][0][0]), float(r[0][0][1])


def red_candidates(frame, mat_bbox, H):
    """twin_prep.red_candidates と同じ (向きは使わないので出さない)."""
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    m = cv2.inRange(hsv, np.array([0, 100, 100]), np.array([10, 255, 255])) | \
        cv2.inRange(hsv, np.array([160, 100, 100]), np.array([180, 255, 255]))
    m = cv2.morphologyEx(m, cv2.MORPH_OPEN, np.ones((5, 5), np.uint8))
    cnts, _ = cv2.findContours(m, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    out = []
    for c in cnts:
        a = cv2.contourArea(c)
        if a < 500:
            continue
        (cx, cy), (rw, rh), _ang = cv2.minAreaRect(c)
        if not (mat_bbox[0] <= cx <= mat_bbox[1] and mat_bbox[2] <= cy <= mat_bbox[3]):
            continue
        aspect = max(rw, rh) / max(1e-6, min(rw, rh))
        extent = a / max(1e-6, rw * rh)
        mm = _px_to_mm(H, cx, cy)
        if math.hypot(*mm) < BLOCK_MIN_DIST_FROM_BASE_MM or aspect > 1.8 or extent < 0.6:
            continue
        out.append({"area": float(a), "px": (float(cx), float(cy)), "mm": mm})
    return out


def detect_corners(frame):
    with contextlib.redirect_stdout(sys.stderr):
        import mat_corner_detection as mcd
        return mcd.detect_corners(frame)


def block_mm(run_dir, corners_fn=None):
    """補正入りの run: 上カメラで見つけたブロックの位置. 戻り値 (dict or None, 理由)."""
    corners_fn = corners_fn or detect_corners
    rec = Path(run_dir) / "recording"
    if not (rec / "top.mp4").exists() or not (rec / "top_frame_log.csv").exists():
        return None, "top.mp4 か top_frame_log.csv がない"
    tc = None
    if (rec / "states.csv").exists():
        gt, gs = gd.load_gripper_cmds(rec / "states.csv")
        tc = gd.close_time(gt, gs)
    _, fts = gd.load_frame_log(rec / "top_frame_log.csv")
    cap = cv2.VideoCapture(str(rec / "top.mp4"))
    try:
        ok, f0 = cap.read()
        if not ok:
            return None, "top.mp4 が読めない"
        corners = corners_fn(f0)
        if corners is None:
            return None, "マットの四隅が見つからない"
        co = [[float(x), float(y)] for x, y in corners]
        H = cv2.getPerspectiveTransform(np.array(co, np.float32), np.array(MAT_CORNERS_MM, np.float32))
        bbox = (int(min(co[0][0], co[3][0])), int(max(co[1][0], co[2][0])),
                int(min(co[0][1], co[1][1])), int(max(co[2][1], co[3][1])))
        best, k, f = None, 0, f0
        while ok:
            if k < len(fts) and tc is not None and fts[k] > tc:
                break
            if k % FRAME_STEP == 0:
                cs = red_candidates(f, bbox, H)
                if cs:
                    c = max(cs, key=lambda c: c["area"])
                    if best is None or c["area"] > best["area"]:
                        best = dict(c, frame=k)
            ok, f = cap.read()
            k += 1
    finally:
        cap.release()
    if best is None:
        return None, "閉じる前のコマでブロックが見つからない"
    return best, "ok"


def find_run_dir(stem, runs_root):
    for sub in RUN_SUBDIRS:
        d = Path(runs_root) / sub / stem
        if d.is_dir():
            return d
    return None


def is_correction(meta, stem):
    src = (meta or {}).get("source", "")
    if src:
        return src.startswith("pi05_policy")
    return stem.startswith("pi05_")


def classify(stem, meta, runs_root, corners_fn=None):
    """1 本の位置. 戻り値 dict(stem, kind, position, how, ...)."""
    kind = "correction" if is_correction(meta, stem) else "teach"
    out = {"stem": stem, "kind": kind, "position": UNKNOWN, "how": None}
    rd = find_run_dir(stem, runs_root)
    if rd is None:
        out["how"] = "runs/ に試行フォルダがない"
        return out
    if kind == "teach":
        out["position"], out["how"] = teach_position(rd)
        return out
    try:
        b, why = block_mm(rd, corners_fn)
    except Exception as e:   # 見つけ方で落ちても数えるのは止めない
        b, why = None, f"exception:{type(e).__name__}:{e}"
    if b is None:
        out["how"] = why
        return out
    pos, near, d = nearest_position(b["mm"])
    out.update(position=pos, how=f"top.mp4 のブロック (コマ {b['frame']}) → 位置 {near} まで {d}mm",
               block_mm=[round(v, 1) for v in b["mm"]], nearest=near, dist_mm=d)
    if pos == UNKNOWN:
        out["how"] += f" (線 {MAX_DIST_MM:g}mm を超える)"
    return out


# ---------------------------------------------------------------- 外した本・手の本
def _shallow(v):
    g = v.get("grasp_depth") or {}
    r = str(v.get("reason", ""))
    return bool(g.get("shallow")) or r.startswith("浅い") or r.startswith("shallow")


def _hand(v):
    g = v.get("grasp_depth") or {}
    return bool(v.get("hand_in_frame")) or bool(g.get("hand_suspect"))


def excluded_entries(ds_dir):
    """データセットの index.json から, 外した本 {名前: 中身}. merge の excluded と build の used=false の両方."""
    p = Path(ds_dir) / "index.json"
    if not p.exists():
        return {}, {}
    idx = json.loads(p.read_text())
    out, kept_info = {}, {}
    for k, v in (idx.get("excluded") or {}).items():
        out[k] = v
    for k, v in idx.items():
        if isinstance(v, dict) and "used" in v and "run" in v:
            if v["used"]:
                kept_info[k] = v
            elif v.get("grasp_depth") or v.get("hand_in_frame"):
                out[k] = v
    return out, kept_info


# ---------------------------------------------------------------- 数える
def resolve_input(x, data_root):
    p = Path(x)
    if p.is_dir() and (p.name == "raw_episodes" or list(p.glob("[!.]*/episode.npz"))):
        return p, p.parent
    d = Path(data_root) / "datasets" / x
    return d / "raw_episodes", d


def count(inputs, data_root=DATA_ROOT, target=DEFAULT_TARGET, measure_depth=False, corners_fn=None, log=print):
    runs_root = Path(data_root) / "runs"
    eps, excl, kept_info, seen = [], [], {}, set()
    for x in inputs:
        raw, ds = resolve_input(x, data_root)
        if not raw.is_dir():
            raise SystemExit(f"[ABORT] raw_episodes がない: {raw}")
        for ep in sorted(p.parent for p in raw.glob("[!.]*/episode.npz")):
            if ep.name in seen:
                continue
            seen.add(ep.name)
            meta = json.loads((ep / "meta.json").read_text()) if (ep / "meta.json").exists() else {}
            stem = meta.get("run_stem", ep.name)
            eps.append((ep.name, stem, meta))
        ex, ki = excluded_entries(ds)
        kept_info.update(ki)
        for k, v in ex.items():
            if k not in seen:
                seen.add(k)
                excl.append((k, v))
    rows = []
    for name, stem, meta in eps:
        r = classify(stem, meta, runs_root, corners_fn)
        r["name"] = name
        g = (kept_info.get(stem) or {}).get("grasp_depth")
        if measure_depth:
            rd = find_run_dir(stem, runs_root)
            g = gd.measure_run(rd) if rd else None
        r["hand_suspect"] = bool(g and g.get("hand_suspect"))
        r["depth_known"] = g is not None
        rows.append(r)
        log(f"[POS ] {name}  {'教えた動き' if r['kind'] == 'teach' else '補正入り'}  位置 {r['position']}  {r['how']}")
    ex_rows = []
    for name, v in excl:
        kind_meta = {"source": "pi05_policy"} if (v.get("kind") == "補正入り" or name.startswith("pi05_")) else {}
        r = classify(name, kind_meta, runs_root, corners_fn)
        r.update(name=name, shallow=_shallow(v), hand=_hand(v), reason=v.get("reason"))
        ex_rows.append(r)
        log(f"[EXCL] {name}  位置 {r['position']}  {r.get('reason')}")
    return summarize(rows, ex_rows, target)


def summarize(rows, ex_rows, target):
    keys = list(POSITIONS) + [UNKNOWN]
    table = {}
    for k in keys:
        rs = [r for r in rows if r["position"] == k]
        es = [r for r in ex_rows if r["position"] == k]
        n = len(rs)
        table[k] = {
            "episodes": n,
            "teach": sum(r["kind"] == "teach" for r in rs),
            "correction": sum(r["kind"] == "correction" for r in rs),
            "to_add": (max(0, target - n) if k != UNKNOWN else None),
            "excluded_shallow": sum(r["shallow"] for r in es),
            "excluded_hand": sum(r["hand"] for r in es),
            "hand_suspect_in_data": sum(r["hand_suspect"] for r in rs),
        }
    return {"target": target, "max_dist_mm": MAX_DIST_MM, "table": table,
            "total": len(rows), "depth_known": sum(r["depth_known"] for r in rows),
            "episodes": rows, "excluded": ex_rows}


def table_lines(res):
    """Markdown の表 (README と端末で同じもの)."""
    t = res["table"]
    lines = [f"| 位置 | 本数 | 教えた動き | 補正入り | 目標 {res['target']} 本まで | 浅くて外した | 手で外した | "
             "入っている本で手が写っていそう |",
             "| --- | --- | --- | --- | --- | --- | --- | --- |"]
    for k, v in t.items():
        name = f"位置 {k}" if k != UNKNOWN else "分からない"
        add = "—" if v["to_add"] is None else f"+{v['to_add']}"
        hand_in = v["hand_suspect_in_data"] if res["depth_known"] else "—"
        lines.append(f"| {name} | {v['episodes']} | {v['teach']} | {v['correction']} | {add} | "
                     f"{v['excluded_shallow']} | {v['excluded_hand']} | {hand_in} |")
    lines.append(f"| 合計 | {res['total']} | {sum(v['teach'] for v in t.values())} | "
                 f"{sum(v['correction'] for v in t.values())} | "
                 f"+{sum(v['to_add'] or 0 for v in t.values())} | "
                 f"{sum(v['excluded_shallow'] for v in t.values())} | {sum(v['excluded_hand'] for v in t.values())} | "
                 f"{sum(v['hand_suspect_in_data'] for v in t.values()) if res['depth_known'] else '—'} |")
    return lines


def readme_section(res):
    unk = [r for r in res["episodes"] + res["excluded"] if r["position"] == UNKNOWN]
    lines = ["## 置き場所ごとの本数 (`pi05/count_by_position.py`。依頼 118)", "",
             "教えた動きは `teach/` の教えた記録のファイル名 (LOG352 の表) で、補正入りは上カメラで見つけたブロックの位置を"
             f"いちばん近い教えた位置に割り当てた ({res['max_dist_mm']:g}mm を超えたら「分からない」)。"
             "「浅くて外した」「手で外した」は、このデータセットの `index.json` で外したエピソードの数 (データには入っていない)。", ""]
    lines += table_lines(res)
    if not res["depth_known"]:
        lines += ["", "- 入っている本の「手が写っていそう」は測っていない (`--measure-depth` で測る)"]
    for r in unk:
        lines.append(f"- 分からない: {r['name']} ({r['how']})")
    return lines


def main():
    ap = argparse.ArgumentParser(description=__doc__.split("\n")[0])
    ap.add_argument("inputs", nargs="+", help="データセット名 (datasets/ の下) か raw_episodes のフォルダ")
    ap.add_argument("--target", type=int, default=DEFAULT_TARGET, help=f"位置ごとの目標本数 (既定 {DEFAULT_TARGET})")
    ap.add_argument("--measure-depth", action="store_true",
                    help="入っている本を grasp_depth.py で測り, 手が写っていそうな本を数える (遅い)")
    ap.add_argument("--json", help="結果を JSON に書く (書く先はこのファイルだけ)")
    ap.add_argument("--data-root", default=str(DATA_ROOT), help=argparse.SUPPRESS)
    args = ap.parse_args()
    res = count(args.inputs, args.data_root, args.target, args.measure_depth)
    print()
    print("\n".join(table_lines(res)))
    if args.json:
        Path(args.json).write_text(json.dumps(res, indent=2, ensure_ascii=False, default=str))
        print(f"[JSON] {args.json}")
    return 0


if __name__ == "__main__":
    sys.exit(main())
```


## 依頼131：5か所を10本ずつにそろえた学習データを作った

撮り終えたあと、本数は10本でそろえると決めました。依頼131 では、この日に撮った31本（位置1が10本・位置2が7本・位置3が9本・位置4が5本）を学習データにし、前の深いデータ（mecharm_redblock_box_teach_v1_trim2_corr_v5_deep・21本）とまとめています。10本を超えた位置3と位置5（どちらも11本）は、その位置でいちばん浅い1本を外しました。

| 位置 | 本数 | 教えた動き | 補正入り | 外した本 |
|---|---|---|---|---|
| 1 | 10 | 10 | 0 | — |
| 2 | 10 | 10 | 0 | — |
| 3 | 10 | 10 | 0 | 123756（21.8px） |
| 4 | 10 | 10 | 0 | — |
| 5 | 10 | 4 | 6 | pi05_20261101_190854（21.4px・補正入り） |
| 合計 | 50 | 44 | 6 | 2 |

できたデータは mecharm_redblock_box_deep_even10_v1（50本・7,128コマ）で、tar は193MB です。データの点検（check_dataset.py）は6項目すべて合格でした。

学習データにするときの深さの測り直しで、位置2の2本（103943・104517）に手が写っていそうという印が出ました。閉じる1.5秒前のコマだけが237.8px・237.7px と大きく、0.5秒前と閉じる直前は24.2px・22.1px で普通です。Claude Code が全体の画を見て、手は写っておらず赤いケーブルを拾った値と判断し、外さずに入れています。つかみも深い（−7.8px・−7.7px）本です。

### 依頼131 の依頼文（依頼箱/済み/20261109_131_今日の深いお手本をデータにし位置ごと10本にそろえてまとめる.md）

```markdown
---
作業フォルダ: /Users/shimazueiichi/r2r2r-scripts
上限時間: 120
---
# 依頼131：2026-11-09 に撮った深いお手本をデータにし、今の deep とまとめて位置1〜5 を各10本にそろえる

pi05/DEEP_DEMOS.md の 3.（撮り終えたら）を今日の本で行う。実機は動かさない。エイイチは見ていない。
**エイイチの決め（2026-11-09）：本数は各位置ちょうど10本にそろえる。**
依頼130（TEACH_FILES に位置4 の 130300 を足す）が終わってから始めること（記録.log で完了を確かめる。終わっていなければ止めて報告）。

## 使う本（今日撮った本。これ以外の今日の run は入れない）
- 位置1（drag_v2_20261109_094222.json）10本：094839 095308 095810 095948 100126 100307 100444 100716 101157 103049（lab/Log25/runs_table.csv の use=使う）
- 位置2（drag_v2_20221013_230205.json）7本：102109 102248 102431 103804 103943 104110 104517（同じ表の use=使う）
- 位置3（drag_v2_20261109_123000.json）9本：123756 123848 124032 124117 124207 124256 124438 124817 124920
- 位置4（drag_v2_20261109_130300.json）5本：130542 130723 130824 130929 131103
（すべて run_0001_20261109_{時刻}。入れなかった本：位置3 の元の記録の9本は全部浅い・123655 と 123940 は浅い・124530 は爪が乗って空で閉じた・位置4 の 125209 125607 125825 は爪が乗って空で閉じた）

## やること
1. 新しい本だけのデータセット mecharm_redblock_box_teach_pos1to4_deep_v1 を作る（DEEP_DEMOS 3. のとおり --trim-mid-idle --max-protrude-px 24。上の31本を --run で渡す）。[DEPTH] の行で外れた本・測れなかった本・手が写っていそうな本を報告に。外れた本があれば、その位置が10本を割るかを報告に書いて止める（撮り足しはエイイチが決める）
2. count_by_position.py で mecharm_redblock_box_teach_v1_trim2_corr_v5_deep と 1. を合わせて数える。見込みは位置1=10・2=10・3=11・4=10・5=11。「分からない」が出たら止めて報告
3. 10本を超える位置（見込みは位置3 と位置5）は、その位置の本の中で「閉じて1.0秒後のはみ出し」（grasp_depth.py の値）がいちばん大きい本から外して10本にする。同じ値なら古い本を外す。外す本と値を merge の --exclude-json に理由と一緒に書く（pi05/excludes/ に置く。理由の文：「位置ごとの本数を10本にそろえるため、その位置でいちばん浅い本を外した（エイイチの決め 2026-11-09）」）
4. merge_raw_episodes.py で mecharm_redblock_box_teach_v1_trim2_corr_v5_deep と 1. をまとめ、mecharm_redblock_box_deep_even10_v1 を作る（--tar。元のデータセットは変えない）。README の最後の位置ごとの表が全部10本・目標まで ＋0 であること
5. check_dataset.py を通す
6. 変えた・足したコードの側のファイル（pi05/excludes/ の json など）だけを指定して git add・commit（git add . は使わない）

## 報告
claude_code_reports/20261109_131.txt に：1 の [DEPTH] の行、2 の表、3 で外した本と値、4 の README の位置ごとの表・エピソード数・tar の大きさと置き場所、5 の結果、commit の番号、決めてほしいこと。
**報告の最後の1行は必ず次のどれか**：「判定：合格」／「判定：止めた（決めてほしいことあり）」／「判定：失敗」
```

### 依頼131 の報告（r2r2r-scripts/claude_code_reports/20261109_131.txt）

```text
依頼131 報告：2026-11-09 の深いお手本をデータにし、今の deep とまとめて位置1〜5 を各10本にそろえた

■ 始める前の確かめ
依頼箱/記録.log に「2026-11-09T13:16:19 完了 20261109_130_位置4を教え直した記録をTEACH_FILESに足す.md」がある（commit 5ae9f10）。実機は動かしていない。

■ 1. 新しい本だけのデータセット mecharm_redblock_box_teach_pos1to4_deep_v1
python3 pi05/build_demo_episodes.py --dataset mecharm_redblock_box_teach_pos1to4_deep_v1 --trim-mid-idle --max-protrude-px 24 --run（依頼の31本）
採用エピソード合計: 31  総ステップ: 4387
[DEPTH] 線 24px: 測った 31 本 / 浅くて外した 0 本 / 測れなかった 0 本 (外していない) / 手が写っていそう 2 本 (外していない)
        手が写っていそう: run_0001_20261109_103943  (画で確かめること)
        手が写っていそう: run_0001_20261109_104517  (画で確かめること)
- 外れた本 0・測れなかった本 0 なので、どの位置も10本を割らない。
- 手が写っていそうな2本（どちらも位置2）：引っかかったのは「閉じる1.5秒前」のコマだけ（237.8px・237.7px。0.5秒前と直前は 24.2px・22.1px で普通）。top.mp4 の閉じる2.0秒前・1.5秒前・1.0秒前のコマ（103943 はコマ 514・529・544、104517 はコマ 503・518・533）を全体の画で見たが、人の手・指は写っていなかった。赤いケーブルを拾った値とみられる。DEEP_DEMOS 3. のとおり外していない（merge の --exclude-json にも書いていない）。閉じたあとのはみ出しは −7.8px・−7.7px（深い）、爪の値は最大 841・840（つかめている）。

■ 2. 位置ごとの本数（count_by_position.py mecharm_redblock_box_teach_v1_trim2_corr_v5_deep mecharm_redblock_box_teach_pos1to4_deep_v1）
| 位置 | 本数 | 教えた動き | 補正入り | 目標 10 本まで | 浅くて外した | 手で外した | 入っている本で手が写っていそう |
| 位置 1 | 10 | 10 | 0 | +0 | 1 | 0 | 0 |
| 位置 2 | 10 | 10 | 0 | +0 | 0 | 2 | 2 |
| 位置 3 | 11 | 11 | 0 | +0 | 2 | 0 | 0 |
| 位置 4 | 10 | 10 | 0 | +0 | 0 | 0 | 0 |
| 位置 5 | 11 | 4 | 7 | +0 | 4 | 0 | 0 |
| 分からない | 0 | 0 | 0 | — | 0 | 0 | 0 |
| 合計 | 52 | 45 | 7 | +0 | 7 | 2 | 2 |
見込み（1=10・2=10・3=11・4=10・5=11）どおり。「分からない」0。

■ 3. 10本を超えた位置から外した本（grasp_depth.py の「閉じて1.0秒後のはみ出し」。同じ値の本はなかった）
位置3（11本）の値：192438 17.9・192539 12.7・123756 21.8・123848 9.5・124032 20.4・124117 2.7・124207 18.1・124256 4.5・124438 −2.1・124817 −0.6・124920 2.2 px
  → 外した本：run_0001_20261109_123756（21.8px。閉じる直前 44.5px）
位置5（11本）の値：194818 15.3・194913 8.3・195023 13.1・195120 12.7（教えた動き）、pi05_20261031_175527 −19.4・180435 20.2・184016 15.9・20261101_190347 14.1・190854 21.4・20261106_183926 14.1・184650 19.8 px（補正入り）
  → 外した本：pi05_20261101_190854（21.4px。閉じる直前 47.0px。補正入り）
書いた先：pi05/excludes/deep_even10_v1.json（理由の文「位置ごとの本数を10本にそろえるため、その位置でいちばん浅い本を外した（エイイチの決め 2026-11-09）」・位置・値・測った grasp_depth の中身）
※ 192438・192539 の値は DEEP_DEMOS.md の表（依頼113 G）の 17.9・12.7 と同じ。

■ 4. まとめたデータセット mecharm_redblock_box_deep_even10_v1
python3 pi05/merge_raw_episodes.py --src mecharm_redblock_box_teach_v1_trim2_corr_v5_deep --src mecharm_redblock_box_teach_pos1to4_deep_v1 --dataset mecharm_redblock_box_deep_even10_v1 --exclude-json pi05/excludes/deep_even10_v1.json --tar
- エピソード数：50 本 / 7128 コマ（今の deep から 20 本 / 2873 コマ・うち補正 224、新しい本から 30 本 / 4255 コマ）
- README の最後の位置ごとの表：
| 位置 | 本数 | 教えた動き | 補正入り | 目標 10 本まで | 浅くて外した | 手で外した | 入っている本で手が写っていそう |
| 位置 1 | 10 | 10 | 0 | +0 | 0 | 0 | — |
| 位置 2 | 10 | 10 | 0 | +0 | 0 | 0 | — |
| 位置 3 | 10 | 10 | 0 | +0 | 0 | 0 | — |
| 位置 4 | 10 | 10 | 0 | +0 | 0 | 0 | — |
| 位置 5 | 10 | 4 | 6 | +0 | 0 | 0 | — |
| 分からない | 0 | 0 | 0 | — | 0 | 0 | — |
| 合計 | 50 | 44 | 6 | +0 | 0 | 0 | — |
  全部10本・目標まで ＋0。
- tar：/Volumes/KIOXIA/r2r2r-data/datasets/mecharm_redblock_box_deep_even10_v1/mecharm_redblock_box_deep_even10_v1_raw_episodes.tar（193,353,728 バイト・193 MB）
- 元のデータセット（..._corr_v5_deep・..._pos1to4_deep_v1）は変えていない。

■ 5. check_dataset.py
python3 pi05/check_dataset.py /Volumes/KIOXIA/r2r2r-data/datasets/mecharm_redblock_box_deep_even10_v1/raw_episodes
[RESULT] 1.PASS  2.PASS  3.PASS  4.PASS  5.PASS  6.PASS / 全項目 PASS
（j1 の最大 +87.89°・グリッパー 50 本すべて 閉→開・つかんだ瞬間の j0 は 5 つの山に 10 本ずつ（−30° 付近 1 本・−25° 付近 9 本は同じ位置）・action と state の差の最大 0.00°）

■ commit
50f71f3（pi05/excludes/deep_even10_v1.json の 1 ファイルだけを指定して add）

■ 決めてほしいこと
なし（手が写っていそうと出た位置2の2本は、画で手が見えなかったので入れたまま。外すなら位置2が8本になるので撮り足しが要る）

判定：合格
```

### 外した2本の一覧（r2r2r-scripts/pi05/excludes/deep_even10_v1.json）

```json
{
  "run_0001_20261109_123756": {
    "reason": "位置ごとの本数を10本にそろえるため、その位置でいちばん浅い本を外した（エイイチの決め 2026-11-09）",
    "kind": "教えた動き",
    "position": 3,
    "after_px": 21.8,
    "before_px": 44.5,
    "rule": "その位置の本の中で閉じて 1.0 秒後のはみ出しがいちばん大きい本 (同じ値なら古い本) を外す. 依頼 131",
    "measured_by": "pi05/grasp_depth.py (2026-11-09 依頼 131)",
    "grasp_depth": {
      "status": "ok",
      "t_close": 1794195495.641,
      "frame_before": 562,
      "frame_after": 593,
      "before_px": 44.5,
      "after_px": 21.8,
      "after_gap_px": 99.9,
      "hand_suspect": false,
      "center_by": "wide",
      "axis_from": "body",
      "max_protrude_px": 24.0,
      "shallow": false,
      "pre_px": {
        "pre1.5s": -24.2,
        "pre0.5s": 44.4,
        "before": 44.5
      },
      "center_px": [
        714,
        642
      ]
    }
  },
  "pi05_20261101_190854": {
    "reason": "位置ごとの本数を10本にそろえるため、その位置でいちばん浅い本を外した（エイイチの決め 2026-11-09）",
    "kind": "補正入り",
    "position": 5,
    "after_px": 21.4,
    "before_px": 47.0,
    "rule": "その位置の本の中で閉じて 1.0 秒後のはみ出しがいちばん大きい本 (同じ値なら古い本) を外す. 依頼 131",
    "measured_by": "pi05/grasp_depth.py (2026-11-09 依頼 131)",
    "grasp_depth": {
      "status": "ok",
      "t_close": 1793527814.91,
      "frame_before": 696,
      "frame_after": 706,
      "before_px": 47.0,
      "after_px": 21.4,
      "after_gap_px": 100.3,
      "hand_suspect": false,
      "center_by": "E",
      "axis_from": "body",
      "max_protrude_px": 24.0,
      "shallow": false,
      "pre_px": {
        "pre1.5s": 47.0,
        "pre0.5s": 48.0,
        "before": 47.0
      },
      "center_px": [
        1147,
        688
      ]
    }
  }
}
```

### できたデータの説明（datasets/mecharm_redblock_box_deep_even10_v1/README.md）

```markdown
# mecharm_redblock_box_deep_even10_v1

いくつかの raw_episodes を 1 つにまとめたデータセット (元は読むだけ。写しを置く)。

- 作成: `python3 pi05/merge_raw_episodes.py --src mecharm_redblock_box_teach_v1_trim2_corr_v5_deep --src mecharm_redblock_box_teach_pos1to4_deep_v1 --dataset mecharm_redblock_box_deep_even10_v1 --exclude-json deep_even10_v1.json`
- LeRobot に変換するときの repo_id: `local/mecharm_redblock_box_deep_even10_v1`

合計 50 本 / 7128 コマ

| 元 | 本数 | コマ | うち補正 (correct) |
| --- | --- | --- | --- |
| mecharm_redblock_box_teach_v1_trim2_corr_v5_deep | 20 | 2873 | 224 |
| mecharm_redblock_box_teach_pos1to4_deep_v1 | 30 | 4255 | 0 |

## 外した本 (2 本. `index.json` の `excluded`)

| エピソード | 元 | コマ | 理由 |
| --- | --- | --- | --- |
| run_0001_20261109_123756 | mecharm_redblock_box_teach_pos1to4_deep_v1 | 132 | 位置ごとの本数を10本にそろえるため、その位置でいちばん浅い本を外した（エイイチの決め 2026-11-09） |
| pi05_20261101_190854 | mecharm_redblock_box_teach_v1_trim2_corr_v5_deep | 145 | 位置ごとの本数を10本にそろえるため、その位置でいちばん浅い本を外した（エイイチの決め 2026-11-09） |

## 置き場所ごとの本数 (`pi05/count_by_position.py`。依頼 118)

教えた動きは `teach/` の教えた記録のファイル名 (LOG352 の表) で、補正入りは上カメラで見つけたブロックの位置をいちばん近い教えた位置に割り当てた (30mm を超えたら「分からない」)。「浅くて外した」「手で外した」は、このデータセットの `index.json` で外したエピソードの数 (データには入っていない)。

| 位置 | 本数 | 教えた動き | 補正入り | 目標 10 本まで | 浅くて外した | 手で外した | 入っている本で手が写っていそう |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 位置 1 | 10 | 10 | 0 | +0 | 0 | 0 | — |
| 位置 2 | 10 | 10 | 0 | +0 | 0 | 0 | — |
| 位置 3 | 10 | 10 | 0 | +0 | 0 | 0 | — |
| 位置 4 | 10 | 10 | 0 | +0 | 0 | 0 | — |
| 位置 5 | 10 | 4 | 6 | +0 | 0 | 0 | — |
| 分からない | 0 | 0 | 0 | — | 0 | 0 | — |
| 合計 | 50 | 44 | 6 | +0 | 0 | 0 | — |

- 入っている本の「手が写っていそう」は測っていない (`--measure-depth` で測る)
```


## 端末の出力（全量）

Mac の端末1つで、measure・ドライラン・再生と記録・ゲームパッド・重ねて置く画面を順に動かしました。12:04 から 13:11 までの全量です。recorder を動かしていた別の端末の出力は残していません。

### 端末（12:04〜13:11・measure・再生と記録・ゲームパッド・camera_align）

```text
Last login: Mon Nov  9 12:04:46 on ttys005
(base) shimazueiichi@shimadzueiichinoMacBook-Pro ~ % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py measure
python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20221013_231249.json
python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20221013_231249.json --execute
python3: can't open file '/Users/shimazueiichi/dynamic_tracking_limits/drag_teaching/record_teach_demo.py': [Errno 2] No such file or directory
python3: can't open file '/Users/shimazueiichi/dynamic_tracking_limits/drag_teaching/record_teach_demo.py': [Errno 2] No such file or directory
python3: can't open file '/Users/shimazueiichi/dynamic_tracking_limits/drag_teaching/record_teach_demo.py': [Errno 2] No such file or directory
(base) shimazueiichi@shimadzueiichinoMacBook-Pro ~ % cd ~/r2r2r-scripts
python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py measure
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] measure: 上カメラで検出します（repeat=5 interval=0.3s）
[CAM] 接続中カメラ一覧:
  index=0  name=FaceTime HDカメラ
  index=1  name=Iriun Camera
  index=2  name=‎iPhone14 Pro MAXのカメラ
[CAM] 上カメラ(iPhone)  index=2
[CAM] 横カメラ(Iriun)   index=1
[DETECT] resolved top index: 2
[Mac] マット四隅検出中... (10フレーム)
[Mac] ✓ マット四隅検出: 10/10 フレーム成功
[Mac] ✓ 動的homography計算完了
[Mac] ✓ マット範囲: X=[304, 1701] Y=[0, 948]
[06f] TEMPLATES_DIR overridden to: /Users/shimazueiichi/r2r2r-scripts/dynamic_tracking_limits/place/templates
[06f] ROTATION_ANGLES_DEG overridden to: [0, 15, 30, 45, 60, 75]
[06f] SCALES overridden to: [0.85, 1.0, 1.15]
[テンプレ] loading white box templates from: /Users/shimazueiichi/r2r2r-scripts/dynamic_tracking_limits/place/templates
[テンプレ] glob '/Users/shimazueiichi/r2r2r-scripts/dynamic_tracking_limits/place/templates/*.png' → 8 file(s)
[テンプレ]   - white_box_20260520_163829_004.png
[テンプレ]   - white_box_20260520_163838_005.png
[テンプレ]   - white_box_20260520_163846_006.png
[テンプレ]   - white_box_20260520_163905_009.png
[テンプレ]   - white_box_20260520_163912_010.png
[テンプレ]   - white_box_20260520_163918_011.png
[テンプレ]   - white_box_20260520_163923_012.png
[テンプレ]   - white_box_20260520_163929_013.png
[テンプレ] 計 8 枚 (day165=8, auto=0)
[06f] WARN: 輪郭中心とテンプレ中心の距離が閾値超 |Δ|=102.5px > 60px → 輪郭捨てて fallback
[06f] DETECT: center=(1489,553) source=template_fallback score=0.647 angle=0° scale=1.15 size=(226x211) template=white_box_20260520_163838_005.png (eval 5.54s)
[DETECT][1/5] box Unity=(-0.218,+0.182) score=0.6472325325012207
  赤ブロック pixel=(723, 682) → Unity=(0.1279, 0.2394)
[DETECT][1/5] block Unity=(+0.128,+0.239) score=null
[06f] WARN: 輪郭中心とテンプレ中心の距離が閾値超 |Δ|=102.2px > 60px → 輪郭捨てて fallback
[06f] DETECT: center=(1489,553) source=template_fallback score=0.648 angle=0° scale=1.15 size=(226x211) template=white_box_20260520_163838_005.png (eval 5.45s)
[DETECT][2/5] box Unity=(-0.218,+0.182) score=0.6475574374198914
  赤ブロック pixel=(724, 683) → Unity=(0.1275, 0.2399)
[DETECT][2/5] block Unity=(+0.127,+0.240) score=null
[06f] WARN: 輪郭中心とテンプレ中心の距離が閾値超 |Δ|=102.5px > 60px → 輪郭捨てて fallback
[06f] DETECT: center=(1489,554) source=template_fallback score=0.647 angle=0° scale=1.15 size=(226x211) template=white_box_20260520_163838_005.png (eval 5.73s)
[DETECT][3/5] box Unity=(-0.218,+0.183) score=0.6469919085502625
  赤ブロック pixel=(724, 682) → Unity=(0.1274, 0.2394)
[DETECT][3/5] block Unity=(+0.127,+0.239) score=null
[06f] WARN: 輪郭中心とテンプレ中心の距離が閾値超 |Δ|=102.5px > 60px → 輪郭捨てて fallback
[06f] DETECT: center=(1489,554) source=template_fallback score=0.647 angle=0° scale=1.15 size=(226x211) template=white_box_20260520_163838_005.png (eval 5.21s)
[DETECT][4/5] box Unity=(-0.218,+0.183) score=0.6472181081771851
  赤ブロック pixel=(723, 683) → Unity=(0.1279, 0.2399)
[DETECT][4/5] block Unity=(+0.128,+0.240) score=null
[06f] WARN: 輪郭中心とテンプレ中心の距離が閾値超 |Δ|=102.8px > 60px → 輪郭捨てて fallback
[06f] DETECT: center=(1490,554) source=template_fallback score=0.647 angle=0° scale=1.15 size=(226x211) template=white_box_20260520_163838_005.png (eval 5.25s)
[DETECT][5/5] box Unity=(-0.219,+0.183) score=0.6470634937286377
  赤ブロック pixel=(724, 683) → Unity=(0.1275, 0.2399)
[DETECT][5/5] block Unity=(+0.127,+0.240) score=null
[RTD   ] measure: block = (+127.5, +239.9) mm
[RTD   ] measure: box   = (-218.3, +183.0) mm  score=0.6472181081771851
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_120729.jpg
[RTD   ] homography のもとになった四隅と、測り直した四隅の差: 最大 1.56px（上限 15.0px・やり直し 1 回）
[RTD   ] ブロックのばらつき: 1.0px = 0.47mm（5 枚・上限 4.0mm）
[RTD   ] 元の検出と測り直しの差: 0.47mm（上限 3.0mm）
[RTD   ] 保存しました: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_120729.json
[RTD   ] 次は Pi で教示 → daemon 起動 → recorder.py --top --no-side 常駐 → run --teach <file> --execute
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20221013_231249.json
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: ドライラン（アームに何も送りません）
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20221013_231249.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_1m9msi0m/drag_v2_20221013_231249.json
[RTD   ] 入力ファイル: drag_v2_20221013_231249.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=146 (start=146 end=194, gap=12.04°)
                    angles = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
  PICK           <- gripper close mark idx=214（PICK phase 範囲内）
                    angles = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=286 (start=286 end=321, gap=20.83°)
                    angles = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
  PLACE          <- gripper open mark idx=345（PLACE phase 範囲内）
                    angles = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 137 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 18.20°（しきい値 3.0° 以上）
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = 未取得（ドライラン・daemon に接続していない）
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            max |Δ| = 71.80°  1 回送信 speed=20  (~ 3.6s @ 20°/s 目安・到達待ち 最大 12.8s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            to      = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
            max |Δ| = 12.04°  1 回送信 speed=20  (~ 0.6s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
            to      = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            max |Δ| = 12.04°  1 回送信 speed=20  (~ 0.6s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 69.16°  1 回送信 speed=20  (~ 3.5s @ 20°/s 目安・到達待ち 最大 12.4s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 49.39°  1 回送信 speed=20  (~ 2.5s @ 20°/s 目安・到達待ち 最大 9.4s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 29.8s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 12.8s（max|Δ| 合計 256.1° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_120729.json
[RTD   ]   measured_at = 2026-11-09T12:07:31.373791  block = (+127.5, +239.9) mm  box = (-218.3, +183.0) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] 再生直前: block = (+127.4, +239.4) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_120752.jpg
[RTD   ] ブロック位置の照合 OK（画素の差 1.0px <= 許容 10.5px = 5.0mm / mm 換算の差 0.47mm）
[RTD   ] マット四隅のずれ 最大 1.4px（上限 15.0px・やり直し 1 回）
[RTD   ] ドライランなので、ここで終了します（アームには何も送っていません）
[RTD   ] Pi 版と比べる点: 抽出ウェイポイント 4 姿勢と各区間の max|Δ| は同じ。送り方は単発（Pi 版は 0.1s 補間ストリーミング）なので n_steps / ticks は比較対象外。送信 8 回 / 想定所要 ≈ 29.8s
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20221013_231249.json --execute
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20221013_231249.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_nzrpmtyh/drag_v2_20221013_231249.json
[RTD   ] 入力ファイル: drag_v2_20221013_231249.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=146 (start=146 end=194, gap=12.04°)
                    angles = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
  PICK           <- gripper close mark idx=214（PICK phase 範囲内）
                    angles = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=286 (start=286 end=321, gap=20.83°)
                    angles = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
  PLACE          <- gripper open mark idx=345（PLACE phase 範囲内）
                    angles = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 137 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 18.20°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  +0.17,   +1.49,   +0.79,   -0.17,   -0.26,  -30.23]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  +0.17,   +1.49,   +0.79,   -0.17,   -0.26,  -30.23]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 1.49°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            max |Δ| = 71.80°  1 回送信 speed=20  (~ 3.6s @ 20°/s 目安・到達待ち 最大 12.8s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            to      = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
            max |Δ| = 12.04°  1 回送信 speed=20  (~ 0.6s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
            to      = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            max |Δ| = 12.04°  1 回送信 speed=20  (~ 0.6s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 69.16°  1 回送信 speed=20  (~ 3.5s @ 20°/s 目安・到達待ち 最大 12.4s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 49.39°  1 回送信 speed=20  (~ 2.5s @ 20°/s 目安・到達待ち 最大 9.4s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 29.8s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 12.8s（max|Δ| 合計 256.1° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_120729.json
[RTD   ]   measured_at = 2026-11-09T12:07:31.373791  block = (+127.5, +239.9) mm  box = (-218.3, +183.0) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] 再生直前: block = (+127.4, +239.4) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_120813.jpg
[RTD   ] ブロック位置の照合 OK（画素の差 1.0px <= 許容 10.5px = 5.0mm / mm 換算の差 0.47mm）
[RTD   ] マット四隅のずれ 最大 1.1px（上限 15.0px・やり直し 1 回）
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_120818
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_120818/teach/drag_v2_20221013_231249.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_120818/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 1.49° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=1.49° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.015s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 12.8s)
[RTD   ] 送信 OK（daemon 往復 1.021s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.14° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.043s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=1.93° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.013s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.030s）
[RTD   ] arrival OK (PICK → APPROACH_PICK (lift), max|Δ|=2.29° <= tol 3.0°)
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 12.4s)
[RTD   ] 送信 OK（daemon 往復 1.055s）
[RTD   ] arrival OK (APPROACH_PICK → APPROACH_PLACE, max|Δ|=2.81° <= tol 3.0°)
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.030s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=1.76° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.004s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.040s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.72° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 9.4s)
[RTD   ] 送信 OK（daemon 往復 1.058s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.46° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 58/58 回, 実効 1.61 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（1.61 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.039s / p50 1.040s / 最大 1.058s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.058s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 2.36s / 最大 4.64s
[RECORD] 電流の記録終了 77 行 (2.14 行/秒. 本体が眠っている間だけ読む. 爪の間 14.05 秒は読まない. 見込み超え 0 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_120818/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > y
[RTD   ] 箱に入ったか (y/n) > y
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_120818/run_0001_20261109_120818.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=yes place=yes recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_120818 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20221013_231249.json --execute
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20221013_231249.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_z9apcvd5/drag_v2_20221013_231249.json
[RTD   ] 入力ファイル: drag_v2_20221013_231249.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=146 (start=146 end=194, gap=12.04°)
                    angles = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
  PICK           <- gripper close mark idx=214（PICK phase 範囲内）
                    angles = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=286 (start=286 end=321, gap=20.83°)
                    angles = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
  PLACE          <- gripper open mark idx=345（PLACE phase 範囲内）
                    angles = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 137 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 18.20°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  -0.43,   +1.49,   +1.75,   +0.00,   -0.26,  -30.23]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  -0.43,   +1.49,   +1.75,   +0.00,   -0.26,  -30.23]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 1.75°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            max |Δ| = 71.80°  1 回送信 speed=20  (~ 3.6s @ 20°/s 目安・到達待ち 最大 12.8s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            to      = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
            max |Δ| = 12.04°  1 回送信 speed=20  (~ 0.6s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
            to      = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            max |Δ| = 12.04°  1 回送信 speed=20  (~ 0.6s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 69.16°  1 回送信 speed=20  (~ 3.5s @ 20°/s 目安・到達待ち 最大 12.4s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 49.39°  1 回送信 speed=20  (~ 2.5s @ 20°/s 目安・到達待ち 最大 9.4s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 29.8s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 12.8s（max|Δ| 合計 256.1° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_120729.json
[RTD   ]   measured_at = 2026-11-09T12:07:31.373791  block = (+127.5, +239.9) mm  box = (-218.3, +183.0) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] 再生直前: block = (+153.9, +233.3) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_121012.jpg
[RTD   ] [WARN] ブロックが measure 時から動いています（止めません・項目8）: ブロックが measure 時から 61.4px（≒27.2mm）動いています（許容 10.5px = 5.0mm）。ブロックを戻すか measure をやり直してください
[RTD   ] [WARN]   画素の差 61.4px（許容 10.5px = 5.0mm）/ mm 換算の差 27.23mm
[RTD   ] [WARN]   つかみ損ねる可能性があります。気になるなら Enter の前に measure を取り直してください
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121128
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121128/teach/drag_v2_20221013_231249.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121128/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 1.75° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=1.75° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.014s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 12.8s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.32° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.022s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=1.85° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.012s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.049s）
[RTD   ] arrival OK (PICK → APPROACH_PICK (lift), max|Δ|=2.81° <= tol 3.0°)
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 12.4s)
[RTD   ] 送信 OK（daemon 往復 1.032s）
[RTD   ] arrival OK (APPROACH_PICK → APPROACH_PLACE, max|Δ|=2.55° <= tol 3.0°)
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.032s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=1.93° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.017s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.046s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.72° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 9.4s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.28° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 60/60 回, 実効 1.65 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（1.65 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.035s / p50 1.032s / 最大 1.049s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.049s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 2.43s / 最大 4.43s
[RECORD] 電流の記録終了 81 行 (2.22 行/秒. 本体が眠っている間だけ読む. 爪の間 14.054 秒は読まない. 見込み超え 0 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121128/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > y
[RTD   ] 箱に入ったか (y/n) > y
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121128/run_0001_20261109_121128.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=yes place=yes recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_121128 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20221013_231249.json --execute
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20221013_231249.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_9axsa31m/drag_v2_20221013_231249.json
[RTD   ] 入力ファイル: drag_v2_20221013_231249.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=146 (start=146 end=194, gap=12.04°)
                    angles = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
  PICK           <- gripper close mark idx=214（PICK phase 範囲内）
                    angles = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=286 (start=286 end=321, gap=20.83°)
                    angles = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
  PLACE          <- gripper open mark idx=345（PLACE phase 範囲内）
                    angles = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 137 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 18.20°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  -0.43,   +1.49,   +1.75,   +0.00,   -0.26,  -30.23]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  -0.43,   +1.49,   +1.75,   +0.00,   -0.26,  -30.23]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 1.75°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            max |Δ| = 71.80°  1 回送信 speed=20  (~ 3.6s @ 20°/s 目安・到達待ち 最大 12.8s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            to      = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
            max |Δ| = 12.04°  1 回送信 speed=20  (~ 0.6s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
            to      = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            max |Δ| = 12.04°  1 回送信 speed=20  (~ 0.6s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 69.16°  1 回送信 speed=20  (~ 3.5s @ 20°/s 目安・到達待ち 最大 12.4s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 49.39°  1 回送信 speed=20  (~ 2.5s @ 20°/s 目安・到達待ち 最大 9.4s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 29.8s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 12.8s（max|Δ| 合計 256.1° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_120729.json
[RTD   ]   measured_at = 2026-11-09T12:07:31.373791  block = (+127.5, +239.9) mm  box = (-218.3, +183.0) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] 再生直前: block = (+135.4, +237.4) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_121219.jpg
[RTD   ] [WARN] ブロックが measure 時から動いています（止めません・項目8）: ブロックが measure 時から 18.7px（≒8.3mm）動いています（許容 10.5px = 5.0mm）。ブロックを戻すか measure をやり直してください
[RTD   ] [WARN]   画素の差 18.7px（許容 10.5px = 5.0mm）/ mm 換算の差 8.31mm
[RTD   ] [WARN]   つかみ損ねる可能性があります。気になるなら Enter の前に measure を取り直してください
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121224
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121224/teach/drag_v2_20221013_231249.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121224/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 1.75° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=1.75° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.014s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 12.8s)
[RTD   ] 送信 OK（daemon 往復 1.041s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.23° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.032s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=1.93° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.013s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.029s）
[RTD   ] arrival OK (PICK → APPROACH_PICK (lift), max|Δ|=2.29° <= tol 3.0°)
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 12.4s)
[RTD   ] 送信 OK（daemon 往復 1.029s）
[RTD   ] arrival OK (APPROACH_PICK → APPROACH_PLACE, max|Δ|=2.99° <= tol 3.0°)
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=1.76° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.013s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.056s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.55° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 9.4s)
[RTD   ] 送信 OK（daemon 往復 1.039s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.28° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 59/59 回, 実効 1.64 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（1.64 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.037s / p50 1.032s / 最大 1.056s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.056s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 2.38s / 最大 4.66s
[RECORD] 電流の記録終了 79 行 (2.19 行/秒. 本体が眠っている間だけ読む. 爪の間 14.052 秒は読まない. 見込み超え 0 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121224/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > y
[RTD   ] 箱に入ったか (y/n) > y
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121224/run_0001_20261109_121224.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=yes place=yes recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_121224 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20221013_231249.json --execute
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20221013_231249.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_53m4i4bn/drag_v2_20221013_231249.json
[RTD   ] 入力ファイル: drag_v2_20221013_231249.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=146 (start=146 end=194, gap=12.04°)
                    angles = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
  PICK           <- gripper close mark idx=214（PICK phase 範囲内）
                    angles = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=286 (start=286 end=321, gap=20.83°)
                    angles = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
  PLACE          <- gripper open mark idx=345（PLACE phase 範囲内）
                    angles = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 137 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 18.20°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  -0.43,   +1.49,   +1.75,   +0.08,   -0.26,  -30.23]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  -0.43,   +1.49,   +1.75,   +0.08,   -0.26,  -30.23]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 1.75°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            max |Δ| = 71.80°  1 回送信 speed=20  (~ 3.6s @ 20°/s 目安・到達待ち 最大 12.8s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            to      = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
            max |Δ| = 12.04°  1 回送信 speed=20  (~ 0.6s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
            to      = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            max |Δ| = 12.04°  1 回送信 speed=20  (~ 0.6s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 69.16°  1 回送信 speed=20  (~ 3.5s @ 20°/s 目安・到達待ち 最大 12.4s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 49.39°  1 回送信 speed=20  (~ 2.5s @ 20°/s 目安・到達待ち 最大 9.4s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 29.8s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 12.8s（max|Δ| 合計 256.1° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_120729.json
[RTD   ]   measured_at = 2026-11-09T12:07:31.373791  block = (+127.5, +239.9) mm  box = (-218.3, +183.0) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] 再生直前: block = (+130.5, +236.1) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_121316.jpg
[RTD   ] [WARN] ブロックが measure 時から動いています（止めません・項目8）: ブロックが measure 時から 10.6px（≒4.9mm）動いています（許容 10.5px = 5.0mm）。ブロックを戻すか measure をやり直してください
[RTD   ] [WARN]   画素の差 10.6px（許容 10.5px = 5.0mm）/ mm 換算の差 4.90mm
[RTD   ] [WARN]   つかみ損ねる可能性があります。気になるなら Enter の前に measure を取り直してください
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121320
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121320/teach/drag_v2_20221013_231249.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121320/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 1.75° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=1.75° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.013s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 12.8s)
[RTD   ] 送信 OK（daemon 往復 1.030s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.32° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=1.85° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.012s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.030s）
[RTD   ] arrival OK (PICK → APPROACH_PICK (lift), max|Δ|=2.29° <= tol 3.0°)
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 12.4s)
[RTD   ] 送信 OK（daemon 往復 1.037s）
[RTD   ] arrival OK (APPROACH_PICK → APPROACH_PLACE, max|Δ|=2.90° <= tol 3.0°)
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.032s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=1.76° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.013s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.054s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.64° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 9.4s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.37° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 58/58 回, 実効 1.62 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（1.62 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.035s / p50 1.031s / 最大 1.054s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.054s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 2.34s / 最大 4.37s
[RECORD] 電流の記録終了 77 行 (2.16 行/秒. 本体が眠っている間だけ読む. 爪の間 14.048 秒は読まない. 見込み超え 0 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121320/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > y
[RTD   ] 箱に入ったか (y/n) > y
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121320/run_0001_20261109_121320.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=yes place=yes recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_121320 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20221013_231249.json --execute
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20221013_231249.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_2pa2_2i3/drag_v2_20221013_231249.json
[RTD   ] 入力ファイル: drag_v2_20221013_231249.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=146 (start=146 end=194, gap=12.04°)
                    angles = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
  PICK           <- gripper close mark idx=214（PICK phase 範囲内）
                    angles = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=286 (start=286 end=321, gap=20.83°)
                    angles = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
  PLACE          <- gripper open mark idx=345（PLACE phase 範囲内）
                    angles = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 137 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 18.20°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  -0.43,   +1.49,   +1.75,   +0.00,   -0.26,  -30.23]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  -0.43,   +1.49,   +1.75,   +0.00,   -0.26,  -30.23]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 1.75°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            max |Δ| = 71.80°  1 回送信 speed=20  (~ 3.6s @ 20°/s 目安・到達待ち 最大 12.8s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            to      = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
            max |Δ| = 12.04°  1 回送信 speed=20  (~ 0.6s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
            to      = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            max |Δ| = 12.04°  1 回送信 speed=20  (~ 0.6s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 69.16°  1 回送信 speed=20  (~ 3.5s @ 20°/s 目安・到達待ち 最大 12.4s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 49.39°  1 回送信 speed=20  (~ 2.5s @ 20°/s 目安・到達待ち 最大 9.4s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 29.8s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 12.8s（max|Δ| 合計 256.1° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_120729.json
[RTD   ]   measured_at = 2026-11-09T12:07:31.373791  block = (+127.5, +239.9) mm  box = (-218.3, +183.0) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] 再生直前: block = (+133.5, +226.5) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_121413.jpg
[RTD   ] [WARN] ブロックが measure 時から動いています（止めません・項目8）: ブロックが measure 時から 31.3px（≒14.7mm）動いています（許容 10.5px = 5.0mm）。ブロックを戻すか measure をやり直してください
[RTD   ] [WARN]   画素の差 31.3px（許容 10.5px = 5.0mm）/ mm 換算の差 14.67mm
[RTD   ] [WARN]   つかみ損ねる可能性があります。気になるなら Enter の前に measure を取り直してください
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121416
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121416/teach/drag_v2_20221013_231249.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121416/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 1.75° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=1.75° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.015s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 12.8s)
[RTD   ] 送信 OK（daemon 往復 1.048s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.32° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=1.85° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.011s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.029s）
[RTD   ] arrival OK (PICK → APPROACH_PICK (lift), max|Δ|=2.29° <= tol 3.0°)
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 12.4s)
[RTD   ] 送信 OK（daemon 往復 1.055s）
[RTD   ] arrival OK (APPROACH_PICK → APPROACH_PLACE, max|Δ|=2.55° <= tol 3.0°)
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.032s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=2.02° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.013s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.032s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.99° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 9.4s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.28° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 60/60 回, 実効 1.65 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（1.65 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.037s / p50 1.032s / 最大 1.055s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.055s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 2.42s / 最大 4.38s
[RECORD] 電流の記録終了 81 行 (2.23 行/秒. 本体が眠っている間だけ読む. 爪の間 14.053 秒は読まない. 見込み超え 0 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121416/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > y
[RTD   ] 箱に入ったか (y/n) > y
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121416/run_0001_20261109_121416.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=yes place=yes recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_121416 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20221013_231249.json --execute
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20221013_231249.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_ba2f9hiv/drag_v2_20221013_231249.json
[RTD   ] 入力ファイル: drag_v2_20221013_231249.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=146 (start=146 end=194, gap=12.04°)
                    angles = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
  PICK           <- gripper close mark idx=214（PICK phase 範囲内）
                    angles = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=286 (start=286 end=321, gap=20.83°)
                    angles = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
  PLACE          <- gripper open mark idx=345（PLACE phase 範囲内）
                    angles = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 137 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 18.20°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  -0.43,   +1.49,   +1.75,   +0.08,   -0.26,  -30.23]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  -0.43,   +1.49,   +1.75,   +0.08,   -0.26,  -30.23]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 1.75°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            max |Δ| = 71.80°  1 回送信 speed=20  (~ 3.6s @ 20°/s 目安・到達待ち 最大 12.8s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            to      = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
            max |Δ| = 12.04°  1 回送信 speed=20  (~ 0.6s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
            to      = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            max |Δ| = 12.04°  1 回送信 speed=20  (~ 0.6s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 69.16°  1 回送信 speed=20  (~ 3.5s @ 20°/s 目安・到達待ち 最大 12.4s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 49.39°  1 回送信 speed=20  (~ 2.5s @ 20°/s 目安・到達待ち 最大 9.4s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 29.8s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 12.8s（max|Δ| 合計 256.1° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_120729.json
[RTD   ]   measured_at = 2026-11-09T12:07:31.373791  block = (+127.5, +239.9) mm  box = (-218.3, +183.0) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] 再生直前: block = (+128.4, +241.8) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_121507.jpg
[RTD   ] ブロック位置の照合 OK（画素の差 4.5px <= 許容 10.5px = 5.0mm / mm 換算の差 2.10mm）
[RTD   ] マット四隅のずれ 最大 2.2px（上限 15.0px・やり直し 1 回）
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121511
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121511/teach/drag_v2_20221013_231249.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121511/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 1.75° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=1.75° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.016s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 12.8s)
[RTD   ] 送信 OK（daemon 往復 1.032s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.40° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.056s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=1.85° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.010s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.028s）
[RTD   ] arrival OK (PICK → APPROACH_PICK (lift), max|Δ|=2.37° <= tol 3.0°)
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 12.4s)
[RTD   ] 送信 OK（daemon 往復 1.053s）
[RTD   ] arrival OK (APPROACH_PICK → APPROACH_PLACE, max|Δ|=2.55° <= tol 3.0°)
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.030s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=2.02° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.004s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.037s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.37° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 9.4s)
[RTD   ] 送信 OK（daemon 往復 1.043s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.37° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 57/57 回, 実効 1.61 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（1.61 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.040s / p50 1.037s / 最大 1.056s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.056s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 2.29s / 最大 4.41s
[RECORD] 電流の記録終了 75 行 (2.12 行/秒. 本体が眠っている間だけ読む. 爪の間 14.053 秒は読まない. 見込み超え 0 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121511/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > y
[RTD   ] 箱に入ったか (y/n) > y
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121511/run_0001_20261109_121511.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=yes place=yes recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_121511 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20221013_231249.json --execute
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20221013_231249.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_z7s9m0g_/drag_v2_20221013_231249.json
[RTD   ] 入力ファイル: drag_v2_20221013_231249.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=146 (start=146 end=194, gap=12.04°)
                    angles = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
  PICK           <- gripper close mark idx=214（PICK phase 範囲内）
                    angles = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=286 (start=286 end=321, gap=20.83°)
                    angles = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
  PLACE          <- gripper open mark idx=345（PLACE phase 範囲内）
                    angles = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 137 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 18.20°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  -0.43,   +1.49,   +1.75,   +0.08,   -0.26,  -30.23]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  -0.43,   +1.49,   +1.75,   +0.08,   -0.26,  -30.23]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 1.75°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            max |Δ| = 71.80°  1 回送信 speed=20  (~ 3.6s @ 20°/s 目安・到達待ち 最大 12.8s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            to      = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
            max |Δ| = 12.04°  1 回送信 speed=20  (~ 0.6s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
            to      = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            max |Δ| = 12.04°  1 回送信 speed=20  (~ 0.6s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 69.16°  1 回送信 speed=20  (~ 3.5s @ 20°/s 目安・到達待ち 最大 12.4s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 49.39°  1 回送信 speed=20  (~ 2.5s @ 20°/s 目安・到達待ち 最大 9.4s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 29.8s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 12.8s（max|Δ| 合計 256.1° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_120729.json
[RTD   ]   measured_at = 2026-11-09T12:07:31.373791  block = (+127.5, +239.9) mm  box = (-218.3, +183.0) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] 再生直前: block = (+136.2, +228.9) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_121600.jpg
[RTD   ] [WARN] ブロックが measure 時から動いています（止めません・項目8）: ブロックが measure 時から 30.5px（≒14.1mm）動いています（許容 10.5px = 5.0mm）。ブロックを戻すか measure をやり直してください
[RTD   ] [WARN]   画素の差 30.5px（許容 10.5px = 5.0mm）/ mm 換算の差 14.06mm
[RTD   ] [WARN]   つかみ損ねる可能性があります。気になるなら Enter の前に measure を取り直してください
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121605
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121605/teach/drag_v2_20221013_231249.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121605/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 1.75° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=1.75° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.013s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 12.8s)
[RTD   ] 送信 OK（daemon 往復 1.039s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.49° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.035s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=1.93° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.012s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.039s）
[RTD   ] arrival OK (PICK → APPROACH_PICK (lift), max|Δ|=2.46° <= tol 3.0°)
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 12.4s)
[RTD   ] 送信 OK（daemon 往復 1.030s）
[RTD   ] arrival OK (APPROACH_PICK → APPROACH_PLACE, max|Δ|=2.55° <= tol 3.0°)
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.032s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=2.11° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.013s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.044s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.64° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 9.4s)
[RTD   ] 送信 OK（daemon 往復 1.032s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.46° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 58/58 回, 実効 1.62 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（1.62 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.036s / p50 1.035s / 最大 1.044s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.044s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 2.34s / 最大 4.44s
[RECORD] 電流の記録終了 77 行 (2.16 行/秒. 本体が眠っている間だけ読む. 爪の間 14.059 秒は読まない. 見込み超え 0 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121605/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > y
[RTD   ] 箱に入ったか (y/n) > y
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121605/run_0001_20261109_121605.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=yes place=yes recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_121605 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20221013_231249.json --execute
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20221013_231249.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_6h81jhhb/drag_v2_20221013_231249.json
[RTD   ] 入力ファイル: drag_v2_20221013_231249.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=146 (start=146 end=194, gap=12.04°)
                    angles = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
  PICK           <- gripper close mark idx=214（PICK phase 範囲内）
                    angles = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=286 (start=286 end=321, gap=20.83°)
                    angles = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
  PLACE          <- gripper open mark idx=345（PLACE phase 範囲内）
                    angles = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 137 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 18.20°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  -0.43,   +1.49,   +1.93,   +0.08,   -0.26,  -30.23]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  -0.43,   +1.49,   +1.93,   +0.08,   -0.26,  -30.23]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 1.93°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            max |Δ| = 71.80°  1 回送信 speed=20  (~ 3.6s @ 20°/s 目安・到達待ち 最大 12.8s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            to      = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
            max |Δ| = 12.04°  1 回送信 speed=20  (~ 0.6s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
            to      = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            max |Δ| = 12.04°  1 回送信 speed=20  (~ 0.6s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 69.16°  1 回送信 speed=20  (~ 3.5s @ 20°/s 目安・到達待ち 最大 12.4s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 49.39°  1 回送信 speed=20  (~ 2.5s @ 20°/s 目安・到達待ち 最大 9.4s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 29.8s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 12.8s（max|Δ| 合計 256.1° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_120729.json
[RTD   ]   measured_at = 2026-11-09T12:07:31.373791  block = (+127.5, +239.9) mm  box = (-218.3, +183.0) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] 再生直前: block = (+131.9, +241.7) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_121656.jpg
[RTD   ] [WARN] ブロックが measure 時から動いています（止めません・項目8）: ブロックが measure 時から 10.8px（≒4.8mm）動いています（許容 10.5px = 5.0mm）。ブロックを戻すか measure をやり直してください
[RTD   ] [WARN]   画素の差 10.8px（許容 10.5px = 5.0mm）/ mm 換算の差 4.81mm
[RTD   ] [WARN]   つかみ損ねる可能性があります。気になるなら Enter の前に measure を取り直してください
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121659
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121659/teach/drag_v2_20221013_231249.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121659/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 1.93° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=1.93° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.016s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 12.8s)
[RTD   ] 送信 OK（daemon 往復 1.030s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.40° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.167s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=1.85° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.010s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.034s）
[RTD   ] arrival OK (PICK → APPROACH_PICK (lift), max|Δ|=2.37° <= tol 3.0°)
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 12.4s)
[RTD   ] 送信 OK（daemon 往復 1.030s）
[RTD   ] arrival OK (APPROACH_PICK → APPROACH_PLACE, max|Δ|=2.64° <= tol 3.0°)
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.040s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=2.11° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.014s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.029s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.72° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 9.4s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.28° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 60/60 回, 実効 1.65 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（1.65 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.052s / p50 1.031s / 最大 1.167s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.167s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 2.43s / 最大 4.42s
[RECORD] 電流の記録終了 81 行 (2.22 行/秒. 本体が眠っている間だけ読む. 爪の間 14.054 秒は読まない. 見込み超え 0 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121659/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > y
[RTD   ] 箱に入ったか (y/n) > y
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121659/run_0001_20261109_121659.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=yes place=yes recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_121659 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20221013_231249.json --execute
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20221013_231249.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_nnd1ylfz/drag_v2_20221013_231249.json
[RTD   ] 入力ファイル: drag_v2_20221013_231249.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=146 (start=146 end=194, gap=12.04°)
                    angles = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
  PICK           <- gripper close mark idx=214（PICK phase 範囲内）
                    angles = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=286 (start=286 end=321, gap=20.83°)
                    angles = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
  PLACE          <- gripper open mark idx=345（PLACE phase 範囲内）
                    angles = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 137 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 18.20°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  -0.43,   +1.49,   +1.75,   +0.08,   -0.26,  -30.23]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  -0.43,   +1.49,   +1.75,   +0.08,   -0.26,  -30.23]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 1.75°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            max |Δ| = 71.80°  1 回送信 speed=20  (~ 3.6s @ 20°/s 目安・到達待ち 最大 12.8s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            to      = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
            max |Δ| = 12.04°  1 回送信 speed=20  (~ 0.6s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -27.68,  +63.10,  +13.27,   -8.26,  -59.76,  -27.33]
            to      = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            max |Δ| = 12.04°  1 回送信 speed=20  (~ 0.6s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -28.12,  +57.21,  +19.86,   -3.60,  -71.80,  -27.50]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 69.16°  1 回送信 speed=20  (~ 3.5s @ 20°/s 目安・到達待ち 最大 12.4s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 49.39°  1 回送信 speed=20  (~ 2.5s @ 20°/s 目安・到達待ち 最大 9.4s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 29.8s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 12.8s（max|Δ| 合計 256.1° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_120729.json
[RTD   ]   measured_at = 2026-11-09T12:07:31.373791  block = (+127.5, +239.9) mm  box = (-218.3, +183.0) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] 再生直前: block = (+130.0, +228.5) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_121754.jpg
[RTD   ] [WARN] ブロックが measure 時から動いています（止めません・項目8）: ブロックが measure 時から 24.7px（≒11.7mm）動いています（許容 10.5px = 5.0mm）。ブロックを戻すか measure をやり直してください
[RTD   ] [WARN]   画素の差 24.7px（許容 10.5px = 5.0mm）/ mm 換算の差 11.70mm
[RTD   ] [WARN]   つかみ損ねる可能性があります。気になるなら Enter の前に measure を取り直してください
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121815
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121815/teach/drag_v2_20221013_231249.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121815/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 1.75° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=1.75° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.013s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 12.8s)
[RTD   ] 送信 OK（daemon 往復 1.030s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.32° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=1.85° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.013s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.049s）
[RTD   ] arrival OK (PICK → APPROACH_PICK (lift), max|Δ|=2.37° <= tol 3.0°)
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 12.4s)
[RTD   ] 送信 OK（daemon 往復 1.032s）
[RTD   ] arrival OK (APPROACH_PICK → APPROACH_PLACE, max|Δ|=2.55° <= tol 3.0°)
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=1.93° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.013s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.029s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.90° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 9.4s)
[RTD   ] 送信 OK（daemon 往復 1.032s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.28° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 60/60 回, 実効 1.65 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（1.65 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.034s / p50 1.031s / 最大 1.049s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.049s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 2.41s / 最大 4.42s
[RECORD] 電流の記録終了 81 行 (2.23 行/秒. 本体が眠っている間だけ読む. 爪の間 14.049 秒は読まない. 見込み超え 1 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121815/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > y
[RTD   ] 箱に入ったか (y/n) > y
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_121815/run_0001_20261109_121815.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=yes place=yes recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_121815 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 tools/gamepad_teleop.py --execute
/opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/pkgdata.py:25: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.
  from pkg_resources import resource_stream, resource_exists
objc[15510]: Class SDLApplication is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x102dad2c8) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10b8f4890). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15510]: Class SDLAppDelegate is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x102dad318) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10b8f48e0). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15510]: Class SDLTranslatorResponder is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x102dad390) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10b8f4958). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15510]: Class SDLMessageBoxPresenter is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x102dad3b8) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10b8f4980). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15510]: Class SDL_cocoametalview is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x102dad408) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10b8f49d0). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15510]: Class SDLOpenGLContext is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x102dad458) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10b8f4a20). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15510]: Class SDL_ShapeData is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x102dad4d0) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10b8f4a98). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15510]: Class SDL_CocoaClosure is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x102dad520) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10b8f4ae8). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15510]: Class SDL_VideoData is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x102dad570) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10b8f4b38). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15510]: Class SDL_WindowData is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x102dad5c0) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10b8f4b88). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15510]: Class SDLWindow is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x102dad5e8) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10b8f4bb0). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15510]: Class Cocoa_WindowListener is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x102dad610) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10b8f4bd8). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15510]: Class SDLView is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x102dad688) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10b8f4c50). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15510]: Class METAL_RenderData is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x102dad700) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10b8f4cc8). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15510]: Class METAL_TextureData is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x102dad750) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10b8f4d18). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15510]: Class SDL_RumbleMotor is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x102dad778) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10b8f4d40). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15510]: Class SDL_RumbleContext is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x102dad7c8) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10b8f4d90). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
[記録] /Volumes/KIOXIA/r2r2r-data/runs/experiments/gamepad_teleop/teleop_20261109_122141
[実機] daemon に送ります。起動したときの姿勢: -0.43 +1.49 +1.75 +0.08 -0.26 -30.23
コントローラーを待っています（つないでいなければ、今つないでください）
[接続] PS4 Controller  GUID=03008fe54c050000cc09000000016800  軸=6  ボタン=16
[長押し] j0 を -0.43° → -9.93° まで（目標を 1 回送信。止めます）
[送信] j0 -1.0° → -16.64 +1.49 +1.75 +0.08 -0.26 -30.23  届いた（ずれ 1.75°）  届いた角度 -17.05 +1.49 +1.93 +0.08 +1.49 -30.23
[送信] j0 -1.0° → -17.64 +1.49 +1.75 +0.08 -0.26 -30.23  動かなかった（次の押しは この目標の先から）・無視されたので 2 回送り直した（ずれ 1.75°）  届いた角度 -16.43 +1.49 +1.93 +0.08 +1.49 -30.23
[長押し] j0 を -16.43° → -16.43° まで（目標を 1 回送信。止めます）
[長押し] j0 を -16.69° → -22.85° まで（目標を 1 回送信。止めます）
[送信] j0 +1.0° → -29.32 +1.49 +1.75 +0.08 -0.26 -30.23  届いた（ずれ 1.92°）  届いた角度 -29.09 +1.58 +1.84 +0.00 +1.66 -30.32
[送信] j0 +1.0° → -28.32 +1.49 +1.75 +0.08 -0.26 -30.23  届いた（ずれ 1.92°）  届いた角度 -28.74 +1.58 +1.84 +0.00 +1.66 -30.32
[送信] j0 +1.0° → -27.32 +1.49 +1.75 +0.08 -0.26 -30.23  届いた（ずれ 1.92°）  届いた角度 -27.33 +1.58 +1.84 +0.00 +1.66 -30.32
[送信] j0 +1.0° → -26.32 +1.49 +1.75 +0.08 -0.26 -30.23  動かなかった（次の押しは この目標の先から）・無視されたので 2 回送り直した（ずれ 0.78°）  届いた角度 -27.07 +1.58 +1.84 +0.00 +0.52 -30.32
[送信] j0 +1.0° → -25.32 +1.49 +1.75 +0.08 -0.26 -30.23  動かなかった（次の押しは この目標の先から）・無視されたので 2 回送り直した（ずれ 1.75°）  届いた角度 -27.07 +1.58 +1.84 +0.00 +0.52 -30.32
[関節] 上下で動かす関節を j2 にしました
[長押し] j2 を +1.84° → -7.47° まで（目標を 1 回送信。止めます）
[関節] 上下で動かす関節を j3 にしました
[関節] 上下で動かす関節を j4 にしました
  [WARN] daemon_get_angles failed: daemon error: get_angles returned empty/invalid after 12 retries
  [WARN] daemon_get_angles failed: daemon error: get_angles returned empty/invalid after 12 retries
  [WARN] daemon_get_angles failed: daemon error: get_angles returned empty/invalid after 12 retries
[関節] 上下で動かす関節を j5 にしました
[関節] 上下で動かす関節を j1 にしました
  [WARN] daemon_get_angles failed: daemon error: get_angles returned empty/invalid after 12 retries
  [WARN] daemon_get_angles failed: daemon error: get_angles returned empty/invalid after 12 retries
  [WARN] daemon_get_angles failed: daemon error: get_angles returned empty/invalid after 12 retries
  [WARN] daemon_get_angles failed: daemon error: get_angles returned empty/invalid after 12 retries
[送信] j4 -1.0° → -25.32 +1.49 -26.42 +0.08 -1.00 -30.23  動かなかった（次の押しは この目標の先から）・無視されたので 2 回送り直した（ずれ 1.38°）  届いた角度 -25.04 +1.49 -25.04 +0.00 +0.00 -30.23
[送信] j1 +1.0° → -25.32 +2.49 -26.42 +0.08 -1.00 -30.23  届いた（ずれ 1.38°）  届いた角度 -25.04 +2.81 -25.04 +0.00 -1.58 -30.23
[長押し] j1 を +3.42° → +11.60° まで（目標を 1 回送信。止めます）
  [WARN] daemon_get_angles failed: daemon error: get_angles returned empty/invalid after 12 retries
  [WARN] daemon_get_angles failed: daemon error: get_angles returned empty/invalid after 12 retries
[送信] j1 +1.0° → -25.32 +21.83 -26.42 +0.08 -1.00 -30.23  手前で止まった（次の押しは この目標の先から）（ずれ 1.9°）  届いた角度 -25.04 +22.93 -24.52 +0.08 +0.17 -30.23
[長押し] j1 を +22.93° → +29.79° まで（目標を 1 回送信。止めます）
[関節] 上下で動かす関節を j2 にしました
[関節] 上下で動かす関節を j3 にしました
[関節] 上下で動かす関節を j4 にしました
[長押し] j4 を +1.84° → -36.82° まで（目標を 4 回送信。止めます）
[関節] 上下で動かす関節を j5 にしました
[関節] 上下で動かす関節を j1 にしました
[送信] j1 -1.0° → -25.32 +38.81 -26.42 +0.08 -36.65 -30.23  動かなかった（次の押しは この目標の先から）・無視されたので 2 回送り直した（ずれ 2.96°）  届いた角度 -25.04 +41.22 -23.46 +0.08 -36.38 -30.23
[長押し] j1 を +41.22° → +46.75° まで（目標を 1 回送信。止めます）
[関節] 上下で動かす関節を j2 にしました
[長押し] j2 を -23.99° → -23.11° まで（目標を 1 回送信。止めます）
[長押し] j2 を -8.17° → -7.11° まで（目標を 1 回送信。止めます）
[関節] 上下で動かす関節を j3 にしました
[関節] 上下で動かす関節を j4 にしました
[関節] 上下で動かす関節を j5 にしました
[関節] 上下で動かす関節を j1 にしました
[送信] j1 -1.0° → -25.32 +57.88 -2.81 +0.08 -36.65 -30.23  動かなかった（次の押しは この目標の先から）・無視されたので 2 回送り直した（ずれ 4.3°）  届いた角度 -25.04 +60.38 -2.81 +0.17 -40.95 -30.23
[長押し] j1 を +60.38° → +51.94° まで（目標を 1 回送信。止めます）
[関節] 上下で動かす関節を j2 にしました
[長押し] j2 を +0.43° → +0.43° まで（目標を 1 回送信。止めます）
[送信] j2 +1.0° → -25.32 +50.00 +10.75 +0.08 -36.65 -30.23  届いた（ずれ 5.27°）  届いた角度 -25.04 +47.81 +10.72 +0.26 -41.92 -30.23
[長押し] j2 を +11.25° → +11.25° まで（目標を 1 回送信。止めます）
[関節] 上下で動かす関節を j3 にしました
[関節] 上下で動かす関節を j4 にしました
[関節] 上下で動かす関節を j5 にしました
[関節] 上下で動かす関節を j1 にしました
[長押し] j1 を +48.42° → +48.07° まで（目標を 1 回送信。止めます）
[長押し] j1 を +44.47° → +42.36° まで（目標を 1 回送信。止めます）
[関節] 上下で動かす関節を j2 にしました
[止める] stop（released_while_sending）  止まった角度 -25.04 +48.16 +24.34 -0.08 -44.64 -30.76
[長押し] j2 を +24.34° → +24.25° まで（目標を 1 回送信。止めます）
[長押し] j2 を +18.01° → +17.75° まで（目標を 1 回送信。止めます）
[関節] 上下で動かす関節を j3 にしました
[関節] 上下で動かす関節を j4 にしました
[関節] 上下で動かす関節を j5 にしました
[関節] 上下で動かす関節を j1 にしました
[送信] j1 +1.0° → -25.32 +52.76 +6.32 +0.08 -36.65 -30.23  手前で止まった（次の押しは この目標の先から）（ずれ 5.27°）  届いた角度 -25.04 +53.87 +4.21 +0.26 -41.92 -30.58
[長押し] j1 を +53.87° → +52.11° まで（目標を 1 回送信。止めます）
[長押し] j1 を +42.89° → +42.62° まで（目標を 1 回送信。止めます）
[送信] j1 +1.0° → -25.32 +53.47 +6.32 +0.08 -36.65 -30.23  届いた（ずれ 2.54°）  届いた角度 -25.04 +53.61 +5.53 +0.26 -39.19 -30.58
[送信] j1 +1.0° → -25.32 +54.47 +6.32 +0.08 -36.65 -30.23  手前で止まった（次の押しは この目標の先から）（ずれ 2.9°）  届いた角度 -25.04 +55.63 +4.65 +0.26 -39.55 -30.58
[送信] j1 +1.0° → -25.32 +55.47 +6.32 +0.08 -36.65 -30.23  届いた（ずれ 2.9°）  届いた角度 -25.04 +55.63 +4.65 +0.26 -39.55 -30.58
[送信] j1 +2.0° → -25.32 +57.47 +6.32 +0.08 -36.65 -30.23  届いた（ずれ 3.86°）  届いた角度 -25.04 +57.74 +4.57 +0.26 -40.51 -30.49
[関節] 上下で動かす関節を j2 にしました
[送信] j2 -1.0° → -25.32 +57.47 +5.32 +0.08 -36.65 -30.23  届いた（ずれ 4.21°）  届いた角度 -25.04 +58.53 +4.83 +0.17 -40.86 -30.23
[送信] j2 -1.0° → -25.32 +57.47 +4.32 +0.08 -36.65 -30.23  動かなかった（次の押しは この目標の先から）・無視されたので 2 回送り直した（ずれ 5.44°）  届いた角度 -25.04 +58.53 +5.71 +0.00 -42.09 -30.23
[送信] j2 +1.0° → -25.32 +57.47 +5.32 +0.08 -36.65 -30.23  届いた（ずれ 5.44°）  届いた角度 -25.04 +58.53 +5.71 +0.00 -42.09 -30.23
[送信] j2 +1.0° → -25.32 +57.47 +6.32 +0.08 -36.65 -30.23  届いた（ずれ 5.44°）  届いた角度 -25.04 +58.53 +6.06 +0.00 -42.09 -30.23
[送信] j2 +2.0° → -25.32 +57.47 +8.32 +0.08 -36.65 -30.23  届いた（ずれ 7.2°）  届いた角度 -25.04 +58.53 +7.99 -0.17 -43.85 -30.23
[止める] stop（released_while_sending）  止まった角度 -25.04 +59.06 +7.99 -0.17 -44.47 -30.41
[送信] j2 +2.0° → -25.32 +57.47 +9.99 +0.08 -36.65 -30.23  手前で止まった（次の押しは この目標の先から）（ずれ 7.47°）  届いた角度 -25.04 +58.62 +9.05 -0.35 -44.12 -30.58
[関節] 上下で動かす関節を j3 にしました
[送信] j3 -1.0° → -25.32 +57.47 +9.99 -0.92 -36.65 -30.23  届いた（ずれ 7.2°）  届いた角度 -25.04 +58.62 +9.05 -0.43 -43.85 -30.49
[送信] j3 -1.0° → -25.32 +57.47 +9.99 -1.92 -36.65 -30.23  手前で止まった（次の押しは この目標の先から）（ずれ 6.5°）  届いた角度 -25.31 +58.27 +9.05 -1.23 -43.15 -30.41
[関節] 上下で動かす関節を j4 にしました
[送信] j4 -1.0° → -25.32 +57.47 +9.99 -1.92 -43.62 -30.23  動かなかった（次の押しは この目標の先から）・無視されたので 2 回送り直した（ずれ 1.0°）  届いた角度 -25.40 +58.18 +9.05 -1.40 -42.62 -30.32
[止める] stop（released_while_sending）  止まった角度 -25.40 +58.35 +9.05 -1.40 -43.76 -30.32
[長押し] j4 を -43.76° → -44.82° まで（目標を 1 回送信。止めます）
[送信] j4 -1.0° → -25.32 +57.47 +9.99 -1.92 -48.28 -30.23  動かなかった（次の押しは この目標の先から）・無視されたので 2 回送り直した（ずれ 1.68°）  届いた角度 -25.40 +59.15 +9.84 -1.23 -47.37 -30.41
[送信] j4 -1.0° → -25.32 +57.47 +9.99 -1.92 -49.28 -30.23  手前で止まった（次の押しは この目標の先から）（ずれ 1.68°）  届いた角度 -25.40 +59.15 +9.84 -1.31 -47.72 -30.41
[長押し] j4 を -47.81° → -47.81° まで（目標を 1 回送信。止めます）
[長押し] j4 を -51.41° → -57.39° まで（目標を 1 回送信。止めます）
[関節] 上下で動かす関節を j5 にしました
[関節] 上下で動かす関節を j1 にしました
[送信] j1 +1.0° → -25.32 +62.25 +9.99 -1.92 -62.05 -30.23  手前で止まった（次の押しは この目標の先から）（ずれ 3.95°）  届いた角度 -25.40 +63.45 +10.01 -1.14 -66.00 -30.41
[送信] j1 +1.0° → -25.32 +63.25 +9.99 -1.92 -62.05 -30.23  届いた（ずれ 3.95°）  届いた角度 -25.40 +63.45 +10.01 -1.23 -66.00 -30.41
[長押し] j1 を +64.24° → +66.09° まで（目標を 1 回送信。止めます）
[送信] j1 -1.0° → -25.32 +69.22 +9.99 -1.92 -62.05 -30.23  動かなかった（次の押しは この目標の先から）・無視されたので 2 回送り直した（ずれ 5.8°）  届いた角度 -25.40 +70.22 +10.01 -1.40 -67.85 -29.97
[送信] j1 -1.0° → -25.32 +68.22 +9.99 -1.92 -62.05 -30.23  動かなかった（次の押しは この目標の先から）・無視されたので 2 回送り直した（ずれ 5.53°）  届いた角度 -25.40 +70.04 +10.01 -1.40 -67.58 -29.97
[送信] j1 -1.0° → -25.32 +67.22 +9.99 -1.92 -62.05 -30.23  手前で止まった（次の押しは この目標の先から）（ずれ 3.78°）  届いた角度 -25.40 +68.90 +10.01 -1.40 -65.83 -30.05
[長押し] j1 を +68.90° → +66.88° まで（目標を 1 回送信。止めます）
[送信] j1 +1.0° → -25.32 +60.58 +9.99 -1.92 -62.05 -30.23  手前で止まった（次の押しは この目標の先から）（ずれ 2.28°）  届いた角度 -25.40 +61.78 +10.01 -1.23 -64.33 -30.14
[送信] j1 +1.0° → -25.32 +61.58 +9.99 -1.92 -62.05 -30.23  届いた（ずれ 2.28°）  届いた角度 -25.40 +61.78 +10.01 -1.23 -64.33 -30.14
[送信] j1 +2.0° → -25.32 +63.58 +9.99 -1.92 -62.05 -30.23  届いた（ずれ 3.07°）  届いた角度 -25.40 +64.07 +10.10 -1.31 -65.12 -30.14
[送信] j1 +2.0° → -25.32 +65.58 +9.99 -1.92 -62.05 -30.23  手前で止まった（次の押しは この目標の先から）（ずれ 3.51°）  届いた角度 -25.40 +66.62 +10.10 -1.40 -65.56 -30.14
[関節] 上下で動かす関節を j2 にしました
[送信] j2 +1.0° → -25.32 +65.58 +10.99 -1.92 -62.05 -30.23  届いた（ずれ 3.95°）  届いた角度 -25.40 +66.70 +11.07 -1.58 -66.00 -30.23
[送信] j2 -1.0° → -25.32 +65.58 +9.99 -1.92 -62.05 -30.23  動かなかった（次の押しは この目標の先から）・無視されたので 2 回送り直した（ずれ 1.75°）  届いた角度 -25.40 +66.70 +11.25 -1.58 -63.80 -30.14
[止める] stop（released_while_sending）  止まった角度 -25.40 +67.41 +9.31 -1.66 -62.05 -30.05
[長押し] j2 を +9.31° → +9.31° まで（目標を 1 回送信。止めます）
  [Pi] GRIPPER: VALUE=20 speed=100 result= None
[爪] 爪を閉じる（待ち 0.8 秒のあと受付）
  [Pi] GRIPPER: OPEN result= None
[爪] 爪を開く（待ち 0.8 秒のあと受付）
[送信] j2 -1.0° → -25.32 +65.58 -2.93 -1.92 -50.71 -30.23  手前で止まった（次の押しは この目標の先から）（ずれ 12.48°）  届いた角度 -25.48 +68.20 -1.84 -1.40 -63.19 -30.14
[送信] j2 +1.0° → -25.32 +65.58 -1.93 -1.92 -63.19 -30.23  届いた（ずれ 2.62°）  届いた角度 -25.48 +68.20 -1.84 -1.40 -63.19 -30.14
[送信] j2 +1.0° → -25.32 +65.58 -0.93 -1.92 -63.19 -30.23  届いた（ずれ 2.62°）  届いた角度 -25.48 +68.20 -1.05 -1.40 -64.07 -30.14
[送信] j2 +1.0° → -25.32 +65.58 +0.07 -1.92 -63.19 -30.23  届いた（ずれ 2.62°）  届いた角度 -25.48 +68.20 -0.08 -1.40 -64.16 -30.14
[送信] j2 +2.0° → -25.32 +65.58 +2.07 -1.92 -63.19 -30.23  届いた（ずれ 2.62°）  届いた角度 -25.48 +68.20 +2.19 -1.40 -65.21 -30.14
[送信] j2 +2.0° → -25.32 +65.58 +4.07 -1.92 -63.19 -30.23  届いた（ずれ 2.62°）  届いた角度 -25.48 +68.20 +4.13 -1.40 -65.56 -30.14
[送信] j2 +2.0° → -25.32 +65.58 +6.07 -1.92 -63.19 -30.23  届いた（ずれ 2.64°）  届いた角度 -25.48 +68.20 +6.32 -1.40 -65.83 -30.14
[送信] j2 +2.0° → -25.32 +65.58 +8.07 -1.92 -63.19 -30.23  届いた（ずれ 2.81°）  届いた角度 -25.48 +68.20 +7.82 -1.40 -66.00 -30.14
  [Pi] GRIPPER: VALUE=20 speed=100 result= None
[爪] 爪を閉じる（待ち 0.8 秒のあと受付）
[関節] 上下で動かす関節を j3 にしました
[関節] 上下で動かす関節を j4 にしました
[関節] 上下で動かす関節を j5 にしました
[関節] 上下で動かす関節を j1 にしました
[長押し] j1 を +68.20° → +47.19° まで（目標を 3 回送信。止めます）
  [Pi] GRIPPER: OPEN result= None
[爪] 爪を開く（待ち 0.8 秒のあと受付）
^C
[終了] Ctrl+C
[終了] アームは動かしていません。記録: /Volumes/KIOXIA/r2r2r-data/runs/experiments/gamepad_teleop/teleop_20261109_122141
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % >....                                           
たので 2 回送り直した（ずれ 1.75°）  届いた角度 -25.40 +66.70 +11.25 -1.58 -63.80 -30.14
[止める] stop（released_while_sending）  止まった角度 -25.40 +67.41 +9.31 -1.66 -62.05 -30.05
[長押し] j2 を +9.31° → +9.31° まで（目標を 1 回送信。止めます）
  [Pi] GRIPPER: VALUE=20 speed=100 result= None
[爪] 爪を閉じる（待ち 0.8 秒のあと受付）
  [Pi] GRIPPER: OPEN result= None
[爪] 爪を開く（待ち 0.8 秒のあと受付）
[送信] j2 -1.0° → -25.32 +65.58 -2.93 -1.92 -50.71 -30.23  手前で止まった（次の押しは この目標の先から）（ずれ 12.48°）  届いた角度 -25.48 +68.20 -1.84 -1.40 -63.19 -30.14
[送信] j2 +1.0° → -25.32 +65.58 -1.93 -1.92 -63.19 -30.23  届いた（ずれ 2.62°）  届いた角度 -25.48 +68.20 -1.84 -1.40 -63.19 -30.14
[送信] j2 +1.0° → -25.32 +65.58 -0.93 -1.92 -63.19 -30.23  届いた（ずれ 2.62°）  届いた角度 -25.48 +68.20 -1.05 -1.40 -64.07 -30.14
[送信] j2 +1.0° → -25.32 +65.58 +0.07 -1.92 -63.19 -30.23  届いた（ずれ 2.62°）  届いた角度 -25.48 +68.20 -0.08 -1.40 -64.16 -30.14
[送信] j2 +2.0° → -25.32 +65.58 +2.07 -1.92 -63.19 -30.23  届いた（ずれ 2.62°）  届いた角度 -25.48 +68.20 +2.19 -1.40 -65.21 -30.14
[送信] j2 +2.0° → -25.32 +65.58 +4.07 -1.92 -63.19 -30.23  届いた（ずれ 2.62°）  届いた角度 -25.48 +68.20 +4.13 -1.40 -65.56 -30.14
[送信] j2 +2.0° → -25.32 +65.58 +6.07 -1.92 -63.19 -30.23  届いた（ずれ 2.64°）  届いた角度 -25.48 +68.20 +6.32 -1.40 -65.83 -30.14
[送信] j2 +2.0° → -25.32 +65.58 +8.07 -1.92 -63.19 -30.23  届いた（ずれ 2.81°）  届いた角度 -25.48 +68.20 +7.82 -1.40 -66.00 -30.14
  [Pi] GRIPPER: VALUE=20 speed=100 result= None
[爪] 爪を閉じる（待ち 0.8 秒のあと受付）
[関節] 上下で動かす関節を j3 にしました
[関節] 上下で動かす関節を j4 にしました
[関節] 上下で動かす関節を j5 にしました
[関節] 上下で動かす関節を j1 にしました
[長押し] j1 を +68.20° → +47.19° まで（目標を 3 回送信。止めます）
  [Pi] GRIPPER: OPEN result= None
[爪] 爪を開く（待ち 0.8 秒のあと受付）
^C
[終了] Ctrl+C
[終了] アームは動かしていません。記録: /Volumes/KIOXIA/r2r2r-data/runs/experiments/gamepad_teleop/teleop_20261109_122141
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts %
python3 tools/gamepad_teleop.py --execute
zsh: parse error near `shimazueiichi@shimad...'
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 tools/gamepad_teleop.py --execute
/opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/pkgdata.py:25: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.
  from pkg_resources import resource_stream, resource_exists
objc[15740]: Class SDLApplication is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x1060bd2c8) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10edcc890). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15740]: Class SDLAppDelegate is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x1060bd318) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10edcc8e0). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15740]: Class SDLTranslatorResponder is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x1060bd390) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10edcc958). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15740]: Class SDLMessageBoxPresenter is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x1060bd3b8) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10edcc980). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15740]: Class SDL_cocoametalview is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x1060bd408) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10edcc9d0). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15740]: Class SDLOpenGLContext is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x1060bd458) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10edcca20). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15740]: Class SDL_ShapeData is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x1060bd4d0) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10edcca98). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15740]: Class SDL_CocoaClosure is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x1060bd520) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10edccae8). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15740]: Class SDL_VideoData is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x1060bd570) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10edccb38). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15740]: Class SDL_WindowData is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x1060bd5c0) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10edccb88). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15740]: Class SDLWindow is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x1060bd5e8) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10edccbb0). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15740]: Class Cocoa_WindowListener is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x1060bd610) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10edccbd8). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15740]: Class SDLView is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x1060bd688) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10edccc50). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15740]: Class METAL_RenderData is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x1060bd700) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10edcccc8). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15740]: Class METAL_TextureData is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x1060bd750) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10edccd18). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15740]: Class SDL_RumbleMotor is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x1060bd778) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10edccd40). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[15740]: Class SDL_RumbleContext is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x1060bd7c8) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10edccd90). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
[記録] /Volumes/KIOXIA/r2r2r-data/runs/experiments/gamepad_teleop/teleop_20261109_122554
[実機] daemon に送ります。起動したときの姿勢: -25.48 +43.06 +8.52 -2.10 -13.18 -30.23
コントローラーを待っています（つないでいなければ、今つないでください）
[接続] PS4 Controller  GUID=03008fe54c050000cc09000000016800  軸=6  ボタン=16
[HOME] 0.61 秒で離したので送りません（1 秒の長押しで送ります）
[送信] HOME → +0.00 +0.00 +0.00 +0.00 +0.00 -30.00  届いた（ずれ 2.1°）  届いた角度 -0.08 +1.66 +2.10 -0.26 +0.70 -30.23
^C
[終了] Ctrl+C
[終了] アームは動かしていません。記録: /Volumes/KIOXIA/r2r2r-data/runs/experiments/gamepad_teleop/teleop_20261109_122554
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % scp -i ~/.ssh/id_rsa_pi /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/drag_v2_20261109_123000.json ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/
drag_v2_20261109_123000.json                                                   100%   37KB   7.2MB/s   00:00    
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py measure
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] measure: 上カメラで検出します（repeat=5 interval=0.3s）
[CAM] 接続中カメラ一覧:
  index=0  name=FaceTime HDカメラ
  index=1  name=Iriun Camera
  index=2  name=‎iPhone14 Pro MAXのカメラ
[CAM] 上カメラ(iPhone)  index=2
[CAM] 横カメラ(Iriun)   index=1
[DETECT] resolved top index: 2
[Mac] マット四隅検出中... (10フレーム)
[Mac] ✓ マット四隅検出: 10/10 フレーム成功
[Mac] ✓ 動的homography計算完了
[Mac] ✓ マット範囲: X=[302, 1703] Y=[0, 949]
[06f] TEMPLATES_DIR overridden to: /Users/shimazueiichi/r2r2r-scripts/dynamic_tracking_limits/place/templates
[06f] ROTATION_ANGLES_DEG overridden to: [0, 15, 30, 45, 60, 75]
[06f] SCALES overridden to: [0.85, 1.0, 1.15]
[テンプレ] loading white box templates from: /Users/shimazueiichi/r2r2r-scripts/dynamic_tracking_limits/place/templates
[テンプレ] glob '/Users/shimazueiichi/r2r2r-scripts/dynamic_tracking_limits/place/templates/*.png' → 8 file(s)
[テンプレ]   - white_box_20260520_163829_004.png
[テンプレ]   - white_box_20260520_163838_005.png
[テンプレ]   - white_box_20260520_163846_006.png
[テンプレ]   - white_box_20260520_163905_009.png
[テンプレ]   - white_box_20260520_163912_010.png
[テンプレ]   - white_box_20260520_163918_011.png
[テンプレ]   - white_box_20260520_163923_012.png
[テンプレ]   - white_box_20260520_163929_013.png
[テンプレ] 計 8 枚 (day165=8, auto=0)
[06f] WARN: 輪郭中心とテンプレ中心の距離が閾値超 |Δ|=99.4px > 60px → 輪郭捨てて fallback
[06f] DETECT: center=(1495,572) source=template_fallback score=0.655 angle=0° scale=0.85 size=(167x156) template=white_box_20260520_163838_005.png (eval 5.09s)
[DETECT][1/5] box Unity=(-0.220,+0.191) score=0.6553379893302917
  赤ブロック pixel=(881, 223) → Unity=(0.0540, 0.0197)
[DETECT][1/5] block Unity=(+0.054,+0.020) score=null
[06f] WARN: 輪郭中心とテンプレ中心の距離が閾値超 |Δ|=100.3px > 60px → 輪郭捨てて fallback
[06f] DETECT: center=(1495,571) source=template_fallback score=0.655 angle=0° scale=0.85 size=(167x156) template=white_box_20260520_163838_005.png (eval 5.13s)
[DETECT][2/5] box Unity=(-0.220,+0.191) score=0.655491054058075
  赤ブロック pixel=(880, 226) → Unity=(0.0545, 0.0212)
[DETECT][2/5] block Unity=(+0.054,+0.021) score=null
[06f] WARN: 輪郭中心とテンプレ中心の距離が閾値超 |Δ|=100.3px > 60px → 輪郭捨てて fallback
[06f] DETECT: center=(1496,571) source=template_fallback score=0.656 angle=0° scale=0.85 size=(167x156) template=white_box_20260520_163838_005.png (eval 5.13s)
[DETECT][3/5] box Unity=(-0.221,+0.191) score=0.6559053659439087
  赤ブロック pixel=(881, 221) → Unity=(0.0540, 0.0187)
[DETECT][3/5] block Unity=(+0.054,+0.019) score=null
[06f] WARN: 輪郭中心とテンプレ中心の距離が閾値超 |Δ|=100.3px > 60px → 輪郭捨てて fallback
[06f] DETECT: center=(1495,571) source=template_fallback score=0.656 angle=0° scale=0.85 size=(167x156) template=white_box_20260520_163838_005.png (eval 5.12s)
[DETECT][4/5] box Unity=(-0.220,+0.191) score=0.6560110449790955
  赤ブロック pixel=(879, 283) → Unity=(0.0554, 0.0488)
[DETECT][4/5] block Unity=(+0.055,+0.049) score=null
[06f] WARN: 輪郭中心とテンプレ中心の距離が閾値超 |Δ|=100.3px > 60px → 輪郭捨てて fallback
[06f] DETECT: center=(1495,571) source=template_fallback score=0.655 angle=0° scale=0.85 size=(167x156) template=white_box_20260520_163838_005.png (eval 5.15s)
[DETECT][5/5] box Unity=(-0.220,+0.191) score=0.6551560163497925
  赤ブロック pixel=(880, 281) → Unity=(0.0549, 0.0478)
[DETECT][5/5] block Unity=(+0.055,+0.048) score=null
[RTD   ] measure: block = (+54.5, +21.2) mm
[RTD   ] measure: box   = (-220.2, +190.9) mm  score=0.655491054058075
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_122827.jpg
[RTD   ] homography のもとになった四隅と、測り直した四隅の差: 最大 2.24px（上限 15.0px・やり直し 1 回）
[RTD   ] [WARN] 検出したブロックがアームの根元から 58.4mm しか離れていません（120.0mm 以内は不可）。教示で使う位置は 200mm 以上離れているので、赤いケーブル等の別のものを拾っている可能性が高いです: (+54.5, +21.2) mm（WARN のみ・保存します）
[RTD   ] 何を拾ったかは確認画像で見てください: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_122827.jpg
[RTD   ] ブロックのばらつき: 2.0px = 0.97mm（5 枚・上限 4.0mm）
[RTD   ] 元の検出と測り直しの差: 26.65mm（上限 3.0mm）
[RTD   ] [WARN] 元の検出 (+54.5, +21.2) mm と測り直し (+54.9, +47.8) mm が 26.65mm 食い違います（上限 3.0mm）。元の検出が外れている可能性があります（WARN のみ・保存します）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_122827.jpg
[RTD   ] 保存しました: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_122827.json
[RTD   ] [WARN] この measure には WARN が 2 件あります: block_too_close_to_base, vs_recheck_over
[RTD   ] [WARN] 値が外れている可能性があります。気になるなら取り直してください（保存はしてあります）
[RTD   ] 次は Pi で教示 → daemon 起動 → recorder.py --top --no-side 常駐 → run --teach <file> --execute
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20261109_123000.json
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: ドライラン（アームに何も送りません）
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20261109_123000.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_44o19u8o/drag_v2_20261109_123000.json
[RTD   ] 入力ファイル: drag_v2_20261109_123000.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=146 (start=146 end=194, gap=25.14°)
                    angles = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
  PICK           <- gripper close mark idx=214（PICK phase 範囲内）
                    angles = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=286 (start=286 end=321, gap=20.83°)
                    angles = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
  PLACE          <- gripper open mark idx=345（PLACE phase 範囲内）
                    angles = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 146 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 19.78°（しきい値 3.0° 以上）
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = 未取得（ドライラン・daemon に接続していない）
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 66.53°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 66.52°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 49.39°  1 回送信 speed=20  (~ 2.5s @ 20°/s 目安・到達待ち 最大 9.4s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 30.7s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 13.7s（max|Δ| 合計 274.4° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_122827.json
[RTD   ]   measured_at = 2026-11-09T12:28:29.041753  block = (+54.5, +21.2) mm  box = (-220.2, +190.9) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] 再生直前: block = (+54.9, +48.3) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_122842.jpg
[RTD   ] 何を拾ったかは確認画像で見てください: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_122842.jpg
[RTD   ] [WARN] 検出したブロックがアームの根元から 73.1mm しか離れていません（120.0mm 以内は不可）。教示で使う位置は 200mm 以上離れているので、赤いケーブル等の別のものを拾っている可能性が高いです: (+54.9, +48.3) mm（**止めません**・WARN のみ）
[RTD   ] [WARN] ブロックが measure 時から動いています（止めません・項目8）: ブロックが measure 時から 56.0px（≒27.1mm）動いています（許容 10.3px = 5.0mm）。ブロックを戻すか measure をやり直してください
[RTD   ] [WARN]   画素の差 56.0px（許容 10.3px = 5.0mm）/ mm 換算の差 27.13mm
[RTD   ] [WARN]   つかみ損ねる可能性があります。気になるなら Enter の前に measure を取り直してください
[RTD   ] ドライランなので、ここで終了します（アームには何も送っていません）
[RTD   ] Pi 版と比べる点: 抽出ウェイポイント 4 姿勢と各区間の max|Δ| は同じ。送り方は単発（Pi 版は 0.1s 補間ストリーミング）なので n_steps / ticks は比較対象外。送信 8 回 / 想定所要 ≈ 30.7s
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 tools/gamepad_teleop.py --execute
/opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/pkgdata.py:25: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.
  from pkg_resources import resource_stream, resource_exists
objc[16047]: Class SDLApplication is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x1035352c8) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10d248890). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[16047]: Class SDLAppDelegate is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x103535318) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10d2488e0). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[16047]: Class SDLTranslatorResponder is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x103535390) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10d248958). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[16047]: Class SDLMessageBoxPresenter is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x1035353b8) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10d248980). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[16047]: Class SDL_cocoametalview is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x103535408) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10d2489d0). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[16047]: Class SDLOpenGLContext is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x103535458) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10d248a20). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[16047]: Class SDL_ShapeData is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x1035354d0) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10d248a98). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[16047]: Class SDL_CocoaClosure is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x103535520) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10d248ae8). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[16047]: Class SDL_VideoData is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x103535570) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10d248b38). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[16047]: Class SDL_WindowData is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x1035355c0) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10d248b88). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[16047]: Class SDLWindow is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x1035355e8) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10d248bb0). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[16047]: Class Cocoa_WindowListener is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x103535610) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10d248bd8). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[16047]: Class SDLView is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x103535688) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10d248c50). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[16047]: Class METAL_RenderData is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x103535700) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10d248cc8). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[16047]: Class METAL_TextureData is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x103535750) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10d248d18). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[16047]: Class SDL_RumbleMotor is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x103535778) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10d248d40). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[16047]: Class SDL_RumbleContext is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x1035357c8) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10d248d90). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
[記録] /Volumes/KIOXIA/r2r2r-data/runs/experiments/gamepad_teleop/teleop_20261109_122924
[実機] daemon に送ります。起動したときの姿勢: -0.26 +1.66 +2.10 -0.26 -0.26 -30.23
コントローラーを待っています（つないでいなければ、今つないでください）
[接続] PS4 Controller  GUID=03008fe54c050000cc09000000016800  軸=6  ボタン=16
[送信] HOME → +0.00 +0.00 +0.00 +0.00 +0.00 -30.00  届いた（ずれ 2.1°）  届いた角度 -0.26 +1.66 +2.10 -0.26 -0.26 -30.23
^C
[終了] Ctrl+C
[終了] アームは動かしていません。記録: /Volumes/KIOXIA/r2r2r-data/runs/experiments/gamepad_teleop/teleop_20261109_122924
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py measure
python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20261109_123000.json
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] measure: 上カメラで検出します（repeat=5 interval=0.3s）
[CAM] 接続中カメラ一覧:
  index=0  name=FaceTime HDカメラ
  index=1  name=Iriun Camera
  index=2  name=‎iPhone14 Pro MAXのカメラ
[CAM] 上カメラ(iPhone)  index=2
[CAM] 横カメラ(Iriun)   index=1
[DETECT] resolved top index: 2
[Mac] マット四隅検出中... (10フレーム)
[Mac] ✓ マット四隅検出: 10/10 フレーム成功
[Mac] ✓ 動的homography計算完了
[Mac] ✓ マット範囲: X=[302, 1703] Y=[0, 949]
[06f] TEMPLATES_DIR overridden to: /Users/shimazueiichi/r2r2r-scripts/dynamic_tracking_limits/place/templates
[06f] ROTATION_ANGLES_DEG overridden to: [0, 15, 30, 45, 60, 75]
[06f] SCALES overridden to: [0.85, 1.0, 1.15]
[テンプレ] loading white box templates from: /Users/shimazueiichi/r2r2r-scripts/dynamic_tracking_limits/place/templates
[テンプレ] glob '/Users/shimazueiichi/r2r2r-scripts/dynamic_tracking_limits/place/templates/*.png' → 8 file(s)
[テンプレ]   - white_box_20260520_163829_004.png
[テンプレ]   - white_box_20260520_163838_005.png
[テンプレ]   - white_box_20260520_163846_006.png
[テンプレ]   - white_box_20260520_163905_009.png
[テンプレ]   - white_box_20260520_163912_010.png
[テンプレ]   - white_box_20260520_163918_011.png
[テンプレ]   - white_box_20260520_163923_012.png
[テンプレ]   - white_box_20260520_163929_013.png
[テンプレ] 計 8 枚 (day165=8, auto=0)
[06f] WARN: 輪郭中心とテンプレ中心の距離が閾値超 |Δ|=99.4px > 60px → 輪郭捨てて fallback
[06f] DETECT: center=(1495,572) source=template_fallback score=0.655 angle=0° scale=0.85 size=(167x156) template=white_box_20260520_163838_005.png (eval 5.46s)
[DETECT][1/5] box Unity=(-0.220,+0.191) score=0.6554038524627686
  赤ブロック pixel=(879, 284) → Unity=(0.0554, 0.0493)
[DETECT][1/5] block Unity=(+0.055,+0.049) score=null
[06f] WARN: 輪郭中心とテンプレ中心の距離が閾値超 |Δ|=99.4px > 60px → 輪郭捨てて fallback
[06f] DETECT: center=(1495,572) source=template_fallback score=0.655 angle=0° scale=0.85 size=(167x156) template=white_box_20260520_163838_005.png (eval 5.95s)
[DETECT][2/5] box Unity=(-0.220,+0.191) score=0.6552867293357849
  赤ブロック pixel=(880, 230) → Unity=(0.0545, 0.0231)
[DETECT][2/5] block Unity=(+0.054,+0.023) score=null
[06f] WARN: 輪郭中心とテンプレ中心の距離が閾値超 |Δ|=99.4px > 60px → 輪郭捨てて fallback
[06f] DETECT: center=(1495,572) source=template_fallback score=0.655 angle=0° scale=0.85 size=(167x156) template=white_box_20260520_163838_005.png (eval 5.51s)
[DETECT][3/5] box Unity=(-0.220,+0.191) score=0.6552579998970032
  赤ブロック pixel=(880, 282) → Unity=(0.0549, 0.0483)
[DETECT][3/5] block Unity=(+0.055,+0.048) score=null
[06f] WARN: 輪郭中心とテンプレ中心の距離が閾値超 |Δ|=99.4px > 60px → 輪郭捨てて fallback
[06f] DETECT: center=(1495,572) source=template_fallback score=0.655 angle=0° scale=0.85 size=(167x156) template=white_box_20260520_163838_005.png (eval 6.63s)
[DETECT][4/5] box Unity=(-0.220,+0.191) score=0.6553944945335388
  赤ブロック pixel=(880, 281) → Unity=(0.0549, 0.0478)
[DETECT][4/5] block Unity=(+0.055,+0.048) score=null
[06f] WARN: 輪郭中心とテンプレ中心の距離が閾値超 |Δ|=99.7px > 60px → 輪郭捨てて fallback
[06f] DETECT: center=(1495,572) source=template_fallback score=0.655 angle=0° scale=0.85 size=(167x156) template=white_box_20260520_163838_005.png (eval 5.56s)
[DETECT][5/5] box Unity=(-0.220,+0.191) score=0.6553799510002136
  赤ブロック pixel=(880, 204) → Unity=(0.0543, 0.0105)
[DETECT][5/5] block Unity=(+0.054,+0.010) score=null
[RTD   ] measure: block = (+54.9, +47.8) mm
[RTD   ] measure: box   = (-220.1, +191.4) mm  score=0.6553799510002136
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123031.jpg
[RTD   ] homography のもとになった四隅と、測り直した四隅の差: 最大 0.22px（上限 15.0px・やり直し 1 回）
[RTD   ] [WARN] 検出したブロックがアームの根元から 72.8mm しか離れていません（120.0mm 以内は不可）。教示で使う位置は 200mm 以上離れているので、赤いケーブル等の別のものを拾っている可能性が高いです: (+54.9, +47.8) mm（WARN のみ・保存します）
[RTD   ] 何を拾ったかは確認画像で見てください: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123031.jpg
[RTD   ] ブロックのばらつき: 113.0px = 54.85mm（5 枚・上限 4.0mm）
[RTD   ] [WARN] 検出が不安定です: ブロックのばらつきが 113.0px = 54.85mm（上限 4.0mm）。（WARN のみ・保存します）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123031.jpg
[RTD   ] 元の検出と測り直しの差: 0.00mm（上限 3.0mm）
[RTD   ] 保存しました: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123031.json
[RTD   ] [WARN] この measure には WARN が 2 件あります: block_too_close_to_base, block_spread_over
[RTD   ] [WARN] 値が外れている可能性があります。気になるなら取り直してください（保存はしてあります）
[RTD   ] 次は Pi で教示 → daemon 起動 → recorder.py --top --no-side 常駐 → run --teach <file> --execute
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: ドライラン（アームに何も送りません）
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20261109_123000.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_n_pens_2/drag_v2_20261109_123000.json
[RTD   ] 入力ファイル: drag_v2_20261109_123000.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=146 (start=146 end=194, gap=25.14°)
                    angles = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
  PICK           <- gripper close mark idx=214（PICK phase 範囲内）
                    angles = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=286 (start=286 end=321, gap=20.83°)
                    angles = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
  PLACE          <- gripper open mark idx=345（PLACE phase 範囲内）
                    angles = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 146 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 19.78°（しきい値 3.0° 以上）
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = 未取得（ドライラン・daemon に接続していない）
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 66.53°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 66.52°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 49.39°  1 回送信 speed=20  (~ 2.5s @ 20°/s 目安・到達待ち 最大 9.4s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 30.7s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 13.7s（max|Δ| 合計 274.4° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123031.json
[RTD   ]   measured_at = 2026-11-09T12:30:33.117494  block = (+54.9, +47.8) mm  box = (-220.1, +191.4) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] 再生直前: block = (+54.9, +47.8) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_123035.jpg
[RTD   ] 何を拾ったかは確認画像で見てください: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_123035.jpg
[RTD   ] [WARN] 検出したブロックがアームの根元から 72.8mm しか離れていません（120.0mm 以内は不可）。教示で使う位置は 200mm 以上離れているので、赤いケーブル等の別のものを拾っている可能性が高いです: (+54.9, +47.8) mm（**止めません**・WARN のみ）
[RTD   ] ブロック位置の照合 OK（画素の差 0.0px <= 許容 10.3px = 5.0mm / mm 換算の差 0.00mm）
[RTD   ] マット四隅のずれ 最大 0.0px（上限 15.0px・やり直し 1 回）
[RTD   ] ドライランなので、ここで終了します（アームには何も送っていません）
[RTD   ] Pi 版と比べる点: 抽出ウェイポイント 4 姿勢と各区間の max|Δ| は同じ。送り方は単発（Pi 版は 0.1s 補間ストリーミング）なので n_steps / ticks は比較対象外。送信 8 回 / 想定所要 ≈ 30.7s
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py measure
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] measure: 上カメラで検出します（repeat=5 interval=0.3s）
[CAM] 接続中カメラ一覧:
  index=0  name=FaceTime HDカメラ
  index=1  name=Iriun Camera
  index=2  name=‎iPhone14 Pro MAXのカメラ
[CAM] 上カメラ(iPhone)  index=2
[CAM] 横カメラ(Iriun)   index=1
[DETECT] resolved top index: 2
[Mac] マット四隅検出中... (10フレーム)
[Mac] ✓ マット四隅検出: 10/10 フレーム成功
[Mac] ✓ 動的homography計算完了
[Mac] ✓ マット範囲: X=[302, 1703] Y=[0, 949]
[06f] TEMPLATES_DIR overridden to: /Users/shimazueiichi/r2r2r-scripts/dynamic_tracking_limits/place/templates
[06f] ROTATION_ANGLES_DEG overridden to: [0, 15, 30, 45, 60, 75]
[06f] SCALES overridden to: [0.85, 1.0, 1.15]
[テンプレ] loading white box templates from: /Users/shimazueiichi/r2r2r-scripts/dynamic_tracking_limits/place/templates
[テンプレ] glob '/Users/shimazueiichi/r2r2r-scripts/dynamic_tracking_limits/place/templates/*.png' → 8 file(s)
[テンプレ]   - white_box_20260520_163829_004.png
[テンプレ]   - white_box_20260520_163838_005.png
[テンプレ]   - white_box_20260520_163846_006.png
[テンプレ]   - white_box_20260520_163905_009.png
[テンプレ]   - white_box_20260520_163912_010.png
[テンプレ]   - white_box_20260520_163918_011.png
[テンプレ]   - white_box_20260520_163923_012.png
[テンプレ]   - white_box_20260520_163929_013.png
[テンプレ] 計 8 枚 (day165=8, auto=0)
[06f] WARN: 輪郭中心とテンプレ中心の距離が閾値超 |Δ|=99.4px > 60px → 輪郭捨てて fallback
[06f] DETECT: center=(1495,572) source=template_fallback score=0.655 angle=0° scale=0.85 size=(167x156) template=white_box_20260520_163838_005.png (eval 6.32s)
[DETECT][1/5] box Unity=(-0.220,+0.191) score=0.6553415656089783
  赤ブロック pixel=(880, 282) → Unity=(0.0549, 0.0483)
[DETECT][1/5] block Unity=(+0.055,+0.048) score=null
[06f] WARN: 輪郭中心とテンプレ中心の距離が閾値超 |Δ|=99.4px > 60px → 輪郭捨てて fallback
[06f] DETECT: center=(1495,572) source=template_fallback score=0.656 angle=0° scale=0.85 size=(167x156) template=white_box_20260520_163838_005.png (eval 5.43s)
[DETECT][2/5] box Unity=(-0.220,+0.191) score=0.6555894017219543
  赤ブロック pixel=(880, 282) → Unity=(0.0549, 0.0483)
[DETECT][2/5] block Unity=(+0.055,+0.048) score=null
[06f] WARN: 輪郭中心とテンプレ中心の距離が閾値超 |Δ|=99.4px > 60px → 輪郭捨てて fallback
[06f] DETECT: center=(1495,572) source=template_fallback score=0.656 angle=0° scale=0.85 size=(167x156) template=white_box_20260520_163838_005.png (eval 5.61s)
[DETECT][3/5] box Unity=(-0.220,+0.191) score=0.6555450558662415
  赤ブロック pixel=(880, 226) → Unity=(0.0545, 0.0212)
[DETECT][3/5] block Unity=(+0.054,+0.021) score=null
[06f] WARN: 輪郭中心とテンプレ中心の距離が閾値超 |Δ|=100.3px > 60px → 輪郭捨てて fallback
[06f] DETECT: center=(1495,571) source=template_fallback score=0.655 angle=0° scale=0.85 size=(167x156) template=white_box_20260520_163838_005.png (eval 5.28s)
[DETECT][4/5] box Unity=(-0.220,+0.191) score=0.6551064252853394
  赤ブロック pixel=(880, 281) → Unity=(0.0549, 0.0478)
[DETECT][4/5] block Unity=(+0.055,+0.048) score=null
[06f] WARN: 輪郭中心とテンプレ中心の距離が閾値超 |Δ|=99.4px > 60px → 輪郭捨てて fallback
[06f] DETECT: center=(1495,572) source=template_fallback score=0.655 angle=0° scale=0.85 size=(167x156) template=white_box_20260520_163838_005.png (eval 5.32s)
[DETECT][5/5] box Unity=(-0.220,+0.191) score=0.6553043127059937
  赤ブロック pixel=(880, 281) → Unity=(0.0549, 0.0478)
[DETECT][5/5] block Unity=(+0.055,+0.048) score=null
[RTD   ] measure: block = (+54.9, +47.8) mm
[RTD   ] measure: box   = (-220.1, +191.4) mm  score=0.6553415656089783
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123220.jpg
[RTD   ] homography のもとになった四隅と、測り直した四隅の差: 最大 0.1px（上限 15.0px・やり直し 1 回）
[RTD   ] [WARN] 検出したブロックがアームの根元から 72.8mm しか離れていません（120.0mm 以内は不可）。教示で使う位置は 200mm 以上離れているので、赤いケーブル等の別のものを拾っている可能性が高いです: (+54.9, +47.8) mm（WARN のみ・保存します）
[RTD   ] 何を拾ったかは確認画像で見てください: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123220.jpg
[RTD   ] ブロックのばらつき: 1.0px = 0.48mm（5 枚・上限 4.0mm）
[RTD   ] 元の検出と測り直しの差: 0.00mm（上限 3.0mm）
[RTD   ] 保存しました: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123220.json
[RTD   ] [WARN] この measure には WARN が 1 件あります: block_too_close_to_base
[RTD   ] [WARN] 値が外れている可能性があります。気になるなら取り直してください（保存はしてあります）
[RTD   ] 次は Pi で教示 → daemon 起動 → recorder.py --top --no-side 常駐 → run --teach <file> --execute
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py measure
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] measure: 上カメラで検出します（repeat=5 interval=0.3s）
[CAM] 接続中カメラ一覧:
  index=0  name=FaceTime HDカメラ
  index=1  name=Iriun Camera
  index=2  name=‎iPhone14 Pro MAXのカメラ
[CAM] 上カメラ(iPhone)  index=2
[CAM] 横カメラ(Iriun)   index=1
[DETECT] resolved top index: 2
[Mac] マット四隅検出中... (10フレーム)
[Mac] ✓ マット四隅検出: 10/10 フレーム成功
[Mac] ✓ 動的homography計算完了
[Mac] ✓ マット範囲: X=[302, 1702] Y=[0, 949]
[06f] TEMPLATES_DIR overridden to: /Users/shimazueiichi/r2r2r-scripts/dynamic_tracking_limits/place/templates
[06f] ROTATION_ANGLES_DEG overridden to: [0, 15, 30, 45, 60, 75]
[06f] SCALES overridden to: [0.85, 1.0, 1.15]
[テンプレ] loading white box templates from: /Users/shimazueiichi/r2r2r-scripts/dynamic_tracking_limits/place/templates
[テンプレ] glob '/Users/shimazueiichi/r2r2r-scripts/dynamic_tracking_limits/place/templates/*.png' → 8 file(s)
[テンプレ]   - white_box_20260520_163829_004.png
[テンプレ]   - white_box_20260520_163838_005.png
[テンプレ]   - white_box_20260520_163846_006.png
[テンプレ]   - white_box_20260520_163905_009.png
[テンプレ]   - white_box_20260520_163912_010.png
[テンプレ]   - white_box_20260520_163918_011.png
[テンプレ]   - white_box_20260520_163923_012.png
[テンプレ]   - white_box_20260520_163929_013.png
[テンプレ] 計 8 枚 (day165=8, auto=0)
[06f] WARN: 輪郭中心とテンプレ中心の距離が閾値超 |Δ|=100.3px > 60px → 輪郭捨てて fallback
[06f] DETECT: center=(1495,571) source=template_fallback score=0.655 angle=0° scale=0.85 size=(167x156) template=white_box_20260520_163838_005.png (eval 5.34s)
[DETECT][1/5] box Unity=(-0.220,+0.191) score=0.6553701758384705
  赤ブロック pixel=(880, 280) → Unity=(0.0548, 0.0473)
[DETECT][1/5] block Unity=(+0.055,+0.047) score=null
[06f] WARN: 輪郭中心とテンプレ中心の距離が閾値超 |Δ|=100.3px > 60px → 輪郭捨てて fallback
[06f] DETECT: center=(1495,571) source=template_fallback score=0.656 angle=0° scale=0.85 size=(167x156) template=white_box_20260520_163838_005.png (eval 5.47s)
[DETECT][2/5] box Unity=(-0.220,+0.191) score=0.6557032465934753
  赤ブロック pixel=(880, 280) → Unity=(0.0548, 0.0473)
[DETECT][2/5] block Unity=(+0.055,+0.047) score=null
[06f] WARN: 輪郭中心とテンプレ中心の距離が閾値超 |Δ|=100.3px > 60px → 輪郭捨てて fallback
[06f] DETECT: center=(1495,571) source=template_fallback score=0.656 angle=0° scale=0.85 size=(167x156) template=white_box_20260520_163838_005.png (eval 5.45s)
[DETECT][3/5] box Unity=(-0.220,+0.191) score=0.655527651309967
  赤ブロック pixel=(880, 280) → Unity=(0.0548, 0.0473)
[DETECT][3/5] block Unity=(+0.055,+0.047) score=null
[06f] WARN: 輪郭中心とテンプレ中心の距離が閾値超 |Δ|=100.3px > 60px → 輪郭捨てて fallback
[06f] DETECT: center=(1495,571) source=template_fallback score=0.656 angle=0° scale=0.85 size=(167x156) template=white_box_20260520_163838_005.png (eval 5.92s)
[DETECT][4/5] box Unity=(-0.220,+0.191) score=0.6557596921920776
  赤ブロック pixel=(880, 280) → Unity=(0.0548, 0.0473)
[DETECT][4/5] block Unity=(+0.055,+0.047) score=null
[06f] WARN: 輪郭中心とテンプレ中心の距離が閾値超 |Δ|=100.3px > 60px → 輪郭捨てて fallback
[06f] DETECT: center=(1495,571) source=template_fallback score=0.655 angle=0° scale=0.85 size=(167x156) template=white_box_20260520_163838_005.png (eval 5.51s)
[DETECT][5/5] box Unity=(-0.220,+0.191) score=0.6554656624794006
  赤ブロック pixel=(880, 280) → Unity=(0.0548, 0.0473)
[DETECT][5/5] block Unity=(+0.055,+0.047) score=null
[RTD   ] measure: block = (+54.8, +47.3) mm
[RTD   ] measure: box   = (-220.3, +190.8) mm  score=0.655527651309967
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123559.jpg
[RTD   ] homography のもとになった四隅と、測り直した四隅の差: 最大 1.41px（上限 15.0px・やり直し 1 回）
[RTD   ] [WARN] 検出したブロックがアームの根元から 72.4mm しか離れていません（120.0mm 以内は不可）。教示で使う位置は 200mm 以上離れているので、赤いケーブル等の別のものを拾っている可能性が高いです: (+54.8, +47.3) mm（WARN のみ・保存します）
[RTD   ] 何を拾ったかは確認画像で見てください: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123559.jpg
[RTD   ] ブロックのばらつき: 1.0px = 0.45mm（5 枚・上限 4.0mm）
[RTD   ] 元の検出と測り直しの差: 0.00mm（上限 3.0mm）
[RTD   ] 保存しました: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123559.json
[RTD   ] [WARN] この measure には WARN が 1 件あります: block_too_close_to_base
[RTD   ] [WARN] 値が外れている可能性があります。気になるなら取り直してください（保存はしてあります）
[RTD   ] 次は Pi で教示 → daemon 起動 → recorder.py --top --no-side 常駐 → run --teach <file> --execute
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20261109_123000.json --execute
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20261109_123000.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_bvnahdtr/drag_v2_20261109_123000.json
[RTD   ] 入力ファイル: drag_v2_20261109_123000.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=146 (start=146 end=194, gap=25.14°)
                    angles = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
  PICK           <- gripper close mark idx=214（PICK phase 範囲内）
                    angles = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=286 (start=286 end=321, gap=20.83°)
                    angles = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
  PLACE          <- gripper open mark idx=345（PLACE phase 範囲内）
                    angles = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 146 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 19.78°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  -0.26,   +1.66,   +2.10,   -0.26,   -0.26,  -30.23]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  -0.26,   +1.66,   +2.10,   -0.26,   -0.26,  -30.23]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 2.10°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 66.53°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 66.52°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 49.39°  1 回送信 speed=20  (~ 2.5s @ 20°/s 目安・到達待ち 最大 9.4s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 30.7s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 13.7s（max|Δ| 合計 274.4° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123559.json
[RTD   ]   measured_at = 2026-11-09T12:36:01.355235  block = (+54.8, +47.3) mm  box = (-220.3, +190.8) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] 再生直前: block = (+54.8, +47.7) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_123651.jpg
[RTD   ] 何を拾ったかは確認画像で見てください: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_123651.jpg
[RTD   ] [WARN] 検出したブロックがアームの根元から 72.7mm しか離れていません（120.0mm 以内は不可）。教示で使う位置は 200mm 以上離れているので、赤いケーブル等の別のものを拾っている可能性が高いです: (+54.8, +47.7) mm（**止めません**・WARN のみ）
[RTD   ] ブロック位置の照合 OK（画素の差 1.0px <= 許容 10.3px = 5.0mm / mm 換算の差 0.48mm）
[RTD   ] マット四隅のずれ 最大 1.3px（上限 15.0px・やり直し 1 回）
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_123655
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_123655/teach/drag_v2_20261109_123000.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_123655/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 2.10° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=2.10° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.004s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 12.0s)
[RTD   ] 送信 OK（daemon 往復 1.028s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.06° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.030s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=0.88° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.009s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.041s）
[RTD   ] arrival OK (PICK → APPROACH_PICK (lift), max|Δ|=2.02° <= tol 3.0°)
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 12.0s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (APPROACH_PICK → APPROACH_PLACE, max|Δ|=2.55° <= tol 3.0°)
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.055s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=2.02° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.015s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.029s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.55° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 9.4s)
[RTD   ] 送信 OK（daemon 往復 1.028s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.37° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 55/55 回, 実効 1.58 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（1.58 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.034s / p50 1.030s / 最大 1.055s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.055s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 2.22s / 最大 4.62s
[RECORD] 電流の記録終了 71 行 (2.04 行/秒. 本体が眠っている間だけ読む. 爪の間 14.043 秒は読まない. 見込み超え 0 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_123655/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > y
[RTD   ] 箱に入ったか (y/n) > y
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_123655/run_0001_20261109_123655.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=yes place=yes recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_123655 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20261109_123000.json --execute
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20261109_123000.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_4s9566yb/drag_v2_20261109_123000.json
[RTD   ] 入力ファイル: drag_v2_20261109_123000.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=146 (start=146 end=194, gap=25.14°)
                    angles = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
  PICK           <- gripper close mark idx=214（PICK phase 範囲内）
                    angles = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=286 (start=286 end=321, gap=20.83°)
                    angles = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
  PLACE          <- gripper open mark idx=345（PLACE phase 範囲内）
                    angles = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 146 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 19.78°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  -0.43,   +1.49,   +1.93,   +0.08,   -0.26,  -30.23]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  -0.43,   +1.49,   +1.93,   +0.08,   -0.26,  -30.23]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 1.93°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 66.53°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 66.52°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 49.39°  1 回送信 speed=20  (~ 2.5s @ 20°/s 目安・到達待ち 最大 9.4s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 30.7s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 13.7s（max|Δ| 合計 274.4° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123559.json
[RTD   ]   measured_at = 2026-11-09T12:36:01.355235  block = (+54.8, +47.3) mm  box = (-220.3, +190.8) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] 再生直前: block = (+140.0, +221.3) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_123753.jpg
[RTD   ] [WARN] ブロックが measure 時から動いています（止めません・項目8）: ブロックが measure 時から 409.7px（≒193.7mm）動いています（許容 10.3px = 5.0mm）。ブロックを戻すか measure をやり直してください
[RTD   ] [WARN]   画素の差 409.7px（許容 10.3px = 5.0mm）/ mm 換算の差 193.73mm
[RTD   ] [WARN]   つかみ損ねる可能性があります。気になるなら Enter の前に measure を取り直してください
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_123756
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_123756/teach/drag_v2_20261109_123000.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_123756/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 1.93° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=1.93° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.015s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 12.0s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.94° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.035s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=0.88° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.012s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (PICK → APPROACH_PICK (lift), max|Δ|=2.02° <= tol 3.0°)
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 12.0s)
[RTD   ] 送信 OK（daemon 往復 1.055s）
[RTD   ] arrival OK (APPROACH_PICK → APPROACH_PLACE, max|Δ|=2.64° <= tol 3.0°)
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=1.76° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.08° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.004s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.032s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.64° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 9.4s)
[RTD   ] 送信 OK（daemon 往復 1.059s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.46° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 54/54 回, 実効 1.57 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（1.57 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.039s / p50 1.032s / 最大 1.059s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.059s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 2.18s / 最大 4.42s
[RECORD] 電流の記録終了 69 行 (2.0 行/秒. 本体が眠っている間だけ読む. 爪の間 14.044 秒は読まない. 見込み超え 0 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_123756/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > y
[RTD   ] 箱に入ったか (y/n) > y
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_123756/run_0001_20261109_123756.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=yes place=yes recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_123756 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20261109_123000.json --execute
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20261109_123000.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_xv19h0b5/drag_v2_20261109_123000.json
[RTD   ] 入力ファイル: drag_v2_20261109_123000.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=146 (start=146 end=194, gap=25.14°)
                    angles = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
  PICK           <- gripper close mark idx=214（PICK phase 範囲内）
                    angles = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=286 (start=286 end=321, gap=20.83°)
                    angles = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
  PLACE          <- gripper open mark idx=345（PLACE phase 範囲内）
                    angles = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 146 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 19.78°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  -0.26,   +1.49,   +1.93,   +0.08,   -0.26,  -30.23]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  -0.26,   +1.49,   +1.93,   +0.08,   -0.26,  -30.23]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 1.93°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 66.53°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 66.52°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 49.39°  1 回送信 speed=20  (~ 2.5s @ 20°/s 目安・到達待ち 最大 9.4s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 30.7s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 13.7s（max|Δ| 合計 274.4° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123559.json
[RTD   ]   measured_at = 2026-11-09T12:36:01.355235  block = (+54.8, +47.3) mm  box = (-220.3, +190.8) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] 再生直前: block = (+136.9, +226.1) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_123843.jpg
[RTD   ] [WARN] ブロックが measure 時から動いています（止めません・項目8）: ブロックが measure 時から 415.5px（≒196.8mm）動いています（許容 10.3px = 5.0mm）。ブロックを戻すか measure をやり直してください
[RTD   ] [WARN]   画素の差 415.5px（許容 10.3px = 5.0mm）/ mm 換算の差 196.76mm
[RTD   ] [WARN]   つかみ損ねる可能性があります。気になるなら Enter の前に measure を取り直してください
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_123848
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_123848/teach/drag_v2_20261109_123000.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_123848/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 1.93° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=1.93° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.016s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 12.0s)
[RTD   ] 送信 OK（daemon 往復 1.033s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.06° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.040s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=1.23° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.014s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.029s）
[RTD   ] arrival OK (PICK → APPROACH_PICK (lift), max|Δ|=2.02° <= tol 3.0°)
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 12.0s)
[RTD   ] 送信 OK（daemon 往復 1.032s）
[RTD   ] arrival OK (APPROACH_PICK → APPROACH_PLACE, max|Δ|=2.64° <= tol 3.0°)
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.030s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=2.20° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.08° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.013s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.72° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 9.4s)
[RTD   ] 送信 OK（daemon 往復 1.030s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.46° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 56/56 回, 実効 1.60 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（1.60 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.032s / p50 1.031s / 最大 1.040s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.040s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 2.26s / 最大 4.61s
[RECORD] 電流の記録終了 73 行 (2.08 行/秒. 本体が眠っている間だけ読む. 爪の間 14.062 秒は読まない. 見込み超え 0 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_123848/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > y
[RTD   ] 箱に入ったか (y/n) > y
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_123848/run_0001_20261109_123848.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=yes place=yes recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_123848 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20261109_123000.json --execute
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20261109_123000.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_mqlncefe/drag_v2_20261109_123000.json
[RTD   ] 入力ファイル: drag_v2_20261109_123000.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=146 (start=146 end=194, gap=25.14°)
                    angles = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
  PICK           <- gripper close mark idx=214（PICK phase 範囲内）
                    angles = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=286 (start=286 end=321, gap=20.83°)
                    angles = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
  PLACE          <- gripper open mark idx=345（PLACE phase 範囲内）
                    angles = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 146 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 19.78°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  -0.43,   +1.49,   +1.93,   +0.08,   -0.26,  -30.23]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  -0.43,   +1.49,   +1.93,   +0.08,   -0.26,  -30.23]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 1.93°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 66.53°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 66.52°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 49.39°  1 回送信 speed=20  (~ 2.5s @ 20°/s 目安・到達待ち 最大 9.4s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 30.7s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 13.7s（max|Δ| 合計 274.4° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123559.json
[RTD   ]   measured_at = 2026-11-09T12:36:01.355235  block = (+54.8, +47.3) mm  box = (-220.3, +190.8) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] 再生直前: block = (+137.1, +235.5) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_123937.jpg
[RTD   ] [WARN] ブロックが measure 時から動いています（止めません・項目8）: ブロックが measure 時から 433.7px（≒205.5mm）動いています（許容 10.3px = 5.0mm）。ブロックを戻すか measure をやり直してください
[RTD   ] [WARN]   画素の差 433.7px（許容 10.3px = 5.0mm）/ mm 換算の差 205.46mm
[RTD   ] [WARN]   つかみ損ねる可能性があります。気になるなら Enter の前に measure を取り直してください
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_123940
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_123940/teach/drag_v2_20261109_123000.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_123940/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 1.93° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=1.93° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.013s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 12.0s)
[RTD   ] 送信 OK（daemon 往復 1.049s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.94° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=0.88° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.002s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.041s）
[RTD   ] arrival OK (PICK → APPROACH_PICK (lift), max|Δ|=2.02° <= tol 3.0°)
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 12.0s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (APPROACH_PICK → APPROACH_PLACE, max|Δ|=2.64° <= tol 3.0°)
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.056s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=2.02° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.08° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.014s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.90° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 9.4s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.46° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 56/56 回, 実効 1.60 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（1.60 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.038s / p50 1.032s / 最大 1.056s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.056s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 2.26s / 最大 4.41s
[RECORD] 電流の記録終了 73 行 (2.08 行/秒. 本体が眠っている間だけ読む. 爪の間 14.048 秒は読まない. 見込み超え 0 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_123940/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > y
[RTD   ] 箱に入ったか (y/n) > y
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_123940/run_0001_20261109_123940.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=yes place=yes recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_123940 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20261109_123000.json --execute
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20261109_123000.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_buxu9ak6/drag_v2_20261109_123000.json
[RTD   ] 入力ファイル: drag_v2_20261109_123000.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=146 (start=146 end=194, gap=25.14°)
                    angles = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
  PICK           <- gripper close mark idx=214（PICK phase 範囲内）
                    angles = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=286 (start=286 end=321, gap=20.83°)
                    angles = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
  PLACE          <- gripper open mark idx=345（PLACE phase 範囲内）
                    angles = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 146 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 19.78°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  -0.43,   +1.49,   +1.93,   +0.08,   -0.26,  -30.23]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  -0.43,   +1.49,   +1.93,   +0.08,   -0.26,  -30.23]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 1.93°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 66.53°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 66.52°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 49.39°  1 回送信 speed=20  (~ 2.5s @ 20°/s 目安・到達待ち 最大 9.4s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 30.7s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 13.7s（max|Δ| 合計 274.4° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123559.json
[RTD   ]   measured_at = 2026-11-09T12:36:01.355235  block = (+54.8, +47.3) mm  box = (-220.3, +190.8) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] 再生直前: block = (+134.4, +234.6) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_124029.jpg
[RTD   ] [WARN] ブロックが measure 時から動いています（止めません・項目8）: ブロックが measure 時から 429.4px（≒203.6mm）動いています（許容 10.3px = 5.0mm）。ブロックを戻すか measure をやり直してください
[RTD   ] [WARN]   画素の差 429.4px（許容 10.3px = 5.0mm）/ mm 換算の差 203.58mm
[RTD   ] [WARN]   つかみ損ねる可能性があります。気になるなら Enter の前に measure を取り直してください
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124032
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124032/teach/drag_v2_20261109_123000.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124032/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 1.93° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=1.93° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.004s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 12.0s)
[RTD   ] 送信 OK（daemon 往復 1.028s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.32° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=0.88° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.012s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (PICK → APPROACH_PICK (lift), max|Δ|=2.02° <= tol 3.0°)
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 12.0s)
[RTD   ] 送信 OK（daemon 往復 1.042s）
[RTD   ] arrival OK (APPROACH_PICK → APPROACH_PLACE, max|Δ|=2.64° <= tol 3.0°)
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=2.11° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.08° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.012s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.021s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.72° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 9.4s)
[RTD   ] 送信 OK（daemon 往復 1.040s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.46° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 54/54 回, 実効 1.57 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（1.57 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.032s / p50 1.031s / 最大 1.042s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.042s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 2.18s / 最大 4.46s
[RECORD] 電流の記録終了 69 行 (2.0 行/秒. 本体が眠っている間だけ読む. 爪の間 14.04 秒は読まない. 見込み超え 0 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124032/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > y
[RTD   ] 箱に入ったか (y/n) > y
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124032/run_0001_20261109_124032.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=yes place=yes recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_124032 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20261109_123000.json --execute
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20261109_123000.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_htztmv7s/drag_v2_20261109_123000.json
[RTD   ] 入力ファイル: drag_v2_20261109_123000.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=146 (start=146 end=194, gap=25.14°)
                    angles = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
  PICK           <- gripper close mark idx=214（PICK phase 範囲内）
                    angles = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=286 (start=286 end=321, gap=20.83°)
                    angles = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
  PLACE          <- gripper open mark idx=345（PLACE phase 範囲内）
                    angles = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 146 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 19.78°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  -0.43,   +1.49,   +1.84,   +0.00,   -0.61,  -30.32]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  -0.43,   +1.49,   +1.84,   +0.00,   -0.61,  -30.32]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 1.84°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 66.53°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 66.52°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 49.39°  1 回送信 speed=20  (~ 2.5s @ 20°/s 目安・到達待ち 最大 9.4s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 30.7s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 13.7s（max|Δ| 合計 274.4° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123559.json
[RTD   ]   measured_at = 2026-11-09T12:36:01.355235  block = (+54.8, +47.3) mm  box = (-220.3, +190.8) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] 再生直前: block = (+133.4, +226.6) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_124113.jpg
[RTD   ] [WARN] ブロックが measure 時から動いています（止めません・項目8）: ブロックが measure 時から 413.1px（≒195.8mm）動いています（許容 10.3px = 5.0mm）。ブロックを戻すか measure をやり直してください
[RTD   ] [WARN]   画素の差 413.1px（許容 10.3px = 5.0mm）/ mm 換算の差 195.80mm
[RTD   ] [WARN]   つかみ損ねる可能性があります。気になるなら Enter の前に measure を取り直してください
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124117
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124117/teach/drag_v2_20261109_123000.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124117/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 1.84° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=1.84° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.013s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 12.0s)
[RTD   ] 送信 OK（daemon 往復 1.029s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.94° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=1.05° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.013s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.032s）
[RTD   ] arrival OK (PICK → APPROACH_PICK (lift), max|Δ|=2.02° <= tol 3.0°)
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 12.0s)
[RTD   ] 送信 OK（daemon 往復 1.057s）
[RTD   ] arrival OK (APPROACH_PICK → APPROACH_PLACE, max|Δ|=2.64° <= tol 3.0°)
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.032s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=2.29° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.004s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.81° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 9.4s)
[RTD   ] 送信 OK（daemon 往復 1.050s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.46° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 53/53 回, 実効 1.55 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（1.55 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.038s / p50 1.032s / 最大 1.057s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.057s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 2.14s / 最大 4.41s
[RECORD] 電流の記録終了 67 行 (1.96 行/秒. 本体が眠っている間だけ読む. 爪の間 14.055 秒は読まない. 見込み超え 0 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124117/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > y
[RTD   ] 箱に入ったか (y/n) > y
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124117/run_0001_20261109_124117.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=yes place=yes recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_124117 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20261109_123000.json --execute
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20261109_123000.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_l6l42858/drag_v2_20261109_123000.json
[RTD   ] 入力ファイル: drag_v2_20261109_123000.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=146 (start=146 end=194, gap=25.14°)
                    angles = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
  PICK           <- gripper close mark idx=214（PICK phase 範囲内）
                    angles = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=286 (start=286 end=321, gap=20.83°)
                    angles = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
  PLACE          <- gripper open mark idx=345（PLACE phase 範囲内）
                    angles = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 146 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 19.78°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  -0.43,   +1.49,   +1.93,   +0.08,   -0.35,  -30.23]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  -0.43,   +1.49,   +1.93,   +0.08,   -0.35,  -30.23]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 1.93°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 66.53°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 66.52°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 49.39°  1 回送信 speed=20  (~ 2.5s @ 20°/s 目安・到達待ち 最大 9.4s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 30.7s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 13.7s（max|Δ| 合計 274.4° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123559.json
[RTD   ]   measured_at = 2026-11-09T12:36:01.355235  block = (+54.8, +47.3) mm  box = (-220.3, +190.8) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] 再生直前: block = (+134.3, +227.0) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_124203.jpg
[RTD   ] [WARN] ブロックが measure 時から動いています（止めません・項目8）: ブロックが measure 時から 414.8px（≒196.6mm）動いています（許容 10.3px = 5.0mm）。ブロックを戻すか measure をやり直してください
[RTD   ] [WARN]   画素の差 414.8px（許容 10.3px = 5.0mm）/ mm 換算の差 196.58mm
[RTD   ] [WARN]   つかみ損ねる可能性があります。気になるなら Enter の前に measure を取り直してください
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124207
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124207/teach/drag_v2_20261109_123000.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124207/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 1.93° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=1.93° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.004s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 12.0s)
[RTD   ] 送信 OK（daemon 往復 1.040s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.85° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.033s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=0.88° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.013s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.030s）
[RTD   ] arrival OK (PICK → APPROACH_PICK (lift), max|Δ|=2.02° <= tol 3.0°)
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 12.0s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (APPROACH_PICK → APPROACH_PLACE, max|Δ|=2.55° <= tol 3.0°)
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=2.02° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.08° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.013s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.032s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.46° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 9.4s)
[RTD   ] 送信 OK（daemon 往復 1.040s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.28° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 54/54 回, 実効 1.57 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（1.57 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.034s / p50 1.032s / 最大 1.040s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.040s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 2.17s / 最大 4.42s
[RECORD] 電流の記録終了 69 行 (2.01 行/秒. 本体が眠っている間だけ読む. 爪の間 14.044 秒は読まない. 見込み超え 0 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124207/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > y
[RTD   ] 箱に入ったか (y/n) > y
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124207/run_0001_20261109_124207.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=yes place=yes recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_124207 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20261109_123000.json --execute
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20261109_123000.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_b4kxq_6u/drag_v2_20261109_123000.json
[RTD   ] 入力ファイル: drag_v2_20261109_123000.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=146 (start=146 end=194, gap=25.14°)
                    angles = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
  PICK           <- gripper close mark idx=214（PICK phase 範囲内）
                    angles = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=286 (start=286 end=321, gap=20.83°)
                    angles = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
  PLACE          <- gripper open mark idx=345（PLACE phase 範囲内）
                    angles = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 146 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 19.78°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  -0.43,   +1.49,   +1.93,   +0.08,   -0.26,  -30.23]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  -0.43,   +1.49,   +1.93,   +0.08,   -0.26,  -30.23]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 1.93°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 66.53°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 66.52°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 49.39°  1 回送信 speed=20  (~ 2.5s @ 20°/s 目安・到達待ち 最大 9.4s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 30.7s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 13.7s（max|Δ| 合計 274.4° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123559.json
[RTD   ]   measured_at = 2026-11-09T12:36:01.355235  block = (+54.8, +47.3) mm  box = (-220.3, +190.8) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] 再生直前: block = (+128.7, +232.8) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_124253.jpg
[RTD   ] [WARN] ブロックが measure 時から動いています（止めません・項目8）: ブロックが measure 時から 420.6px（≒199.7mm）動いています（許容 10.3px = 5.0mm）。ブロックを戻すか measure をやり直してください
[RTD   ] [WARN]   画素の差 420.6px（許容 10.3px = 5.0mm）/ mm 換算の差 199.71mm
[RTD   ] [WARN]   つかみ損ねる可能性があります。気になるなら Enter の前に measure を取り直してください
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124256
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124256/teach/drag_v2_20261109_123000.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124256/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 1.93° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=1.93° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.016s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 12.0s)
[RTD   ] 送信 OK（daemon 往復 1.032s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.14° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.055s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=0.88° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.013s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.032s）
[RTD   ] arrival OK (PICK → APPROACH_PICK (lift), max|Δ|=2.02° <= tol 3.0°)
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 12.0s)
[RTD   ] 送信 OK（daemon 往復 1.048s）
[RTD   ] arrival OK (APPROACH_PICK → APPROACH_PLACE, max|Δ|=2.55° <= tol 3.0°)
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.022s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=1.93° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.08° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.013s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.028s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.81° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 9.4s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.46° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 55/55 回, 実効 1.58 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（1.58 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.036s / p50 1.032s / 最大 1.055s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.055s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 2.22s / 最大 4.60s
[RECORD] 電流の記録終了 71 行 (2.04 行/秒. 本体が眠っている間だけ読む. 爪の間 14.06 秒は読まない. 見込み超え 0 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124256/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > y
[RTD   ] 箱に入ったか (y/n) > y
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124256/run_0001_20261109_124256.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=yes place=yes recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_124256 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20261109_123000.json --execute
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20261109_123000.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_7bjpxg62/drag_v2_20261109_123000.json
[RTD   ] 入力ファイル: drag_v2_20261109_123000.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=146 (start=146 end=194, gap=25.14°)
                    angles = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
  PICK           <- gripper close mark idx=214（PICK phase 範囲内）
                    angles = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=286 (start=286 end=321, gap=20.83°)
                    angles = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
  PLACE          <- gripper open mark idx=345（PLACE phase 範囲内）
                    angles = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 146 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 19.78°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  -0.43,   +1.49,   +1.84,   +0.08,   -0.26,  -30.23]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  -0.43,   +1.49,   +1.84,   +0.08,   -0.26,  -30.23]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 1.84°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 66.53°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 66.52°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 49.39°  1 回送信 speed=20  (~ 2.5s @ 20°/s 目安・到達待ち 最大 9.4s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 30.7s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 13.7s（max|Δ| 合計 274.4° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123559.json
[RTD   ]   measured_at = 2026-11-09T12:36:01.355235  block = (+54.8, +47.3) mm  box = (-220.3, +190.8) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] 再生直前: block = (+55.3, +46.8) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_124435.jpg
[RTD   ] 何を拾ったかは確認画像で見てください: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_124435.jpg
[RTD   ] [WARN] 検出したブロックがアームの根元から 72.4mm しか離れていません（120.0mm 以内は不可）。教示で使う位置は 200mm 以上離れているので、赤いケーブル等の別のものを拾っている可能性が高いです: (+55.3, +46.8) mm（**止めません**・WARN のみ）
[RTD   ] ブロック位置の照合 OK（画素の差 1.4px <= 許容 10.3px = 5.0mm / mm 換算の差 0.66mm）
[RTD   ] マット四隅のずれ 最大 0.7px（上限 15.0px・やり直し 1 回）
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124438
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124438/teach/drag_v2_20261109_123000.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124438/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 1.84° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=1.84° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.012s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 12.0s)
[RTD   ] 送信 OK（daemon 往復 1.032s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.23° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.039s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=0.88° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.011s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (PICK → APPROACH_PICK (lift), max|Δ|=2.02° <= tol 3.0°)
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 12.0s)
[RTD   ] 送信 OK（daemon 往復 1.029s）
[RTD   ] arrival OK (APPROACH_PICK → APPROACH_PLACE, max|Δ|=2.64° <= tol 3.0°)
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.030s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=2.02° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.012s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.029s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.72° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 9.4s)
[RTD   ] 送信 OK（daemon 往復 1.037s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.46° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 54/54 回, 実効 1.51 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（1.51 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.032s / p50 1.031s / 最大 1.039s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.039s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 2.34s / 最大 4.47s
[RECORD] 電流の記録終了 69 行 (1.93 行/秒. 本体が眠っている間だけ読む. 爪の間 14.055 秒は読まない. 見込み超え 0 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124438/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > y
[RTD   ] 箱に入ったか (y/n) > y
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124438/run_0001_20261109_124438.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=yes place=yes recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_124438 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20261109_123000.json --execute
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20261109_123000.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_gl8upm_g/drag_v2_20261109_123000.json
[RTD   ] 入力ファイル: drag_v2_20261109_123000.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=146 (start=146 end=194, gap=25.14°)
                    angles = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
  PICK           <- gripper close mark idx=214（PICK phase 範囲内）
                    angles = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=286 (start=286 end=321, gap=20.83°)
                    angles = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
  PLACE          <- gripper open mark idx=345（PLACE phase 範囲内）
                    angles = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 146 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 19.78°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  -0.43,   +1.49,   +1.84,   +0.08,   -0.26,  -30.23]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  -0.43,   +1.49,   +1.84,   +0.08,   -0.26,  -30.23]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 1.84°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 66.53°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 66.52°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 49.39°  1 回送信 speed=20  (~ 2.5s @ 20°/s 目安・到達待ち 最大 9.4s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 30.7s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 13.7s（max|Δ| 合計 274.4° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123559.json
[RTD   ]   measured_at = 2026-11-09T12:36:01.355235  block = (+54.8, +47.3) mm  box = (-220.3, +190.8) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] 再生直前: block = (+142.1, +212.7) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_124527.jpg
[RTD   ] [WARN] ブロックが measure 時から動いています（止めません・項目8）: ブロックが measure 時から 396.1px（≒187.0mm）動いています（許容 10.3px = 5.0mm）。ブロックを戻すか measure をやり直してください
[RTD   ] [WARN]   画素の差 396.1px（許容 10.3px = 5.0mm）/ mm 換算の差 187.04mm
[RTD   ] [WARN]   つかみ損ねる可能性があります。気になるなら Enter の前に measure を取り直してください
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124530
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124530/teach/drag_v2_20261109_123000.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124530/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 1.84° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=1.84° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.013s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 12.0s)
[RTD   ] 送信 OK（daemon 往復 1.052s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.32° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=2.72° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.013s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.029s）
[RTD   ] [WARN] arrival timeout (PICK → APPROACH_PICK (lift), max|Δ|=41.75° > tol 3.0°, 8.0s)
[RTD   ] [WARN] 到達確認タイムアウト（max|Δ|=41.75° > tol 3.0°）ですが pre→last max|Δ| 44.30° >= 1.0°（動いているので再送しない）。**止めずに次の区間へ進みます**
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 12.0s)
[RTD   ] 送信 OK（daemon 往復 1.030s）
[RTD   ] [WARN] arrival timeout (APPROACH_PICK → APPROACH_PLACE, max|Δ|=36.48° > tol 3.0°, 12.0s)
[RTD   ] [WARN] 到達確認タイムアウト（max|Δ|=36.48° > tol 3.0°）ですが pre→last max|Δ| 67.13° >= 1.0°（動いているので再送しない）。**止めずに次の区間へ進みます**
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.051s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=2.90° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 1.76° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.013s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.029s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.37° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 9.4s)
[RTD   ] 送信 OK（daemon 往復 1.041s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.46° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 131/131 回, 実効 2.19 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（2.19 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.038s / p50 1.031s / 最大 1.052s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.052s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 5.32s / 最大 13.32s
[RECORD] 電流の記録終了 227 行 (3.79 行/秒. 本体が眠っている間だけ読む. 爪の間 14.057 秒は読まない. 見込み超え 0 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124530/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > n
[RTD   ] 箱に入ったか (y/n) > n
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124530/run_0001_20261109_124530.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=no place=no recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_124530 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 pi05/camera_align.py --raw-dir /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/align_ref
[REF   ] 基準画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/align_ref/run_0001_20261109_124117/frames/000000.jpg
[REF   ] お手本 run_0001_20261109_124117 (つかんだ瞬間が不明)  ← --episode 未指定なので最初のエピソード
[REF   ] 重なった画像のブロックに実物のブロックを合わせると, お手本と同じ位置に置ける
[ALIGN ] |dy| <= 20 なら OK. アームは HOME に置いた状態で合わせる. q または Esc で終了 (ファイルには何も書かない)
[ALIGN ] dy=  +0.9  dx=  -0.8  response=0.671  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[ALIGN ] dy=  -0.8  dx=  -0.1  response=0.705  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[ALIGN ] dy=  +0.7  dx=  -0.9  response=0.673  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[DONE  ] 終了 (何も書いていません)
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20261109_123000.json --execute
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20261109_123000.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_8ws6r9vs/drag_v2_20261109_123000.json
[RTD   ] 入力ファイル: drag_v2_20261109_123000.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=146 (start=146 end=194, gap=25.14°)
                    angles = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
  PICK           <- gripper close mark idx=214（PICK phase 範囲内）
                    angles = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=286 (start=286 end=321, gap=20.83°)
                    angles = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
  PLACE          <- gripper open mark idx=345（PLACE phase 範囲内）
                    angles = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 146 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 19.78°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  -0.43,   +1.49,   +1.84,   -0.26,   -0.26,  -30.23]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  -0.43,   +1.49,   +1.84,   -0.26,   -0.26,  -30.23]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 1.84°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 66.53°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 66.52°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 49.39°  1 回送信 speed=20  (~ 2.5s @ 20°/s 目安・到達待ち 最大 9.4s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 30.7s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 13.7s（max|Δ| 合計 274.4° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123559.json
[RTD   ]   measured_at = 2026-11-09T12:36:01.355235  block = (+54.8, +47.3) mm  box = (-220.3, +190.8) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] 再生直前: block = (+141.0, +229.3) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_124812.jpg
[RTD   ] [WARN] ブロックが measure 時から動いています（止めません・項目8）: ブロックが measure 時から 425.8px（≒201.4mm）動いています（許容 10.3px = 5.0mm）。ブロックを戻すか measure をやり直してください
[RTD   ] [WARN]   画素の差 425.8px（許容 10.3px = 5.0mm）/ mm 換算の差 201.41mm
[RTD   ] [WARN]   つかみ損ねる可能性があります。気になるなら Enter の前に measure を取り直してください
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124817
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124817/teach/drag_v2_20261109_123000.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124817/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 1.84° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=1.84° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.013s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 12.0s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.14° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.032s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=1.14° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.012s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.029s）
[RTD   ] arrival OK (PICK → APPROACH_PICK (lift), max|Δ|=2.02° <= tol 3.0°)
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 12.0s)
[RTD   ] 送信 OK（daemon 往復 1.054s）
[RTD   ] arrival OK (APPROACH_PICK → APPROACH_PLACE, max|Δ|=2.64° <= tol 3.0°)
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.040s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=2.37° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.08° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.004s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.039s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.55° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 9.4s)
[RTD   ] 送信 OK（daemon 往復 1.051s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.37° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 56/56 回, 実効 1.59 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（1.59 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.040s / p50 1.039s / 最大 1.054s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.054s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 2.27s / 最大 4.61s
[RECORD] 電流の記録終了 73 行 (2.07 行/秒. 本体が眠っている間だけ読む. 爪の間 14.046 秒は読まない. 見込み超え 0 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124817/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > y
[RTD   ] 箱に入ったか (y/n) > y
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124817/run_0001_20261109_124817.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=yes place=yes recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_124817 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 pi05/camera_align.py --raw-dir /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/align_ref
[REF   ] 基準画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/align_ref/run_0001_20261109_124117/frames/000000.jpg
[REF   ] お手本 run_0001_20261109_124117 (つかんだ瞬間が不明)  ← --episode 未指定なので最初のエピソード
[REF   ] 重なった画像のブロックに実物のブロックを合わせると, お手本と同じ位置に置ける
[ALIGN ] |dy| <= 20 なら OK. アームは HOME に置いた状態で合わせる. q または Esc で終了 (ファイルには何も書かない)
[ALIGN ] dy=  +0.8  dx=  -0.7  response=0.679  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[DONE  ] 終了 (何も書いていません)
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20261109_123000.json --execute
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20261109_123000.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_wcevrdkg/drag_v2_20261109_123000.json
[RTD   ] 入力ファイル: drag_v2_20261109_123000.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=146 (start=146 end=194, gap=25.14°)
                    angles = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
  PICK           <- gripper close mark idx=214（PICK phase 範囲内）
                    angles = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=286 (start=286 end=321, gap=20.83°)
                    angles = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
  PLACE          <- gripper open mark idx=345（PLACE phase 範囲内）
                    angles = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 146 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 19.78°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  -0.43,   +1.49,   +1.93,   +0.08,   -0.26,  -30.23]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  -0.43,   +1.49,   +1.93,   +0.08,   -0.26,  -30.23]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 1.93°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 66.53°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -25.48,  +68.20,   +8.43,   -1.58,  -66.53,  -30.14]
            to      = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            max |Δ| = 25.14°  1 回送信 speed=20  (~ 1.3s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -25.48,  +43.06,   +8.52,   -1.58,  -66.53,  -30.14]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 66.52°  1 回送信 speed=20  (~ 3.3s @ 20°/s 目安・到達待ち 最大 12.0s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +40.69,  +61.78,   +1.14,   +4.13,  -70.22,  -31.28]
            to      = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            max |Δ| = 20.83°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +41.04,  +42.36,   +1.66,   +2.54,  -49.39,  -31.90]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 49.39°  1 回送信 speed=20  (~ 2.5s @ 20°/s 目安・到達待ち 最大 9.4s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 30.7s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 13.7s（max|Δ| 合計 274.4° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123559.json
[RTD   ]   measured_at = 2026-11-09T12:36:01.355235  block = (+54.8, +47.3) mm  box = (-220.3, +190.8) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] 再生直前: block = (+55.2, +45.3) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_124917.jpg
[RTD   ] 何を拾ったかは確認画像で見てください: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_124917.jpg
[RTD   ] [WARN] 検出したブロックがアームの根元から 71.4mm しか離れていません（120.0mm 以内は不可）。教示で使う位置は 200mm 以上離れているので、赤いケーブル等の別のものを拾っている可能性が高いです: (+55.2, +45.3) mm（**止めません**・WARN のみ）
[RTD   ] ブロック位置の照合 OK（画素の差 4.1px <= 許容 10.3px = 5.0mm / mm 換算の差 1.98mm）
[RTD   ] マット四隅のずれ 最大 1.0px（上限 15.0px・やり直し 1 回）
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124920
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124920/teach/drag_v2_20261109_123000.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124920/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 1.93° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=1.93° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.004s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 12.0s)
[RTD   ] 送信 OK（daemon 往復 1.048s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.23° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.030s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=1.23° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.012s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (PICK → APPROACH_PICK (lift), max|Δ|=2.02° <= tol 3.0°)
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 12.0s)
[RTD   ] 送信 OK（daemon 往復 1.030s）
[RTD   ] arrival OK (APPROACH_PICK → APPROACH_PLACE, max|Δ|=2.64° <= tol 3.0°)
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.037s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=2.29° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.08° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.015s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.041s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.72° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 9.4s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.46° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 54/54 回, 実効 1.56 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（1.56 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.035s / p50 1.031s / 最大 1.048s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.048s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 2.19s / 最大 4.54s
[RECORD] 電流の記録終了 69 行 (1.99 行/秒. 本体が眠っている間だけ読む. 爪の間 14.052 秒は読まない. 見込み超え 0 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124920/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > y
[RTD   ] 箱に入ったか (y/n) > y
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_124920/run_0001_20261109_124920.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=yes place=yes recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_124920 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 pi05/camera_align.py --raw-dir /Volumes/KIOXIA/r2r2r-data/datasets/mecharm_redblock_box_teach_v1_trim2/raw_episodes --episode 193825
[REF   ] 基準画像: /Volumes/KIOXIA/r2r2r-data/datasets/mecharm_redblock_box_teach_v1_trim2/raw_episodes/run_0001_20261019_193825/frames/000000.jpg
[REF   ] お手本 run_0001_20261019_193825 (つかんだ瞬間の j0 = -61.5°)
[REF   ] 重なった画像のブロックに実物のブロックを合わせると, お手本と同じ位置に置ける
[ALIGN ] |dy| <= 20 なら OK. アームは HOME に置いた状態で合わせる. q または Esc で終了 (ファイルには何も書かない)
[ALIGN ] dy=  +3.2  dx=  -3.5  response=0.859  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[ALIGN ] dy=  +1.8  dx=  +6.2  response=0.927  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[ALIGN ] dy=  +0.7  dx=  +3.6  response=0.946  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[ALIGN ] dy=  +2.2  dx=  -3.6  response=0.895  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[ALIGN ] dy=  +3.8  dx=  -3.9  response=0.888  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[ALIGN ] dy=  +5.0  dx=  -3.4  response=0.894  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[ALIGN ] dy=  +3.9  dx=  -3.2  response=0.885  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[ALIGN ] dy=  +1.7  dx=  -2.0  response=0.930  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[ALIGN ] dy=  +0.7  dx=  -4.4  response=0.929  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[ALIGN ] dy=  +1.7  dx=  -7.4  response=0.892  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[ALIGN ] dy=  +0.4  dx=  -3.8  response=0.892  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[ALIGN ] dy=  +2.7  dx=  -4.2  response=0.898  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[ALIGN ] dy=  +3.9  dx=  -3.5  response=0.877  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[ALIGN ] dy=  +2.2  dx=  -2.3  response=0.912  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[ALIGN ] dy=  +0.2  dx=  -0.1  response=0.912  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[ALIGN ] dy=  -1.0  dx=  -1.1  response=0.935  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[DONE  ] 終了 (何も書いていません)
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20221013_232345.json --execute
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20221013_232345.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo__zfoteg1/drag_v2_20221013_232345.json
[RTD   ] 入力ファイル: drag_v2_20221013_232345.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=123 (start=123 end=197, gap=18.89°)
                    angles = [ -59.94,  +54.31,  +22.67,   +1.49,  -78.04,  -32.34]
  PICK           <- gripper close mark idx=223（PICK phase 範囲内）
                    angles = [ -62.05,  +61.69,  +13.71,   +0.87,  -59.15,  -32.34]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=304 (start=304 end=352, gap=18.81°)
                    angles = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
  PLACE          <- gripper open mark idx=367（PLACE phase 範囲内）
                    angles = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 165 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 11.96°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  -0.43,   +1.49,   +1.84,   +0.08,   -0.26,  -30.23]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  -0.43,   +1.49,   +1.84,   +0.08,   -0.26,  -30.23]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 1.84°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -59.94,  +54.31,  +22.67,   +1.49,  -78.04,  -32.34]
            max |Δ| = 78.04°  1 回送信 speed=20  (~ 3.9s @ 20°/s 目安・到達待ち 最大 13.7s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -59.94,  +54.31,  +22.67,   +1.49,  -78.04,  -32.34]
            to      = [ -62.05,  +61.69,  +13.71,   +0.87,  -59.15,  -32.34]
            max |Δ| = 18.89°  1 回送信 speed=20  (~ 0.9s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -62.05,  +61.69,  +13.71,   +0.87,  -59.15,  -32.34]
            to      = [ -59.94,  +54.31,  +22.67,   +1.49,  -78.04,  -32.34]
            max |Δ| = 18.89°  1 回送信 speed=20  (~ 0.9s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -59.94,  +54.31,  +22.67,   +1.49,  -78.04,  -32.34]
            to      = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            max |Δ| = 102.91°  1 回送信 speed=20  (~ 5.1s @ 20°/s 目安・到達待ち 最大 17.4s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            to      = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
            max |Δ| = 18.81°  1 回送信 speed=20  (~ 0.9s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
            to      = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            max |Δ| = 18.81°  1 回送信 speed=20  (~ 0.9s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 54.58°  1 回送信 speed=20  (~ 2.7s @ 20°/s 目安・到達待ち 最大 10.2s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 32.5s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 15.5s（max|Δ| 合計 310.9° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123559.json
[RTD   ]   measured_at = 2026-11-09T12:36:01.355235  block = (+54.8, +47.3) mm  box = (-220.3, +190.8) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] [WARN] 再生直前: 四隅が最大 16.5px ずれています（1 回目 / 上限 15.0px）。測り直します
[RTD   ] [WARN] 再生直前: 四隅が最大 16.5px ずれています（2 回目 / 上限 15.0px）。測り直します
[RTD   ] [WARN] 再生直前: 四隅が最大 16.5px ずれています（3 回目 / 上限 15.0px）。やり直しの上限に達しました
[RTD   ] 再生直前: block = (+237.4, +106.4) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_125202.jpg
[RTD   ] 弾いた理由と各回の記録を残しました: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_125202_rejected.json
[RTD   ] [WARN] マット四隅が measure 時から最大 16.5px ずれています（上限 15.0px・最大 3 回やり直しても収まらず）。カメラが動いた可能性があるので止めます。measure を取り直してください（各隅のずれ: 4.0, 10.0, 14.8, 16.5）（**止めません**・WARN のみ）
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_125209
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_125209/teach/drag_v2_20221013_232345.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_125209/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 1.84° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=1.84° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.014s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 13.7s)
[RTD   ] 送信 OK（daemon 往復 1.029s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.14° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.030s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=2.90° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.44° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.012s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.028s）
[RTD   ] [WARN] arrival timeout (PICK → APPROACH_PICK (lift), max|Δ|=10.72° > tol 3.0°, 8.0s)
[RTD   ] [WARN] 到達確認タイムアウト（max|Δ|=10.72° > tol 3.0°）ですが pre→last max|Δ| 8.97° >= 1.0°（動いているので再送しない）。**止めずに次の区間へ進みます**
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 17.4s)
[RTD   ] 送信 OK（daemon 往復 1.039s）
[RTD   ] [WARN] arrival timeout (APPROACH_PICK → APPROACH_PLACE, max|Δ|=7.39° > tol 3.0°, 17.5s)
[RTD   ] [WARN] 到達確認タイムアウト（max|Δ|=7.39° > tol 3.0°）ですが pre→last max|Δ| 103.35° >= 1.0°（動いているので再送しない）。**止めずに次の区間へ進みます**
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.034s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=1.41° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.016s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.028s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.11° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 10.2s)
[RTD   ] 送信 OK（daemon 往復 1.034s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.46° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 150/150 回, 実効 2.27 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（2.27 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.032s / p50 1.030s / 最大 1.039s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.039s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 6.14s / 最大 18.83s
[RECORD] 電流の記録終了 265 行 (4.0 行/秒. 本体が眠っている間だけ読む. 爪の間 14.065 秒は読まない. 見込み超え 0 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_125209/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > n
[RTD   ] 箱に入ったか (y/n) > n
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_125209/run_0001_20261109_125209.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=no place=no recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_125209 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 pi05/camera_align.py --raw-dir /Volumes/KIOXIA/r2r2r-data/datasets/mecharm_redblock_box_teach_v1_trim2/raw_episodes --episode 193825
[REF   ] 基準画像: /Volumes/KIOXIA/r2r2r-data/datasets/mecharm_redblock_box_teach_v1_trim2/raw_episodes/run_0001_20261019_193825/frames/000000.jpg
[REF   ] お手本 run_0001_20261019_193825 (つかんだ瞬間の j0 = -61.5°)
[REF   ] 重なった画像のブロックに実物のブロックを合わせると, お手本と同じ位置に置ける
[ALIGN ] |dy| <= 20 なら OK. アームは HOME に置いた状態で合わせる. q または Esc で終了 (ファイルには何も書かない)
[ALIGN ] dy=  -1.2  dx=  -1.6  response=0.836  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[DONE  ] 終了 (何も書いていません)
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % scp -i ~/.ssh/id_rsa_pi /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/drag_v2_20261109_130000.json ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/
python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20261109_130000.json
drag_v2_20261109_130000.json                                                   100%   38KB   2.2MB/s   00:00    
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: ドライラン（アームに何も送りません）
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20261109_130000.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_jlsxds3m/drag_v2_20261109_130000.json
[RTD   ] 入力ファイル: drag_v2_20261109_130000.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=123 (start=123 end=197, gap=20.00°)
                    angles = [ -62.05,  +41.69,  +13.71,   +0.87,  -59.15,  -32.34]
  PICK           <- gripper close mark idx=223（PICK phase 範囲内）
                    angles = [ -62.05,  +61.69,  +13.71,   +0.87,  -59.15,  -32.34]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=304 (start=304 end=352, gap=18.81°)
                    angles = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
  PLACE          <- gripper open mark idx=367（PLACE phase 範囲内）
                    angles = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 158 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 26.99°（しきい値 3.0° 以上）
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = 未取得（ドライラン・daemon に接続していない）
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -62.05,  +41.69,  +13.71,   +0.87,  -59.15,  -32.34]
            max |Δ| = 62.05°  1 回送信 speed=20  (~ 3.1s @ 20°/s 目安・到達待ち 最大 11.3s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -62.05,  +41.69,  +13.71,   +0.87,  -59.15,  -32.34]
            to      = [ -62.05,  +61.69,  +13.71,   +0.87,  -59.15,  -32.34]
            max |Δ| = 20.00°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -62.05,  +61.69,  +13.71,   +0.87,  -59.15,  -32.34]
            to      = [ -62.05,  +41.69,  +13.71,   +0.87,  -59.15,  -32.34]
            max |Δ| = 20.00°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -62.05,  +41.69,  +13.71,   +0.87,  -59.15,  -32.34]
            to      = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            max |Δ| = 105.02°  1 回送信 speed=20  (~ 5.3s @ 20°/s 目安・到達待ち 最大 17.8s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            to      = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
            max |Δ| = 18.81°  1 回送信 speed=20  (~ 0.9s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
            to      = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            max |Δ| = 18.81°  1 回送信 speed=20  (~ 0.9s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 54.58°  1 回送信 speed=20  (~ 2.7s @ 20°/s 目安・到達待ち 最大 10.2s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 32.0s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 15.0s（max|Δ| 合計 299.3° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123559.json
[RTD   ]   measured_at = 2026-11-09T12:36:01.355235  block = (+54.8, +47.3) mm  box = (-220.3, +190.8) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] [WARN] 再生直前: 四隅が最大 16.5px ずれています（1 回目 / 上限 15.0px）。測り直します
[RTD   ] [WARN] 再生直前: 四隅が最大 16.7px ずれています（2 回目 / 上限 15.0px）。測り直します
[RTD   ] [WARN] 再生直前: 四隅が最大 16.6px ずれています（3 回目 / 上限 15.0px）。やり直しの上限に達しました
[RTD   ] 再生直前: block = (+235.6, +100.7) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_125530.jpg
[RTD   ] 弾いた理由と各回の記録を残しました: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_125530_rejected.json
[RTD   ] [WARN] マット四隅が measure 時から最大 16.6px ずれています（上限 15.0px・最大 3 回やり直しても収まらず）。カメラが動いた可能性があるので止めます。measure を取り直してください（各隅のずれ: 4.0, 10.0, 16.6, 16.5）（**止めません**・WARN のみ）
[RTD   ] ドライランなので、ここで終了します（アームには何も送っていません）
[RTD   ] Pi 版と比べる点: 抽出ウェイポイント 4 姿勢と各区間の max|Δ| は同じ。送り方は単発（Pi 版は 0.1s 補間ストリーミング）なので n_steps / ticks は比較対象外。送信 8 回 / 想定所要 ≈ 32.0s
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20221013_232345.json --execute
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20221013_232345.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_solcgfb7/drag_v2_20221013_232345.json
[RTD   ] 入力ファイル: drag_v2_20221013_232345.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=123 (start=123 end=197, gap=18.89°)
                    angles = [ -59.94,  +54.31,  +22.67,   +1.49,  -78.04,  -32.34]
  PICK           <- gripper close mark idx=223（PICK phase 範囲内）
                    angles = [ -62.05,  +61.69,  +13.71,   +0.87,  -59.15,  -32.34]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=304 (start=304 end=352, gap=18.81°)
                    angles = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
  PLACE          <- gripper open mark idx=367（PLACE phase 範囲内）
                    angles = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 165 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 11.96°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  -0.43,   +1.49,   +2.46,   +0.26,   -0.26,  -30.23]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  -0.43,   +1.49,   +2.46,   +0.26,   -0.26,  -30.23]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 2.46°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -59.94,  +54.31,  +22.67,   +1.49,  -78.04,  -32.34]
            max |Δ| = 78.04°  1 回送信 speed=20  (~ 3.9s @ 20°/s 目安・到達待ち 最大 13.7s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -59.94,  +54.31,  +22.67,   +1.49,  -78.04,  -32.34]
            to      = [ -62.05,  +61.69,  +13.71,   +0.87,  -59.15,  -32.34]
            max |Δ| = 18.89°  1 回送信 speed=20  (~ 0.9s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -62.05,  +61.69,  +13.71,   +0.87,  -59.15,  -32.34]
            to      = [ -59.94,  +54.31,  +22.67,   +1.49,  -78.04,  -32.34]
            max |Δ| = 18.89°  1 回送信 speed=20  (~ 0.9s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -59.94,  +54.31,  +22.67,   +1.49,  -78.04,  -32.34]
            to      = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            max |Δ| = 102.91°  1 回送信 speed=20  (~ 5.1s @ 20°/s 目安・到達待ち 最大 17.4s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            to      = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
            max |Δ| = 18.81°  1 回送信 speed=20  (~ 0.9s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
            to      = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            max |Δ| = 18.81°  1 回送信 speed=20  (~ 0.9s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 54.58°  1 回送信 speed=20  (~ 2.7s @ 20°/s 目安・到達待ち 最大 10.2s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 32.5s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 15.5s（max|Δ| 合計 310.9° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123559.json
[RTD   ]   measured_at = 2026-11-09T12:36:01.355235  block = (+54.8, +47.3) mm  box = (-220.3, +190.8) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] [WARN] 再生直前: 四隅が最大 16.5px ずれています（1 回目 / 上限 15.0px）。測り直します
[RTD   ] [WARN] 再生直前: 四隅が最大 16.5px ずれています（2 回目 / 上限 15.0px）。測り直します
[RTD   ] [WARN] 再生直前: 四隅が最大 16.5px ずれています（3 回目 / 上限 15.0px）。やり直しの上限に達しました
[RTD   ] 再生直前: block = (+235.6, +100.7) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_125558.jpg
[RTD   ] 弾いた理由と各回の記録を残しました: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_125558_rejected.json
[RTD   ] [WARN] マット四隅が measure 時から最大 16.5px ずれています（上限 15.0px・最大 3 回やり直しても収まらず）。カメラが動いた可能性があるので止めます。measure を取り直してください（各隅のずれ: 4.0, 10.0, 15.7, 16.5）（**止めません**・WARN のみ）
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_125607
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_125607/teach/drag_v2_20221013_232345.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_125607/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 2.46° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=2.46° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.014s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 13.7s)
[RTD   ] 送信 OK（daemon 往復 1.032s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.06° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.054s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=2.98° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.08° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.011s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (PICK → APPROACH_PICK (lift), max|Δ|=2.37° <= tol 3.0°)
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 17.4s)
[RTD   ] 送信 OK（daemon 往復 1.029s）
[RTD   ] [WARN] arrival timeout (APPROACH_PICK → APPROACH_PLACE, max|Δ|=35.51° > tol 3.0°, 17.5s)
[RTD   ] [WARN] 到達確認タイムアウト（max|Δ|=35.51° > tol 3.0°）ですが pre→last max|Δ| 103.53° >= 1.0°（動いているので再送しない）。**止めずに次の区間へ進みます**
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.029s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=2.19° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.17° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.012s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.19° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 10.2s)
[RTD   ] 送信 OK（daemon 往復 1.030s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.10° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 139/139 回, 実効 2.21 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（2.21 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.034s / p50 1.031s / 最大 1.054s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.054s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 5.72s / 最大 18.86s
[RECORD] 電流の記録終了 239 行 (3.8 行/秒. 本体が眠っている間だけ読む. 爪の間 14.057 秒は読まない. 見込み超え 2 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_125607/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > n
[RTD   ] 箱に入ったか (y/n) > n
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_125607/run_0001_20261109_125607.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=no place=no recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_125607 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 pi05/camera_align.py --raw-dir /Volumes/KIOXIA/r2r2r-data/datasets/mecharm_redblock_box_teach_v1_trim2/raw_episodes --episode 193825
[REF   ] 基準画像: /Volumes/KIOXIA/r2r2r-data/datasets/mecharm_redblock_box_teach_v1_trim2/raw_episodes/run_0001_20261019_193825/frames/000000.jpg
[REF   ] お手本 run_0001_20261019_193825 (つかんだ瞬間の j0 = -61.5°)
[REF   ] 重なった画像のブロックに実物のブロックを合わせると, お手本と同じ位置に置ける
[ALIGN ] |dy| <= 20 なら OK. アームは HOME に置いた状態で合わせる. q または Esc で終了 (ファイルには何も書かない)
[ALIGN ] dy=  -1.2  dx=  -1.7  response=0.432  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[DONE  ] 終了 (何も書いていません)
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20261109_130000.json --execute
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20261109_130000.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_0c3b7wly/drag_v2_20261109_130000.json
[RTD   ] 入力ファイル: drag_v2_20261109_130000.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=123 (start=123 end=197, gap=20.00°)
                    angles = [ -62.05,  +41.69,  +13.71,   +0.87,  -59.15,  -32.34]
  PICK           <- gripper close mark idx=223（PICK phase 範囲内）
                    angles = [ -62.05,  +61.69,  +13.71,   +0.87,  -59.15,  -32.34]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=304 (start=304 end=352, gap=18.81°)
                    angles = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
  PLACE          <- gripper open mark idx=367（PLACE phase 範囲内）
                    angles = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 158 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 26.99°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  -0.43,   +1.49,   +2.10,   -0.26,   -0.26,  -29.70]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  -0.43,   +1.49,   +2.10,   -0.26,   -0.26,  -29.70]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 2.10°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -62.05,  +41.69,  +13.71,   +0.87,  -59.15,  -32.34]
            max |Δ| = 62.05°  1 回送信 speed=20  (~ 3.1s @ 20°/s 目安・到達待ち 最大 11.3s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -62.05,  +41.69,  +13.71,   +0.87,  -59.15,  -32.34]
            to      = [ -62.05,  +61.69,  +13.71,   +0.87,  -59.15,  -32.34]
            max |Δ| = 20.00°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -62.05,  +61.69,  +13.71,   +0.87,  -59.15,  -32.34]
            to      = [ -62.05,  +41.69,  +13.71,   +0.87,  -59.15,  -32.34]
            max |Δ| = 20.00°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -62.05,  +41.69,  +13.71,   +0.87,  -59.15,  -32.34]
            to      = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            max |Δ| = 105.02°  1 回送信 speed=20  (~ 5.3s @ 20°/s 目安・到達待ち 最大 17.8s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            to      = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
            max |Δ| = 18.81°  1 回送信 speed=20  (~ 0.9s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
            to      = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            max |Δ| = 18.81°  1 回送信 speed=20  (~ 0.9s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 54.58°  1 回送信 speed=20  (~ 2.7s @ 20°/s 目安・到達待ち 最大 10.2s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 32.0s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 15.0s（max|Δ| 合計 299.3° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123559.json
[RTD   ]   measured_at = 2026-11-09T12:36:01.355235  block = (+54.8, +47.3) mm  box = (-220.3, +190.8) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] [WARN] 再生直前: 四隅が最大 16.8px ずれています（1 回目 / 上限 15.0px）。測り直します
[RTD   ] [WARN] 再生直前: 四隅が最大 16.5px ずれています（2 回目 / 上限 15.0px）。測り直します
[RTD   ] [WARN] 再生直前: 四隅が最大 16.5px ずれています（3 回目 / 上限 15.0px）。やり直しの上限に達しました
[RTD   ] 再生直前: block = (+234.3, +104.0) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_125818.jpg
[RTD   ] 弾いた理由と各回の記録を残しました: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_125818_rejected.json
[RTD   ] [WARN] マット四隅が measure 時から最大 16.5px ずれています（上限 15.0px・最大 3 回やり直しても収まらず）。カメラが動いた可能性があるので止めます。measure を取り直してください（各隅のずれ: 4.0, 10.0, 15.9, 16.5）（**止めません**・WARN のみ）
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_125825
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_125825/teach/drag_v2_20261109_130000.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_125825/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 2.10° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=2.10° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.015s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 11.3s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.94° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=2.98° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.013s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] [WARN] arrival timeout (PICK → APPROACH_PICK (lift), max|Δ|=23.30° > tol 3.0°, 8.0s)
[RTD   ] [WARN] 到達確認タイムアウト（max|Δ|=23.30° > tol 3.0°）ですが pre→last max|Δ| 26.28° >= 1.0°（動いているので再送しない）。**止めずに次の区間へ進みます**
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 17.8s)
[RTD   ] 送信 OK（daemon 往復 1.038s）
[RTD   ] [WARN] arrival timeout (APPROACH_PICK → APPROACH_PLACE, max|Δ|=39.20° > tol 3.0°, 17.7s)
[RTD   ] [WARN] 到達確認タイムアウト（max|Δ|=39.20° > tol 3.0°）ですが pre→last max|Δ| 104.58° >= 1.0°（動いているので再送しない）。**止めずに次の区間へ進みます**
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=2.81° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.26° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.012s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.040s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.19° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 10.2s)
[RTD   ] 送信 OK（daemon 往復 1.030s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.19° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 152/152 回, 実効 2.27 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（2.27 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.033s / p50 1.031s / 最大 1.040s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.040s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 6.23s / 最大 18.83s
[RECORD] 電流の記録終了 269 行 (4.01 行/秒. 本体が眠っている間だけ読む. 爪の間 14.056 秒は読まない. 見込み超え 0 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_125825/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > n
[RTD   ] 箱に入ったか (y/n) > n
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_125825/run_0001_20261109_125825.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=no place=no recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_125825 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 pi05/camera_align.py --raw-dir /Volumes/KIOXIA/r2r2r-data/datasets/mecharm_redblock_box_teach_v1_trim2/raw_episodes --episode 193825
[REF   ] 基準画像: /Volumes/KIOXIA/r2r2r-data/datasets/mecharm_redblock_box_teach_v1_trim2/raw_episodes/run_0001_20261019_193825/frames/000000.jpg
[REF   ] お手本 run_0001_20261019_193825 (つかんだ瞬間の j0 = -61.5°)
[REF   ] 重なった画像のブロックに実物のブロックを合わせると, お手本と同じ位置に置ける
[ALIGN ] |dy| <= 20 なら OK. アームは HOME に置いた状態で合わせる. q または Esc で終了 (ファイルには何も書かない)
[ALIGN ] dy=  -1.0  dx=  -1.7  response=0.883  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[DONE  ] 終了 (何も書いていません)
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 tools/gamepad_teleop.py --execute
/opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/pkgdata.py:25: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.
  from pkg_resources import resource_stream, resource_exists
objc[17606]: Class SDLApplication is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x106cf12c8) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10fa60890). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[17606]: Class SDLAppDelegate is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x106cf1318) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10fa608e0). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[17606]: Class SDLTranslatorResponder is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x106cf1390) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10fa60958). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[17606]: Class SDLMessageBoxPresenter is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x106cf13b8) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10fa60980). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[17606]: Class SDL_cocoametalview is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x106cf1408) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10fa609d0). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[17606]: Class SDLOpenGLContext is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x106cf1458) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10fa60a20). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[17606]: Class SDL_ShapeData is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x106cf14d0) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10fa60a98). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[17606]: Class SDL_CocoaClosure is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x106cf1520) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10fa60ae8). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[17606]: Class SDL_VideoData is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x106cf1570) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10fa60b38). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[17606]: Class SDL_WindowData is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x106cf15c0) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10fa60b88). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[17606]: Class SDLWindow is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x106cf15e8) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10fa60bb0). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[17606]: Class Cocoa_WindowListener is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x106cf1610) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10fa60bd8). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[17606]: Class SDLView is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x106cf1688) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10fa60c50). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[17606]: Class METAL_RenderData is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x106cf1700) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10fa60cc8). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[17606]: Class METAL_TextureData is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x106cf1750) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10fa60d18). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[17606]: Class SDL_RumbleMotor is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x106cf1778) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10fa60d40). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
objc[17606]: Class SDL_RumbleContext is implemented in both /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/pygame/.dylibs/libSDL2-2.0.0.dylib (0x106cf17c8) and /opt/homebrew/Caskroom/miniforge/base/lib/python3.12/site-packages/cv2/.dylibs/libSDL2-2.0.0.dylib (0x10fa60d90). This may cause spurious casting failures and mysterious crashes. One of the duplicates must be removed or renamed.
[記録] /Volumes/KIOXIA/r2r2r-data/runs/experiments/gamepad_teleop/teleop_20261109_130126
[実機] daemon に送ります。起動したときの姿勢: -0.43 +1.58 +2.19 -0.26 -0.26 -30.23
コントローラーを待っています（つないでいなければ、今つないでください）
[接続] PS4 Controller  GUID=03008fe54c050000cc09000000016800  軸=6  ボタン=16
[長押し] j0 を -0.43° → -54.22° まで（目標を 5 回送信。止めます）
[送信] j0 -1.0° → -54.87 +1.58 +2.19 -0.26 -0.26 -30.23  届いた（ずれ 1.75°）  届いた角度 -54.40 +1.58 +2.02 -0.17 +1.49 -30.23
[送信] j0 -2.0° → -56.87 +1.58 +2.19 -0.26 -0.26 -30.23  届いた（ずれ 1.75°）  届いた角度 -56.77 +1.58 +2.02 -0.17 +1.49 -30.23
[送信] j0 -2.0° → -58.87 +1.58 +2.19 -0.26 -0.26 -30.23  届いた（ずれ 1.75°）  届いた角度 -58.97 +1.58 +2.02 -0.17 +1.49 -30.32
[送信] j0 -2.0° → -60.87 +1.58 +2.19 -0.26 -0.26 -30.23  届いた（ずれ 1.66°）  届いた角度 -61.08 +1.58 +2.02 -0.17 +1.40 -30.32
[関節] 上下で動かす関節を j2 にしました
[関節] 上下で動かす関節を j3 にしました
[関節] 上下で動かす関節を j4 にしました
[長押し] j4 を +0.52° → -28.30° まで（目標を 3 回送信。止めます）
[関節] 上下で動かす関節を j5 にしました
[関節] 上下で動かす関節を j1 にしました
[長押し] j1 を +2.63° → +2.10° まで（目標を 1 回送信。止めます）
  [WARN] daemon_get_angles failed: daemon error: get_angles returned empty/invalid after 12 retries
  [WARN] daemon_get_angles failed: daemon error: get_angles returned empty/invalid after 12 retries
  [WARN] daemon_get_angles failed: daemon error: get_angles returned empty/invalid after 12 retries
  [WARN] daemon_get_angles failed: daemon error: get_angles returned empty/invalid after 12 retries
[送信] j1 +1.0° → -60.87 +21.21 +2.19 -0.26 -38.58 -30.23  手前で止まった（次の押しは この目標の先から）（ずれ 1.2°）  届いた角度 -61.08 +22.41 +1.84 -0.08 -37.79 -30.32
[送信] j1 +2.0° → -60.87 +23.21 +2.19 -0.26 -38.58 -30.23  手前で止まった（次の押しは この目標の先から）（ずれ 1.22°）  届いた角度 -61.17 +24.43 +1.75 +0.00 -37.96 -30.32
[長押し] j1 を +24.43° → +35.15° まで（目標を 2 回送信。止めます）
[関節] 上下で動かす関節を j2 にしました
[長押し] j2 を +2.63° → +2.63° まで（目標を 1 回送信。止めます）
[長押し] j2 を +3.42° → +3.42° まで（目標を 1 回送信。止めます）
[送信] j0 +1.0° → -59.87 +40.69 +18.89 -0.26 -38.58 -30.23  届いた（ずれ 0.96°）  届いた角度 -60.20 +41.30 +18.89 +0.70 -38.23 -29.61
[送信] j0 +1.0° → -58.87 +40.69 +18.89 -0.26 -38.58 -30.23  届いた（ずれ 0.78°）  届いた角度 -58.53 +41.30 +18.89 +0.52 -38.32 -29.61
[関節] 上下で動かす関節を j3 にしました
[関節] 上下で動かす関節を j4 にしました
[送信] j4 -1.0° → -58.87 +40.69 +18.89 -0.26 -39.58 -30.23  届いた（ずれ 0.61°）  届いた角度 -58.88 +41.30 +18.89 +0.17 -39.63 -30.05
[送信] j4 -1.0° → -58.87 +40.69 +18.89 -0.26 -40.58 -30.23  届いた（ずれ 0.61°）  届いた角度 -58.88 +41.30 +18.89 +0.17 -40.69 -30.05
[長押し] j4 を -41.83° → -41.83° まで（目標を 1 回送信。止めます）
[長押し] j4 を -45.61° → -48.42° まで（目標を 1 回送信。止めます）
[関節] 上下で動かす関節を j5 にしました
[関節] 上下で動かす関節を j1 にしました
[関節] 上下で動かす関節を j2 にしました
[関節] 上下で動かす関節を j3 にしました
[関節] 上下で動かす関節を j4 にしました
[長押し] j4 を -25.83° → -49.39° まで（目標を 3 回送信。止めます）
[長押し] j4 を -49.39° → -56.95° まで（目標を 1 回送信。止めます）
[関節] 上下で動かす関節を j5 にしました
[関節] 上下で動かす関節を j1 にしました
[長押し] j1 を +42.53° → +47.10° まで（目標を 1 回送信。止めます）
[長押し] j1 を +52.64° → +53.70° まで（目標を 1 回送信。止めます）
[送信] j1 +1.0° → -58.87 +57.68 +18.89 -0.26 -60.02 -30.23  届いた（ずれ 3.26°）  届いた角度 -58.88 +58.00 +18.89 +0.43 -63.28 -30.23
[送信] j1 +1.0° → -58.87 +58.68 +18.89 -0.26 -60.02 -30.23  届いた（ずれ 3.26°）  届いた角度 -58.88 +58.71 +18.89 +0.52 -63.28 -30.23
[関節] 上下で動かす関節を j2 にしました
[送信] j2 +1.0° → -58.87 +58.68 +19.89 -0.26 -60.02 -30.23  届いた（ずれ 5.54°）  届いた角度 -58.88 +59.67 +20.30 +0.35 -65.56 -30.23
[送信] j2 -1.0° → -58.87 +58.68 +18.89 -0.26 -60.02 -30.23  動かなかった（次の押しは この目標の先から）・無視されたので 2 回送り直した（ずれ 5.54°）  届いた角度 -58.88 +59.67 +20.21 +0.35 -65.56 -30.23
[長押し] j2 を +20.21° → +20.21° まで（目標を 1 回送信。止めます）
[長押し] j2 を +20.12° → +20.12° まで（目標を 1 回送信。止めます）
  [Pi] GRIPPER: VALUE=20 speed=100 result= None
[爪] 爪を閉じる（待ち 0.8 秒のあと受付）
[関節] 上下で動かす関節を j3 にしました
[関節] 上下で動かす関節を j4 にしました
[関節] 上下で動かす関節を j5 にしました
[関節] 上下で動かす関節を j1 にしました
[長押し] j1 を +61.87° → +45.87° まで（目標を 3 回送信。止めます）
  [Pi] GRIPPER: OPEN result= None
[爪] 爪を開く（待ち 0.8 秒のあと受付）
[送信] HOME → +0.00 +0.00 +0.00 +0.00 +0.00 -30.00  届いた（ずれ 2.1°）  届いた角度 -0.35 +1.49 +2.10 -0.08 +0.61 -30.32
[受付なし] HOME: 前の操作が終わっていません（押し直してください）
[受付なし] HOME: 前の操作が終わっていません（押し直してください）
[受付なし] HOME: 前の操作が終わっていません（押し直してください）
[関節] 上下で動かす関節を j2 にしました
[関節] 上下で動かす関節を j3 にしました
[関節] 上下で動かす関節を j4 にしました
[送信] HOME → +0.00 +0.00 +0.00 +0.00 +0.00 -30.00  届かなかった（ずれ 53.34°）  届いた角度 -0.43 +1.49 +2.10 -0.17 +53.34 -30.23
[送信] j4 -1.0° → +0.00 +0.00 +0.00 +0.00 +52.34 -30.00  届いた（ずれ 2.1°）  届いた角度 -0.43 +1.49 +2.10 -0.17 +51.94 -30.23
[長押し] j4 を +51.94° → -3.86° まで（目標を 7 回送信。止めます）
[送信] HOME → +0.00 +0.00 +0.00 +0.00 +0.00 -30.00  届いた（ずれ 2.9°）  届いた角度 -0.43 +1.49 +1.84 -0.17 -2.90 -30.23
^C
[終了] Ctrl+C
[終了] アームは動かしていません。記録: /Volumes/KIOXIA/r2r2r-data/runs/experiments/gamepad_teleop/teleop_20261109_130126
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % scp -i ~/.ssh/id_rsa_pi /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/drag_v2_20261109_130300.json ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/
python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20261109_130300.json
drag_v2_20261109_130300.json                                                   100%   38KB   9.2MB/s   00:00    
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: ドライラン（アームに何も送りません）
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20261109_130300.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_w52iq5a0/drag_v2_20261109_130300.json
[RTD   ] 入力ファイル: drag_v2_20261109_130300.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=123 (start=123 end=197, gap=20.13°)
                    angles = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
  PICK           <- gripper close mark idx=223（PICK phase 範囲内）
                    angles = [ -58.88,  +61.87,   +9.31,   +0.08,  -54.05,  -30.14]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=304 (start=304 end=352, gap=18.81°)
                    angles = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
  PLACE          <- gripper open mark idx=367（PLACE phase 範囲内）
                    angles = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 156 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 26.99°（しきい値 3.0° 以上）
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = 未取得（ドライラン・daemon に接続していない）
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
            max |Δ| = 58.88°  1 回送信 speed=20  (~ 2.9s @ 20°/s 目安・到達待ち 最大 10.8s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
            to      = [ -58.88,  +61.87,   +9.31,   +0.08,  -54.05,  -30.14]
            max |Δ| = 20.13°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -58.88,  +61.87,   +9.31,   +0.08,  -54.05,  -30.14]
            to      = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
            max |Δ| = 20.13°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
            to      = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            max |Δ| = 101.85°  1 回送信 speed=20  (~ 5.1s @ 20°/s 目安・到達待ち 最大 17.3s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            to      = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
            max |Δ| = 18.81°  1 回送信 speed=20  (~ 0.9s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
            to      = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            max |Δ| = 18.81°  1 回送信 speed=20  (~ 0.9s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 54.58°  1 回送信 speed=20  (~ 2.7s @ 20°/s 目安・到達待ち 最大 10.2s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 31.7s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 14.7s（max|Δ| 合計 293.2° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123559.json
[RTD   ]   measured_at = 2026-11-09T12:36:01.355235  block = (+54.8, +47.3) mm  box = (-220.3, +190.8) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] [WARN] 再生直前: 四隅が最大 16.3px ずれています（1 回目 / 上限 15.0px）。測り直します
[RTD   ] 再生直前: 四隅が 2 回目で収まりました（最大 14.9px <= 15.0px）
[RTD   ] 再生直前: block = (+238.7, +106.4) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_130520.jpg
[RTD   ] [WARN] ブロックが measure 時から動いています（止めません・項目8）: ブロックが measure 時から 431.8px（≒193.2mm）動いています（許容 10.3px = 5.0mm）。ブロックを戻すか measure をやり直してください
[RTD   ] [WARN]   画素の差 431.8px（許容 10.3px = 5.0mm）/ mm 換算の差 193.17mm
[RTD   ] [WARN]   つかみ損ねる可能性があります。気になるなら Enter の前に measure を取り直してください
[RTD   ] ドライランなので、ここで終了します（アームには何も送っていません）
[RTD   ] Pi 版と比べる点: 抽出ウェイポイント 4 姿勢と各区間の max|Δ| は同じ。送り方は単発（Pi 版は 0.1s 補間ストリーミング）なので n_steps / ticks は比較対象外。送信 8 回 / 想定所要 ≈ 31.7s
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20261109_130300.json --execute
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20261109_130300.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_gh64qcxm/drag_v2_20261109_130300.json
[RTD   ] 入力ファイル: drag_v2_20261109_130300.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=123 (start=123 end=197, gap=20.13°)
                    angles = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
  PICK           <- gripper close mark idx=223（PICK phase 範囲内）
                    angles = [ -58.88,  +61.87,   +9.31,   +0.08,  -54.05,  -30.14]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=304 (start=304 end=352, gap=18.81°)
                    angles = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
  PLACE          <- gripper open mark idx=367（PLACE phase 範囲内）
                    angles = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 156 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 26.99°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  -0.52,   +1.49,   +1.75,   -0.17,   +0.17,  -30.23]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  -0.52,   +1.49,   +1.75,   -0.17,   +0.17,  -30.23]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 1.75°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
            max |Δ| = 58.88°  1 回送信 speed=20  (~ 2.9s @ 20°/s 目安・到達待ち 最大 10.8s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
            to      = [ -58.88,  +61.87,   +9.31,   +0.08,  -54.05,  -30.14]
            max |Δ| = 20.13°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -58.88,  +61.87,   +9.31,   +0.08,  -54.05,  -30.14]
            to      = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
            max |Δ| = 20.13°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
            to      = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            max |Δ| = 101.85°  1 回送信 speed=20  (~ 5.1s @ 20°/s 目安・到達待ち 最大 17.3s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            to      = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
            max |Δ| = 18.81°  1 回送信 speed=20  (~ 0.9s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
            to      = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            max |Δ| = 18.81°  1 回送信 speed=20  (~ 0.9s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 54.58°  1 回送信 speed=20  (~ 2.7s @ 20°/s 目安・到達待ち 最大 10.2s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 31.7s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 14.7s（max|Δ| 合計 293.2° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123559.json
[RTD   ]   measured_at = 2026-11-09T12:36:01.355235  block = (+54.8, +47.3) mm  box = (-220.3, +190.8) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] [WARN] 再生直前: 四隅が最大 15.5px ずれています（1 回目 / 上限 15.0px）。測り直します
[RTD   ] [WARN] 再生直前: 四隅が最大 15.9px ずれています（2 回目 / 上限 15.0px）。測り直します
[RTD   ] [WARN] 再生直前: 四隅が最大 15.5px ずれています（3 回目 / 上限 15.0px）。やり直しの上限に達しました
[RTD   ] 再生直前: block = (+238.7, +105.9) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_130534.jpg
[RTD   ] 弾いた理由と各回の記録を残しました: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_130534_rejected.json
[RTD   ] [WARN] マット四隅が measure 時から最大 15.5px ずれています（上限 15.0px・最大 3 回やり直しても収まらず）。カメラが動いた可能性があるので止めます。measure を取り直してください（各隅のずれ: 4.0, 10.0, 15.1, 15.5）（**止めません**・WARN のみ）
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_130542
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_130542/teach/drag_v2_20261109_130300.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_130542/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 1.75° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=1.75° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.016s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 10.8s)
[RTD   ] 送信 OK（daemon 往復 1.021s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.15° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.042s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=1.23° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.011s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.034s）
[RTD   ] arrival OK (PICK → APPROACH_PICK (lift), max|Δ|=2.11° <= tol 3.0°)
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 17.3s)
[RTD   ] 送信 OK（daemon 往復 1.049s）
[RTD   ] arrival OK (APPROACH_PICK → APPROACH_PLACE, max|Δ|=1.84° <= tol 3.0°)
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.035s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=1.58° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.004s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.63° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 10.2s)
[RTD   ] 送信 OK（daemon 往復 1.053s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.28° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 59/59 回, 実効 1.63 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（1.63 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.038s / p50 1.035s / 最大 1.053s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.053s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 2.39s / 最大 4.63s
[RECORD] 電流の記録終了 79 行 (2.18 行/秒. 本体が眠っている間だけ読む. 爪の間 14.045 秒は読まない. 見込み超え 0 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_130542/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > y
[RTD   ] 箱に入ったか (y/n) > y
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_130542/run_0001_20261109_130542.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=yes place=yes recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_130542 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 pi05/camera_align.py --raw-dir /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/align_ref --episode 130542
python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20261109_130300.json --execute
[REF   ] 基準画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/align_ref/run_0001_20261109_130542/frames/000000.jpg
[REF   ] お手本 run_0001_20261109_130542 (つかんだ瞬間が不明)
[REF   ] 重なった画像のブロックに実物のブロックを合わせると, お手本と同じ位置に置ける
[ALIGN ] |dy| <= 20 なら OK. アームは HOME に置いた状態で合わせる. q または Esc で終了 (ファイルには何も書かない)
[ALIGN ] dy=  +1.8  dx=  +6.7  response=0.577  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[ALIGN ] dy=  +0.3  dx=  +6.0  response=0.587  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[DONE  ] 終了 (何も書いていません)
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20261109_130300.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_0yz2jwh1/drag_v2_20261109_130300.json
[RTD   ] 入力ファイル: drag_v2_20261109_130300.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=123 (start=123 end=197, gap=20.13°)
                    angles = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
  PICK           <- gripper close mark idx=223（PICK phase 範囲内）
                    angles = [ -58.88,  +61.87,   +9.31,   +0.08,  -54.05,  -30.14]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=304 (start=304 end=352, gap=18.81°)
                    angles = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
  PLACE          <- gripper open mark idx=367（PLACE phase 範囲内）
                    angles = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 156 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 26.99°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  -0.08,   +1.49,   +2.02,   +0.26,   -0.26,  -30.23]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  -0.08,   +1.49,   +2.02,   +0.26,   -0.26,  -30.23]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 2.02°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
            max |Δ| = 58.88°  1 回送信 speed=20  (~ 2.9s @ 20°/s 目安・到達待ち 最大 10.8s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
            to      = [ -58.88,  +61.87,   +9.31,   +0.08,  -54.05,  -30.14]
            max |Δ| = 20.13°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -58.88,  +61.87,   +9.31,   +0.08,  -54.05,  -30.14]
            to      = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
            max |Δ| = 20.13°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
            to      = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            max |Δ| = 101.85°  1 回送信 speed=20  (~ 5.1s @ 20°/s 目安・到達待ち 最大 17.3s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            to      = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
            max |Δ| = 18.81°  1 回送信 speed=20  (~ 0.9s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
            to      = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            max |Δ| = 18.81°  1 回送信 speed=20  (~ 0.9s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 54.58°  1 回送信 speed=20  (~ 2.7s @ 20°/s 目安・到達待ち 最大 10.2s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 31.7s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 14.7s（max|Δ| 合計 293.2° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123559.json
[RTD   ]   measured_at = 2026-11-09T12:36:01.355235  block = (+54.8, +47.3) mm  box = (-220.3, +190.8) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] [WARN] 再生直前: 四隅が最大 16.7px ずれています（1 回目 / 上限 15.0px）。測り直します
[RTD   ] [WARN] 再生直前: 四隅が最大 16.7px ずれています（2 回目 / 上限 15.0px）。測り直します
[RTD   ] [WARN] 再生直前: 四隅が最大 16.8px ずれています（3 回目 / 上限 15.0px）。やり直しの上限に達しました
[RTD   ] 再生直前: block = (+240.0, +102.0) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_130716.jpg
[RTD   ] 弾いた理由と各回の記録を残しました: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_130716_rejected.json
[RTD   ] [WARN] マット四隅が measure 時から最大 16.8px ずれています（上限 15.0px・最大 3 回やり直しても収まらず）。カメラが動いた可能性があるので止めます。measure を取り直してください（各隅のずれ: 4.0, 10.0, 16.8, 15.5）（**止めません**・WARN のみ）
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_130723
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_130723/teach/drag_v2_20261109_130300.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_130723/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 2.02° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=2.02° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.012s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 10.8s)
[RTD   ] 送信 OK（daemon 往復 1.033s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.50° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.029s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=1.14° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.011s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (PICK → APPROACH_PICK (lift), max|Δ|=2.11° <= tol 3.0°)
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 17.3s)
[RTD   ] 送信 OK（daemon 往復 1.053s）
[RTD   ] arrival OK (APPROACH_PICK → APPROACH_PLACE, max|Δ|=1.75° <= tol 3.0°)
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.030s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=1.50° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.014s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.048s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.54° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 10.2s)
[RTD   ] 送信 OK（daemon 往復 1.029s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.19° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 57/57 回, 実効 1.61 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（1.61 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.036s / p50 1.031s / 最大 1.053s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.053s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 2.31s / 最大 4.46s
[RECORD] 電流の記録終了 75 行 (2.11 行/秒. 本体が眠っている間だけ読む. 爪の間 14.052 秒は読まない. 見込み超え 0 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_130723/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > y
[RTD   ] 箱に入ったか (y/n) > y
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_130723/run_0001_20261109_130723.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=yes place=yes recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_130723 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 pi05/camera_align.py --raw-dir /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/align_ref --episode 130542
python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20261109_130300.json --execute
[REF   ] 基準画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/align_ref/run_0001_20261109_130542/frames/000000.jpg
[REF   ] お手本 run_0001_20261109_130542 (つかんだ瞬間が不明)
[REF   ] 重なった画像のブロックに実物のブロックを合わせると, お手本と同じ位置に置ける
[ALIGN ] |dy| <= 20 なら OK. アームは HOME に置いた状態で合わせる. q または Esc で終了 (ファイルには何も書かない)
[ALIGN ] dy=  +1.1  dx=  +7.8  response=0.598  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[DONE  ] 終了 (何も書いていません)
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20261109_130300.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_3cwlo00h/drag_v2_20261109_130300.json
[RTD   ] 入力ファイル: drag_v2_20261109_130300.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=123 (start=123 end=197, gap=20.13°)
                    angles = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
  PICK           <- gripper close mark idx=223（PICK phase 範囲内）
                    angles = [ -58.88,  +61.87,   +9.31,   +0.08,  -54.05,  -30.14]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=304 (start=304 end=352, gap=18.81°)
                    angles = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
  PLACE          <- gripper open mark idx=367（PLACE phase 範囲内）
                    angles = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 156 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 26.99°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  -0.08,   +1.49,   +2.02,   +0.26,   -0.26,  -30.23]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  -0.08,   +1.49,   +2.02,   +0.26,   -0.26,  -30.23]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 2.02°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
            max |Δ| = 58.88°  1 回送信 speed=20  (~ 2.9s @ 20°/s 目安・到達待ち 最大 10.8s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
            to      = [ -58.88,  +61.87,   +9.31,   +0.08,  -54.05,  -30.14]
            max |Δ| = 20.13°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -58.88,  +61.87,   +9.31,   +0.08,  -54.05,  -30.14]
            to      = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
            max |Δ| = 20.13°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
            to      = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            max |Δ| = 101.85°  1 回送信 speed=20  (~ 5.1s @ 20°/s 目安・到達待ち 最大 17.3s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            to      = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
            max |Δ| = 18.81°  1 回送信 speed=20  (~ 0.9s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
            to      = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            max |Δ| = 18.81°  1 回送信 speed=20  (~ 0.9s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 54.58°  1 回送信 speed=20  (~ 2.7s @ 20°/s 目安・到達待ち 最大 10.2s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 31.7s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 14.7s（max|Δ| 合計 293.2° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123559.json
[RTD   ]   measured_at = 2026-11-09T12:36:01.355235  block = (+54.8, +47.3) mm  box = (-220.3, +190.8) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] [WARN] 再生直前: 四隅が最大 16.7px ずれています（1 回目 / 上限 15.0px）。測り直します
[RTD   ] [WARN] 再生直前: 四隅が最大 16.7px ずれています（2 回目 / 上限 15.0px）。測り直します
[RTD   ] [WARN] 再生直前: 四隅が最大 16.7px ずれています（3 回目 / 上限 15.0px）。やり直しの上限に達しました
[RTD   ] 再生直前: block = (+239.6, +103.0) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_130817.jpg
[RTD   ] 弾いた理由と各回の記録を残しました: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_130817_rejected.json
[RTD   ] [WARN] マット四隅が measure 時から最大 16.7px ずれています（上限 15.0px・最大 3 回やり直しても収まらず）。カメラが動いた可能性があるので止めます。measure を取り直してください（各隅のずれ: 4.0, 10.0, 16.7, 15.5）（**止めません**・WARN のみ）
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_130824
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_130824/teach/drag_v2_20261109_130300.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_130824/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 2.02° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=2.02° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.004s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 10.8s)
[RTD   ] 送信 OK（daemon 往復 1.030s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.50° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.620s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=1.14° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.013s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.033s）
[RTD   ] arrival OK (PICK → APPROACH_PICK (lift), max|Δ|=2.11° <= tol 3.0°)
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 17.3s)
[RTD   ] 送信 OK（daemon 往復 1.047s）
[RTD   ] arrival OK (APPROACH_PICK → APPROACH_PLACE, max|Δ|=1.75° <= tol 3.0°)
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.055s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=1.41° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.017s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.032s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.54° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 10.2s)
[RTD   ] 送信 OK（daemon 往復 1.030s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.28° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 57/57 回, 実効 1.58 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（1.58 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.121s / p50 1.033s / 最大 1.620s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.620s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 2.38s / 最大 4.46s
[RECORD] 電流の記録終了 75 行 (2.08 行/秒. 本体が眠っている間だけ読む. 爪の間 14.05 秒は読まない. 見込み超え 0 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_130824/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > y
[RTD   ] 箱に入ったか (y/n) > y
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_130824/run_0001_20261109_130824.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=yes place=yes recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_130824 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 pi05/camera_align.py --raw-dir /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/align_ref --episode 130542
python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20261109_130300.json --execute
[REF   ] 基準画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/align_ref/run_0001_20261109_130542/frames/000000.jpg
[REF   ] お手本 run_0001_20261109_130542 (つかんだ瞬間が不明)
[REF   ] 重なった画像のブロックに実物のブロックを合わせると, お手本と同じ位置に置ける
[ALIGN ] |dy| <= 20 なら OK. アームは HOME に置いた状態で合わせる. q または Esc で終了 (ファイルには何も書かない)
[ALIGN ] dy=  +1.9  dx=  +7.0  response=0.600  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[DONE  ] 終了 (何も書いていません)
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20261109_130300.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_x5tqexdu/drag_v2_20261109_130300.json
[RTD   ] 入力ファイル: drag_v2_20261109_130300.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=123 (start=123 end=197, gap=20.13°)
                    angles = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
  PICK           <- gripper close mark idx=223（PICK phase 範囲内）
                    angles = [ -58.88,  +61.87,   +9.31,   +0.08,  -54.05,  -30.14]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=304 (start=304 end=352, gap=18.81°)
                    angles = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
  PLACE          <- gripper open mark idx=367（PLACE phase 範囲内）
                    angles = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 156 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 26.99°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  +0.00,   +1.49,   +2.02,   +0.26,   -0.26,  -30.23]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  +0.00,   +1.49,   +2.02,   +0.26,   -0.26,  -30.23]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 2.02°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
            max |Δ| = 58.88°  1 回送信 speed=20  (~ 2.9s @ 20°/s 目安・到達待ち 最大 10.8s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
            to      = [ -58.88,  +61.87,   +9.31,   +0.08,  -54.05,  -30.14]
            max |Δ| = 20.13°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -58.88,  +61.87,   +9.31,   +0.08,  -54.05,  -30.14]
            to      = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
            max |Δ| = 20.13°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
            to      = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            max |Δ| = 101.85°  1 回送信 speed=20  (~ 5.1s @ 20°/s 目安・到達待ち 最大 17.3s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            to      = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
            max |Δ| = 18.81°  1 回送信 speed=20  (~ 0.9s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
            to      = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            max |Δ| = 18.81°  1 回送信 speed=20  (~ 0.9s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 54.58°  1 回送信 speed=20  (~ 2.7s @ 20°/s 目安・到達待ち 最大 10.2s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 31.7s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 14.7s（max|Δ| 合計 293.2° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123559.json
[RTD   ]   measured_at = 2026-11-09T12:36:01.355235  block = (+54.8, +47.3) mm  box = (-220.3, +190.8) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] [WARN] 再生直前: 四隅が最大 15.5px ずれています（1 回目 / 上限 15.0px）。測り直します
[RTD   ] [WARN] 再生直前: 四隅が最大 15.5px ずれています（2 回目 / 上限 15.0px）。測り直します
[RTD   ] [WARN] 再生直前: 四隅が最大 15.9px ずれています（3 回目 / 上限 15.0px）。やり直しの上限に達しました
[RTD   ] 再生直前: block = (+241.8, +104.4) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_130922.jpg
[RTD   ] 弾いた理由と各回の記録を残しました: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_130922_rejected.json
[RTD   ] [WARN] マット四隅が measure 時から最大 15.9px ずれています（上限 15.0px・最大 3 回やり直しても収まらず）。カメラが動いた可能性があるので止めます。measure を取り直してください（各隅のずれ: 4.0, 10.0, 15.9, 15.5）（**止めません**・WARN のみ）
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_130929
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_130929/teach/drag_v2_20261109_130300.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_130929/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 2.02° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=2.02° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.014s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 10.8s)
[RTD   ] 送信 OK（daemon 往復 1.034s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.50° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.041s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=1.14° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.08° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.010s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.029s）
[RTD   ] arrival OK (PICK → APPROACH_PICK (lift), max|Δ|=2.11° <= tol 3.0°)
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 17.3s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (APPROACH_PICK → APPROACH_PLACE, max|Δ|=1.75° <= tol 3.0°)
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.055s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=1.41° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.016s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.038s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.54° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 10.2s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.19° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 57/57 回, 実効 1.61 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（1.61 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.037s / p50 1.034s / 最大 1.055s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.055s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 2.31s / 最大 4.46s
[RECORD] 電流の記録終了 75 行 (2.11 行/秒. 本体が眠っている間だけ読む. 爪の間 14.059 秒は読まない. 見込み超え 0 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_130929/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > y
[RTD   ] 箱に入ったか (y/n) > y
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_130929/run_0001_20261109_130929.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=yes place=yes recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_130929 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 pi05/camera_align.py --raw-dir /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/align_ref --episode 130542
python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20261109_130300.json --execute
[REF   ] 基準画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/align_ref/run_0001_20261109_130542/frames/000000.jpg
[REF   ] お手本 run_0001_20261109_130542 (つかんだ瞬間が不明)
[REF   ] 重なった画像のブロックに実物のブロックを合わせると, お手本と同じ位置に置ける
[ALIGN ] |dy| <= 20 なら OK. アームは HOME に置いた状態で合わせる. q または Esc で終了 (ファイルには何も書かない)
[ALIGN ] dy=  +0.8  dx=  +6.9  response=0.628  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[ALIGN ] dy=  +1.9  dx=  +6.7  response=0.586  → OK (|dy|<=20 / |dx|<=20 / response>=0.20)
[DONE  ] 終了 (何も書いていません)
[RTD   ] 到達許容差は本線 run_pick_place.py の stage 値を使います（区間ごと。一律 8.0° は 2026-10-19 にやめた）:
[RTD   ]   HOME                       2.5°  ← rpp.TOL_HOME（stage1_to_home / HOME 復帰）
[RTD   ]   APPROACH_PICK              2.0°  ← rpp.TOL_APPROACH（approach 系）
[RTD   ]   PICK                       3.0°  ← rpp.TOL_PICK_PLACE（stage4_pick）
[RTD   ]   APPROACH_PICK (lift)       3.0°  ← rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）
[RTD   ]   APPROACH_PLACE             3.0°  ← rpp.TOL_APPROACH_PLACE（stage7）
[RTD   ]   PLACE                      3.0°  ← rpp.TOL_PICK_PLACE（stage8_place）
[RTD   ]   APPROACH_PLACE (retreat)   3.0°  ← rpp.TOL_LIFT_BACK（stage10_lift_back）
[RTD   ] 到達を待つ最大時間 = clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒（本線と同じ wr._compute_arrival_timeout）
[RTD   ] モード: EXECUTE（実機）  記録: ON
[RTD   ] Pi から教えた記録を取得します: ubuntu@192.168.2.1:r2r2r-scripts/dynamic_tracking_limits/drag_teaching/drag_v2_20261109_130300.json
[RTD   ] 取得しました → /var/folders/5w/2q2mc64n6yv63gfh31h34w6h0000gn/T/record_teach_demo_7l1gks85/drag_v2_20261109_130300.json
[RTD   ] 入力ファイル: drag_v2_20261109_130300.json
[RTD   ] 抽出ウェイポイント:
  APPROACH_PICK  <- phase APPROACH_PICK argmax_idx=123 (start=123 end=197, gap=20.13°)
                    angles = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
  PICK           <- gripper close mark idx=223（PICK phase 範囲内）
                    angles = [ -58.88,  +61.87,   +9.31,   +0.08,  -54.05,  -30.14]
  APPROACH_PLACE <- phase APPROACH_PLACE argmax_idx=304 (start=304 end=352, gap=18.81°)
                    angles = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
  PLACE          <- gripper open mark idx=367（PLACE phase 範囲内）
                    angles = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
[RTD   ] JOINT_LIMITS 一括検証 OK（全 endpoint + HOME）
[RTD   ] 姿勢検査 OK（全 156 姿勢が 有限値 + JOINT_LIMITS + J4_SAFE [-90.0, +60.0] 内）
[RTD   ] j4 の余裕は最小 26.99°（しきい値 3.0° 以上）
[RTD   ] 現在姿勢を daemon から取得します
[RTD   ] 現在姿勢 = [  -0.08,   +1.49,   +2.02,   +0.26,   -0.26,  -30.23]
==============================================================================
[RTD   ] 実行プラン（daemon 経由・区間ごとに 1 回送信 → 到達待ち）
==============================================================================
  [STEP  1] MOVE → HOME (single send + settle)  speed=20
            current = [  -0.08,   +1.49,   +2.02,   +0.26,   -0.26,  -30.23]
            to HOME = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 2.02°  (settle 3.0s)
  [STEP  2] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  tol=2.0°  [rpp.TOL_APPROACH（approach 系）]
            from    = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            to      = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
            max |Δ| = 58.88°  1 回送信 speed=20  (~ 2.9s @ 20°/s 目安・到達待ち 最大 10.8s)
  [STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage4_pick）]
            from    = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
            to      = [ -58.88,  +61.87,   +9.31,   +0.08,  -54.05,  -30.14]
            max |Δ| = 20.13°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  5] GRIPPER CLOSE  daemon_set_gripper_value(20, 50) + sleep(2.0s)
  [STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  tol=3.0°  [rpp.TOL_LIFT_BACK（lift の残差 2.19° を吸収）]
            from    = [ -58.88,  +61.87,   +9.31,   +0.08,  -54.05,  -30.14]
            to      = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
            max |Δ| = 20.13°  1 回送信 speed=20  (~ 1.0s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  tol=3.0°  [rpp.TOL_APPROACH_PLACE（stage7）]
            from    = [ -58.88,  +41.74,   +9.31,   +0.08,  -54.05,  -30.14]
            to      = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            max |Δ| = 101.85°  1 回送信 speed=20  (~ 5.1s @ 20°/s 目安・到達待ち 最大 17.3s)
  [STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  [critical]  tol=3.0°  [rpp.TOL_PICK_PLACE（stage8_place）]
            from    = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            to      = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
            max |Δ| = 18.81°  1 回送信 speed=20  (~ 0.9s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP  9] GRIPPER OPEN  daemon_set_gripper(0, 50, wait=0) ×1 回（daemon 事前 2.0s + 事後 2.0s + 待ち 2.0s）= 計 6.0s
            開いたかは確認しません（gv を使わず・開始前の y/n も無し。判定は終了後の y/n と動画）
  [STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  tol=3.0°  [rpp.TOL_LIFT_BACK（stage10_lift_back）]
            from    = [ +43.85,  +62.22,   -4.83,   +7.82,  -63.01,  -36.12]
            to      = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            max |Δ| = 18.81°  1 回送信 speed=20  (~ 0.9s @ 20°/s 目安・到達待ち 最大 8.0s)
  [STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  tol=2.5°  [rpp.TOL_HOME（stage1_to_home / HOME 復帰）]
            from    = [ +42.97,  +43.41,   +4.13,   +7.20,  -54.58,  -35.33]
            to      = [  +0.00,   +0.00,   +0.00,   +0.00,   +0.00,  -30.00]
            max |Δ| = 54.58°  1 回送信 speed=20  (~ 2.7s @ 20°/s 目安・到達待ち 最大 10.2s)
==============================================================================
[RTD   ] 送信 = 8 回（STEP 1 + move 7 区間）, 想定所要時間 ≈ 31.7s（最悪 73.0s）
[RTD   ]   内訳: 先頭 settle 3.0s + 移動 14.7s（max|Δ| 合計 293.2° @ 20°/s 目安） + gripper 14.0s
[RTD   ]   到達確認: 許容は区間ごと（本線 run_pick_place.py の stage 値）/ 最大は clamp(2.0 + max|Δ|/20*3.0, 8.0, 30.0) 秒
[RTD   ]   届かないとき: 送信前から 1.0° 未満しか動いていなければ 5.0s 待って**同じ目標へ 1 回だけ**再送（本線と同じ）。それでも届かなければ ABORT（HOME へ自動で戻らない）
[RTD   ]   実測 j4: [-90.0, +60.0] の外は WARN / [-98.0, +68.0] の外は ABORT
==============================================================================
[RTD   ] measure: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/measure_20261109_123559.json
[RTD   ]   measured_at = 2026-11-09T12:36:01.355235  block = (+54.8, +47.3) mm  box = (-220.3, +190.8) mm
[RTD   ] 再生直前: 上カメラでマット四隅とブロック画素を確認します
[RTD   ] [WARN] 再生直前: 四隅が最大 16.7px ずれています（1 回目 / 上限 15.0px）。測り直します
[RTD   ] [WARN] 再生直前: 四隅が最大 16.8px ずれています（2 回目 / 上限 15.0px）。測り直します
[RTD   ] [WARN] 再生直前: 四隅が最大 16.8px ずれています（3 回目 / 上限 15.0px）。やり直しの上限に達しました
[RTD   ] 再生直前: block = (+239.1, +102.1) mm（measure の homography で換算）
[RTD   ] 確認画像: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_131056.jpg
[RTD   ] 弾いた理由と各回の記録を残しました: /Volumes/KIOXIA/r2r2r-data/mecharm_calibration/teach_poses_20261109/prerun_20261109_131056_rejected.json
[RTD   ] [WARN] マット四隅が measure 時から最大 16.8px ずれています（上限 15.0px・最大 3 回やり直しても収まらず）。カメラが動いた可能性があるので止めます。measure を取り直してください（各隅のずれ: 4.0, 10.0, 16.8, 15.5）（**止めません**・WARN のみ）
[RTD   ] [SAFETY] 再生中はグリッパーが実機で開閉します。爪に指を挟まないこと。
[RTD   ] [SAFETY] 止めるときはアームの電源を切ること。Ctrl-C は新しい送信をやめるだけで、進行中の移動は止まりません。
[RTD   ] [SAFETY] 開いたかの自動確認はしません（gv は使わない）。STEP 2 で open を送ってから PICK へ降ります。
[RTD   ] 周囲に手・物が無いか確認してください。OK なら Enter で開始

[RTD   ] 試行フォルダ: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_131103
[RTD   ] 教えた記録のコピー: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_131103/teach/drag_v2_20261109_130300.json
[RTD   ] recorder に trial_start を送りました。1.0s 待ってから動き出します（mp4 writer が開くまで）
[RTD   ] 爪と肩の電流を 1 秒 10 回で記録します（爪を動かしている間は読みません）→ /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_131103/recording/currents.csv
  [Pi] fresh_mode=1
[RTD   ] daemon_set_fresh_mode(1)（最新コマンド優先・本線 run_pick_place.py L3976 と同じ。647 試行の実績はこの状態）
[STEP  1] MOVE → HOME  daemon_send_angles(HOME, 20)
[STEP  1] 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 8.0s
[RTD   ] 先頭移動: 送信直前の実測で max|Δ| = 2.02° / 到達待ち 最大 8.0s
[STEP  1] 3.0s 待ちます（settle）
[RTD   ] arrival OK (current → HOME, max|Δ|=2.02° <= tol 2.5°)
[STEP  2] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step2_open: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.012s
[STEP  2] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  2] gripper dwell 2.0s（読み取りなし）
[STEP  3] MOVE → APPROACH_PICK  segment HOME → APPROACH_PICK  (1 回送信 speed=20 → 到達待ち 許容 2.0°[TOL_APPROACH（approach 系）] / 最大 10.8s)
[RTD   ] 送信 OK（daemon 往復 1.031s）
[RTD   ] arrival OK (HOME → APPROACH_PICK, max|Δ|=1.15° <= tol 2.0°)
[STEP  4] MOVE → PICK  segment APPROACH_PICK → PICK  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage4_pick）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.028s）
[RTD   ] arrival OK (APPROACH_PICK → PICK, max|Δ|=1.23° <= tol 3.0°)
[STEP  5] GRIPPER CLOSE → daemon_set_gripper_value(20, 50)
[RTD   ] 静止確認 OK（step5_close: 連続 3 回・連続差 最大 0.00° <= 1.0°）
  [Pi] GRIPPER: VALUE=20 speed=50 result= None
[RTD   ] gripper close (1/1 回目) の daemon 往復 = 0.012s
[STEP  5] gripper dwell 2.0s（読み取りなし）
[STEP  6] MOVE → APPROACH_PICK (lift)  segment PICK → APPROACH_PICK (lift)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（lift の残差 2.19° を吸収）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.038s）
[RTD   ] arrival OK (PICK → APPROACH_PICK (lift), max|Δ|=2.11° <= tol 3.0°)
[STEP  7] MOVE → APPROACH_PLACE  segment APPROACH_PICK → APPROACH_PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_APPROACH_PLACE（stage7）] / 最大 17.3s)
[RTD   ] 送信 OK（daemon 往復 1.032s）
[RTD   ] arrival OK (APPROACH_PICK → APPROACH_PLACE, max|Δ|=1.84° <= tol 3.0°)
[STEP  8] MOVE → PLACE  segment APPROACH_PLACE → PLACE  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_PICK_PLACE（stage8_place）] / 最大 8.0s)  [critical]
[RTD   ] 送信 OK（daemon 往復 1.039s）
[RTD   ] arrival OK (APPROACH_PLACE → PLACE, max|Δ|=1.50° <= tol 3.0°)
[STEP  9] GRIPPER OPEN → daemon_set_gripper(0, 50, wait=0)
[RTD   ] 静止確認 OK（step9_open: 連続 3 回・連続差 最大 0.09° <= 1.0°）
  [Pi] GRIPPER: OPEN result= None
[RTD   ] gripper open (1/1 回目) の daemon 往復 = 2.014s
[STEP  9] open 後 2.0s 待ちます（本線の daemon wait=2 相当・読み取りなし）
[STEP  9] gripper dwell 2.0s（読み取りなし）
[STEP 10] MOVE → APPROACH_PLACE (retreat)  segment PLACE → APPROACH_PLACE (retreat)  (1 回送信 speed=20 → 到達待ち 許容 3.0°[TOL_LIFT_BACK（stage10_lift_back）] / 最大 8.0s)
[RTD   ] 送信 OK（daemon 往復 1.029s）
[RTD   ] arrival OK (PLACE → APPROACH_PLACE (retreat), max|Δ|=2.54° <= tol 3.0°)
[STEP 11] MOVE → HOME  segment APPROACH_PLACE → HOME  (1 回送信 speed=20 → 到達待ち 許容 2.5°[TOL_HOME（stage1_to_home / HOME 復帰）] / 最大 10.2s)
[RTD   ] 送信 OK（daemon 往復 1.028s）
[RTD   ] arrival OK (APPROACH_PLACE → HOME, max|Δ|=2.19° <= tol 2.5°)
  [Pi] fresh_mode=0
[RTD   ] daemon_set_fresh_mode(0) 完了
[RTD   ] 実測角の読み取り: ok 58/58 回, 実効 1.62 Hz（目標 3.0 Hz 以上）
[RTD   ] [WARN] 実測角の読み取りが目標 3.0 Hz を下回りました（1.62 Hz）。学習データの state 密度が 19 本より薄くなります
[RTD   ] send_angles の daemon 往復 (7 回): 平均 1.032s / p50 1.031s / 最大 1.040s（timeout 6.0s）
[RTD   ] [WARN] 送信 1 回に 1.040s かかった回があります。daemon は送信後に角度を読み直すので、動き始めで読めないと伸びます（単発送信なので試行全体への影響は小さい）
[RTD   ] 区間の所要（送信→到達確認まで）(8 区間): 平均 2.34s / 最大 4.46s
[RECORD] 電流の記録終了 77 行 (2.15 行/秒. 本体が眠っている間だけ読む. 爪の間 14.051 秒は読まない. 見込み超え 0 回. read_servo)  → /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_131103/recording/currents.csv
==============================================================================
[RTD   ] 再生 完了
==============================================================================
[RTD   ] つかめたか (y/n) > y
[RTD   ] 箱に入ったか (y/n) > y
[RTD   ] 試行 JSON: /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261109_131103/run_0001_20261109_131103.json
[LEDGER] append OK: /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (pick=yes place=yes recording_status=ok)
[RTD   ] 次に進むには: python3 /Users/shimazueiichi/r2r2r-scripts/pi05/build_demo_episodes.py --run run_0001_20261109_131103 --dataset mecharm_redblock_box_teach_v1
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % 
```
