フィジカルAI研究室を作る Log#34 | mechArm 270 の電源を5Aに替え、ブロックを落とさなくなった

この記事の素材(コード・ログ・データ 4ファイル・まとめてダウンロードあり)
AIで読む ChatGPT・Claude などで、この記事に質問できます

小型ロボットアーム mechArm 270 がつかんだブロックを落とす原因は、電源アダプターの不足でした。12V・2A(24W)から12V・5A(60W)に替えると、Physical Intelligence の π0.5 に動かさせた位置5 のつかみは5回とも成功し、同じモデル・同じ爪の閉じる値で12V・2A だった11月11日の3回中1回から変わりました。 人が手で教えた動きの再生も、位置5 で6回、位置2 で1回、すべて箱に入りました。

この回の差し替えで、次のことが変わりました。

  • 人が手を出す回数が減った:12V・2A の日は位置5 の3回とも、途中でゲームパッドを使って人がアームを持ち上げ直していた。12V・5A では5回のうち4回、人は Enter を押して進めるだけで終わった
  • 爪の力が抜けなくなった:爪のサーボの電流は、12V・2A の日は3回とも、つかんでいる途中で0付近まで落ちていた(閉じてから26.7秒・72.4秒・103.8秒)。12V・5A では5回のうち4回、箱の上で開くまで600〜780 のまま保った
  • 費用:アダプターは3,355円。この回の GPU(Runpod の A40)は2回借りて約27円と約7円
  • アームの動きが目で見てきびきびした(体感。動きの速さは数字で比べていない)

前の回(LOG487)で、位置5 の失敗はブロックまで届かないのではなく、つかんだあとに落とすものだと分かりました。爪の電流が、指令を何も送っていないのに急に抜けていたのです。アームの台座のラベルは40W を求めているのに、届いたときから使っていたアダプターは24W でした。アームは2026年3月に届き、箱に AC アダプターが入っていなかったため、あとから別に送られてきたのがこの12V・2A です。8か月の実機の記録は、すべてこの電源で取っていたことになります。

新しいアダプターが届いたので、差し替えて同じ動きを試しました。

やったことなぜ結果
Pi を落として、12V・5A に差し替える
電源を本体の求める量より多くする
起動し、つながった(つながるまで約3分)
位置5 で教えた動きを6回再生する
毎回同じ動きで、爪が緩むかを見る
6回とも成功。つかんでいる間の爪の位置は1615〜1618 のまま
12V・2A で同じ再生を撮るかを決める
比べる記録を残すか
目で見て違いがはっきりしたので撮らない
位置5 で π0.5 を5回動かす
落としていた場面そのもので確かめる
5回とも成功。1回だけ、人が持ち上げた瞬間に爪の電流が落ちた
位置2 で教えた動きを1回再生する
ほかの置き場所でも動きを見る成功。お手本どおりに動いた
新しく届いたスイッチサイエンスの AC アダプター。ラベルは出力 DC 12V・5A、型番 SNDEI3060-120050PA

実機と推論の記録は、KIOXIA の runs/run_pick_place/run_0001_20261113_*(再生)と runs/pi05_policy/pi05_20261113_*(推論)、lab/Log34/ に入れています。

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

導入比較ガイドロボットAIの学習用GPU、買うか借りるか実際に借りて学習させた費用と、損益分岐の計算機で決められます

作業ログ ― 電源を12V・5A に替え、位置5 と位置2 でつかみを確かめるまで

ここから下は作業の記録です。コマンド・出力・コードは全量で載せます。効果を書いた所のうち、数字で書いたものは測った値、「見込み」と書いたものはまだ確かめていない値です。

この回で何度も出てくる言葉を先に言い換えておきます。

  • 位置1〜位置5:赤いブロックを置く5つの場所。お手本はこの5か所で10本ずつ撮った
  • 教えた動きの再生:人がアームを手で動かして教えた要所の姿勢(ブロックの真上・つかむ位置・箱の上・放す位置)を、毎回同じ角度・同じ速さで送り直す動かし方(record_teach_demo.py)。AI は使わない
  • π0.5:Physical Intelligence が公開しているロボット用の AI。上カメラの画像と関節の角度を見て、次の動きを出す。この回は、位置ごとに10本そろえた50本で学習したモデル deep1 を使った(LOG480)
  • 爪の電流:爪を動かすサーボが使っている電流を、サーボの番地から直接読んだ値(単位のない生の数。LOG461)。爪がブロックを押しているあいだは600〜900、開いているときはマイナス50前後、何も押していないときは0付近になる
  • 爪の位置:爪のサーボの今の角度を、番地56・57 から読んだ生の値。この機体では開いたとき約2034、ブロックをつかんだとき約1617 だった
  • 閉じる値:爪を閉じるときにサーボへ送る目標の値(0〜100)。再生は20、π0.5 の推論は25 で動かした
  • Pod:Runpod で借りる GPU のマシン。π0.5 はこの上で動き、Mac から画像と関節の角度を送って次の動きを受け取る

