Version 2.1.2: Python bindings, OBJ assets support, bugfixes.

PiperOrigin-RevId: 434731612
Change-Id: I0cfda3e7a3d1c72036764986efc252ffa1b8c6b0
This commit is contained in:
Saran Tunyasuvunakool
2022-03-15 14:04:44 +00:00
parent 175d25cd9f
commit 3577e2cf8b
304 changed files with 23906 additions and 1013 deletions
+137 -53
View File
@@ -23,7 +23,7 @@ MuJoCo defines a large number of primitive types described here. Except for :ref
rest of the API does not use these enum types directly. Instead it uses ints, and only the documentation/comments state
that certain ints correspond to certain enum types. This is because we want the API to be compiler-independent, and the
C standard does not dictate how many bytes must be used to represent an enum type. Nevertheless we recommend using these
types when calling the API functions (and letting the compiler do the enum-to-int type cast.)
types when calling the API functions (and letting the compiler do the enum-to-int type cast).
.. _mjtNum:
@@ -38,7 +38,8 @@ mjtNum
typedef float mjtNum;
#endif
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| Defined in `mjtnum.h <https://github.com/deepmind/mujoco/blob/main/include/mjtnum.h>`_
| This is the floating-point type used throughout the simulator. If the symbol ``mjUSEDOUBLE`` is defined in
``mjmodel.h``, this type is defined as ``double``, otherwise it is defined as ``float``. Currently only the
double-precision version of MuJoCo is distributed, although the entire code base works with single-precision as well.
@@ -47,7 +48,7 @@ mjtNum
write code that works with either single or double precision. To this end we provide math utility functions that are
always defined with the correct floating-point type.
| Note that changing ``mjUSEDOUBLE`` in ``mjmodel.h`` will not change how the library was compiled, and instead will
| Note that changing ``mjUSEDOUBLE`` in ``mjtnum.h`` will not change how the library was compiled, and instead will
result in numerous link errors. In general, the header files distributed with precompiled MuJoCo should never be
changed by the user.
@@ -61,6 +62,7 @@ mjtByte
typedef unsigned char mjtByte;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| Byte type used to represent boolean variables.
.. _mjtDisableBit:
@@ -89,6 +91,7 @@ mjtDisableBit
} mjtDisableBit;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| Constants which are powers of 2. They are used as bitmasks for the field ``disableflags`` of :ref:`mjOption`.
At runtime this field is ``m->opt.disableflags``. The number of these constants is given by ``mjNDISABLE`` which is
also the length of the global string array :ref:`mjDISABLESTRING` with text descriptions of these
@@ -112,6 +115,7 @@ mjtEnableBit
} mjtEnableBit;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| Constants which are powers of 2. They are used as bitmasks for the field ``enableflags`` of :ref:`mjOption`.
At runtime this field is ``m->opt.enableflags``. The number of these constants is given by ``mjNENABLE`` which is also
the length of the global string array :ref:`mjENABLESTRING` with text descriptions of these flags.
@@ -132,6 +136,7 @@ mjtJoint
} mjtJoint;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| Primitive joint types. These values are used in ``m->jnt_type``. The numbers in the comments indicate how many
positional coordinates each joint type has. Note that ball joints and rotational components of free joints are
represented as unit quaternions - which have 4 positional coordinates but 3 degrees of freedom each.
@@ -169,6 +174,7 @@ mjtGeom
} mjtGeom;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| Geometric types supported by MuJoCo. The first group are "official" geom types that can be used in the model. The
second group are geom types that cannot be used in the model but are used by the visualizer to add decorative
elements. These values are used in ``m->geom_type`` and ``m->site_type``.
@@ -190,6 +196,7 @@ mjtCamLight
} mjtCamLight;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| Dynamic modes for cameras and lights, specifying how the camera/light position and orientation are computed. These
values are used in ``m->cam_mode`` and ``m->light_mode``.
@@ -208,6 +215,7 @@ mjtTexture
} mjtTexture;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| Texture types, specifying how the texture will be mapped. These values are used in ``m->tex_type``.
.. _mjtIntegrator:
@@ -224,6 +232,7 @@ mjtIntegrator
} mjtIntegrator;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| Numerical integrator types. These values are used in ``m->opt.integrator``.
.. _mjtCollision:
@@ -241,7 +250,8 @@ mjtCollision
} mjtCollision;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| Collision modes specifying how candidate geom pair are generated for near-phase collision checking. These values are
| Collision modes specifying how candidate geom pairs are generated for near-phase collision checking. These values are
used in ``m->opt.collision``.
.. _mjtCone:
@@ -258,6 +268,7 @@ mjtCone
} mjtCone;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| Available friction cone types. These values are used in ``m->opt.cone``.
.. _mjtJacobian:
@@ -275,6 +286,7 @@ mjtJacobian
} mjtJacobian;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| Available Jacobian types. These values are used in ``m->opt.jacobian``.
.. _mjtSolver:
@@ -292,6 +304,7 @@ mjtSolver
} mjtSolver;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| Available constraint solver algorithms. These values are used in ``m->opt.solver``.
.. _mjtEq:
@@ -311,6 +324,7 @@ mjtEq
} mjtEq;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| Equality constraint types. These values are used in ``m->eq_type``.
.. _mjtWrap:
@@ -331,6 +345,7 @@ mjtWrap
} mjtWrap;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| Tendon wrapping object types. These values are used in ``m->wrap_type``.
.. _mjtTrn:
@@ -352,6 +367,7 @@ mjtTrn
} mjtTrn;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| Actuator transmission types. These values are used in ``m->actuator_trntype``.
.. _mjtDyn:
@@ -371,6 +387,7 @@ mjtDyn
} mjtDyn;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| Actuator dynamics types. These values are used in ``m->actuator_dyntype``.
.. _mjtGain:
@@ -388,6 +405,7 @@ mjtGain
} mjtGain;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| Actuator gain types. These values are used in ``m->actuator_gaintype``.
.. _mjtBias:
@@ -406,6 +424,7 @@ mjtBias
} mjtBias;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| Actuator bias types. These values are used in ``m->actuator_biastype``.
.. _mjtObj:
@@ -444,6 +463,7 @@ mjtObj
} mjtObj;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| MuJoCo object types. These values are used in the support functions :ref:`mj_name2id` and
:ref:`mj_id2name` to convert between object names and integer ids.
@@ -467,6 +487,7 @@ mjtConstraint
} mjtConstraint;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| Constraint types. These values are not used in mjModel, but are used in the mjData field ``d->efc_type`` when the list
of active constraints is constructed at each simulation time step.
@@ -487,6 +508,7 @@ mjtConstraintState
} mjtConstraintState;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| These values are used by the solver internally to keep track of the constraint states.
.. _mjtSensor:
@@ -550,6 +572,7 @@ mjtSensor
} mjtSensor;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| Sensor types. These values are used in ``m->sensor_type``.
.. _mjtStage:
@@ -568,6 +591,7 @@ mjtStage
} mjtStage;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| These are the compute stages for the skipstage parameters of :ref:`mj_forwardSkip` and
:ref:`mj_inverseSkip`.
@@ -587,6 +611,7 @@ mjtDataType
} mjtDataType;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| These are the possible sensor data types, used in ``mjData.sensor_datatype``.
.. _mjtWarning:
@@ -611,6 +636,7 @@ mjtWarning
} mjtWarning;
| Defined in `mjdata.h <https://github.com/deepmind/mujoco/blob/main/include/mjdata.h>`_
| Warning types. The number of warning types is given by ``mjNWARNING`` which is also the length of the array
``mjData.warning``.
@@ -646,6 +672,7 @@ mjtTimer
} mjtTimer;
| Defined in `mjdata.h <https://github.com/deepmind/mujoco/blob/main/include/mjdata.h>`_
| Timer types. The number of timer types is given by ``mjNTIMER`` which is also the length of the array
``mjData.timer``, as well as the length of the string array :ref:`mjTIMERSTRING` with timer names.
@@ -665,6 +692,7 @@ mjtCatBit
} mjtCatBit;
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
| These are the available categories of geoms in the abstract visualizer. The bitmask can be used in the function
:ref:`mjr_render` to specify which categories should be rendered.
@@ -687,8 +715,9 @@ mjtMouse
} mjtMouse;
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
| These are the mouse actions that the abstract visualizer recognizes. It is up to the user to intercept mouse events
and translate them into these actions, as illustrated in simulate.cc.
and translate them into these actions, as illustrated in ``simulate.cc``.
.. _mjtPertBit:
@@ -704,8 +733,9 @@ mjtPertBit
} mjtPertBit;
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
| These bitmasks enable the translational and rotational components of the mouse perturbation. For the regular mouse,
only one can be enabled at a time. For the 3D mouse (SpaceNavigator) both can be enabled simultaneously. Tehy are used
only one can be enabled at a time. For the 3D mouse (SpaceNavigator) both can be enabled simultaneously. They are used
in ``mjvPerturb.active``.
.. _mjtCamera:
@@ -724,6 +754,7 @@ mjtCamera
} mjtCamera;
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
| These are the possible camera types, used in ``mjvCamera.type``.
.. _mjtLabel:
@@ -754,6 +785,7 @@ mjtLabel
} mjtLabel;
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
| These are the abstract visualization elements that can have text labels. Used in ``mjvOption.label``.
.. _mjtFrame:
@@ -777,6 +809,7 @@ mjtFrame
} mjtFrame;
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
| These are the MuJoCo objects whose spatial frames can be rendered. Used in ``mjvOption.frame``.
.. _mjtVisFlag:
@@ -815,6 +848,7 @@ mjtVisFlag
} mjtVisFlag;
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
| These are indices in the array ``mjvOption.flags``, whose elements enable/disable the visualization of the
corresponding model or decoration element.
@@ -841,6 +875,7 @@ mjtRndFlag
} mjtRndFlag;
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
| These are indices in the array ``mjvScene.flags``, whose elements enable/disable OpenGL rendering effects.
.. _mjtStereo:
@@ -858,6 +893,7 @@ mjtStereo
} mjtStereo;
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
| These are the possible stereo rendering types. They are used in ``mjvScene.stereo``.
.. _mjtGridPos:
@@ -876,6 +912,7 @@ mjtGridPos
} mjtGridPos;
| Defined in `mjrender.h <https://github.com/deepmind/mujoco/blob/main/include/mjrender.h>`_
| These are the possible grid positions for text overlays. They are used as an argument to the function
:ref:`mjr_overlay`.
@@ -893,6 +930,7 @@ mjtFramebuffer
} mjtFramebuffer;
| Defined in `mjrender.h <https://github.com/deepmind/mujoco/blob/main/include/mjrender.h>`_
| These are the possible framebuffers. They are used as an argument to the function :ref:`mjr_setBuffer`.
.. _mjtFontScale:
@@ -913,6 +951,7 @@ mjtFontScale
} mjtFontScale;
| Defined in `mjrender.h <https://github.com/deepmind/mujoco/blob/main/include/mjrender.h>`_
| These are the possible font sizes. The fonts are predefined bitmaps stored in the dynamic library at three different
sizes.
@@ -931,6 +970,7 @@ mjtFont
} mjtFont;
| Defined in `mjrender.h <https://github.com/deepmind/mujoco/blob/main/include/mjrender.h>`_
| These are the possible font types.
.. _mjtButton:
@@ -949,6 +989,7 @@ mjtButton
} mjtButton;
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mjui.h>`_
| Mouse button IDs used in the UI framework.
.. _mjtEvent:
@@ -970,6 +1011,7 @@ mjtEvent
} mjtEvent;
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mjui.h>`_
| Event types used in the UI framework.
.. _mjtItem:
@@ -1002,6 +1044,7 @@ mjtItem
} mjtItem;
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mjui.h>`_
| Item types used in the UI framework.
.. _tyFunction:
@@ -1118,6 +1161,7 @@ mjVFS
typedef struct _mjVFS mjVFS;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| This is the data structure with the virtual file system. It can only be constructed programmatically, and does not
have an analog in MJCF.
@@ -1167,6 +1211,7 @@ mjOption
typedef struct _mjOption mjOption;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| This is the data structure with simulation options. It corresponds to the MJCF element
:ref:`option <option>`. One instance of it is embedded in mjModel.
@@ -1272,6 +1317,7 @@ mjVisual
typedef struct _mjVisual mjVisual;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| This is the data structure with abstract visualization options. It corresponds to the MJCF element
:ref:`visual <visual>`. One instance of it is embedded in mjModel.
@@ -1293,6 +1339,7 @@ mjStatistic
typedef struct _mjStatistic mjStatistic;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| This is the data structure with model statistics precomputed by the compiler or set by the user. It corresponds to the
MJCF element :ref:`statistic <statistic>`. One instance of it is embedded in mjModel.
@@ -1641,6 +1688,8 @@ mjModel
int* sensor_needstage; // required compute stage (mjtStage) (nsensor x 1)
int* sensor_objtype; // type of sensorized object (mjtObj) (nsensor x 1)
int* sensor_objid; // id of sensorized object (nsensor x 1)
int* sensor_reftype; // type of reference frame (mjtObj) (nsensor x 1)
int* sensor_refid; // id of reference frame; -1: global frame (nsensor x 1)
int* sensor_dim; // number of scalar outputs (nsensor x 1)
int* sensor_adr; // address in sensor array (nsensor x 1)
mjtNum* sensor_cutoff; // cutoff for real and positive; 0: ignore (nsensor x 1)
@@ -1699,6 +1748,7 @@ mjModel
typedef struct _mjModel mjModel;
| Defined in `mjmodel.h <https://github.com/deepmind/mujoco/blob/main/include/mjmodel.h>`_
| This is the main data structure holding the MuJoCo model. It is treated as constant by the simulator.
.. _mjContact:
@@ -1739,6 +1789,7 @@ mjContact
typedef struct _mjContact mjContact;
| Defined in `mjdata.h <https://github.com/deepmind/mujoco/blob/main/include/mjdata.h>`_
| This is the data structure holding information about one contact. ``mjData.contact`` is a preallocated array of
mjContact data structures, populated at runtime with the contacts found by the collision detector. Additional contact
information is then filled-in by the simulator.
@@ -1758,6 +1809,7 @@ mjWarningStat
typedef struct _mjWarningStat mjWarningStat;
| Defined in `mjdata.h <https://github.com/deepmind/mujoco/blob/main/include/mjdata.h>`_
| This is the data structure holding information about one warning type. ``mjData.warning`` is a preallocated array of
mjWarningStat data structures, one for each warning type.
@@ -1776,6 +1828,7 @@ mjTimerStat
typedef struct _mjTimerStat mjTimerStat;
| Defined in `mjdata.h <https://github.com/deepmind/mujoco/blob/main/include/mjdata.h>`_
| This is the data structure holding information about one timer. ``mjData.timer`` is a preallocated array of
mjTimerStat data structures, one for each timer type.
@@ -1799,6 +1852,7 @@ mjSolverStat
typedef struct _mjSolverStat mjSolverStat;
| Defined in `mjdata.h <https://github.com/deepmind/mujoco/blob/main/include/mjdata.h>`_
| This is the data structure holding information about one solver iteration. ``mjData.solver`` is a preallocated array
of mjSolverStat data structures, one for each iteration of the solver, up to a maximum of mjNSOLVER. The actual number
of solver iterations is given by ``mjData.solver_iter``.
@@ -1861,19 +1915,19 @@ mjData
mjtNum* qfrc_applied; // applied generalized force (nv x 1)
mjtNum* xfrc_applied; // applied Cartesian force/torque (nbody x 6)
// dynamics
mjtNum* qacc; // acceleration (nv x 1)
mjtNum* act_dot; // time-derivative of actuator activation (na x 1)
// mocap data
mjtNum* mocap_pos; // positions of mocap bodies (nmocap x 3)
mjtNum* mocap_quat; // orientations of mocap bodies (nmocap x 4)
// dynamics
mjtNum* qacc; // acceleration (nv x 1)
mjtNum* act_dot; // time-derivative of actuator activation (na x 1)
// user data
mjtNum* userdata; // user data, not touched by engine (nuserdata x 1)
mjtNum* userdata; // user data, not touched by engine (nuserdata x 1)
// sensors
mjtNum* sensordata; // sensor data array (nsensordata x 1)
mjtNum* sensordata; // sensor data array (nsensordata x 1)
//-------------------------------- POSITION dependent
@@ -2005,6 +2059,7 @@ mjData
typedef struct _mjData mjData;
| Defined in `mjdata.h <https://github.com/deepmind/mujoco/blob/main/include/mjdata.h>`_
| This is the main data structure holding the simulation state. It is the workspace where all functions read their
modifiable inputs and write their outputs.
@@ -2028,6 +2083,7 @@ mjvPerturb
typedef struct _mjvPerturb mjvPerturb;
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
| This is the data structure holding information about mouse perturbations.
.. _mjvCamera:
@@ -2053,6 +2109,7 @@ mjvCamera
typedef struct _mjvCamera mjvCamera;
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
| This is the data structure describing one abstract camera.
.. _mjvGLCamera:
@@ -2079,6 +2136,7 @@ mjvGLCamera
typedef struct _mjvGLCamera mjvGLCamera;
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
| This is the data structure describing one OpenGL camera.
.. _mjvGeom:
@@ -2121,6 +2179,7 @@ mjvGeom
typedef struct _mjvGeom mjvGeom;
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
| This is the data structure describing one abstract visualization geom - which could correspond to a model geom or to a
decoration element constructed by the visualizer.
@@ -2148,6 +2207,7 @@ mjvLight
typedef struct _mjvLight mjvLight;
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
| This is the data structure describing one OpenGL light.
.. _mjvOption:
@@ -2171,6 +2231,7 @@ mjvOption
typedef struct _mjvOption mjvOption;
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
| This structure contains options that enable and disable the visualization of various elements.
.. _mjvScene:
@@ -2198,7 +2259,7 @@ mjvScene
// OpenGL lights
int nlight; // number of lights currently in buffer
mjvLight lights[8]; // buffer for lights
mjvLight lights[mjMAXLIGHT]; // buffer for lights
// OpenGL cameras
mjvGLCamera camera[2]; // left and right camera
@@ -2216,6 +2277,7 @@ mjvScene
typedef struct _mjvScene mjvScene;
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
| This structure contains everything needed to render the 3D scene in OpenGL.
.. _mjvFigure:
@@ -2269,6 +2331,7 @@ mjvFigure
typedef struct _mjvFigure mjvFigure;
| Defined in `mjvisualize.h <https://github.com/deepmind/mujoco/blob/main/include/mjvisualize.h>`_
| This structure contains everything needed to render a 2D plot in OpenGL. The buffers for line points etc. are
preallocated, and the user has to populate them before calling the function :ref:`mjr_figure` with this
data structure as an argument.
@@ -2290,6 +2353,7 @@ mjrRect
typedef struct _mjrRect mjrRect;
| Defined in `mjrender.h (57) <https://github.com/deepmind/mujoco/blob/main/include/mjrender.h#L57>`_
| This structure specifies a rectangle.
.. _mjrContext:
@@ -2384,6 +2448,7 @@ mjrContext
typedef struct _mjrContext mjrContext;
| Defined in `mjrender.h (67) <https://github.com/deepmind/mujoco/blob/main/include/mjrender.h#L67>`_
| This structure contains the custom OpenGL rendering context, with the ids of all OpenGL resources uploaded to the GPU.
.. _mjuiState:
@@ -2434,6 +2499,7 @@ mjuiState
typedef struct _mjuiState mjuiState;
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mjui.h>`_
| This structure contains the keyboard and mouse state used by the UI framework.
.. _mjuiThemeSpacing:
@@ -2460,6 +2526,7 @@ mjuiThemeSpacing
typedef struct _mjuiThemeSpacing mjuiThemeSpacing;
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mjui.h>`_
| This structure defines the spacing of UI items in the theme.
.. _mjuiThemeColor:
@@ -2496,6 +2563,7 @@ mjuiThemeColor
typedef struct _mjuiThemeColor mjuiThemeColor;
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mjui.h>`_
| This structure defines the colors of UI items in the theme.
.. _mjuiItem:
@@ -2553,6 +2621,7 @@ mjuiItem
typedef struct _mjuiItem mjuiItem;
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mjui.h>`_
| This structure defines one UI item.
.. _mjuiSection:
@@ -2579,6 +2648,7 @@ mjuiSection
typedef struct _mjuiSection mjuiSection;
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mjui.h>`_
| This structure defines one section of the UI.
.. _mjUI:
@@ -2625,6 +2695,7 @@ mjUI
typedef struct _mjUI mjUI;
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mjui.h>`_
| This structure defines the entire UI.
.. _mjuiDef:
@@ -2645,6 +2716,7 @@ mjuiDef
typedef struct _mjuiDef mjuiDef;
| Defined in `mjui.h <https://github.com/deepmind/mujoco/blob/main/include/mjui.h>`_
| This structure defines one entry in the definition table used for simplified UI construction.
.. _tyXMacro:
@@ -2717,7 +2789,7 @@ Global variables
Error callbacks
^^^^^^^^^^^^^^^
All user callbacks (i.e. global function pointers whose name starts with 'mjcb') are initially set to NULL, which
All user callbacks (i.e., global function pointers whose name starts with 'mjcb') are initially set to NULL, which
disables them and allows the default processing to take place. To install a callback, simply set the corresponding
global pointer to a user function of the correct type. Keep in mind that these are global and not model-specific. So if
you are simulating multiple models in parallel, they use the same set of callbacks.
@@ -2732,7 +2804,7 @@ mju_user_error
extern void (*mju_user_error)(const char*);
This is called from within the main error function :ref:`mju_error`. When installed, this function overrides the default
error processing. Once it prints error mesages (or whatever else the user wants to do), it must **exit** the program.
error processing. Once it prints error messages (or whatever else the user wants to do), it must **exit** the program.
MuJoCo is written with the assumption that mju_error will not return. If it does, the behavior of the software is
undefined.
@@ -2878,7 +2950,7 @@ mjcb_time
extern mjfTime mjcb_time;
Installing this callback enables the built-in profiler, and keeps timing statistics in ``mjData.timer``. The return type
is mjtNum, while the time units are up to the user. simulate.cc assumes the unit is 1 millisecond. In order to be
is mjtNum, while the time units are up to the user. ``simulate.cc`` assumes the unit is 1 millisecond. In order to be
useful, the callback should use high-resolution timers with at least microsecond precision. This is because the
computations being timed are very fast.
@@ -3022,7 +3094,7 @@ mjVISSTRING
| [1]: the string "0" or "1" indicating if the flag is on or off by default, as set by
:ref:`mjv_defaultOption`;
| [2]: one-character string with a suggested keyboard shortcut, used in simulate.cc.
| [2]: one-character string with a suggested keyboard shortcut, used in ``simulate.cc``.
.. _mjRNDSTRING:
@@ -3156,8 +3228,8 @@ API functions
The main header `mujoco.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco.h>`_ exposes a very large number
of functions. However the functions that most users are likely to need are a small fraction. For example,
``simulate.cc`` which is as elaborate as a MuJoCo application is likely to get, calls around 40 of these functions,
while basic.cc calls around 20. The rest are explosed just in case someone has a use for them. This includes us as users
of MuJoCo -- we do our own work with the public library instead of relying on internal builds.
while ``basic.cc`` calls around 20. The rest are explosed just in case someone has a use for them. This includes us as
users of MuJoCo -- we do our own work with the public library instead of relying on internal builds.
.. _Activation:
@@ -3672,9 +3744,9 @@ mj_printFormattedModel
.. code-block:: C
void mj_printFormattedModel(const mjModel* m, const char* filename, const char* float_format_str);
void mj_printFormattedModel(const mjModel* m, const char* filename, const char* float_format);
Print ``mjModel`` to text file, specifying format. ``float_format_str`` must be a valid printf-style format string for a
Print ``mjModel`` to text file, specifying format. ``float_format`` must be a valid printf-style format string for a
single float value.
.. _mj_printModel:
@@ -3688,6 +3760,18 @@ mj_printModel
Print model to text file.
.. _mj_printFormattedData:
mj_printFormattedData
~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: C
void mj_printFormattedData(const mjModel* m, mjData* d, const char* filename, const char* float_format);
Print ``mjData`` to text file, specifying format. ``float_format`` must be a valid printf-style format string for a
single float value.
.. _mj_printData:
mj_printData
@@ -4140,7 +4224,7 @@ mj_constraintUpdate
.. code-block:: C
void mj_constraintUpdate(const mjModel* m, mjData* d, const mjtNum* jar,
mjtNum* cost, int flg_coneHessian);
mjtNum cost[1], int flg_coneHessian);
Compute efc_state, efc_force, qfrc_constraint, and (optionally) cone Hessians. If cost is not NULL, set \*cost = s(jar)
where jar = Jac*qacc-aref.
@@ -4380,8 +4464,8 @@ mj_applyFT
.. code-block:: C
void mj_applyFT(const mjModel* m, mjData* d,
const mjtNum* force, const mjtNum* torque,
const mjtNum* point, int body, mjtNum* qfrc_target);
const mjtNum[3] force, const mjtNum[3] torque,
const mjtNum[3] point, int body, mjtNum* qfrc_target);
This function can be used to apply a Cartesian force and torque to a point on a body, and add the result to the vector
mjData.qfrc_applied of all applied forces. Note that the function requires a pointer to this vector, because sometimes
@@ -4395,7 +4479,7 @@ mj_objectVelocity
.. code-block:: C
void mj_objectVelocity(const mjModel* m, const mjData* d,
int objtype, int objid, mjtNum* res, int flg_local);
int objtype, int objid, mjtNum[6] res, int flg_local);
Compute object 6D velocity in object-centered frame, world/local orientation.
@@ -4407,7 +4491,7 @@ mj_objectAcceleration
.. code-block:: C
void mj_objectAcceleration(const mjModel* m, const mjData* d,
int objtype, int objid, mjtNum* res, int flg_local);
int objtype, int objid, mjtNum[6] res, int flg_local);
Compute object 6D acceleration in object-centered frame, world/local orientation.
@@ -4418,7 +4502,7 @@ mj_contactForce
.. code-block:: C
void mj_contactForce(const mjModel* m, const mjData* d, int id, mjtNum* result);
void mj_contactForce(const mjModel* m, const mjData* d, int id, mjtNum[6] result);
Extract 6D force:torque given contact id, in the contact frame.
@@ -4468,8 +4552,8 @@ mj_local2Global
.. code-block:: C
void mj_local2Global(mjData* d, mjtNum* xpos, mjtNum* xmat,
const mjtNum* pos, const mjtNum* quat,
void mj_local2Global(mjData* d, mjtNum[3] xpos, mjtNum[9] xmat,
const mjtNum[3] pos, const mjtNum[4] quat,
int body, mjtByte sameframe);
Map from body local to global Cartesian coordinates.
@@ -4539,9 +4623,9 @@ mj_ray
.. code-block:: C
mjtNum mj_ray(const mjModel* m, const mjData* d, const mjtNum* pnt, const mjtNum* vec,
mjtNum mj_ray(const mjModel* m, const mjData* d, const mjtNum[3] pnt, const mjtNum[3] vec,
const mjtByte* geomgroup, mjtByte flg_static, int bodyexclude,
int* geomid);
int geomid[1]);
Intersect ray (pnt+x*vec, x>=0) with visible geoms, except geoms in bodyexclude. Return geomid and distance (x) to
nearest surface, or -1 if no intersection.
@@ -4559,7 +4643,7 @@ mj_rayHfield
.. code-block:: C
mjtNum mj_rayHfield(const mjModel* m, const mjData* d, int geomid,
const mjtNum* pnt, const mjtNum* vec);
const mjtNum[3] pnt, const mjtNum[3] vec);
Interect ray with hfield, return nearest distance or -1 if no intersection.
@@ -4571,7 +4655,7 @@ mj_rayMesh
.. code-block:: C
mjtNum mj_rayMesh(const mjModel* m, const mjData* d, int geomid,
const mjtNum* pnt, const mjtNum* vec);
const mjtNum[3] pnt, const mjtNum[3] vec);
Interect ray with mesh, return nearest distance or -1 if no intersection.
@@ -4582,8 +4666,8 @@ mju_rayGeom
.. code-block:: C
mjtNum mju_rayGeom(const mjtNum* pos, const mjtNum* mat, const mjtNum* size,
const mjtNum* pnt, const mjtNum* vec, int geomtype);
mjtNum mju_rayGeom(const mjtNum[3] pos, const mjtNum[9] mat, const mjtNum[3] size,
const mjtNum[3] pnt, const mjtNum[3] vec, int geomtype);
Interect ray with pure geom, return nearest distance or -1 if no intersection.
@@ -4595,7 +4679,7 @@ mju_raySkin
.. code-block:: C
mjtNum mju_raySkin(int nface, int nvert, const int* face, const float* vert,
const mjtNum* pnt, const mjtNum* vec, int* vertid);
const mjtNum[3] pnt, const mjtNum[3] vec, int vertid[1]);
Interect ray with skin, return nearest vertex id.
@@ -4605,7 +4689,7 @@ Interaction
^^^^^^^^^^^
These function implement abstract mouse interactions, allowing control over cameras and perturbations. Their use is well
illustrated in simulate.cc.
illustrated in ``simulate.cc``.
.. _mjv_defaultCamera:
@@ -4636,8 +4720,8 @@ mjv_room2model
.. code-block:: C
void mjv_room2model(mjtNum* modelpos, mjtNum* modelquat, const mjtNum* roompos,
const mjtNum* roomquat, const mjvScene* scn);
void mjv_room2model(mjtNum[3] modelpos, mjtNum[4] modelquat, const mjtNum[3] roompos,
const mjtNum[4] roomquat, const mjvScene* scn);
Transform pose from room to model space.
@@ -4648,8 +4732,8 @@ mjv_model2room
.. code-block:: C
void mjv_model2room(mjtNum* roompos, mjtNum* roomquat, const mjtNum* modelpos,
const mjtNum* modelquat, const mjvScene* scn);
void mjv_model2room(mjtNum[3] roompos, mjtNum[4] roomquat, const mjtNum[3] modelpos,
const mjtNum[4] modelquat, const mjvScene* scn);
Transform pose from model to room space.
@@ -4660,7 +4744,7 @@ mjv_cameraInModel
.. code-block:: C
void mjv_cameraInModel(mjtNum* headpos, mjtNum* forward, mjtNum* up,
void mjv_cameraInModel(mjtNum[3] headpos, mjtNum[3] forward, mjtNum[3] up,
const mjvScene* scn);
Get camera info in model space; average left and right OpenGL cameras.
@@ -4672,7 +4756,7 @@ mjv_cameraInRoom
.. code-block:: C
void mjv_cameraInRoom(mjtNum* headpos, mjtNum* forward, mjtNum* up,
void mjv_cameraInRoom(mjtNum[3] headpos, mjtNum[3] forward, mjtNum[3] up,
const mjvScene* scn);
Get camera info in room space; average left and right OpenGL cameras.
@@ -4695,7 +4779,7 @@ mjv_alignToCamera
.. code-block:: C
void mjv_alignToCamera(mjtNum* res, const mjtNum* vec, const mjtNum* forward);
void mjv_alignToCamera(mjtNum[3] res, const mjtNum[3] vec, const mjtNum[3] forward);
Rotate 3D vec in horizontal plane by angle between (0,1) and (forward_x,forward_y).
@@ -4731,7 +4815,7 @@ mjv_moveModel
.. code-block:: C
void mjv_moveModel(const mjModel* m, int action, mjtNum reldx, mjtNum reldy,
const mjtNum* roomup, mjvScene* scn);
const mjtNum roomup[3], mjvScene* scn);
Move model with mouse; action is mjtMouse.
@@ -4791,13 +4875,13 @@ mjv_select
int mjv_select(const mjModel* m, const mjData* d, const mjvOption* vopt,
mjtNum aspectratio, mjtNum relx, mjtNum rely,
const mjvScene* scn, mjtNum* selpnt, int* geomid, int* skinid);
const mjvScene* scn, mjtNum[3] selpnt, int geomid[1], int skinid[1]);
This function is used for mouse selection. Previously selection was done via OpenGL, but as of MuJoCo 1.50 it relies on
ray intersections which are much more efficient. aspectratio is the viewport width/height. relx and rely are the
relative coordinates of the 2D point of interest in the viewport (usually mouse cursor). The function returns the id of
the geom under the specified 2D point, or -1 if there is no geom (note that they skybox if present is not a model geom).
The 3D coordinates of the clicked point are returned in selpnt. See simulate.cc for an illustration.
The 3D coordinates of the clicked point are returned in selpnt. See ``simulate.cc`` for an illustration.
.. _Visualization-api:
@@ -4806,7 +4890,7 @@ Visualization
The functions in this section implement abstract visualization. The results are used by the OpenGL rendered, and can
also be used by users wishing to implement their own rendered, or hook up MuJoCo to advanced rendering tools such as
Unity or Unreal Engine. See simulate.cc for illustration of how to use these functions.
Unity or Unreal Engine. See ``simulate.cc`` for illustration of how to use these functions.
.. _mjv_defaultOption:
@@ -4837,8 +4921,8 @@ mjv_initGeom
.. code-block:: C
void mjv_initGeom(mjvGeom* geom, int type, const mjtNum* size,
const mjtNum* pos, const mjtNum* mat, const float* rgba);
void mjv_initGeom(mjvGeom* geom, int type, const mjtNum[3] size,
const mjtNum[3] pos, const mjtNum[9] mat, const float[4] rgba);
Initialize given geom fields when not NULL, set the rest to their default values.
@@ -4951,7 +5035,7 @@ Update skins.
OpenGL rendering
^^^^^^^^^^^^^^^^
These functions expose the OpenGL renderer. See simulate.cc for illustration of how to use these functions.
These functions expose the OpenGL renderer. See ``simulate.cc`` for illustration of how to use these functions.
.. _mjr_defaultContext:
@@ -6185,7 +6269,7 @@ mju_cholFactor
int mju_cholFactor(mjtNum* mat, int n, mjtNum mindiag);
Cholesky decomposition: mat = L*L'; return rank.
Cholesky decomposition: mat = L*L'; return rank, decomposition performed in-place into mat.
.. _mju_cholSolve:
@@ -6214,7 +6298,7 @@ mju_eig3
.. code-block:: C
int mju_eig3(mjtNum* eigval, mjtNum* eigvec, mjtNum* quat, const mjtNum* mat);
int mju_eig3(mjtNum[3] eigval, mjtNum[9] eigvec, mjtNum[4] quat, const mjtNum[9] mat);
Eigenvalue decomposition of symmetric 3x3 matrix.
+96 -66
View File
@@ -1214,6 +1214,8 @@ XML schema
| | | +-------------------------+-------------------------+-------------------------+ |
| | | | :at:`cutoff` | :at:`noise` | :at:`user` | |
| | | +-------------------------+-------------------------+-------------------------+ |
| | | | :at:`reftype` | :at:`refname` | | |
| | | +-------------------------+-------------------------+-------------------------+ |
+--------------------------+----+------------------------------------------------------------------------------------+
| |_2|:el:`framequat` | \* | .. table:: |
| | | :class: mjcf-attributes |
@@ -1223,6 +1225,8 @@ XML schema
| | | +-------------------------+-------------------------+-------------------------+ |
| | | | :at:`cutoff` | :at:`noise` | :at:`user` | |
| | | +-------------------------+-------------------------+-------------------------+ |
| | | | :at:`reftype` | :at:`refname` | | |
| | | +-------------------------+-------------------------+-------------------------+ |
+--------------------------+----+------------------------------------------------------------------------------------+
| |_2|:el:`framexaxis` | \* | .. table:: |
| | | :class: mjcf-attributes |
@@ -1232,6 +1236,8 @@ XML schema
| | | +-------------------------+-------------------------+-------------------------+ |
| | | | :at:`cutoff` | :at:`noise` | :at:`user` | |
| | | +-------------------------+-------------------------+-------------------------+ |
| | | | :at:`reftype` | :at:`refname` | | |
| | | +-------------------------+-------------------------+-------------------------+ |
+--------------------------+----+------------------------------------------------------------------------------------+
| |_2|:el:`frameyaxis` | \* | .. table:: |
| | | :class: mjcf-attributes |
@@ -1241,6 +1247,8 @@ XML schema
| | | +-------------------------+-------------------------+-------------------------+ |
| | | | :at:`cutoff` | :at:`noise` | :at:`user` | |
| | | +-------------------------+-------------------------+-------------------------+ |
| | | | :at:`reftype` | :at:`refname` | | |
| | | +-------------------------+-------------------------+-------------------------+ |
+--------------------------+----+------------------------------------------------------------------------------------+
| |_2|:el:`framezaxis` | \* | .. table:: |
| | | :class: mjcf-attributes |
@@ -1250,6 +1258,8 @@ XML schema
| | | +-------------------------+-------------------------+-------------------------+ |
| | | | :at:`cutoff` | :at:`noise` | :at:`user` | |
| | | +-------------------------+-------------------------+-------------------------+ |
| | | | :at:`reftype` | :at:`refname` | | |
| | | +-------------------------+-------------------------+-------------------------+ |
+--------------------------+----+------------------------------------------------------------------------------------+
| |_2|:el:`framelinvel` | \* | .. table:: |
| | | :class: mjcf-attributes |
@@ -1259,6 +1269,8 @@ XML schema
| | | +-------------------------+-------------------------+-------------------------+ |
| | | | :at:`cutoff` | :at:`noise` | :at:`user` | |
| | | +-------------------------+-------------------------+-------------------------+ |
| | | | :at:`reftype` | :at:`refname` | | |
| | | +-------------------------+-------------------------+-------------------------+ |
+--------------------------+----+------------------------------------------------------------------------------------+
| |_2|:el:`frameangvel` | \* | .. table:: |
| | | :class: mjcf-attributes |
@@ -1268,6 +1280,8 @@ XML schema
| | | +-------------------------+-------------------------+-------------------------+ |
| | | | :at:`cutoff` | :at:`noise` | :at:`user` | |
| | | +-------------------------+-------------------------+-------------------------+ |
| | | | :at:`reftype` | :at:`refname` | | |
| | | +-------------------------+-------------------------+-------------------------+ |
+--------------------------+----+------------------------------------------------------------------------------------+
| |_2|:el:`framelinacc` | \* | .. table:: |
| | | :class: mjcf-attributes |
@@ -1641,10 +1655,11 @@ adjust it properly through the XML.
around this convention (both the camera and perturbation commands are based on it) so we do not recommend deviating
from it.
:at:`wind`: :at-val:`real(3), "0 0 0"`
Velocity vector of the medium (i.e. wind). This vector is subtracted from the 3D translational velocity of each body,
and the result is used to compute viscous, lift and drag forces acting on the body; recall :ref:`Passive forces
Velocity vector of the medium (i.e., wind). This vector is subtracted from the 3D translational velocity of each
body, and the result is used to compute viscous, lift and drag forces acting on the body; recall :ref:`Passive forces
<gePassive>` in the Computation chapter. The magnitude of these forces scales with the values of the next two
attributes.
:at:`magnetic`: :at-val:`real(3), "0 -0.5 0"`
Global magnetic flux. This vector is used by magnetometer sensors, which are defined as sites and return the magnetic
flux at the site position expressed in the site frame.
@@ -1744,7 +1759,7 @@ from its default.
This flag disables the clamping of control inputs to all actuators, even if the actuator-specific attributes are set
to enable clamping.
:at:`warmstart`: :at-val:`[disable, enable], "enable"`
This flag disables warm-starting of the constraint solver. By default the solver uses the solution (i.e. the
This flag disables warm-starting of the constraint solver. By default the solver uses the solution (i.e., the
constraint force) from the previous time step to initialize the iterative optimization. This feature should be
disabled when evaluating the dynamics at a collection of states that do not form a trajectory - in which case warm
starts make no sense and are likely to slow down the solver.
@@ -1785,7 +1800,7 @@ fields of mjOption which can be modified at runtime, sizes are structural parame
compilation.
:at:`njmax`: :at-val:`int, "-1"`
This and the next two attributes specify the maximum sizes of the dynamic arrays in mjData, i.e. arrays whose
This and the next two attributes specify the maximum sizes of the dynamic arrays in mjData, i.e., arrays whose
effective length varies at runtime. This attribute specifies the maximum number of scalar constraints (or
equivalently, rows of the constraint Jacobian) that can be handled at runtime. If the number of active constraints is
about to exceed this maximum (usually because too many contacts become active) the extra constraints are discarded
@@ -1801,7 +1816,7 @@ compilation.
warning is generated. The actual number of contacts is stored in mjData.ncon. If this value is negative, the compiler
will use a heuristic to guess an appropriate number.
:at:`nstack`: :at-val:`int, "-1"`
This attribute specifies the size of the pre-allocated stack in mjData, in units of sizeof(mjtNum) which is currently
This attribute specifies the size of the preallocated stack in mjData, in units of sizeof(mjtNum) which is currently
defined as double; thus the size in bytes is 8 times larger. The custom stack is used by all MuJoCo functions that
need dynamically allocated memory. We do not use heap memory allocation at runtime, so as to speed up processing as
well as avoid heap fragmentation. Note that the internal allocator keeps track of how much stack space has ever been
@@ -1814,23 +1829,23 @@ compilation.
The number of key frames allocated in mjModel is the larger of this value and the number of :ref:`key <key>` elements
below. Note that the interactive simulator has the ability to take snapshots of the system state and save them as key
frames.
:at:`nuser_body`: :at-val:`int, "0"`
:at:`nuser_body`: :at-val:`int, "-1"`
The number of custom user parameters added to the definition of each body. See also :ref:`User parameters <CUser>`.
The parameter values are set via the user attribute of the :ref:`body <body>` element. These values are not accessed
by MuJoCo. They can be used to define element properties needed in user callbacks and other custom code.
:at:`nuser_jnt`: :at-val:`int, "0"`
:at:`nuser_jnt`: :at-val:`int, "-1"`
The number of custom user parameters added to the definition of each :ref:`joint <joint>`.
:at:`nuser_geom`: :at-val:`int, "0"`
:at:`nuser_geom`: :at-val:`int, "-1"`
The number of custom user parameters added to the definition of each :ref:`geom <geom>`.
:at:`nuser_site"`: :at-val:`int, "0"`
:at:`nuser_site`: :at-val:`int, "-1"`
The number of custom user parameters added to the definition of each :ref:`site <site>`.
:at:`nuser_cam"`: :at-val:`int, "0"`
:at:`nuser_cam`: :at-val:`int, "-1"`
The number of custom user parameters added to the definition of each :ref:`camera <camera>`.
:at:`nuser_tendon`: :at-val:`int, "0"`
:at:`nuser_tendon`: :at-val:`int, "-1"`
The number of custom user parameters added to the definition of each :ref:`tendon <tendon>`.
:at:`nuser_actuator`: :at-val:`int, "0"`
:at:`nuser_actuator`: :at-val:`int, "-1"`
The number of custom user parameters added to the definition of each :ref:`actuator <actuator>`.
:at:`nuser_sensor`: :at-val:`int, "0"`
:at:`nuser_sensor`: :at-val:`int, "-1"`
The number of custom user parameters added to the definition of each :ref:`sensor <sensor>`.
.. _visual:
@@ -1843,7 +1858,7 @@ compilation.
yields a list of geometric entities for subsequent rendering. The settings here are global, in contrast with the
element-specific visual settings. The global and element-specific settings refer to non-overlapping properties. Some
of the global settings affect properties such as triangulation of geometric primitives that cannot be set per element.
Other global settings affect the properties of decorative objects, i.e. objects such as contact points and force
Other global settings affect the properties of decorative objects, i.e., objects such as contact points and force
arrows which do not correspond to model elements. The visual settings are grouped semantically into several
subsections.
| This element is a good candidate for the :ref:`file include <CInclude>` mechanism. One can create an XML file with
@@ -1858,7 +1873,7 @@ While all settings in mjVisual are global, the settings here could not be fit in
is effectively a miscellaneous subsection.
:at:`fovy`: :at-val:`real, "45"`
This attribute specifies the vertical field of view of the free camera, i.e. the camera that is always available in
This attribute specifies the vertical field of view of the free camera, i.e., the camera that is always available in
the visualizer even if no cameras are explicitly defined in the model. It is always expressed in degrees, regardless
of the setting of the angle attribute of :ref:`compiler <compiler>`, and is also represented in the low level model
in degrees. This is because we pass it to OpenGL which uses degrees. The same convention applies to the fovy
@@ -2013,7 +2028,7 @@ documented below.
:at:`light`: :at-val:`real, "0.3"`
The size of the decorative object used to represent model lights in the rendering.
:at:`selectpoint`: :at-val:`real, "0.2"`
The radius of the sphere used to render the selection point (i.e. the point where the user left-double-clicked to
The radius of the sphere used to render the selection point (i.e., the point where the user left-double-clicked to
select a body). Note that the local and global coordinates of this point can be printed in the 3D view by activating
the corresponding rendering flags. In this way, the coordinates of points of interest can be found.
:at:`jointlength`: :at-val:`real, "1.0"`
@@ -2093,7 +2108,7 @@ disables the rendering of the corresponding object.
Color of slider-crank mechanisms.
:at:`crankbroken`: :at-val:`real(4), "0.9 0 0 1"`
Color used to render the crank of slide-crank mechanisms, in model configurations where the specified rod length
cannot be maintained, i.e. it is "broken".
cannot be maintained, i.e., it is "broken".
.. _statistic:
@@ -2458,7 +2473,7 @@ chapter.
different from "none", the texture is treated as procedural and any file names are ignored. The keywords have the
following meaning:
The **gradient** type generates a color gradient from rgb1 to rgb2. The interpolation in color space is done through
a sigmoid function. For cube and skybox textures the gradient is along the +Y axis, i.e. from top to bottom for
a sigmoid function. For cube and skybox textures the gradient is along the +Y axis, i.e., from top to bottom for
skybox rendering.
The **checker** type generates a 2-by-2 checker pattern with alternating colors given by rgb1 to rgb2. This is
@@ -2486,11 +2501,11 @@ chapter.
texture size and probability need to be adjusted jointly. Together with a gradient skybox texture, this can create
the appearance of a night sky with stars.
:at:`width`: :at-val:`int, "0"`
The width of the procedural texture, i.e. the number of columns in the image. For cube and skybox procedural textures
the width and height must be equal. Larger values usually result in higher quality images, although in some cases
(e.g. checker patterns) small values are sufficient.
The width of the procedural texture, i.e., the number of columns in the image. For cube and skybox procedural
textures the width and height must be equal. Larger values usually result in higher quality images, although in some
cases (e.g. checker patterns) small values are sufficient.
:at:`height`: :at-val:`int, "0"`
The height of the procedural texture, i.e. the number of rows in the image.
The height of the procedural texture, i.e., the number of rows in the image.
:at:`hflip`: :at-val:`[false, true], "false"`
If true, images loaded from file are flipped in the horizontal direction. Does not affect procedural textures.
:at:`vflip`: :at-val:`[false, true], "false"`
@@ -2548,7 +2563,7 @@ also known as terrain map, is a 2D matrix of elevation data. The data can be spe
with the file contents.
:at:`nrow`: :at-val:`int, "0"`
This attribute and the next are used to allocate a height field in mjModel and leave the elevation data undefined
(i.e. set to 0). This attribute specifies the number of rows in the elevation data matrix. The default value of 0
(i.e., set to 0). This attribute specifies the number of rows in the elevation data matrix. The default value of 0
means that the data will be loaded from a file, which will be used to infer the size of the matrix.
:at:`ncol`: :at-val:`int, "0"`
This attribute specifies the number of columns in the elevation data matrix.
@@ -2962,7 +2977,7 @@ axes of inertia of the body. Thus the inertia matrix is diagonal in this frame.
:at:`fullinertia`: :at-val:`real(6), optional`
Full inertia matrix M. Since M is 3-by-3 and symmetric, it is specified using only 6 numbers in the following order:
M(1,1), M(2,2), M(3,3), M(1,2), M(1,3), M(2,3). The compiler computes the eigenvalue decomposition of M and sets the
frame orientation and diagonal inertia accordingly. If non-positive eigenvalues are encountered (i.e. if M is not
frame orientation and diagonal inertia accordingly. If non-positive eigenvalues are encountered (i.e., if M is not
positive definite) a compile error is generated.
.. _joint:
@@ -3058,7 +3073,7 @@ unit quaternions.
Armature inertia (or rotor inertia, or reflected inertia) of all degrees of freedom created by this joint. These are
constants added to the diagonal of the inertia matrix in generalized coordinates. They make the simulation more
stable, and often increase physical realism. This is because when a motor is attached to the system with a
transmission that amplifies the motor force by c, the inertia of the rotor (i.e. the moving part of the motor) is
transmission that amplifies the motor force by c, the inertia of the rotor (i.e., the moving part of the motor) is
amplified by c*c. The same holds for gears in the early stages of planetary gear boxes. These extra inertias often
dominate the inertias of the robot parts that are represented explicitly in the model, and the armature attribute is
the way to model them.
@@ -3280,7 +3295,7 @@ mjModel. If the XML model is saved, it will appear as a regular joint of type "f
in :ref:`CSolver`. The quantity this function is applied to is the distance between
the two geoms minus the margin plus the gap.
:at:`gap`: :at-val:`real, "0"`
This attribute is used to enable the generation of inactive contacts, i.e. contacts that are ignored by the
This attribute is used to enable the generation of inactive contacts, i.e., contacts that are ignored by the
constraint solver but are included in mjData.contact for the purpose of custom computations. When this value is
positive, geom distances between margin and margin-gap correspond to such inactive contacts.
:at:`fromto`: :at-val:`real(6), optional`
@@ -3380,7 +3395,7 @@ and the +Y axis points up. Thus the frame position and orientation are the key a
:at:`mode`: :at-val:`[fixed, track, trackcom, targetbody, targetbodycom], "fixed"`
This attribute specifies how the camera position and orientation in world coordinates are computed in forward
kinematics (which in turn determine what the camera sees). "fixed" means that the position and orientation specified
below are fixed relative to the parent (i.e. the body where the camera is defined). "track" means that the camera
below are fixed relative to the parent (i.e., the body where the camera is defined). "track" means that the camera
position is at a constant offset from the parent in world coordinates, while the camera orientation is constant in
world coordinates. These constants are determined by applying forward kinematics in qpos0 and treating the camera as
fixed. Tracking can be used for example to position a camera above a body, point it down so it sees the body, and
@@ -3447,7 +3462,7 @@ the direction specified by the dir attribute. It does not have a full spatial fr
computed by the compiler but can also be overridden by specifying the extent attribute of :ref:`statistic
<statistic>`. Internally the shadow-mapping mechanism renders the scene from the light viewpoint (as if it were a
camera) into a depth texture, and then renders again from the camera viewpoint, using the depth texture to create
shadows. The internal rendering pass uses the same near and far clipping planes as regular rendering, i.e. these
shadows. The internal rendering pass uses the same near and far clipping planes as regular rendering, i.e., these
clipping planes bound the cone or box shadow volume in the light direction. As a result, some shadows (especially
those very close to the light) may be clipped.
:at:`active`: :at-val:`[false, true], "true"`
@@ -3765,7 +3780,7 @@ element.
:at:`margin`: :at-val:`real, "0"`
Distance threshold below which contacts are detected and included in the global array mjData.contact.
:at:`gap`: :at-val:`real, "0"`
This attribute is used to enable the generation of inactive contacts, i.e. contacts that are ignored by the
This attribute is used to enable the generation of inactive contacts, i.e., contacts that are ignored by the
constraint solver but are included in mjData.contact for the purpose of custom computations. When this value is
positive, geom distances between margin and margin-gap correspond to such inactive contacts.
@@ -3850,7 +3865,7 @@ of the other body, without any joint elements in the child body.
and changing the corresponding component of mjModel.eq_active at runtime can be used to fix the body temporarily.
:at:`relpose`: :at-val:`real(7), "0 1 0 0 0 0 0"`
This attribute specifies the relative pose (3D position followed by 4D quaternion orientation) of body2 relative to
body1. If the quaternion part (i.e. last 4 components of the vector) are all zeros, as in the default setting, this
body1. If the quaternion part (i.e., last 4 components of the vector) are all zeros, as in the default setting, this
attribute is ignored and the relative pose is the one corresponding to the model reference pose in qpos0. The unusual
default is because all equality constraint types share the same default for their numeric parameters.
@@ -4145,7 +4160,7 @@ specify them independently.
If specified, the actuator acts on the given tendon. The actuator length equals the tendon length times the gear
ratio. Both spatial and fixed tendons can be used.
:at:`cranksite`: :at-val:`string, optional`
If specified, the actuator acts on a slider-crank mechanism which is implicitly determined by the actuator (i.e. it
If specified, the actuator acts on a slider-crank mechanism which is implicitly determined by the actuator (i.e., it
is not a separate model element). The specified site corresponds to the pin joining the crank and the connecting rod.
The actuator length equals the position of the slider-crank mechanism times the gear ratio.
:at:`slidersite`: :at-val:`string, required for slider-crank transmission`
@@ -4217,7 +4232,7 @@ specify them independently.
such shortcut is encountered, the parser creates a :el:`general` actuator and sets its dynprm, gainprm and biasprm
attributes to the internal defaults shown above, regardless of any default settings. It then adjusts dyntype, gaintype
and biastype depending on the shortcut, parses any custom attributes (beyond the common ones), and translates them
into regular attributes (i.e. attributes of the :el:`general` actuator type) as explained here.
into regular attributes (i.e., attributes of the :el:`general` actuator type) as explained here.
| This element creates a direct-drive actuator. The underlying :el:`general` attributes are set as follows:
========= ======= ========= =======
@@ -4464,7 +4479,7 @@ This element creates a 3-axis force sensor. The sensor outputs three numbers, wh
child and a parent body, expressed in the site frame defining the sensor. The convention is that the site is attached to
the child body, and the force points from the child towards the parent. To change the sign of the sensor reading, use
the scale attribute. The computation here takes into account all forces acting on the system, including contacts as well
as external perturbations. Using this sensor often requires creating a dummy body welded to its parent (i.e. having no
as external perturbations. Using this sensor often requires creating a dummy body welded to its parent (i.e., having no
joint elements).
:at:`name`, :at:`noise`, :at:`cutoff`, :at:`user`
@@ -4724,7 +4739,8 @@ This element creates a tendon limit sensor for constraint force.
:el-prefix:`sensor/` **framepos** (*)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This element creates a sensor that returns the 3D position of the spatial frame of the object, in global coordinates.
This element creates a sensor that returns the 3D position of the spatial frame of the object, in global coordinates or
optionally with respect to a given frame-of-reference.
:at:`name`, :at:`noise`, :at:`cutoff`, :at:`user`
See :ref:`CSensor`.
@@ -4734,6 +4750,12 @@ This element creates a sensor that returns the 3D position of the spatial frame
the joint with the parent body).
:at:`objname`: :at-val:`string, required`
The name of the object to which the sensor is attached.
:at:`reftype`: :at-val:`[body, xbody, geom, site, camera]`
The type of object to which the frame-of-reference is attached. The semantics are identical to the :at:`objtype`
attribute. If :at:`reftype` and :at:`refname` are given, the sensor values will be measured with respect to this
frame. If they are not given, sensor values will be measured with respect to the global frame.
:at:`refname`: :at-val:`string`
The name of the object to which the frame-of-reference is attached.
.. _sensor-framequat:
@@ -4746,11 +4768,13 @@ object, in global coordinates.
:at:`name`, :at:`noise`, :at:`cutoff`, :at:`user`
See :ref:`CSensor`.
:at:`objtype`: :at-val:`[body, xbody, geom, site, camera], required`
The type of object to which the sensor is attached. This must be an object type that has a spatial frame. "body"
refers to the inertial frame of the body, while "xbody" refers to the regular frame of the body (usually centered at
the joint with the parent body).
See :ref:`framepos<sensor-framepos>` sensor.
:at:`objname`: :at-val:`string, required`
The name of the object to which the sensor is attached.
See :ref:`framepos<sensor-framepos>` sensor.
:at:`reftype`: :at-val:`[body, xbody, geom, site, camera]`
See :ref:`framepos<sensor-framepos>` sensor.
:at:`refname`: :at-val:`string`
See :ref:`framepos<sensor-framepos>` sensor.
.. _sensor-framexaxis:
@@ -4763,11 +4787,13 @@ object, in global coordinates.
:at:`name`, :at:`noise`, :at:`cutoff`, :at:`user`
See :ref:`CSensor`.
:at:`objtype`: :at-val:`[body, xbody, geom, site, camera], required`
The type of object to which the sensor is attached. This must be an object type that has a spatial frame. "body"
refers to the inertial frame of the body, while "xbody" refers to the regular frame of the body (usually centered at
the joint with the parent body).
See :ref:`framepos<sensor-framepos>` sensor.
:at:`objname`: :at-val:`string, required`
The name of the object to which the sensor is attached.
See :ref:`framepos<sensor-framepos>` sensor.
:at:`reftype`: :at-val:`[body, xbody, geom, site, camera]`
See :ref:`framepos<sensor-framepos>` sensor.
:at:`refname`: :at-val:`string`
See :ref:`framepos<sensor-framepos>` sensor.
.. _sensor-frameyaxis:
@@ -4780,11 +4806,13 @@ object, in global coordinates.
:at:`name`, :at:`noise`, :at:`cutoff`, :at:`user`
See :ref:`CSensor`.
:at:`objtype`: :at-val:`[body, xbody, geom, site, camera], required`
The type of object to which the sensor is attached. This must be an object type that has a spatial frame. "body"
refers to the inertial frame of the body, while "xbody" refers to the regular frame of the body (usually centered at
the joint with the parent body).
See :ref:`framepos<sensor-framepos>` sensor.
:at:`objname`: :at-val:`string, required`
The name of the object to which the sensor is attached.
See :ref:`framepos<sensor-framepos>` sensor.
:at:`reftype`: :at-val:`[body, xbody, geom, site, camera]`
See :ref:`framepos<sensor-framepos>` sensor.
:at:`refname`: :at-val:`string`
See :ref:`framepos<sensor-framepos>` sensor.
.. _sensor-framezaxis:
@@ -4797,11 +4825,13 @@ object, in global coordinates.
:at:`name`, :at:`noise`, :at:`cutoff`, :at:`user`
See :ref:`CSensor`.
:at:`objtype`: :at-val:`[body, xbody, geom, site, camera], required`
The type of object to which the sensor is attached. This must be an object type that has a spatial frame. "body"
refers to the inertial frame of the body, while "xbody" refers to the regular frame of the body (usually centered at
the joint with the parent body).
See :ref:`framepos<sensor-framepos>` sensor.
:at:`objname`: :at-val:`string, required`
The name of the object to which the sensor is attached.
See :ref:`framepos<sensor-framepos>` sensor.
:at:`reftype`: :at-val:`[body, xbody, geom, site, camera]`
See :ref:`framepos<sensor-framepos>` sensor.
:at:`refname`: :at-val:`string`
See :ref:`framepos<sensor-framepos>` sensor.
.. _sensor-framelinvel:
@@ -4814,11 +4844,13 @@ coordinates.
:at:`name`, :at:`noise`, :at:`cutoff`, :at:`user`
See :ref:`CSensor`.
:at:`objtype`: :at-val:`[body, xbody, geom, site, camera], required`
The type of object to which the sensor is attached. This must be an object type that has a spatial frame. "body"
refers to the inertial frame of the body, while "xbody" refers to the regular frame of the body (usually centered at
the joint with the parent body).
See :ref:`framepos<sensor-framepos>` sensor.
:at:`objname`: :at-val:`string, required`
The name of the object to which the sensor is attached.
See :ref:`framepos<sensor-framepos>` sensor.
:at:`reftype`: :at-val:`[body, xbody, geom, site, camera]`
See :ref:`framepos<sensor-framepos>` sensor.
:at:`refname`: :at-val:`string`
See :ref:`framepos<sensor-framepos>` sensor.
.. _sensor-frameangvel:
@@ -4831,11 +4863,13 @@ coordinates.
:at:`name`, :at:`noise`, :at:`cutoff`, :at:`user`
See :ref:`CSensor`.
:at:`objtype`: :at-val:`[body, xbody, geom, site, camera], required`
The type of object to which the sensor is attached. This must be an object type that has a spatial frame. "body"
refers to the inertial frame of the body, while "xbody" refers to the regular frame of the body (usually centered at
the joint with the parent body).
See :ref:`framepos<sensor-framepos>` sensor.
:at:`objname`: :at-val:`string, required`
The name of the object to which the sensor is attached.
See :ref:`framepos<sensor-framepos>` sensor.
:at:`reftype`: :at-val:`[body, xbody, geom, site, camera]`
See :ref:`framepos<sensor-framepos>` sensor.
:at:`refname`: :at-val:`string`
See :ref:`framepos<sensor-framepos>` sensor.
.. _sensor-framelinacc:
@@ -4848,11 +4882,9 @@ coordinates.
:at:`name`, :at:`noise`, :at:`cutoff`, :at:`user`
See :ref:`CSensor`.
:at:`objtype`: :at-val:`[body, xbody, geom, site, camera], required`
The type of object to which the sensor is attached. This must be an object type that has a spatial frame. "body"
refers to the inertial frame of the body, while "xbody" refers to the regular frame of the body (usually centered at
the joint with the parent body).
See :ref:`framepos<sensor-framepos>` sensor.
:at:`objname`: :at-val:`string, required`
The name of the object to which the sensor is attached.
See :ref:`framepos<sensor-framepos>` sensor.
.. _sensor-frameangacc:
@@ -4865,11 +4897,9 @@ coordinates.
:at:`name`, :at:`noise`, :at:`cutoff`, :at:`user`
See :ref:`CSensor`.
:at:`objtype`: :at-val:`[body, xbody, geom, site, camera], required`
The type of object to which the sensor is attached. This must be an object type that has a spatial frame. "body"
refers to the inertial frame of the body, while "xbody" refers to the regular frame of the body (usually centered at
the joint with the parent body).
See :ref:`framepos<sensor-framepos>` sensor.
:at:`objname`: :at-val:`string, required`
The name of the object to which the sensor is attached.
See :ref:`framepos<sensor-framepos>` sensor.
.. _sensor-subtreecom:
+79 -2
View File
@@ -2,6 +2,83 @@
Changelog
=========
Version 2.1.2 (Date TBD, 2022)
------------------------------
New modules
^^^^^^^^^^^
1. Added new :doc:`Python bindings<python>`, which can be installed via ``pip install mujoco``,
and imported as ``import mujoco``.
#. Added new :doc:`Unity plug-in<unity>`.
#. Added a new ``introspect`` module, which provides reflection-like capability for MuJoCo's public API, currently
describing functions and enums. While implemented in Python, this module is expected to be generally useful for
automatic code generation targeting multiple languages. (This is not shipped as part of the ``mujoco`` Python
bindings package.)
API changes
^^^^^^^^^^^
4. Moved definition of ``mjtNum`` floating point type into a new header
`mjtnum.h <https://github.com/deepmind/mujoco/blob/main/include/mjtnum.h>`_.
#. Renamed header `mujoco_export.h` to :ref:`mjexport.h<inHeader>`.
#. Added ``mj_printFormattedData``, which accepts a format string for floating point numbers, for example to increase
precision.
General
^^^^^^^
7. MuJoCo can load `OBJ <https://en.wikipedia.org/wiki/Wavefront_.obj_file>`_ mesh files.
a. Meshes containing polygons with more than 4 vertices are not supported.
#. In OBJ files containing multiple object groups, any groups after the first one will be ignored.
#. Added optional frame-of-reference specification to :ref:`framepos<sensor-framepos>`,
:ref:`framequat<sensor-framequat>`, :ref:`framexaxis<sensor-framexaxis>`, :ref:`frameyaxis<sensor-frameyaxis>`,
:ref:`framezaxis<sensor-framezaxis>`, :ref:`framelinvel<sensor-framelinvel>`, and
:ref:`frameangvel<sensor-frameangvel>` sensors. The frame-of-reference is specified by new :at:`reftype` and
:at:`refname` attributes.
#. Sizes of :ref:`user parameters <CUser>` are now automatically inferred.
a. Declarations of user parameters in the top-level :ref:`size <size>` clause (e.g. :at:`nuser_body`,
:at:`nuser_jnt`, etc.) now accept a value of -1, which is the default. This will automatically set the value to
the length of the maximum associated :at:`user` attribute defined in the model.
#. Setting a value smaller than -1 will lead to a compiler error (previously a segfault).
#. Setting a value to a length smaller than some :at:`user` attribute defined in the model will lead to an error
(previously additional values were ignored).
#. Increased the maximum number of lights in an :ref:`mjvScene` from 8 to 100.
#. Saved XML files only contain explicit :ref:`inertial <inertial>` elements if the original XML included them. Inertias
that were automatically inferred by the compiler's :ref:`inertiafromgeom <compiler>` mechanism remain unspecified.
#. User-selected geoms are always rendered as opaque. This is useful in interactive visualizers.
#. Static geoms now respect their :ref:`geom group<geom>` for visualisation. Until this change rendering of static geoms
could only be toggled using the :ref:`mjVIS_STATIC<mjtVisFlag>` visualisation flag . After this change, both the geom
group and the visualisation flag need to be enabled for the geom to be rendered.
#. Pointer parameters in function declarations in :ref:`mujoco.h<inHeader>` that are supposed to represent fixed-length
arrays are now spelled as arrays with extents, e.g. ``mjtNum quat[4]`` rather than ``mjtNum* quat``. From the
perspective of C and C++, this is a non-change since array types in function signatures decay to pointer types.
However, it allows autogenerated code to be aware of expected input shapes.
Bug Fixes
^^^^^^^^^
15. ``mj_loadXML`` and ``mj_saveLastXML`` are now locale-independent. The Unity plugin should now work correctly for
users whose system locales use commas as decimal separators.
#. XML assets in VFS no longer need to end in a null character. Instead, the file size is determined by the size
parameter of the corresponding VFS entry.
#. Fix a vertex buffer object memory leak in ``mjrContext`` when skins are used.
#. Camera quaternions are now normalized during XML compilation.
Binary build
^^^^^^^^^^^^
18. Windows binaries are now built with Clang.
Version 2.1.1 (Dec. 16, 2021)
-----------------------------
@@ -45,7 +122,7 @@ Bug Fixes
:ref:`weld <equality-weld>` constraints.
.. note::
Forces generated by :ref:`spatial tendons <spatial>` which are outside the kinematic tree (i.e. between bodies
Forces generated by :ref:`spatial tendons <spatial>` which are outside the kinematic tree (i.e., between bodies
which have no ancestral relationship) are still not taken into account by force and torque sensors. This remains a
future work item.
@@ -118,7 +195,7 @@ New features
General
^^^^^^^
3. The pre-allocated sizes in the virtual file system (VFS) increased to 2000 and 1000, to allow for larger projects.
3. The preallocated sizes in the virtual file system (VFS) increased to 2000 and 1000, to allow for larger projects.
#. The C structs in the ``mjuiItem`` union are now named, for compatibility.
#. Fixed: ``mjcb_contactfilter`` type is ``mjfConFilt`` (was ``mjfGeneric``).
#. Fixed: The array of sensors in ``mjCModel`` was not cleared.
+7 -7
View File
@@ -189,7 +189,7 @@ change at runtime. In that case there is still a fixed enumeration order (corres
elements appear in ``mjModel``) but any inactive constraints are omitted.
The number of position coordinates :math:`n_Q` is larger than the number of degrees of freedom :math:`n_V` whenever
quaternions are used to represent 3D orientations. This occurs when the model contains ball joints or free joints (i.e.
quaternions are used to represent 3D orientations. This occurs when the model contains ball joints or free joints (i.e.,
in most models). In that case :math:`\dot{q}` does not equal :math:`v`, at least not in the usual sense. Instead one has
to consider the group of rigid body orientations :math:`SO(3)` - which has the geometry of a unit sphere in 4D space.
Velocities live in the 3D tangent space to this sphere. This is taken into account by all internal computations. For
@@ -326,7 +326,7 @@ Passive forces
Passive forces are defined as forces that depend only on position and velocity, and not on control in forward dynamics
or acceleration in inverse dynamics. As a result, such forces are inputs to both the forward and inverse dynamics
computations, and are identical in both cases. They are stored in ``mjData.qfrc_passive``. The passive forces computed
by MuJoCo are also passive in the sense of physics, i.e. they do not increase energy, however the user can install the
by MuJoCo are also passive in the sense of physics, i.e., they do not increase energy, however the user can install the
callback :ref:`mjcb_passive` and add forces to ``mjData.qfrc_passive`` that may increase energy. This will not interfere
with MuJoCo's operation as long as such user forces depend only on position and velocity.
@@ -460,7 +460,7 @@ constraint contributes :math:`\dim(r)` elements to the total constraint count :m
properties of quaternions, differentiation with respect to :math:`q` produces vectors of size :math:`n_V` rather than
:math:`n_Q`.
Among other applications, equality constraints can be used to create "loop joints", i.e. joints that cannot be modeled
Among other applications, equality constraints can be used to create "loop joints", i.e., joints that cannot be modeled
via the kinematic tree. Gaming engines represent all joints in this way. The same can be done in MuJoCo but is not
recommended - because it leads to both slower and less accurate simulation, effectively turning MuJoCo into a gaming
engine. The only reason to represent joints with equality constraints would be to model soft joints - which can be done
@@ -562,7 +562,7 @@ with a 1 at the joint address. For tendons this is known as the moment arm vecto
spatial tendons this could be used to model friction between the tendon and the surfaces it wraps around. Such
friction will be load-independent though. To construct a more detailed model of this phenomenon, create several small
floating spheres and connect them with tendons in series. Then the contacts between the spheres and the surrounding
surfaces will have load-dependent (i.e. Coulomb) friction, but this is less efficient to simulate.
surfaces will have load-dependent (i.e., Coulomb) friction, but this is less efficient to simulate.
.. _coLimit:
@@ -588,7 +588,7 @@ because solving for equality constraint forces is generally faster.
``joint`` : 1 or 2
Limits can be defined for scalar joints (hinge and slide) as well as for ball joints. Scalar joints are treated as
described above. Ball joint limits are applied to the exponential-map or angle-axis representation of the joint
quaternion, i.e. the vector :math:`(\theta x, \theta y, \theta z)` where :math:`\theta` is the rotation angle and
quaternion, i.e., the vector :math:`(\theta x, \theta y, \theta z)` where :math:`\theta` is the rotation angle and
:math:`(x, y, z)` is the unit vector corresponding to the rotation axis. The limit is applied to the absolute value
of the rotation angle :math:`\theta`. At runtime the limit is determined by the larger of the two range parameters.
For semantic clarity however, one should use the second range parameter to specify the limit and set the first range
@@ -1022,7 +1022,7 @@ compute it.
Note that the quadratic term in the inverse problem is weighted by :math:`R` instead of :math:`A+R`. This tells us two
things. First, in the limit :math:`R \to 0` corresponding to hard constraints the inverse is no longer defined, as one
would expect. Second and more useful, the inverse problem is diagonal, i.e. it decouples into independent optimization
would expect. Second and more useful, the inverse problem is diagonal, i.e., it decouples into independent optimization
problems over the individual constraint forces. The only remaining coupling is due to the constraint set :math:`\Omega`,
but that set is also decoupled over the conceptual constraints discussed earlier. It turns out that all these
independent optimization problems can be solved analytically. The only non-trivial case is the elliptic friction cone
@@ -1110,7 +1110,7 @@ Substituting :math:`f^+` in the constraint dynamics :eq:`eq:identity` and rearra
Thus the constrained acceleration interpolates between the unconstrained and the reference acceleration. In particular,
in the limit :math:`R \to 0` we have a hard constraint and :math:`a^1 = a^*`, while in the limit :math:`R \to \infty` we
have have an infinitely soft constraint (i.e. no constraint) and :math:`a^1 = a^0`. It is then natural to introduce a
have have an infinitely soft constraint (i.e., no constraint) and :math:`a^1 = a^0`. It is then natural to introduce a
model parameter which directly controls the interpolation. We call this parameter *impedance* and denote it :math:`d`.
It is a vector with dimensionality :math:`n_C` satisfying :math:`0<d<1` element-wise. Once it is specified, we compute
the diagonal elements of the regularizer as
+2 -4
View File
@@ -1,4 +1,4 @@
## Copyright 2021 DeepMind Technologies Limited
# Copyright 2021 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -8,13 +8,11 @@
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Configuration file for the Sphinx documentation builder."""
import doctest
import inspect
import os
import sys
+1
View File
@@ -13,5 +13,6 @@
XMLreference
programming
APIreference
python
unity
changelog
+31 -29
View File
@@ -45,7 +45,7 @@ XML file has a unique top-level element. This element must be :el:`mujoco` for M
Compiling models
~~~~~~~~~~~~~~~~
Once a high-level mjCModel is created - by loading an MJCF file or an URDF file, or programmatically when such
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
@@ -159,7 +159,7 @@ cylinder 1 0 0 1
The box uses the top-level defaults class "main" to set the values of its undefined attributes, because no other class
was specified. The body specifies childclass "sub", causing all children of this body (and all their children etc) to
was specified. The body specifies childclass "sub", causing all children of this body (and all their children etc.) to
use class "sub" unless specified otherwise. So the ellipsoid uses class "sub". The sphere has explicitly defined rgba
which overrides the default settings. The cylinder specifies defaults class "main", and so it uses "main" instead of
"sub", even though the latter was specified in the childclass attribute of the body containing the geom.
@@ -187,7 +187,7 @@ geoms attached to the body. The undefined state cannot be entered in the XML fil
defined in a given class, it cannot be undefined in that class or in any of its child classes. So if the goal is to
leave a certain attribute undefined in a given model element, it must be undefined in the active defaults class.
A final twist here are actuators. They are different because some of the actuator-related elements are actually
A final twist here is actuators. They are different because some of the actuator-related elements are actually
shortcuts, and shortcuts interact with the defaults setting mechanism in a non-obvious way. This is explained in the
:ref:`Actuator shortcuts <CActuator>` section below.
@@ -234,7 +234,7 @@ relative to the body.
In principle the user always has a choice between local and global coordinates, but in practice this choice is viable
only when using geometric primitives rather than meshes. For meshes, the 3D vertex positions are expressed in either
local and global coordinates depending on how the mesh was designed - effectively forcing the user to adopt the same
local or global coordinates depending on how the mesh was designed - effectively forcing the user to adopt the same
convention for the entire model. The alternative would be to pre-process the mesh data outside MuJoCo so as to change
coordinates, but that effort is rarely justified.
@@ -308,7 +308,7 @@ First we explain the setting of the impedance d. Recall that d must lie between
to the range [:ref:`mjMINIMP mjMAXIMP <glNumeric>`] which is currently set to [0.0001 0.9999]. It
causes the solver to interpolate between the unforced acceleration a0 and reference acceleration aref. Small values of
d correspond to soft/weak constraints while large values of d correspond to strong/hard constraints. The user can set
d to a constant, or take advantage of its interpolating property and make it position-dependent, i.e. a function of r.
d to a constant, or take advantage of its interpolating property and make it position-dependent, i.e., a function of r.
Position-dependent impedance can be used to model soft contact layers around objects, or define equality constraints
that become stronger with larger violation (so as to approximate backlash for example). The shape of the function d(r)
is determined by the element-specific parameter vector :at:`solimp`.
@@ -408,11 +408,11 @@ margin, gap
margin and gap are distance properties and a one-sided specification makes little sense.
solref, solimp
If one of the two geoms has higher priority, its solref and solimp parameters are used. If both geoms have the same
priority, the weighted average is used. The weights are proportional to the solmix attributes, i.e. weight1 = solmix1
/ (solmix1 + solmix2) and similarly for weight2. There is one important exception to this weighted averaging rule. If
solref for either geom is non-positive, i.e. it relies on the new direct format introduced in MuJoCo 2.0, then the
element-wise minimum is used regardless of solmix. This is because averaging solref parameters in different formats
would be meaningless.
priority, the weighted average is used. The weights are proportional to the solmix attributes, i.e., weight1 =
solmix1 / (solmix1 + solmix2) and similarly for weight2. There is one important exception to this weighted averaging
rule. If solref for either geom is non-positive, i.e., it relies on the new direct format introduced in MuJoCo 2.0,
then the element-wise minimum is used regardless of solmix. This is because averaging solref parameters in different
formats would be meaningless.
.. _COverride:
@@ -443,12 +443,14 @@ User parameters
~~~~~~~~~~~~~~~
A number of MJCF elements have the optional attribute :at:`user`, which defines a custom element-specific parameter
array. This interacts with the corresponding "nuser_XXX" attribute of the :ref:`size <size>` element.
If for example we set :at:`nuser_geom` to 5, then every geom in mjModel will have a custom array of 5 real-valued
parameters. These geom-specific parameters are either defined in the MJCF file via the :at:`user` attribute of
:ref:`geom <geom>`, or set to 0 by the compiler if this attribute is omitted. MuJoCo does not use these
parameters in any internal computations; instead they are available for custom computations. The parser allows arrays
of arbitrary length in the XML, and the compiler later resizes them to length nuser_XXX.
array. This interacts with the corresponding "nuser_XXX" attribute of the :ref:`size <size>` element. If for example we
set :at:`nuser_geom` to 5, then every geom in mjModel will have a custom array of 5 real-valued parameters. These geom-
specific parameters are either defined in the MJCF file via the :at:`user` attribute of :ref:`geom <geom>`, or set to 0
by the compiler if this attribute is omitted. The default value of all "nuser_XXX" attributes is -1, which instructs the
compiler to automatically set this value to the length of the maximum associated :at:`user` attribute defined in the
model. MuJoCo does not use these parameters in any internal computations; instead they are available for custom
computations. The parser allows arrays of arbitrary length in the XML, and the compiler later resizes them to length
nuser_XXX.
Some element-specific parameters that are normally used in internal computations can also be used in custom
computations. This is done by installing user callbacks which override parts of the simulation pipeline. For example,
@@ -483,12 +485,12 @@ well as solver statistics per iteration. We can offer the following general guid
- The constraint Jacobian should be dense for small models and sparse for large models. The default setting is 'auto';
it resolves to dense when the number of degrees of freedom is up to 60, and sparse over 60. Note however that the
threshold is better defined in terms of number of active constraints, which is model and behavior dependent.
- The choice between pyramidal and elliptic friction cones is a modeling choice rather than an algorithmic choice, i.e.
it leads to a different optimization problem solved with the same algorithms. Elliptic cones correspond more closely
to physical reality. However pyramidal cones can improve the performance of the algorithms - but not necessarily.
While the default is pyramidal, we recommend trying the elliptic cones. When contact slip is a problem, the best way
to suppress it is to use elliptic cones, large impratio, and the Newton algorithm with very small tolerance. If that
is not sufficient, enable the Noslip solver.
- The choice between pyramidal and elliptic friction cones is a modeling choice rather than an algorithmic choice,
i.e., it leads to a different optimization problem solved with the same algorithms. Elliptic cones correspond more
closely to physical reality. However pyramidal cones can improve the performance of the algorithms - but not
necessarily. While the default is pyramidal, we recommend trying the elliptic cones. When contact slip is a problem,
the best way to suppress it is to use elliptic cones, large impratio, and the Newton algorithm with very small
tolerance. If that is not sufficient, enable the Noslip solver.
- The Newton algorithm is the best choice for most models. It has quadratic convergence near the global minimum and
gets there in surprisingly few iterations - usually around 5, and rarely more than 20. It should be used with
aggressive tolerance values, say 1e-10, because it is capable of achieving high accuracy without added delay (due to
@@ -635,7 +637,7 @@ the shortcut :ref:`muscle <muscle>` is more convenient. As with all other actuat
production mechanism and the transmission are defined independently. Nevertheless, muscles only make (bio)physical
sense when attached to tendon or joint transmissions. For concreteness we will assume a tendon transmission here.
First we discuss length and length scaling. The range of feasible lengths of the transmission (i.e. MuJoCo tendon)
First we discuss length and length scaling. The range of feasible lengths of the transmission (i.e., MuJoCo tendon)
will play an important role; see :ref:`Length range <CLengthRange>` section above. In biomechanics, a muscle and a
tendon are attached in series and form a muscle-tendon actuator. Our convention is somewhat different: in MuJoCo the
entity that has spatial properties (in particular length and velocity) is the tendon, while the muscle is an abstract
@@ -684,7 +686,7 @@ force. We multiply the scaled force by a muscle-specific constant F0 to obtain t
actuator_force = - FLV(L, V, act) \* F0
The negative sign is because positive muscle activation generates pulling force. The constant F0 is the peak active
force at zero velocity. It is related to the muscle thickness (i.e. physiological cross-sectional area or PCSA). If
force at zero velocity. It is related to the muscle thickness (i.e., physiological cross-sectional area or PCSA). If
known, it can be set with the attribute force of element :ref:`muscle <muscle>`. If it is not known, we
set it to -1 which is the default. In that case we rely on the fact that larger muscles tend to act on joints that
move more weight. The attribute scale defines this relationship as:
@@ -787,7 +789,7 @@ instability. In practice tendons are quite stiff, and their effect can be captur
curve corresponding to the inelastic case (Zajac 89). This can be done in MuJoCo by shortening the muscle operating
range.
Pennation angle (i.e. the angle between the muscle and the line of force) is not modeled in MuJoCo and is assumed to
Pennation angle (i.e., the angle between the muscle and the line of force) is not modeled in MuJoCo and is assumed to
be 0. This effect can be approximated by scaling down the muscle force and also adjusting the operating range.
Tendon wrapping is also more limited in MuJoCo. We allow spheres and infinite cylinders as wrapping objects, and require
@@ -1064,14 +1066,14 @@ is a grouping element for XML purposes and would violate the MJCF format if incl
This functionality enables modular MJCF models; see the MPL family of models in the model library. One example of
modularity is constructing a model of a robot (which tends to be elaborate) and then including it in multiple
"scenes", i.e. MJCF models defining the objects in the robot's environment. Another example is creating a file with
"scenes", i.e., MJCF models defining the objects in the robot's environment. Another example is creating a file with
commonly used assets (say materials with carefully adjusted rgba values) and including it in multiple models which
reference those assets.
The included files are not required to be valid MJCF files on their own, but they usually are. Indeed we have designed
this mechanism to allow MJCF models to be included in other MJCF models. To make this possible, repeated MJCF sections
are allowed even when that does not make sense semantically in the context of a single model. For example, we allow
the kinematic tree to have multiple roots (i.e. multiple :el:`worldbody` elements) which are merged automatically by
the kinematic tree to have multiple roots (i.e., multiple :el:`worldbody` elements) which are merged automatically by
the parser. Otherwise including robots into scenes would be impossible.
The flexibility of repeated MCJF sections comes at a price: global settings that apply to the entire model, such as
@@ -1260,7 +1262,7 @@ in a visible way, and the energy fluctuates around the initial value instead of
Model sizes
~~~~~~~~~~~
MuJoCo pre-allocates all the memory needed at runtime in mjData, and does not access the C/C++ memory manager after
MuJoCo preallocates all the memory needed at runtime in mjData, and does not access the C/C++ memory manager after
model creation. It is therefore essential to allocate enough memory. The allocation is controlled by three size
parameters specified in the :ref:`size <size>` element, namely the stack size :at:`nstack`, the
maximum number of contacts :at:`nconmax`, and the maximum number of scalar constraints :at:`njmax`. The default
@@ -1287,7 +1289,7 @@ model. If you only intend to use the CG solver, you can get away with significan
Motion capture
~~~~~~~~~~~~~~
Mocap bodies are static children of the world (i.e. have no joints) and their :at:`mocap` attribute is set to
Mocap bodies are static children of the world (i.e., have no joints) and their :at:`mocap` attribute is set to
"true". They can be used to input a data stream from a motion capture device into a MuJoCo simulation. Suppose you are
holding a VR controller, or an object instrumented with motion capture markers (e.g. Vicon), and want to have a
simulated object moving in the same way but also interacting with other simulated objects. There is a dilemma here:
+44 -14
View File
@@ -64,7 +64,7 @@ Tendon geometry
General actuation model
Designing a sufficiently rich actuation model while using a model-agnostic API is challenging. MuJoCo achieves this
goal by adopting an abstract actuation model that can have different types of transmission, force generation, and
internal dynamics (i.e. state variables which make the overall dynamics 3rd order). These components can be
internal dynamics (i.e., state variables which make the overall dynamics 3rd order). These components can be
instantiated so as to model motors, pneumatic and hydraulic cylinders, PD controllers, biological muscles and many
other actuators in a unified way.
@@ -89,7 +89,7 @@ Separation of model and data
this is done by the user.
- ``mjData`` contains all dynamic variables and intermediate results. It is used as a scratch pad where all
functions read their inputs and write their outputs -- which then become the inputs to subsequent stages in the
simulation pipeline. It also contains a pre-allocated and internally managed stack, so that the runtime module
simulation pipeline. It also contains a preallocated and internally managed stack, so that the runtime module
does not need to call memory allocation functions after the model is initialized.
``mjModel`` is constructed by the compiler. :ref:`mjData` is constructed at runtime, given
@@ -593,6 +593,36 @@ section is to preemptively clarify the aspects that are most likely to be confus
and a tutorial on selected topics. We will need to refer to material covered later in the documentation, but
nevertheless the text below is as self-contained and introductory as possible.
.. _Units:
Units are undefined
~~~~~~~~~~~~~~~~~~~
In MuJoCo basic physical units are undefined. The user may interpret the system of units as they choose, as long as it
is consistent. To understand this, consider an example: the dynamics of a 1 Meter spaceship that weighs 1 Kg and has a 1
Newton thruster are the same as those of a 1 cm spaceship that weighs 1 gram and has a 1 dyn thruster. This is because
both `MKS <https://en.wikipedia.org/wiki/MKS_system_of_units>`__ and `CGS
<https://en.wikipedia.org/wiki/Centimetre%E2%80%93gram%E2%80%93second_system_of_units>`__ are consistent systems of
units. This property allows the user to scale their model as they choose, which is useful when simulating very small or
very large things, to improve the numerical properties of the simulation.
That said, users are encouraged to use MKS, as there are two places where MuJoCo uses MKS-like default values:
- The default value of :ref:`gravity<option>` is (0, 0, -9.81), which corresponds to Earth surface gravity in MKS.
Note that this does not really define system of units to be MKS, since we might be using CGS on
`Enceladus <https://en.wikipedia.org/wiki/Enceladus>`__.
- The default value of :ref:`geom density<geom>` (used to infer body masses and inertias) is 1000, which corresponds to
the density of water in MKS.
Once a consistent system of basic units (length, mass, time) is chosen, all derived units correspond to this system, as
in `Dimensional Analysis <https://en.wikipedia.org/wiki/Dimensional_analysis>`__. For example if our model is
interpreted as MKS, then forces and torques are in Newton and Newton-Meter, respectively.
**Angles:** Although angles can be specified using degrees in MJCF (and indeed degrees are the
:ref:`default <compiler>`), internally all angles are `Radians <https://en.wikipedia.org/wiki/Radian>`__. So e.g., if we
are using MKS, angular velocities reported by :ref:`gyroscopes<sensor-gyro>` would be in rad/s while stiffness of hinge
joints would be in Nm/rad.
.. _NotObject:
Not object-oriented
@@ -724,14 +754,14 @@ and two geoms to one body in this case.
.. code:: XML
<mujoco>
<worldbody>
<body pos="0 0 0">
<geom type="sphere" size=".1" rgba=".9 .9 .1 1"/>
<geom type="capsule" pos="0 0 .1" size=".05 .1" rgba=".9 .9 .1 1"/>
<site type="box" pos="0 -.1 .3" size=".02 .02 .02" rgba=".9 .1 .9 1"/>
<site type="ellipsoid" pos="0 .1 .3" size=".02 .03 .04" rgba=".9 .1 .9 1"/>
</body>
</worldbody>
<worldbody>
<body pos="0 0 0">
<geom type="sphere" size=".1" rgba=".9 .9 .1 1"/>
<geom type="capsule" pos="0 0 .1" size=".05 .1" rgba=".9 .9 .1 1"/>
<site type="box" pos="0 -.1 .3" size=".02 .02 .02" rgba=".9 .1 .9 1"/>
<site type="ellipsoid" pos="0 .1 .3" size=".02 .03 .04" rgba=".9 .1 .9 1"/>
</body>
</worldbody>
</mujoco>
.. figure:: images/overview/bodygeomsite.png
@@ -784,7 +814,7 @@ When working in joint coordinates, you cannot simply set the position and orient
you want. To achieve that effect you would have to implement some form of inverse kinematics, which computes a (not
necessarily unique) set of joint coordinates for which the forward kinematics place the body where you want it to be.
The situation is different for floating bodies, i.e. bodies that are connected to the world with a free joint. The
The situation is different for floating bodies, i.e., bodies that are connected to the world with a free joint. The
positions and orientations as well as the linear and angular velocities of such bodies are explicitly represented in
``mjData.qpos`` and ``mjData.qvel``, and can therefore be manipulated directly. The general approach is to find the
addresses in qpos and qvel where the body's data are. Of course qpos and qvel represents joints and not bodies, so you
@@ -805,7 +835,7 @@ can be obtained as:
qveladr = m->jnt_dofadr[m->body_jntadr[bodyid]];
}
Now if everything went well (i.e. "myfloatingbody" was indeed a floating body), qposadr and qveladr are the addresses in
qpos and qvel where the data for our floating body/joint lives. The position data is 7 numbers (3D position followed by
unit quaternion) while the velocity data is 6 numbers (3D linear velocity followed by 3D angular velocity). These
Now if everything went well (i.e., "myfloatingbody" was indeed a floating body), qposadr and qveladr are the addresses
in qpos and qvel where the data for our floating body/joint lives. The position data is 7 numbers (3D position followed
by unit quaternion) while the velocity data is 6 numbers (3D linear velocity followed by 3D angular velocity). These
numbers can now be set to the desired pose and velocity of the body.
+213 -202
View File
@@ -129,10 +129,15 @@ mjrender.h   `(source) <https://github.com/deepmind/mujoco/blob/main/include/m
This file defines the primitive types and structures needed by the OpenGL renderer.
mjui.h   `(source) <https://github.com/deepmind/mujoco/blob/main/include/mjui.h>`__
This file defines the primitive types and structures needed by the UI framework.
mjtnum.h   `(source) <https://github.com/deepmind/mujoco/blob/main/include/mjtnum.h>`__
Defines MuJoCo's ``mjtNum`` floating-point type to be either ``double`` or ``float``. See :ref:`mjtNum`.
mjxmacro.h   `(source) <https://github.com/deepmind/mujoco/blob/main/include/mjxmacro.h>`__
This file is optional and is not included by mujoco.h. It defines :ref:`X Macros <tyXMacro>` that can
automate the mapping of mjModel and mjData into scripting languages, as well as other operations that require
accessing all fields of mjModel and mjData. See code sample :ref:`testxml.cc <saTestXML>`.
mjexport.h   `(source) <https://github.com/deepmind/mujoco/blob/main/include/mjexport.h>`__
Macros used for exporting public symbols from the MuJoCo library. This header should not be used directly by client
code.
glfw3.h
This file is optional and is not included by mujoco.h. It is the only header file needed for the GLFW library. See
code sample :ref:`simulate.cc <saSimulate>`.
@@ -379,9 +384,10 @@ is extracted from the diagnostic fields of mjData. It is a very useful tool for
constraint solver algorithms. The outputs of the sensors defined in the model are visualized as a bar graph.
Note that the profiler shows timing information collected with high-resolution timers. On Windows, depending on the
power settings, the OS may reduce the CPU frequency; this is because simulate.cc sleeps most of the time in order to
slow down to realtime. This results in inaccurate timings. To avoid this problem, change the Windows power plan so
that the minimum processor state is 100%.
power settings, the OS may reduce the CPU frequency; this is because `simulate.cc
<https://github.com/deepmind/mujoco/blob/main/sample/simulate.cc>`_ sleeps most of the time in order to slow down to
realtime. This results in inaccurate timings. To avoid this problem, change the Windows power plan so that the minimum
processor state is 100%.
.. _saRecord:
@@ -390,11 +396,12 @@ that the minimum processor state is 100%.
This code sample simulates the passive dynamics of a given model, renders it offscreen, reads the color and depth pixel
values, and saves them into a raw data file that can then be converted into a movie file with tools such as ffmpeg. The
rendering is simplified compared to simulate.cc because there is no user interaction, visualization options or timing;
instead we simply render with the default settings as fast as possible. The dimensions and number of multi-samples for
the offscreen buffer are specified in the MuJoCo model, while the simulation duration, frames-per-second to be rendered
(usually much less than the physics simulation rate), and output file name are specified as command-line arguments. For
example, a 5 second animation at 60 frames per second is created with:
rendering is simplified compared to `simulate.cc <https://github.com/deepmind/mujoco/blob/main/sample/simulate.cc>`_
because there is no user interaction, visualization options or timing; instead we simply render with the default
settings as fast as possible. The dimensions and number of multi-samples for the offscreen buffer are specified in the
MuJoCo model, while the simulation duration, frames-per-second to be rendered (usually much less than the physics
simulation rate), and output file name are specified as command-line arguments. For example, a 5 second animation at 60
frames per second is created with:
.. code-block:: Shell
@@ -456,12 +463,12 @@ more accurate. Here ``f`` is one of the functions
The code sample computes six Jacobian matrices, containing the derivative of each function with respect to its three
arguments. The results are stored in the array ``deriv``. All six Jacobian matrices are square, with dimensionality
equal to the number of degrees of freedom mjModel.nv. When the model configuration includes quaternion joints,
equal to the number of degrees of freedom ``mjModel.nv``. When the model configuration includes quaternion joints,
mjData.qpos has larger dimensionality than the other vectors, however the derivative is only defined in the tangent
space to the configuration manifold. This is why, when differentiating with respect to the elements of mjData.qpos, we
do not directly add ``eps`` but instead use the function :ref:`mju_quatIntegrate`
to perturb the quaternion in the tangent space, keeping it normalized. This technique should also be used in any other
situation where quaternions need to be perturbed.
space to the configuration manifold. This is why, when differentiating with respect to the elements of ``mjData.qpos``,
we do not directly add ``eps`` but instead use the function :ref:`mju_quatIntegrate` to perturb the quaternion in the
tangent space, keeping it normalized. This technique should also be used in any other situation where quaternions need
to be perturbed.
There are some important subtleties in this code that improve speed as well as accuracy. To speed up the computation,
we re-use intermediate results whenever possible. This relies on the skip mechanism described under :ref:`forward
@@ -475,9 +482,9 @@ Accuracy depends on the value of ``eps`` which is user-adjustable, as well as th
of forward dynamics however, the function evaluation involves an iterative constraint solver, and this must be handled
with care. In general, the difference between ``f(x+eps)`` and ``f(x)`` is very small, thus any noise affecting the
two function evaluations differently can make the resulting derivatives meaningless. Different warm-starts or
different number of solver iterations can act as such noise here. Therefore we fix the warm-start mjData.qacc to a
different number of solver iterations can act as such noise here. Therefore we fix the warm-start ``mjData.qacc`` to a
value pre-computed at the center point, using ``nwarmup`` extra major iterations to obtain a more accurate warm-start.
We also fix the number of solver iterations to ``niter`` and set mjModel.opt.tolerance = 0; this disables the early
We also fix the number of solver iterations to ``niter`` and set ``mjModel.opt.tolerance = 0``; this disables the early
termination mechanism. Note that the original simulation options are restored in the serial code which advances the
state.
@@ -485,18 +492,19 @@ We emphasize that the above subtleties are not high-order corrections that can b
of unilateral constraints, numerical derivatives are hard to compute and there is no shortcut around it; indeed they
would not even be defined if it wasn't for our soft-constraint model. Making the constraints softer results in more
accurate results. This effect is so strong that in some situations it makes sense to intentionally work with the wrong
model, i.e. a model that is softer than desired, so as to obtain more accurate derivatives.
model, i.e., a model that is softer than desired, so as to obtain more accurate derivatives.
.. _saUItools:
uitools
~~~~~~~
`(uitools.h) <https://github.com/deepmind/mujoco/blob/main/sample/uitools.h>`_
`(uitools.c) <https://github.com/deepmind/mujoco/blob/main/sample/uitools.c>`_
This is not a stand-alone code sample, but rather a small utility used to hook up the new UI to GLFW. It is used in
simulate.cc and can also be used in user projects that involve the new UI. If GLFW is replaced with a different window
library, this is the only file that would have to be changed in order to access the UI functionality.
`(uitools.h) <https://github.com/deepmind/mujoco/blob/main/sample/uitools.h>`_ `(uitools.c)
<https://github.com/deepmind/mujoco/blob/main/sample/uitools.c>`_ This is not a stand-alone code sample, but rather a
small utility used to hook up the new UI to GLFW. It is used in `simulate.cc
<https://github.com/deepmind/mujoco/blob/main/sample/simulate.cc>`_ and can also be used in user projects that involve
the new UI. If GLFW is replaced with a different window library, this is the only file that would have to be changed in
order to access the UI functionality.
.. _Simulation:
@@ -514,7 +522,7 @@ be discussed later.
mjModel and mjData should never be allocated directly by the user. Instead they are allocated and initialized by the
corresponding API functions. These are very elaborate data structures, containing (arrays of) other structures,
pre-allocated data arrays for all intermediate results, as well as an :ref:`internal stack <siStack>`. Our strategy is
preallocated data arrays for all intermediate results, as well as an :ref:`internal stack <siStack>`. Our strategy is
to allocate all necessary heap memory at the beginning of the simulation, and free it after the simulation is done, so
that we never have to call the C memory allocation and deallocation functions during the simulation. This is done for
speed, avoidance of memory fragmentation, future GPU portability, and ease of managing the state of the entire
@@ -532,7 +540,7 @@ available options are
mjModel* m = mj_loadXML("mymodel.xml", NULL, errstr, errstr_sz);
// option 2: parse and compile XML from virtual file system
mjModel* m = mj_loadXML("mymodel.xml", vfs, errstr_sz);
mjModel* m = mj_loadXML("mymodel.xml", vfs, errstr, errstr_sz);
// option 3: load precompiled model from MJB file
mjModel* m = mj_loadModel("mymodel.mjb", NULL);
@@ -613,12 +621,12 @@ The default (and recommended) way to control the system is to implement a contro
mju_scl(d->ctrl, d->qvel, -0.1, m->nv);
}
This illustrates two concepts. First, we are checking if the number of controls mjModel.nu equals the number of dofs
mjModel.nv. In general, the same callback may be used with multiple models depending on how the user code is structured,
and so it is a good idea to check the model dimensions in the callback. Second, MuJoCo has a library of BLAS-like
functions that are very useful; indeed a large part of the code base consists of calling such functions internally. The
:ref:`mju_scl` function above scales the velocity vector mjData.qvel by a constant feedback
gain and copies the result into the control vector mjData.ctrl. To install this callback, we simply assign it to the
This illustrates two concepts. First, we are checking if the number of controls ``mjModel.nu`` equals the number of
DoFs ``mjModel.nv``. In general, the same callback may be used with multiple models depending on how the user code is
structured, and so it is a good idea to check the model dimensions in the callback. Second, MuJoCo has a library of
BLAS-like functions that are very useful; indeed a large part of the code base consists of calling such functions
internally. The :ref:`mju_scl` function above scales the velocity vector ``mjData.qvel`` by a constant feedback
gain and copies the result into the control vector ``mjData.ctrl``. To install this callback, we simply assign it to the
global control callback pointer :ref:`mjcb_control`:
.. code-block:: C
@@ -631,10 +639,10 @@ signal is needed by the simulation pipeline, and as a result we will end up simu
damping does not really do justice to the notion of control, and is better implemented as a passive joint property,
but these are finer points).
Instead of relying on a control callback, we could set the control vector mjData.ctrl directly. Alternatively we could
set applied forces as explained in :ref:`state and control <siStateControl>`. If we could compute these
control-related quantities before mj_step is called, then the simulation loop for the controlled dynamics (without
using a control callback) would become
Instead of relying on a control callback, we could set the control vector ``mjData.ctrl`` directly. Alternatively we
could set applied forces as explained in :ref:`state and control <siStateControl>`. If we could compute these control-
related quantities before mj_step is called, then the simulation loop for the controlled dynamics (without using a
control callback) would become
.. code-block:: C
@@ -646,18 +654,18 @@ using a control callback) would become
Why would we not be able to compute the controls before mj_step is called? After all, isn't this what causality means?
The answer is subtle but important, and has to do with the fact that we are simulating in discrete time. The top-level
simulation function mj_step basically does two things: compute the :ref:`forward dynamics <siForward>` in continuous
time, and then integrate over a time period specified by mjModel.opt.timestep. Forward dynamics computes the
acceleration mjData.qacc at time mjData.time, given the :ref:`state and control <siStateControl>` at time mjData.time.
The numerical integrator then advances the state and time to mjData.time + mjModel.opt.timestep. Now, the control is
required to be a function of the state at time mjData.time. However a general feedback controller can be a very complex
function, depending on various features of the state - in particular all the features computed by MuJoCo as intermediate
results of the simulation. These may include contacts, Jacobians, passive forces. None of these quantities are available
before mj_step is called (or rather, they are available but outdated by one time step). In contrast, when mj_step calls
our control callback, it does so as late in the computation as possible - namely after all the intermediate results
dependent on the state but not on the control have been computed.
simulation function ``mj_step`` basically does two things: compute the :ref:`forward dynamics <siForward>` in continuous
time, and then integrate over a time period specified by ``mjModel.opt.timestep``. Forward dynamics computes the
acceleration ``mjData.qacc`` at time ``mjData.time``, given the :ref:`state and control <siStateControl>` at time
``mjData.time``. The numerical integrator then advances the state and time to ``mjData.time + mjModel.opt.timestep``.
Now, the control is required to be a function of the state at time ``mjData.time``. However a general feedback
controller can be a very complex function, depending on various features of the state - in particular all the features
computed by MuJoCo as intermediate results of the simulation. These may include contacts, Jacobians, passive forces.
None of these quantities are available before ``mj_step`` is called (or rather, they are available but outdated by one
time step). In contrast, when ``mj_step`` calls our control callback, it does so as late in the computation as possible
- namely after all the intermediate results dependent on the state but not on the control have been computed.
The same effect can be achieved without using a control callback. This is done by breaking mj_step in two parts:
The same effect can be achieved without using a control callback. This is done by breaking ``mj_step`` in two parts:
before the control is needed, and after the control is needed. The simulation loop now becomes
.. code-block:: C
@@ -672,7 +680,7 @@ before the control is needed, and after the control is needed. The simulation lo
There is one complication however: this only works with Euler integration. The Runge-Kutta integrator (as well as other
advanced integrators we plan to implement) need to evaluate the entire dynamics including the feedback control law
multiple times per step, which can only be done using a control callback. But with Euler integration, the above
separation of mj_step into :ref:`mj_step1` and :ref:`mj_step2` is sufficient to provide the control law with the
separation of ``mj_step`` into :ref:`mj_step1` and :ref:`mj_step2` is sufficient to provide the control law with the
intermediate results of the computation.
To make the above discussion more clear, we provide the internal implementation of mj_step, mj_step1 and mj_step2,
@@ -705,7 +713,7 @@ The control callback (if any) is called from within the forward dynamics functio
Next we show the implementation of the two-part stepping approach, although the specifics will make sense only after
we explain the :ref:`forward dynamics <siForward>` later. Note that the control callback is now called directly, since
we have essentially unpacked the forward dynamics function. Note also that we always call the Euler integrator in
mj_step2 regardless of the setting of mjModel.opt.integrator.
mj_step2 regardless of the setting of ``mjModel.opt.integrator``.
.. code-block:: C
@@ -767,19 +775,19 @@ The state vector in MuJoCo is:
For a second-order dynamical system the state contains only position and velocity, however MuJoCo can also model
actuators (such as cylinders and biological muscles) that have their own activation states assembled in the vector
mjData.act. While the physics model is time-invariant, user-defined control laws may be time-varying; in particular
control laws obtained from trajectory optimizers would normally be indexed by mjData.time.
``mjData.act``. While the physics model is time-invariant, user-defined control laws may be time-varying; in particular
control laws obtained from trajectory optimizers would normally be indexed by ``mjData.time``.
The reason for the "official" caveat above is because user callbacks may store additional state variables that change
over time and affect the callback outputs; indeed the field mjData.userdata exists mostly for that purpose. Other
state-like quantities that are part of mjData and are treated as inputs by forward dynamics are mjData.mocap_pos and
mjData.mocap_quat. These quantities are unusual in that they are meant to change at each time step (normally driven by
a motion capture device), however this change is implemented by the user, while the simulator treats them as
constants. In that sense they are no different from all the constants in mjModel, or the function callback pointers
set by the user: such constants affect the computation, but are not part of the state vector of a dynamical system.
over time and affect the callback outputs; indeed the field ``mjData.userdata`` exists mostly for that purpose. Other
state-like quantities that are part of mjData and are treated as inputs by forward dynamics are ``mjData.mocap_pos`` and
mjData.mocap_quat. These quantities are unusual in that they are meant to change at each time step (normally driven by a
motion capture device), however this change is implemented by the user, while the simulator treats them as constants. In
that sense they are no different from all the constants in mjModel, or the function callback pointers set by the user:
such constants affect the computation, but are not part of the state vector of a dynamical system.
The warm-start mechanism in the constraint solver effectively introduces another state variable. This mechanism uses
the output of forward dynamics from the previous time step, namely the acceleration vector mjData.qacc, to estimate
the output of forward dynamics from the previous time step, namely the acceleration vector ``mjData.qacc``, to estimate
the current constraint forces via inverse dynamics. This estimate then initializes the optimization algorithm in the
solver. If this algorithm runs until convergence the warm-start will affect the speed of convergence but not the final
solution (since the underlying optimization problem is convex and does not have local minima), but in practice the
@@ -791,8 +799,8 @@ Next we turn to the controls and applied forces. The control vector in MuJoCo is
u = (mjData.ctrl, mjData.qfrc_applied, mjData.xfrc_applied)
These quantities specify control signals (mjData.ctrl) for the actuators defined in the model, or directly apply
forces and torques specified in joint space (mjData.qfrc_applied) or in Cartesian space (mjData.xfrc_applied).
These quantities specify control signals (``mjData.ctrl``) for the actuators defined in the model, or directly apply
forces and torques specified in joint space (``mjData.qfrc_applied``) or in Cartesian space (mjData.xfrc_applied).
Finally, calling mj_forward which corresponds to the abstract dynamics function ``f(t,x,u)`` computes the
time-derivative of the state vector. The corresponding fields of mjData are
@@ -801,8 +809,8 @@ time-derivative of the state vector. The corresponding fields of mjData are
dx/dt = f(t,x,u) = (1, mjData.qvel, mjData.qacc, mjData.act_dot)
In the presence of quaternions (i.e. when free or ball joints are used), the position vector mjData.qpos has higher
dimensionality than the velocity vector mjData.qvel and so this is not a simple time-derivative in the sense of
In the presence of quaternions (i.e., when free or ball joints are used), the position vector ``mjData.qpos`` has higher
dimensionality than the velocity vector ``mjData.qvel`` and so this is not a simple time-derivative in the sense of
scalars, but instead takes quaternion algebra into account.
To illustrate how the simulation state can be manipulated, suppose we have two mjData pointers src and dst
@@ -851,9 +859,9 @@ If the user has installed a control callback :ref:`mjcb_control` different from
pointer), the user callback would be expected to set some of the above fields to non-zero. Note that MuJoCo will not
clear these controls/forces at the end of the time step. This is the responsibility of the user.
Also relevant in this context is the function :ref:`mj_resetData`. It sets mjData.qpos equal to the model reference
configuration mjModel.qpos0; mjData.mocap_pos and mjData.mocap_quat equal to the corresponding fixed body poses from
mjModel; and all other state and control variables to 0.
Also relevant in this context is the function :ref:`mj_resetData`. It sets ``mjData.qpos`` equal to the model reference
configuration ``mjModel.qpos0``, ``mjData.mocap_pos`` and ``mjData.mocap_quat`` equal to the corresponding fixed body
poses from mjModel; and all other state and control variables to 0.
.. _siForward:
@@ -861,7 +869,7 @@ Forward dynamics
~~~~~~~~~~~~~~~~
The goal of forward dynamics is to compute the time-derivative of the state, namely the acceleration vector
mjData.qacc and the activation time-derivative mjData.act_dot. Along the way it computes everything else needed to
mjData.qacc and the activation time-derivative ``mjData.act_dot``. Along the way it computes everything else needed to
simulate the dynamics, including active contacts and other constraints, joint-space inertia and its LTDL
decomposition, constraint forces, sensor data and so on. All these intermediate results are available in mjData and
can be used in custom computations. As illustrated in the :ref:`simulation loop <siSimulation>` section above, the
@@ -951,31 +959,31 @@ inverse dynamics (with the acceleration computed at the previous time step) to w
solver in forward dynamics.
The inputs to inverse dynamics are the same as the state vector in forward dynamics as illustrated in :ref:`state and
control <siStateControl>`, but without mjData.act and mjData.time. Assuming no callbacks that depend on user-defined
state variables, the inputs to inverse dynamics are the following fields of mjData:
control <siStateControl>`, but without ``mjData.act`` and ``mjData.time``. Assuming no callbacks that depend on user-
defined state variables, the inputs to inverse dynamics are the following fields of mjData:
::
(mjData.qpos, mjData.qvel, mjData.qacc, mjData.mocap_pos, mjData.mocap_quat)
The main output is mjData.qfrc_inverse. This is the force that must have acted on the system in order to achieve the
observed acceleration mjData.qacc. If forward dynamics were to be computed exactly, by running the iterative solver to
full convergence, we would have
The main output is ``mjData.qfrc_inverse``. This is the force that must have acted on the system in order to achieve the
observed acceleration ``mjData.qacc``. If forward dynamics were to be computed exactly, by running the iterative solver
to full convergence, we would have
::
mjData.qfrc_inverse = mjData.qfrc_applied + Jacobian'*mjData.xfrc_applied + mjData.qfrc_actuator
where mjData.qfrc_actuator is the joint-space force produced by the actuators and the Jacobian is the mapping from
joint to Cartesian space. When the "fwdinv" flag in mjModel.opt.enableflags is set, the above identity is used to
monitor the quality of the forward dynamics solution. In particular, the two components of mjData.solver_fwdinv are
where ``mjData.qfrc_actuator`` is the joint-space force produced by the actuators and the Jacobian is the mapping from
joint to Cartesian space. When the "fwdinv" flag in ``mjModel.opt.enableflags`` is set, the above identity is used to
monitor the quality of the forward dynamics solution. In particular, the two components of ``mjData.solver_fwdinv`` are
set to the L2 norm of the difference between the forward and inverse solutions, in terms of joint forces and
constraint forces respectively.
Similar to forward dynamics, mj_inverse internally calls :ref:`mj_inverseSkip` with skip arguments (mjSTAGE_NONE, 0).
The skip mechanism is the same as in forward dynamics, and can be used to speed up structured sampling. The result
mjData.qfrc_inverse is obtained by using the Recursive Newton-Euler algorithm to compute the net force acting on the
system, and then subtracting from it all internal forces.
Similar to forward dynamics, ``mj_inverse`` internally calls :ref:`mj_inverseSkip` with skip arguments
``(mjSTAGE_NONE, 0)``. The skip mechanism is the same as in forward dynamics, and can be used to speed up structured
sampling. The result ``mjData.qfrc_inverse`` is obtained by using the Recursive Newton-Euler algorithm to compute the
net force acting on the system, and then subtracting from it all internal forces.
Inverse dynamics can be used as an analytical tool when experimental data are available. This is common in robotics as
well as biomechanics. It can also be used to compute the joint torques needed to drive the system along a given
@@ -1073,7 +1081,7 @@ Model changes
The MuJoCo model contained in mjModel is supposed to represent constant physical properties of the system, and in
theory should not change after compilation. Of course in practice things are not that simple. It is often desirable to
change the physics options in mjModel.opt, so as to experiment with different aspects of the physics or to create
change the physics options in ``mjModel.opt``, so as to experiment with different aspects of the physics or to create
custom computations. Indeed these options are designed in such a way that the user can make arbitrary changes to them
between time steps.
@@ -1082,16 +1090,16 @@ because that may result in incorrect sizes or indexing. This rule does not hold
parameters such as inertias are expected to obey certain properties. On the other hand, some structural parameters
such as object types may be possible to change, but that depends on whether any sizes or indexes depend on them.
Arrays of type mjtByte can be changed safely, since they are binary indicators that enable and disable certain
features. The only exception here is mjModel.tex_rgb which is texture data represented as mjtByte.
features. The only exception here is ``mjModel.tex_rgb`` which is texture data represented as mjtByte.
When changing mjModel fields that corresponds to resources uploaded to the GPU, the user must also call the
corresponding upload function: mjr_uploadTexture, mjr_uploadMesh, mjr_uploadHField. Otherwise the data used for
corresponding upload function: ``mjr_uploadTexture``, ``mjr_uploadMesh``, ``mjr_uploadHField``. Otherwise the data used for
simulation and for rendering will no longer be consistent.
A related consideration has to do with changing real-valued fields of mjModel that have been used by the compiler to
compute other real-valued fields: if we make a change, we want it to propagate. That is what the function
:ref:`mj_setConst` does: it updates all derived fields of mjModel. These are fields whose names end with "0",
corresponding to precomputed quantities when the model is in the reference configuration mjModel.qpos0.
corresponding to precomputed quantities when the model is in the reference configuration ``mjModel.qpos0``.
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
@@ -1123,17 +1131,17 @@ essential to keep it in mind at all times. All MuJoCo utility functions that ope
difference between row-major and column-major formats.
When possible, MuJoCo exploits sparsity. This can make all the difference between O(N) and O(N^3) scaling. The inertia
matrix mjData.qM and its LTDL factorization mjData.qLD are always represented as sparse, using a custom indexing
format designed for matrices that correspond to tree topology. The functions :ref:`mj_factorM`, :ref:`mj_solveM`,
:ref:`mj_solveM2` and :ref:`mj_mulM` are used for sparse factorization, substitution and matrix-vector multiplication.
The user can also convert these matrices to dense format with the function :ref:`mj_fullM` although MuJoCo never does
that internally.
matrix ``mjData.qM`` and its LTDL factorization ``mjData.qLD`` are always represented as sparse, using a custom
indexing format designed for matrices that correspond to tree topology. The functions :ref:`mj_factorM`,
:ref:`mj_solveM`, :ref:`mj_solveM2` and :ref:`mj_mulM` are used for sparse factorization, substitution and
matrix-vector multiplication. The user can also convert these matrices to dense format with the function
:ref:`mj_fullM` although MuJoCo never does that internally.
The constraint Jacobian matrix mjData.efc_J is represented as sparse whenever the sparse Jacobian option is enabled.
The function :ref:`mj_isSparse` can be used to determine if sparse format is currently in use. In that case the
transposed Jacobian mjData.efc_JT is also computed, and the inverse constraint inertia mjData.efc_AR becomes sparse.
Sparse matrices are stored in the compressed sparse row (CSR) format. For a generic matrix A with dimensionality
m-by-n, this format is:
The constraint Jacobian matrix ``mjData.efc_J`` is represented as sparse whenever the sparse Jacobian option is
enabled. The function :ref:`mj_isSparse` can be used to determine if sparse format is currently in use. In that case
the transposed Jacobian ``mjData.efc_JT`` is also computed, and the inverse constraint inertia ``mjData.efc_AR``
becomes sparse. Sparse matrices are stored in the compressed sparse row (CSR) format. For a generic matrix A with
dimensionality m-by-n, this format is:
======== ====== ============================================
Variable Size Meaning
@@ -1163,13 +1171,13 @@ translational component. We do not provide utility functions for working with th
scope here. See Roy Featherstone's webpage on `Spatial Algebra <http://royfeatherstone.org/spatial/>`__. The unusual
order (rotation before translation) is based on this material, and was apparently standard convention in the past.
The data structures mjModel and mjData contain many pointers to pre-allocated buffers. The constructors of these data
structures (mj_makeModel and mj_makeData) allocate one large buffer, namely mjModel.buffer and mjData.buffer, and then
partition it and set all the other pointers in it. mjData also contains a stack outside this main buffer, as discussed
below. Even if two pointers appear one after the other, say mjData.qpos and mjData.qvel, do not assume that the data
arrays are contiguous and there is no gap between them. The constructors implement byte-alignment for each data array,
and skip bytes when necessary. So if you want to copy mjData.qpos and mjData.qvel, the correct way to do it is the
hard way:
The data structures mjModel and mjData contain many pointers to preallocated buffers. The constructors of these data
structures (mj_makeModel and mj_makeData) allocate one large buffer, namely ``mjModel.buffer`` and ``mjData.buffer``,
and then partition it and set all the other pointers in it. mjData also contains a stack outside this main buffer, as
discussed below. Even if two pointers appear one after the other, say ``mjData.qpos`` and ``mjData.qvel``, do not
assume that the data arrays are contiguous and there is no gap between them. The constructors implement byte-alignment
for each data array, and skip bytes when necessary. So if you want to copy ``mjData.qpos`` and ``mjData.qvel``, the
correct way to do it is the hard way:
.. code-block:: C
@@ -1180,10 +1188,10 @@ hard way:
// DO NOT do this, there may be padding at the end of d->qpos
mju_copy(myqposqvel, d->qpos, m->nq + m->nv);
The :ref:`X Macros <tyXMacro>` defined in the optional header file mjxmacro.h can be used to automate allocation of data
structure that match mjModel and mjData, for example when writing a MuJoCo wrapper for a scripting language. In the code
sample :ref:`testxml.cc <saTestXML>` we use these unusual macros to compare all data arrays from two instances of
mjModel and find the one with the largest difference. Apparently X Macros were invented in the 1960's for assembly
The :ref:`X Macros <tyXMacro>` defined in the optional header file ``mjxmacro.h`` can be used to automate allocation of
data structure that match mjModel and mjData, for example when writing a MuJoCo wrapper for a scripting language. In
the code sample :ref:`testxml.cc <saTestXML>` we use these unusual macros to compare all data arrays from two instances
of mjModel and find the one with the largest difference. Apparently X Macros were invented in the 1960's for assembly
language, and remain a great idea.
.. _siStack:
@@ -1191,23 +1199,23 @@ language, and remain a great idea.
Internal stack
~~~~~~~~~~~~~~
MuJoCo allocates and manages its own stack of mjtNums. mjData.stack is the pointer to the pre-allocated memory buffer.
mjData.nstack is the maximum number of mjtNums that the stack can hold, as determined by the :at:`nstack` attribute of
the :ref:`size <size>` element in MJCF. mjData.pstack is the first available address in the stack; this is our custom
stack pointer.
MuJoCo allocates and manages its own stack of mjtNums. ``mjData.stack`` is the pointer to the preallocated memory
buffer. ``mjData.nstack`` is the maximum number of mjtNums that the stack can hold, as determined by the :at:`nstack`
attribute of the :ref:`size <size>` element in MJCF. ``mjData.pstack`` is the first available address in the stack;
this is our custom stack pointer.
Most top-level MuJoCo functions allocate space on the stack, use it for internal computations, and then deallocate it.
They cannot do this with the regular C stack because the allocation size is determined dynamically at runtime. And
calling the heap memory management functions would be inefficient and result in fragmentation - thus a custom stack.
When any MuJoCo function is called, upon return the value of mjData.pstack is the same. The only exception is the
function :ref:`mj_resetData` and its variants: they set mjData.pstack = 0. Note that this function is called
internally when an instability is detected in mj_step, mj_step1 and mj_step2. So if user functions take advantage of
the custom stack (as they should), this needs to be done in-between MuJoCo calls that have the potential to reset the
simulation.
When any MuJoCo function is called, upon return the value of ``mjData.pstack`` is the same. The only exception is the
function :ref:`mj_resetData` and its variants: they set ``mjData.pstack = 0``. Note that this function is called
internally when an instability is detected in ``mj_step``, ``mj_step1`` and ``mj_step2``. So if user functions take
advantage of the custom stack (as they should), this needs to be done in-between MuJoCo calls that have the potential
to reset the simulation.
Below is the general template for using the custom stack in user code. This assumes that mjData\* d is defined in the
scope. If not, saving and restoring the stack pointer should be done manually instead of using the :ref:`mjMARKSTACK`
and :ref:`mjFREESTACK` macros.
Below is the general template for using the custom stack in user code. This assumes that ``mjData\* d`` is defined in
the scope. If not, saving and restoring the stack pointer should be done manually instead of using the
:ref:`mjMARKSTACK` and :ref:`mjFREESTACK` macros.
.. code-block:: C
@@ -1289,20 +1297,20 @@ in the diagnostics section at the beginning of mjData.
When the simulator encounters a situation that is not a terminal error but is nevertheless suspicious and likely to
result in inaccurate numerical results, it triggers a warning. There are several possible warning types, indexed by
the enum type :ref:`mjtWarning`. The array mjData.warning contains one :ref:`mjWarningStat` data structure per warning
type, indicating how many times each warning type has been triggered since the last reset and any information about
the warning (usually the index of the problematic model element). The counters are cleared upon reset. When a warning
of a given type is first triggered, the warning text is also printed by mju_warning as documented in :ref:`error and
memory <siError>` above. All this is done by the function :ref:`mj_warning` which the simulator calls internally when
it encounters a warning. The user can also call this function directly to emulate a warning.
the enum type :ref:`mjtWarning`. The array ``mjData.warning`` contains one :ref:`mjWarningStat` data structure per
warning type, indicating how many times each warning type has been triggered since the last reset and any information
about the warning (usually the index of the problematic model element). The counters are cleared upon reset. When a
warning of a given type is first triggered, the warning text is also printed by mju_warning as documented in
:ref:`error and memory <siError>` above. All this is done by the function :ref:`mj_warning` which the simulator calls
internally when it encounters a warning. The user can also call this function directly to emulate a warning.
When a model needs to be optimized for high-speed simulation, it is important to know where in the pipeline the CPU
time is spent. This can in turn suggest which parts of the model to simplify or how to design the user application.
MuJoCo provides an extensive profiling mechanism. It involves multiple timers indexed by the enum type
:ref:`mjtTimer`. Each timer corresponds to a top-level API function, or to a component of such a function. Similar to
warnings, timer information accumulates and is only cleared on reset. The array mjData.timer contains one
:ref:`mjTimerStat` data structure per timer. The average duration per call for a given timer (corresponding to mj_step
in the example below) can be computed as:
warnings, timer information accumulates and is only cleared on reset. The array ``mjData.timer`` contains one
:ref:`mjTimerStat` data structure per timer. The average duration per call for a given timer (corresponding to
``mj_step`` in the example below) can be computed as:
.. code-block:: C
@@ -1314,43 +1322,46 @@ to implement high-resolution timers in C without bringing in additional dependen
does not need timing, and in that case there is no reason to call timing functions.
One part of the simulation pipeline that needs to be monitored closely is the iterative constraint solver. The
simplest diagnostic here is mjData.solver_iter which shows how many iterations the solver took on the last call to
mj_step or mj_forward. Note that the solver has tolerance parameters for early termination, so this number is usually
smaller than the maximum number of iterations allowed. The array mjData.solver contains one :ref:`mjSolverStat` data
structure per iteration of the constraint solver, with information about the constraint state and line search.
simplest diagnostic here is ``mjData.solver_iter`` which shows how many iterations the solver took on the last call to
mj_step or ``mj_forward``. Note that the solver has tolerance parameters for early termination, so this number is
usually smaller than the maximum number of iterations allowed. The array ``mjData.solver`` contains one
:ref:`mjSolverStat` data structure per iteration of the constraint solver, with information about the constraint state
and line search.
When the option :at:`fwdinv` is enabled in mjModel.opt.enableflags, the field mjData.fwdinv is also populated. It
contains the difference between the forward and inverse dynamics, in terms of generalized forces and constraint
When the option :at:`fwdinv` is enabled in ``mjModel.opt.enableflags``, the field ``mjData.fwdinv`` is also populated.
It contains the difference between the forward and inverse dynamics, in terms of generalized forces and constraint
forces. Recall that that the inverse dynamics use analytical formulas and are always exact, thus any discrepancy is
due to poor convergence of the iterative solver in the forward dynamics. The numbers in mjData.solver near termination
have similar order-of-magnitude as the numbers in mjData.fwdinv, but nevertheless these are two different diagnostics.
due to poor convergence of the iterative solver in the forward dynamics. The numbers in ``mjData.solver`` near
termination have similar order-of-magnitude as the numbers in ``mjData.fwdinv``, but nevertheless these are two
different diagnostics.
Since MuJoCo's runtime works with compiled models, memory is preallocated when a model is compiled or loaded. Recall the
:ref:`size <size>` element in MJCF, which has the attributes :at:`njmax`, :at:`nconmax` and :at:`nstack`. They determine
the maximum number of scalar constraints that can be active simultaneously, the maximum number of contact points that
can be included in mjData.contact, and the size of the internal stack. How is the user supposed to know what the
can be included in ``mjData.contact``, and the size of the internal stack. How is the user supposed to know what the
appropriate settings are? If there were a reliable recipe we would have implemented it in the compiler, but there isn't
one. The theoretical worst-case, namely all geoms contacting all other geoms, calls for huge allocation which is almost
never needed in practice. So our approach is to provide default settings in MJCF which are sufficient for most models,
and allow the user to adjust them manually with the above attributes. If the simulator runs out of stack space at
runtime it will trigger an error. If it runs out of space for contacts or scalar constraints, it will trigger a warning
and omit the contacts and constraints that do not fit in the allocated buffers. When such errors or warnings are
triggered, the user should adjust the sizes. The fields mjData.maxuse_stack, mjData.maxuse_con, mjData.maxuse_efc are
designed to help with this adjustment. They keep track of the maximum stack allocation, number of contacts and number of
scalar constraints respectively since the last reset. So one strategy is to make very large allocation, then monitor
these maxuse_XXX statistics during typical simulations, and use them to reduce the allocation. Of course modern
computers have so much memory that most users will not bother with such adjustment once they get rid of the
out-of-memory errors and warnings, but nevertheless we provide this mechanism for the perfectionist.
triggered, the user should adjust the sizes. The fields ``mjData.maxuse_stack``, ``mjData.maxuse_con``,
``mjData.maxuse_efc`` are designed to help with this adjustment. They keep track of the maximum stack allocation,
number of contacts and number of scalar constraints respectively since the last reset. So one strategy is to make very
large allocation, then monitor these ``maxuse_XXX`` statistics during typical simulations, and use them to reduce the
allocation. Of course modern computers have so much memory that most users will not bother with such adjustment once
they get rid of the out-of-memory errors and warnings, but nevertheless we provide this mechanism for the
perfectionist.
The kinetic and potential energy are computed and stored in mjData.energy when the corresponding flag in
mjModel.opt.enableflags is set. This can be used as another diagnostic. In general, simulation instability is
The kinetic and potential energy are computed and stored in ``mjData.energy`` when the corresponding flag in
``mjModel.opt.enableflags`` is set. This can be used as another diagnostic. In general, simulation instability is
associated with increasing energy. In some special cases (when all unilateral constraints, actuators and dissipative
forces are disabled) the underlying physical system is energy-conserving. In that case any temporal fluctuations in
the total energy indicate inaccuracies in numerical integration. For such systems the Runge-Kutta integrator has much
better performance than the default semi-implicit Euler integrator.
Finally, the user can implement additional diagnostics as needed. Two examples were provided in the code samples
testxml.cc and derivative.cc, where we computed model mismatches after save and load, and assessed the accuracy of the
``testxml.cc`` and ``derivative.cc``, where we computed model mismatches after save and load, and assessed the accuracy of the
numerical derivatives respectively. Key to such diagnostics is to implement two different algorithms or simulation
paths that compute the same quantity, and compare the results numerically. This type of sanity check is essential when
dealing with complex dynamical systems where we do not really know what the numerical output should be; if we knew
@@ -1365,30 +1376,30 @@ The derivative of any vector function with respect to its vector argument is cal
in multi-joint kinematics and dynamics, it refers to the derivative of some spatial quantity as a function of the
system configuration. In that case the Jacobian is also a linear map that operates on vectors in the (co)tangent space
to the configuration manifold - such as velocities, momenta, accelerations, forces. One caveat here is that the system
configuration encoded in mjData.qpos has dimensionality mjModel.nq, while the tangent space has dimensionality
mjModel.nv, and the latter is smaller when quaternion joints are present. So the size of the Jacobian matrix is
N-by-mjModel.nv where N is the dimensionality of the spatial quantity being differentiated.
configuration encoded in ``mjData.qpos`` has dimensionality ``mjModel.nq``, while the tangent space has dimensionality
``mjModel.nv``, and the latter is smaller when quaternion joints are present. So the size of the Jacobian matrix is
N-by-``mjModel.nv`` where N is the dimensionality of the spatial quantity being differentiated.
MuJoCo can differentiate analytically many spatial quantities. These include tendon lengths, actuator transmission
lengths, end-effector poses, contact and other constraint violations. In the case of tendons and actuator
transmissions the corresponding quantities are mjData.ten_moment and mjData.actuator_moment; we call them moment arms
but mathematically they are Jacobians. The Jacobian matrix of all scalar constraint violations is stored in
mjData.efc_J. Note that we are talking about constraint violations rather than the constraints themselves. This is
because constraint violations have units of length, i.e. they are spatial quantities that we can differentiate.
transmissions the corresponding quantities are ``mjData.ten_moment`` and ``mjData.actuator_moment``; we call them
moment arms but mathematically they are Jacobians. The Jacobian matrix of all scalar constraint violations is stored in
``mjData.efc_J``. Note that we are talking about constraint violations rather than the constraints themselves. This is
because constraint violations have units of length, i.e., they are spatial quantities that we can differentiate.
Constraints are more abstract entities and it is not clear what it means to differentiate them.
Beyond these automatically-computed Jacobians, we provide support functions allowing the user to compute additional
Jacobians on demand. The main function for doing this is :ref:`mj_jac`. It is given a 3D point and a MuJoCo body to
which this point is considered to be attached. mj_jac then computes both the translational and rotational Jacobians,
which tell us how a spatial frame anchored at the given point will translate and rotate if we make a small change to
the kinematic configuration. More precisely, the Jacobian maps joint velocities to end-effector velocities, while the
transpose of the Jacobian maps end-effector forces to joint forces. There are also several other mj_jacXXX functions;
these are convenience functions that call the main mj_jac function with different points of interest - such as a body
center of mass, geom center etc.
which this point is considered to be attached. ``mj_jac`` then computes both the translational and rotational
Jacobians, which tell us how a spatial frame anchored at the given point will translate and rotate if we make a small
change to the kinematic configuration. More precisely, the Jacobian maps joint velocities to end-effector velocities,
while the transpose of the Jacobian maps end-effector forces to joint forces. There are also several other
``mj_jacXXX`` functions; these are convenience functions that call the main ``mj_jac`` function with different points
of interest - such as a body center of mass, geom center etc.
The ability to compute end-effector Jacobians exactly and efficiently is a key advantage of working in joint
coordinates. Such Jacobians are the foundation of many control schemes that map end-effector errors to actuator
commands suitable for suppressing those errors. The computation of end-effector Jacobians in MuJoCo via the mj_jac
commands suitable for suppressing those errors. The computation of end-effector Jacobians in MuJoCo via the ``mj_jac``
function is essentially free in terms of CPU cost; so do not hesitate to use this function.
.. _siContact:
@@ -1399,7 +1410,7 @@ Contacts
Collision detection and solving for contact forces were explained in detail in the :doc:`computation` chapter. Here we
further clarify contact processing from a programming perspective.
The collision detection stage finds contacts between geoms, and records them in the array mjData.contact of
The collision detection stage finds contacts between geoms, and records them in the array ``mjData.contact`` of
:ref:`mjContact` data structures. They are sorted such that multiple contacts between the same pair of bodies are
contiguous (note that one body can have multiple geoms attached to it), and the body pairs themselves are sorted such
that the first body acts as the major index and the second body as the minor index. Not all detected contacts are
@@ -1408,26 +1419,26 @@ mjContact.efc_address is the address in the list of active scalar constraints. R
:at:`gap` attribute of :ref:`geom <geom>`, as well as certain kinds of internal processing that use virtual contacts
for intermediate computations.
The list mjData.contact is generated by the position stage of both forward and inverse dynamics. This is done
The list ``mjData.contact`` is generated by the position stage of both forward and inverse dynamics. This is done
automatically. However the user can override the internal collision detection functions, for example to implement
non-convex mesh collisions, or to replace some of the convex collision functions we use with geom-specific primitives
beyond the ones provided by MuJoCo. The global 2D array :ref:`mjCOLLISIONFUNC` contains the collision function pointer
for each pair of geom types (in the upper-left triangle). To replace them, simply set these pointers to your
functions. The collision function type is :ref:`mjfCollision`. When user collision functions detect contacts, they
should construct an mjvContact structure for each contact and then call the function :ref:`mj_addContact` to add that
contact to mjData.contact. The reference documentation of mj_addContact explains which fields of mjContact must be
contact to ``mjData.contact``. The reference documentation of mj_addContact explains which fields of mjContact must be
filled in by custom collision functions. Note that the functions we are talking about here correspond to near-phase
collisions, and are called only after the list of candidate geom pairs has been constructed by the internal
broad-phase collision mechanism.
After the constraint forces have been computed, the vector of forces for contact i starts at:
After the constraint forces have been computed, the vector of forces for contact ``i`` starts at:
.. code-block:: C
mjtNum* contactforce = d->efc_force + d->contact[i].efc_address;
and similarly for all other efc_XXX vectors. Keep in mind that the contact friction cone can be pyramidal or elliptic,
depending on which solver is selected in mjModel.opt. The function :ref:`mj_isPyramidal`
and similarly for all other ``efc_XXX`` vectors. Keep in mind that the contact friction cone can be pyramidal or
elliptic, depending on which solver is selected in ``mjModel.opt``. The function :ref:`mj_isPyramidal`
can be used to determine which friction cone type is used. For pyramidal cones, the interpretation of the contact force
(whose address we computed above) is non-trivial, because the components are forces along redundant non-orthogonal axes
corresponding to the edges of the pyramid. The function :ref:`mj_contactForce` can be
@@ -1439,7 +1450,7 @@ columns. Here the axes are along the rows of the matrix. Thus, given that MuJoCo
normal axis (which is the X axis of the contact frame by our convention) is in position mjContact.frame[0-2], the Y axis
is in [3-5] and the Z axis is in [6-8]. The reason for this arrangement is because we can have frictionless contacts
where only the normal axis is used, so it makes sense to have its coordinates in the first 3 positions of
mjContact.frame.
``mjContact.frame``.
.. _siCoordinate:
@@ -1450,43 +1461,43 @@ There are multiple coordinate frames used in MuJoCo. The top-level distinction i
Cartesian coordinates. The mapping from the vector of joints coordinates to the Cartesian positions and orientations
of all bodies is called forward kinematics and is the first step in the physics pipeline. The opposite mapping is
called inverse kinematics but it is not uniquely defined and is not implemented in MuJoCo. Recall that mappings
between the tangent spaces (i.e. joint velocities and forces to Cartesian velocities and forces) are given by the body
between the tangent spaces (i.e., joint velocities and forces to Cartesian velocities and forces) are given by the body
Jacobians.
Here we explain further subtleties and subdivisions of the coordinate frames, and summarize the available
transformation functions. In joint coordinates, the only complication is that the position vector mjData.qpos has
different dimensionality than the velocity and acceleration vectors mjData.qvel and mjData.qacc due to quaternion
joints. The function :ref:`mj_differentiatePos` "subtracts" two joint position vectors and returns a velocity vector.
Conversely, the function :ref:`mj_integratePos` takes a position vector and a velocity vector, and returns a new
position vector which has been displaced by the given velocity.
transformation functions. In joint coordinates, the only complication is that the position vector ``mjData.qpos`` has
different dimensionality than the velocity and acceleration vectors ``mjData.qvel`` and ``mjData.qacc`` due to
quaternion joints. The function :ref:`mj_differentiatePos` "subtracts" two joint position vectors and returns a
velocity vector. Conversely, the function :ref:`mj_integratePos` takes a position vector and a velocity vector, and
returns a new position vector which has been displaced by the given velocity.
Cartesian coordinates are more complicated because there are three different coordinate frames that we use: local,
global, and com-based. Local coordinates are used in mjModel to represent the static offsets between a parent and a
child body, as well as the static offsets between a body and any geoms, sites, cameras and lights attached to it.
These static offsets are applied in addition to any joint transformations. So mjModel.body_pos, mjModel.body_quat and
all other spatial quantities in mjModel are expressed in local coordinates. The job of forward kinematics is to
accumulate the joint transformations and static offsets along the kinematic tree and compute all positions and
orientations in global coordinates. The quantities in mjData that start with "x" are expressed in global coordinates.
These are mjData.xpos, mjData.geom_xpos etc. Frame orientations are usually stored as 3-by-3 matrices (xmat), except
for bodies whose orientation is also stored as a unit quaternion mjData.xquat. Given this body quaternion, the
quaternions of all other objects attached to the body can be reconstructed by a quaternion multiplication. The
function :ref:`mj_local2Global` converts from local body coordinates to global
Cartesian coordinates.
These static offsets are applied in addition to any joint transformations. So ``mjModel.body_pos``,
``mjModel.body_quat`` and all other spatial quantities in mjModel are expressed in local coordinates. The job of
forward kinematics is to accumulate the joint transformations and static offsets along the kinematic tree and compute
all positions and orientations in global coordinates. The quantities in mjData that start with "x" are expressed in
global coordinates. These are ``mjData.xpos``, ``mjData.geom_xpos`` etc. Frame orientations are usually stored as
3-by-3 matrices (xmat), except for bodies whose orientation is also stored as a unit quaternion ``mjData.xquat``. Given
this body quaternion, the quaternions of all other objects attached to the body can be reconstructed by a quaternion
multiplication. The function :ref:`mj_local2Global` converts from local body coordinates to global Cartesian
coordinates.
:ref:`mju_negPose` and :ref:`mju_trnVecPose`. A pose is a grouping of a 3D position and a unit quaternion orientation.
There is no separate data structure; the grouping is in terms of logic. This represents a position and orientation in
space, or in other words a spatial frame. Note that OpenGL uses 4-by-4 matrices to represent the same information,
except here we use a quaternion for orientation. The function mju_mulPose multiplies two poses, meaning that it
transforms the first pose by the second pose (the order is important). mju_negPose constructs the opposite pose, while
mju_trnVecPose transforms a 3D vector by a pose, mapping it from local coordinates to global coordinates if we think
of the pose as a coordinate frame. If we want to manipulate only the orientation part, we can do that with the
transforms the first pose by the second pose (the order is important). ``mju_negPose`` constructs the opposite pose,
while ``mju_trnVecPose`` transforms a 3D vector by a pose, mapping it from local coordinates to global coordinates if
we think of the pose as a coordinate frame. If we want to manipulate only the orientation part, we can do that with the
analogous quaternion utility functions :ref:`mju_mulQuat`, :ref:`mju_negQuat` and :ref:`mju_rotVecQuat`.
Finally, there is the com-based frame. This is used to represent 6D spatial vectors containing a 3D angular velocity
or acceleration or torque, followed by a 3D linear velocity or acceleration or force. Note the backwards order:
rotation followed by translation. mjData.cdof and mjData.cacc are example of such vectors; the names start with "c".
These vectors play a key role in the multi-joint dynamics computation. Explaining this is beyond our scope here; see
Featherstone's excellent `slides <http://royfeatherstone.org/spatial>`__ on the subject. In general, the user should
rotation followed by translation. ``mjData.cdof`` and ``mjData.cacc`` are example of such vectors; the names start with
"c". These vectors play a key role in the multi-joint dynamics computation. Explaining this is beyond our scope here;
see Featherstone's excellent `slides <http://royfeatherstone.org/spatial>`__ on the subject. In general, the user should
avoid working with such quantities directly. Instead use the functions :ref:`mj_objectVelocity`,
:ref:`mj_objectAcceleration` and the low-level :ref:`mju_transformSpatial` to obtain linear and angular velocities,
accelerations and forces for a given body. Still, for the interested reader, we summarize the most unusual aspect of
@@ -1646,7 +1657,7 @@ mjCAMERA_FIXED
targeting mode, it will move.
mjCAMERA_USER
This means that the abstract camera is ignored during an update and the low-level OpenGL cameras are not changed. It
is equivalent to not specifying an abstract camera at all, i.e. passing a NULL pointer to mjvCamera in the update
is equivalent to not specifying an abstract camera at all, i.e., passing a NULL pointer to mjvCamera in the update
functions explained below.
The low-level mjvGLCamera is what determines the actual rendering. There are two such cameras embedded in mjvScene, one
@@ -1655,9 +1666,9 @@ frame, while up corresponds to the positive Y axis. There is also a frustum in t
average of the left and right frustum edges and then during rendering compute the actual edges from the viewport aspect
ratio assuming 1:1 pixel aspect ratio. The distance between the two camera positions corresponds to the inter-pupilary
distance (ipd). When the low-level camera parameters are computed automatically from an abstract camera, the ipd as well
as vertical field of view (fovy) are taken from mjModel.vis.global.ipd/fovy for free and tracking cameras, and from the
camera-specific mjModel.cam_ipd/fovy for cameras defined in the model. When stereoscopic mode is not enabled, as
determined by mjvScene.stereo, the camera data for the two eyes are internally averaged during rendering.
as vertical field of view (fovy) are taken from ``mjModel.vis.global.ipd``/``fovy`` for free and tracking cameras, and
from the camera-specific ``mjModel.cam_ipd/fovy`` for cameras defined in the model. When stereoscopic mode is not
enabled, as determined by mjvScene.stereo, the camera data for the two eyes are internally averaged during rendering.
.. _viSelect:
@@ -1686,24 +1697,24 @@ Perturbations
Interactive perturbations have proven very useful in exploring the model dynamics as well as probing closed-loop
control systems. The user is free to implement any perturbation mechanism of their choice by setting
mjData.qfrc_applied or mjData.xfrc_applied to suitable forces (in generalized and Cartesian coordinates respectively).
``mjData.qfrc_applied`` or ``mjData.xfrc_applied`` to suitable forces (in generalized and Cartesian coordinates respectively).
Prior to MuJoCo version 1.40, user code had to maintain a collection of objects in order to implement perturbations.
All these objects are now grouped into the data structure :ref:`mjvPerturb`. Its use is illustrated in
:ref:`simulate.cc <saSimulate>`.
The idea is to select a MuJoCo body of interest, and provide a reference pose (i.e. a 3D position and quaternion
The idea is to select a MuJoCo body of interest, and provide a reference pose (i.e., a 3D position and quaternion
orientation) for that body. These are stored in mjPerturb.respos/quat. The function :ref:`mjv_movePerturb` is a mouse
hook for controlling the reference pose with the mouse. The function :ref:`mjv_initPerturb` is used to set the
reference pose equal to the selected body pose at the onset of perturbation, so as to avoid jumps.
This perturbation object can then be used to move the selected body directly (when the simulation is paused or when
the selected body is a mocap body), or to apply forces and torques to the body. This is done with the functions
This perturbation object can then be used to move the selected body directly (when the simulation is paused or when the
selected body is a mocap body), or to apply forces and torques to the body. This is done with the functions
:ref:`mjv_applyPerturbPose` and :ref:`mjv_applyPerturbForce` respectively. The latter function writes the external
perturbation force to mjData.xfrc_applied for the selected body. However it does not clear mjData.xfrc_applied for the
remaining bodies, thus it is recommended to clear it in user code, in case the selected body changed and some
perturbation force to ``mjData.xfrc_applied`` for the selected body. However it does not clear ``mjData.xfrc_applied``
for the remaining bodies, thus it is recommended to clear it in user code, in case the selected body changed and some
perturbation force was left over from a previous time step. If there is more than one device that can apply
perturbations or user code needs to add perturbations from other sources, the user must implement the necessary logic
so that only the desired perturbations are present in mjData.xfrc_applied and any old perturbations are cleared.
perturbations or user code needs to add perturbations from other sources, the user must implement the necessary logic so
that only the desired perturbations are present in ``mjData.xfrc_applied`` and any old perturbations are cleared.
In addition to affecting the simulation, the perturbation object is recognized by the abstract visualizer and can be
rendered. This is done by adding a visual string to denote the positional difference, and a rotating cube to denote
@@ -1728,13 +1739,13 @@ else needed for specify how rendering should be done. mjvScene also contains up
copied from the model, as well as a headlight which is in light position 0 when present.
The above procedure is the most common approach, and it updates the entire scene at each frame. In addition, we
provide two functions for finer control. :ref:`mjv_updateCamera` updates only the camera (i.e. maps the abstract
provide two functions for finer control. :ref:`mjv_updateCamera` updates only the camera (i.e., maps the abstract
mjvCamera to the low-level mjvGLCamera) but does not touch the geoms or lights. This is useful when the user is moving
the camera rapidly but the simulation state has not changed - in that case there is no point in re-creating the lists
of geoms and lights.
More advanced rendering effects can be achieved by manipulating the list of abstract geoms. For example, the user can
add custom geoms at the end of the list. Sometimes it is desirable to render a sequence of simulation states (i.e. a
add custom geoms at the end of the list. Sometimes it is desirable to render a sequence of simulation states (i.e., a
trajectory) and not just the current state. For this purpose, we have provided the function :ref:`mjv_addGeoms` which
adds the geoms corresponding to the current simulation state to the list already in mjvScene. It does not change the
list of lights, because lighting is additive and having too many lights will make the scene too bright. Importantly,
@@ -1809,7 +1820,7 @@ yet the user is expected to move them programmatically at each simulation step.
through contacts, or better yet, through soft equality constraints to regular bodies which in turn make contacts. The
latter approach is illustrated in the MPL models available on the Forum. It provides effective dynamic filtering and
avoids contacts involving bodies that behave as if they are infinitely heavy (which is what a fixed body is). Note
that the time-varying positions and orientations of the mocap bodies are stored in mjData.mocap_pos/quat, as opposed
that the time-varying positions and orientations of the mocap bodies are stored in ``mjData.mocap_pos/quat``, as opposed
to storing them in mjModel. This is because mjModel is supposed to remain constant. The fixed mocap body pose stored
in mjModel is only used at initialization and reset, when user code has not yet had a chance to update
mjData.mocap_pos/quat.
@@ -1864,11 +1875,11 @@ mjrContext is specific to MuJoCo. After creation, it contains references (called
resources that were uploaded to the GPU by mjr_makeContext. These include model-specific resources such as meshes and
textures, as well as generic resources such as font bitmaps for the specified font scale, framebuffer objects for
shadow mapping and offscreen rendering, and associated renderbuffers. It also contains OpenGL-related options copied
from mjModel.vis, capabilities of the default window framebuffer that are discovered automatically, and the currently
active buffer for rendering; see :ref:`buffers <reBuffer>` below. Note that even though MuJoCo uses fixed-function
OpenGL, it avoids immediate mode rendering and instead uploads all resources to the GPU upfront. This makes it as
efficient as a modern shader, and possibly more efficient, because fixed-function OpenGL is now implemented via
internal shaders that have been written by the video driver developers and tuned extensively.
from ``mjModel.vis``, capabilities of the default window framebuffer that are discovered automatically, and the
currently active buffer for rendering; see :ref:`buffers <reBuffer>` below. Note that even though MuJoCo uses
fixed-function OpenGL, it avoids immediate mode rendering and instead uploads all resources to the GPU upfront. This
makes it as efficient as a modern shader, and possibly more efficient, because fixed-function OpenGL is now implemented
via internal shaders that have been written by the video driver developers and tuned extensively.
Most of the fields of mjrContext remain constant after the call to mjr_makeContext. The only exception is
mjrContext.currentBuffer which changes whenever the active buffer changes. Some of the GPU resources may also change
@@ -1918,7 +1929,7 @@ code samples. All OpenGL can do is detect these properties; we do this in mjr_ma
various window capabilities fields of mjrContext. This is why such properties are not part of the MuJoCo model; they are
session/software-specific and not model-specific. In contrast, the offscreen framebuffer is managed entirely by OpenGL,
and so we can create that buffer with whatever properties we want, namely with the resolution and multi-sample
properties specified in mjModel.vis.
properties specified in ``mjModel.vis``.
The user can directly access the pixels in the two buffers. This is done with the functions :ref:`mjr_readPixels`,
:ref:`mjr_drawPixels` and :ref:`mjr_blitBuffer`. Read/draw transfer pixels from/to the active buffer to/from the CPU.
+338
View File
@@ -0,0 +1,338 @@
===============
Python Bindings
===============
Introduction
------------
Starting with version 2.1.2, MuJoCo comes with native Python bindings that are developed in C++ using
`pybind11 <https://pybind11.readthedocs.io/>`__. Unlike previous Python bindings, these are officially supported by the
MuJoCo development team and will be kept up-to-date with the latest developments in MuJoCo itself.
The Python bindings are distributed as the ``mujoco`` package on `PyPI <https://pypi.org/project/mujoco>`__. These are
low-level bindings that are meant to give as close to a direct access to the MuJoCo library as possible. However, in
order to provide an API and semantics that developers would expect in a typical Python library, the bindings
deliberately diverge from the raw MuJoCo API in a number of places, which are documented throughout this page.
DeepMind’s `dm_control <https://github.com/deepmind/dm_control>`__ reinforcement learning library (which prior to
version 1.0.0 implemented its own MuJoCo bindings based on ``ctypes``) has been updated to depend on the ``mujoco``
package and continues to be supported by DeepMind. Changes in dm_control should be largely transparent to users of
previous versions, however code that depended directly on its low-level API may need to be updated. Consult the
`migration guide <https://github.com/deepmind/dm_control/blob/main/migration_guide_1.0.md>`__ for detail.
For mujoco-py users, we include :ref:`notes <PyMjpy_migration>` below to aid migration.
Installation
------------
The package can be installed from `PyPI <https://pypi.org/project/mujoco/>`__ via
.. code-block:: shell
pip install mujoco
A copy of the MuJoCo library is provided as part of the package and does **not** need to be downloaded or installed
separately.
Building from source
--------------------
Source code for the Python bindings are available in the ``python`` top-level directory in MuJoCo's
`GitHub repository <https://github.com/deepmind/mujoco>`__. Developers wishing to build the bindings from source should
work with a full clone of the Git repository, run the ``make_sdist.sh`` script to generate a
`source distribution (sdist) <https://packaging.python.org/en/latest/glossary/#term-Source-Distribution-or-sdist>`__
tarball, then run ``pip wheel name_of_sdist.tar.gz`` to build the libraries and generate a
`wheel <https://packaging.python.org/en/latest/glossary/#term-Built-Distribution>`__. The ``make_sdist.sh`` script
generates additional C++ header files that are needed to build the bindings, and also pulls in other required files from
elsewhere in the repository outside the ``python`` directory into the sdist.
CMake and a C++17 compiler are needed to build the bindings from source.
Basic usage
-----------
Once installed, the package can be imported via ``import mujoco``. Structs, functions, constants, and enums are
available directly from the top-level ``mujoco`` module.
.. _PyStructs:
Structs
=======
MuJoCo data structures are exposed as Python classes. In order to conform to
`PEP 8 <https://peps.python.org/pep-0008/>`__ naming guidelines, struct names begin with a capital letter, for example
``mjData`` becomes ``mujoco.MjData`` in Python.
All structs other than ``mjModel`` have constructors in Python. For structs that have an ``mj_defaultFoo``-style
initialization function, the Python constructor calls the default initializer automatically, so for example
``mujoco.MjOption()`` creates a new ``mjOption`` instance that is pre-initialized with :ref:`mj_defaultOption`.
Otherwise, the Python constructor zero-initializes the underlying C struct.
Structs with a ``mj_makeFoo``-style initialization function have corresponding constructor overloads in Python,
for example ``mujoco.MjvScene(model, maxgeom=10)`` in Python creates a new ``mjvScene`` instance that is
initialized with ``mjv_makeScene(model, [the new mjvScene instance], 10)`` in C. When this form of initialization is
used, the corresponding deallocation function ``mj_freeFoo/mj_deleteFoo`` is automatically called when the Python
object is deleted. The user does not need to manually free resources.
The ``mujoco.MjModel`` class does not a have Python constructor. Instead, we provide three static factory functions
that create a new ``mjModel`` instance: ``mujoco.MjModel.from_xml_string``, ``mujoco.MjModel.from_xml_path``, and
``mujoco.MjModel.from_binary_path``. The first function accepts a model XML as a string, while the latter two
functions accept the path to either an XML or MJB model file. All three functions optionally accept a Python
dictionary which is converted into a MuJoCo :ref:`Virtualfilesystem` for use during model compilation.
Functions
=========
MuJoCo functions are exposed as Python functions of the same name. Unlike with structs, we do not attempt to make
the function names `PEP 8 <https://peps.python.org/pep-0008/>`__-compliant, as MuJoCo uses both underscores and
CamelCases. In most cases, function arguments appear exactly as they do in C, and keyword arguments are supported
with the same names as declared in :ref:`mujoco.h<inHeader>`. Python bindings to C functions that accept array input
arguments expect NumPy arrays or iterable objects that are convertible to NumPy arrays (e.g. lists). Output
arguments (i.e. array arguments that MuJoCo expect to write values back to the caller) must always be writeable
NumPy arrays.
In the C API, functions that take dynamically-sized arrays as inputs expect a pointer argument to the array along with
an integer argument that specifies the array's size. In Python, the size arguments are omitted since we can
automatically (and indeed, more safely) deduce it from the NumPy array. When calling these functions, pass all
arguments other than array sizes in the same order as they appear in :ref:`mujoco.h<inHeader>`, or use keyword
arguments. For example, :ref:`mj_jac` should be called as ``mujoco.mj_jac(m, d, jacp, jacr, point, body)`` in Python.
The bindings **releases the Python Global Interpreter Lock (GIL)** before calling the underlying MuJoCo function.
This allows for some thread-based parallelism, however users should bear in mind that the GIL is only released for the
duration of the MuJoCo C function itself, and not during the execution of any other Python code.
Enums and constants
===================
MuJoCo enums are available as ``mujoco.mjtEnumType.ENUM_VALUE``, for example ``mujoco.mjtObj.mjOBJ_SITE``. MuJoCo
constants are available with the same name directly under the ``mujoco`` module, for example ``mujoco.mjVISSTRING``.
Minimal example
---------------
.. code-block:: python
import mujoco
XML=r"""
<mujoco>
<asset>
<mesh file="gizmo.stl"/>
</asset>
<worldbody>
<body>
<freejoint/>
<geom type="mesh" name="gizmo" mesh="gizmo"/>
</body>
</worldbody>
</mujoco>
"""
ASSETS=dict()
with open('/path/to/gizmo.stl', 'rb') as f:
ASSETS['gizmo.stl'] = f.read()
model = mujoco.MjModel.from_xml_string(XML, ASSETS)
data = mujoco.MjData(model)
while data.time < 1:
mujoco.mj_step(model, data)
print(data.geom_xpos)
.. _PyNamed:
Named access
------------
Most well-designed MuJoCo models assign names to objects (joints, geoms, bodies, etc.) of interest. When the model is
compiled down to an ``mjModel`` instance, these names become associated with numeric IDs that are used to index into the
various array members. For convenience and code readability, the Python bindings provide "named access" API on
``MjModel`` and ``MjData``. Each ``name_fooadr`` field in the ``mjModel`` struct defines a name category ``foo``.
For each name category ``foo``, ``mujoco.MjModel`` and ``mujoco.MjData`` objects provide a method ``foo`` that takes
a single string argument, and returns an accessor object for all arrays corresponding to the entity ``foo`` of the
given name. The accessor object contains attributes whose names correspond to the fields of either ``mujoco.MjModel`` or
``mujoco.MjData`` but with the part before the underscore removed. For example:
- ``m.geom('gizmo')`` returns an accessor for arrays in the ``MjModel`` object ``m`` associated with the geom named
"gizmo".
- ``m.geom('gizmo').rgba`` is a NumPy array view of length 4 that specifies the RGBA color for the geom.
Specifically, it corresponds to the portion of ``m.geom_rgba[4*i:4*i+4]`` where
``i = mujoco.mj_name2id(m, mujoco.mjtObj.mjOBJ_GEOM, 'gizmo')``.
Additionally, the Python API define a number of aliases for some name categories corresponding to the XML element name
in the MJCF schema that defines an entity of that category. For example, ``m.joint('foo')`` is the same as
``m.jnt('foo')``. A complete list of these aliases are provided below.
The accessor for joints is somewhat different that of the other categories. Some ``mjModel`` and ``mjData`` fields
(those of size size ``nq`` or ``nv``) are associated with degrees of freedom (DoFs) rather than joints. This is because
different types of joints have different numbers of DoFs. We nevertheless associate these fields to their corresponding
joints, for example through ``d.joint('foo').qpos`` and ``d.joint('foo').qvel``, however the size of these arrays would
differ between accessors depending on the joint's type.
Named access is guaranteed to be O(1) in the number of entities in the model. In other words, the time it takes to
access an entity by name does not grow with the number of names or entities in the model. (This is currently **not** the
case for the :ref:`mj_name2id` function, which performs a linear scan.)
For completeness, we provide here a complete list of all name categories in MuJoCo, along with their corresponding
aliases defined in the Python API.
- ``body``
- ``jnt`` or ``joint``
- ``geom``
- ``site``
- ``cam`` or ``camera``
- ``light``
- ``mesh``
- ``skin``
- ``hfield``
- ``tex`` or ``texture``
- ``mat`` or ``material``
- ``pair``
- ``exclude``
- ``eq`` or ``equality``
- ``tendon`` or ``ten``
- ``actuator``
- ``sensor``
- ``numeric``
- ``text``
- ``tuple``
- ``key`` or ``keyframe``
Rendering
---------
MuJoCo itself expects users to set up a working OpenGL context before calling any of its ``mjr_`` rendering routine.
The Python bindings provide a basic class ``mujoco.GLContext`` that helps users set up such a context for offscreen
rendering. To create a context, call ``ctx = mujoco.GLContext(max_width, max_height)``. Once the context is created,
it must be made current before MuJoCo rendering functions can be called, which you can do so via ``ctx.make_current()``.
Note that a context can only be made current on one thread at any given time, and all subsequent rendering calls must be
made on the same thread.
The context is freed automatically when the ``ctx`` object is deleted, but in some multi-threaded scenario it may be
necessary to explicitly free the underlying OpenGL context. To do so, call ``ctx.free()``, after which point it is the
user's responsibility to ensure that no further rendering calls are made on the context.
Once the context is created, users can follow MuJoCo's standard rendering, for example as documented in the
:ref:`Visualization` section.
Error handling
--------------
MuJoCo reports irrecoverable errors via the :ref:`mju_error` mechanism, which immediately terminates the entire process.
Users are permitted to install a custom error handler via the :ref:`mju_user_error` callback, but it too is expected
to terminate the process, otherwise the behavior of MuJoCo after the callback returns is undefined. In actuality, it is
sufficient to ensure that error callbacks do not return *to MuJoCo*, but it is permitted to use
`longjmp <https://en.cppreference.com/w/c/program/longjmp>`__ to skip MuJoCo's call stack back to the external callsite.
The Python bindings utilises longjmp to allow it to convert irrecoverable MuJoCo errors into Python exceptions of type
``mujoco.FatalError`` that can be caught and processed in the usual Pythonic way. Furthermore, it installs its error
callback in a thread-local manner using a currently private API, thus allowing for concurrent calls into MuJoCo from
multiple threads.
Callbacks
---------
MuJoCo allows users to install custom callback functions to modify certain parts of its computation pipeline.
For example, :ref:`mjcb_sensor` can be used to implement custom sensors, and :ref:`mjcb_control` can be used to
implement custom actuators. Callbacks are exposed through the function pointers prefixed ``mjcb_`` in
:ref:`mujoco.h<inHeader>`.
For each callback ``mjcb_foo``, users can set it to a Python callable via ``mujoco.set_mjcb_foo(some_callable)``. To
reset it, call ``mujoco.set_mjcb_foo(None)``. To retrieve the currently installed callback, call
``mujoco.get_mjcb_foo()``. (The getter **should not** be used if the callback is not installed via the Python bindings.)
The bindings automatically acquire the GIL each time the callback is entered, and release it before reentering MuJoCo.
This is likely to incur a severe performance impact as callbacks are triggered several times throughout MuJoCo's
computation pipeline and is unlikely to be suitable for "production" use case. However, it is expected that this feature
will be useful for prototyping complex models.
Alternatively, if a callback is implemented in a native dynamic library, users can use
`ctypes <https://docs.python.org/3/library/ctypes.html>`__ to obtain a Python handle to the C function pointer and pass
it to ``mujoco.set_mjcb_foo``. The bindings will then retrieve the underlying function pointer and assign it directly to
the raw callback pointer, and the GIL will **not** be acquired each time the callback is entered.
.. _PyMjpy_migration:
Migration Notes for mujoco-py
-----------------------------
In mujoco-py, the main entry point is the `MjSim <https://github.com/openai/mujoco-py/blob/master/mujoco_py/mjsim.pyx>`_
class. Users constuct a stateful ``MjSim`` instance from an MJCF model (similar to ``dm_control.Physics``), and this
instance holds references to an ``mjModel`` instance and its associated ``mjData``. In contrast, the MuJoCo Python
bindings (``mujoco``) take a more low-level approach, as explained above: following the design principle of the C
library, the ``mujoco`` module itself is stateless, and merely wraps the underlying native structs and functions.
While a complete survey of mujoco-py is beyond the scope of this document, we offer below implementation notes for a
non-exhaustive list of specific mujoco-py features:
``mujoco_py.load_model_from_xml(bstring)``
===========================================
This factory function constructs a stateful ``MjSim`` instance. When using ``mujoco``, the user should call the factory
function ``mujoco.MjModel.from_xml_*`` as described :ref:`above <PyStructs>`. The user is then responsible for holding
the resulting ``MjModel`` struct instance and explicitly generating the corresponding ``MjData`` by calling
``mujoco.MjData(model)``.
``sim.reset()``, ``sim.forward()``, ``sim.step()``
==================================================
Here as above, ``mujoco`` users needs to call the underlying library functions, passing instances of ``MjModel`` and
``MjData``: :ref:`mujoco.mj_resetData(model, data) <mj_resetData>`, :ref:`mujoco.mj_forward(model, data) <mj_forward>`,
and :ref:`mujoco.mj_step(model, data) <mj_step>`.
``sim.get_state()``, ``sim.set_state(state)``, ``sim.get_flattened_state()``, ``sim.set_state_from_flattened(state)``
=====================================================================================================================
The MuJoCo library’s computation is deterministic given a specific input, as explained in the :ref:`Programming section
<Simulation>`. mujoco-py implements methods for getting and setting some of the relevant fields (and similarly
``dm_control.Physics`` offers methods that correspond to the flattened case). ``mujoco`` do not offer such abstraction,
and the user is expected to get/set the values of the relevant fields explicitly.
``sim.model.get_joint_qvel_addr(joint_name)``
=============================================
This is a convenience method in mujoco-py that returns a list of contiguous indices corresponding to this joint. The
list starts from ``model.jnt_qposadr[joint_index]``, and its length depends on the joint type. ``mujoco`` doesn't offer
this functionality, but this list can be easily constructed using ``model.jnt_qposadr[joint_index]`` and ``xrange``.
``sim.model.*_name2id(name)``
=============================
mujoco-py creates dicts in ``MjSim`` that allow for efficient lookup of indices for objects of different types:
``site_name2id``, ``body_name2id`` etc. These functions replace the function :ref:`mujoco.mj_name2id(model, type_enum,
name) <mj_name2id>` whose current implementation is inefficient. ``mujoco`` offers a different
approach for using entity names – :ref:`named access <PyNamed>`, as well as access to the native :ref:`mj_name2id`.
``sim.save(fstream, format_name)``
==================================
This is the one context in which the MuJoCo library (and therefore also ``mujoco``) is stateful: it holds a copy in
memory of the last XML that was compiled, which is used in :ref:`mujoco.mj_saveLastXML(fname) <mj_saveLastXML>`. Note
that mujoco-py’s implementation has a convenient extra feature, whereby the pose (as determined by ``sim.data``’s
state) is transformed to a keyframe that’s added to the model before saving. This extra feature is not currently
available in ``mujoco``.
Code Sample: open-loop rollout
------------------------------
We include a code sample showing how to add additional C/C++ functionality, exposed as a Python module via pybind11. The
sample, implemented in ``rollout.cc`` and wrapped in ``rollout.py``, implements a common use case where tight loops
implemented outside of Python are beneficial: rolling out a trajectory (i.e., calling ``mj_step()`` in a loop), given an
intial state and sequence of controls, and returning subsequent states and sensor values. The canonical usage form is
.. code-block:: python
state, sensordata = rollout.rollout(model, data, initial_state, ctrl)
``initial_state`` is a ``nstate x nqva`` array, with ``nstate`` initial states of length ``nqva``, where ``nqva =
model.nq + model.nv + model.na`` is the size of the full MuJoCo mechanical state: positions (``data.qpos``), velocities
(``data.qvel``) and actuator activations (``data.act``). ``ctrl`` is a ``nstate x nstep x nu`` array of control
sequences.
The ``rollout`` function is designed to be completely stateless, so all inputs of the stepping pipeline are set and any
values already present in the given ``MjData`` instance will have no effect on the output. In order to facilitate this,
all inputs including ``time`` and ``qacc_warmstart`` are set to default values, as are auxillary controls
(``qfrc_applied``, ``xfrc_applied`` and ``mocap_{pos,quat}``). These can also be optionally set by the user.
Since the Global Interpreter Lock can be released, this function can be efficiently threaded using Python threads. See
the ``test_threading`` function in ``rollout_test.py`` for an example of threaded operation.
+2
View File
@@ -8,3 +8,5 @@ pygments==2.7.4
jq==1.1.1
Jinja2==2.11.3
wheel
# see https://github.com/aws/aws-sam-cli/issues/3661 regarding markupsafe
markupsafe==2.0.1
+3 -3
View File
@@ -16,8 +16,8 @@ Installation instructions
The plug-in directory (available at https://github.com/deepmind/mujoco/tree/main/unity) includes a ``package.json``
file. Unity's package manager recognizes this file and will import the plug-in's C# codebase to your project. In
addition, Unity also needs the native MuJoCo library, which can be found in the specific platfomr archive at
https://github.com/deepmind/mujoco/release.
addition, Unity also needs the native MuJoCo library, which can be found in the specific platform archive at
https://github.com/deepmind/mujoco/releases.
On Unity version 2020.2 and later, the Package Manager will look for the native library file and copy it to the package
directory when the package is imported. Alternatively, you can manually copy the native library to the package directory
@@ -170,7 +170,7 @@ components, you can call ``MjScene.CreateScene()`` when the initialization phase
Scene recreation maintains continuity of physics and state in the following way:
1. The position and velocity of joints is cached.
1. The position and velocity of joints are cached.
2. MuJoCo’s state is reset (to ``qpos0``) and Unity transforms are synchronized.
3. A new XML is generated, creating a model that has the same ``qpos0`` as the previous one for the joints that
persisted.