承認済みの CAD 部品をロボットアームのシミュレーションに載せる:質量の照合と、持ち運べる MJCF・OpenUSD の書き出し

承認済み CAD 部品だけを MuJoCo のアームに搭載。メッシュ質量は B-Rep と 3% 以内、MJCF と OpenUSD に書き出し。

比較図:タイトル「1 つの部品、3 つの幾何表現」の下に、番号のない塗りつぶした円が 3 つ横に並び、それぞれの下に横線と文字があります。左から順に、B-Rep ソリッド、質量の基準、参照ブラケット 48.37 g;厳密なメッシュ体積、質量と慣性、B-Rep との差 3 % 以内;凸包、衝突形状のみ、既定の凸包慣性では 31.85 g が 110 g に。列のあいだに矢印はありません。下端に出典の注記があります。
pai-design-workbench のロボットシミュレーションにおける 1 つの部品の 3 つの幾何表現と、それぞれの用途。3 列は並列で、並び順は手順や優劣を表しません。commit 70330e2 の docs/PHYSICS.md と native/robot_sim.py に基づいて作図。

あるブラケットが CAD レビューで形状チェックと有限要素チェックに合格しました。次に問うべきは、ロボットアームの先端に取り付けたとき、ワークセルがサイクルタイム内に衝突なくピック・アンド・プレースを完了できるかどうかです。pai-design-workbench の物理レーンはこれを MuJoCo で確かめますが、その前に、取り付ける部品が承認されたその部品であること、質量が正しく計算されていることを確認し、そのうえでシミュレーションのシーンを、ほかの環境でも開き直せる MJCF と OpenUSD に書き出します。本記事では、commit 70330e2 に固定した docs/PHYSICS.md、native/robot_sim.py、保存されたデモ記録 docs/evidence/physics-demo.json に基づき、CAD からロボットシミュレーションへの各段階が何を確認し、何を確認できないのかを説明します。

本文の数字はすべてプロジェクト自身のドキュメント、コード、記録によるものです([O]、プロジェクトの自己報告)。本サイトはこれらのテストを実行しておらず、デモも再現していません。同じリポジトリの空力レーンは 固定版の OpenFOAM ケースを AWS Batch で実行する:ハッシュ照合、2 つのメッシュ、ローカルとの抗力係数比較 で扱いました。本記事はブラケットの最適化の過程には触れず、部品がワークセルに入ってから先だけを扱います。

ワークセルシミュレーションが確かめること

robot_sim.py はユーザーが用意した XML を受け付けません。範囲付きの 8 つのパラメーターだけを受け取り、MJCF モデルを自分で生成します。範囲外の値があれば終了します。

パラメーター許容範囲
pickDistance、placeDistance0.25–1.1
pickHeight、placeHeight0.6–1.2
pedestalHeight0.3–1.0
guardClearance0.1–1.5
speedFraction0.1–1.0
jitter0.0–0.08

上記のパラメーター範囲はソースどおりに示しており、範囲の定義には単位の注記がありません。ドキュメントではガードの間隔をメートルで示し、speedFraction は定格関節速度に対する割合です。

シーンには、台座に載った汎用の 6 軸アーム(リンク長は UR5e の公開データシートの寸法による UR5e クラス)、コンベヤーのピックステーション、治具のプレースステーション、4 枚のガードパネルがあります。ドキュメントに書かれた標準の実行では 10 個の固定シードを使い、シードごとにピック姿勢へシードから生成したオフセットを加えます。各シードでは 3 つのことを順に行います。MuJoCo のヤコビアン上で減衰最小二乗法による逆運動学を関節限界内で解くこと、定格関節速度の指定割合で関節空間の 5 次多項式軌道を生成し、アプローチ、ピック、持ち上げ、搬送、プレース、退避を通ること、位置アクチュエーターで駆動して 500 Hz の完全な剛体動力学で計算し、アームのリンクと静的なシーンとの接触を検出すること(グリッパーと把持するワークとの意図した接触は除外)です。4 つのチェックは次のとおりです。

  • reach:すべてのシードで、ピック位置とプレース位置の TCP 誤差が 2 mm 以下。ドキュメントは、このチェックをピック位置とプレース位置の誤差として説明しています。コードでは関節限界内で、各目標について減衰最小二乗法を最大 400 回反復します。そして、取放し位置の 0.12 m 上にあるアプローチと持ち上げの位置を含む、6 つの逆運動学目標すべての最大 TCP 誤差を取り、2 mm を超えると失敗とします。失敗の原因は、目標がワークスペースの外にあること(フィジカルAIラボ 1.1:座標系と運動学――2 リンクのアームがコップに届く計算を手で追う の「解がないこともある」に当たる場合)のこともあれば、解は存在するのに反復が収束しなかったことのこともあります。このチェックは両者を区別しません。
  • collision-free:動作中、アームのリンクがガード、コンベヤーのフレーム、治具に接触しない。
  • cycle-time:最も遅いシードのサイクル(停止までの時間を含む)が maxCycleSeconds 以下。
  • success-rate:到達、衝突なし、サイクル内のすべてを満たすシードの割合が minSuccessRate 以上。

