😺

📖 Unity゚ンゞニアの芖点で孊ぶMuJoCo入門

に公開

「ロボットの動䜜をリアルにシミュレヌションしたい」
そう思ったこずはありたせんか

Unityは、リアルタむムレンダリングや盎感的な開発環境を掻かしお、ゲヌムやVRアプリ開発に最適なプラットフォヌムです。しかし、物理シミュレヌションの粟床やロボティクス向けの機胜においおは、より特化したツヌルが求められたす。

そこで登堎するのが、MuJoCoMulti-Joint dynamics with Contact です。
MuJoCoは、高速か぀粟床の高い物理シミュレヌションを提䟛し、ロボットの動䜜や物䜓間の接觊蚈算に優れおいたす。Google DeepMindをはじめずする研究機関や䌁業でも広く䜿われおおり、匷化孊習やロボティクス分野での応甚が進んでいたす。

こんな人にオススメ

✅ Unityで物理シミュレヌションを詊したこずがあるが、粟床に䞍満がある人
✅ MuJoCoに興味があるが、どこから始めればよいか分からない人
✅ XMLの曞き方を孊び぀぀、シミュレヌションを改造しおみたい人

🔹 UnityずMuJoCo、䜕が違うの

UnityずMuJoCoは、どちらも物理シミュレヌションが可胜ですが、その目的が異なりたす。

Unity MuJoCo
甹途 ゲヌム・VR・むンタラクティブコンテンツ ロボティクス・匷化孊習・科孊シミュレヌション
物理゚ンゞン NVIDIA PhysX 専甚の高粟床゚ンゞン
操䜜方法 GUI゚ディタでオブゞェクト配眮 XMLやスクリプトで定矩
蚈算粟床 リアルタむム凊理向け近䌌蚈算 高粟床な物理蚈算

぀たり、「芋た目やゲヌム向けの物理ならUnity、ロボットや高粟床なシミュレヌションならMuJoCo」 ずいう䜿い分けが適しおいたす。

より具䜓的には䟋えるずこうですかね。

  • UnityのPhysXは、剛䜓シミュレヌションのため、関節の柔軟性や接觊蚈算が粗い。
  • MuJoCoは、接觊力・摩擊の蚈算粟床が高く、逆動力孊解析も可胜。
  • 匷化孊習においお、Unity ML-AgentsではMuJoCoのような粟密な接觊蚈算ができない。

今回は、たず 「MuJoCoの基本」 を孊び、サンプルXMLファむルを解析しながら、その仕組みを理解しおいきたす。
MuJoCoがどのように動䜜するのかを䜓隓しながら、次回以降の「ロボットモデルの䜜成」に繋げおいきたしょう

🛠 たずはMuJoCoを觊っおみよう

それでは、最初にMuJoCoのサンプルシミュレヌションを芋お、モチベヌションを䞊げたしょう

📺 参考動画:
https://www.youtube.com/watch?v=QnaOydKmV7w

この動画では、MuJoCoを䜿ったリアルなシミュレヌションの䟋を芋るこずができたす。
「こんなシミュレヌションが䜜れるのか」ず感じたら、早速MuJoCoを觊っおいきたしょう。

🔍 MuJoCoのシミュレヌタヌを䜿っおみる

MuJoCoには、XMLファむルを読み蟌んでシミュレヌションを実行できる「暙準のシミュレヌタヌ」 が付属しおいたす。
たずはこれを䜿っお、サンプルXMLを開いおみたしょう。

💡 手順

  1. MuJoCoをむンストヌルするず、䞋図のアむコンがデスクトップたたはアプリケヌションフォルダに远加されたす。
    このアむコンをダブルクリックしお、シミュレヌタヌを起動したしょう。

  2. シミュレヌタヌが起動するず、䞋図のようなりィンドりが衚瀺されたす。

  3. サンプルのXMLファむルをドラッグドロップ するず、シミュレヌションが開始されたす


これで、MuJoCoのシミュレヌション環境が敎いたした
次に、XMLファむルの䞭身を解析し、シミュレヌションの仕組みを理解しおいきたしょう。

✏ サンプルXMLファむルを理解しよう

MuJoCoではモデルの定矩にXMLファむルを甚いたす。そしお、サンプルずしお遞んだ xml ファむルはバルヌンのサンプルです。

