Implementation:Google deepmind Dm control MuJoCo Wrapper Core
| Knowledge Sources | |
|---|---|
| Domains | Robotics Simulation, Physics Engine Integration |
| Last Updated | 2026-02-15 04:00 GMT |
Overview
The core module provides the main user-facing Python wrapper classes around MuJoCo's core C data structures (MjModel, MjData) and visualization/rendering structures (MjvCamera, MjvOption, MjvScene, MjrContext, MjvPerturb, MjvFigure), along with utility functions for model loading, callbacks, and XML serialization.
Description
MjModel and MjData use metaclasses (_MjModelMeta, _MjDataMeta) that dynamically create property descriptors delegating attribute access to the underlying mujoco.MjModel and mujoco.MjData objects, providing transparent passthrough while adding dm_control-specific functionality. MjModel provides named constructors for loading from XML strings (from_xml_string), XML file paths (from_xml_path), byte strings (from_byte_string), and compiled binary paths (from_binary_path) via internal helper functions _get_model_ptr_from_xml and _get_model_ptr_from_binary. It adds name2id/id2name lookups for converting between element names and integer IDs, a disable context manager for temporarily disabling simulation flags (e.g., gravity, contact), binary serialization (save_binary, to_bytes), and copy semantics.
MjData wraps simulation state and provides object_velocity for computing 6D velocity (linear, angular) of any MuJoCo object, contact_force for retrieving contact wrench data, a contact property that returns a variable-length recarray of current contacts, copy semantics with optional model sharing, and pickling support. The visualization classes extend their mujoco counterparts: MjvCamera adds backward-compatible type_ property, MjvOption disables rangefinder visualization by default, MjvScene adds override_flags context manager for temporary render flag changes and automatic max_geom estimation, and MjrContext manages the OpenGL rendering context lifecycle with weak references and reference counting to prevent resource leaks.
Module-level code verifies MuJoCo header/library version consistency, installs custom warning/error callbacks via ctypes, and provides set_callback/callback_context for overriding MuJoCo callback functions. The enable_timer utility hooks Python's time.time into MuJoCo's timer callback.
Usage
This module is the foundational layer of dm_control's MuJoCo integration. Use MjModel to load simulation models and MjData to interact with simulation state. All higher-level code (the Physics engine, tasks, environments) depends on these wrapper classes. Use the callback utilities when you need to customize MuJoCo's behavior (e.g., custom passive forces, collision callbacks), and the visualization classes when rendering simulations.
Code Reference
Source Location
- Repository: Google_deepmind_Dm_control
- File: dm_control/mujoco/wrapper/core.py
- Lines: 1-757
Signature
class MjModel(metaclass=_MjModelMeta):
def __init__(self, model_ptr): ...
@classmethod
def from_xml_string(cls, xml_string, assets=None): ...
@classmethod
def from_xml_path(cls, xml_path): ...
@classmethod
def from_byte_string(cls, byte_string): ...
@classmethod
def from_binary_path(cls, binary_path): ...
def name2id(self, name, object_type): ...
def id2name(self, object_id, object_type): ...
def save_binary(self, binary_path): ...
def to_bytes(self): ...
@contextlib.contextmanager
def disable(self, *flags): ...
class MjData(metaclass=_MjDataMeta):
def __init__(self, model_or_data): ...
def object_velocity(self, object_id, object_type, local_frame=False): ...
def contact_force(self, contact_id): ...
def copy(self): ...
class MjvCamera(mujoco.MjvCamera): ...
class MjvOption(mujoco.MjvOption): ...
class MjvScene(mujoco.MjvScene):
def __init__(self, model=None, max_geom=None): ...
@contextlib.contextmanager
def override_flags(self, overrides): ...
class MjrContext:
def __init__(self, model, gl_context, font_scale=...): ...
def free(self): ...
class MjvPerturb(mujoco.MjvPerturb): ...
class MjvFigure(mujoco.MjvFigure): ...
def set_callback(name, new_callback=None): ...
@contextlib.contextmanager
def callback_context(name, new_callback=None): ...
def enable_timer(enabled=True): ...
def get_schema(): ...
def save_last_parsed_model_to_xml(xml_path, check_model=None): ...
Import
from dm_control.mujoco.wrapper.core import MjModel, MjData
from dm_control.mujoco.wrapper.core import MjvScene, MjvCamera, MjvOption
from dm_control.mujoco.wrapper.core import set_callback, callback_context
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| xml_string | str | Yes (for from_xml_string) | MJCF or URDF model description string |
| xml_path | str | Yes (for from_xml_path) | Path to an MJCF or URDF model file |
| assets | dict | No | External assets as {filename: contents_bytes} pairs |
| byte_string | bytes | Yes (for from_byte_string) | Serialized MuJoCo model binary |
| binary_path | str | Yes (for from_binary_path) | Path to a compiled MJB model binary |
| name | str | Yes (for name2id) | Element name to look up |
| object_type | str or int | Yes (for name2id/id2name) | MuJoCo object type (e.g., 'body', 'geom', or mjtObj enum) |
| object_id | int | Yes (for object_velocity) | Integer ID of the MuJoCo object |
| contact_id | int | Yes (for contact_force) | Index of the contact within the contact buffer |
Outputs
| Name | Type | Description |
|---|---|---|
| MjModel instance | MjModel | Wrapper around the MuJoCo model with Pythonic API |
| MjData instance | MjData | Wrapper around simulation state with velocity/contact methods |
| name2id() | int | Integer ID corresponding to the named object |
| id2name() | str | Name corresponding to the object ID (empty string if unnamed) |
| object_velocity() | np.ndarray (2, 3) | Stacked (linear_velocity, angular_velocity) array |
| contact_force() | np.ndarray (2, 3) | Stacked (force, torque) wrench in the contact frame |
| to_bytes() | bytes | Serialized model binary |
Usage Examples
Loading a Model
from dm_control.mujoco.wrapper.core import MjModel, MjData
# Load from an XML file
model = MjModel.from_xml_path('/path/to/model.xml')
# Load from an XML string
model = MjModel.from_xml_string('<mujoco><worldbody/></mujoco>')
# Load with external assets
model = MjModel.from_xml_string(xml_string, assets={'mesh.stl': mesh_bytes})
# Create simulation data
data = MjData(model)
Working with Simulation Data
# Look up element IDs by name
body_id = model.name2id('torso', 'body')
geom_id = model.name2id('floor', 'geom')
# Get object velocity
linear_vel, angular_vel = data.object_velocity(body_id, 'body')
# Get contact forces
if data.ncon > 0:
force, torque = data.contact_force(0)
# Temporarily disable gravity
with model.disable('gravity'):
# Simulate without gravity
pass
Using Callbacks
from dm_control.mujoco.wrapper.core import set_callback, callback_context
# Temporarily override a callback
with callback_context('mjcb_control', my_controller):
# Simulation uses my_controller during this block
pass
# Enable MuJoCo's internal timer
from dm_control.mujoco.wrapper.core import enable_timer
enable_timer(True)