フィジカルAIラボ 2.1:MuJoCo でつかむ場面をつくる――XML に書かれていない質量・単位・ステップ幅・衝突ルールを計算で確かめる

MuJoCo でつかむ場面をつくる――XML に書かれていない質量・単位・ステップ幅・衝突ルールを計算で確かめる。日本語動画、解説、確認問題、出典をこのページにまとめました(2026-10-13 更新)。

この回の動画

ナレーションは AI 合成音声です。 動画の章・文字起こし・出典

文字起こし

文字起こし

知行の問い

数十ぎょうの文字を書くだけで、コンピューターの中のコップが、勝手に落ちるの?今回は、ムジョコを使って、一枚のエックスエムエルからつかむ場面をつくります。そして、一歩ずつ動かしていきます。

XML で世界を記述する

ムジョコとは、多関節の接触ダイナミクスという意味です。物理エンジンで、エックスエムエルを読んで、世界を組み立てます。いちばん外側はワールドボディ、世界の根っこです。その中に物体のボディを置き、ボディに形のジオムを付けます。どのボディにも、位置と向きがあります。机は真ん中に、コップは机の少し上に置きます。この世界にあるのは三つだけ。机が一つ、コップが一つ、二本指のグリッパーが一つです。形にはいくつか種類があります。平面、箱、球、カプセル、円柱、そしてメッシュ。机は箱、コップは円柱にします。メッシュやテクスチャのようなものは、アセットと呼びます。モデルから参照して、たとえば机に木目を貼ります。コップは、自由関節で世界につなぎます。これで平行移動も回転もできる、六つの自由度を持ち、だから下に落ちます。ムジョコの関節は全部で四種類。ボール、スライド、ヒンジ、そしてこの自由関節です。質量は書かなくても大丈夫。体積と標準の密度から計算します。標準の密度は水の密度で、立方メートルあたり千キログラムです。それから重力。標準の重力は、真下向きです。毎秒毎秒、九点八一メートル。ほぼ地表の重力です。ついでに言うと、ムジョコは単位を決めていません。自分で一式決めて、前後で矛盾しなければ大丈夫。ここではメートル、キログラム、秒を使います。ジオムには、色や材質も設定できます。でもそれは見た目が変わるだけ。本当に計算に効くのは、形と接触です。サイトやセンサーも置けます。たとえば触覚センサーは、接触の法線方向の力を読み取ります。力センサーとトルクセンサーは、サイトにかかる力とトルクを読み取ります。接触はやわらかいんです。ソルレフはじていすうと減衰比を、ソルインプは拘束インピーダンスを調整します。くり返し使う属性は、デフォルトクラスにまとめられます。ウェブのシーエスエスのように継承されるので、一つずつ書かずにすみます。世界をつくるには、まず何があって、どうつながって、どれだけ重いかを言えばいいんだ。

一歩ずつ物理を進める

できた世界は、まず二つに分けます。変わらない部分はエムジェイ・モデル、変わっていく状態はエムジェイ・データです。状態は、二つのベクトルだけ。位置のキューポスと、速度のキューベルです。物理とは、この二つを更新し続けることです。ステップを進める前に、初期状態を忘れずに。コップをどこに置き、どんな速さにするか、すべてここから始まります。力だけ計算して、時間は進めたくないときは、エムジェイ・フォワードを呼びます。状態は更新されますが、時間は止まったままです。本当に進めるには、関数一つ。エムジェイ・ステップです。一回呼ぶたびに、時間が一ステップ分進みます。標準のステップ幅は二ミリ秒。ドキュメントによると、これは速さと精度のトレードオフです。小さいほど正確で安定しますが、遅くなります。標準では、半陰的オイラー法を使います。なめらかな系には、よじのルンゲ・クッタ法が向いています。このNotebookでは、インプリシットファストを使います。やり直したいときは、エムジェイ・リセットデータを一回呼べば、状態は最初に戻ります。あるいは、キーフレームへ直接飛ぶこともできます。このくらいの小さなモデルなら、ムジョコはたいてい現実の時間より速く動きます。でも接触が増えると、遅くなります。では、コップを机の上から落としてみます。手を離すと、下に落ちて、机にぶつかり、一度跳ねて、止まります。コップと机が触れると、接触が生まれます。接触の力は、とつ最適化という問題にして求めます。どの接触点も、読み出せます。接触の位置、法線の向き、そして力。エヌコンは、いまの接触の数です。落とし穴が一つ。標準では、親子の物体どうしは衝突を判定しません。机は静止していますが、コップはちゃんとぶつかります。コップが止まらず、数字が暴れたら、たいていステップ幅が大きすぎて、物理が発散しています。ステップ幅を小さくすれば、たいてい安定します。やってみましょう。Notebook で、ステップを何度も進めます。コップの高さを、一本の曲線にします。曲線を見れば一目瞭然です。まず落ちて、底に当たり、一度跳ねて、最後は机の高さで止まります。物理エンジンって、法則を一歩ずつ小さく計算してるだけなんだ!