12V・5A のアダプターに差し替え、Pi が起動するまで

差し替えの順番:Pi を落としてから電源を抜く

電源を差し替える手順は、前の日に pi05/POWER_AB.md に書いてありました。アームの電源だけを抜き差しせず、先に中の Raspberry Pi を shutdown し、ランプが消えてからアダプターを替えます。

届いたアダプターは、出力が DC 12V・5A(60W)、プラグの中心がプラスの記号でした。前に使っていた12V・2A と同じ向きです。

起動直後に Pi へつながらなかった理由

差し替えて電源を入れたあと、しばらく ssh も ping も返ってきませんでした。Mac の有線の口(en8)にも 192.168.2 の番号が付いておらず、Mac とアームのあいだの線がまだつながっていない状態でした。アームのサーボは力を保っていたので、電源は来ていました。数分待って同じコマンドを打つと、en8 に 192.168.2.2 が付き、ping が返り、daemon(アームを動かす Pi 側の常駐プログラム)も起動していました。差し替えの直後は、Pi の起動が終わるまで3分ほどかかったことになります。

途中の recorder.py のエラーは、置き場所を間違えて打ったもので、正しくは dynamic_tracking_limits/place/place_modules/recorder.py です。

差し替えから daemon の確認までのターミナル

Last login: Tue Nov 10 19:34:16 on ttys004
(base) shimazueiichi@shimadzueiichinoMacBook-Pro ~ % ssh -i ~/.ssh/id_rsa_pi ubuntu@192.168.2.1 'sudo shutdown -h now'
Connection to 192.168.2.1 closed by remote host.
(base) shimazueiichi@shimadzueiichinoMacBook-Pro ~ % cd ~/r2r2r-scripts && python3 recorder.py --top --no-side
python3: can't open file '/Users/shimazueiichi/r2r2r-scripts/recorder.py': [Errno 2] No such file or directory
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % cd ~/r2r2r-scripts
ssh -i ~/.ssh/id_rsa_pi ubuntu@192.168.2.1 'echo ok'
bash tools/daemon_ctl.sh status
ssh: connect to host 192.168.2.1 port 22: Operation timed out
ssh: connect to host 192.168.2.1 port 22: Operation timed out
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % ping -c 3 192.168.2.1
PING 192.168.2.1 (192.168.2.1): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1

--- 192.168.2.1 ping statistics ---
3 packets transmitted, 0 packets received, 100.0% packet loss
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % bash tools/daemon_ctl.sh status
ssh: connect to host 192.168.2.1 port 22: Operation timed out
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % ping -c 3 192.168.2.1
PING 192.168.2.1 (192.168.2.1): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1

--- 192.168.2.1 ping statistics ---
3 packets transmitted, 0 packets received, 100.0% packet loss
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % ifconfig | grep -B4 "192.168.2"
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % ifconfig | grep -B4 "192.168.2"
ping -c 3 192.168.2.1
en8: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	options=6464<VLAN_MTU,TSO4,TSO6,CHANNEL_IO,PARTIAL_CSUM,ZEROINVERT_CSUM>
	ether 00:e0:4c:46:23:48
	inet6 fe80::188e:3b4f:ba1:e28%en8 prefixlen 64 secured scopeid 0x16 
	inet 192.168.2.2 netmask 0xffffff00 broadcast 192.168.2.255
PING 192.168.2.1 (192.168.2.1): 56 data bytes
64 bytes from 192.168.2.1: icmp_seq=0 ttl=64 time=1.886 ms
64 bytes from 192.168.2.1: icmp_seq=1 ttl=64 time=1.249 ms
64 bytes from 192.168.2.1: icmp_seq=2 ttl=64 time=1.497 ms

--- 192.168.2.1 ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 1.249/1.544/1.886/0.262 ms
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % bash tools/daemon_ctl.sh status
ssh: connect to host 192.168.2.1 port 22: Operation timed out
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % bash tools/daemon_ctl.sh status
--- process
512 /usr/bin/python3 -u /home/ubuntu/mecharm_daemon.py
--- 5555
LISTEN0      1                                 0.0.0.0:5555        0.0.0.0:*    
--- systemd
enabled: enabled
active:  active

