Skip to content

Commit b77977a

Browse files
yuvaltassacopybara-github
authored andcommitted
Update Programming/simulation chapter.
PiperOrigin-RevId: 847424298 Change-Id: Icc6efb05dee5e67a5813ed04caa15a5703e59aee
1 parent b8a4ac5 commit b77977a

File tree

7 files changed

+283
-288
lines changed

7 files changed

+283
-288
lines changed

doc/APIreference/functions.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ Copy real-valued arrays from model to spec, returns 1 on success.
8989
Recompile spec to model, preserving the state. Like :ref:`mj_compile`, this function compiles an :ref:`mjSpec` to an
9090
:ref:`mjModel`, with two differences. First, rather than returning an entirely new model, it will
9191
reallocate existing :ref:`mjModel` and :ref:`mjData` instances in-place. Second, it will preserve the
92-
:ref:`integration state<geIntegrationState>`, as given in the provided :ref:`mjData` instance, while accounting for
92+
:ref:`integration state<siIntegrationState>`, as given in the provided :ref:`mjData` instance, while accounting for
9393
newly added or removed degrees of freedom. This allows the user to continue simulation with the same model and data
9494
struct pointers while editing the model programmatically.
9595

@@ -2753,7 +2753,7 @@ outputs of derivative functions are the trailing rather than leading arguments.
27532753

27542754
Compute finite-differenced discrete-time transition matrices.
27552755

2756-
Letting :math:`x, u` denote the current :ref:`state<gePhysicsState>` and :ref:`control<geInput>`
2756+
Letting :math:`x, u` denote the current :ref:`state<siPhysicsState>` and :ref:`control<siInput>`
27572757
vector in an mjData instance, and letting :math:`y, s` denote the next state and sensor
27582758
values, the top-level :ref:`mj_step` function computes :math:`(x,u) \rightarrow (y,s)`
27592759
:ref:`mjd_transitionFD` computes the four associated Jacobians using finite-differencing.
@@ -2804,7 +2804,7 @@ These matrices and their dimensions are:
28042804

28052805
Finite differenced continuous-time inverse-dynamics Jacobians.
28062806

2807-
Letting :math:`x, a` denote the current :ref:`state<gePhysicsState>` and acceleration vectors in an mjData instance, and
2807+
Letting :math:`x, a` denote the current :ref:`state<siPhysicsState>` and acceleration vectors in an mjData instance, and
28082808
letting :math:`f, s` denote the forces computed by the inverse dynamics (``qfrc_inverse``), the function
28092809
:ref:`mj_inverse` computes :math:`(x,a) \rightarrow (f,s)`. :ref:`mjd_inverseFD` computes seven associated Jacobians
28102810
using finite-differencing. These matrices and their dimensions are:

doc/APIreference/functions_override.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ If compilation fails, :ref:`mj_compile` returns ``NULL``; the error can be read
4848
Recompile spec to model, preserving the state. Like :ref:`mj_compile`, this function compiles an :ref:`mjSpec` to an
4949
:ref:`mjModel`, with two differences. First, rather than returning an entirely new model, it will
5050
reallocate existing :ref:`mjModel` and :ref:`mjData` instances in-place. Second, it will preserve the
51-
:ref:`integration state<geIntegrationState>`, as given in the provided :ref:`mjData` instance, while accounting for
51+
:ref:`integration state<siIntegrationState>`, as given in the provided :ref:`mjData` instance, while accounting for
5252
newly added or removed degrees of freedom. This allows the user to continue simulation with the same model and data
5353
struct pointers while editing the model programmatically.
5454

@@ -643,7 +643,7 @@ outputs of derivative functions are the trailing rather than leading arguments.
643643

644644
Compute finite-differenced discrete-time transition matrices.
645645

646-
Letting :math:`x, u` denote the current :ref:`state<gePhysicsState>` and :ref:`control<geInput>`
646+
Letting :math:`x, u` denote the current :ref:`state<siPhysicsState>` and :ref:`control<siInput>`
647647
vector in an mjData instance, and letting :math:`y, s` denote the next state and sensor
648648
values, the top-level :ref:`mj_step` function computes :math:`(x,u) \rightarrow (y,s)`
649649
:ref:`mjd_transitionFD` computes the four associated Jacobians using finite-differencing.
@@ -689,7 +689,7 @@ These matrices and their dimensions are:
689689

690690
Finite differenced continuous-time inverse-dynamics Jacobians.
691691

