依頼 142：上カメラの傾き（回転）を数字で出し、位置合わせの画面に足す（Log28・実機は動かしていない）

■ 1. 変えた所
- pi05/camera_tilt.py（新規）
  - tilt_deg(frame)：count_by_position.detect_corners でマットの四隅を取り、下の 2 つ（左下 BL・右下 BR）を結ぶ線の角度を返す。
    度で、プラス＝右下がり（atan2(BR.y − BL.y, BR.x − BL.x)）。四隅が取れない・見つけ方が落ちる・左右が逆のときは None（＝測れない）。
  - reference_tilt(raw_dir)：各エピソードの 1 枚目の傾きの中央値（測れた本数・全本数も返す）。50 本で 0.1 秒。
  - tilt_text(今, お手本)：端末用の 1 行。差が ±0.5°（TILT_WARN_DEG）を超えたら「傾きがお手本と違う」。
  - 道具として：--dataset（位置ごとの表）／--live（上カメラ 1 枚と全体の中央値との差）／--video（動画の 1 コマ目. 記録の見直し用. 足した）。何も書き出さない。
- pi05/camera_align.py
  - 画面の dy/resp の下に「tilt=… ref=… diff=… deg」を出す。差が ±0.5° を超えたら橙色にして「TILT DIFFERS (> 0.5 deg)」を大きく出す。四隅が取れなければ「tilt: NO CORNERS」。止めはしない。
  - [ALIGN ] の行の最後に傾き・お手本の中央値・差を足した（傾きが 0.15° 以上動いたときも行を出す）。始めに [TILT  ] でお手本のフォルダと中央値を出す。
  - --tilt-raw-dir を足した（傾きのお手本を取る raw_episodes。未指定なら --raw-dir）。写り方の判定（±20px・response）は変えていない。
  - 傾きは画面と同じ縮めた画像（長辺 384. 学習画像と同じ大きさ）で測る。
- lab_start.sh：camera_align.py に --tilt-raw-dir "$RAW_RANGE"（安全範囲と同じ raw_episodes。deep1・deep1b なら deep_even10_v1、ほかは trim2）を渡す。起動時に [TILT  ] の行で取り先を出す。頭の説明に 1 項足した。
  （位置合わせの重ねる画像は今までどおり trim2。どちらを見るか迷ったので、依頼どおり安全範囲の --raw-dir の方にした）
- pi05/run_policy_client.py：[CAMERA] 基準: の次に [CAMERA] 傾き … の 1 行（お手本は --raw-dir＝安全範囲と同じ）。表示だけで、log.jsonl・判定・停止は変えていない。測り方が落ちても「測れない」の行を出して続く。
- pi05/test_camera_tilt.py（新規）・test_lab_start.sh（2 項足した）

■ 2. deep_even10_v1 の表（python3 pi05/camera_tilt.py --dataset mecharm_redblock_box_deep_even10_v1）
| 位置 | 本数 | 測れた | 中央値 (°) | 最小〜最大 (°) |
| --- | --- | --- | --- | --- |
| 位置 1 | 10 | 10 | +0.41 | -1.43 〜 +0.62 |
| 位置 2 | 10 | 10 | -0.82 | -1.03 〜 -0.41 |
| 位置 3 | 10 | 10 | -1.03 | -1.03 〜 -0.61 |
| 位置 4 | 10 | 10 | -0.82 | -1.03 〜 -0.41 |
| 位置 5 | 10 | 10 | -0.41 | -1.64 〜 +0.21 |
| 全体 | 50 | 50 | -0.61 | -1.64 〜 +0.62 |

依頼の数字と合う：
- 位置 1 の 11/09 午前の 9 本（094839〜101157）は +0.41〜+0.62（右下がり）。位置 1 の残り 1 本 103049 は -1.43。
- 位置 2〜5 はほぼ -0.41〜-1.03（右上がり）。位置 5 の 10/31 の 3 本は 0.00、11/01 は +0.21、11/06 の 2 本は -1.64。
- 学習画像は長辺 384 なので 1 本の値は約 0.2° きざみ（-0.41／-0.61／-0.82／-1.03 が並ぶのはそのため）。
（trim2 の 19 本の全体の中央値は -0.41°。trim・corr 系で lab_start を使うとこちらがお手本になる）