位置5 で教えた動きを12V・5A で6回再生した

この記事のコード・ログ・データは、1ファイルずつ下に置いています。全文はリンク先にあります。

ファイルの一覧(4本)

01_measure_806px_1.txt ― measure でマットの四隅が806px ずれて見えた件 / 1回目:measure・ドライラン・再生のターミナル・24,682字

02_measure_806px_2_6.txt ― measure でマットの四隅が806px ずれて見えた件 / 2〜6回目の再生のターミナル・61,807字

03_5_5_lab_start.sh.txt ― 位置5 の推論5回のターミナル / lab_start.sh(deep1・閉じる値25・Log34)のターミナル・163,576字

04_2_measure.txt ― 推論ではなく、教えた動きの再生で位置2 を見た / 位置2 の measure・ドライラン・再生のターミナル・23,252字

再生のコマンドと、記録に足したもの

位置5 の教えた記録 drag_v2_20221013_233323.json を、--power 5A を付けて再生しました。--power を付けると、いつもの記録(上カメラの映像・関節の角度・爪と肩の電流)に、爪の位置(サーボ7 の番地56・57)と電圧(肩のサーボ2 と爪のサーボ7 の番地62)が足されます。前の日に電源の比べのために入れた仕組みで、実機で通したのはこれが初めてです。

  • ねらい:爪が緩むかを、目で見た感じではなく、爪の位置と電流と電圧の数字で確かめる
  • 変わったこと:足した番地は4つとも、1回あたり17〜24回読めた(読めなかった番地はない)
  • 見込める効果:これから電源・爪の閉じる値・つかむ物を変えたときも、同じ列で前後を並べられる

6回の数字:爪の位置は1615〜1618 のまま動かなかった

6回とも、つかんで箱に入りました。つかんでいる間の数字は次のとおりです。

試行運ぶ間の爪の電流つかんでいる間の爪の位置電圧(肩 / 爪)
19:13(run_0001_20261113_191353)
907→877161870〜72 / 69〜74
19:17(191709)894→848161769〜72 / 67〜75
19:18(191807)893→868161570〜73 / 70〜74
19:19(191916)878→858161871〜72 / 68〜74
19:20(192043)871→852161870〜72 / 70〜74
19:22(192223)865→850161771〜72 / 68〜75

つかんでいる間、爪の位置は6回とも1615〜1618 から動かず、開く向きに戻った回はありませんでした。 爪の電流は1回の中で3〜5% ずつ下がり、回を重ねるごとに出だしの値も907 から865 へ下がっています。原因は確かめていません。

電圧の番地62 は、69〜75 の間で落ち着いていました。手順書には「0.1V 単位なら12V で120前後になるはず」と書いていましたが、実際はそれより低い値です。サーボに届く電圧が12V から下げてあるなら7.2V 前後を示していると読めますが、この番地の単位はこの機体ではまだ確かめていません。持ち上げで急に下がる様子はありませんでした。

19:13 の1回目のあとに、爪の位置と電圧の生の値を開いて見ました。開いた状態が2034、ブロックをつかんで運んでいる間が1618 で、箱の上で開くとまた2034 に戻っています。

ts,r7_56,r7_57,gripper_pos,r2_62,r7_62,note
1794564836.007821,64,7,1856,,,
1794564836.289328,,,,71,72,
1794564836.410041,64,7,1856,,,
1794564836.690279,,,,71,72,
1794564837.090282,64,7,1856,,,
1794564837.490369,,,,72,73,
1794564837.610246,63,7,1855,,,
1794564837.886076,,,,72,73,
1794564838.300705,63,7,1855,,,
1794564838.411324,,,,72,74,
1794564838.700701,63,7,1855,,,
1794564838.813386,,,,72,73,
1794564839.342287,63,7,1855,,,
1794564839.666017,,,,72,72,
1794564839.990259,63,7,1855,,,
1794564847.396785,,,,72,74,
1794564847.721627,242,7,2034,,,
1794564848.033381,,,,72,72,
1794564848.357695,242,7,2034,,,
1794564848.685924,,,,72,71,
1794564849.325770,242,7,2034,,,
1794564849.649592,,,,70,71,
1794564849.992583,242,7,2034,,,
1794564850.320003,,,,72,73,
1794564850.650722,242,7,2034,,,
1794564850.951843,,,,72,74,
1794564852.373621,244,7,2036,,,
1794564852.701508,,,,72,73,
1794564853.023256,244,7,2036,,,
1794564857.529508,,,,71,69,
1794564858.957396,82,6,1618,,,
1794564859.274433,,,,72,70,
1794564859.600132,82,6,1618,,,
1794564868.109303,,,,72,73,
1794564868.433587,242,7,2034,,,
1794564868.753541,,,,71,74,

