UnityシミュレーションフェーズからmechArm 270実機フェーズへ|R2R2Rの転換点
LOG101R2R2R2026/3/17

UnityシミュレーションフェーズからmechArm 270実機フェーズへ|R2R2Rの転換点

数字が並んだ。success=True × 12。これで第一フェーズを閉じる。

このプロジェクトについて

iPhoneで撮影した現実空間をUnityでデジタルツイン化し、ロボットアームの動作をシミュレーションで最適化してから実機に展開するパイプラインを個人で構築している。

ターゲットはシンプルだ。ロボットアームがコーヒーカップを掴み、台座の上に置く。その一連の動作を、iPhoneとUnityだけで設計できることを証明する。

この記録は「一つの答えが出た日」の話だ。

検出ロジックの修正

LOG100で「全12パターン失敗」と見えたsummary.csvの誤検知を修正した。

問題は3つあった。

問題1:GRASP_MISS誤検知 isGrasping フラグではなく endEffectorとカップの物理距離 で判定していた。把持が成立しているのに「距離が遠い」という理由でFailが記録されていた。

修正前:dist = Vector3.Distance(endEffector, cup) > 0.05m → GRASP_MISS
修正後:isGrasping == false → GRASP_MISS

問題2:JOINT_LAG閾値が厳しすぎた 15度設定に対してfastパターンが21〜23度に達していた。動作は完走しているのに失敗扱いになっていた。

修正前:JOINT_LAG_THRESHOLD = 15度
修正後:JOINT_LAG_THRESHOLD = 20度

問題3:fast速度が速すぎた 閾値を20度に緩和してもfastが18〜19度に収まるよう、速度を20%落とした(セグメント時間を×1.25倍に延長)。

修正前:fast base_sec = 1.5秒
修正後:fast base_sec = 1.875秒(20%延長)

3つの修正を順番に入れてbatch02→03→04と確認した。最終結果:

batch04 / success=True × 12

high_fast:     True  j_lag_max=18.06° place_err=0.0001m
high_normal:   True  j_lag_max=12.38° place_err=0.0002m
high_slow:     True  j_lag_max= 8.58° place_err=0.0000m
low_fast:      True  j_lag_max=18.06° place_err=0.0001m
low_normal:    True  j_lag_max=12.38° place_err=0.0002m
low_slow:      True  j_lag_max= 8.58° place_err=0.0000m
side_fast:     True  j_lag_max=19.78° place_err=0.0001m
side_normal:   True  j_lag_max=13.61° place_err=0.0002m
side_slow:     True  j_lag_max= 8.69° place_err=0.0000m
standard_fast: True  j_lag_max=19.37° place_err=0.0001m
standard_normal:True j_lag_max=12.68° place_err=0.0002m
standard_slow: True  j_lag_max= 8.58° place_err=0.0000m

place_err は全パターンで0.0〜0.2mm。実質ゼロだ。

シミュレーションフェーズで確立したこと

このプロジェクトで確立してきたことを整理する。

iPhoneスキャン(LOG1〜LOG30台) 3Dpressoによるターンテーブルスキャンでコーヒーカップの3Dモデルを生成した。スケール合わせ(小鉢直径10.5cm = Unity Scale 0.105)を確立した。

デジタルツイン構築(LOG30台〜LOG70台) mecharm_270_m5のURDFをUnityにインポートし、ArticulationBodyベースの物理シミュレーションを動かした。Stiffness 20,000 / Damping 2,000の物理パラメータを確立した。

CCD IK実装(LOG89〜LOG91) anchorRotation による真の回転軸導出と平面投影SignedAngle計算で6軸制御を実現した。5mm目標到達精度を達成した。

FixedJointグラスピング(LOG92) EndEffectorにRigidbody(IsKinematic=ON)を追加してFixedJoint把持を確立した。4ステートループ(REACH_CUP → GRASP → REACH_PLACE → PLACE)が完成した。

軌道設計とCSV化(LOG99〜LOG100) 5次多項式補間によるスムーズな軌道生成。4アプローチ × 3速度 = 12パターンのCSVを自動生成するパイプラインを構築した。

ログ診断インフラ(LOG100〜LOG101) フレームログ + サマリーの2層ログ構造を確立した。失敗検出4種(GRASP_MISS / GRASP_DRIFT / PLACE_MISS / JOINT_LAG)の計測ロジックを完成させた。

何が証明されたか

iPhoneとUnityだけで、
ロボットアームがカップを掴んで台座に置く動作を
個人が設計できることが証明された。

これがこのプロジェクトのコアメッセージだった。シミュレーション上では成立した。

追加機材は使っていない。エンジニアリングチームもない。秋田の自宅で、iPhoneとMacとUnityだけで到達した。

次のフェーズへ:シミュレーションと実機の差分を埋める

シミュレーションでは cup_x/y/z がUnityの物理エンジンからフレームごとに取れる。実機では取れない。

この差分を埋めることがフェーズ2の課題だ。

フェーズ2a:
  関節完走フラグ + iPhone LiDAR前後スナップ比較
  → 「カップが台座に乗っているか」を数値で確認

フェーズ2b:
  iPhone ARKitリアルタイムストリーミング
  → シミュレーションと同じログ構造で実機データを取得

パイプラインの入り口はiPhoneだった。出口もiPhoneになる。

実装コード(TrajectoryFollower.cs・修正後のGRASP_MISS判定)

// GRASP_MISS判定:isGraspingフラグで判定する
// (物理距離ではなく、把持が成立したかどうかで判定)
if (prevSegment == "to_grasp" && segment != "to_grasp" && !failDetected)
{
    if (!isGrasping)
    {
        failDetected = true;
        failState    = "to_grasp";
        failFrame    = frameIndex;
        failReason   = FAIL_GRASP_MISS;
    }
    // isGrasping == true なら成功。何もしない。
}
# generate_motions.py:fast速度を20%延長
SPEEDS = {
    "slow":   {"base_sec": 5.0,   "fps": 50},
    "normal": {"base_sec": 3.0,   "fps": 50},
    "fast":   {"base_sec": 1.875, "fps": 50},  # 1.5 × 1.25 (20%延長)
}
※ プロジェクト名「R2R2R」は、UC Berkeley・Toyota Research Instituteの研究「Real2Render2Real」(Yu, Fu et al., 2025)の概念に触発されています。現実空間をデジタルツイン化し、仮想空間での試行から得た知見を実世界のモーター駆動へ還元する——その設計と実装過程を毎日記録しています。技術アプローチおよび目的は独自のものです。