Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

UniEnv Genesis Lab

This repository contains the implementation of the adaptor that connects the Genesis simulation engine to the UniEnv's node system interface. It is designed as a full simulation framework in the spirit of mjlab and IsaacLab, bringing the same modular, composable scene-building philosophy to Genesis.

Node System

mjlab (MuJoCo's Python interface) and IsaacLab (NVIDIA's GPU-accelerated RL framework for Omniverse) both share a common idea: a simulation environment should be assembled from independent, reusable building blocks — robots, sensors, scene elements — each responsible for its own lifecycle. genesis_adaptor mirrors this philosophy for the Genesis engine, providing:

  • A node-based scene description system that lets you compose robots, sensors, and scene geometry declaratively.
  • A priority-ordered lifecycle that guarantees correct initialisation order without manual dependency management.
  • Pluggable controllers that decouple the physics entity from the control law, just as IsaacLab separates actuator models from robot assets.
  • Transparent batching so that the same node code runs identically on a single environment or thousands of parallelised GPU environments.

Lifecycle Phases & Priorities

Each lifecycle phase is executed by sorting all registered nodes by their declared priority for that phase and calling them in descending order. A higher priority number runs first.

Phase Purpose
reload Destroy the old scene; add geometry / entities to the new one.
after_reload Scene is compiled. Initialise controllers, cache entity handles.
reset Move entities back to their starting poses; clear queued actions.
after_reset Populate the first observation cache after reset.
pre_environment_step Apply the pending action to the physics engine.
post_environment_step Read back state and refresh the observation cache.

Typical priority assignments:

Priority Range Node Catgories
[80, 100) static scene geometry (planes, tables)
[50, 80) robots and articulated entities
(-20, 0] controllers and sensors that depend on entities
$\mathbb{Z}$ Task control logic can declare any priority to ensure it runs after all the necessary state has been updated by the controllers and sensors.

This means a floor plane is always added to the scene before a robot, and a camera that is attached to a robot link is always attached after the robot entity exists.

Composing a Scene

world  = GenesisWorld()
plane  = PlaneBuilder(world, name="floor")
table  = TableBuilder(world, name="table", pos=(0, 0, 0.6))
franka = FrankaFR3WithHand(world, name="franka", pos=(-0.7, 0, 0.6))
camera = CameraSensorNode(world, name="camera", ...)

env = WorldEnv(world, [plane, table, franka, camera])
context, obs, info = env.reset(seed=0, reload=True)
# obs = {
#   "franka": {"joint_position": ..., "eef_position": ..., ...},
#   "camera": {"rgb": ..., "depth": ...},
# }
# Each space describes its data, e.g.
# env.observation_space["camera"]["rgb"].metadata["layout"] == "HWC"

WorldEnv calls each node's lifecycle methods in the correct priority order automatically. You do not manage dependencies by hand.

Space Metadata

Every observation and action space the nodes declare carries unienv space metadata describing what the data means, so wrappers, storages and dataset exporters can find e.g. the camera images without knowing the node:

from unienv_interface.space.space_utils.metadata_utils import find_spaces_by_metadata

