rofunc.utils.robolab.formatter.mjcf_parser.physics#

Helpers for MJCF elements to interact with dm_control.mujoco.Physics.

1.  Module Contents#

1.1.  Classes#

SynchronizingArrayWrapper

A non-contiguous view of an ndarray that synchronizes with the original.

Binding

Binding between a mujoco.Physics and an mjcf.Element or a list of Elements.

Physics

A specialized mujoco.Physics that supports binding to MJCF elements.

1.2.  Functions#

names_from_elements

Returns namespace and named_index for mjcf_elements.

1.3.  Data#

FLAGS

1.4.  API#

rofunc.utils.robolab.formatter.mjcf_parser.physics.FLAGS = None#
rofunc.utils.robolab.formatter.mjcf_parser.physics.names_from_elements(mjcf_elements)#

Returns namespace and named_index for mjcf_elements.

Args:
mjcf_elements: Either an mjcf.Element, or an iterable of mjcf.Element

of the same kind.

Returns:
A tuple of (namespace, named_indices) where

-namespace is the Mujoco element type (eg: ‘geom’, ‘body’, etc.) -named_indices are the names of mjcf_elements, either as a single

string or an iterable of strings depending on whether mjcf_elements was an mjcf.Element or an iterable of `mjcf_Element`s.

Raises:

ValueError: If mjcf_elements cannot be bound to this Physics.

class rofunc.utils.robolab.formatter.mjcf_parser.physics.SynchronizingArrayWrapper(shape, dtype=float, buffer=None, offset=0, strides=None, order=None)#

Bases: numpy.ndarray

A non-contiguous view of an ndarray that synchronizes with the original.

Note: this class should not be instantiated directly.

Initialization

copy(order='C')#
class rofunc.utils.robolab.formatter.mjcf_parser.physics.Binding(physics, namespace, named_index)#

Binding between a mujoco.Physics and an mjcf.Element or a list of Elements.

This object should normally be created by calling physics.bind(element) where physics is an instance of mjcf.Physics. See docstring for that function for details.

Initialization

property element_id#

The ID number of this element within MuJoCo’s data structures.

class rofunc.utils.robolab.formatter.mjcf_parser.physics.Physics#

Bases: dm_control.mujoco.Physics

A specialized mujoco.Physics that supports binding to MJCF elements.

classmethod from_mjcf_model(mjcf_model)#

Constructs a new mjcf.Physics from an mjcf.RootElement.

Args:

mjcf_model: An mjcf.RootElement instance.

Returns:

A new mjcf.Physics instance.

reload_from_mjcf_model(mjcf_model)#

Reloads this mjcf.Physics from an mjcf.RootElement.

After calling this method, the state of this Physics instance is the same as a new Physics instance created with the from_mjcf_model named constructor.

Args:

mjcf_model: An mjcf.RootElement instance.

property is_dirty#

Whether this physics’ internal state needs to be recalculated.

mark_as_dirty()#

Marks this physics as dirty, thus requiring recalculation.

forward()#

Recomputes the forward dynamics without advancing the simulation.

bind(mjcf_elements) rofunc.utils.robolab.formatter.mjcf_parser.physics.Binding#

Creates a binding between this Physics instance and `mjcf.Element`s.

The binding allows for easier interaction with the Physics data structures related to an MJCF element. For example, in order to access the Cartesian position of a geom, we can use:

`python physics.bind(geom_element).pos `

instead of the more cumbersome:

`python physics.named.model.geom_pos[geom_element.full_identifier] `

Note that the binding takes into account the type of element. This allows us to remove prefixes from certain common attributes in order to unify access. For example, we can use:

`python physics.bind(geom_element).pos = [1, 2, 3] physics.bind(site_element).pos = [4, 5, 6] `

instead of:

`python physics.named.model.geom_pos[geom_element.full_identifier] = [1, 2, 3] physics.named.model.site_pos[site_element.full_identifier] = [4, 5, 6] `

This in turn allows for the creation of common algorithms that can operate across a wide range of element type.

When attribute values are modified through the binding, future queries of derived values are automatically recalculated if necessary. For example, if a joint’s qpos is modified and a site’s xpos is later read, the value of the xpos is updated according to the new joint configuration. This is done lazily when an updated value is required, so repeated value modifications do not incur a performance penalty.

It is also possible to bind a sequence containing one or more elements, provided they are all of the same type. In this case the binding exposes SynchronizingArrayWrapper`s, which are array-like objects that provide writeable views onto the corresponding memory addresses in MuJoCo. Writing into a `SynchronizingArrayWrapper causes the underlying values in MuJoCo to be updated, and if necessary causes derived values to be recalculated. Note that in order to trigger recalculation it is necessary to reference a derived attribute of a binding.

`python bound_joints = physics.bind([joint1, joint2]) bound_bodies = physics.bind([body1, body2]) # `qpos_view` and `xpos_view` are `SynchronizingArrayWrapper`s providing # views onto `physics.data.qpos` and `physics.data.xpos` respectively. qpos_view = bound_joints.qpos xpos_view = bound_bodies.xpos # This updates the corresponding values in `physics.data.qpos`, and marks # derived values (such as `physics.data.xpos`) as needing recalculation. qpos_view[0] += 1. # Note: at this point `xpos_view` still contains the old values, since we # need to actually read the value of a derived attribute in order to # trigger recalculation. another_xpos_view = bound_bodies.xpos  # Triggers recalculation of `xpos`. # Now both `xpos_view` and `another_xpos_view` will contain the updated # values. `

Note that SynchronizingArrayWrapper`s cannot be pickled. We also do not recommend holding references to them - instead hold a reference to the binding object, or call `physics.bind again.

Bindings also support numpy-style square bracket indexing. The first element in the indexing expression should be an attribute name, and the second element (if present) is used to index into the columns of the underlying array. Named indexing into columns is also allowed, provided that the corresponding field in physics.named supports it.

`python physics.bind([geom1, geom2])['pos'] = [[1, 2, 3], [4, 5, 6]] physics.bind([geom1, geom2])['pos', ['x', 'z']] = [[1, 3], [4, 6]] `

Args:
mjcf_elements: Either an mjcf.Element, or an iterable of mjcf.Element

of the same kind.

Returns:

A binding between this Physics instance an mjcf_elements, as described above.

Raises:

ValueError: If mjcf_elements cannot be bound to this Physics.