692-
Letting :math:`x, a` denote the current :ref:`state<gePhysicsState>` and acceleration vectors in an mjData instance, and
692+
Letting :math:`x, a` denote the current :ref:`state<siPhysicsState>` and acceleration vectors in an mjData instance, and
693693
letting :math:`f, s` denote the forces computed by the inverse dynamics (``qfrc_inverse``), the function
694694
:ref:`mj_inverse` computes :math:`(x,a) \rightarrow (f,s)`. :ref:`mjd_inverseFD` computes seven associated Jacobians
695695
using finite-differencing. These matrices and their dimensions are:

doc/changelog.rst

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@ MJX
2929
^^^
3030
- Added ``actuator_length``, ``cdof`` and ``cdof_dof`` fields to ``mjx.Data``.
3131

32+
33+
Documentation
34+
^^^^^^^^^^^^^
35+
- General improvements to the :ref:`Programming/Simulation<Simulation>` chapter. Notably, the main discussion of
36+
:ref:`state<siStateControl>` has been moved there, and the section on :ref:`mjModel changes<siChange>` has been
37+
expanded.
38+
39+
3240
Bug fixes
3341
^^^^^^^^^
3442

@@ -1081,8 +1089,8 @@ Python bindings
10811089
12. Improved the implementation of the :ref:`rollout<PyRollout>` module. Note the changes below are breaking, dependent
10821090
code will require modification.
10831091

1084-
- Uses :ref:`mjSTATE_FULLPHYSICS<geFullPhysics>` as state spec, enabling divergence detection by inspecting time.
1085-
- Allows user-defined control spec for any combination of :ref:`user input<geInput>` fields as controls.
1092+
- Uses :ref:`mjSTATE_FULLPHYSICS<siFullPhysics>` as state spec, enabling divergence detection by inspecting time.
1093+
- Allows user-defined control spec for any combination of :ref:`user input<siInput>` fields as controls.
10861094
- Outputs are no longer squeezed and always have dim=3.
10871095
13. The ``sync`` function for the :ref:`passive viewer<PyViewerPassive>` can now pick up changes to rendering flags in
10881096
``user_scn``, as requested in :issue:`1190`.

doc/computation/index.rst

Lines changed: 16 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -599,126 +599,29 @@ Fast implicit-in-velocity (``implicitfast``)
599599
``implicitfast`` yet conserves energy well under ``RK4``. Note that under ``implicit``, this model doesn't diverge
600600
but rather loses energy.
601601

602-
.. _geState:
603-
604-
The State
605-
~~~~~~~~~
606-
607-
To complete our description of the general framework we will now discuss the notion of *state*. MuJoCo has a compact,
608-
well-defined internal state which, together with the :ref:`deterministic computational pipeline<piReproducibility>`,
609-
means that operations like resetting the state and computing dynamics derivatives are also well-defined.
610-
611-
The state is entirely encapsulated in the :ref:`mjData` struct and consists of several components. The components are
612-
enumerated in :ref:`mjtState` as bit flags, along with several common combinations, corresponding to the groupings
613-
below. Concatenated state vectors can be conveniently read from and written into :ref:`mjData` using :ref:`mj_getState`
614-
and :ref:`mj_setState`, respectively.
615602

