Add mjtState enum and related mj_stateSize, mj_getState and mj_setState functions.
PiperOrigin-RevId: 539667943 Change-Id: I14c34be8ce4c287e529380257b5c5bffc3ab45ce
This commit is contained in:
committed by
Copybara-Service
parent
84c33e53df
commit
f67e359532
@@ -346,6 +346,18 @@ Data
|
||||
The enums below are defined in `mjdata.h <https://github.com/deepmind/mujoco/blob/main/include/mujoco/mjdata.h>`_.
|
||||
|
||||
|
||||
|
||||
.. _mjtState:
|
||||
|
||||
mjtState
|
||||
~~~~~~~~
|
||||
|
||||
State component elements as integer bitflags and several convenient combinations of these flags. Used by
|
||||
:ref:`mj_getState`, :ref:`mj_setState` and :ref:`mj_stateSize`.
|
||||
|
||||
.. mujoco-include:: mjtState
|
||||
|
||||
|
||||
.. _mjtWarning:
|
||||
|
||||
mjtWarning
|
||||
|
||||
@@ -151,6 +151,36 @@ These are support functions that need access to :ref:`mjModel` and :ref:`mjData`
|
||||
not need such access. Support functions are called within the simulator but some of them can also be useful for custom
|
||||
computations, and are documented in more detail below.
|
||||
|
||||
.. _mj_stateSize:
|
||||
|
||||
mj_stateSize
|
||||
~~~~~~~~~~~~
|
||||
|
||||
.. mujoco-include:: mj_stateSize
|
||||
|
||||
Returns the number of :ref:`mjtNum` |-| s required for a given state specification. The bits of the integer ``spec``
|
||||
correspond to element fields of :ref:`mjtState`.
|
||||
|
||||
.. _mj_getState:
|
||||
|
||||
mj_getState
|
||||
~~~~~~~~~~~
|
||||
|
||||
.. mujoco-include:: mj_getState
|
||||
|
||||
Copy concatenated state components specified by ``spec`` from ``d`` into ``state``. The bits of the integer
|
||||
``spec`` correspond to element fields of :ref:`mjtState`. Fails with :ref:`mju_error` if ``spec`` is invalid.
|
||||
|
||||
.. _mj_setState:
|
||||
|
||||
mj_setState
|
||||
~~~~~~~~~~~
|
||||
|
||||
.. mujoco-include:: mj_setState
|
||||
|
||||
Copy concatenated state components specified by ``spec`` from ``state`` into ``d``. The bits of the integer
|
||||
``spec`` correspond to element fields of :ref:`mjtState`. Fails with :ref:`mju_error` if ``spec`` is invalid.
|
||||
|
||||
.. _mj_addContact:
|
||||
|
||||
mj_addContact
|
||||
|
||||
@@ -96,6 +96,21 @@ These are support functions that need access to :ref:`mjModel` and :ref:`mjData`
|
||||
not need such access. Support functions are called within the simulator but some of them can also be useful for custom
|
||||
computations, and are documented in more detail below.
|
||||
|
||||
.. _mj_stateSize:
|
||||
|
||||
Returns the number of :ref:`mjtNum` |-| s required for a given state specification. The bits of the integer ``spec``
|
||||
correspond to element fields of :ref:`mjtState`.
|
||||
|
||||
.. _mj_getState:
|
||||
|
||||
Copy concatenated state components specified by ``spec`` from ``d`` into ``state``. The bits of the integer
|
||||
``spec`` correspond to element fields of :ref:`mjtState`. Fails with :ref:`mju_error` if ``spec`` is invalid.
|
||||
|
||||
.. _mj_setState:
|
||||
|
||||
Copy concatenated state components specified by ``spec`` from ``state`` into ``d``. The bits of the integer
|
||||
``spec`` correspond to element fields of :ref:`mjtState`. Fails with :ref:`mju_error` if ``spec`` is invalid.
|
||||
|
||||
.. _mj_mulJacVec:
|
||||
|
||||
This function multiplies the constraint Jacobian mjData.efc_J by a vector. Note that the Jacobian can be either dense or
|
||||
|
||||
@@ -63,6 +63,8 @@ Simulate
|
||||
General
|
||||
^^^^^^^
|
||||
|
||||
- Added :ref:`mj_getState` and :ref:`mj_setState` for getting and setting the simulation state as a concatenated vector
|
||||
of floating point numbers. See the :ref:`State<geState>` section for details.
|
||||
- Added :ref:`mjContact.solreffriction<mjContact>`, allowing different :ref:`solref<CSolver>` parameters for the normal
|
||||
and frictional axes of contacts when using :ref:`elliptic friction cones<option-cone>`. This attribute is required
|
||||
for elastic frictional collisions, see associated
|
||||
|
||||
+49
-37
@@ -569,41 +569,60 @@ Fast implicit-in-velocity (``implicitfast``)
|
||||
|
||||
.. _geState:
|
||||
|
||||
The **state**
|
||||
~~~~~~~~~~~~~
|
||||
The State
|
||||
~~~~~~~~~
|
||||
|
||||
To complete our description of the general framework we will now discuss the notion of *state*. MuJoCo has a compact,
|
||||
well-defined internal state which, together with the deterministic computational pipeline, means that operations like
|
||||
resetting the state and computing dynamics derivatives are also well-defined. The state is entirely encapsulated in the
|
||||
``mjData`` struct and consists of several components:
|
||||
well-defined internal state which, together with the :ref:`deterministic computational pipeline<piReproducibility>`,
|
||||
means that operations like resetting the state and computing dynamics derivatives are also well-defined.
|
||||
|
||||
The state is entirely encapsulated in the :ref:`mjData` struct and consists of several components. The components are
|
||||
enumerated in :ref:`mjtState` as bit flags, along with several common combinations, corresponding to the groupings
|
||||
below. Concatenated state vectors can be conveniently read from and written into :ref:`mjData` using :ref:`mj_getState`
|
||||
and :ref:`mj_setState`, respectively.
|
||||
|
||||
.. _gePhysicsState:
|
||||
|
||||
Physics state
|
||||
^^^^^^^^^^^^^
|
||||
The *physics state* contains all quantities which are time-integrated during stepping.
|
||||
These are ``mjData.{qpos, qvel, act, time}``:
|
||||
The *physics state* (:ref:`mjSTATE_PHYSICS<mjtState>`) contains the main quantities which are time-integrated during
|
||||
stepping. These are ``mjData.{qpos, qvel, act}``:
|
||||
|
||||
Mechanical state: ``qpos`` and ``qvel``
|
||||
The *mechanical state* of a simulation is given by the generalized position (``mjData.qpos``) and velocity
|
||||
(``mjData.qvel``) vectors, denoted above as :math:`q` and :math:`v`, respectively.
|
||||
Position: ``qpos``
|
||||
The configuration in generalized coodinates, denoted above as :math:`q`.
|
||||
|
||||
Actuator activations: ``act``
|
||||
Velocity: ``qvel``
|
||||
The generalized velocities, denoted above as :math:`v`.
|
||||
|
||||
Actuator activation: ``act``
|
||||
``mjData.act`` contains the internal states of stateful actuators, denoted above as :math:`w`.
|
||||
|
||||
.. _geFullPhysics:
|
||||
|
||||
Full physics state
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The *full physics state* (:ref:`mjSTATE_FULLPHYSICS<mjtState>`) contains the physics state and two additional
|
||||
components:
|
||||
|
||||
Time: ``time``
|
||||
The time of the simulation is given by the scalar ``mjData.time``. Since physics is time-invariant, it is
|
||||
often excluded from the *physics state*; an exception could be a time-dependent user callback (e.g., an open-loop
|
||||
The simulation time is given by the scalar ``mjData.time``. Since physics is time-invariant, it is
|
||||
excluded from the *physics state*; exceptions include time-dependent user callbacks and plugins (e.g., an open-loop
|
||||
controller), in which case time should be included.
|
||||
|
||||
Plugin state: ``plugin_state``
|
||||
``mjData.plugin_state`` are states declared by :ref:`engine plugins<exPlugin>`. Please see the :ref:`exPluginState`
|
||||
section for more details.
|
||||
|
||||
.. _geInput:
|
||||
|
||||
User inputs
|
||||
^^^^^^^^^^^
|
||||
These input fields are set by the user and affect the physics simulation, but are untouched by the simulator. All input
|
||||
fields except for MoCap poses default to 0.
|
||||
|
||||
Controls: ``ctrl``
|
||||
These input fields (:ref:`mjSTATE_USER<mjtState>`) are set by the user and affect the physics simulation, but are
|
||||
untouched by the simulator. All input fields except for MoCap poses default to 0.
|
||||
|
||||
Control: ``ctrl``
|
||||
Controls are defined by the :ref:`actuator<actuator>` section of the XML. ``mjData.ctrl`` values either produce
|
||||
generalized forces directly (stateless actuators), or affect the actuator activations in ``mjData.act``, which then
|
||||
produce forces.
|
||||
@@ -627,8 +646,8 @@ User data: ``userdata``
|
||||
|
||||
.. _geWarmstart:
|
||||
|
||||
Warmstart accelerations
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Warmstart acceleration
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
``qacc_warmstart``
|
||||
``mjData.qacc_warmstart`` are accelerations used to warmstart the constraint solver, saved from the previous step.
|
||||
@@ -642,34 +661,27 @@ Warmstart accelerations
|
||||
<https://en.wikipedia.org/wiki/Lyapunov_exponent>`__ when time-stepping, quickly leading to divergent trajectories
|
||||
for different warmstarts.
|
||||
|
||||
.. _gePlugin:
|
||||
|
||||
Plugin state
|
||||
^^^^^^^^^^^^
|
||||
|
||||
``plugin_state``
|
||||
``mjData.plugin_state`` are states declared by :ref:`engine plugins<exPlugin>`. Please see the :ref:`exPluginState`
|
||||
section for more details.
|
||||
|
||||
.. _geIntegrationState:
|
||||
|
||||
Integration state
|
||||
^^^^^^^^^^^^^^^^^
|
||||
The *integration state* is the union of all the above ``mjData`` fields and constitutes the entire set of inputs to
|
||||
the *forward dynamics*. In the case of *inverse dynamics*, ``mjData.qacc`` is also treated as an input variable. All
|
||||
other ``mjData`` fields are functions of the integration state.
|
||||
|br| When saving the integration state in order to reload it elsewhere, it is sensible to avoid saving unused fields
|
||||
that always remain in their default values. Specifically, ``xfrc_applied`` can be quite large (``6 x nbody``) yet is
|
||||
often unused.
|
||||
|
||||
The *integration state* (:ref:`mjSTATE_INTEGRATION<mjtState>`) is the union of all the above :ref:`mjData` fields and
|
||||
constitutes the entire set of inputs to the *forward dynamics*. In the case of *inverse dynamics*, ``mjData.qacc`` is
|
||||
also treated as an input variable. All other :ref:`mjData` fields are functions of the integration state.
|
||||
|
||||
Note that the full integration state as given by :ref:`mjSTATE_INTEGRATION<mjtState>` is maximalist and includes fields
|
||||
which are often unused. If a small state size is desired, it might be sensible to avoid saving unused fields.
|
||||
In particular `xfrc_applied`` can be quite large (``6 x nbody``) yet is often unused.
|
||||
|
||||
.. _geSimulationState:
|
||||
|
||||
Simulation state: ``mjData``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
The *simulation state* is the entirety of the ``mjData`` struct and associated memory buffer. This state includes
|
||||
all derived quantities computed during dynamics computation. Because the ``mjData`` buffers are preallocated for the
|
||||
The *simulation state* is the entirety of the :ref:`mjData` struct and associated memory buffer. This state includes
|
||||
all derived quantities computed during dynamics computation. Because the :ref:`mjData` buffers are preallocated for the
|
||||
worst case, it is often significantly faster to recompute derived quantities from the *integration state* rather than
|
||||
using ``mj_copyData``.
|
||||
using :ref:`mj_copyData`.
|
||||
|
||||
.. _Constraint:
|
||||
|
||||
@@ -1591,7 +1603,7 @@ MuJoCo's simulation pipeline is entirely deterministic and reproducible -- if a
|
||||
saved and reloaded and :ref:`mj_step` called again, the resulting next state will be identical. However, there are some
|
||||
important caveats:
|
||||
|
||||
- Save all the required :ref:`integration state<IntegrationState>` components. In particular :ref:`warmstart
|
||||
- Save all the required :ref:`integration state<geIntegrationState>` components. In particular :ref:`warmstart
|
||||
accelerations<geWarmstart>` have only a very small effect on the next state, but should be saved if bit-wise equality
|
||||
is required.
|
||||
- Any numerical difference between states, no matter how small, will become significant upon integration, especially for
|
||||
|
||||
@@ -16,6 +16,29 @@
|
||||
// Error: C reference not found
|
||||
// NOLINTBEGIN
|
||||
|
||||
typedef enum mjtState_ { // state elements
|
||||
mjSTATE_TIME = 1<<0, // time
|
||||
mjSTATE_QPOS = 1<<1, // position
|
||||
mjSTATE_QVEL = 1<<2, // velocity
|
||||
mjSTATE_ACT = 1<<3, // actuator activation
|
||||
mjSTATE_WARMSTART = 1<<4, // acceleration used for warmstart
|
||||
mjSTATE_CTRL = 1<<5, // control
|
||||
mjSTATE_QFRC_APPLIED = 1<<6, // applied generalized force
|
||||
mjSTATE_XFRC_APPLIED = 1<<7, // applied Cartesian force/torque
|
||||
mjSTATE_MOCAP_POS = 1<<8, // positions of mocap bodies
|
||||
mjSTATE_MOCAP_QUAT = 1<<9, // orientations of mocap bodies
|
||||
mjSTATE_USERDATA = 1<<10, // user data
|
||||
mjSTATE_PLUGIN = 1<<11, // plugin state
|
||||
|
||||
mjNSTATE = 12, // number of state elements
|
||||
|
||||
// convenience values for commonly used state specifications
|
||||
mjSTATE_PHYSICS = mjSTATE_QPOS | mjSTATE_QVEL | mjSTATE_ACT,
|
||||
mjSTATE_FULLPHYSICS = mjSTATE_PHYSICS | mjSTATE_TIME | mjSTATE_PLUGIN,
|
||||
mjSTATE_USER = mjSTATE_CTRL | mjSTATE_QFRC_APPLIED | mjSTATE_XFRC_APPLIED |
|
||||
mjSTATE_MOCAP_POS | mjSTATE_MOCAP_QUAT | mjSTATE_USERDATA,
|
||||
mjSTATE_INTEGRATION = mjSTATE_FULLPHYSICS | mjSTATE_USER | mjSTATE_WARMSTART
|
||||
} mjtState;
|
||||
typedef enum mjtWarning_ { // warning types
|
||||
mjWARN_INERTIA = 0, // (near) singular inertia matrix
|
||||
mjWARN_CONTACTFULL, // too many contacts in contact list
|
||||
@@ -2176,6 +2199,9 @@ void mj_projectConstraint(const mjModel* m, mjData* d);
|
||||
void mj_referenceConstraint(const mjModel* m, mjData* d);
|
||||
void mj_constraintUpdate(const mjModel* m, mjData* d, const mjtNum* jar,
|
||||
mjtNum cost[1], int flg_coneHessian);
|
||||
int mj_stateSize(const mjModel* m, unsigned int spec);
|
||||
void mj_getState(const mjModel* m, const mjData* d, mjtNum* state, unsigned int spec);
|
||||
void mj_setState(const mjModel* m, mjData* d, const mjtNum* state, unsigned int spec);
|
||||
int mj_addContact(const mjModel* m, mjData* d, const mjContact* con);
|
||||
int mj_isPyramidal(const mjModel* m);
|
||||
int mj_isSparse(const mjModel* m);
|
||||
|
||||
Reference in New Issue
Block a user