# 確認依頼：π0.5 が実機でブロックを持ち上げない原因（学習と実機の食い違いの点検）

対象（読むだけ。コードの変更はしないでください）
- `~/r2r2r-scripts/pi05/run_policy_client.py`（実機クライアント。とくに grab_rgb / 状態の作り方 / plan_chunk / apply_limits / グリッパーの扱い）
- `~/r2r2r-scripts/pi05/build_demo_episodes.py`（お手本 → raw_episodes。--trim-mid-idle を含む版で teach_v1_trim2 を作った）
- `~/r2r2r-scripts/pi05/convert_to_lerobot.py`（raw_episodes → LeRobot 形式）
- `~/r2r2r-scripts/pi05/openpi_addon/`（mecharm_policy.py と config の追加。入力・出力の変換、正規化、delta かどうか）
- `~/r2r2r-scripts/pi05/eval_policy_offline.py`（お手本の画像と角度でサーバーに問い合わせる答え合わせ）
- 学習設定：`/Volumes/KIOXIA/r2r2r-data/lab/Log11/pod/add_trim_config.py`（pi05_mecharm_lora を写して repo_id・名前・ステップ数だけ変えたもの）

---

## 何が起きているか

mechArm 270 で、Physical Intelligence の π0.5 を LoRA で学習した（お手本19本・5か所・teach_v1_trim2・4,000ステップ）。
タスクは「赤いブロックをつかんで白い箱に入れる」。

実機では、ブロックはつかめる。しかし**つかんだあと持ち上げず、マットの上を引きずったまま箱へ運び、爪が箱の壁に当たって箱を押す**（横からの動画で確認済み）。お手本は、つかんだあと肩 j1 を 64° → 45° と約19°上げてから箱の上で下ろしている。お手本の持ち上げは十分に大きい。

## 分かっている事実（数値）

1. **答え合わせ（オフライン）では合っている**：お手本の画像と角度を渡すと、つかむ前後・持ち上げ・運ぶ間のすべてで、予測とお手本のずれは平均 0.1〜0.5°（記録：`/Volumes/KIOXIA/r2r2r-data/lab/Log11/offline_eval/20261021_180539/rows.csv`。位置C = run_0001_20261019_192343 の t=36〜108 を参照）
2. **実機では持ち上げが足りない**。ブロックはお手本の位置C ちょうどに置いた（上カメラの写り方は OK を確認）
   | 記録 | 1回に動かす長さ | 上限に当たった関節 | つかんだ姿勢 j0 / j1 | 運ぶ途中の j1 / j4 |
   |---|---|---|---|---|
   | お手本 位置C（4本） | — | — | −28 / 64 | 45〜51 / −54〜−66 |
   | pi05_20261022_095251 | 1秒（10ステップ） | 手を伸ばす間 j1・j4、運ぶ間 j0 | −33 / 63 | 51 / −46〜−49 |
   | pi05_20261022_100713 | 1秒（10ステップ） | 同上 | −37 / 63 | 51 / −44〜−47 |
   | pi05_20261022_102053 | 0.5秒（5ステップ） | なし | −31 / **69** | **56〜58** / −62〜−67 |
   （j4 は + が爪先を下げる向き。記録は `/Volumes/KIOXIA/r2r2r-data/runs/pi05_policy/{記録名}/log.jsonl` と `frames/`。各チャンクの state・予測 actions・送った target がある）
3. 0.5秒ずつの回は、閉じる前に肩を少しずつ下げ続け、お手本より5°深くつかんだ。つかんだ後の予測は、5ステップあたり j1 −2〜−3.6° と小さく、1ステップあたりの持ち上げはお手本の4分の1ほど。回転もお手本の半分ほどの速さ
4. 昨日（10/21）の夕方の8回も、同じく「持ち上げが足りず引きずる」だった（そのときはブロックをお手本の位置の間に置いていた）

## 点検してほしいこと

**オフラインでは合い、実機ではずれる**ので、学習時と実機の推論時で、モデルに渡す入力や予測の使い方が食い違っていないかを見てほしい。

A1. **画像**：学習の画像（recorder が保存した jpg → raw_episodes → LeRobot）と、実機の grab_rgb（1920×1080 を 384×216 に INTER_AREA で縮め、RGB）の作り方は同じか。色の順、縮め方、JPEG を通すかどうか、大きさ、パディングの違い
A2. **状態 state**：7次元（6関節＋グリッパー）。実機のグリッパーの値（0/1）を切り替えるタイミングと、お手本でグリッパーの値が変わるタイミングは同じか。関節角の読み方（daemon_get_angles と、お手本の記録の読み方）に違いはないか
A3. **行動 actions**：お手本の action は「0.1秒後の state（絶対角）」。openpi 側で delta に変換しているか。している場合、推論時に絶対角へ戻す処理と、クライアントの扱いが合っているか。グリッパーの次元の扱い（delta の対象から外れているか）
A4. **正規化**：学習で使った norm_stats（teach_v1_trim2）と、推論サーバーが読む norm_stats は同じか（サーバーの起動ログ：`/Volumes/KIOXIA/r2r2r-data/lab/Log12/serve.log`）
A5. **実行の仕方**：クライアントはチャンクの最後の1つ（5番目または10番目）だけを send_angles で送り、着くまで待ってから次を問い合わせる。お手本では腕が動き続けているが、実機では毎回止まった状態で問い合わせる。この違いで、予測が「動き出し」の小さな動きを繰り返す形になり得るか
A6. そのほか、オフラインの答え合わせと実機の推論で、入力の作り方が違う箇所

## 返してほしいもの

- A1〜A6 それぞれについて、✅ 同じ／⚠️ 気になる／❌ 食い違っている（該当ファイルと行番号）
- 持ち上げが足りない原因として、いちばん疑わしいもの
- 原因を切り分けるための、**アームを動かさない**確かめ方の提案（たとえば、実機の記録の画像とお手本の画像を入れ替えてサーバーに問い合わせる、など）

固定事項（変えない）：HOME = [0,0,0,0,0,−30]、SPEED = 20、J4_SAFE −90〜+60、send_coords() は使わない。