env.observation_space["camera"]["rgb"].metadata
# {"kind": "image", "format": "rgb", "layout": "HWC", "source": "camera"}
env.observation_space["franka"]["arm"]["joint_position"].metadata["units"]
# ["rad", "rad", ...]   one entry per DOF, "m" for prismatic joints
find_spaces_by_metadata(franka.action_space, control="gripper")
# [(("gripper",), BoxSpace(...))]
  • Cameras: rgb (image, rgb / HWC), depth (metres, HW), seg (segmentation, with the scene's segmentation level), normal, position (world pointcloud), intrinsics_cv / extrinsics_cv / local_extrinsics_cv (OpenCV camera_cv frame). source is the camera node's name.
  • Joint readings and targets: per-DOF units (rad / rad/s / N*m for revolute DOFs, m / m/s / N for prismatic ones) and names from the entity's joints; root and end-effector poses state their frame (world, or base with a configured base_frame) and rotation="quat_wxyz".
  • Actions: control / mode (joint_position, joint_velocity, eef_pose with the rotation of its rotation_representation, gripper for a mimic gripper with open_value / closed_value).
  • Tasks: kind="task" goals and targets in the world frame.

Controller configs are checked as well: a keyword argument that no controller uses raises an UnknownControllerOptionWarning (see EntityController.extra_attributes for the extra attributes a controller config may carry).

Articulated Rooms

Rooms furnished with fixed articulated furniture (RoboCasa kitchen cabinets, drawers and appliances; ReplicaCAD fridges, cupboards and doors; ArtVIP USD appliances; MolmoSpaces Ai2-THOR furniture; Lightwheel SimReady assets; NVIDIA SimReady Warehouse rigid props) are built by RoomBuilder (baked layouts or procedural sampling), and a single named joint of one furniture instance can be driven by OpenArticulatedJointTask — dense fraction-tracking reward, per-env goals, masked resets:

room = RoomBuilder(world, name="room", layout_yaml="robocasa_kitchen/open_kitchen")
task = OpenArticulatedJointTask(
    world, room, furniture_key="cabinet_hinge", joint_name="rightdoorhinge",
    grasp_link_name="cabinet_hinge_right_door_handle",
)
env = WorldEnv(world, [room, franka, task])

Procedural rooms sample from a catalog-backed furniture pool, e.g. make_artvip_pool(tags="kitchen", n=6) for the ArtVIP USD appliances, make_molmospaces_pool(tags="kitchen", n=6) for the MolmoSpaces THOR furniture, make_lightwheel_pool(tags="kitchen", n=6) for the Lightwheel SimReady assets or make_simready_warehouse_pool(tags="prop", n=8) for the Warehouse rigid props (see docs/articulated_rooms.md).

See docs/articulated_rooms.md for the API, the packaged assets (RoboCasa CC BY 4.0; ArtVIP is Apache-2.0 per its card with no committed LICENSE file — caveat there; ReplicaCAD and Lightwheel are CC BY-NC 4.0 — non-commercial, see the license caveats there; MolmoSpaces is CC BY 4.0 with attribution; the SimReady Warehouse card tags CC BY 4.0 but the archive commits no LICENSE file — caveat there) and how to regenerate them, plus the runnable examples/room_open_drawer_fr3.py.


Installation

Install from PyPI:

pip install unienv_genesis

Or install the adaptor locally from source:

git clone https://github.com/UniEnvOrg/genesis_adaptor/
cd genesis_adaptor
pip install -e .

Metadata

Release files for unienv-genesis 0.0.2a2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for unienv-genesis 0.0.2a2
File Size Uploaded
unienv_genesis-0.0.2a2.tar.gz 579.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for unienv-genesis 0.0.2a2
File Interpreter ABI Platform
unienv_genesis-0.0.2a2-py3-none-any.whl Python 3 none any Details

Total release size: 990.3 kB

Release files / unienv_genesis-0.0.2a2.tar.gz

Download URL unienv_genesis-0.0.2a2.tar.gz
Size 579.6 kB
Tags Source
SHA-256 checksum
How to use checksums
7c854f7cb2cde96cad7836ac279f292e6875663588616aafbf205497634f8715
BLAKE2b-256 checksum
How to use checksums
3151d7c8b9bb18976b1263ac134cc01fe6d9c294c03cefcd983febb87ff856f4
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 Oct 17, 2026.

Transparency log

Release files / unienv_genesis-0.0.2a2-py3-none-any.whl

Download URL unienv_genesis-0.0.2a2-py3-none-any.whl
Size 410.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
65dad4969167979343f5a0d8432d8a58bdf08a5249f767247dce28fbee9f05de
BLAKE2b-256 checksum
How to use checksums
1aba7c649ec24516710ca5c425562004305ab041c2e9ecc1390d13e3146b7a46
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 Oct 17, 2026.

Transparency log
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page