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
Independent Genesis backend exposed through the host NumPy profile. |
- class unisim.backend.genesis.backend.GenesisBackend[source]¶
Bases:
SimBackendIndependent 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). Callclose()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]¶
- 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:
- get_actuator_ctrl_range()[source]¶
MJCF
ctrlrangemetadata; Genesis does not enforce it in-engine.- Return type:
- 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.
- get_keyframe_qpos(name)[source]¶
Return the full qpos for a named keyframe, including the floating base.
- get_default_qpos()[source]¶
Return the backend/model default qpos through a stable contract.
- Return type:
- 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:
- get_init_qvel()[source]¶
Return a zero-initialized qvel vector compatible with
set_state.- Return type:
- 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_nameowns 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:
- Return type:
- Returns:
int32array 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).
- 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.
- get_joint_dof_vel_indices(names)[source]¶
Resolve joint names to DoF indices in velocity space (qvel).
- get_joint_state_qpos_indices(names)[source]¶
Resolve single-DoF joints to full
set_stateqpos columns.Unlike
get_joint_dof_pos_indices(), these indices address the complete qpos vector accepted byset_state(), including any root coordinates. Manager reset transactions resolve them on the cold path.
- get_joint_state_qvel_indices(names)[source]¶
Resolve single-DoF joints to full
set_stateqvel columns.
- set_state(env_indices, qpos, qvel, randomization=None)[source]¶
Set physics state for selected environments.
- Parameters:
env_indices (
ndarray) – Environment indices.qpos (
ndarray) – Position state. Free-root columns exposed byget_root_state_layout()use world xyz and wxyz quaternion.qvel (
ndarray) – Velocity state. Free-root columns exposed byget_root_state_layout()use world linear velocity and body-frame angular velocity.randomization (
ResetRandomizationPayload|None) – Optional backend randomization payload.
- Return type:
- 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 treatNoneor missing keys as “not reported” — the outer wall-clock measurement inDomainRandomizationManager.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:
- 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 withNotImplementedErrornaming 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:
- apply_body_force(body_ids, force, torque=None)[source]¶
Apply a world-frame force per body through the solver-level API.
- 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.
- 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.Viewerbuilt on the visualizer’s shared context; capture uses a visualizer camera built on demand.spacing/offset_modeare 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.
- capture_video_frame()[source]¶
Capture one offscreen RGB frame (self-initializes headless+capture).
- Return type:
- 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_kwargsis normalized intoCameraCfgat this boundary; unknown mapping keys fail closed with an error naming them.debug_overlay_getteris an optional per-frame callback returning a sequence with one entry per environment (len == num_envs); each entry is that env’s sequence ofDebugPrimitive(Noneor empty marks an env without overlay) and returningNonedisables overlays for the frame. Primitive poses are env-local; the renderer applies grid offsets when composing multiple envs. Backends whoseget_play_capabilities().supports_debug_overlayis False fail closed withNotImplementedErrorwhen this is notNone. On the interactive rendering path only backends whosesupports_interactive_debug_overlayis True consume it; the others fail closed withNotImplementedError.on_frameis 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 orNoneto keep the original. Backends rendering through a native (non-offline) renderer fail closed withNotImplementedErrorwhen this is notNone.Known boundary:
envis 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.
- get_base_pos()[source]¶
Return base position in the world frame.
- Return type:
- Returns:
(num_envs, 3)
- get_base_quat()[source]¶
Return base quaternion in the world frame as
wxyz.- Return type:
- 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:
- 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:
- Returns:
(num_envs, 3)
- get_dof_pos()[source]¶
Return joint positions, excluding the base.
- Return type:
- Returns:
(num_envs, num_dof)
- get_dof_vel()[source]¶
Return joint velocities, excluding the base.
- Return type:
- Returns:
(num_envs, num_dof)
- 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).
- 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).