Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Implementation:Google deepmind Dm control MJCF Element Add

From Leeroopedia
Metadata
Knowledge Sources dm_control
Domains Physics Simulation, Robotics, Model Authoring
Last Updated 2026-02-15 00:00 GMT

Overview

Concrete tool for building MJCF model trees by adding child elements via element.add() and setting attributes through Python attribute assignment, backed by strongly typed attribute classes.

Description

The add() method on any MJCF element creates a new child element of the specified tag type and returns it. Keyword arguments become the initial attribute values for the new element. Internally, add() delegates to insert() which:

  1. Validates that the tag is a legitimate child of the parent element.
  2. Checks whether the child spec is repeated (can appear multiple times) or on-demand (created lazily). A non-repeated, non-on-demand child that already exists raises a ValueError.
  3. Constructs the new element via _make_element(), which selects the correct element subclass (e.g., _AttachableElement for sites, _DefaultElement for defaults).
  4. Appends the new element to the parent's child list (or inserts at a specified position).
  5. Increments the name scope revision counter to invalidate any cached identifiers.

Attribute assignment works through Python's __setattr__ override on _ElementImpl. When a user writes element.pos = [1, 2, 3], the element checks whether the name corresponds to a known MJCF attribute and dispatches to the typed attribute object's value setter. The attribute classes in dm_control/mjcf/attribute.py handle validation:

  • String -- must be a non-empty str.
  • Integer -- must be convertible to int without truncation.
  • Float -- must be convertible to float.
  • Array -- converts to a 1-D NumPy array of the specified dtype and checks length constraints.
  • Keyword -- must match one of the predefined valid values (case-insensitive).
  • Identifier -- must be a unique string within its namespace and must not contain /.
  • Reference -- must be a string or an mjcf.Element of the correct namespace.
  • File -- can be a file path string or an Asset object; the file contents are loaded and hashed for VFS registration.

Usage

This is the primary API for authoring model content after a root element exists. Every body, geom, joint, actuator, sensor, and other MJCF component is created through add() calls and configured through attribute setters.

Code Reference

Property Value
Source Location dm_control/mjcf/element.py:L616-661 (add/insert), dm_control/mjcf/attribute.py:L1-578 (attribute types)
Signature (add) add(element_name, **kwargs) -> Element
Signature (insert) insert(element_name, position, **kwargs) -> Element
Attribute setter element.<attr_name> = value (via __setattr__)
Import from dm_control import mjcf

I/O Contract

Inputs (add):

Parameter Type Description
element_name str The MJCF tag of the child to create (e.g., 'body', 'geom', 'joint').
**kwargs various Initial attribute values. Keys must be valid MJCF attributes for the child element.

Inputs (attribute setter):

Parameter Type Description
value depends on attribute type The new value; validated by the corresponding attribute class (Array, Float, Keyword, etc.).

Outputs:

Output Type Description
return value (add) mjcf.Element The newly created child element, ready for further mutation.
side effect (setter) none The attribute value is stored in the element's internal attribute dictionary and the name scope revision is incremented.

Usage Examples

from dm_control import mjcf
import numpy as np

# Create a model and build its structure
model = mjcf.RootElement(model='arm')

# Add a body to the worldbody
upper_arm = model.worldbody.add('body', name='upper_arm', pos=[0, 0, 1])

# Add a geom and a joint to the body
upper_arm.add('geom', type='capsule', size=[0.04, 0.2])
upper_arm.add('joint', name='shoulder', type='hinge', axis=[0, 1, 0])

# Add a child body (forearm) to the upper arm
forearm = upper_arm.add('body', name='forearm', pos=[0, 0, 0.4])
forearm.add('geom', type='capsule', size=[0.03, 0.15])
forearm.add('joint', name='elbow', type='hinge', axis=[0, 1, 0],
            range=[-2.0, 0.0])

# Modify attributes after creation
forearm.pos = [0, 0, 0.45]  # Update position via attribute setter
forearm.geom[0].rgba = [1, 0, 0, 1]  # Set color

# Add actuators that reference joints
model.actuator.add('motor', name='shoulder_motor', joint='shoulder')
model.actuator.add('motor', name='elbow_motor', joint='elbow')

# Add a sensor
model.sensor.add('jointpos', name='elbow_sensor', joint='elbow')

# Verify the model compiles
print(model.to_xml_string())

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment