MJWarp Preliminary#
This page introduces the upstream mujoco_warp package only as background. It is included to explain the workflow and API pattern that comfree_warp largely preserves, not because mujoco_warp is the primary target of this documentation.
If you are here to use ComFree directly, you can treat this page as a short compatibility primer and then move on to ComFree Warp Usage.
mujoco_warp is a Warp-based simulation backend for MuJoCo models. In broad terms, the workflow is:
MjModel / MjData -> put_model / put_data -> step / forward
We include this MJWarp introduction because comfree_warp intentionally stays close to the same interface and execution pattern. Understanding the basic mujoco_warp usage pattern makes it much easier to understand comfree_warp, since the same core entry points such as put_model, put_data, step, forward, reset_data, and get_data_into carry over directly.
For full upstream documentation, see the mujoco_warp docs.
Imports#
import mujoco
import warp as wp
import mujoco_warp as mjwarp
Minimal Example#
# 1) Load and compile a MuJoCo model, then allocate runtime state
model_path = "benchmark/test_data/primitives.xml"
mjm = mujoco.MjSpec.from_file(model_path).compile()
mjd = mujoco.MjData(mjm)
mujoco.mj_forward(mjm, mjd)
# 2) Convert the model and data into Warp-side structures
m = mjwarp.put_model(mjm)
d = mjwarp.put_data(mjm, mjd, nworld=1, nconmax=1000, njmax=5000)
# 3) Warm up once, then capture a Warp graph for repeated execution
mjwarp.step(m, d)
mjwarp.step(m, d)
with wp.ScopedCapture() as capture:
mjwarp.step(m, d)
graph = capture.graph
# 4) Launch the captured graph and copy results back when needed
for _ in range(100):
wp.capture_launch(graph)
wp.synchronize()
mjwarp.get_data_into(mjd, mjm, d)
What This Example Shows#
mujoco.MjSpec.from_file(...).compile()produces a compiledMjModel, stored here inmjm.mujoco.MjData(mjm)allocates the corresponding runtimeMjDatastructure on the host.mjwarp.put_model(mjm)places the host-sideMjModelonto device and returns anmjwarp.Model.mjwarp.put_data(mjm, mjd, ...)places the host-sideMjDataonto device and returns anmjwarp.Data.mjwarp.Modelandmjwarp.Datamirror their MuJoCo counterparts conceptually, but store Warp arrays on device and may omit fields associated with unsupported features.mjwarp.step(m, d)advances the device-side simulation state by executing the MJWarp simulation pipeline.mjwarp.get_data_into(mjd, mjm, d)copies one world from device back into an existing host-sideMjDatawhen MuJoCo-side access is needed.
Notes#
nworldspecifies how many parallel simulation worlds are allocated in the Warp-side data object.nconmaxis the expected number of contacts per world. The total number of contacts across all worlds can exceednconmaxfor an individual world as long as the overall batch allocation is not exceeded.njmaxis the maximum number of constraints per world, and this limit is enforced per world.mujoco.mj_forward(mjm, mjd)is used here to start from a consistent host-side state before transferring data to device.get_data_into(...)is only needed when downstream code, logging, or visualization must read host-side MuJoCo state.
For basic usage, comfree_warp keeps the same overall call structure as mujoco_warp, which is why understanding this page is useful before moving on to the ComFree-specific API extensions.