# 深いお手本で置き場所ごとの本数をそろえる（位置 1〜5 を各 10 本。2026-11-07 依頼 117・118・121）

学習（`RUNPOD_TRAIN.md`）の前に、LOG352 で教えた 5 か所（位置 1〜5）それぞれで、ブロックが爪の奥まで入ってから閉じるお手本を撮り足し、**どの位置も 10 本**にそろえる手順。**この手順はまだ実機で通していない**（書いただけ）。

**なぜそろえるか**: 今のデータ `mecharm_redblock_box_teach_v1_trim2_corr_v5_deep`（21 本。浅い 7 本・指の写った 2 本を外した版）は半分以上が位置 5 に寄っている。SO-101 で π0.5 を学習した例（LOG443）では、タスクごとの本数の偏りがそのまま失敗の形になり、本数をそろえて直していた。エイイチの決め（2026-11-07）: 置き場所ごとの本数をそろえる。目安は各位置 10 本。

## 0. 今の本数と足す本数

`python3 pi05/count_by_position.py mecharm_redblock_box_teach_v1_trim2_corr_v5_deep` の表（2026-11-07）:

| 位置 | 教えた記録 | 今の本数 | うち教えた動き | うち補正入り | 足す本数 | 外した本（浅い・指） |
| --- | --- | --- | --- | --- | --- | --- |
| 1 | `drag_v2_20221013_144348.json` | 0 | 0 | 0 | **＋10** | 浅い 1（183454） |
| 2 | `drag_v2_20221013_230205.json` | 3 | 3 | 0 | **＋7** | 指 2（191347・191441） |
| 3 | `drag_v2_20221013_231249.json` | 2 | 2 | 0 | **＋8** | 浅い 2（192343・192633） |
| 4 | `drag_v2_20221013_232345.json` | 5 | 5 | 0 | **＋5** | 0 |
| 5 | `drag_v2_20221013_233323.json` | 11 | 4 | 7 | **＋0** | 浅い 4（補正入り） |
| 合計 | | 21 | 14 | 7 | **＋30** | 7 |

- 位置の決め方（`count_by_position.py` の頭にも書いた）: 教えた動きは試行フォルダの `teach/` にある教えた記録のファイル名。補正入りは上カメラで見つけたブロックの位置（マットの上の mm）をいちばん近い教えた位置に割り当て、30mm を超えたら「分からない」
- 位置 5 は足さない（今の 11 本で目安を超えている）。位置 5 の補正入りを減らすかどうかは決めていない

**目安時間**: 1 本あたり約 3 分（置き直し・measure・再生 約 1 分・y/n・深さを測る。10/19 の位置 4 の 5 本は 1〜2 分おきに撮れていた）。位置を替えるときに印の確認と 1 本目の確かめで 5〜10 分。**全体で約 30 本・2 時間前後**（30 本 × 3 分 ＋ 位置の替え 4 回）（浅くて撮り直す分と、位置 1 を教え直す場合はその分だけ延びる）。

## 1. 撮る前に（全部の位置で 1 回）

- **ブロックを教えた位置からずらして置かない。** 再生するのは教えたときの関節の角度そのもので、ブロックの位置を見て動きを変えない。LOG352 では位置 4 から約 46mm ずらして置いた 193729 が使えなかった（`count_by_position.py` の見つけ方でも位置 4 から 48mm 離れて「分からない」になる）
- **マットに 5 か所の印を付けておく**（ブロックの四隅が分かる小さな印。上カメラに大きく写る色・赤は使わない）。印の場所は LOG352 で採った試行の上カメラの最初のコマ（HOME で、ブロックが置かれた画）で合わせる: `/Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_20261019_{183454（位置 1）・191541（位置 2）・192438（位置 3）・193459（位置 4）・194913（位置 5）}/recording/top.mp4` の 1 コマめ（`teach_poses_LOG352/prerun_*.jpg` はブロックが箱の中に写っている回があり、目安にならない）。`count_by_position.py` の `TEACH_REF_MM`（同じ見つけ方での 10/19 のブロックの中心）も目安になる: 位置 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) mm
- `measure` の `block_xz` は根元近くの赤いケーブルを拾うことがあり当てにならない（LOG352 の分かったこと）。置けたかは印と画で人が見る
- 閉じる前に人がブロックを押し込まない（指が学習の画に写る。191347・191441 で起きて外した）。`run --execute` は Enter のあとは止まらないので、浅いと思ったら Enter の前に置き直すか、撮ったあとで外す