603+
.. Leave links below to sections that were previously here and have moved to the simulation chapter.
616604
.. _gePhysicsState:
617-
618-
Physics state
619-
^^^^^^^^^^^^^
620-
The *physics state* (:ref:`mjSTATE_PHYSICS<mjtState>`) contains the main quantities which are time-integrated during
621-
stepping. These are ``mjData.{qpos, qvel, act}``:
622-
623-
Position: ``qpos``
624-
The configuration in generalized coodinates, denoted above as :math:`q`.
625-
626-
Velocity: ``qvel``
627-
The generalized velocities, denoted above as :math:`v`.
628-
629-
Actuator activation: ``act``
630-
``mjData.act`` contains the internal states of stateful actuators, denoted above as :math:`w`.
631-
632605
.. _geFullPhysics:
633-
634-
Full physics state
635-
^^^^^^^^^^^^^^^^^^
636-
637-
The *full physics state* (:ref:`mjSTATE_FULLPHYSICS<mjtState>`) contains the physics state and two additional
638-
components:
639-
640-
Time: ``time``
641-
The simulation time is given by the scalar ``mjData.time``. Since physics is time-invariant, it is
642-
excluded from the *physics state*; exceptions include time-dependent user callbacks and plugins (e.g., an open-loop
643-
controller), in which case time should be included.
644-
645-
Plugin state: ``plugin_state``
646-
``mjData.plugin_state`` are states declared by :ref:`engine plugins<exPlugin>`. Please see the :ref:`exPluginState`
647-
section for more details.
648-
649606
.. _geInput:
650-
651-
User inputs
652-
^^^^^^^^^^^
653-
654-
These input fields (:ref:`mjSTATE_USER<mjtState>`) are set by the user and affect the physics simulation, but are
655-
untouched by the simulator. All input fields except for MoCap poses default to 0.
656-
657-
Control: ``ctrl``
658-
Controls are defined by the :ref:`actuator<actuator>` section of the XML. ``mjData.ctrl`` values either produce
659-
generalized forces directly (stateless actuators), or affect the actuator activations in ``mjData.act``, which then
660-
produce forces.
661-
662-
Auxiliary Controls: ``qfrc_applied`` and ``xfrc_applied``
663-
| ``mjData.qfrc_applied`` are directly applied generalized forces.
664-
| ``mjData.xfrc_applied`` are Cartesian wrenches applied to the CoM of individual bodies. This field is used for
665-
example, by the :ref:`native viewer<saSimulate>` to apply mouse perturbations.
666-
| Note that the effects of ``qfrc_applied`` and ``xfrc_applied`` can usually be recreated by appropriate actuator
667-
definitions.
668-
669-
MoCap poses: ``mocap_pos`` and ``mocap_quat``
670-
``mjData.mocap_pos`` and ``mjData.mocap_quat`` are special optional kinematic states :ref:`described here<CMocap>`,
671-
which allow the user to set the positions and orientations of static bodies in real-time, for example when streaming
672-
6D poses from a motion-capture device. The default values set by :ref:`mj_resetData` are the poses of the bodies at
673-
the default configuration.
674-
675-
Equality constraint toggle: ``eq_active``
676-
``mjData.eq_active`` is a byte-valued array that allows the user to toggle the state of equality constraints at
677-
runtime. The initial value of this array is ``mjModel.eq_active0`` which can be set in XML using the
678-
:ref:`active<equality-connect-active>` attribute of :ref:`equality constraints<coEquality>`.
679-
680-
User data: ``userdata``
681-
``mjData.userdata`` acts as a user-defined memory space untouched by the engine. For example it can be used by
682-
callbacks. This is described in more detail in the :ref:`Programming chapter<siSimulation>`.
683-
684607
.. _geWarmstart:
685-
686-
Warmstart acceleration
687-
^^^^^^^^^^^^^^^^^^^^^^
688-
689-
``qacc_warmstart``
690-
``mjData.qacc_warmstart`` are accelerations used to warmstart the constraint solver, saved from the previous step.
691-
When using a slowly-converging :ref:`constraint solver<Solver>` like PGS, these can speed up simulation by reducing
692-
the number of iterations required for convergence. Note however that the default Newton solver converges so quickly
693-
(usually 2-3 iterations), that warmstarts often have no effect on speed and can be disabled.
694-
695-
Different warmstarts have no perceptible effect on the dynamics but should be saved if perfect numerical
696-
reproducibility is required when loading a non-initial state. Note that even though their effect on physics is
697-
negligible, many physical systems will accumulate small differences `exponentially
698-
<https://en.wikipedia.org/wiki/Lyapunov_exponent>`__ when time-stepping, quickly leading to divergent trajectories
699-
for different warmstarts.
700-
701608
.. _geIntegrationState:
609+
.. _geSimulationState:
702610

703-
Integration state
704-
^^^^^^^^^^^^^^^^^
611+
.. _geState:
705612

706-
The *integration state* (:ref:`mjSTATE_INTEGRATION<mjtState>`) is the union of all the above :ref:`mjData` fields and
707-
constitutes the entire set of inputs to the *forward dynamics*. In the case of *inverse dynamics*, ``mjData.qacc`` is
708-
also treated as an input variable. All other :ref:`mjData` fields are functions of the integration state.
613+
The State
614+
~~~~~~~~~
709615

