Make model editing API public, fixes #364

Still missing:

- Detailed documentation.
- Python bindings.

PiperOrigin-RevId: 641445626
Change-Id: I20e67b707cf1bebae7e0cc94d17f7b76a89171f0
This commit is contained in:
Alessio Quaglino
2024-06-07 22:27:10 -07:00
committed by Copybara-Service
parent 4c3d9461ae
commit 7a06bcfdaf
46 changed files with 8508 additions and 980 deletions
+418 -11
View File
@@ -9,9 +9,11 @@ MuJoCo defines a large number of types:
- Enums used in :ref:`mjModel<tyModelEnums>`.
- Enums used in :ref:`mjData<tyDataEnums>`.
- Abstract :ref:`visualization enums<tyVisEnums>`.
- Enums for abstract :ref:`visualization<tyVisEnums>`.
- Enums used by the :ref:`openGL renderer<tyRenderEnums>`.
- Enums used by the :ref:`mjUI<tyUIEnums>` user interface package.
- Enums used by :ref:`engine plugins<tyPluginEnums>`.
- Enums used for :ref:`procedural model manipulation<tySpecEnums>`.
Note that the API does not use these enum types directly. Instead it uses ints, and the documentation/comments state
that certain ints correspond to certain enum types. This is because we want the API to be compiler-independent, and
@@ -31,9 +33,10 @@ MuJoCo defines a large number of types:
- Structs for :ref:`abstract visualization<tyVisStructure>`.
- Structs used by the :ref:`openGL renderer<tyRenderStructure>`.
- Structs used by the :ref:`UI framework<tyUIStructure>`.
- Structs used for :ref:`procedural model manipulation<tySpecStructure>`.
- Structs used by :ref:`engine plugins<tyPluginStructure>`.
- Several :ref:`tyFunction` for user-defined callbacks.
- Several :ref:`function types<tyFunction>` for user-defined callbacks.
- :ref:`tyNotes` regarding specific data structures that require detailed description.
@@ -43,7 +46,7 @@ MuJoCo defines a large number of types:
Primitive types
---------------
The two types below are defined in `mjtnum.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjtnum.h>`_.
The two types below are defined in `mjtnum.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjtnum.h>`__.
.. _mjtNum:
@@ -89,13 +92,14 @@ Byte type used to represent boolean variables.
Enum types
----------
All enum types use the ``mjt`` prefix.
.. _tyModelEnums:
Model
^^^^^
The enums below are defined in `mjmodel.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`_.
The enums below are defined in `mjmodel.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjmodel.h>`__.
.. _mjtDisableBit:
@@ -333,7 +337,7 @@ These are the possible sensor data types, used in ``mjData.sensor_datatype``.
Data
^^^^
The enums below are defined in `mjdata.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjdata.h>`_.
The enums below are defined in `mjdata.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjdata.h>`__.
@@ -376,7 +380,7 @@ Timer types. The number of timer types is given by ``mjNTIMER`` which is also th
Visualization
^^^^^^^^^^^^^
The enums below are defined in `mjvisualize.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjvisualize.h>`_.
The enums below are defined in `mjvisualize.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjvisualize.h>`__.
.. _mjtCatBit:
@@ -480,7 +484,7 @@ These are the possible stereo rendering types. They are used in ``mjvScene.stere
Rendering
^^^^^^^^^
The enums below are defined in `mjrender.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjrender.h>`_.
The enums below are defined in `mjrender.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjrender.h>`__.
.. _mjtGridPos:
@@ -542,7 +546,7 @@ These are the possible font types.
User Interface
^^^^^^^^^^^^^^
The enums below are defined in `mjui.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjui.h>`_.
The enums below are defined in `mjui.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjui.h>`__.
.. _mjtButton:
@@ -574,13 +578,74 @@ Item types used in the UI framework.
.. mujoco-include:: mjtItem
.. _tySpecEnums:
Spec
^^^^
The enums below are defined in `mjspec.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjspec.h>`__.
.. _mjtGeomInertia:
mjtGeomInertia
~~~~~~~~~~~~~~
Type of inertia inference.
.. mujoco-include:: mjtGeomInertia
.. _mjtBuiltin:
mjtBuiltin
~~~~~~~~~~
Type of built-in procedural texture.
.. mujoco-include:: mjtBuiltin
.. _mjtMark:
mjtMark
~~~~~~~
Mark type for procedural textures.
.. mujoco-include:: mjtMark
.. _mjtLimited:
mjtLimited
~~~~~~~~~~
Type of limit specification.
.. mujoco-include:: mjtLimited
.. _mjtInertiaFromGeom:
mjtInertiaFromGeom
~~~~~~~~~~~~~~~~~~
Whether to infer body inertias from child geoms.
.. mujoco-include:: mjtInertiaFromGeom
.. _mjtOrientation:
mjtOrientation
~~~~~~~~~~~~~~
Type of orientation specifier.
.. mujoco-include:: mjtOrientation
.. _tyPluginEnums:
Plugins
^^^^^^^
The enums below are defined in `mjplugin.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjplugin.h>`_.
The enums below are defined in `mjplugin.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjplugin.h>`__.
See :ref:`exPlugin` for details.
@@ -994,6 +1059,348 @@ is initialized, others change at runtime.
.. mujoco-include:: mjUI
.. _tySpecStructure:
mjSpec
^^^^^^
The strucs below are defined in `mjspec.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjspec.h>`__
and, with the exception of the top level :ref:`mjSpec` struct, begin with the ``mjs`` prefix.
For more details, see the :doc:`Model Editing <../programming/modeledit>` chapter.
.. _mjSpec:
mjSpec
~~~~~~
Model specification.
.. mujoco-include:: mjSpec
.. _mjsElement:
mjsElement
~~~~~~~~~~
Special type corresponding to any element.
.. mujoco-include:: mjsElement
.. _mjsOrientation:
mjsOrientation
~~~~~~~~~~~~~~
Alternative orientation specifiers.
.. mujoco-include:: mjsOrientation
.. _mjsBody:
mjsBody
~~~~~~~
Body specification.
.. mujoco-include:: mjsBody
.. _mjsFrame:
mjsFrame
~~~~~~~~
Frame specification.
.. mujoco-include:: mjsFrame
.. _mjsJoint:
mjsJoint
~~~~~~~~
Joint specification.
.. mujoco-include:: mjsJoint
.. _mjsGeom:
mjsGeom
~~~~~~~
Geom specification.
.. mujoco-include:: mjsGeom
.. _mjsSite:
mjsSite
~~~~~~~
Site specification.
.. mujoco-include:: mjsSite
.. _mjsCamera:
mjsCamera
~~~~~~~~~
Camera specification.
.. mujoco-include:: mjsCamera
.. _mjsLight:
mjsLight
~~~~~~~~
Light specification.
.. mujoco-include:: mjsLight
.. _mjsFlex:
mjsFlex
~~~~~~~
Flex specification.
.. mujoco-include:: mjsFlex
.. _mjsMesh:
mjsMesh
~~~~~~~
Mesh specification.
.. mujoco-include:: mjsMesh
.. _mjsHField:
mjsHField
~~~~~~~~~
Height field specification.
.. mujoco-include:: mjsHField
.. _mjsSkin:
mjsSkin
~~~~~~~
Skin specification.
.. mujoco-include:: mjsSkin
.. _mjsTexture:
mjsTexture
~~~~~~~~~~
Texture specification.
.. mujoco-include:: mjsTexture
.. _mjsMaterial:
mjsMaterial
~~~~~~~~~~~
Material specification.
.. mujoco-include:: mjsMaterial
.. _mjsPair:
mjsPair
~~~~~~~
Pair specification.
.. mujoco-include:: mjsPair
.. _mjsExclude:
mjsExclude
~~~~~~~~~~
Exclude specification.
.. mujoco-include:: mjsExclude
.. _mjsEquality:
mjsEquality
~~~~~~~~~~~
Equality specification.
.. mujoco-include:: mjsEquality
.. _mjsTendon:
mjsTendon
~~~~~~~~~
Tendon specification.
.. mujoco-include:: mjsTendon
.. _mjsWrap:
mjsWrap
~~~~~~~
Wrapping object specification.
.. mujoco-include:: mjsWrap
.. _mjsActuator:
mjsActuator
~~~~~~~~~~~
Actuator specification.
.. mujoco-include:: mjsActuator
.. _mjsSensor:
mjsSensor
~~~~~~~~~
Sensor specification.
.. mujoco-include:: mjsSensor
.. _mjsNumeric:
mjsNumeric
~~~~~~~~~~
Custom numeric field specification.
.. mujoco-include:: mjsNumeric
.. _mjsText:
mjsText
~~~~~~~
Custom text specification.
.. mujoco-include:: mjsText
.. _mjsTuple:
mjsTuple
~~~~~~~~
Tuple specification.
.. mujoco-include:: mjsTuple
.. _mjsKey:
mjsKey
~~~~~~
Keyframe specification.
.. mujoco-include:: mjsKey
.. _mjsDefault:
mjsDefault
~~~~~~~~~~
Default specification.
.. mujoco-include:: mjsDefault
.. _mjsPlugin:
mjsPlugin
~~~~~~~~~
Plugin specification.
.. mujoco-include:: mjsPlugin
.. _mjString:
.. _mjStringVec:
.. _mjIntVec:
.. _mjIntVecVec:
.. _mjFloatVec:
.. _mjFloatVecVec:
.. _mjDoubleVec:
Array handles
~~~~~~~~~~~~~
Explain how handles work.
.. code-block:: C++
#ifdef __cplusplus
// C++: defined to be compatible with corresponding std types
using mjString = std::string;
using mjStringVec = std::vector<std::string>;
using mjIntVec = std::vector<int>;
using mjIntVecVec = std::vector<std::vector<int>>;
using mjFloatVec = std::vector<float>;
using mjFloatVecVec = std::vector<std::vector<float>>;
using mjDoubleVec = std::vector<double>;
#else
// C: opaque types
typedef void mjString;
typedef void mjStringVec;
typedef void mjIntVec;
typedef void mjIntVecVec;
typedef void mjFloatVec;
typedef void mjFloatVecVec;
typedef void mjDoubleVec;
#endif
.. _tyPluginStructure:
Plugins
@@ -1028,8 +1435,8 @@ Function types
--------------
MuJoCo callbacks have corresponding function types. They are defined in `mjdata.h
<https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjdata.h>`_ and in `mjui.h
<https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjui.h>`_. The actual callback functions are documented
<https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjdata.h>`__ and in `mjui.h
<https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjui.h>`__. The actual callback functions are documented
in the :doc:`globals<APIglobals>` page.
File diff suppressed because it is too large Load Diff
+7 -2
View File
@@ -312,7 +312,7 @@ depending on which UI item was modified and what the state of that item is after
This function is called in the screen refresh loop. It copies the offscreen OpenGL buffer to the window framebuffer. If
there are multiple UIs in the application, it should be called once for each UI. Thus ``mjui_render`` is called all the
time, while :ref:`mjui_update` is called only when changes in the UI take place.
time, while :ref:`mjui_update` is called only when changes in the UI take place. dsffsdg
@@ -545,7 +545,7 @@ Finite-differenced discrete-time transition matrices.
Letting :math:`x, u` denote the current :ref:`state<gePhysicsState>` and :ref:`control<geInput>`
vector in an mjData instance, and letting :math:`y, s` denote the next state and sensor
values, the top-level :ref:`mj_step` function computes :math:`(x,u) \rightarrow (y,s)`.
values, the top-level :ref:`mj_step` function computes :math:`(x,u) \rightarrow (y,s)`
:ref:`mjd_transitionFD` computes the four associated Jacobians using finite-differencing.
These matrices and their dimensions are:
@@ -623,3 +623,8 @@ to the inputs. Below, :math:`\bar q` denotes the pre-modified quaternion:
Note that derivatives depend only on :math:`h` and :math:`v` (in fact, on :math:`s = h v`).
All outputs are optional.
.. _SpecManip:
These functions provide high level manipulation for :ref:`mjSpec` structs, which represent an uncompiled :ref:`mjModel`.
+17 -12
View File
@@ -7,16 +7,21 @@ Upcoming version (not yet released)
General
^^^^^^^
1. Added a new API for :doc:`procedural model manipulation<programming/modeledit>`. Fixes :github:issue:`364`.
Still missing:
- Detailed documentation.
- Python bindings.
2. Added :ref:`maxhullvert<asset-mesh-maxhullvert>`, the maximum number of vertices in a mesh's convex hull.
1. Added :ref:`maxhullvert<asset-mesh-maxhullvert>`, the maximum number of vertices in a mesh's convex hull.
MJX
~~~
2. Added support for :ref:`elliptic friction cones<option-cone>`.
3. Fixed a bug that resulted in less-optimal linesearch solutions for some difficult constraint settings.
4. Fixed a bug in the Newton solver that sometimes resulted in less-optimal gradients.
3. Added support for :ref:`elliptic friction cones<option-cone>`.
4. Fixed a bug that resulted in less-optimal linesearch solutions for some difficult constraint settings.
5. Fixed a bug in the Newton solver that sometimes resulted in less-optimal gradients.
Version 3.1.6 (Jun 3, 2024)
---------------------------
@@ -731,13 +736,13 @@ General
Previously, the smooth part consisted of two stitched quadratics, once continuously differentiable.
It is now a single quintic, twice continuously differentiable:
.. math::
s(x) =
\begin{cases}
0, & & x \le 0 \\
6x^5 - 15x^4 + 10x^3, & 0 \lt & x \lt 1 \\
1, & 1 \le & x \qquad
\end{cases}
.. math::
s(x) =
\begin{cases}
0, & & x \le 0 \\
6x^5 - 15x^4 + 10x^3, & 0 \lt & x \lt 1 \\
1, & 1 \le & x \qquad
\end{cases}
17. Added optional :ref:`tausmooth<actuator-muscle-tausmooth>` attribute to muscle actuators. When positive, the
time-constant :math:`\tau` of muscle activation/deactivation uses :ref:`mju_sigmoid` to transition smoothly
+8
View File
@@ -266,6 +266,14 @@ dt .at {
margin-bottom: 0.3em;
}
/* Adjust margins around code blocks */
.highlight pre {
margin-top: -0.3em;
margin-bottom: -0.3em;
margin-left: -0.5em;
margin-right: -0.5em;
}
details summary {
font-weight: 600;
}
+735 -2
View File
@@ -1598,6 +1598,637 @@ struct mjrContext_ { // custom OpenGL context
int readDepthMap; // depth mapping: mjDEPTH_ZERONEAR or mjDEPTH_ZEROFAR
};
typedef struct mjrContext_ mjrContext;
typedef enum mjtGeomInertia_ { // type of inertia inference
mjINERTIA_VOLUME, // mass distributed in the volume
mjINERTIA_SHELL, // mass distributed on the surface
} mjtGeomInertia;
typedef enum mjtBuiltin_ { // type of built-in procedural texture
mjBUILTIN_NONE = 0, // no built-in texture
mjBUILTIN_GRADIENT, // gradient: rgb1->rgb2
mjBUILTIN_CHECKER, // checker pattern: rgb1, rgb2
mjBUILTIN_FLAT // 2d: rgb1; cube: rgb1-up, rgb2-side, rgb3-down
} mjtBuiltin;
typedef enum mjtMark_ { // mark type for procedural textures
mjMARK_NONE = 0, // no mark
mjMARK_EDGE, // edges
mjMARK_CROSS, // cross
mjMARK_RANDOM // random dots
} mjtMark;
typedef enum mjtLimited_ { // type of limit specification
mjLIMITED_FALSE = 0, // not limited
mjLIMITED_TRUE, // limited
mjLIMITED_AUTO, // limited inferred from presence of range
} mjtLimited;
typedef enum mjtInertiaFromGeom_ { // whether to infer body inertias from child geoms
mjINERTIAFROMGEOM_FALSE = 0, // do not use; inertial element required
mjINERTIAFROMGEOM_TRUE, // always use; overwrite inertial element
mjINERTIAFROMGEOM_AUTO // use only if inertial element is missing
} mjtInertiaFromGeom;
typedef enum mjtOrientation_ { // type of orientation specifier
mjORIENTATION_QUAT = 0, // quaternion
mjORIENTATION_AXISANGLE, // axis and angle
mjORIENTATION_XYAXES, // x and y axes
mjORIENTATION_ZAXIS, // z axis (minimal rotation)
mjORIENTATION_EULER, // Euler angles
} mjtOrientation;
typedef struct mjsElement_ { // element type, do not modify
mjtObj elemtype; // element type
} mjsElement;
typedef struct mjSpec_ { // model specification
mjsElement* element; // element type
mjString* modelname; // model name
// compiler settings
mjtByte autolimits; // infer "limited" attribute based on range
double boundmass; // enforce minimum body mass
double boundinertia; // enforce minimum body diagonal inertia
double settotalmass; // rescale masses and inertias; <=0: ignore
mjtByte balanceinertia; // automatically impose A + B >= C rule
mjtByte strippath; // automatically strip paths from mesh files
mjtByte fitaabb; // meshfit to aabb instead of inertia box
mjtByte degree; // angles in radians or degrees
char euler[3]; // sequence for euler rotations
mjString* meshdir; // mesh and hfield directory
mjString* texturedir; // texture directory
mjtByte discardvisual; // discard visual geoms in parser
mjtByte convexhull; // compute mesh convex hulls
mjtByte usethread; // use multiple threads to speed up compiler
mjtByte fusestatic; // fuse static bodies with parent
int inertiafromgeom; // use geom inertias (mjtInertiaFromGeom)
int inertiagrouprange[2]; // range of geom groups used to compute inertia
mjtByte exactmeshinertia; // if false, use old formula
mjLROpt LRopt; // options for lengthrange computation
// engine data
mjOption option; // physics options
mjVisual visual; // visual options
mjStatistic stat; // statistics override (if defined)
// sizes
size_t memory; // number of bytes in arena+stack memory
int nemax; // max number of equality constraints
int nuserdata; // number of mjtNums in userdata
int nuser_body; // number of mjtNums in body_user
int nuser_jnt; // number of mjtNums in jnt_user
int nuser_geom; // number of mjtNums in geom_user
int nuser_site; // number of mjtNums in site_user
int nuser_cam; // number of mjtNums in cam_user
int nuser_tendon; // number of mjtNums in tendon_user
int nuser_actuator; // number of mjtNums in actuator_user
int nuser_sensor; // number of mjtNums in sensor_user
int nkey; // number of keyframes
int njmax; // (deprecated) max number of constraints
int nconmax; // (deprecated) max number of detected contacts
size_t nstack; // (deprecated) number of mjtNums in mjData stack
// global data
mjString* comment; // comment at top of XML
mjString* modelfiledir; // path to model file
// other
mjtByte hasImplicitPluginElem; // already encountered an implicit plugin sensor/actuator
} mjSpec;
typedef struct mjsOrientation_ { // alternative orientation specifiers
mjtOrientation type; // active orientation specifier
double axisangle[4]; // axis and angle
double xyaxes[6]; // x and y axes
double zaxis[3]; // z axis (minimal rotation)
double euler[3]; // Euler angles
} mjsOrientation;
typedef struct mjsPlugin_ { // plugin specification
mjsElement* instance; // element type
mjString* name; // name
mjString* instance_name; // instance name
int plugin_slot; // global registered slot number of the plugin
mjtByte active; // is the plugin active
mjString* info; // message appended to compiler errors
} mjsPlugin;
typedef struct mjsBody_ { // body specification
mjsElement* element; // element type
mjString* name; // name
mjString* childclass; // childclass name
// body frame
double pos[3]; // frame position
double quat[4]; // frame orientation
mjsOrientation alt; // frame alternative orientation
// inertial frame
double mass; // mass
double ipos[3]; // inertial frame position
double iquat[4]; // inertial frame orientation
double inertia[3]; // diagonal inertia (in i-frame)
mjsOrientation ialt; // inertial frame alternative orientation
double fullinertia[6]; // non-axis-aligned inertia matrix
// other
mjtByte mocap; // is this a mocap body
double gravcomp; // gravity compensation
mjDoubleVec* userdata; // user data
mjtByte explicitinertial; // whether to save the body with explicit inertial clause
mjsPlugin plugin; // passive force plugin
mjString* info; // message appended to compiler errors
} mjsBody;
typedef struct mjsFrame_ { // frame specification
mjsElement* element; // element type
mjString* name; // name
mjString* childclass; // childclass name
double pos[3]; // position
double quat[4]; // orientation
mjsOrientation alt; // alternative orientation
mjString* info; // message appended to compiler errors
} mjsFrame;
typedef struct mjsJoint_ { // joint specification
mjsElement* element; // element type
mjString* name; // name
mjString* classname; // class name
mjtJoint type; // joint type
// kinematics
double pos[3]; // anchor position
double axis[3]; // joint axis
double ref; // value at reference configuration: qpos0
// stiffness
double stiffness; // stiffness coefficient
double springref; // spring reference value: qpos_spring
double springdamper[2]; // timeconst, dampratio
// limits
int limited; // does joint have limits (mjtLimited)
double range[2]; // joint limits
double margin; // margin value for joint limit detection
mjtNum solref_limit[mjNREF]; // solver reference: joint limits
mjtNum solimp_limit[mjNIMP]; // solver impedance: joint limits
int actfrclimited; // are actuator forces on joint limited (mjtLimited)
double actfrcrange[2]; // actuator force limits
// dof properties
double armature; // armature inertia (mass for slider)
double damping; // damping coefficient
double frictionloss; // friction loss
mjtNum solref_friction[mjNREF]; // solver reference: dof friction
mjtNum solimp_friction[mjNIMP]; // solver impedance: dof friction
// other
int group; // group
mjtByte actgravcomp; // is gravcomp force applied via actuators
mjDoubleVec* userdata; // user data
mjString* info; // message appended to compiler errors
} mjsJoint;
typedef struct mjsGeom_ { // geom specification
mjsElement* element; // element type
mjString* name; // name
mjString* classname; // classname
mjtGeom type; // geom type
// frame, size
double pos[3]; // position
double quat[4]; // orientation
mjsOrientation alt; // alternative orientation
double fromto[6]; // alternative for capsule, cylinder, box, ellipsoid
double size[3]; // type-specific size
// contact related
int contype; // contact type
int conaffinity; // contact affinity
int condim; // contact dimensionality
int priority; // contact priority
double friction[3]; // one-sided friction coefficients: slide, roll, spin
double solmix; // solver mixing for contact pairs
mjtNum solref[mjNREF]; // solver reference
mjtNum solimp[mjNIMP]; // solver impedance
double margin; // margin for contact detection
double gap; // include in solver if dist < margin-gap
// inertia inference
double mass; // used to compute density
double density; // used to compute mass and inertia from volume or surface
mjtGeomInertia typeinertia; // selects between surface and volume inertia
// fluid forces
mjtNum fluid_ellipsoid; // whether ellipsoid-fluid model is active
mjtNum fluid_coefs[5]; // ellipsoid-fluid interaction coefs
// visual
mjString* material; // name of material
float rgba[4]; // rgba when material is omitted
int group; // group
// other
mjString* hfieldname; // heightfield attached to geom
mjString* meshname; // mesh attached to geom
double fitscale; // scale mesh uniformly
mjDoubleVec* userdata; // user data
mjsPlugin plugin; // sdf plugin
mjString* info; // message appended to compiler errors
} mjsGeom;
typedef struct mjsSite_ { // site specification
mjsElement* element; // element type
mjString* name; // name
mjString* classname; // class name
// frame, size
double pos[3]; // position
double quat[4]; // orientation
mjsOrientation alt; // alternative orientation
double fromto[6]; // alternative for capsule, cylinder, box, ellipsoid
double size[3]; // geom size
// visual
mjtGeom type; // geom type
mjString* material; // name of material
int group; // group
float rgba[4]; // rgba when material is omitted
// other
mjDoubleVec* userdata; // user data
mjString* info; // message appended to compiler errors
} mjsSite;
typedef struct mjsCamera_ { // camera specification
mjsElement* element; // element type
mjString* name; // name
mjString* classname; // class name
// extrinsics
double pos[3]; // position
double quat[4]; // orientation
mjsOrientation alt; // alternative orientation
mjtCamLight mode; // tracking mode
mjString* targetbody; // target body for tracking/targeting
// intrinsics
double fovy; // y-field of view
double ipd; // inter-pupilary distance
float intrinsic[4]; // camera intrinsics (length)
float sensor_size[2]; // sensor size (length)
float resolution[2]; // resolution (pixel)
float focal_length[2]; // focal length (length)
float focal_pixel[2]; // focal length (pixel)
float principal_length[2]; // principal point (length)
float principal_pixel[2]; // principal point (pixel)
// other
mjDoubleVec* userdata; // user data
mjString* info; // message appended to compiler errors
} mjsCamera;
typedef struct mjsLight_ { // light specification
mjsElement* element; // element type
mjString* name; // name
mjString* classname; // class name
// frame
double pos[3]; // position
double dir[3]; // direction
mjtCamLight mode; // tracking mode
mjString* targetbody; // target body for targeting
// intrinsics
mjtByte active; // is light active
mjtByte directional; // is light directional or spot
mjtByte castshadow; // does light cast shadows
double bulbradius; // bulb radius, for soft shadows
float attenuation[3]; // OpenGL attenuation (quadratic model)
float cutoff; // OpenGL cutoff
float exponent; // OpenGL exponent
float ambient[3]; // ambient color
float diffuse[3]; // diffuse color
float specular[3]; // specular color
// other
mjString* info; // message appended to compiler errorsx
} mjsLight;
typedef struct mjsFlex_ { // flex specification
mjsElement* element; // element type
mjString* name; // name
mjString* classname; // class name
// contact properties
int contype; // contact type
int conaffinity; // contact affinity
int condim; // contact dimensionality
int priority; // contact priority
double friction[3]; // one-sided friction coefficients: slide, roll, spin
double solmix; // solver mixing for contact pairs
mjtNum solref[mjNREF]; // solver reference
mjtNum solimp[mjNIMP]; // solver impedance
double margin; // margin for contact detection
double gap; // include in solver if dist<margin-gap
// other properties
int dim; // element dimensionality
double radius; // radius around primitive element
mjtByte internal; // enable internal collisions
mjtByte flatskin; // render flex skin with flat shading
int selfcollide; // mode for flex self colllision
int activelayers; // number of active element layers in 3D
int group; // group for visualizatioh
double edgestiffness; // edge stiffness
double edgedamping; // edge damping
float rgba[4]; // rgba when material is omitted
mjString* material; // name of material used for rendering
// mesh properties
mjStringVec* vertbody; // vertex body names
mjDoubleVec* vert; // vertex positions
mjIntVec* elem; // element vertex ids
mjFloatVec* texcoord; // vertex texture coordinates
// other
mjString* info; // message appended to compiler errors
} mjsFlex;
typedef struct mjsMesh_ { // mesh specification
mjsElement* element; // element type
mjString* name; // name
mjString* classname; // class name
mjString* content_type; // content type of file
mjString* file; // mesh file
double refpos[3]; // reference position
double refquat[4]; // reference orientation
double scale[3]; // rescale mesh
mjtByte smoothnormal; // do not exclude large-angle faces from normals
int maxhullvert; // maximum vertex count for the convex hull
mjFloatVec* uservert; // user vertex data
mjFloatVec* usernormal; // user normal data
mjFloatVec* usertexcoord; // user texcoord data
mjIntVec* userface; // user vertex indices
mjIntVec* userfacenormal; // user normal indices
mjIntVec* userfacetexcoord; // user texcoord indices
mjsPlugin plugin; // sdf plugin
mjString* info; // message appended to compiler errors
} mjsMesh;
typedef struct mjsHField_ { // height field specification
mjsElement* element; // element type
mjString* name; // name
mjString* content_type; // content type of file
mjString* file; // file: (nrow, ncol, [elevation data])
double size[4]; // hfield size (ignore referencing geom size)
int nrow; // number of rows
int ncol; // number of columns
mjFloatVec* userdata; // user-provided elevation data
mjString* info; // message appended to compiler errors
} mjsHField;
typedef struct mjsSkin_ { // skin specification
mjsElement* element; // element type
mjString* name; // name
mjString* classname; // class name
mjString* file; // skin file
mjString* material; // name of material used for rendering
float rgba[4]; // rgba when material is omitted
float inflate; // inflate in normal direction
int group; // group for visualization
// mesh
mjFloatVec* vert; // vertex positions
mjFloatVec* texcoord; // texture coordinates
mjIntVec* face; // faces
// skin
mjStringVec* bodyname; // body names
mjFloatVec* bindpos; // bind pos
mjFloatVec* bindquat; // bind quat
mjIntVecVec* vertid; // vertex ids
mjFloatVecVec* vertweight; // vertex weights
// other
mjString* info; // message appended to compiler errors
} mjsSkin;
typedef struct mjsTexture_ { // texture specification
mjsElement* element; // element type
mjString* name; // name
mjString* classname; // class name
mjtTexture type; // texture type
// method 1: builtin
int builtin; // builtin type (mjtBuiltin)
int mark; // mark type (mjtMark)
double rgb1[3]; // first color for builtin
double rgb2[3]; // second color for builtin
double markrgb[3]; // mark color
double random; // probability of random dots
int height; // height in pixels (square for cube and skybox)
int width; // width in pixels
// method 2: single file
mjString* content_type; // content type of file
mjString* file; // png file to load; use for all sides of cube
int gridsize[2]; // size of grid for composite file; (1,1)-repeat
char gridlayout[13]; // row-major: L,R,F,B,U,D for faces; . for unused
// method 3: separate files
mjStringVec* cubefiles; // different file for each side of the cube
// flip options
mjtByte hflip; // horizontal flip
mjtByte vflip; // vertical flip
// other
mjString* info; // message appended to compiler errors
} mjsTexture;
typedef struct mjsMaterial_ { // material specification
mjsElement* element; // element type
mjString* name; // name
mjString* classname; // class name
mjString* texture; // name of texture (empty: none)
mjtByte texuniform; // make texture cube uniform
float texrepeat[2]; // texture repetition for 2D mapping
float emission; // emission
float specular; // specular
float shininess; // shininess
float reflectance; // reflectance
float metallic; // metallic
float roughness; // roughness
float rgba[4]; // rgba
mjString* info; // message appended to compiler errors
} mjsMaterial;
typedef struct mjsPair_ { // pair specification
mjsElement* element; // element type
mjString* name; // name
mjString* classname; // class name
mjString* geomname1; // name of geom 1
mjString* geomname2; // name of geom 2
// optional parameters: computed from geoms if not set by user
int condim; // contact dimensionality
mjtNum solref[mjNREF]; // solver reference, normal direction
mjtNum solreffriction[mjNREF]; // solver reference, frictional directions
mjtNum solimp[mjNIMP]; // solver impedance
double margin; // margin for contact detection
double gap; // include in solver if dist<margin-gap
double friction[5]; // full contact friction
mjString* info; // message appended to errors
} mjsPair;
typedef struct mjsExclude_ { // exclude specification
mjsElement* element; // element type
mjString* name; // name
mjString* bodyname1; // name of geom 1
mjString* bodyname2; // name of geom 2
mjString* info; // message appended to errors
} mjsExclude;
typedef struct mjsEquality_ { // equality specification
mjsElement* element; // element type
mjString* name; // name
mjString* classname; // class name
mjtEq type; // constraint type
double data[mjNEQDATA]; // type-dependent data
mjtByte active; // is equality initially active
mjString* name1; // name of object 1
mjString* name2; // name of object 2
mjtNum solref[mjNREF]; // solver reference
mjtNum solimp[mjNIMP]; // solver impedance
mjString* info; // message appended to errors
} mjsEquality;
typedef struct mjsTendon_ { // tendon specification
mjsElement* element; // element type
mjString* name; // name
mjString* classname; // class name
// stiffness, damping, friction
double stiffness; // stiffness coefficient
double springlength[2]; // spring resting length; {-1, -1}: use qpos_spring
double damping; // damping coefficient
double frictionloss; // friction loss
mjtNum solref_friction[mjNREF]; // solver reference: tendon friction
mjtNum solimp_friction[mjNIMP]; // solver impedance: tendon friction
// length range
int limited; // does tendon have limits (mjtLimited)
double range[2]; // length limits
double margin; // margin value for tendon limit detection
mjtNum solref_limit[mjNREF]; // solver reference: tendon limits
mjtNum solimp_limit[mjNIMP]; // solver impedance: tendon limits
// visual
mjString* material; // name of material for rendering
double width; // width for rendering
float rgba[4]; // rgba when material is omitted
int group; // group
// other
mjDoubleVec* userdata; // user data
mjString* info; // message appended to errors
} mjsTendon;
typedef struct mjsWrap_ { // wrapping object specification
mjsElement* element; // element type
mjString* info; // message appended to errors
} mjsWrap;
typedef struct mjsActuator_ { // actuator specification
mjsElement* element; // element type
mjString* name; // name
mjString* classname; // class name
// gain, bias
mjtGain gaintype; // gain type
double gainprm[mjNGAIN]; // gain parameters
mjtBias biastype; // bias type
double biasprm[mjNGAIN]; // bias parameters
// activation state
mjtDyn dyntype; // dynamics type
double dynprm[mjNDYN]; // dynamics parameters
int actdim; // number of activation variables
int plugin_actdim; // actuator state size for plugins
mjtByte actearly; // apply next activations to qfrc
// transmission
mjtTrn trntype; // transmission type
double gear[6]; // length and transmitted force scaling
mjString* target; // name of transmission target
mjString* refsite; // reference site, for site transmission
mjString* slidersite; // site defining cylinder, for slider-crank
double cranklength; // crank length, for slider-crank
double lengthrange[2]; // transmission length range
double inheritrange; // automatic range setting for position and intvelocity
// input/output clamping
int ctrllimited; // are control limits defined (mjtLimited)
double ctrlrange[2]; // control range
int forcelimited; // are force limits defined (mjtLimited)
double forcerange[2]; // force range
int actlimited; // are activation limits defined (mjtLimited)
double actrange[2]; // activation range
// other
int group; // group
mjDoubleVec* userdata; // user data
mjsPlugin plugin; // actuator plugin
mjString* info; // message appended to compiler errors
} mjsActuator;
typedef struct mjsSensor_ { // sensor specification
mjsElement* element; // element type
mjString* name; // name
mjString* classname; // class name
// sensor definition
mjtSensor type; // type of sensor
mjtObj objtype; // type of sensorized object
mjString* objname; // name of sensorized object
mjtObj reftype; // type of referenced object
mjString* refname; // name of referenced object
// user-defined sensors
mjtDataType datatype; // data type for sensor measurement
mjtStage needstage; // compute stage needed to simulate sensor
int dim; // number of scalar outputs
// output post-processing
double cutoff; // cutoff for real and positive datatypes
double noise; // noise stdev
// other
mjDoubleVec* userdata; // user data
mjsPlugin plugin; // sensor plugin
mjString* info; // message appended to compiler errors
} mjsSensor;
typedef struct mjsNumeric_ { // custom numeric field specification
mjsElement* element; // element type
mjString* name; // name
mjDoubleVec* data; // initialization data
int size; // array size, can be bigger than data size
mjString* info; // message appended to compiler errors
} mjsNumeric;
typedef struct mjsText_ { // custom text specification
mjsElement* element; // element type
mjString* name; // name
mjString* data; // text string
mjString* info; // message appended to compiler errors
} mjsText;
typedef struct mjsTuple_ { // tuple specification
mjsElement* element; // element type
mjString* name; // name
mjIntVec* objtype; // object types
mjStringVec* objname; // object names
mjDoubleVec* objprm; // object parameters
mjString* info; // message appended to compiler errors
} mjsTuple;
typedef struct mjsKey_ { // keyframe specification
mjsElement* element; // element type
mjString* name; // name
double time; // time
mjDoubleVec* qpos; // qpos
mjDoubleVec* qvel; // qvel
mjDoubleVec* act; // act
mjDoubleVec* mpos; // mocap pos
mjDoubleVec* mquat; // mocap quat
mjDoubleVec* ctrl; // ctrl
mjString* info; // message appended to compiler errors
} mjsKey;
typedef struct mjsDefault_ { // default specification
mjsElement* element; // element type
mjString* name; // class name
mjsJoint* joint; // joint defaults
mjsGeom* geom; // geom defaults
mjsSite* site; // site defaults
mjsCamera* camera; // camera defaults
mjsLight* light; // light defaults
mjsFlex* flex; // flex defaults
mjsMesh* mesh; // mesh defaults
mjsMaterial* material; // material defaults
mjsPair* pair; // pair defaults
mjsEquality* equality; // equality defaults
mjsTendon* tendon; // tendon defaults
mjsActuator* actuator; // actuator defaults
} mjsDefault;
typedef enum mjtTaskStatus_ { // status values for mjTask
mjTASK_NEW = 0, // newly created
mjTASK_QUEUED, // enqueued in a thread pool
@@ -2431,10 +3062,15 @@ int mj_deleteFileVFS(mjVFS* vfs, const char* filename);
void mj_deleteVFS(mjVFS* vfs);
int mj_makeEmptyFileVFS(mjVFS* vfs, const char* filename, int filesize);
mjModel* mj_loadXML(const char* filename, const mjVFS* vfs, char* error, int error_sz);
mjSpec* mj_parseXML(const char* filename, const mjVFS* vfs, char* error, int error_sz);
mjSpec* mj_parseXMLString(const char* xml, const mjVFS* vfs, char* error, int error_sz);
mjModel* mj_compile(mjSpec* s, const mjVFS* vfs);
void mj_recompile(mjSpec* s, const mjVFS* vfs, mjModel* m, mjData* d);
int mj_saveLastXML(const char* filename, const mjModel* m, char* error, int error_sz);
void mj_freeLastXML(void);
int mj_printSchema(const char* filename, char* buffer, int buffer_sz,
int flg_html, int flg_pad);
void mj_copyBack(mjSpec* s, const mjModel* m);
int mj_saveXMLString(const mjSpec* s, char* xml, int xml_sz, char* error, int error_sz);
int mj_saveXML(const mjSpec* s, const char* filename, char* error, int error_sz);
void mj_step(const mjModel* m, mjData* d);
void mj_step1(const mjModel* m, mjData* d);
void mj_step2(const mjModel* m, mjData* d);
@@ -2466,6 +3102,9 @@ void mj_resetCallbacks(void);
void mj_setConst(mjModel* m, mjData* d);
int mj_setLengthRange(mjModel* m, mjData* d, int index,
const mjLROpt* opt, char* error, int error_sz);
mjSpec* mj_makeSpec(void);
mjSpec* mj_copySpec(const mjSpec* s);
void mj_deleteSpec(mjSpec* s);
void mj_printFormattedModel(const mjModel* m, const char* filename, const char* float_format);
void mj_printModel(const mjModel* m, const char* filename);
void mj_printFormattedData(const mjModel* m, mjData* d, const char* filename,
@@ -2474,6 +3113,8 @@ void mj_printData(const mjModel* m, mjData* d, const char* filename);
void mju_printMat(const mjtNum* mat, int nr, int nc);
void mju_printMatSparse(const mjtNum* mat, int nr,
const int* rownnz, const int* rowadr, const int* colind);
int mj_printSchema(const char* filename, char* buffer, int buffer_sz,
int flg_html, int flg_pad);
void mj_fwdPosition(const mjModel* m, mjData* d);
void mj_fwdVelocity(const mjModel* m, mjData* d);
void mj_fwdActuation(const mjModel* m, mjData* d);
@@ -2695,6 +3336,8 @@ void* mju_malloc(size_t size);
void mju_free(void* ptr);
void mj_warning(mjData* d, int warning, int info);
void mju_writeLog(const char* type, const char* msg);
const char* mjs_getError(mjSpec* s);
int mjs_isWarning(mjSpec* s);
void mju_zero3(mjtNum res[3]);
void mju_copy3(mjtNum res[3], const mjtNum data[3]);
void mju_scl3(mjtNum res[3], const mjtNum vec[3], mjtNum scl);
@@ -2838,4 +3481,94 @@ void mju_threadPoolEnqueue(mjThreadPool* thread_pool, mjTask* task);
void mju_threadPoolDestroy(mjThreadPool* thread_pool);
void mju_defaultTask(mjTask* task);
void mju_taskJoin(mjTask* task);
int mjs_attachBody(mjsFrame* parent, const mjsBody* child,
const char* prefix, const char* suffix);
int mjs_attachFrame(mjsBody* parent, const mjsFrame* child,
const char* prefix, const char* suffix);
int mjs_detachBody(mjSpec* s, mjsBody* b);
mjsBody* mjs_addBody(mjsBody* body, mjsDefault* def);
mjsSite* mjs_addSite(mjsBody* body, mjsDefault* def);
mjsJoint* mjs_addJoint(mjsBody* body, mjsDefault* def);
mjsJoint* mjs_addFreeJoint(mjsBody* body);
mjsGeom* mjs_addGeom(mjsBody* body, mjsDefault* def);
mjsCamera* mjs_addCamera(mjsBody* body, mjsDefault* def);
mjsLight* mjs_addLight(mjsBody* body, mjsDefault* def);
mjsFrame* mjs_addFrame(mjsBody* body, mjsFrame* parentframe);
void mjs_delete(mjsElement* element);
mjsActuator* mjs_addActuator(mjSpec* s, mjsDefault* def);
mjsSensor* mjs_addSensor(mjSpec* s);
mjsFlex* mjs_addFlex(mjSpec* s);
mjsPair* mjs_addPair(mjSpec* s, mjsDefault* def);
mjsExclude* mjs_addExclude(mjSpec* s);
mjsEquality* mjs_addEquality(mjSpec* s, mjsDefault* def);
mjsTendon* mjs_addTendon(mjSpec* s, mjsDefault* def);
mjsWrap* mjs_wrapSite(mjsTendon* tendon, const char* name);
mjsWrap* mjs_wrapGeom(mjsTendon* tendon, const char* name, const char* sidesite);
mjsWrap* mjs_wrapJoint(mjsTendon* tendon, const char* name, double coef);
mjsWrap* mjs_wrapPulley(mjsTendon* tendon, double divisor);
mjsNumeric* mjs_addNumeric(mjSpec* s);
mjsText* mjs_addText(mjSpec* s);
mjsTuple* mjs_addTuple(mjSpec* s);
mjsKey* mjs_addKey(mjSpec* s);
mjsPlugin* mjs_addPlugin(mjSpec* s);
mjsDefault* mjs_addDefault(mjSpec* s, const char* classname, int parentid, int* id);
mjsMesh* mjs_addMesh(mjSpec* s, mjsDefault* def);
mjsHField* mjs_addHField(mjSpec* s);
mjsSkin* mjs_addSkin(mjSpec* s);
mjsTexture* mjs_addTexture(mjSpec* s);
mjsMaterial* mjs_addMaterial(mjSpec* s, mjsDefault* def);
mjSpec* mjs_getSpec(mjsBody* body);
mjsBody* mjs_findBody(mjSpec* s, const char* name);
mjsBody* mjs_findChild(mjsBody* body, const char* name);
mjsMesh* mjs_findMesh(mjSpec* s, const char* name);
mjsFrame* mjs_findFrame(mjSpec* s, const char* name);
mjsDefault* mjs_getDefault(mjsElement* element);
mjsDefault* mjs_findDefault(mjSpec* s, const char* classname);
mjsDefault* mjs_getSpecDefault(mjSpec* s);
int mjs_getId(mjsElement* element);
mjsElement* mjs_firstChild(mjsBody* body, mjtObj type);
mjsElement* mjs_nextChild(mjsBody* body, mjsElement* child);
void mjs_setString(mjString* dest, const char* text);
void mjs_setStringVec(mjStringVec* dest, const char* text);
mjtByte mjs_setInStringVec(mjStringVec* dest, int i, const char* text);
void mjs_appendString(mjStringVec* dest, const char* text);
void mjs_setInt(mjIntVec* dest, const int* array, int size);
void mjs_appendIntVec(mjIntVecVec* dest, const int* array, int size);
void mjs_setFloat(mjFloatVec* dest, const float* array, int size);
void mjs_appendFloatVec(mjFloatVecVec* dest, const float* array, int size);
void mjs_setDouble(mjDoubleVec* dest, const double* array, int size);
void mjs_setPluginAttributes(mjsPlugin* plugin, void* attributes);
const char* mjs_getString(const mjString* source);
const double* mjs_getDouble(const mjDoubleVec* source, int* size);
void mjs_setActivePlugins(mjSpec* s, void* activeplugins);
void mjs_setDefault(mjsElement* element, mjsDefault* def);
void mjs_setFrame(mjsElement* dest, mjsFrame* frame);
const char* mjs_resolveOrientation(double quat[4], mjtByte degree, const char* sequence,
const mjsOrientation* orientation);
const char* mjs_fullInertia(double quat[4], double inertia[3], const double fullinertia[6]);
void mjs_defaultSpec(mjSpec* spec);
void mjs_defaultOrientation(mjsOrientation* orient);
void mjs_defaultBody(mjsBody* body);
void mjs_defaultFrame(mjsFrame* frame);
void mjs_defaultJoint(mjsJoint* joint);
void mjs_defaultGeom(mjsGeom* geom);
void mjs_defaultSite(mjsSite* site);
void mjs_defaultCamera(mjsCamera* camera);
void mjs_defaultLight(mjsLight* light);
void mjs_defaultFlex(mjsFlex* flex);
void mjs_defaultMesh(mjsMesh* mesh);
void mjs_defaultHField(mjsHField* hfield);
void mjs_defaultSkin(mjsSkin* skin);
void mjs_defaultTexture(mjsTexture* texture);
void mjs_defaultMaterial(mjsMaterial* material);
void mjs_defaultPair(mjsPair* pair);
void mjs_defaultEquality(mjsEquality* equality);
void mjs_defaultTendon(mjsTendon* tendon);
void mjs_defaultActuator(mjsActuator* actuator);
void mjs_defaultSensor(mjsSensor* sensor);
void mjs_defaultNumeric(mjsNumeric* numeric);
void mjs_defaultText(mjsText* text);
void mjs_defaultTuple(mjsTuple* tuple);
void mjs_defaultKey(mjsKey* key);
void mjs_defaultPlugin(mjsPlugin* plugin);
// NOLINTEND
+18 -10
View File
@@ -36,19 +36,19 @@ mjModel memory buffer. MJCF and URDF files are loaded with :ref:`mj_loadXML` whi
:ref:`mj_loadModel`.
When an XML file is loaded, it is first parsed into a document object model (DOM) using the TinyXML parser internally.
This DOM is then processed and converted into a high-level mjCModel object. The conversion depends on the model format
- which is inferred from the top-level element in the XML file, and not from the file extension. Recall that a valid
XML file has a unique top-level element. This element must be :el:`mujoco` for MJCF, and :el:`robot` for URDF.
This DOM is then processed and converted into a high-level :ref:`mjSpec` object. The conversion depends on the model
format -- which is inferred from the top-level element in the XML file, and not from the file extension. Recall that a
valid XML file has a unique top-level element. This element must be :el:`mujoco` for MJCF, and :el:`robot` for URDF.
.. _Compile:
Compiling models
~~~~~~~~~~~~~~~~
Once a high-level mjCModel is created---by loading an MJCF file or a URDF file, or programmatically when such
functionality becomes available---it is compiled into mjModel. Even though loading and compilation are presently
combined in one step, compilation is independent of loading, meaning that the compiler works in the same way
regardless of how mjCModel was created. Both the parser and the compiler perform extensive error checking, and abort
Once a high-level :ref:`mjSpec` is created---by loading an MJCF file or a URDF file, or
:doc:`programmatically<programming/modeledit>`---it is compiled into :ref:`mjModel`.
Compilation is independent of loading, meaning that the compiler works in the same way regardless of how :ref:`mjSpec`
was created. Both the parser and the compiler perform extensive error checking, and abort
when the first error is encountered. The resulting error messages contain the row and column number in the XML file,
and are self-explanatory so we do not document them here. The parser uses a custom schema to make sure that the file
structure, elements and attributes are valid. The compiler then applies many additional semantic checks. Finally, one
@@ -72,9 +72,9 @@ binary MJB file with :ref:`mj_saveModel`. The MJB is a stand-alone file and does
refer to any other files. It also loads faster. So we recommend saving commonly used models as MJB and loading them
when needed for simulation.
It is also possible to save a compiled mjCModel as MJCF with :ref:`mj_saveLastXML`. If any real-valued fields in the
corresponding mjModel were modified after compilation (which is unusual but can happen in system identification
applications for example), the modifications are automatically copied back into mjCModel before saving. Note that
It is also possible to save a compiled :ref:`mjSpec` as MJCF with :ref:`mj_saveLastXML`. If any real-valued fields in
the corresponding mjModel were modified after compilation (which is unusual but can happen in system identification
applications for example), the modifications are automatically copied back into :ref:`mjSpec` before saving. Note that
structural changes cannot be made in the compiled model. The XML writer attempts to generate the smallest MJCF file
which is guaranteed to compile into the same model, modulo negligible numeric differences caused by the plain text
representation of real values. The resulting file may not have the same structure as the original because MJCF has many
@@ -83,6 +83,14 @@ subset of MJCF where all coordinates are local and all body positions, orientati
explicitly specified. In the Computation chapter we showed an `example <_static/example.xml>`__ MJCF file and the
corresponding `saved example <_static/example_saved.xml>`__.
.. _EditModel:
Editing models
~~~~~~~~~~~~~~
As of MuJoCo 3.2, it is possible to create and modify models using the :ref:`mjSpec` struct and related API.
For further documentation, please see the :doc:`Model Editing<programming/modeledit>` chapter.
.. _Mechanisms:
MJCF Mechanisms
+18 -20
View File
@@ -141,32 +141,30 @@ There are several entities called "model" in MuJoCo. The user defines the model
The software can then create multiple instances of the same model in different media (file or memory) and on different
levels of description (high or low). All combinations are possible as shown in the following table:
+------------+----------------------+----------------------+
| | High level | Low level |
+============+======================+======================+
| **File** | MJCF/URDF (XML) | MJB (binary) |
+------------+----------------------+----------------------+
| **Memory** | mjCModel (C++ class) | mjModel (C struct) |
+------------+----------------------+----------------------+
+------------+---------------------------+----------------------------+
| | High level | Low level |
+============+===========================+============================+
| **File** | MJCF/URDF (XML) | MJB (binary) |
+------------+---------------------------+----------------------------+
| **Memory** | :ref:`mjSpec` (C struct) | :ref:`mjModel` (C struct) |
+------------+---------------------------+----------------------------+
All runtime computations are performed with ``mjModel`` which is too complex to create manually. This is why we have two
levels of modeling. The high level exists for user convenience: its sole purpose is to be compiled into a low level
model on which computations can be performed. The resulting ``mjModel`` can be loaded and saved into a binary file
All runtime computations are performed with :ref:`mjModel` which is too complex to create manually. This is why we have
two levels of modeling. The high level exists for user convenience: its sole purpose is to be compiled into a low level
model on which computations can be performed. The resulting :ref:`mjModel` can be loaded and saved into a binary file
(MJB), however those are version-specific and cannot be decompiled, thus models should always be maintained as XML
files.
The (internal) C++ class ``mjCModel`` is roughly in one-to-one correspondence with the MJCF file format. The XML parser
interprets the MJCF or URDF file and creates the corresponding ``mjCModel``. In principle the user can create
``mjCModel`` programmatically and then save it to MJCF or compile it. However this functionality is not yet exposed
because a C++ API cannot be exported from a compiler-independent library. There is a plan to develop a C wrapper around
it, but for the time being the parser and compiler are always invoked together, and models can only be created in XML.
The :ref:`mjSpec` C struct is in one-to-one correspondence with the MJCF file format. The XML loader interprets the MJCF
or URDF file, creates the corresponding :ref:`mjSpec` and compiles it to :ref:`mjModel`. The user can create
:ref:`mjSpec` programmatically and then save it to MJCF or compile it. Procedural model creation and editing is
described in the :doc:`Model Editing <programming/modeledit>` chapter.
The following diagram shows the different paths to obtaining an ``mjModel`` (again, the second bullet point is not yet
available):
The following diagram shows the different paths to obtaining an :ref:`mjModel`:
- (text editor) → MJCF/URDF file → (MuJoCo parser → mjCModel → MuJoCo compiler) → mjModel
- (user code) → mjCModel → (MuJoCo compiler) → mjModel
- MJB file → (MuJoCo loader) → mjModel
- (text editor) → MJCF/URDF file → (MuJoCo parser → mjSpec → compiler) → mjModel
- (user code) → mjSpec → (MuJoCo compiler) → mjModel
- MJB file → (model loader) → mjModel
.. _Examples:
+14 -7
View File
@@ -18,7 +18,7 @@ Engine
The simulator (or physics engine) is written in C. It is responsible for all runtime computations.
Parser
The XML parser is written in C++. It can parse MJCF models and URDF models, converting them into an internal mjCModel
C++ object which is not directly exposed to the user.
C++ object which is exposed to the user via mjSpec.
Compiler
The compiler is written in C++. It takes an mjCModel C++ object constructed by the parser, and converts it into an
mjModel C structure used at runtime.
@@ -108,10 +108,10 @@ Building from source
To build MuJoCo from source, you will need CMake and a working C++17 compiler installed. The steps are:
#. Clone the ``mujoco`` repository from GitHub.
#. Create a new build directory somewhere, and ``cd`` into it.
#. Run ``cmake $PATH_TO_CLONED_REPO`` to configure the build.
#. Run ``cmake --build .`` to build.
#. Clone the ``mujoco`` repository from GitHub.
#. Create a new build directory somewhere, and ``cd`` into it.
#. Run ``cmake $PATH_TO_CLONED_REPO`` to configure the build.
#. Run ``cmake --build .`` to build.
MuJoCo's build system automatically fetches dependencies from upstream repositories over the Internet using CMake's
`FetchContent <https://cmake.org/cmake/help/latest/module/FetchContent.html>`_ module.
@@ -123,8 +123,8 @@ section of the documentation.
Additionally, the CMake setup also implements an installation phase which will copy and organize the output files to a
target directory.
5. Select the directory: ``cmake $PATH_TO_CLONED_REPO -DCMAKE_INSTALL_PREFIX=<my_install_dir>``
#. After building, install with ``cmake --install .``
5. Select the directory: ``cmake $PATH_TO_CLONED_REPO -DCMAKE_INSTALL_PREFIX=<my_install_dir>``
#. After building, install with ``cmake --install .``
When building on Windows, use Visual Studio 2019 or later and make sure Windows SDK version 10.0.22000 or later is
installed (see `here <https://github.com/google-deepmind/mujoco/issues/862>`__ for more details).
@@ -160,6 +160,8 @@ links below, to make this documentation self-contained.
Defines the primitive types and structures needed by the UI framework.
`mjtnum.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjtnum.h>`__
Defines MuJoCo's ``mjtNum`` floating-point type to be either ``double`` or ``float``. See :ref:`mjtNum`.
`mjspec.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjspec.h>`__
Defines enums and structs used for :doc:`procedural model editing <modeledit>`.
`mjmacro.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjmacro.h>`__
Defines C macros that are useful in user code.
`mjxmacro.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjxmacro.h>`__
@@ -226,6 +228,8 @@ to which the symbol belongs. First we list the prefixes corresponding to type de
Data structure related to OpenGL rendering, for example :ref:`mjrContext`.
``mjui``
Data structure related to UI framework, for example :ref:`mjuiSection`.
``mjs``
Data structure related :doc:`procedural model editing <modeledit>`, for example :ref:`mjsJoint`.
Next we list the prefixes corresponding to function definitions. Note that function prefixes always end with underscore.
@@ -247,6 +251,8 @@ Next we list the prefixes corresponding to function definitions. Note that funct
custom callbacks by setting these global pointers to user-defined functions.
``mjd_``
Functions for computing derivatives, for example :ref:`mjd_transitionFD`.
``mjs_``
Functions for :doc:`procedural model editing <modeledit>`, for example :ref:`mjs_addJoint`.
.. _inOpenGL:
@@ -276,5 +282,6 @@ now lazily resolved at runtime after the switch to GLAD, the "nogl" libraries ar
simulation
visualization
ui
modeledit
samples
extension
+44
View File
@@ -0,0 +1,44 @@
Model Editing
-------------
.. admonition:: Unstable API
:class: attention
The API described below is new and unstable. There may be latent bugs and function signatures may change. Early
adopters are welcome (indeed, encouraged) to try it out and report any issues on GitHub.
As of MuJoCo 3.2, it is possible to create and modify models using the :ref:`mjSpec` struct and related API.
This datastructure is in one-to-one correspondence with MJCF and indeed, MuJoCo's own XML parsers (both MJCF and URDF)
use this API when loading a model.
.. _meOverview:
Overview
~~~~~~~~
As summarized in the the :ref:`Overview chapter<Instance>`, the traditional workflow to create compiled :ref:`mjModel`
instances is:
1. Create an XML model description file (MJCF or URDF).
2. Call :ref:`mj_loadXML` passing in the XML (and associated assets), obtain an :ref:`mjModel` instance.
The new workflow looks like:
1. Create an :ref:`mjSpec`, either an empty one corresponding to the XML ``<mujoco/>``, or by loading an existing XML
file.
2. Modify the :ref:`mjSpec` as desired, adding, editing and removing elements.
3. Compile the :ref:`mjSpec` at any point, obtaining an updated :ref:`mjModel` instance. After compilation, the
:ref:`mjSpec` remains editable, so steps 2 and 3 are interchangable.
.. _meUsage:
Usage
~~~~~
Detailed documentation is still missing. In the meantime, advanced users can refer to
`user_api_test.cc <https://github.com/google-deepmind/mujoco/blob/main/test/user/user_api_test.cc>`__ and the MJCF
parser in `xml_native_reader.cc <https://github.com/google-deepmind/mujoco/blob/main/src/xml/xml_native_reader.cc>`__,
which is already using this API.
+2 -2
View File
@@ -585,8 +585,8 @@ corresponding to precomputed quantities when the model is in the reference confi
Finally, if changes are made to mjModel at runtime, it may be desirable to save them back to the XML. The function
:ref:`mj_saveLastXML` does that in a limited sense: it copies all real-valued parameters from mjModel back to the
internal mjCModel, and then saves it as XML. This does not cover all possible changes that the user could have made.
The only way to guarantee that all changes are saved is to save the model as a binary MJB file with the function
internal :ref:`mjSpec`, and then saves it as XML. This does not cover all possible changes that the user could have
made. The only way to guarantee that all changes are saved is to save the model as a binary MJB file with the function
:ref:`mj_saveModel`, or even better, make the changes directly in the XML. Unfortunately there are situations where
changes need to be made programmatically, as in system identification for example, and this can only be done with the
compiled model. So in summary, we have reasonable but not perfect mechanisms for saving model changes. The reason for