modeledit.rst 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. Model Editing
  2. -------------
  3. .. admonition:: Unstable API
  4. :class: attention
  5. The API described below is new and unstable. There may be latent bugs and function signatures may change. Early
  6. adopters are welcome (indeed, encouraged) to try it out and report any issues on GitHub.
  7. As of MuJoCo 3.2, it is possible to create and modify models using the :ref:`mjSpec` struct and related API.
  8. This datastructure is in one-to-one correspondence with MJCF and indeed, MuJoCo's own XML parsers (both MJCF and URDF)
  9. use this API when loading a model.
  10. .. _meOverview:
  11. Overview
  12. ~~~~~~~~
  13. The new API augments the traditional workflow of creating and editing models using XML files, breaking up the *parse* and
  14. *compile* steps. As summarized in the the :ref:`Overview chapter<Instance>`, the traditional workflow is:
  15. 1. Create an XML model description file (MJCF or URDF) and associated assets. |br|
  16. 2. Call :ref:`mj_loadXML`, obtain an :ref:`mjModel` instance.
  17. The new workflow is:
  18. 1. :ref:`Create<mj_makeSpec>` an empty :ref:`mjSpec` or :ref:`parse<mj_parseXML>` an existing XML file to an
  19. :ref:`mjSpec`.
  20. 2. Edit the mutable :ref:`mjSpec` datastructure adding, changing and removing elements.
  21. 3. Compile the :ref:`mjSpec` at any point, obtaining an updated :ref:`mjModel` instance. After compilation, the
  22. :ref:`mjSpec` remains editable, so steps 2 and 3 are interchangable.
  23. .. _meUsage:
  24. Usage
  25. ~~~~~
  26. Here we describe the C API for procedural model editing, but it is also exposed in the
  27. :ref:`Python bindings<PyModelEdit>`.
  28. After creating a new :ref:`mjSpec` or parsing an existing XML file to an :ref:`mjSpec`, procedural editing corresponds
  29. to setting attributes. For example, in order to change the timestep, one can do:
  30. .. code-block:: C
  31. mjSpec* spec = mj_makeSpec();
  32. spec->opt.timestep = 0.01;
  33. ...
  34. mjModel* model = mj_compile(spec);
  35. Attributes which have variable length are C++ vectors and strings, :ref:`exposed to C as opaque types<ArrayHandles>`.
  36. In C one uses the provided :ref:`getters<AttributeGetters>` and :ref:`setters<AttributeSetters>`:
  37. .. code-block:: C
  38. mjs_setString(model->modelname, "my_model");
  39. In C++ one can use these directly:
  40. .. code-block:: C++
  41. std::string modelname = "my_model";
  42. *spec->modelname = modelname;
  43. .. _meMjsElements:
  44. Model elements
  45. ^^^^^^^^^^^^^^
  46. Model elements corresponding to MJCF are added to the spec using the corresponding functions. For example, to add a box
  47. geom to the world body, one would do
  48. .. code-block:: C
  49. mjSpec* spec = mj_makeSpec();
  50. mjsBody* world = mjs_findBody(spec, "world");
  51. mjsGeom* my_geom = mjs_addGeom(world, NULL);
  52. my_geom->type = mjGEOM_BOX;
  53. my_geom->size[0] = my_geom->size[1] = my_geom->size[2] = 0.5;
  54. mjModel* model = mj_compile(spec);
  55. The ``NULL`` second argument to :ref:`mjs_addGeom` is the optional default class pointer. When using defaults
  56. procedurally, default classes are passed in explicitly to element constructors. The global defaults of all elements
  57. (used when no default class is passed in) can be inspected in
  58. `user_init.c <https://github.com/google-deepmind/mujoco/blob/main/src/user/user_init.c>`__.
  59. .. _meAttachment:
  60. Attachment
  61. ^^^^^^^^^^
  62. The new framework introduces a powerful new feature: attaching and detaching model subtrees. Attachment allows the user
  63. copy a subtree from one model into another, while also copying related referenced assets and referencing elements from
  64. outside the kinematic tree (e.g., actuators and sensors). Similarly, detaching a subtree will remove all associated
  65. elements from the model.
  66. This feature is incomplete and will be described in detail once it is fully implemented, but it is already used to power
  67. the :ref:`attach<body-attach>` and :ref:`replicate<replicate>` meta-elements in MJCF.
  68. .. _meKnownIssues:
  69. Known issues
  70. ~~~~~~~~~~~~
  71. - Better documentation is still missing and will be added in the future. In the meantime, advanced users can refer
  72. to `user_api_test.cc <https://github.com/google-deepmind/mujoco/blob/main/test/user/user_api_test.cc>`__ and the MJCF
  73. parser in `xml_native_reader.cc <https://github.com/google-deepmind/mujoco/blob/main/src/xml/xml_native_reader.cc>`__,
  74. which is already using this API.
  75. - One of the central design considerations of the new API is incremental compilation, meaning that after making small
  76. changes to a spec that has already been compiled, subsequent re-compilation will be very fast. While the code is
  77. written to support incremental compilation, this functionality is not fully implemented and will be added in the
  78. future, resulting in faster re-compilation times.
  79. - Since the main test for the new API is the MJCF parser, which always constructs a model from scratch, there
  80. might be latent bugs related to model editing. Please report such bugs if you encounter them.