710-
Note that the full integration state as given by :ref:`mjSTATE_INTEGRATION<mjtState>` is maximalist and includes fields
711-
which are often unused. If a small state size is desired, it might be sensible to avoid saving unused fields.
712-
In particular ``xfrc_applied`` can be quite large (``6 x nbody``) yet is often unused.
616+
To complete our description of the general framework we will quickly discuss the notion of *state*. MuJoCo has a
617+
compact, well-defined internal state which, together with the :ref:`deterministic pipeline<piReproducibility>`, means
618+
that operations like (re)setting the state and computing dynamics derivatives are also well-defined.
713619

714-
.. _geSimulationState:
620+
The state is entirely encapsulated in the :ref:`mjData` struct and consists of several components. The components are
621+
enumerated in :ref:`mjtState` as bit flags. Concatenated state vectors can be conveniently read from and written into
622+
:ref:`mjData` using :ref:`mj_getState` and :ref:`mj_setState`, respectively.
715623

716-
Simulation state: ``mjData``
717-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
718-
The *simulation state* is the entirety of the :ref:`mjData` struct and associated memory buffer. This state includes
719-
all derived quantities computed during dynamics computation. Because the :ref:`mjData` buffers are preallocated for the
720-
worst case, it is often significantly faster to recompute derived quantities from the *integration state* rather than
721-
using :ref:`mj_copyData`.
624+
More detail can be found in the :ref:`State and Control<siStateControl>` section in the Simulation chapter.
722625

723626
.. _Constraint:
724627

@@ -1824,8 +1727,8 @@ Control callback
18241727

18251728
Force/acceleration
18261729
''''''''''''''''''
1827-
The stages below compute quantities that depend on :ref:`user inputs<geInput>`. Due to the sequential nature
1828-
of the pipeline, the actual dependence is on the entire :ref:`integration state<geIntegrationState>`.
1730+
The stages below compute quantities that depend on :ref:`user inputs<siInput>`. Due to the sequential nature
1731+
of the pipeline, the actual dependence is on the entire :ref:`integration state<siIntegrationState>`.
18291732

18301733
20. Compute the actuator forces and activation dynamics if defined: :ref:`mj_fwdActuation`
18311734
21. Compute the joint acceleration resulting from all forces except for the (still unknown) constraint forces:
@@ -1871,8 +1774,8 @@ MuJoCo's simulation pipeline is entirely deterministic and reproducible -- if a
18711774
saved and reloaded and :ref:`mj_step` called again, the resulting next state will be identical. However, there are some
18721775
important caveats:
18731776

1874-
- Save all the required :ref:`integration state<geIntegrationState>` components. In particular :ref:`warmstart
1875-
accelerations<geWarmstart>` have only a very small effect on the next state, but should be saved if bit-wise equality
1777+
- Save all the required :ref:`integration state<siIntegrationState>` components. In particular :ref:`warmstart
1778+
accelerations<siWarmstart>` have only a very small effect on the next state, but should be saved if bit-wise equality
18761779
is required.
18771780
- Any numerical difference between states, no matter how small, will become significant upon integration, especially for
18781781
systems with contact. Contact events have high `Lyapunov exponents

doc/programming/modeledit.rst

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@ The new API augments the traditional workflow of creating and editing models usi
2121
*compile* steps. As summarized in the :ref:`Overview chapter<Instance>`, the traditional workflow is:
2222

2323
1. Create an XML model description file (MJCF or URDF) and associated assets. |br|
24-
2. Call :ref:`mj_loadXML`, obtain an mjModel instance.
24+
2. Call :ref:`mj_loadXML`, obtain an :ref:`mjModel` instance.
2525

2626
The new workflow using :ref:`mjSpec` is:
2727

28-
1. :ref:`Create<mj_makeSpec>` an empty mjSpec or :ref:`parse<mj_parseXML>` an existing XML file.
29-
2. Programmatically edit the mjSpec datastructure by adding, modifying and removing elements.
30-
3. :ref:`Compile<mj_compile>` the mjSpec to an mjModel instance.
28+
1. Create an empty :ref:`mjSpec` using :ref:`mj_makeSpec` or parse an existing XML file using :ref:`mj_parseXML`.
29+
2. Programmatically edit the :ref:`mjSpec` datastructure by adding, modifying and removing elements.
30+
3. Compile the :ref:`mjSpec` to an :ref:`mjModel` instance using :ref:`mj_compile`.
3131

32-
After compilation, the mjSpec remains editable, so steps 2 and 3 are interchangeable.
32+
After compilation, the :ref:`mjSpec` remains editable, so steps 2 and 3 are interchangeable.
3333

3434

3535
.. _meUsage:

0 commit comments

Comments
 (0)