参照セルと候補セルは同じシードで実行され、画面ではシードごとに結果を対にして並べ、参照では成功したのに候補では失敗したシードに印を付けます。Robot Reel のペア比較と同じ考え方です。PHYSICS.md には、サイクル目標を 5 秒に引き上げたあとの npm run test:robot の結果が記録されています。

セル結果
参照、速度 50 %5.90 s、新しい目標を満たさない
速度 75 %、ガードを 0.12 m まで近づける4.60 s、ただしすべてのシードで肘がガードに当たる:却下
同じ速度、ガード 0.30 m4.60 s、10/10 シードが成功:承認(参照より 22 % 速い)

保存されたデモ記録 physics-demo.json は、プロジェクトのホスト環境で録画された別の実行で、上の表の npm run test:robot の結果ではありません。その値を丸めると表の値と一致します。却下されたセルのサイクルは 4.598 s で、10 シードのうち衝突のなかったものは 0(0/10)、参照は 5.897 s でした。修正で変えたのは guardClearance 0.12 → 0.3 の 1 項目だけで、requirementsRelaxed は false、つまり要件は緩めていません。(5.897 − 4.598) / 5.897 ≈ 0.22 で、記録の 22 % と一致します。記録には修正を提案したエンジンとモデルの名前がありますが、modelEvidence フィールドは acp_advertised です。これはエンジン自身が申告した識別情報であり、独立に確認されたモデルの出所ではありません。

部品をグリッパーに取り付ける:承認されたものだけ

ワークセルのリクエストには tool: { cadReviewId, payloadKg } を付けられます。PHYSICS.md によれば、サーバーは同じプロジェクトの完了済みで結論が承認の CAD レビューだけを受け付け、そのレビューが記録したダイジェストで STL を照合します。承認されていない部品は TOOL_NOT_ACCEPTED で拒否されます。robot_sim.py 自身も STL の SHA-256 を計算し直し、入力仕様のダイジェスト(コードのエラーメッセージでは CAD レビューの記録)と違えば終了します。また、ペイロード 0–3 kg、モーター軸位置 5–120 mm、B-Rep 質量 1–2000 g の範囲も確認します。

これらを通ると、厳密な STL がメッシュボディとしてグリッパーに取り付けられ、宣言したペイロードがモーター軸の位置に加えられます(既定は 0.28 kg の NEMA 17 モーターで、コード上は指定質量の直方体)。参照セルと候補セルには同じツールを付けるので、比較されるのはセルであってツールではありません。部品の衝突形状は collision-free に含まれます。コードは cad-tool をアーム側に分類するので、部品がガードに触れても衝突と判定されます。

1 つの部品、3 つの幾何表現

この経路で最も参考になるのがここです。シミュレーションの中で 1 つの部品は 3 つの幾何表現を持ち、それぞれ用途が異なるので、混同してはいけません。

表現用途記録された数字
B-Rep ソリッド(CAD レビュー)質量の基準参照ブラケット 48.37 g
厳密なメッシュ体積(inertia="exact"、2.70 g/cm³、非凸)MuJoCo での質量と慣性参照ブラケット 48.37 g。B-Rep との差が 3 % を超えると失敗
凸包衝突形状のみ既定の凸包慣性では、31.85 g の部品が 110 g と計算されたことがある

ドキュメントによれば、3 % チェックがあるのは最後の行のためです。110 g は 31.85 g の約 3.5 倍です。ドキュメントは、この差を既定の凸包慣性によるものと説明し、3 % チェックで検出すべき例として挙げています。ただし、質量が約 3.5 倍になった詳しい理由までは示していません。ここでは、計算された質量を読み戻して閾値と照合することを重視します。コードでは、cad-tool ボディの総質量からペイロードを引いた値をメッシュ質量とし、入力仕様の B-Rep 質量と比べます。3 % を超えると「tool mass mismatch」で終了します。

書き出し:MJCF と OpenUSD がそれぞれ確認すること

MJCF。 scene.xml は同じディレクトリにある tool.stl を参照し、ローカルパスを含まないので、ディレクトリごとほかの場所へコピーして読み込み直せます。test:robot はこれを確認します。

OpenUSD。 scene.usda は Z 軸が上、単位はメートルです。MuJoCo の各ボディは MassAPI(質量、重心、対角慣性、主軸)を持つ剛体になり、メッシュのコライダーは凸包です。限界付きの回転関節が 6 つ、溶接されたボディ(グリッパー上の部品など)には固定関節があり、さらに articulation root があります。ステージを開き直したうえで、OpenUSD 26.8 に登録されたすべての UsdValidation バリデーターを実行します。UsdPhysics の剛体、関節、articulation、コライダーのチェックも含み、エラーや警告が 1 つでもあれば失敗します。固定以外の関節が 6 つでない場合も失敗です。

