unity.rst 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. =============
  2. Unity Plug-in
  3. =============
  4. Introduction
  5. ------------
  6. The MuJoCo `Unity plug-in <https://github.com/google-deepmind/mujoco/tree/main/unity>`_ allows the Unity Editor and
  7. runtime to use the MuJoCo physics engine. Users can import MJCF files and edit the models in the Editor. The plug-in
  8. relies on Unity for most aspects -- assets, game logic, simulation time -- but uses MuJoCo to determine how objects
  9. move, giving the designer access to MuJoCo's full API.
  10. .. _UInstallation:
  11. Installation instructions
  12. -------------------------
  13. The plug-in directory (available at https://github.com/google-deepmind/mujoco/tree/main/unity) includes a
  14. ``package.json`` file. Unity's package manager recognizes this file and will import the plug-in's C# codebase to your
  15. project. In addition, Unity also needs the native MuJoCo library, which can be found in the specific platform archive at
  16. https://github.com/google-deepmind/mujoco/releases.
  17. On Unity version 2020.2 and later, the Package Manager will look for the native library file and copy it to the package
  18. directory when the package is imported. Alternatively, you can manually copy the native library to the package directory
  19. and rename it, see platform-specific instructions below. The library can also be copied into any location under your
  20. project's Assets directory.
  21. MacOS
  22. _____
  23. The MuJoCo app needs to be run at least once before the native library can be used, in order to register the library as
  24. a trusted binary. Then, copy the dynamic library file from
  25. ``/Applications/MuJoCo.app/Contents/Frameworks/mujoco.framework/Versions/Current/libmujoco.3.2.5.dylib`` (it can be
  26. found by browsing the contents of ``MuJoCo.app``) and rename it as ``mujoco.dylib``.
  27. Linux
  28. _____
  29. Expand the ``tar.gz`` archive to ``~/.mujoco``. Then copy the dynamic library from
  30. ``~/.mujoco/mujoco-3.2.5/lib/libmujoco.so.3.2.5`` and rename it as ``libmujoco.so``.
  31. Windows
  32. _______
  33. Expand the ``zip`` archive to a directory called ``MuJoCo`` in your user directory, and copy the file
  34. ``MuJoCo\bin\mujoco.dll``.
  35. .. _UUsing:
  36. Using the plug-in
  37. -----------------
  38. .. _UImporter:
  39. Importer
  40. ________
  41. The importer is invoked from the Editor's *Asset* menu: click on "Import MuJoCo Scene" and select the XML file with your
  42. model's MJCF specification.
  43. Context menus
  44. _____________
  45. - Right-clicking a geom component offers two options:
  46. - "Add mesh renderer" adds components to the same game object that render the geom: a standard ``MeshRenderer`` and a
  47. ``MjMeshFilter`` that creates a procedural mesh that is recreated when the geom shape properties change.
  48. - "Convert to free object" adds two new game objects: a parent with an ``MjBody`` component and a sibling with an
  49. ``MjFreeJoint`` component. This allows the previously static geom to move about freely in the scene. This action
  50. only applies to "world" geoms -- those that do not currently have an ``MjBody`` parent.
  51. - Right-clicking a Unity Collider offers the option to "Add a matching MuJoCo geom" to the same game object. Note that
  52. this does not comprise a complete conversion of the physics -- Rigidbody, ArticulationBody and Joint configurations
  53. still need to be recreated manually.
  54. Mouse spring
  55. ____________
  56. When the selected game object has an ``MjBody`` component, spring forces can be applied to this body towards the mouse
  57. cursor through a control-left-drag action in the Scene view. The 3D position of the spring force origin is found by
  58. projecting the mouse position on a plane defined by the camera X direction and the world Y direction. Adding the shift
  59. key changes the projection plane to be parallel to the world's X and Z axes.
  60. .. _UTips:
  61. Tips to Unity users
  62. ___________________
  63. - If any compilation or runtime errors are encountered, the state of the system is undefined. Therefore, we recommend
  64. turning on “Error Pause” in the console window.
  65. - In PhysX, every `Rigidbody` is a “free body”. In contrast, MuJoCo requires explicit specification of joints for
  66. mobility. For convenience, we provide a context menu for “freeing” a world geom (i.e., an ``MjGeom`` component without
  67. any ``MjBody`` ancestor) by adding a parent ``MjBody`` and a sibling ``MjFreeJoint``.
  68. - The plug-in doesn’t support collision detection without physical presence, so there is no built-in notion of trigger
  69. colliders. The presence or absence of a contact force can be read by adding a touch sensor and reading its
  70. ``SensorReading`` value (which will correspond to the normal force, see `touch sensor documentation <sensor-touch>`).
  71. .. _UDesign:
  72. Design principles
  73. -----------------
  74. The plug-in design provides a one-to-one mapping between MJCF elements and Unity components. In order to simulate a
  75. Unity scene (e.g., when the user hits the “play” button in the Editor) using MuJoCo, the plug-in:
  76. 1. Scans the GameObject hierarchy in the scene for MuJoCo components.
  77. 2. Creates an MJCF description and passes it to MuJoCo’s compiler.
  78. 3. Binds every component to the MuJoCo runtime via the corresponding index in MuJoCo’s data structures. This index is
  79. used for updating Unity’s transforms during simulation.
  80. This design principle has several implications:
  81. - Most fields of the Unity components correspond directly to MJCF attributes. Therefore, the user can refer to the
  82. MuJoCo documentation for details on the semantics of different values.
  83. - The layout of MuJoCo components in the GameObject hierarchy determines the layout of the resulting MuJoCo model.
  84. Therefore, we adopt a design rule that **every game object must have at most one MuJoCo component**.
  85. - We rely on Unity for spatial configuration, which requires vector components to be `swizzled
  86. <https://en.wikipedia.org/wiki/Swizzling_(computer_graphics)>`_ since Unity uses left-handed frames with Y as the
  87. vertical axis, while MuJoCo uses right-handed frames with Z as the vertical axis.
  88. - Unity transform scaling affects positions, orientations, and scale of the entire game object subtree. However, MuJoCo
  89. doesn’t support collision of skewed cylinders and capsules (skewed spheres are supported via the ellipsoid primitive).
  90. The gizmo for geoms and sites ignores this skew (similarly to PhysX colliders), and will always show the primitive
  91. shape as it will appear to the physics.
  92. - During runtime, changing values of component fields will not trigger scene recreation, so it will have no immediate
  93. effect on the physics. However, the new values will be loaded upon the next scene recreation.
  94. Wherever possible, we do things the Unity Way: gravity is read from Unity’s physics settings, and the simulation step is
  95. read from Unity’s Time Manager’s `Fixed Timestep`. All aspects of appearance (e.g., meshes, materials, and textures)
  96. are handled by Unity’s Asset Manager, and RGBA specifications are done using material assets.
  97. .. _UNotes:
  98. Implementation notes
  99. --------------------
  100. Importer workflow
  101. _________________
  102. When the user selects an MJCF file, the importer first loads
  103. the file in MuJoCo, saves it to a temporary location, and then processes the generated saved file. This has several
  104. effects:
  105. - It validates the MJCF - we are guaranteed that the saved MJCF matches the :ref:`schema <CSchema>`.
  106. - It validates the assets (materials, meshes, textures) and imports these assets into Unity, as well as creating new
  107. material assets for geom RGBA specification.
  108. - It allows the importer to handle :ref:`\<include\> <include>` elements without replicating MuJoCo’s file-system
  109. workflow.
  110. - The current version of MuJoCo generates MJCF files with explicit :ref:`\<inertial\> <body-inertial>` elements, even when
  111. the original model uses geoms for implicit definition of the body inertia. If you plan to change geom properties of
  112. an imported model, remove these auto-generated ``MjInertial`` components manually. We plan to address this in a
  113. future release of MuJoCo.
  114. In Unity, there is no equivalent to MJCF’s “cascading” :ref:`\<default\> <default>` clauses. Therefore, components in
  115. Unity reflect the corresponding elements’ state after applying all the relevant default classes, and the class structure
  116. in the original MJCF is discarded.
  117. The MuJoCo Scene
  118. ________________
  119. When a MuJoCo scene is created, the ``MjScene`` component first scans the scene for all instances of ``MjComponent``.
  120. Each component creates its own MJCF element using Unity scene’s spatial structure to describe the model’s initial
  121. reference pose (called ``qpos0`` in MuJoCo). ``MjScene`` combines these XML elements according to the hierarchy of the
  122. respective game objects and creates a single MJCF description of the physics model. It then creates the runtime structs
  123. ``mjModel`` and ``mjData``, and binds each component to the runtime by identifying its unique index.
  124. During runtime, ``MjScene.FixedUpdate()`` calls :ref:`mj_step`, and then synchronizes the state of each game object
  125. according to the index ``MjComponent.MujocoId`` identified at binding time. An ``MjScene`` component is added
  126. automatically when the application starts (e.g., when the user hits “play”) if and only if the scene includes any MuJoCo
  127. components. If your application’s initialization phase involves ticking the physics while adding game objects and
  128. components, you can call ``MjScene.CreateScene()`` when the initialization phase is over.
  129. Scene recreation maintains continuity of physics and state in the following way:
  130. 1. The position and velocity of joints are cached.
  131. 2. MuJoCo’s state is reset (to ``qpos0``) and Unity transforms are synchronized.
  132. 3. A new XML is generated, creating a model that has the same ``qpos0`` as the previous one for the joints that
  133. persisted.
  134. 4. The MuJoCo state (for the joints that persisted) is set from the cache, and Unity transforms are synchronized.
  135. Because the MuJoCo library doesn’t (yet) expose an API for scene editing, adding and removing MuJoCo components causes
  136. complete scene recreation. This can be expensive for large models or if it happens frequently. We expect this
  137. performance limitation to be lifted in future versions of MuJoCo.
  138. Global Settings
  139. _______________
  140. An exception to the one-element-per-one-component is the Global Settings component. This component is responsible for
  141. all the configuration options that are included in the fixed-size, singleton, global elements of MJCF. Currently it
  142. holds information that corresponds to the :ref:`\<option\> <option>` and :ref:`\<size\> <size>` elements, and in the
  143. future it will also be used for the :ref:`\<compiler\> <compiler>` element, if/when fields there will be relevant to the
  144. Unity plug-in.
  145. Invoking the importer at application runtime
  146. ____________________________________________
  147. The importer is implemented by the class ``MjImporterWithAssets``, which is a subclass of ``MjcfImporter``. This parent
  148. class takes an MJCF string and generates the hierarchy of components. It can be invoked at play-time (it doesn’t
  149. involve Editor functionality), and it doesn’t invoke any functions of the MuJoCo library. This is useful when MuJoCo
  150. models are generated procedurally (e.g., by some evolutionary process) and/or when an MJCF is imported only to be
  151. converted (e.g., to PhysX, or URDF). Since it cannot interact with Unity’s ``AssetManager`` (which is a feature of the
  152. Editor), this class’s functionality is restricted. Specifically:
  153. - It ignores all assets (including collision meshes).
  154. - It ignores visuals (including RGBA specifications).
  155. MuJoCo sensor components
  156. ________________________
  157. MuJoCo defines many sensors, and we were concerned that creating a separate ``MjComponent`` class for each would lead to
  158. a lot of code duplication. Therefore, we created classes according to the type of object (actuator / body / geom /
  159. joint / site) whose properties are measured, and the type (scalar / vector / quaternion) of the measured data.
  160. Here’s a table that maps types to sensors:
  161. +------------------------+---------------+---------------------+
  162. | **Mujoco Object Type** | **Data Type** | **Sensor Name** |
  163. +------------------------+---------------+---------------------+
  164. | Actuator | Scalar | - ``actuatorpos`` |
  165. | | | - ``actuatorvel`` |
  166. | | | - ``actuatorfrc`` |
  167. +------------------------+---------------+---------------------+
  168. | Body | Vector | - ``subtreecom`` |
  169. | | | - ``subtreelinvel`` |
  170. | | | - ``subtreeangmom`` |
  171. | | | - ``framepos`` |
  172. | | | - ``framexaxis`` |
  173. | | | - ``frameyaxis`` |
  174. | | | - ``framezaxis`` |
  175. | | | - ``framelinvel`` |
  176. | | | - ``frameangvel`` |
  177. | | | - ``framelinacc`` |
  178. | | | - ``frameangacc`` |
  179. +------------------------+---------------+---------------------+
  180. | Body | Quaternion | - ``framequat`` |
  181. +------------------------+---------------+---------------------+
  182. | Geom | Vector | - ``framepos`` |
  183. | | | - ``framexaxis`` |
  184. | | | - ``frameyaxis`` |
  185. | | | - ``framezaxis`` |
  186. | | | - ``framelinvel`` |
  187. | | | - ``frameangvel`` |
  188. | | | - ``framelinacc`` |
  189. | | | - ``frameangacc`` |
  190. +------------------------+---------------+---------------------+
  191. | Geom | Quaternion | - ``framequat`` |
  192. +------------------------+---------------+---------------------+
  193. | Joint | Scalar | - ``jointpos`` |
  194. | | | - ``jointvel`` |
  195. | | | - ``jointlimitpos`` |
  196. | | | - ``jointlimitvel`` |
  197. | | | - ``jointlimitfrc`` |
  198. +------------------------+---------------+---------------------+
  199. | Site | Scalar | - ``touch`` |
  200. | | | - ``rangefinder`` |
  201. +------------------------+---------------+---------------------+
  202. | Site | Vector | - ``accelerometer`` |
  203. | | | - ``velocimeter`` |
  204. | | | - ``force`` |
  205. | | | - ``torque`` |
  206. | | | - ``gyro`` |
  207. | | | - ``magnetometer`` |
  208. | | | - ``framepos`` |
  209. | | | - ``framexaxis`` |
  210. | | | - ``frameyaxis`` |
  211. | | | - ``framezaxis`` |
  212. | | | - ``framelinvel`` |
  213. | | | - ``frameangvel`` |
  214. | | | - ``framelinacc`` |
  215. | | | - ``frameangacc`` |
  216. +------------------------+---------------+---------------------+
  217. | Site | Quaternion | - ``framequat`` |
  218. +------------------------+---------------+---------------------+
  219. Here’s the same table in reverse, mapping sensors to classes:
  220. ================= ===================================
  221. Sensor Name Plugin Class
  222. ================= ===================================
  223. ``accelerometer`` SiteVector
  224. ``actuatorfrc`` ActuatorScalar
  225. ``actuatorpos`` ActuatorScalar
  226. ``actuatorvel`` ActuatorScalar
  227. ``force`` SiteVector
  228. ``frameangacc`` \*Vector (depends on frame type)
  229. ``frameangvel`` \*Vector (depends on frame type)
  230. ``framelinacc`` \*Vector (depends on frame type)
  231. ``framelinvel`` \*Vector (depends on frame type)
  232. ``framepos`` \*Vector (depends on frame type)
  233. ``framequat`` \*Quaternion (depends on frame type)
  234. ``framexaxis`` \*Vector (depends on frame type)
  235. ``frameyaxis`` \*Vector (depends on frame type)
  236. ``framezaxis`` \*Vector (depends on frame type)
  237. ``gyro`` SiteVector
  238. ``jointlimitfrc`` JointScalar
  239. ``jointlimitpos`` JointScalar
  240. ``jointlimitvel`` JointScalar
  241. ``jointpos`` JointScalar
  242. ``jointvel`` JointScalar
  243. ``magnetometer`` SiteVector
  244. ``subtreeangmom`` BodyVector
  245. ``subtreecom`` BodyVector
  246. ``subtreelinvel`` BodyVector
  247. ``torque`` SiteVector
  248. ``touch`` SiteScalar
  249. ``velocimeter`` SiteVector
  250. ================= ===================================
  251. The following sensors are not yet implemented:
  252. | ``tendonpos``
  253. | ``tendonvel``
  254. | ``ballquat``
  255. | ``ballangvel``
  256. | ``tendonlimitpos``
  257. | ``tendonlimitvel``
  258. | ``tendonlimitfrc``
  259. | ``user``
  260. Mesh Shapes
  261. ___________
  262. The plug-in allows using arbitrary Unity meshes for MuJoCo collision. At model compilation, MuJoCo calls `qhull
  263. <http://www.qhull.org/>`__ to create a convex hull of the mesh, and uses that for collisions. Currently the computed
  264. convex hull is not visible in Unity, but we intend to expose it in future versions.
  265. Interaction with External Processes
  266. ___________________________________
  267. Roboti’s `MuJoCo plug-in for Unity <https://roboti.us/download.html>`_ steps the simulation in an external Python
  268. process, and uses Unity only for rendering. In contrast, our plug-in relies on Unity to step the simulation. It should
  269. be possible to use our plug-in while an external process "drives" the simulation, for example by setting ``qpos``,
  270. calling ``mj_kinematics``, synchronizing the transforms, and then using Unity to render or compute game logic. In order
  271. to establish communication with an external process, you can use Unity's `ML-Agents
  272. <https://github.com/Unity-Technologies/ml-agents>`_ package.