dora-openarm-mujoco
MuJoCo simulation node for the OpenArm bimanual robot, designed to run inside a dora-rs dataflow.
It replaces the physical follower arms and cameras: it accepts joint-position commands and publishes arm observations and JPEG camera frames at the same interface as the real hardware.
Installation
uv sync
Quick start
A self-contained dummy dataflow is included for testing without real hardware. It wires a dummy leader node to the MuJoCo sim and records to disk.
uv run dora build dataflow-dummy.yaml --uv
uv run dora run dataflow-dummy.yaml
Dataflow configuration
Minimal (headless and position forwarding only no cameras)
- id: openarm-mujoco
build: pip install -e .
path: dora-openarm-mujoco
inputs:
position_right: leader/follower_position_right
position_left: leader/follower_position_left
outputs:
- status
- arm_right_observation
- arm_left_observation
Full (interactive viewer + all cameras, with contacts, can be used for vr teleoperation)
- id: openarm-mujoco
build: pip install -e .
path: dora-openarm-mujoco
args: "--viewer --render --enable-collision --ctrl --keyframe home"
inputs:
position_right: leader/follower_position_right
position_left: leader/follower_position_left
outputs:
- status
- arm_right_observation
- arm_left_observation
- camera_wrist_right
- camera_wrist_left
- camera_head_left
- camera_head_right
- camera_ceiling
Inputs
| ID | Type | Description |
|---|---|---|
position_right |
float32[8] |
Target joint positions for the right arm: joints 1–7 then the gripper. ~500 Hz. |
position_left |
float32[8] |
Same layout for the left arm. |
pose_right |
float32[7] |
VR controller pose [x, y, z, qw, qx, qy, qz], expressed in the --origin-frame frame (default: the scene's arm_origin site). Used only with --debug-frames. |
pose_left |
float32[7] |
Same for the left controller. |
button_x |
bool[1] |
X button state. Edge-triggered: on press every scene joint on non-arm bodies (freejoint objects plus fixtures like drawers/doors) snaps back to the --keyframe pose; with --randomize-objects the freejoint objects land at a randomized pose instead. The button must be released to re-arm. |
Outputs
| ID | Type | Description |
|---|---|---|
arm_right_observation |
float32[8] |
Observed joint positions, published per incoming command. |
arm_left_observation |
float32[8] |
Same for the left arm. |
camera_wrist_right |
uint8[N] |
JPEG frame, ~30 Hz. Requires --render. |
camera_wrist_left |
uint8[N] |
JPEG frame, ~30 Hz. Requires --render. |
camera_head_left |
uint8[N] |
JPEG frame, ~30 Hz. Requires --render. |
camera_head_right |
uint8[N] |
JPEG frame, ~30 Hz. Requires --render. |
camera_ceiling |
uint8[N] |
JPEG frame, ~30 Hz. Requires --render. |
Camera outputs carry metadata={"encoding": "jpeg"}.
Arguments
Pass these via the args: field in the dataflow YAML, or directly on the command line.
| Argument | Default | Description |
|---|---|---|
--xml PATH |
unset | MJCF scene file to load. Overrides --scene when set. |
--scene NAME |
cell |
Bundled scene to load when --xml is not set. Choices: cell, demo, pedestal, bimanual. |
--keyframe NAME |
home |
Keyframe in the MJCF to reset to on startup. |
--randomize-objects [RANGE_M] |
off | Randomize freejoint scene objects (e.g. cubes) on startup and on each button_x reset: uniform xy offset within ±RANGE_M m of the keyframe pose plus a uniform yaw. z and articulated fixtures are unchanged. RANGE_M defaults to 0.05 when omitted. |
--enable-collision |
off | Enable contact/collision detection. Disabled by default to avoid unexpected joint-locking during teleoperation. |
--ctrl |
off | Write incoming positions to data.ctrl and step the physics (mj_step) to simulate actuator control. The default writes directly to data.qpos with mj_forward. |
--viewer |
off | Open the interactive MuJoCo viewer window. Requires a display. |
--render |
off | Enable offscreen camera rendering and publish JPEG frames. Leave off if cameras are not needed. |
--debug-frames |
off | Draw VR controller poses as coloured arrows in the viewer. Only visible with --viewer. |
--origin-frame NAME |
arm_origin |
Frame incoming pose_right/pose_left are relative to; the overlay composes poses with its live world pose and draws the reference axes there. Pass world for raw world-frame poses. Missing frame → warning + world fallback. |
--origin-frame-type TYPE |
site |
MuJoCo object type of --origin-frame. Choices: body, site, geom. |
Environment variables
Every argument's default can also be set via an environment variable named
DORA_OPENARM_MUJOCO_ + the upper-cased argument name:
| Environment variable | Argument |
|---|---|
DORA_OPENARM_MUJOCO_XML |
--xml |
DORA_OPENARM_MUJOCO_SCENE |
--scene |
DORA_OPENARM_MUJOCO_KEYFRAME |
--keyframe |
DORA_OPENARM_MUJOCO_ENABLE_COLLISION |
--enable-collision |
DORA_OPENARM_MUJOCO_CTRL |
--ctrl |
DORA_OPENARM_MUJOCO_VIEWER |
--viewer |
DORA_OPENARM_MUJOCO_RENDER |
--render |
DORA_OPENARM_MUJOCO_DEBUG_FRAMES |
--debug-frames |
DORA_OPENARM_MUJOCO_ORIGIN_FRAME |
--origin-frame |
DORA_OPENARM_MUJOCO_ORIGIN_FRAME_TYPE |
--origin-frame-type |
Boolean flags accept 1/0, true/false, yes/no and on/off.
DORA_OPENARM_MUJOCO_VIEWER additionally accepts an FPS number
(e.g. 60); true enables the viewer at the default 30 Hz.
Explicit CLI arguments override the environment. Boolean flags also gain a
--no-* form (e.g. --no-render, --no-viewer) to turn an
environment-enabled option back off. Set the variables via the env: field
of the node in the dataflow YAML:
- id: openarm-mujoco
path: dora-openarm-mujoco
env:
DORA_OPENARM_MUJOCO_VIEWER: "60"
DORA_OPENARM_MUJOCO_RENDER: "true"
License
Licensed under the Apache License 2.0. See LICENSE for details.
Copyright 2026 Enactic, Inc.
Code of Conduct
All participation in the OpenArm project is governed by our Code of Conduct.
Metadata
Release files for dora-openarm-mujoco 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| dora_openarm_mujoco-0.4.0.tar.gz | 20.4 kB | Details |
Release files / dora_openarm_mujoco-0.4.0.tar.gz
| Download URL | dora_openarm_mujoco-0.4.0.tar.gz |
|---|---|
| Size | 20.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ccc8384d790707a1b2ee0f5900129e89d5fe49af977b236a140807b44a9b58c1
|
|
BLAKE2b-256 checksum How to use checksums |
79bb14053fce595c594705ae87b511c198b991967f34fe64d8093a74fcfef2dc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.
Transparency log