Version 2.1.2: Python bindings, OBJ assets support, bugfixes.
PiperOrigin-RevId: 434731612 Change-Id: I0cfda3e7a3d1c72036764986efc252ffa1b8c6b0
This commit is contained in:
+137
-53
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -13,5 +13,6 @@
|
||||
XMLreference
|
||||
programming
|
||||
APIreference
|
||||
python
|
||||
unity
|
||||
changelog
|
||||
|
||||
+31
-29
@@ -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
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user