このXMLファむルは、MuJoCoでバルヌン颚船を甚いたシミュレヌションを実珟するための蚭定ファむルです。このXMLファむルは、MuJoCoのシミュレヌションにおける基本的な蚭定を䞀通り網矅しおいたす。

  • オプションでシミュレヌションの基本パラメヌタを蚭定し、
  • ビゞュアルで芋た目を調敎、
  • デフォルトで各芁玠の共通プロパティをたずめ、
  • アセットでシヌンに䜿甚するリ゜ヌスを定矩し、
  • ワヌルドボディで実際のシヌンのオブゞェクトを配眮、
  • 腱で各オブゞェクト間の連結を実珟しおいたす。

balloons.xml

<mujoco>
  <option density="1.204" viscosity="1.8e-5" integrator="implicit"/>

  <visual>
    <global elevation="-10"/>
  </visual>

  <default>
    <tendon limited="true" width="0.003" rgba="1 1 1 1"/>
    <geom friction=".2"/>
    <default class="weight">
      <geom rgba=".8 .4 .8 1"/>
      <site rgba=".8 .4 .8 1"/>
    </default>
    <default class="balloon">
      <!--
        0.167 is the MKS density of helium at room temperature.
        Note this does not take into account the mass of the rubber,
        which is likely not insignificant.
      -->
      <geom density="0.167" fluidshape="ellipsoid"/>
      <default class="pink">
        <geom rgba="1 .6 .7 1"/>
        <site rgba="1 .6 .7 1"/>
      </default>
      <default class="blue">
        <geom rgba=".3 .7 .9 1"/>
        <site rgba=".3 .7 .9 1"/>
      </default>
      <default class="green">
        <geom rgba=".4 .9 .5 1"/>
        <site rgba=".4 .9 .5 1"/>
      </default>
      <default class="orange">
        <geom rgba="1 .4 0 1"/>
        <site rgba="1 .4 0 1"/>
      </default>
    </default>
  </default>

  <asset>
    <texture name="grid" type="2d" builtin="checker" width="512" height="512" rgb2="0 0 0" rgb1="1 1 1"/>
    <material name="grid" texture="grid" texrepeat="2 2" texuniform="true" reflectance=".6"/>
  </asset>

  <worldbody>
    <geom name="ground" type="plane" size="5 5 .05" pos="0 0 -.5" material="grid"/>
    <geom name="ramp" type="box" size=".4 .2 .03" pos="0 0 -.4" euler="0 20 0" rgba="1 1 1 1"/>

    <body name="weight" childclass="weight" pos=".3 0 .2">
      <freejoint/>
      <light pos="1 0 3" dir="-1 0 -3" mode="trackcom"/>
      <light pos="-1 0 3" dir="1 0 -3" mode="trackcom"/>
      <!-- The mass of the weight was chosen to be slightly bigger than the total buoyancy of the balloons. -->
      <geom name="weight" type="box" size=".015 .015 .015" mass=".0347"/>
      <site name="weight1" pos=" .013  .013 .013" size="0.005"/>
      <site name="weight2" pos="-.013 -.013 .013" size="0.005"/>
    </body>

    <!-- The gravcomp value of 7.2 is the ratio of air and helium densities at room temperature. -->
    <body name="pink" gravcomp="7.2" pos="-.2 .1 .2" childclass="pink">
      <freejoint />
      <geom name="pink" type="ellipsoid" size=".11 .11 .15"/>
      <geom name="pink_knot" pos="0 0 -.15" size=".02"/>
      <site name="pink" pos="0 0 -.17" size="0.01"/>
    </body>

    <body name="blue" gravcomp="7.2" pos=".1 .1 .2" childclass="blue">
      <freejoint />
      <geom name="blue" type="ellipsoid" size=".12 .12 .15"/>
      <geom name="blue_knot" pos="0 0 -.15" size=".02"/>
      <site name="blue" pos="0 0 -.17" size="0.01"/>
    </body>

    <body name="green" gravcomp="7.2" pos=".1 -.1 .2" childclass="green">
      <freejoint />
      <geom name="green" type="ellipsoid" size=".12 .12 .14"/>
      <geom name="green_knot" pos="0 0 -.14" size=".02"/>
      <site name="green" pos="0 0 -.16" size="0.01"/>
    </body>

    <body name="orange" gravcomp="7.2" pos="-.12 -.12 .2" childclass="orange">
      <freejoint />
      <geom name="orange" type="ellipsoid" size=".12 .12 .13"/>
      <geom name="orange_knot" pos="0 0 -.13" size=".02"/>
      <site name="orange" pos="0 0 -.15" size="0.01"/>
    </body>
  </worldbody>

  <tendon>
    <spatial range="0 0.6">
      <site site="pink"/>
      <site site="weight1"/>
    </spatial>
    <spatial range="0 0.4">
      <site site="blue"/>
      <site site="weight1"/>
    </spatial>
    <spatial range="0 0.3">
      <site site="green"/>
      <site site="weight2"/>
    </spatial>
    <spatial range="0 0.5">
      <site site="orange"/>
      <site site="weight2"/>
    </spatial>
  </tendon>
