mechArm 270 Pi · データアーキテクチャ リファレンス

mechArm に使っているデータの全体図

小型ロボットアーム mechArm 270 Pi を「iPhone と Unity だけで物を掴ませる」公開プロジェクト Pixels to Motors で、実機がどんなデータを読み書きしているかの全体図。入力(採用した姿勢)→ アーム → 出力(試行の記録)という流れに、最近足した 補正記憶(実機で測ったズレを位置ごとに覚えて、次の狙いを自動で直す仕組み)が加わっている。「イメージ図」で関係を絵で掴み、「全体解説」で実際のファイルの場所と根拠を確認する。

読み方・用語:DAYxxx(下のファイル名などに出る)=毎日公開している開発ログの通し番号(例:DAY235=開発235日目)。live=入力データ、twin=座標と関節角度を対応づける変換テーブル、real=実行結果の記録。pose_id=同じ姿勢を3系統(live/twin/real)で突き合わせる共通ID。approach=ブロックの手前上空へ行く中間動作、descend=そこから降りて掴む動作。EMA=指数移動平均(新しい測定を少しずつ混ぜて更新していく平均)。KIOXIA=測定データを置いている外付け SSD。件数・行数などデータ増加で変わる数値は載せない。パスは実機とコードで確認済み。

①三系統アーキテクチャ ── live / twin / real