19:22 の6回目は、ターミナルの画面を録画しました。KIOXIA の runs/run_pick_place/run_0001_20261113_192223/screen_terminal_20261113_192205.mp4(約60秒)に置いています。

measure でマットの四隅が806px ずれて見えた件

再生の前の measure(上カメラでブロックと箱の位置を測る段)で、マットの四隅の1つが806px ずれて検出され、「この measure の homography は信用できません」と出ていました。ブロックの位置は5回とも同じ値で、再生は決まった角度で動くので、この回の結果には影響していません。6回目の前だけ、ブロックの位置が (-527.5, +251.4)mm と大きく外れて出ていますが、ブロックはそのまま位置5 にあり、つかめています。四隅の見間違いか、カメラがずれたのかは、確認画像(mecharm_calibration/teach_poses_20261113/measure_20261113_191316.jpg)でまだ見ていません。

1回目:measure・ドライラン・再生のターミナル

01_measure_806px_1.txt24,682字・326行・text
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % cd ~/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_20221013_233323.json --power 5A
python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20221013_233323.json --power 5A --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)
別のタブで開く保存

2〜6回目の再生のターミナル

02_measure_806px_2_6.txt61,807字・795行・text
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20221013_233323.json --power 5A --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)
別のタブで開く保存

12V・2A で同じ再生を撮らずに進めた判断

手順書(POWER_AB.md)では、12V・2A のうちに同じ再生で3回撮り、12V・5A の3回と並べることにしていました。「動きが良くなった気がする」で終わらせないためです。ところが12V・2A の記録を撮る前にアダプターが届き、先に12V・5A で動かしました。

1回目の再生を見て、「アームの動きがキビキビして今までと全然違う」と感じました。Claude は、12V・2A に戻して同じ再生を3回撮ってから比べることを提案しましたが、目で見て違いがはっきりしているので比べる記録は要らないと判断し、12V・5A のまま進めることにしました。そこで、12V・2A との比べは、前の日(11月11日)に同じ位置5・同じモデル・同じ閉じる値で撮った π0.5 の推論の記録と並べることにしました(次の節)。再生どうしの比べは残っていません。

位置5 で π0.5 を12V・5A で5回動かした

Runpod の A40 で deep1 を起動し、位置5 で5回

前の回で落としていたのは、π0.5 に動かさせた位置5 のつかみです。同じ条件(モデル deep1・爪の閉じる値25・位置5)で、lab_start.sh から Pod を作って推論しました。Pod を作り始めてから1回目の推論までは約5分、5回の推論は合わせて約8分(位置合わせの時間を除く)でした。

回推論の記録結果人の手閉じて1秒後の爪の電流
1
pi05_20261113_193254
成功なし791
2
pi05_20261113_193542
成功なし778.5
3
pi05_20261113_193712
成功
ゲームパッドで1回(推論9 のあと、肩 j1 を54°→48° に持ち上げた)
676
4
pi05_20261113_193939
成功なし722
5
pi05_20261113_194108
成功なし765

爪の締め直し(r)は、5回とも一度も使っていません。

12V・2A の日の3回と、つかんでいる間の爪の電流を並べた

11月11日の夕方に、同じ deep1・閉じる値25・位置5 で動かした3回(LOG487 の終わりの3本)と、爪がブロックを押している間の電流を並べました。押している間は、爪の電流が300 を超えてから、開く指令を送るまでとしました。「力が抜けた」は、その間に電流が150 未満へ落ち、1秒以上そのままだったときです。

電源推論の記録結果人の直し押している時間電流の中央値力が抜けた時刻(閉じてから)
12V・2A
pi05_20261111_160851
成功1回121.4秒661103.8秒
12V・2A
pi05_20261111_161402
失敗1回171.1秒63472.4秒
12V・2A
pi05_20261111_161743
失敗1回68.1秒926.7秒
12V・5A
pi05_20261113_193254
成功023.4秒723抜けなかった
12V・5A
pi05_20261113_193542
成功029.5秒627抜けなかった
12V・5A
pi05_20261113_193712
成功1回38.3秒61824.6秒
12V・5A
pi05_20261113_193939
成功027.4秒645抜けなかった
12V・5A
pi05_20261113_194108
成功026.9秒700抜けなかった