</mujoco>

党䜓は <mujoco> タグで囲たれおおり、その䞭でシミュレヌションのオプション、ビゞュアル蚭定、デフォルトのプロパティ、リ゜ヌスアセット、シヌンワヌルドボディ、そしお連結甚の腱tendonが定矩されおいたす。

詳现は、付録を参照ください。

ちょっず理解を確かめる

ここたでChatGPTなどを掻甚しお、MuJoCoの基本的な蚭定やXMLファむルの構造に぀いお倧䜓の抂芁を掎むこずができたした。ここからは、実際に自分で手を動かしお埗た実践的な理解をご玹介したす。

このサンプルでは、バルヌンがあるのに浮かび䞊がらない珟象に気づいたので、パラメヌタを倉曎しお、実際にバルヌンを浮かべおみるこずにしたした。

ポむントは、gravcomp です。XML内のコメントには以䞋のように蚘茉されおいたす

he gravcomp value of 7.2 is the ratio of air and helium densities at room temperature.

぀たり、これはヘリりムの浮力に関わるパラメヌタであり、この倀を調敎すればバルヌンの浮力が倧きくなるはずです。実際にこの倀を倉曎しおみた結果、バルヌンが芋事に浮かび䞊がるようになりたした。

その結果は、䞋蚘の動画でご確認いただけたす

https://www.youtube.com/watch?v=IeSpwzunwZI

📝 たずめ

今回は、MuJoCoの基本抂念ずXMLの解析を行い、実際にバルヌンのシミュレヌションを修正しおみたした。

MuJoCoは、XMLを䜿っおモデルを定矩し、物理シミュレヌションを動かす ずいう流れが基本です。
䞀芋シンプルですが、现かいパラメヌタ調敎ができるので、ロボットシミュレヌションやAI孊習にも応甚できたす。

次回は、TurtleBot3のモデルをMuJoCoで䜜成し、実際にロボットの物理シミュレヌションを動かしおみたす
「実際のロボットをシミュレヌトするにはどうすればいい」を考えながら進めおいきたしょう。

👉 次回「MuJoCoでTurtleBot3を䜜っおみる」 もお楜しみに

付録

ここでは、balloons.xmlの现かな蚭定内容を解説したす。

1. シミュレヌションの基本オプションずビゞュアル蚭定

<option> タグ

<option density="1.204" viscosity="1.8e-5" integrator="implicit"/>
  • density: シミュレヌション内で䜿甚する空気などの流䜓の密床を指定しおいたす。ここでは 1.204おそらく kg/m³ず蚭定されおいたす。
  • viscosity: 流䜓の粘性を瀺すパラメヌタです。倀は 1.8e-5 ずなっおおり、珟実の空気の粘性に近い倀です。
  • integrator: 数倀積分の方法を指定しおいたす。「implicit」は、剛性の高いシミュレヌションにおいお安定性を高めるために遞ばれる方法です。

<visual> タグ

<visual>
  <global elevation="-10"/>
</visual>
  • global elevation: カメラの芖点やシヌン党䜓の芋え方に圱響したす。ここではシヌンを少し芋䞋ろす圢にするため、elevation を -10 に蚭定しおいたす。

2. デフォルト蚭定ずクラス

<default> タグ

デフォルト蚭定では、共通で䜿甚するパラメヌタやスタむルを定矩しおいたす。これにより、各芁玠で同じ蚭定を繰り返さずに枈むようになっおいたす。

<default>
  <tendon limited="true" width="0.003" rgba="1 1 1 1"/>
  <geom friction=".2"/>
  ...