Log28 の 11/10 の試行（top.mp4 の 1 コマ目. 1920×1080 のまま／384 に縮めて）：
| 試行 | 傾き (生) | 傾き (縮めて) | お手本 -0.61° との差 |
| --- | --- | --- | --- |
| pi05_20261110_111034（成功） | -1.02 | -1.02 | -0.41（±0.5 以内） |
| pi05_20261110_112346 | +0.69 | +0.61 | +1.31 → 傾きがお手本と違う |
| pi05_20261110_113600 | +0.65 | +0.61 | +1.27 → 傾きがお手本と違う |
| pi05_20261110_114106 | +0.65 | +0.61 | +1.27 → 傾きがお手本と違う |
（差は生の値で計算。112346 以降の iPhone の付け直しで約 1.7° 回ったことが、この表示なら位置合わせの画面で TILT DIFFERS として出る）

■ 3. テスト
- pi05/test_camera_tilt.py：8 件 OK
  合成画像（黒いマット・上は画面の外）を +1／-1／0／+1.7／-0.5° 回して、生の大きさで ±0.1° 以内（+1° → +0.98、-1° → -0.98、+1.7° → +1.73）、
  384×216 で ±0.35° 以内（+1° → +0.94、-1° → -0.94）。向き（右下がり＝プラス）も確かめた。
  測れないとき（真っ白・画像なし・見つけ方が落ちる・左右が逆・角が 4 つでない）は None で落ちない。
  reference_tilt（空のフォルダ・画像のない本を含む）、±0.5° の線、camera_align の画面（傾きあり・なし・差が大きい・今までの呼び方）、
  camera_align.main のループ（偽物のカメラで 数値→測れない→数値 のとき [ALIGN ] 行に傾きが出る）、run_policy_client.camera_tilt_line（フォルダなし・測り方が落ちる）。
- 既存：test_lab_start.sh 178 OK / NG 0（176 → 178。足したのは deep1 の傾きのお手本が deep_even10_v1・camera_align.py に --tilt-raw-dir "$RAW_RANGE" を渡す の 2 項）。
  pi05/test_*.py はすべて OK（count_by_position・diag_joint_hold・framing_raw_dir・gap_fill・grasp_depth・hf_upload_ckpt・merge_and_config 34・pad_build・pad_correction 4・recorder_currents 15・recorder_rpc・rewind_correct 69・teach_currents 23・trim_hold）。

■ 4. codex
2 回（codex exec -s read-only）。
- 1 回目：必須なし。推奨 2 件 ①camera_align.main のループ（初回・数値→None→数値・[ALIGN ] の出力）をテストする ②reference_tilt／tilt_deg が例外を投げても camera_tilt_line が「測れない」を返すことをテストする → 両方テストに足した。
- 2 回目：必須なし・推奨なし。

■ 5. commit
0531717（変えた 6 ファイルだけを指定して add）

■ 6. エイイチが試す前に使う打ち方
  cd ~/r2r2r-scripts
  python3 pi05/camera_tilt.py --live --dataset mecharm_redblock_box_deep_even10_v1
上カメラ（iPhone 連係）が見えている状態で、アームは HOME。1 枚だけ取って次のように出る（何も書き出さない）：
  [REF ] …/mecharm_redblock_box_deep_even10_v1/raw_episodes  全体の中央値 -0.61°  (測れた 50/50 本)
  [LIVE] 上カメラ (1920×1080) 傾き +0.65° (プラス=右下がり) / お手本の中央値 -0.61° / 差 +1.26° → 傾きがお手本と違う (±0.5° を超える)
差がプラスなら右下がりが強い（iPhone の右側を少し上げる向きに回す）、マイナスなら逆。
lab_start.sh の 7 の位置合わせの画面にも同じ数字が出る（実機での画面の見え方はまだ確かめていない。カメラを開いた確かめもしていない）。

■ 7. 決めてほしいこと（作業は止めていない。次に使う前に見てほしい）
1. 傾きのお手本：lab_start.sh は安全範囲と同じ raw_episodes を渡すようにした（deep1・deep1b は deep_even10_v1 の中央値 -0.61°、trim・corr 系は trim2 の -0.41°）。位置合わせで重ねる画像（trim2）とはお手本が違う。これでよいか。
2. どの傾きに合わせるか：学習データ自体が位置 1 だけ +0.41°、位置 3 は -1.03° とばらついている（全体 -1.64〜+0.62）。全体の中央値 -0.61° に合わせると、位置 1 の写り方とは約 1° 違う。全体の中央値に合わせるか、位置ごとの中央値（表の値）に合わせるか。今は全体の中央値だけを画面に出している。
3. 線 ±0.5°：依頼どおりにした。学習画像の 1 本の値は 0.2° きざみで揺れるので、中央値の近くでは表示がちらつくことがある（止めないので動きには影響しない）。

判定：合格
