๐จ Model Building#
MotrixSim provides a programmatic model building API that allows you to load, transform, and combine multiple models before simulation. This is useful for:
Combining robot models with different end-effectors
Creating multi-robot scenes
Dynamically assembling models at runtime
Basic Concepts#
The model building API is available through the motrixsim.msd module:
Class/Function |
Description |
|---|---|
Load a model file (MJCF/URDF/MSD) and return a |
|
Load a model from string |
|
Attach another model to this one |
|
Build the final |
The Scene object is a mutable representation of a model that can be transformed and combined before being compiled into an immutable SceneModel.
Basic Usage#
Loading and Building a Model#
The simplest usage is to load a model file and build it:
import motrixsim as mx
# Load and build in one chain
model = mx.msd.from_file("robot.xml").build()
# Or step by step
scene = mx.msd.from_file("robot.xml")
model = scene.build()
Loading from String#
You can also create a model from an MJCF/URDF string:
import motrixsim as mx
mjcf_string = """
<mujoco>
<worldbody>
<body name="box">
<geom type="box" size="0.1 0.1 0.1"/>
</body>
</worldbody>
</mujoco>
"""
model = mx.msd.from_str(mjcf_string, format="mjcf").build()
Combining Models#
The attach method allows you to combine multiple models together:
import motrixsim as mx
# Load two models
robot = mx.msd.from_file("robot.xml")
gripper = mx.msd.from_file("gripper.xml")
# Attach gripper to robot's hand link
robot.attach(
gripper,
self_link_name="hand", # Link in robot to attach to
other_prefix="gripper_", # Prefix for gripper's names
other_translation=[0.1, 0, 0] # Offset
)
model = robot.build()
Attach Parameters#
Parameter |
Type |
Description |
|---|---|---|
|
|
The model to attach (cloned internally, can be reused) |
|
|
Link in this model to attach to. If |
|
|
Extract only this subtree from the other model |
|
|
Translation offset for the attached model |
|
|
Rotation quaternion for the attached model |
|
|
Prefix to add to all names in the attached model |
|
|
Suffix to add to all names in the attached model |
Creating Multiple Instances#
Since attach clones the other model internally, you can attach the same model multiple times:
import motrixsim as mx
scene = mx.msd.from_file("scene.xml")
robot = mx.msd.from_file("robot.xml")
# Create multiple robot instances at different positions
scene.attach(robot, other_prefix="robot1_", other_translation=[0, 0, 0])
scene.attach(robot, other_prefix="robot2_", other_translation=[2, 0, 0])
scene.attach(robot, other_prefix="robot3_", other_translation=[4, 0, 0])
model = scene.build()
Extracting Subtrees#
You can extract a specific subtree from a model before attaching:
import motrixsim as mx
robot = mx.msd.from_file("robot.xml")
full_arm = mx.msd.from_file("arm_with_base.xml")
# Only attach the "forearm" subtree, not the entire arm model
robot.attach(
full_arm,
self_link_name="shoulder",
other_link_name="forearm", # Extract from this link
other_prefix="arm_"
)
model = robot.build()
Complete Example#
Hereโs a complete example that creates a scene with multiple robots. For the full example, see examples/combine_msd.py.
import time
import motrixsim as mx
# Load the base scene
msd_scene = mx.msd.from_file("examples/assets/store/scene.xml")
# Load a dog model and attach an arm to it
msd_dog = mx.msd.from_file("examples/assets/boston_dynamics_spot/spot.xml")
msd_arm = mx.msd.from_file("examples/assets/stanford_tidybot_adhesion/tidybot.xml")
# Attach arm subtree to the dog's hip link
msd_dog.attach(
msd_arm,
self_link_name="hl_hip",
other_link_name="bracelet_link", # Extract subtree from arm
other_rotation=[-0.71, 0, 0, 0.71], # Rotate 90 degrees around X axis
other_prefix="arm_",
)
# Attach multiple dogs to the scene at different positions
# Note: other is cloned internally, so msd_dog can be reused
msd_scene.attach(msd_dog, other_translation=[1, 0, 0], other_prefix="dog0_")
msd_scene.attach(msd_dog, other_translation=[2, 0, 0], other_prefix="dog1_")
msd_scene.attach(msd_dog, other_translation=[3, 0, 0], other_prefix="dog2_")
# Build the final model
model = msd_scene.build()
with mx.render.RenderApp("warn") as render:
render.launch(model)
data = mx.SceneData(model)
while True:
time.sleep(model.options.timestep)
mx.step(model, data)
render.sync(data)
MJCF Attach Element#
MotrixSim also supports the MJCF <attach> element for combining models in XML:
<mujoco>
<asset>
<model name="gripper" file="gripper.xml"/>
</asset>
<worldbody>
<body name="robot">
<!-- robot definition -->
<body name="hand">
<attach model="gripper" prefix="gripper_"/>
</body>
</body>
</worldbody>
</mujoco>
For MJCF support details, see MJCF Files.
API Reference#
For detailed API documentation, see motrixsim.msd.