つかんでみる

コップだけでは足りません。動かせるグリッパーが必要です。そこに指を二本付け、土台には縦のスライドレールを足します。二本の指は、じつは小さな箱が二つ。スライド関節に付いていて、開いたり、閉じたりします。指それぞれに、位置アクチュエーターを一つずつ。目標の位置を与えると、目標との差に応じた力で、そこへ近づきます。制御信号は、データのシーティーアールエルに書き込みます。さらにコントロールレンジを付ければ、指が開きすぎません。つかむ前に、グリッパーをコップの両側へ動かし、中心に合わせます。位置がずれていると、閉じてもからぶりします。つかむスクリプトは二段階です。一つ目、指を閉じて、コップを押さえる。二つ目、土台を持ち上げる。指はなぜ、つかんでいられるのか。接触点の摩擦力のおかげです。強く押さえるほど、重い物を持ち上げられます。指先が平らだと、すべりやすいんです。摩擦を大きくするか、接触の次元を上げて、回転まで止めるようにします。閉じたら、土台を上げます。しっかりつかめていれば、コップもいっしょに机を離れます。いちばんシンプルなつかみ方です。指に触覚センサーを付ければ、どれだけ強くつかんでいるか読み取れます。数字が小さすぎたら、すべりかけています。うまくいったかは、二本の曲線で見ます。一本は指の位置、もう一本はコップの高さ。コップが上がれば、つかめたということです。この場面を、画像にすることもできます。ムジョコはオフスクリーン描画に対応していて、カラー画像と深度画像を出せます。動かなければ、曲線だけ残せば大丈夫です。深度画像は何に使うのか。のちほど視覚の方策を学習するとき、ちょうどいい入力になります。見て、コップが本当に持ち上がった!でもこのつかみ方は、私たちが手で書いたスクリプトです。コップの位置が変われば、調整し直し。本当にほしいのは、モデルが自分で学ぶことです。ふりかえりです。ポイントは三つ。一つ、ムジョコは一枚のエックスエムエルで世界を記述する。二つ、エムジェイ・ステップが一歩ずつ物理を進める。三つ、アクチュエーターとスクリプトを足せば、つかんでみられる。動く世界をゼロからつくるのって、こんなに早いんだ!場面はできた。じゃあロボットは、どうやってデータから、自分で動くことを学ぶの?また次回!

根拠と出典

1000 · が標準の密度。質量を書かないとき、MuJoCo は形の体積と密度1000(水の密度、MKS)から質量を求める [O] · MuJoCo ドキュメント · Overview(v3.14.0)

9.81 · m/s² が MuJoCo の標準の重力(真下向き、約9.81)。地表の重力(MKS) [O] · MuJoCo ドキュメント · Overview(v3.14.0)

2ミリ秒 · が MuJoCo の標準ステップ幅(0.002秒)。どの物理シミュレーションにもある速さと精度のトレードオフで、いちばん重要なパラメータ [O] · MuJoCo ドキュメント · XML Reference(v3.14.0)

練習とセルフチェック

小テストは公開で、回答するとすぐ解説が出ます。読み物の練習問題の答えはログイン会員向けです。

階層図。見出しは「hello.xml の 4 層の入れ子」。上から下へ四つの層がある。mujoco 要素、唯一の最上位要素。worldbody、必須の最も外側の body で世界の根。body、自身の位置 pos を持つ。free 関節が 6 自由度を、geom が箱の形を与える。下部に出典の表示がある。
MuJoCo ドキュメントの Overview にある最小の例 hello.xml の入れ子の階層:mujoco は唯一の最上位要素、worldbody は必須の最も外側の body で、その中の body は位置を持ち、body の中の free 関節が 6 自由度を、geom が形を与えます。層の順番は XML の入れ子を表し、重要度ではありません。図に測定値は含まれていません。出典:MuJoCo ドキュメント · Overview と XML Reference。

第 2.1 回の動画は、MuJoCo の XML モデル形式である MJCF を一枚書いて、つかむ場面をつくります。机が一つ、コップが一つ、二本指のグリッパーが一つです。動画のポイントは三つあります。MJCF は worldbody、body、geom、joint で世界を記述すること。mj_step が物理を一歩ずつ進め、標準のステップ幅 0.002 秒は速さと精度のトレードオフであること。位置アクチュエーターと「閉じて、持ち上げる」スクリプトを足せばつかんでみられ、成否は指の位置とコップの高さの二本の曲線で判断すること、です。動画の三枚の数字カードは、いずれも MuJoCo の公式ドキュメントから取っています。標準のステップ幅 0.002 秒、標準の重力 9.81、標準の密度 1000 です。このページはこの回の解説と練習です。文字起こしを繰り返すのではなく、動画では軽く触れただけの問いに答えます。数十行の XML で、なぜ足りるのか。答えは、多くの値は書かれていないものの、なくなっているわけではなく、標準値を取っているからです。この回ではその標準値を一つずつ書き出し、架空のコップを使って、それが重さ・速さ・ステップ数として何を意味するかを計算します。そのうえで、ドキュメントに書かれているのに見落としやすい二つのルールを見ます。数値の発散はステップ幅のせいとは限らないこと、そして親子の物体どうしは衝突しないというルールにも例外があることです。全体を通じたルールは一つです。XML に書かれていない値を、それが前提とする単位とともに書き出せて、はじめてモデルを読めたことになります。

この回の動画、文字起こし、出典はこのページの上部にあり、シーズン全体の構成は講座の概要にあります。これは L2「手を動かす」の最初の回です。前回のフィジカルAIラボ 1.8:評価――「差し引き +2」を対応表に分解し、失敗ラベルと乱数シードを計算で確かめるは、シミュレーションでつかむ場面を自分でつくってみたくないか、という問いで終わりました。今回はその続きです。ステップ幅を小さくすると計算量がどう増えるか、エンジンごとの接触の近似がどう二本の軌道を分かれさせるかは、フィジカルAIラボ 1.4:シミュレータの地図――刻み幅のコストを数え、接触で軌道が分かれる点を読み、3 つの高速化の比較対象を確かめるで扱いました。二本の指が摩擦でコップを挟むのにどれだけの力が要るかは、フィジカルAIラボ 1.3:センサー――1 つのコップで画素数、深度の測定範囲、握る力を手計算するで手計算しました。この回ではそれらを繰り返さず、MuJoCo のドキュメントのうち、この回に直接関わる箇所だけを扱います。

公開小テストの 5 問には詳しい解説が付いています。ログインすると、三つの練習に取り組めます。架空のコップの質量と重さを書き出し、長さをセンチメートルに変えたのに標準の重力と密度を残したモデルを審査する。架空の落下ログを読み、発散の原因がステップ幅か初期の貫通かを見分ける。架空のグリッパーの body の木で衝突を一組ずつ判定し、4 回のつかみ動作の記録を審査する。いずれも段階的な解答例、よくある誤り、20 点満点の採点基準付きです。

1. hello.xml に書かれていない値

MuJoCo ドキュメントの Overview の章には、いちばん小さな MJCF の例 hello.xml が載っています。本文によると、これは世界に固定された平面、ライト一つ、そして 6 自由度を持つ浮いた箱を定義しており、「free」関節がその役目を果たします。シミュレーションすると、箱は地面に落ちます。以下がドキュメントにある元のファイルです。

<mujoco>
  <worldbody>
    <light diffuse=".5 .5 .5" pos="0 0 3" dir="0 0 -1"/>
    <geom type="plane" size="1 1 0.1" rgba=".9 0 0 1"/>
    <body pos="0 0 1">
      <joint type="free"/>
      <geom type="box" size=".1 .2 .3" rgba="0 .9 0 1"/>
    </body>
  </worldbody>
</mujoco>

この 10 行には、質量も、重力も、ステップ幅も、衝突のルールも一つも書かれていません。その理由は、ドキュメントが続く長めの例を説明するところで述べています。次の二文は、それぞれ独立した抜粋です。

Inertial properties are inferred from the geom shape under a uniform density assumption.

Collision rules are defined automatically. Friction properties, gravity, simulation time step etc. are set to their defaults.

動画の三枚の数字カードにあたる三つの標準値の原文は次のとおりで、それぞれ独立に抜粋しています。一つ目は XML Reference の option の節から、残りの二つは Overview の「Units are unspecified」の節からです。

timestep : real, “0.002” Simulation time step in seconds. This is the single most important parameter affecting the speed-accuracy trade-off which is inherent in every physics simulation.

The default value of gravity is (0, 0, -9.81), which corresponds to Earth surface gravity in MKS.

The default value of geom density (used to infer body masses and inertias) is 1000, which corresponds to the density of water in MKS.