12V・2A の日は、3回とも途中で力が抜け、3回とも人がゲームパッドで直していました。押している時間が68〜171秒と長いのは、人の直しを待つ時間が入っているためです。12V・5A では、閉じてから箱の上で開くまでが23〜30秒で終わり、4回は一度も抜けませんでした。

  • ねらい:本体の求める40W に足りない24W の電源を、60W に替える
  • 変わったこと:位置5 の π0.5 は、12V・2A の3回中1回成功から、12V・5A の5回とも成功へ。人の直しは3回中3回から5回中1回へ
  • 見込める効果:π0.5 のお手本を撮り足すときに、緩みかけたお手本が混ざりにくくなる(見込み。次にお手本を撮るときの爪の電流で確かめる)

12V・5A でも1回だけ、持ち上げた瞬間に爪の電流が落ちた

3回目(pi05_20261113_193712)は、推論9 のあとで人がゲームパッドの方向キー(上)を押し、肩 j1 を54.31° から持ち上げました。その記録は 19:38:07.859 に始まり、爪の電流は 19:38:08.73 ごろに610 から93 へ、そのあと開くまで64〜94 のあいだにとどまりました。ブロックは落ちず、箱に入っています。

12V・2A の日に力が抜けていたのも、アームを動かす指令を送った直後でした(LOG487)。12V・5A でも、ゲームパッドで一気に持ち上げた場面では、同じように爪の電流が落ちることがある、ということです。π0.5 が自分で動かした4回では、一度も落ちていません。持ち上げの速さで決まるのか、電源がまだ足りないのかは、この1回からは分かりません。

押している間の電流を出したスクリプト

12V・2A と12V・5A の推論の記録から、上の表の数字を出したコードです。元のデータは読むだけで、結果は lab/Log34/analysis/hold_2A_vs_5A.json に書き出しました。

hold_analysis.py

"""π0.5 の実機推論で、爪がブロックを押している間の電流を、電源 12V・2A の日(2026-11-11)と 12V・5A の日(2026-11-13)で並べる(LOG504)。

元データ(読むだけ): /Volumes/KIOXIA/r2r2r-data/runs/pi05_policy/{run}/recording/currents.csv・log.jsonl・{run}.json
押している間 = 爪の電流が 300 を超えてから、開く指令(grip_cmd=0 のチャンク)を送るまで。
「抜けた」= 押している間に電流が 150 未満へ落ちた(開く指令の前に)。
使い方: python3 hold_analysis.py <runs/pi05_policy のフォルダ> <出力 JSON>
"""
import csv
import json
import sys
from pathlib import Path

RUNS = {
    '2A': ['pi05_20261111_160851', 'pi05_20261111_161402', 'pi05_20261111_161743'],
    '5A': ['pi05_20261113_193254', 'pi05_20261113_193542', 'pi05_20261113_193712',
           'pi05_20261113_193939', 'pi05_20261113_194108'],
}
ON, OFF = 300, 150


