generic_robot_env
A generic MuJoCo-based robot environment generator for LeRobot or Gymnasium-style experiments.
This library is heavily inspired by and depends on the gym_hil project which implemented the first variant of these configurations.
This package provides
RobotConfig: A version of the gym_hil MujocoGymEnv that can extract its configuration from a well-formed mujoco scene.xml file.GenericRobotEnv, a configurable robot-control base environment around a MuJoCo XML model, with reusable robot methods (apply_action,get_robot_state,reset_robot,render,get_gripper_pose).GenericTaskEnv, a task-oriented layer on top ofGenericRobotEnvthat adds Panda-pick-style task behavior (task reset, environment state observation, reward, success/termination).
Features
- Auto-detects joints, actuators, end-effector site, cameras and (optionally) a
homekeyframe from a MuJoCo XML file. - Two control modes:
osc(end-effector operational-space control) andjoint(direct actuator control). - Separation of concerns: robot-control APIs in
GenericRobotEnv, task APIs inGenericTaskEnv. - Optional image observations from model cameras.
- Returns structured observations compatible with Gymnasium
spaces.Dict.
Installation
This project depends on MuJoCo and Gymnasium. Install prerequisites in your Python environment (example using pip):
pip install generic_robot_env
Note: The repository includes typed stubs under typings/ for local development and the project expects a working MuJoCo installation accessible to the mujoco Python package.
Usage examples
- Simple loop: Create a configuration from a scene XML and run a quick random-action loop. mujoco_menagerie is a good repository of scenes.
from pathlib import Path
import numpy as np
from generic_robot_env.generic_robot_env import RobotConfig, GenericTaskEnv
xml = Path("mujoco_menagerie/aloha/scene.xml") # point to a model in the repo
config = RobotConfig.from_xml(xml, robot_name="aloha")
env = GenericTaskEnv(config, control_mode="osc", image_obs=False)
obs, _ = env.reset()
for _ in range(200):
action = env.action_space.sample()
obs, reward, terminated, truncated, info = env.step(action)
if terminated:
break
env.close()
- Image observations: Enable
image_obs=Trueto receive pixel arrays underobs['pixels']keyed by camera name (when cameras exist in the MJCF).
config = RobotConfig.from_xml(Path("mujoco_menagerie/aloha/aloha.xml"), robot_name="aloha")
env = GenericTaskEnv(config, control_mode="osc", image_obs=True)
obs, _ = env.reset()
# obs['pixels'] -> dict(camera_name -> HxWx3 uint8 array)
Notes:
- If the MuJoCo model contains a keyframe named
home, the environment will try to use that as the default joint pose. - If cameras are present and
image_obs=True, pixel observations are returned underobs['pixels']keyed by camera name.
Files
src/generic_robot_env/generic_robot_env.py— main environment implementation (this module).
See src/generic_robot_env/generic_robot_env.py for the full implementation.
Observation and action spaces
GenericRobotEnv observations are returned as a Gymnasium spaces.Dict with primary keys under agent_pos:
joint_pos: Joint positions for the detected robot joints (array)joint_vel: Joint velocities (array)tcp_pose: End-effector pose as [x, y, z, qx, qy, qz, qw]tcp_vel: End-effector linear and angular velocity (6D)gripper_pose(optional): Single-value gripper state when a gripper actuator is detected
When image_obs=True, pixels is included and contains a spaces.Dict of camera-name -> RGB image arrays.
GenericTaskEnv uses Panda-pick-style observations:
- State mode:
{"agent_pos": <vector>, "environment_state": <object position>} - Image mode:
{"pixels": <camera dict>, "agent_pos": <vector>}
Action spaces depend on control_mode:
osc: Continuous Box controlling end-effector delta in position (x,y,z) and rotation (rx,ry,rz). If a gripper is available, an extra dimension for gripper command is appended.joint: Continuous Box mapped directly to actuator control values. When a gripper actuator exists, it is appended to the action vector.
Implementation notes
- The environment auto-resolves joint and actuator ids using the MuJoCo model and maps qpos/qvel indices for direct data access.
- For OSC control, a simple opspace solver (from
gym_hil.controllers.opspace) is used each simulation substep to compute actuator torques that track a desired end-effector target. - Gripper mapping tries to respect actuator control ranges defined in the model (
actuator_ctrlrange) when present.
Running tests
Run the test suite with pytest from the repository root:
pytest tests
Local presubmit hooks
Install local git hooks so linting/formatting runs before commit and tests run before push:
uv run pre-commit install --hook-type pre-commit --hook-type pre-push
Run hooks manually (optional):
uv run pre-commit run --all-files
uv run pre-commit run --hook-stage pre-push
-
Faster experiments: Many models include camera/site names that the environment will auto-detect (end-effector sites, cameras, and optional
homekeyframes). If your chosen model provides ahomekeyframe the environment will attempt to use it as the default reset pose. -
Example with a bundled task: Some pre-made gym-style wrappers (for example in
gym_hil) subclass the same base utilities; you can switch betweenGenericRobotEnvand those wrappers by pointing both at the same XML and configuration.
Tips and troubleshooting
- Missing end-effector/site detection: If the end-effector isn't found automatically, open the XML and add a site with a common name like
ee,end_effector,tcporattachment_siteso auto-detection can find it. - Gripper mapping: If the model exposes a gripper actuator with a control range, the environment will append a gripper command dimension to the action space and will respect
actuator_ctrlrangewhen possible.
Contributing
Contributions, bug reports and improvements are welcome. When adding new robots or tasks, prefer adding descriptive camera and site names in the MJCF so the auto-detection heuristics can find the end-effector and camera frames.
License
This project inherits the license of the repository. Ensure you follow the licensing terms of MuJoCo and any third-party dependencies.
Metadata
Release files for generic-robot-env 0.0.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| generic_robot_env-0.0.3.tar.gz | 243.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| generic_robot_env-0.0.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 254.7 kB
Release files / generic_robot_env-0.0.3.tar.gz
| Download URL | generic_robot_env-0.0.3.tar.gz |
|---|---|
| Size | 243.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b0b7ff0d9d8127b1d0231c3ac39dc36df3f4130c20816602da5aadce5bfa4574
|
|
BLAKE2b-256 checksum How to use checksums |
98b3618f9c43d429b75265428ece1cc6ce1b13b9d07594c7dffbb6b1e1cfbb28
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Feb 20, 2026.
Transparency logRelease files / generic_robot_env-0.0.3-py3-none-any.whl
| Download URL | generic_robot_env-0.0.3-py3-none-any.whl |
|---|---|
| Size | 11.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
566d67764c38116a7ab3ceb4e3aacab8c8bcb6c9014546967212ca35308a01d2
|
|
BLAKE2b-256 checksum How to use checksums |
686f934220bfd5ee79b5d1d78dcc22e295f6de35e7a40e856b4b5c54e0072b36
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Feb 20, 2026.
Transparency log