Best for
- Simulating a low-DOF arm (grasping, pick-and-place, contact-rich
- Rendering camera observations headless for a policy/dataset pipeline, and
- Writing an inverse-kinematics reach + grasp routine by hand (damped
robium-ai/robium/skills/mujoco/SKILL.md
MuJoCo for lightweight, contact-rich robot manipulation simulation on macOS/Linux, especially single-arm grasping without ROS: headless offscreen rendering, MJCF models, mujoco_menagerie assets, damped-least-squares inverse kinematics, and empirical grasp calibration. Use when: 'MuJoCo', 'MJCF', 'mjpython', 'MUJOCO_GL', 'menagerie', 'SO-101' / SO-ARM100 arm, 'offscreen render', 'inverse kinematics' / 'IK', 'grasp' / 'pick and place' in sim, hand-building a manipulation env, or headless mujoco.Re
Decision brief
MuJoCo 3.x for robium's lightweight, non-ROS manipulation side: a fast contact-rich physics engine with an offscreen renderer, well suited to hand-building a single-arm grasping/pick-and-place environment when the full ROS + Gazebo stack (or a GPU-gated Isaac stack) is more than…
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/robium-ai/robium --skill "skills/mujoco"Inspect the Agent Skill "mujoco" from https://github.com/robium-ai/robium/blob/e94a788531ebbbce97693d713ae5fb4ae64155ed/skills/mujoco/SKILL.md at commit e94a788531ebbbce97693d713ae5fb4ae64155ed. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
1. Install (pin MuJoCo explicitly, above the menagerie floor):
Headless render is not the bottleneck on Apple Silicon. Measured on the vla-trial build: 84 fps at 256x256 via MUJOCOGL=cgl, against a 60 fps floor; mjstep 0.012 ms vs 11.8 ms per render. This kills the common upstream worry that "offscreen render is extremely slow": for a low-D…
Simulating a low-DOF arm (grasping, pick-and-place, contact-rich
Delegation posture: embed + links. The robium-specific,
mujoco.mjresetData(model, data) mujoco.mjforward(model, data) renderer.updatescene(data, camera="fixedcam") = renderer.render()
Permission review
No configured static risk pattern was detected
This is not proof of safety. Runtime behavior, indirect dependencies, and hidden external systems are outside the static scan.
Evidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 94/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 8 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
MuJoCo 3.x for robium's lightweight, non-ROS manipulation side: a fast contact-rich physics engine with an offscreen renderer, well suited to hand-building a single-arm grasping/pick-and-place environment when the full ROS + Gazebo stack (or a GPU-gated Isaac stack) is more than the task needs. This skill stays deliberately thin on the MuJoCo API itself: the model format (MJCF), the Python bindings, and the robot assets in mujoco_menagerie are all documented upstream and move release to release. What it embeds instead is the set of hard-won gotchas from the vla-trial SO-101 build (macOS arm64, MuJoCo 3.x, observed 2026-07-13/14): the macOS headless-render backend, version-pin traps, offscreen-render determinism, and the IK / grasp-calibration failure modes that cost the most time and give no error message when they bite.
gazebo
skill.isaac-sim / isaac-lab skills (GPU-gated).simulation umbrella (routes here for
lightweight non-ROS manipulation).lerobot skill;
MuJoCo here is only the sim that produces observations/actions.architect skill.mujoco Python bindings, mj_step/mj_forward, the Renderer class, and
robot assets) point upstream to MuJoCo's docs and the mujoco_menagerie repo
(see References); do not restate the API from memory, it changes across 3.x
releases.MUJOCO_GL=cgl is the only headless render backend. osmesa and
egl are Linux-only (mujoco#2164). Set it before importing mujoco.mujoco<3.9, gym-xarm pins
<3.0); depending on one of those can silently downgrade MuJoCo below the
model's requirement. Pin MuJoCo explicitly and verify the installed version.1. Install (pin MuJoCo explicitly, above the menagerie floor):
uv add "mujoco>=3.1.3" # current 3.10 as of 2026-07; SO-101 needs >=3.1.3
Do not let a gym wrapper (gym-hil, gym-xarm) choose the version transitively; it can pin MuJoCo below what the model needs.
2. Get the robot asset from mujoco_menagerie, not upstream MJCF. Clone mujoco_menagerie and use its SO-101 model (the robotstudio_so101 directory, which ships a pick-and-place scene, manipulation-tuned collision geometry, and a camera mount). Do NOT use the upstream TheRobotStudio/SO-ARM100 MJCF: its own README admits the gripper linear-joint mapping is not reflected in the model.
3. Headless offscreen render (macOS):
import os
os.environ["MUJOCO_GL"] = "cgl" # macOS headless backend; must precede import
import mujoco
model = mujoco.MjModel.from_xml_path("scene.xml")
data = mujoco.MjData(model)
renderer = mujoco.Renderer(model, height=256, width=256)
# warm-up: one throwaway full reset+render (see determinism gotcha below)
mujoco.mj_resetData(model, data)
mujoco.mj_forward(model, data)
renderer.update_scene(data, camera="fixed_cam")
_ = renderer.render()
4. Interactive viewer needs mjpython. mujoco.viewer.launch_passive
requires launching with mjpython, not python (and is buggy under uv,
mujoco#1923). Offscreen rendering (step 3) has no such requirement.
For MJCF syntax, the bindings, and API signatures, go to MuJoCo's own docs (References) before hand-writing model or physics code.
Headless render is not the bottleneck on Apple Silicon. Measured on the
vla-trial build: ~84 fps at 256x256 via MUJOCO_GL=cgl, against a 60 fps
floor; mj_step ~0.012 ms vs ~11.8 ms per render. This kills the common
upstream worry that "offscreen render is extremely slow": for a low-DOF arm
scene it is comfortably real-time. Render, don't skip frames to save time.
Deterministic offscreen rendering (needed for reproducible datasets/evals):
mode="targetbody". A
target-tracking camera re-runs its smoothing filter on every
update_scene(), making the rendered pose call-history-dependent (observed
up to 85 LSB drift) even when the physics is bit-identical.__init__.
A fresh mujoco.Renderer's first reset→mj_forward→render cycle is not
repeatable against later renders (~6 LSB). A raw pre-mj_forward warm-up does
NOT consume the cold cycle; it must be a full reset+render.Reachability probing (IK). Because the DLS solver returns silently on an unreachable target, probe the full task footprint × every lift height independently before trusting the env. Menagerie's default box spawn (0.5, 0, 0.03) is unreachable by the SO-101 mount, for example.
Empirical grasp calibration. The end-effector site is not the grasp point. Calibrate the gripper-local grasp offset by experiment: teleport the object to a grid, close, lift, and keep the offsets that actually lift. Key facts:
Wrist-roll orientation is the silent half of position-only IK. On a 5-DOF
arm, position-only IK leaves wrist roll free. At roll≈0 the pinch axis was 91%
vertical, so a 4.2 cm aperture could not span a 6 cm cube (closed on air,
0/10). Diagnostic: print the world-frame pinch axis and check it is
perpendicular to the grasped dimension. Fix: solve wrist roll as a 1-D root
find (pinch_z(roll) is a smooth sinusoid), then re-solve position with roll
pinned via jnt_range; adding roll to the DLS objective diverges. This took
the oracle grasp from 0/10 to 8/10. (Position-only IK also gives no signal
about the orientation it chose; a level-finger constraint may be genuinely
infeasible on a 5-DOF arm.)
Debugging "arm won't reach / knocked the object over":
qfrc_actuator vs forcerange : saturated joints mean BLOCKED,
not slow. Raising settle steps (e.g. 12→60) is a dead end when joints are
saturated.Resolve gripper geoms by body, not name. Menagerie leaves mesh geoms
UNNAMED, so a name-based gripper-geom list silently misses the fixed-jaw
collision mesh, a false-success risk in contact checks. Collect gripper geoms
by model.geom_bodyid membership instead.
Determine gripper polarity empirically. Drive the gripper joint to each end
of its actuator_ctrlrange and measure the fingertip gap. SO-101 is
LOW=closed / HIGH=open; the upstream SO-ARM100 docs claim the opposite and even
admit their own MJCF disagrees, so measure, don't trust the docs.
MUJOCO_GL=cgl only (osmesa/egl are
Linux-only, mujoco#2164). Set it before import mujoco.mujoco.Renderer created on one thread hangs forever
(no error, no timeout, no exception) the first time a different thread
renders on it; the stack sits in cgl make_current. This bites frameworks
that run handlers on worker threads (e.g. Gradio): a first env.reset()
called from a worker freezes the stream. Fix: construct the env/renderer in
the same thread that runs the episode (a per-run env in the handler), not once
at import on the main thread. (observed 2026-07-15, vla-trial)mjpython, not python, and is buggy under
uv (mujoco#1923). Offscreen rendering does not need mjpython.lerobot skill; keep the sim env and the dataset layer
separate.Renderer API), google-deepmind/mujoco GitHub
repo (releases and the issues
cited above: #2164 render backends, #1923 viewer-under-uv),
mujoco_menagerie
(robot assets, incl. the SO-101 model; prefer this over upstream
TheRobotStudio/SO-ARM100 MJCF). All facts above observed on MuJoCo 3.x,
macOS arm64, 2026-07-13/14 (vla-trial SO-101 build); re-verify version-tied
claims against current releases.simulation umbrella (routes here for lightweight
non-ROS manipulation; owns the Gazebo-vs-Isaac selection), gazebo (ROS 2
simulation), isaac-sim / isaac-lab (GPU-gated photoreal / RL sim),
lerobot (policy training/eval that consumes this sim's observations),
architect (routes the whole stack decision here).1.0.2 (2026-08-03): style pass; removed em dashes throughout (no content changes).
1.0.1 (2026-08-01): anchor IDs added to claim-bearing items (learning-engine Phase 1); no content changes.
1.0.0 (2026-07-31): created: captured from the vla-trial SO-101 manipulation build (2026-07-13/14).
Frequently asked questions
MuJoCo 3.x for robium's lightweight, non-ROS manipulation side: a fast contact-rich physics engine with an offscreen renderer, well suited to hand-building a single-arm grasping/pick-and-place environment when the full ROS + Gazebo stack (or a GPU-gated Isaac stack) is more than…
The source record exposes this install command: npx skills add https://github.com/robium-ai/robium --skill "skills/mujoco". Inspect the command and pinned source before running it.
Alternatives
robium-ai/robium
MuJoCo for lightweight, contact-rich robot manipulation simulation on macOS/Linux, especially single-arm grasping without ROS: headless offscreen rendering, MJCF models, mujoco_menagerie assets, damped-least-squares inverse kinematics, and empirical grasp calibration. Use when: 'MuJoCo', 'MJCF', 'mjpython', 'MUJOCO_GL', 'menagerie', 'SO-101' / SO-ARM100 arm, 'offscreen render', 'inverse kinematics' / 'IK', 'grasp' / 'pick and place' in sim, hand-building a manipulation env, or headless mujoco.Re
robium-ai/robium
MuJoCo for lightweight, contact-rich robot manipulation simulation on macOS/Linux, especially single-arm grasping without ROS: headless offscreen rendering, MJCF models, mujoco_menagerie assets, damped-least-squares inverse kinematics, and empirical grasp calibration. Use when: 'MuJoCo', 'MJCF', 'mjpython', 'MUJOCO_GL', 'menagerie', 'SO-101' / SO-ARM100 arm, 'offscreen render', 'inverse kinematics' / 'IK', 'grasp' / 'pick and place' in sim, hand-building a manipulation env, or headless mujoco.Re
oaustegard/claude-skills
Generate hierarchical _FEATURES.md files that describe what a codebase DOES from a user/consumer perspective, anchored to source symbols via tree-sitting. Supports large complex codebases through feature-driven decomposition into sub-feature files. Uses a multi-pass synthesis: orientation → detail → overview rewrite. Use when someone says "what does this do", "document features", "feature inventory", "_FEATURES.md", or needs to understand a codebase's purpose before modifying it. Complements tre
dancingteeth/unified-code-review
Risk-first code review for PRs and branch audits: blast-radius triage, agent-authored discipline (tests first, intent evidence), call-graph pincer for integration defects between modules, then structural code-judo bar. Use when reviewing PRs, auditing agent-written diffs, catching rubber-stamp green CI, or wiring bugs single-file review misses. Prefer over structure-only thermo-nuclear review alone. Do not use for unrelated coding tasks or as an always-on rule.