def one(root, run):
    d = Path(root) / run
    meta = json.loads((d / f'{run}.json').read_text())
    grip_value, open_t, regrips, pads = None, None, 0, 0
    for line in (d / 'log.jsonl').read_text().splitlines():
        j = json.loads(line)
        if j.get('type') == 'model':
            grip_value = j.get('grip_value')
        if j.get('grip_cmd') == 0 and open_t is None and j.get('executed'):
            open_t = j['t']
        if j.get('type') in ('regrip', 'regrip_tighten'):
            regrips += 1
        if j.get('type') in ('pad_correction', 'correction'):
            pads += 1
    rows = [(float(r['ts']), float(r['gripper_current']))
            for r in csv.DictReader(open(d / 'recording/currents.csv')) if r['gripper_current'] not in ('', None)]
    t_on = next((t for t, v in rows if v > ON), None)
    out = {'run': run, 'outcome': meta.get('outcome'), 'grip_value': grip_value,
           'regrips': regrips, 'corrections': meta.get('corrections'), 'closed': t_on is not None}
    if t_on is None:
        return out
    end = open_t if open_t and open_t > t_on else rows[-1][0]
    hold = [(t - t_on, v) for t, v in rows if t_on <= t <= end]
    drop = next((round(t, 1) for t, v in hold if v < OFF), None)
    vals = sorted(v for _, v in hold)
    out.update({'hold_s': round(end - t_on, 1), 'n': len(hold), 'median': vals[len(vals) // 2],
                'min': vals[0], 'dropped_at_s': drop,
                'series': [(round(t, 2), v) for t, v in rows if t_on - 2 <= t <= end + 1 and True]})
    out['series'] = [(round(t - t_on, 2), v) for t, v in rows if t_on - 2 <= t <= end + 1]
    return out


if __name__ == '__main__':
    root, dest = sys.argv[1], sys.argv[2]
    res = {k: [one(root, r) for r in v] for k, v in RUNS.items()}
    Path(dest).write_text(json.dumps(res, ensure_ascii=False))
    for k, v in res.items():
        for r in v:
            print(k, r['run'], r['outcome'], 'grip', r['grip_value'], 'corr', r['corrections'],
                  'hold', r.get('hold_s'), 'median', r.get('median'), 'min', r.get('min'), 'dropped_at', r.get('dropped_at_s'))

hold_analysis.py の出力

2A pi05_20261111_160851 success grip 25 corr 1 hold 121.4 median 661.0 min 32.0 dropped_at 103.7
2A pi05_20261111_161402 failure grip 25 corr 1 hold 171.1 median 634.0 min -98.0 dropped_at 0.3
2A pi05_20261111_161743 failure grip 25 corr 1 hold 68.1 median 9.0 min -15.0 dropped_at 26.7
5A pi05_20261113_193254 success grip 25 corr 0 hold 23.4 median 724.0 min 423.0 dropped_at None
5A pi05_20261113_193542 success grip 25 corr 0 hold 29.5 median 628.0 min 512.0 dropped_at None
5A pi05_20261113_193712 success grip 25 corr 1 hold 38.3 median 618.0 min 64.0 dropped_at 24.6
5A pi05_20261113_193939 success grip 25 corr 0 hold 27.4 median 645.0 min 315.0 dropped_at None
5A pi05_20261113_194108 success grip 25 corr 0 hold 26.9 median 700.0 min 326.0 dropped_at None

「力が抜けた時刻」は、上の出力の dropped_at(150 未満に初めて落ちた時刻)ではなく、1秒以上150 未満が続いた最初の時刻で数え直しました。161402 の dropped_at が0.3秒なのは、閉じた直後に一瞬だけ値が下がったためで、続けて落ちたのは72.4秒です。数え直しに使ったコマンドと出力です。

$ cd /Volumes/KIOXIA/r2r2r-data/lab/Log34/analysis && python3 -c "
import json;d=json.load(open('hold_2A_vs_5A.json'))
for k in d:
  for r in d[k]:
    s=[(t,v) for t,v in r['series'] if 0<=t<=r['hold_s']]
    sus=None
    for i,(t,v) in enumerate(s):
      if v<150 and all(w<150 for tt,w in s if t<=tt<=t+1.0): sus=t;break
    print(k,r['run'][-6:],'sustained_drop',sus)
"
2A 160851 sustained_drop 103.75
2A 161402 sustained_drop 72.36
2A 161743 sustained_drop 26.7
5A 193254 sustained_drop None
5A 193542 sustained_drop None
5A 193712 sustained_drop 24.57
5A 193939 sustained_drop None
5A 194108 sustained_drop None

位置5 の推論5回のターミナル

Pod の起動から5回の推論までの全部です。Pod の IP とポートは、もとの出力の段階で <POD_IP>:<SSH_PORT> に伏せてあります。

lab_start.sh(deep1・閉じる値25・Log34)のターミナル

03_5_5_lab_start.sh.txt163,576字・2,065行・text
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % cd ~/r2r2r-scripts
./lab_start.sh --model deep1 --grip-value 25 --log Log34
[LOG   ] ターミナルの出力を残します → /Volumes/KIOXIA/r2r2r-data/lab/Log34/lab_start_20261113_192747.txt
[RANGE ] 安全範囲 (学習データ ±10°) は /Volumes/KIOXIA/r2r2r-data/datasets/mecharm_redblock_box_deep_even10_v1/raw_episodes から (--model deep1)
[FRAME ] 写り方の確かめの基準画像は /Volumes/KIOXIA/r2r2r-data/datasets/mecharm_redblock_box_teach_v1_trim2/raw_episodes の最初のエピソードから (位置合わせと同じ trim2. 依頼 137)
[TILT  ] 上カメラの傾きのお手本 (各エピソードの 1 枚目の中央値) は /Volumes/KIOXIA/r2r2r-data/datasets/mecharm_redblock_box_deep_even10_v1/raw_episodes から (安全範囲と同じ. 差だけ画像を回して AI に渡す. 依頼 144)
[GRIP  ] 爪の閉じる値は 25 (--grip-value). 締め直し r はこの値−3 とこの値を交互に送る (依頼 152)
[LAB   ] 2026-11-13 19:27:47  GPU=NVIDIA A40  episode=run_0001_20261019_194818  log=/Volumes/KIOXIA/r2r2r-data/lab/Log34  
別のタブで開く保存

1台目の Pod を消した lab_stop.sh

(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % ./lab_stop.sh
[STOP  ] Log34 の Pod: id bjcya1w5ptkb3i  GPU=NVIDIA A40  作った時刻 2026-11-13 19:27:49
[LOG   ] serve.log を持ち帰った → /Volumes/KIOXIA/r2r2r-data/lab/Log34/serve.log (33 行)
[STOP  ] Terminate を送った (19:44:54)
[STOP  ] Pod (id bjcya1w5ptkb3i) が消えたことを API で確かめた
[COST  ] 借りていた時間 17 分 5 秒 (0.28 時間) × 1時間 0.59 ドル = 約 0.17 ドル (約 27 円. 1ドル=158円)
[TUNNEL] 8000 番のトンネルは残っていません

位置2 で教えた動きを12V・5A で再生した

推論ではなく、教えた動きの再生で位置2 を見た

位置2 は、前の回までに π0.5 が届かなかった場所です(LOG484)。はじめは位置2 も π0.5 で試すつもりで、位置2 のお手本 run_0001_20261019_191541 を位置合わせに重ねる指定で lab_start.sh を動かしました。途中で、推論ではなく教えた一連の動きを見ることにして、Ctrl-C で止めました。そこで位置2 の教えた記録 drag_v2_20221013_230205.json を再生しました。

測ったブロックの位置は (+215.4, +244.8)mm で、お手本の位置2(215.5, 242.2)とほぼ同じ所でした。再生はつかんで箱に入り、到達の誤差はどの区間も許容の中でした(いちばん大きかったのは PICK の2.99°。許容3.0°)。つかんでいる間の爪の電流は829 から782、爪の位置は1619 のままで、電圧は肩も爪も69〜75 でした。見ていても、お手本どおりの動きでした。

recorder.py の Address already in use は、前に起動した recorder がまだ動いていたためで、この回の録画はその recorder で取れています。

途中で止めた lab_start.sh と、recorder の二重起動

(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % cd ~/r2r2r-scripts
./lab_start.sh --model deep1 --grip-value 25 --log Log34 --episode run_0001_20261019_191541
[LOG   ] ターミナルの出力を残します → /Volumes/KIOXIA/r2r2r-data/lab/Log34/lab_start_20261113_194558.txt
[RANGE ] 安全範囲 (学習データ ±10°) は /Volumes/KIOXIA/r2r2r-data/datasets/mecharm_redblock_box_deep_even10_v1/raw_episodes から (--model deep1)
[FRAME ] 写り方の確かめの基準画像は /Volumes/KIOXIA/r2r2r-data/datasets/mecharm_redblock_box_teach_v1_trim2/raw_episodes の最初のエピソードから (位置合わせと同じ trim2. 依頼 137)
[TILT  ] 上カメラの傾きのお手本 (各エピソードの 1 枚目の中央値) は /Volumes/KIOXIA/r2r2r-data/datasets/mecharm_redblock_box_deep_even10_v1/raw_episodes から (安全範囲と同じ. 差だけ画像を回して AI に渡す. 依頼 144)
[GRIP  ] 爪の閉じる値は 25 (--grip-value). 締め直し r はこの値−3 とこの値を交互に送る (依頼 152)
[LAB   ] 2026-11-13 19:45:58  GPU=NVIDIA A40  episode=run_0001_20261019_191541  log=/Volumes/KIOXIA/r2r2r-data/lab/Log34  
[MODEL ] --model deep1: π0.5 base から deep_even10_v1 で新しく学習した 2999 (依頼 133. decay_steps 5000)
         PixelstoMotors/pi05-mecharm-deep-even10-lora-v1 → /workspace/ckpt/deep_v1_2999  設定 pi05_mecharm_deep_even10_lora  assets local/mecharm_redblock_box_deep_even10_v1

=== 1. Pod を作る
[POD   ] 記録の Pod (id bjcya1w5ptkb3i) は API で見ると残っていない. 新しく作ります
         古い記録は /Volumes/KIOXIA/r2r2r-data/lab/Log34/pod/lab_pod_20261113_194559.json に残しました
[POD   ] 作った: id 9zgeyyvteskg4a  GPU=NVIDIA A40  1時間 0.59 ドル  (記録 /Volumes/KIOXIA/r2r2r-data/lab/Log34/pod/lab_pod.json)
    (3 秒)

=== 2. Pod が立ち上がるまで待つ
[POD   ] SSH の IP とポートを API から受け取った (<POD_IP>:<SSH_PORT>)
[POD   ] 入れた: c00b3dbcfbe9
NVIDIA A40, 46068 MiB
    (30 秒)

=== 3a. スクリプトを送る
^C
[STOP  ] 「3a. スクリプトを送る」で止まりました: Ctrl-C で止めました
[STOP  ] Pod は残っています (id 9zgeyyvteskg4a). 消すなら ./lab_stop.sh --log Log34

=== かかった時間  モデル deep1 (PixelstoMotors/pi05-mecharm-deep-even10-lora-v1)
  1. Pod を作る                      3 秒
  2. Pod が立ち上がるまで待つ     30 秒
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % cd ~/r2r2r-scripts && python3 dynamic_tracking_limits/place/place_modules/recorder.py --top --no-side
Traceback (most recent call last):
  File "/Users/shimazueiichi/r2r2r-scripts/dynamic_tracking_limits/place/place_modules/recorder.py", line 742, in <module>
    sys.exit(main())
             ^^^^^^
  File "/Users/shimazueiichi/r2r2r-scripts/dynamic_tracking_limits/place/place_modules/recorder.py", line 540, in main
    sock.bind((UDP_HOST, UDP_PORT))
OSError: [Errno 48] Address already in use

位置2 の measure・ドライラン・再生のターミナル

04_2_measure.txt23,252字・309行・text
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % cd ~/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_20221013_230205.json --power 5A
python3 dynamic_tracking_limits/drag_teaching/record_teach_demo.py run --teach drag_v2_20221013_230205.json --power 5A --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)
別のタブで開く保存

Ctrl-C で止めたあとに残った Pod を消した

lab_start.sh を Ctrl-C で止めたとき、作ったばかりの Pod(9zgeyyvteskg4a)は消えずに残ります。lab_stop.sh --log Log34 で消しました。推論サーバーを起動する前に止めたので serve.log がまだなく、持ち帰りに3回失敗してから、そのまま消しています。借りていたのは4分49秒、約7円でした。1台目の Pod(17分5秒、約27円)と合わせて、この回の GPU は約34円です。

(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts % ./lab_stop.sh --log Log34
[STOP  ] Log34 の Pod: id 9zgeyyvteskg4a  GPU=NVIDIA A40  作った時刻 2026-11-13 19:46:01
scp: /workspace/logs/serve.log: No such file or directory
[LOG   ] (1/3) serve.log の scp に失敗
[LOG   ] 10 秒待ってやり直します
scp: /workspace/logs/serve.log: No such file or directory
[LOG   ] (2/3) serve.log の scp に失敗
[LOG   ] 10 秒待ってやり直します
scp: /workspace/logs/serve.log: No such file or directory
[LOG   ] (3/3) serve.log の scp に失敗
[WARN  ] serve.log を持ち帰れなかった (3 回試した). Pod はこのまま Terminate まで消します
[STOP  ] Terminate を送った (19:50:50)
[STOP  ] Pod (id 9zgeyyvteskg4a) が消えたことを API で確かめた
[COST  ] 借りていた時間 4 分 49 秒 (0.08 時間) × 1時間 0.59 ドル = 約 0.05 ドル (約 7 円. 1ドル=158円)
[TUNNEL] 8000 番のトンネルは残っていません
(base) shimazueiichi@shimadzueiichinoMacBook-Pro r2r2r-scripts %

次に見ること:上カメラの傾きと、持ち上げの速さ

推論の5回とも、上カメラの傾きが -6.5° 前後あり、ソフトで +5.9° 回してから π0.5 に渡していました。手順書の目安の3° を大きく超えています。measure でマットの四隅が大きくずれて見えたのも、これと関係があるかもしれません。次に実機を動かす前に、iPhone の付け方を見直します。

12V・5A でも、ゲームパッドで一気に持ち上げた1回だけ爪の電流が落ちました。π0.5 のお手本を撮り足すときは、持ち上げで爪の電流が落ちないかを、今回足した爪の位置の列と合わせて見ていきます。