UnityでmechArmが2体独立動作した|マルチロボットHRI設計の検証
LOG108R2R2R2026/3/22

UnityでmechArmが2体独立動作した|マルチロボットHRI設計の検証

シーンに2体のロボットアームが並んでいる。左が動き始める。0.1秒遅れて、右も動く。でも右は、左とは逆方向を向いている。

2体は同じコードで動いている。ただし、読んでいるCSVが違う。

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

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

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

シミュレーションフェーズは LOG101 で完了した。この記録は、そのシミュレーション環境を「並列実験基盤」に拡張した話だ。

なぜ2体にするのか

シミュレーションが完成したとき、1体のロボットが12パターン(4アプローチ × 3速度)を順番に実行する構成だった。

ただそれは「直列」だ。1パターン終わったら次のパターン、という順番実行。見ていると何かもったいない感じがある。CPUもGPUも余裕がある。物理エンジンも1体分しか計算していない。

2体を並べれば、比較がリアルタイムになる。「標準アプローチとハイアプローチ、同じ速度で同時に動かしたらどう見える?」という問いを、時間をかけずに答えられる。

将来的には、実機展開で「別々のパラメータを同時にテストする」という用途も見えている。

コードを変えずに2体目を動かす

2体目のロボットをどう動かすか。最初の選択肢は「マルチロボット対応のコードを書く」だった。

でも止まった。TrajectoryFollower.cs は #101 で12/12 success=Trueを達成した実績コードだ。これを改変するリスクを取る必要があるか?

答えはノーだった。

Unityのコンポーネント設計の本質は「同じスクリプトを別のGameObjectにアタッチすれば、独立したインスタンスになる」という点にある。マルチロボット対応のコードなど書かなくていい。TrajectoryFollower.cs をそのまま2体目にアタッチして、Inspectorで別のカップと別のCSVフォルダを指定すればいい。

コードの変更はゼロ。 アーキテクチャの問題をアーキテクチャで解決した。

唯一修正が必要だったのは、カップの初期位置がハードコードされていた点だ。

// 修正前:初期位置がハードコード
static readonly Vector3 CUP_INIT_POS = new Vector3(-0.2f, 0f, 0.22f);

// 修正後:Start()でインスタンスごとに記録
private Vector3 cupInitPos;
void Start() {
    if (cupObject != null)
        cupInitPos = cupObject.transform.position;
}

この変更で、各アームのインスタンスが「自分のカップの初期位置」を記憶するようになった。2体目のカップがリセット時に1体目の位置に戻ってしまう問題が解決した。

逆方向アプローチCSVの生成

2体が同じCSVを読んでも「並列実行」にはなるが「比較実験」にはならない。arm1には別の動作をさせる必要がある。

選んだのは「アプローチ方向を逆にする」という方針だった。arm0がカップの左から掴んで右に置くなら、arm1はカップの右から掴んで左に置く。シーンを見れば直感的に「2体が別々のことをしている」とわかる。

実装は generate_motions.py を複製して generate_motions_arm1.py を作り、j0(ベース回転)を反転させた。

# arm0の確定パラメータ
GRASP      = [38.51, 79.01, -34.54, 0.00, -48.13, 0.00]
LIFT       = [40, 50, -20, 0, -42, 0]
PLACE_HIGH = [-55, 50, -25, 0, -38, 0]

# arm1用:j0を反転
GRASP      = [-38.51, 79.01, -34.54, 0.00, -48.13, 0.00]
LIFT       = [-40, 50, -20, 0, -42, 0]
PLACE_HIGH = [55, 50, -25, 0, -38, 0]

許容範囲(J_MIN/J_MAX)もarm1の動作方向に合わせて調整し、12パターン全フレームでWARNINGなし。

結果

arm0(既存):12/12 success=True(#101からの実績)

arm1(新規):12/12 success=True

指標

arm0

arm1

success率

12/12

12/12

place_err

0.0〜0.2mm

0.0〜0.02mm

j_lag_max

8.6〜19.8°

8.6〜19.8°

2体同時、12パターン、両方success。シーンに2体のアームが並んで、それぞれ逆方向に動いている。

何が変わったか

単体シミュレーションから並列実験基盤への拡張、という言い方もできる。

でも本質はもう少し違うところにある。

「動作パターンの生成」と「動作の実行環境」が分離された。arm0はCSVフォルダAを読み、arm1はCSVフォルダBを読む。CSVを差し替えるだけで、どんなパターンの比較実験でもセットアップできる。

将来的には:

  • 速度の違いを2体で同時に見る

  • アプローチ方向の違いを並べて評価する

  • 実機展開時に「前のパラメータと新しいパラメータ」を同時に試す

シミュレーション環境が「1回ずつ試す場所」から「複数を同時に比較する場所」に変わった。

※ プロジェクト名「R2R2R」は、UC Berkeley・Toyota Research Instituteの研究「Real2Render2Real」(Yu, Fu et al., 2025)の概念に触発されています。現実空間をデジタルツイン化し、仮想空間での試行から得た知見を実世界のモーター駆動へ還元する——その設計と実装過程を毎日記録しています。技術アプローチおよび目的は独自のものです。