- **Pi の daemon に read_servo が入っているか**（爪の電流を残すのに使う。依頼 116・121）。入っていなければ `tools/daemon_add_read_servo.sh` で置く。入っていないまま撮っても再生と映像の記録は今までどおりで、電流だけが空になる（1 本目のあとの 4. で `currents_mode` が `get_angles_fallback` と出る）

```
python3 dynamic_tracking_limits/place/place_modules/recorder.py --top --no-side        # 別のターミナルで常駐
```

## 2. 位置ごとに撮る（位置 1 → 2 → 3 → 4 の順。位置 5 は撮らない）

どの位置も同じ流れ。`{教えた記録}` を位置の表のファイル名に替える。

```
# ブロックを位置 N の印に置く
python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py measure                               # 1 本ごとに置き直したら測り直す
python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach {教えた記録}             # ドライラン（計画だけ）
python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach {教えた記録} --execute   # 再生＋記録
```

| 位置 | `{教えた記録}` | 撮る本数（外れなければ） | 前に撮った本の深さ（閉じて 1.0 秒後。依頼 113 G の g_table.csv） |
| --- | --- | --- | --- |
| 1 | `drag_v2_20221013_144348.json` | 10 | 183454 が 38.9px（浅い）。**教えた記録そのものが浅い可能性がある**（下の 2-1） |
| 2 | `drag_v2_20221013_230205.json` | 7 | 残っている 3 本は 8.1・15.9・18.2px（深い） |
| 3 | `drag_v2_20221013_231249.json` | 8 | 4 本中 2 本が 27.6・28.9px（浅い）、残り 2 本は 12.7・17.9px。線のすぐ上なので置き方で変わる可能性 |
| 4 | `drag_v2_20221013_232345.json` | 5 | 5 本とも 24px 以下（4.4〜22.1px。21.6・22.1px は線に近い） |

### 2-0. 各位置の 1 本目を撮ったら、深さと爪の値を見てから続ける

```
python3 pi05/grasp_depth.py /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_YYYYMMDD_HHMMSS
```

1 本につき 2 行出る（1 行目が深さ、2 行目が閉じたあとの爪の電流。2 行目の見方は 4.）:

```
[深い] run_0001_YYYYMMDD_HHMMSS  閉じる直前 ...px  閉じて 1.0 秒後 ...px (線 24px)  爪先の印の間 ...px
    [爪 つかめていそう] run_0001_YYYYMMDD_HHMMSS  閉じたあとの爪の値 最大 ... 中央値 ... (.. 行) (目安の線 100. ...)
```

- **外すかどうかは今までどおり深さ（1 行目）で決める。** 爪の値（2 行目）は目安で、深さと食い違ったら `top.mp4` の閉じる前後を人が見る
- **閉じて 1.0 秒後のはみ出しが 24px（約 9mm）を超えたら、その位置は撮り続けずに止める。** 置き方を印に合わせ直して 1 本だけ撮り直し、それでも 24px を超えたら、教えた記録が浅いとみて 2-1 に進む（その位置の残りは撮らない）
- 24px 以下なら、その位置の残りを撮る。2 本目からも 1 本ずつ測ってよい（`grasp_depth.py` は何本でも渡せる）
- `[測れない]` が出たら（ブロックが見つからない・爪先の印が見えない）、`top.mp4` の閉じる前後を人が見て決める。測れなかった本は学習データを作るときも外されない
- `手が写っていそう` と出たら、その本は使わない方向で画を見る