書かれていない値標準値どの要素に書くかドキュメントがほかに述べていることこの文が述べていないこと
ステップ幅0.002 soption の timestep小さいほど正確で安定する。実時間で動かすには、ステップ幅が 1 ステップあたりの CPU 時間より大きくなければならない個々のモデルでどのステップ幅を使うべきか。ドキュメントは、安定性はソルバーのパラメータにもよるとし、両方を合わせて調整するよう勧めている
重力(0, 0, −9.81)option の gravityMKS 単位系での地表の重力にあたるMKS を使わなければならないとは決めていない。ドキュメントの言い方では、エンケラドゥスで CGS を使っているかもしれない
質量と慣性geom の形と密度 1000 から求めるgeom の density(属性の一覧には mass もある)1000 は MKS での水の密度にあたる。慣性は一様な密度の仮定で求める求めるのは中身の詰まった物体の質量で、コップが空洞だとは知らない
衝突のルール自動で定義書かない標準では、直接の親子関係にある body どうしの衝突を除外する。ただし静的な親は例外(第 4 節)引用した文は、ほかの絞り込みの仕組みには触れていない

三枚の数字カードはいずれも O レベル(公式の一次資料)です。MuJoCo のドキュメントが自分たちのソフトウェアについて述べたもので、本サイトでは MuJoCo を動かして確認していません。この回で読んだのは 2026-10-12 に取得した stable 版のドキュメントで、動画の数字カードには v3.14.0 と表示されています。ドキュメントは版ごとに更新されます。

コンパイルしたあと、値はどこにあるか。Overview によると、MJCF は組み込みのコンパイラーで低レベルのデータ構造 mjModel にコンパイルされます。mjModel はモデルの記述を持ち、変わらないことが前提です。mjData はすべての動的な変数と途中の計算結果を持ち、実行時に mjModel をもとに作られます。XML Reference はさらに、option 要素が mjModel.opt にある mjOption と一対一に対応すると述べています。つまりステップ幅と重力は最終的に mjModel にあり、コップがいまどこにあって、どれだけの速さで動いているかは mjData にあります。ドキュメントには、これらのオプションは各シミュレーションステップの前に変更してよいが、一つのステップの途中で変更すべきではない、とも書かれています。ドキュメントでいちばん短いシミュレーションのループは一行だけです。

while (d->time < 10) mj_step(m, d);

標準のステップ幅なら、この一行は mj_step をおよそ 10 ÷ 0.002 = 5000 回呼びます(この回の計算)。動画で机を箱、コップを円柱にし、コップを自由関節でつないでいるのは、hello.xml の書き方を大きくしたものです。

制約と注意点

  • ステップ幅 0.002 s、重力 (0, 0, −9.81)、密度 1000、実時間の条件、発散の見分け方、親子の衝突ルールは、いずれも MuJoCo の公式ドキュメント(Overview と XML Reference)によるもので、O レベルです。この回で読んだのは 2026-10-12 に取得した stable 版で、動画の数字カードには v3.14.0 と表示されています。本サイトでは MuJoCo を動かして、どれも確認していません。
  • この回が拠っているのは二つのドキュメントページの抜粋です。geom の size を寸法に換算する方法、ソルバーのパラメータ(solref、solimp など)の詳しい意味、Collision detection の節、contype や conaffinity などのほかの絞り込みの仕組みは含みません。「Surprising Collisions」の節は抜粋では最後まで読めていません。「RK4 では 4 倍より大きくなければならない」は、ドキュメントの括弧内の文をこの回が文字どおりに読んだものです。
  • 第 2・3 節のコップの寸法、机の高さ、0.03 m、CPU 時間の 0.1 ms と 0.6 ms、z = 0.440 m などはこの回の仮定です。0.503 kg、4.93 N、0.0782 s、40 ステップ目、20 倍、約 3.3 倍、5000 回などはこの回の計算です。自由落下の見積もりは離散的な積分、やわらかい接触、空気を無視しており、MuJoCo の出力ではありません。
  • 第 5 節のコップ C、センチメートル版とミリメートル版のファイル、木材の密度 600、実行 A〜C、body の木、アクチュエーターと制御範囲の設定、触覚の読み、G1〜G4、チームメンバーの報告は練習用の架空の設定です。計算した 0.339 kg、589 kg/m³、33.3 N、0.0639 s、0.800 m などは、これらの仮定のもとでだけ成り立ちます。見分け方の順番と三つの問いによる確認は、この回がドキュメントを整理したもので、採点基準は教材としての提案です。
  • この記事では、動画の Notebook、インタラクティブな画面、曲線の実装とデータを確認していません。動画のつかみ動作は手書きのスクリプトです。シミュレーションでつかめても、実機で安全・確実だということにはならず、紙の上の計算もシミュレーションの結果も、ハードウェアの安全性の検証ではありません。

リンク

この回の動画を見る(日本語) · 2.1