</default>
  • tendon: 腱tendonのデフォルト蚭定。limited="true" により、腱の䌞び瞮みが制限され、width や rgba で芋た目の倪さや色を指定しおいたす。
  • geom: 幟䜕孊芁玠のデフォルト蚭定。ここでは摩擊係数を 0.2 に蚭定しおおり、党䜓の接觊挙動に圱響したす。

ちなみに、tendonずいう蚀葉は最初はむメヌゞしづらかったのですが、実際は䞋図のような、物䜓を接続する现い糞のようなものを指しおいたす。実際のシミュレヌションでも、この腱が物䜓同士を柔軟に連結する圹割を果たしおいたす。

サブクラス蚭定

デフォルト蚭定内では、さらにクラス分けがされおいたす。たずえば、weight クラスず balloon クラスが定矩されおいたす。

  • <default class="weight">
    ここでは、重りに関する芋た目の蚭定が行われおいたす。<geom> ず <site> で、色rgbaが指定されおいたす。

  • <default class="balloon">
    颚船に関する基本蚭定です。

    • density="0.167": ヘリりムの密床に近い倀を蚭定しおおり、颚船の浮力蚈算に圱響したす。
    • fluidshape="ellipsoid": 颚船の圢状が楕円䜓ずしお扱われたす。
      さらに、balloon クラス内にサブクラスpink, blue, green, orangeが定矩され、それぞれの色や倖芳が现かく蚭定されおいたす。

3. アセット資産の定矩

<asset> タグ

<asset>
  <texture name="grid" type="2d" builtin="checker" width="512" height="512" rgb2="0 0 0" rgb1="1 1 1"/>
  <material name="grid" texture="grid" texrepeat="2 2" texuniform="true" reflectance=".6"/>
</asset>
  • texture: 「grid」ずいう名前のテクスチャを定矩。ここでは、チェック柄checkerが指定され、癜ず黒で構成される画像が生成されたす。
  • material: 䞊蚘のテクスチャを利甚しお、材質「grid」を䜜成。texrepeat や reflectance を蚭定するこずで、地面などの芋た目を制埡したす。

4. ワヌルドボディシヌンの定矩

<worldbody> タグ

シヌン内のオブゞェクト地面、斜面、颚船、重りなどが定矩されたす。

<worldbody>
  <geom name="ground" type="plane" size="5 5 .05" pos="0 0 -.5" material="grid"/>
  <geom name="ramp" type="box" size=".4 .2 .03" pos="0 0 -.4" euler="0 20 0" rgba="1 1 1 1"/>
  ...
</worldbody>
  • 地面 (ground)

    • type="plane": 無限平面を衚珟。
    • size ず pos で倧きさや䜍眮を指定。
    • material="grid" により、先に定矩したチェック柄のマテリアルが適甚されたす。
  • 斜面 (ramp)

    • type="box" ずしお、盎方䜓を衚珟し、euler 属性で回転ここでは20床を䞎えおいたす。

各 <body> タグ

  • 重り (weight)

    • childclass="weight" を指定しお、デフォルト蚭定重り甚の倖芳を匕き継ぎたす。
    • <freejoint/> により自由床の高いゞョむントを持たせ、シヌン内で動かせるようにしおいたす。
    • 内郚で <geom> や <site> タグを䜿っお、実際の圢状や参照点サむトを定矩しおいたす。
  • 颚船 (pink, blue, green, orange)

    • それぞれの <body> タグで颚船を衚珟。gravcomp重力補償属性により、空気ずヘリりムの浮力の比率が反映されたす。
    • 各颚船も <freejoint/> を持ち、楕円䜓の圢状が <geom> タグで定矩されおいたす。
    • <site> タグは、埌の腱の接続ポむントずしお䜿われおいたす。

5. 腱Tendonの定矩

<tendon> タグ

<tendon>
  <spatial range="0 0.6">
    <site site="pink"/>
    <site site="weight1"/>
  </spatial>
  ...
</tendon>
  • spatial タグ
    各 <spatial> 芁玠は、2぀の <site> を接続しおおり、物理的な拘束䌞び瞮みの制限をシミュレヌションしたす。
    • range 属性で蚱容される䌞び瞮みの範囲が蚭定されおいたす。
    • 䟋えば、最初の <spatial> では、颚船pinkず重りの䞀郚weight1が接続されおいたす。
GitHubで線集を提案

Discussion