run_pick_place アーム本体・処理 live 入力 j0_sweep_adopted/*.json twin 変換テーブル fk_scan_motion_based_v2.csv real 出力 pick_place_ledger_v3.csv 読む descendで読む 書く pose_id 3系統を突合する join key 補正記憶(二次・学習層) block − Δ / EMA KIOXIA · 詳細は ②+ / ③ lookup前に読む EMA更新

live=採用JSON(入力)、twin=descend 時に読む FK テーブル、real=KIOXIA の試行台帳(出力)。中央の run_pick_place が3つをつなぐ処理。pose_id(赤の破線)は3系統を突合する join key。補正記憶は二次の学習層で、詳細は ②+ と③。絶対パスは③。

②実行時データフロー ── 1試行のフローチャート

pose_id を返す no yes 次の stage / phase へ live j0_sweep_adopted/ *.json 読む real pick_place_ledger_v3.csv 書く run_pick_place 起動 lookup(approach=j0 / descend=fk) j0_lookup.py / fk_lookup.py 前に補正記憶を読む(block−Δ) 送角 → アーム動作 run_pick_place.py post_actual 取得(実測角) run_pick_place.py 次の stage / phase ? _append_ledger pose_id・実測角を記録 run_pick_place.py 完了 / 次試行へ twin(FKテーブル) fk_scan_motion_based_v2.csv descend(pick)で fk_lookup が読む approach は live(j0_lookup)
開始 / 終了 処理 分岐 データ入出力 赤=pose_id

使用ファイルを各ノードに併記。データ:live=j0_sweep_adopted/*.json、twin=fk_scan_motion_based_v2.csv(descend で fk_lookup が読む)、real=pick_place_ledger_v3.csv。コード:起動〜記録=run_pick_place.py、採用JSON選択=j0_lookup.py(ともに .../place/place_modules/)。出力先は KIOXIA runs/(台帳+run JSON)。未マウント時は冒頭 ABORT。絶対パスは全体解説③。 descend は fk_lookup+補正記憶。位置ごとの補正ループは下の ②+。

②+実装済みの追従ループ ── 補正記憶 × fk_lookup 実装済み

次試行(記憶を読む) EMA更新 ① ブロック検出 (x,z) 上カメラ 補正記憶を読む 狙い = block − Δ _apply_correction lookup → 6関節 descend=fk_lookup(j1≤88°) approach=j0_lookup 送角 → アーム動作 send_angles 実機 tip のズレを測る Δ(x,z) = 爪先 − ブロック 補正記憶を更新 記憶Δ ← EMA(0.5) 20mm 格子セルごと grip / 次試行へ 補正記憶 位置 → Δ(x,z) 20mm格子 · KIOXIA 実装済み

設計どまりではなく、実機に実装して動いている。 検出位置をいったん 補正記憶(位置→Δ(x,z)・KIOXIA)で block − Δ(検出位置から記憶したズレを引く)に補正してから lookup へ渡す。descend(降りて掴む動き)は fk_lookup が変換テーブルから 6 関節すべてを引く(j1 が一定角を超えるとアームが命令を黙って無視するため、j1≤88° の範囲に絞る)。approach(手前上空への中間動作)は従来どおり。実測した爪先のズレ Δ を EMA(少しずつ混ぜる平均)で記憶へ書き戻し、次試行で読む。X 方向だけ効いていた補正が、6関節で引くようにしたことで Z(奥行き)方向にも効くようになった(爪先の奥行きズレが 25mm 級から 10mm 級へ)。残るのは保持(grip/hold)── 位置は合うが j4 抜け・握り緩みで落とすことがある(④参照)。

③実体パス一覧 ── 絶対パス・省略なし(実機調査+コード根拠で確定)

系統絶対パス読む書く変更メモ
live /Users/shimazueiichi/r2r2r-scripts/dynamic_tracking_limits/logs/j0_sweep/j0_sweep_adopted/ j0_lookup
(ADOPTED_DIR.glob)
採用キュレーション
(scanから選定配置)
追記 採用JSON 5本。pose_id 保有。place_noblock は存在するが lookup 不可(下記)
live /Users/shimazueiichi/r2r2r-scripts/dynamic_tracking_limits/logs/j0_sweep/ (採用元プール) j0_sweep_scan.py
(DEFAULT_OUTPUT_ROOT)
追記 raw sweep j0_sweep_{phase}_{NN}.json+frames。classified/ に分類。adopted/ はここから選定
twin /Users/shimazueiichi/r2r2r-scripts/fk_scan_motion_based_v2.csv fk_lookup(descend)
Unity / planning
Unity FKScanner
(生成のみ)
変更禁止 現行。descend(pick)で fk_lookup が実行時に読む(j1≤88°)。approach は j0_lookup。点追加は Unity 再スキャンのみ
twin /Users/shimazueiichi/Robotics_UX/Robotics_UX_New/Assets/Data/fk_scan_motion_based_v2.csv Unity Unity FKScanner 変更禁止 Mac 側と md5 一致必須(二重配置)
旧twin /Users/shimazueiichi/r2r2r-scripts/fk_scan_motion_based.csv
(+ Unity Assets/Data に同名)
(戻り先・温存) — 変更禁止 v2 不調時のロールバック先
real /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv (分析・突合) run_pick_place
._append_ledger
追記のみ 台帳。LEDGER_CSV_PATH(L147)。try/finally 到達後の完走/中断は1行追記(KIOXIA 未マウントや daemon 失敗の早期 abort は追記されない)。pose_id 記録。KIOXIA専用
real /Volumes/KIOXIA/r2r2r-data/runs/run_pick_place/{run_stem}/ (事後参照) run_pick_place
(LOG_ROOT, L142)
追記 1試行=1フォルダ。run JSON+frames
補正記憶 /Volumes/KIOXIA/r2r2r-data/diag/correction_memory.json _apply_correction
(lookup 前)
EMA 更新
(実測 Δ 後)
読み書き 位置→Δ(x,z)。20mm格子・EMA係数0.5。実装済み(実機で稼働)。_ensure_ssd_mounted() ガードで未マウント時は適用・保存をスキップ(_corr_load 自体にガードはない)
code /Users/shimazueiichi/r2r2r-scripts/dynamic_tracking_limits/place/place_modules/ — — 外部レビュー済✅ run_pick_place.py / j0_lookup.py / fk_lookup.py / j0_sweep_scan.py。descend の fk_lookup は J1_SAFE_MAX=88.0・FK_LOOKUP_PHASES=("pick",)

採用JSON(5本・実ファイル名) ── adopted/ 直下:

├ approach_pick_NA_20pt_adopted_DAY235_01.json
├ pick_NA_20pt_adopted_DAY235_01.json
├ approach_place_NA_20pt_adopted_DAY235_01.json
├ place_withblock_NA_20pt_adopted_DAY235_01.json
└ place_noblock_20pt_adopted_DAY232_01.json ← 存在するが lookup 対象外

コード根拠(誰がどこを読み書きするか=コードが正)

twin の構造詳細:列は ee_x,ee_y,ee_z,j0..j5(ee=Unity 座標 m・関節=度)。ee は Unity 内のグリッパー先端形状(Brep)の位置で、一般の運動学計算(ikpy ライブラリ等)では再現できない。点の追加は Unity の FKScanner を再実行するしかない。

解決:real は「二重化」していなかった

以前「Mac working v3 と KIOXIA v2 が二重化」と疑っていた件は誤り。~/r2r2r-scripts/ 配下に ledger は 0 件(find 確認)。台帳の実体は KIOXIA の /Volumes/KIOXIA/r2r2r-data/runs/pick_place_ledger_v3.csv 単一で、コード(run_pick_place L147)もここを直書き。KIOXIA 専用・ローカル fallback なし。real は単一ソース・v3で確定。

④残務 ── 確定後に残るもの

論点状態内容
MASTER の台帳パス記述済MASTER を v3 に更新済(保存先テーブル・フォルダ構成・保管ルール)
place_noblock の扱い明確化済ファイルは adopted/ に存在するが j0_lookup が設計上拒否(ValueError)。place = withblock
実機のスクリプト構成確定.../place/place_modules/(run_pick_place / j0_lookup / fk_lookup / j0_sweep_scan)
補正記憶レイヤー実装済実機で稼働中。位置→Δ(x,z)・EMA0.5・20mm格子。lookup前に読み実測後に更新。KIOXIA・SSDガードあり
descend の Z 補正解決ベース回転だけ動かす方式(j0_lookup・1関節)では Z(奥行き)が動かなかった。descend を fk_lookup(6関節すべてを引く)にして解決。爪先の奥行きズレが 25mm 級→10mm 級へ
保持(grip / hold)未解決位置は合うが、j4 抜け・爪の握り緩みで掴んだブロックを落とすことがある。姿勢選択とは別レイヤー。次の山
補正記憶の実体ファイル確定/Volumes/KIOXIA/r2r2r-data/diag/correction_memory.json(codex がコードで確認)。③に反映済
補正記憶の保存先カテゴリ保留実体は diag/ 配下にある。MASTER の保存先テーブルでは diag/ は「単軸診断など測定スクリプト出力」。補正記憶は実行時の学習状態で種類が異なるため、種類→場所の整合は要検討(MASTER は場所追加時にテーブル更新が先)
pose_id 付与位置の不揃い保留遡及分=末尾/自動付与=phase直後(今回未調査)。機能上は問題なし