### 2-1. 教えた記録が浅いとき（位置 1 で起きそう）: 深くつかむように教え直す

位置 1 の前の 1 本（183454）は 38.9px で浅かった。置き方ではなく、教えた PICK の姿勢が浅い可能性がある。教え直しはエイイチが手で行う。

1. ブロックを位置 1 の印に置く → 【Mac】`record_teach_demo.py measure`
2. 【Pi】daemon 停止 → `drag_teach_v2.py teach` → daemon 起動（`record_teach_demo.py` の頭の「1 本のお手本を作る流れ」と同じ）
3. 教えるときの決まり（LOG352 の分かったこと）:
   - **肩 j1（0 始まり）は約 88° まで。** 88° を超えた命令はアームが丸ごと捨てて降りない（LOG352 で肩 +95.53〜+99.22° の 4 つが動かなかった。手で教えるときはモーターの力が抜けているので超えて曲げられてしまう）
   - **肩を倒さず、肘と手首で下げる。** 本線は同じ場所を肩 88〜89°・肘 −33°・手首 −52° 前後でつかんでいる
   - 爪の奥（爪先の印より手前）までブロックが入ってから閉じる
4. 新しい教えた記録で 1 本撮り（ドライランで PICK の肩が 88° 以下かを見てから `--execute`）、2-0 で深さを測る。24px 以下になったら残りを撮る
5. **新しい教えた記録のファイル名を `pi05/count_by_position.py` の `TEACH_FILES` に位置 1 として 1 行足す**（エイイチの決め 2026-11-08: 教え直したら足す。足さないと新しい本が「分からない」に数えられる）。元の `drag_v2_20221013_144348.json` の行は消さない（前に撮った本の数え方が変わらないように）:

   ```
   TEACH_FILES = {
       "drag_v2_20221013_144348.json": 1,
       "drag_v2_YYYYMMDD_HHMMSS.json": 1,     # 位置 1 を教え直した記録 (DEEP_DEMOS 2-1)
       ...
   ```

## 3. 撮り終えたら: データにして、位置ごとの本数を見て、足りない分を撮り足す

```
# 1 本ずつの深さ（読むだけ）
python3 pi05/grasp_depth.py /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/run_0001_YYYYMMDD_HHMMSS ...
# 新しい本だけのデータセットを作る（新しい名前。24px を超えた本は外し、index.json の grasp_depth に値と理由を残す）
python3 pi05/build_demo_episodes.py --dataset mecharm_redblock_box_teach_pos1to4_deep_v1 --trim-mid-idle \
    --max-protrude-px 24 --run run_0001_YYYYMMDD_HHMMSS --run ...
# 位置ごとの本数を見る（今の deep と新しい本を合わせて数える。読むだけ）
python3 pi05/count_by_position.py mecharm_redblock_box_teach_v1_trim2_corr_v5_deep mecharm_redblock_box_teach_pos1to4_deep_v1
```

- `build_demo_episodes.py` の最後に `[DEPTH]` の行が出る: 浅くて外した本・**測れなかった本（外していない）**・**手が写っていそうな本（外していない）**の数と名前。測れなかった本と手の本は `top.mp4` の閉じる前後を人が見て、外すなら merge の `--exclude-json` に書く
- `count_by_position.py` の表の「目標 10 本まで」が ＋ の位置だけ、2. に戻って撮り足す（浅くて外れた分）。全部の位置が ＋0 になったら次へ
- 「分からない」が出たら、表の下の理由を見る（teach/ がない・教え直した記録が `TEACH_FILES` にない・補正入りのブロックが教えた位置から 30mm を超える など）

```
# 今の deep とまとめる（元は変えない。外す本が増えたら --exclude-json に理由と一緒に書く）
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 <新しい名前> --tar
python3 pi05/check_dataset.py /Volumes/KIOXIA/r2r2r-data/datasets/<新しい名前>/raw_episodes
```

