unisim.backend.genesis.backend

Host-compatibility implementation of the independent genesis backend.

The adapter serves the SimBackend NumPy contract on top of Genesis 1.3.3, following the measured mappings of scripts/tools/genesis_feasibility/ REPORT.md (#1372): link-addressed root state (never entity-level getters, REPORT §5.5), control_dofs_position inside an adapter-owned nsteps loop honoring set_pre_step_control (§5.4), host caches refreshed once per step/reset barrier (§5.9), MJCF-named sensor equivalents from link state plus one IMUSensor per accelerometer site with clean (noise-free) data (§3.4/§5.3), genesis-native recoded geom contact masks that must not be compared against MuJoCo tables (§5.10), and a DR capability set restricted to the per-env round-trip-measured items (§3.5 [8] / §5.7).

Classes

GenesisBackend

Independent Genesis backend exposed through the host NumPy profile.

class unisim.backend.genesis.backend.GenesisBackend[source]

Bases: SimBackend

Independent Genesis backend exposed through the host NumPy profile.

Construction performs dependency loading, the MJCF cold-path scan, the process-wide gs.init (once), and scene/entity/sensor creation; materialize() builds the batched solver state and binds all runtime caches. Terrain, geom-name contracts, and site Jacobians fail closed. Native interactive/offscreen rendering attaches lazily post-build (see the play contract section). Call close() to end the process-wide Genesis session; re-initialization afterwards fails closed by design.

Parameters:
__init__(scene, num_envs, sim_dt, *, base_name=None, push_body_name=None, device_id=None, integrator=None, constraint_solver=None, friction_cone=None, solver_iterations=None, **unexpected_kwargs)[source]
Parameters:
materialize()[source]

Build the batched scene, cross-check the import, and bind caches.

Idempotent, and called lazily by the first state access: env constructors that validate state shapes before the explicit lifecycle point (ManagerBasedRlEnv builds its EntityScene before calling materialize(), #1382) work like they do on the MuJoCo backend — the same pattern as the isaacgym backend’s lazy materialize. A closed backend cannot be materialized again.

Return type:

None

property num_envs: int

Number of vectorized environments.

property model: Any

Return the backend-owned Genesis rigid entity.

property num_actuators: int

Number of actuators.

property num_dof_vel: int

Number of joint velocity DoFs, excluding the floating base.

get_actuator_ctrl_range()[source]

MJCF ctrlrange metadata; Genesis does not enforce it in-engine.

Return type:

ndarray

get_actuator_names()[source]

Return actuator names in control-vector order on the cold path.

Return type:

tuple[str, ...]

get_actuator_joint_names()[source]

Return each actuator’s target single-DoF joint in control-vector order.

Backends must fail closed when an actuator does not target exactly one hinge/slide joint. Manager action terms use this cold-path metadata to map community joint selectors onto the backend control vector without inspecting backend-private model objects.

Return type:

tuple[str, ...]

get_actuator_gains()[source]

Return per-joint (kp, kd) arrays from the backend model.

Return type:

tuple[ndarray, ndarray]

get_scene_model_file()[source]

Return the materialized scene path for diagnostics, when available.

Return type:

str | None

get_keyframe_qpos(name)[source]

Return the full qpos for a named keyframe, including the floating base.

Parameters:

name (str) – Keyframe name such as "stand" or "home".

Return type:

ndarray

Returns:

Array with shape (nq,).

get_default_qpos()[source]

Return the backend/model default qpos through a stable contract.

Return type:

ndarray

get_default_dof_pos()[source]

Return default joint positions in the same column order as get_dof_pos.

The returned array is detached, one-dimensional, and excludes floating root coordinates. Backends whose DoF view is actuator-indexed must use that same actuator-target order here.

Return type:

ndarray

get_init_qvel()[source]

Return a zero-initialized qvel vector compatible with set_state.

Return type:

ndarray

Returns:

Zero-filled qvel array.

get_root_state_layout(root_body_name)[source]

Resolve one body’s floating-root columns on the cold path.

Backends must verify that root_body_name owns a free/floating joint; fixed bodies and runtimes without body-to-root metadata fail closed. Name/model lookup is forbidden on reset and step hot paths, so callers cache either the returned layout or the unsupported result during scene materialization.

Parameters:

root_body_name (str)

Return type:

BackendRootStateLayout

get_body_ids(names)[source]

Resolve body/link names to backend integer IDs.

Parameters:

names (Sequence[str]) – Body/link names.

Return type:

ndarray

Returns:

int32 array with shape (len(names),).

Raises:

ValueError – If any name is not found.

get_geom_contact_masks()[source]

Genesis-native recoded contype/conaffinity of collision geoms.

Genesis re-synthesizes contype/conaffinity at import: the collision matrix semantics are preserved, but the integer values must NOT be compared against MuJoCo tables (REPORT #1372 §5.10).

Return type:

tuple[ndarray, ndarray]

get_gravity()[source]

Return the backend gravity vector.

Return type:

ndarray

get_body_mass()[source]

Return the backend body-mass table.

Return type:

ndarray

get_body_ipos()[source]

Return the backend body inertial-position table.

Return type:

ndarray

get_dof_armature()[source]

Return the backend dof-armature table.

Return type:

ndarray

get_joint_range()[source]

Return joint position limits, excluding the floating base.

Return type:

ndarray | None

Returns:

Array with shape (num_dof, 2) and columns [low, high], or None when the backend does not expose limits.

get_joint_dof_indices(names)[source]

Resolve joint names to DoF indices in velocity space (qvel).

Parameters:

names (Sequence[str]) – Joint names.

Return type:

ndarray

Returns:

int32 index array with shape (len(names),) relative to the qvel start.

get_joint_dof_pos_indices(names)[source]

Resolve joint names to DoF indices in position space (qpos).

Only single-DoF joints are supported; free joints are excluded.

Parameters:

names (Sequence[str]) – Joint names.

Return type:

ndarray

Returns:

int32 index array with shape (len(names),) relative to the joint section of qpos.

get_joint_dof_vel_indices(names)[source]

Resolve joint names to DoF indices in velocity space (qvel).

Parameters:

names (Sequence[str]) – Joint names.

Return type:

ndarray

Returns:

int32 index array with shape (len(names),) relative to the joint section start.

get_joint_state_qpos_indices(names)[source]

Resolve single-DoF joints to full set_state qpos columns.

Unlike get_joint_dof_pos_indices(), these indices address the complete qpos vector accepted by set_state(), including any root coordinates. Manager reset transactions resolve them on the cold path.

Parameters:

names (Sequence[str])

Return type:

ndarray

get_joint_state_qvel_indices(names)[source]

Resolve single-DoF joints to full set_state qvel columns.

Parameters:

names (Sequence[str])

Return type:

ndarray

step(ctrl, nsteps=1)[source]

Advance physics.

Parameters:
  • ctrl (ndarray) – Control input with shape (num_envs, nu).

  • nsteps (int) – Number of physics substeps.

Return type:

dict[str, dict[str, float]]

Returns:

Optional dictionary. Backends may include a "timing" key with per-phase timings in milliseconds.

set_state(env_indices, qpos, qvel, randomization=None)[source]

Set physics state for selected environments.

Parameters:
Return type:

dict[str, dict[str, float]]

Returns:

Optional dictionary. Backends MAY include a "timing" key with per-substep timings in milliseconds (e.g. set_state_mask_ms, set_state_data_slice_ms, …). Callers MUST treat None or missing keys as “not reported” — the outer wall-clock measurement in DomainRandomizationManager.reset (dr_reset_set_state_ms) remains authoritative for total set_state time.

get_dr_capabilities()[source]

Declare only the per-env round-trip-measured DR items (REPORT §5.7).

Measured: link inertial mass and dof kp/kv (require the materialize- time batch build flags), plus the solver-level external force API (call-verified; physical effect is a REPORT §8 follow-up). Measured- but-unmappable items stay undeclared: frictionloss/damping/armature have no SimBackend reset term, and geom friction only has a per-env ratio API, so absolute geom_friction randomization is unsupported.

Return type:

DomainRandomizationCapabilities

apply_interval_randomization(plan)[source]

Apply a scheduled interval randomization plan.

Generic dispatch: each op yielded by plan.iter_ops() is validated against the builtin term specs (custom terms pass through) and routed to the backend-owned handler table returned by _interval_term_handlers(). A term without a handler fails closed with NotImplementedError naming the backend class and the term. Backends that need per-plan prologue/epilogue semantics (for example clearing staged external forces before the ops accumulate) keep a thin override that calls this base implementation.

Parameters:

plan (IntervalRandomizationPlan)

Return type:

None

apply_body_force(body_ids, force, torque=None)[source]

Apply a world-frame force per body through the solver-level API.

Parameters:
Return type:

None

get_play_capabilities()[source]

Return backend-native play/render capabilities.

Return type:

BackendPlayCapabilities

resolve_play_render_plan(*, play_render_mode, play_steps, output_video)[source]

Resolve high-level playback mode into backend-owned render parameters.

Parameters:
Return type:

BackendPlayRenderPlan

init_renderer(spacing=1.0, *, offset_mode='grid', headless=False, capture=False, width=1280, height=720, camera_kwargs=None)[source]

Lazily attach the Genesis viewer and/or an offscreen camera.

Both are post-build attachments (verified on 1.3.3): the interactive viewer is a genesis.vis.viewer.Viewer built on the visualizer’s shared context; capture uses a visualizer camera built on demand. spacing/offset_mode are accepted for contract parity and ignored: envs are laid out on the Genesis scene’s own grid. The first (headless, capture) pair is pinned, like the isaacgym backend.

Parameters:
Return type:

None

render()[source]

Draw one interactive viewer frame (self-initializes interactive).

Return type:

None

capture_video_frame()[source]

Capture one offscreen RGB frame (self-initializes headless+capture).

Return type:

ndarray

run_playback(*, env, initialize, step, num_steps, output_video=None, render_spacing=None, render_offset_mode=None, headless=None, record_video=None, frame_state_getter=None, camera_kwargs=None, debug_overlay_getter=None, on_frame=None)[source]

Execute backend-owned playback for an env wrapper.

camera_kwargs is normalized into CameraCfg at this boundary; unknown mapping keys fail closed with an error naming them.

debug_overlay_getter is an optional per-frame callback returning a sequence with one entry per environment (len == num_envs); each entry is that env’s sequence of DebugPrimitive (None or empty marks an env without overlay) and returning None disables overlays for the frame. Primitive poses are env-local; the renderer applies grid offsets when composing multiple envs. Backends whose get_play_capabilities().supports_debug_overlay is False fail closed with NotImplementedError when this is not None. On the interactive rendering path only backends whose supports_interactive_debug_overlay is True consume it; the others fail closed with NotImplementedError.

on_frame is an optional per-frame video hook called by offline render pipelines before encoding: it receives (frame_index, frame) with the frame an (H, W, 3) uint8 array, and returns a replacement frame of the same shape/dtype or None to keep the original. Backends rendering through a native (non-offline) renderer fail closed with NotImplementedError when this is not None.

Known boundary: env is the owning env wrapper, not a physics-layer concept. Current playback implementations read env-level configuration (e.g. cfg.scene, cfg.ctrl_dt, cfg.render_spacing) and env-owned playback helpers (get_playback_model, get_physics_state_snapshot) that have no backend-native equivalent yet. The parameter stays on this contract until playback asset/config resolution moves onto backend-owned metadata; backends must only use it on the cold playback path.

Parameters:
Return type:

str | None

get_base_pos()[source]

Return base position in the world frame.

Return type:

ndarray

Returns:

(num_envs, 3)

get_base_quat()[source]

Return base quaternion in the world frame as wxyz.

Return type:

ndarray

Returns:

(num_envs, 4)

get_base_lin_vel()[source]

Return base linear velocity in the world frame.

This is the first three dimensions of generalized velocity qvel, expressed in world coordinates.

Return type:

ndarray

Returns:

(num_envs, 3)

get_base_ang_vel()[source]

Return base angular velocity in the world frame.

This is dimensions 3-5 of generalized velocity qvel, expressed in world coordinates. It differs from gyro readings: gyro sensors report angular velocity components in the body/sensor local frame, while this contract returns world-frame values. Use the matching sensor contract when body-frame angular velocity is required.

Return type:

ndarray

Returns:

(num_envs, 3)

get_dof_pos()[source]

Return joint positions, excluding the base.

Return type:

ndarray

Returns:

(num_envs, num_dof)

get_dof_vel()[source]

Return joint velocities, excluding the base.

Return type:

ndarray

Returns:

(num_envs, num_dof)

get_body_pos_w(body_ids)[source]

Return selected body positions in the world frame.

Parameters:

body_ids (ndarray) – Body ID array.

Return type:

ndarray

Returns:

(num_envs, len(body_ids), 3)

get_body_quat_w(body_ids)[source]

Return selected body quaternions in the world frame as wxyz.

Parameters:

body_ids (ndarray) – Body ID array.

Return type:

ndarray

Returns:

(num_envs, len(body_ids), 4)

get_body_lin_vel_w(body_ids)[source]

Return selected body linear velocities in the world frame.

Parameters:

body_ids (ndarray) – Body ID array.

Return type:

ndarray

Returns:

(num_envs, len(body_ids), 3)

get_body_ang_vel_w(body_ids)[source]

Return selected body angular velocities in the world frame.

Parameters:

body_ids (ndarray) – Body ID array.

Return type:

ndarray

Returns:

(num_envs, len(body_ids), 3)

get_body_pos_b(body_ids)[source]

Return selected body positions in the baselink frame.

Parameters:

body_ids (ndarray) – Body ID array.

Return type:

ndarray

Returns:

(num_envs, len(body_ids), 3)

get_body_quat_b(body_ids)[source]

Return selected body quaternions in the baselink frame as wxyz.

Parameters:

body_ids (ndarray) – Body ID array.

Return type:

ndarray

Returns:

(num_envs, len(body_ids), 4)

get_body_lin_vel_b(body_ids)[source]

Return selected body linear velocities expressed in each body’s own frame.

The value is the body’s world-frame velocity rotated by the inverse of the body’s world-frame orientation, i.e. quat_apply_inverse(quat_w, lin_vel_w) (mjlab/Isaac-style analytical definition). It is well-defined for every body — including the root body — and must NOT be implemented as the motion relative to the baselink frame (which degenerates to zero for the root body).

Parameters:

body_ids (ndarray) – Body ID array.

Return type:

ndarray

Returns:

(num_envs, len(body_ids), 3)

get_body_ang_vel_b(body_ids)[source]

Return selected body angular velocities expressed in each body’s own frame.

The value is the body’s world-frame angular velocity rotated by the inverse of the body’s world-frame orientation, i.e. quat_apply_inverse(quat_w, ang_vel_w) (mjlab/Isaac-style analytical definition). It is well-defined for every body — including the root body — and must NOT be implemented as the motion relative to the baselink frame (which degenerates to zero for the root body).

Parameters:

body_ids (ndarray) – Body ID array.

Return type:

ndarray

Returns:

(num_envs, len(body_ids), 3)

get_sensor_data(name)[source]

Return sensor data.

Parameters:

name (str) – Sensor name.

Return type:

ndarray

Returns:

Sensor data array.

close()[source]

End the process-wide Genesis session; re-init afterwards fails closed.

Return type:

None