検証に通っても、同じロボットだとは限りません。 オプションの Newton 照合(Newton 1.6、専用の venv、CPU Warp、GPU 不要)は、scene.usda を Newton に取り込み、scene.xml を MuJoCo に読み込みます。articulation が 1 つで回転関節が 6 つ、孤立した関節がなく、ボディの質量が同じであることを求め、書き出し姿勢と関節限界内の 32 個のシード付き構成で順運動学を比較します。基準は各ボディの位置差 0.1 mm 以内、姿勢差 0.01° 以内です。ドキュメントによれば、最初の実行で、すべての UsdValidation バリデーターが見逃していた書き出しのバグが 2 つ見つかりました。

  1. articulation root が base に置かれていましたが、base はフラットに並んだボディの祖先ではないため、Newton はすべての関節を孤立関節として拒否しました。現在 root は /Workcell にあります。
  2. 関節座標系をピック姿勢から取っていたため、USD での関節角 0 と限界の意味が MuJoCo と食い違っていました。現在はモデル定数(関節角 0 のときの親ボディからの相対オフセット)から取っています。

修正後は 33 構成で、最大位置誤差 0.45 µm、姿勢誤差 3.1·10⁻⁵ °、質量差 0.5 mg 以内、所要時間 4.8 s でした。この結果は newton.json として別に記録されます。書き出しの適合性の確認であり、レビューの結論は変えません。対象は運動学と質量だけで、2 つのエンジンの動力学が一致するかどうかについては何も示しません。

ローカルで再現する

PHYSICS.md に従い、commit 70330e2 のリポジトリのルートで実行します。

npm run setup:physics                    # Gmsh、Optuna、scikit-learn、MuJoCo はハッシュ固定でインストール。CalculiX は署名付きの Ubuntu アーカイブから
npm run setup:physics -- --with-newton   # オプション:Newton 1.6、専用の venv
npm run test:robot

ドキュメントによれば、setup:physics はハッシュでロックされた固定版(MuJoCo 3.14.0 など)をインストールし、インストールのレシート .state/tools/physics-install-receipt.json に各 .deb のダイジェストとロックファイルのハッシュを記録します。test:robot は参照ブラケット(B-Rep 48.37 g、MuJoCo メッシュ 48.37 g)を取り付け、MJCF の可搬性、USD に物理関節と articulation root があること、承認されていない部品が拒否されることを確認するとされています。提供された資料には、リポジトリのクローンや npm 依存関係のインストール手順は書かれていません。ツールチェーンの表には OpenUSD 自体のインストール方法も載っておらず、test:robot に Newton 照合が含まれるかどうかもドキュメントには書かれていません。

実行ごとに robot.json(シードごとの結果、4 つのチェック、ツールの質量比較)、scene.xml、scene.usda、robot.glb が書き出されます。robot.json には常に "scope": "rigid-body-simulation" と "physicalValidation": false が入ります。

デモ記録とポスター

本記事のカバーはプロジェクトの物理デモのポスターです。デモ記録によれば、画面録画の元の長さは 659 秒で、カットや並べ替えはなく、画面が静止した待ち時間は 2.5 秒以降 6 倍速で再生されています。チャプターは要件、MuJoCo、AI によるセル修正、セルのフィードバック、FEA、AI 最適化、リリースの順です。記録上のフィードバック 2 件(シーンの collision-free と部品の max-deflection)はいずれもクローズされ、部品の正式レビューの結論は承認(46.87 g、9/9 チェック)、リリース R1 の受け入れは 5/5 です。デモのワークセルに CAD 部品が取り付けられていたかどうかは記録に示されておらず、本記事も推測しません。承認された 46.87 g の部品は、MuJoCo と AI によるセル修正の後に続く FEA と AI 最適化のチャプターで得られたものです。これはプロジェクトのホスト環境で録画された 1 回のデモであり、独立した実験でも実機でのテストでもありません。

制約と注意点

  • 対象は汎用アームと汎用コントローラーの剛体シミュレーションです。把持するワークは、グリッパーが閉じたときに運動学的に取り付けられ、把持の物理モデルはありません。一方、CAD ブラケットは、実行中を通してグリッパーに固定されたメッシュ剛体です。メーカーのコントローラーでも、安全評価でも、把持の物理モデルでもありません。リンク長は UR5e クラスで、特定の製品の性能を表すものではありません。
  • 部品の質量は公称密度 2.70 g/cm³ で計算しています。FEA 側は線形静解析、微小変形、公称材料で、接触、ボルト予圧、疲労、熱の影響、公差、試験データは含みません。結果はシミュレーションによる証拠であり、認証ではありません。
  • 凸包近似の一般的な幾何学的制約(当サイトの説明)として、凸包はくぼみを包み込むため、実際の形状が接触しない場合にも衝突と判定する可能性があります。保存されたプロジェクトの記録が、特定の衝突の誤検出を検証したという意味ではありません。
  • Newton 照合が示すのは、書き出された運動学と質量が MuJoCo と一致することだけです。Isaac Lab や Newton で動力学が同じように振る舞うことは示しません。
  • 22 % や 0.45 µm などの数字は、プロジェクト自身の環境での 1 回の実行記録です。本サイトは再実行していません。

リンク