- `merge_raw_episodes.py` は作り終えたときに、位置ごとの本数の表を README の最後に足す（依頼 118。`--no-position-table` で足さない。raw_episodes と index.json は表があってもなくても同じ）。目標は `--target`（既定 10）
- 線 24px の意味は `/Volumes/KIOXIA/r2r2r-data/lab/twin/20261107_失敗の再生と置き場所/G_お手本の閉じる時刻/README.md`
- 補正入りの run（`run_policy_client.py`）を足すときも同じで、`build_correction_episodes.py ... --max-protrude-px 24` を付ける

## 4. 爪の電流でつかめたかを見る（依頼 116・121）

教えた動きの再生（`record_teach_demo.py run --execute`）でも、実機推論の記録と同じ読み方で爪と肩の電流が残る（依頼 121）。

- 置き場所: `{run}/recording/currents.csv`（列は実機推論と同じ。`gripper_current` が爪の符号付きの値）と `currents_meta.json`（行の数・頻度・読めなかった数）。試行 JSON（`{run}/{run}.json`）の `currents` にも同じ数が残る
- **再生の本体が daemon を使わずに待っている間（到達・静止の確かめの 0.3 秒の間など）だけ読む**（多くて 1 秒 10 回）。なので再生の動き・確かめの回数と時刻は電流なしと同じ（偽の daemon で、再生にかかる時間の差 0.1 秒以下・本体を待たせた回 0）。そのかわり行は少ない（偽の daemon で 1 本 約 47 行・全体で 1 秒 約 1.3 行。閉じてから放すまでの約 9 秒で 14 行）。`send_angles` の返事を待つ間（1 回 約 1.6 秒）は daemon が答えないので読めない
- **爪の命令を送ってから待ちが終わるまで（閉じる 2 秒・開く 約 6 秒）と、送り直しの前の待ち（5 秒）はわざと読まない**（「爪を動かした直後にシリアルを触らない」2026-10-19 の決まりを守る）。なので閉じた値は、持ち上げ始めてから放すまでの間の値になる
- states.csv の列・行の種類と並びは今までと同じ（学習データの作り方は変わらない）。`currents_meta.json` の `overruns` は、電流の読み取りが本体の待ちの終わりを超えて続いた回数（見込み 0.15 秒より長くかかった回。そのとき本体が daemon を使えば、その分だけ待つ。偽の daemon では 0）。0 でない本が続いたら知らせる（下の `--no-currents` で電流なしに戻せる）

**電流を残さずに撮るとき**: `record_teach_demo.py run --teach ... --execute --no-currents`（今までと同じ動き。電流の読み取りを一切しない）

**1 本撮るごとに見る**: 2-0 の `grasp_depth.py` の 2 行目（`python3 pi05/grip_current.py {run}` でも同じ 1 行だけ出る）。

| 2 行目 | 意味（目安。依頼 109・116 の測り） | すること |
| --- | --- | --- |
| `[爪 つかめていそう]` 最大が 100 以上 | ブロックをつかむと数百〜990 | 深さ（1 行目）で決める |
| `[爪 空で閉じた？]` 最大が 100 未満 | 空で閉じると 15 前後 | 深さが測れていても `top.mp4` を見る。つかめていなければ y/n の「つかめたか」を n に |
| `[爪 値なし]` | 電流が残っていない | 理由を見る。`currents_mode=get_angles_fallback` なら daemon に read_servo がない（1. の確かめ） |

- 放す（開く）と −50 前後になる。閉じたあとの値に負の値が混じっていたら、開いたあとの値を拾っている（爪の命令の時刻を `states.csv` で見る）
- 線 100 は空（15 前後）とつかんだ値（数百）の間に置いた目安で、再生の記録ではまだ実機で確かめていない。最初の数本で実際の値を見て、合わなければ `pi05/grip_current.py` の `GRASP_LINE` を見直す（外す決めには使っていない）
