rlmesh.adapters
Generalized env-to-model adapters.
import rlmesh.adaptersThe guided tour is Adapters; the full role registry, every leaf option, and the conversion policy are in the Adapter Reference.
rlmesh.adapters derives the preprocessing and postprocessing between an environment and a model from declarative descriptions, instead of a hand-written adapter per pair.
The split is asymmetric. An environment tags its observation and action spaces: it names the semantic role of each entry plus the few facts the spaces cannot carry (image layout, rotation encoding, an explicit value range). A model fully specifies the payload it ingests and the action it emits. resolve() matches the two by role and produces an Adapter; widths, dtypes, and keys come from the gymnasium spaces.
Install the NumPy backend for direct adapter calls and the examples below:
pip install "rlmesh[numpy]"
Environment Tags
An environment publishes EnvTags in its contract metadata (via tag() or EnvServer(env, tags=...)), so a client can resolve an adapter from the handshake alone.
EnvTags.observation_roles (and Session.observation_roles on a live session) groups the declared roles by kind.
Action Layout
The action layout is a shared vocabulary. An environment tags the action vector its step accepts; a model declares the action vector it emits. The resolver converts between them per actuator.
Escape Hatches
When a pairing needs logic a declarative spec cannot express, three mechanisms compose, most local first. A custom input computes one payload slot from the raw observation while the rest stays spec-driven. A custom encoding handles a rotation convention the native crate does not ship. A custom adapter subclasses AdapterBase to add stateful behavior, typically by wrapping a resolved adapter and overriding only the stateful part.
Custom inputs
A Custom input runs host-language code that maps the raw observation to one payload slot. Custom(transform=fn) runs an in-process callable and is local only; Custom(entrypoint="module:callable") names a string that is imported only when you pass resolve(..., trust_entrypoints=True), so it can travel in a contract. A custom input receives the environment’s own keys, not roles, and returns the entire payload slot, so it does no role-matching, dim/index, or range-mapping, and is observation-side only.
Custom encodings
Rotation encodings are a closed vocabulary (the RotationEncoding set listed under Vocabulary). You cannot register one from Python, because a spec is data that travels in a contract and resolves on a remote client with no code. For a convention that is general and stable, like a published model’s rot6d_rowmajor, add it first-party: a few lines on the native RotationEncoding enum plus the Python Literal. It then works on both the observation and action sides, serializes into the contract, and is conformance-tested once.
For a bespoke or proprietary convention, declare a CustomEncoding on the nearest native base encoding (rot6d or a quaternion) and supply the host-side repacking. resolve lowers the field to its base for the native core, so role-matching, range-mapping, and the env-to-base conversion are unchanged; the adapter applies your transforms at the boundary: from_base after the native conversion on the observation side, to_base before it on the action side. Define the encoding once and reference it from both arms:
ROT6D_MINE = adapt.CustomEncoding(
base="rot6d", from_base=rot6d_to_mine, to_base=mine_to_rot6d, name="rot6d_mine"
)
The packing must preserve the base width, so the part it tags keeps it: a dim restates that width or is omitted, and the part may sit at any offset of a multi-part Concat (the repack reads and writes exactly its own slice, whose offset the resolved plan reports). At resolve time the two arms are round-tripped on a probe to catch a mispaired encode/decode; pass resolve(..., check_inverse=False) to skip. The transforms are in-process callables, so the spec is local; a serializable module:callable form is planned.
When the constraints do not fit (a width-changing repack, or non-rotation feature engineering), drop to a custom AdapterBase or replace a whole payload slot with a Custom input. None of these attach a custom encoding to a role in the spec itself: the vocabulary stays closed so specs remain pure data that resolve on a remote client with no code. Reach for the boundary wrapper for a one-off; upstream the encoding once you want it attached to a role and reused.
Custom adapters
Subclass AdapterBase for stateful behavior a spec cannot describe (for example temporal ensembling across action chunks, or a width-changing rotation repack interior to a multi-field state). The usual shape wraps a resolved adapter and overrides only the stateful part. Override reset() to clear episode state and wire it to the model’s on_episode_end.
A pair override replaces the adapter for one specific (model, environment) pairing entirely, for cases like control-space conversion against a robot’s kinematic model. There is no special machinery: keep a registry keyed by the pair and consult it before resolving.
Vocabulary
Semantic roles are an open vocabulary of wire strings matched verbatim between independently authored tags and specs. The well-known conventions that ship with RLMesh are re-exported from the package (single-sourced from the native crate): the core roles IMAGE_PRIMARY, IMAGE_SECONDARY, IMAGE_WRIST, INSTRUCTION, JOINT_POS, JOINT_VEL, ACTION_JOINT_POS, ACTION_JOINT_VEL; the manipulation roles EEF_POS, EEF_ROT, GRIPPER_POS, EEF_WRENCH, ACTION_DELTA_POS, ACTION_DELTA_ROT, ACTION_GRIPPER, ACTION_EEF_POS, ACTION_EEF_ROT; and the body roles BASE_ANG_VEL, BASE_ROT, COMMAND_BASE_VEL. A role that repeats on a body (a second arm, a second wrist camera) is the same role under a part=: any identifier both sides agree on, with LEFT_ARM, RIGHT_ARM, HEAD, TORSO, BASE, LEFT_LEG, and RIGHT_LEG (PARTS) as the suggested spellings. The full registry, with wire strings and widths, is in Adapter Reference.
Rotation widths follow the declared encoding. rlmesh.adapters.ROTATION_DIMS maps each encoding to its dimension count:
| Encoding | Dims | Convention |
|---|---|---|
quat_xyzw |
4 | quaternion, scalar-last |
quat_wxyz |
4 | quaternion, scalar-first |
axis_angle |
3 | rotation vector |
rot6d |
6 | first two columns of the rotation matrix, concatenated |
rot6d_rowmajor |
6 | same two columns flattened row-major |
euler_xyz |
3 | roll-pitch-yaw, extrinsic XYZ |
gravity_xyz |
3 | projected gravity, an observation-side sink for BASE_ROT |
rot6d is the standard 6D rotation; rot6d_rowmajor exists for checkpoints trained on the row-major interleaving. See Adapters for when to add an encoding versus reach for a custom encoding.
Classes
- ActionOrdered action actuators plus optional clipping bounds.
- ActuatorOne contiguous slice of an action vector.
- AdapterA resolved env-to-model adapter; build instances with
resolve(). - AdapterBaseBase class for env-to-model adapters.
- AdvisoryOne non-fatal adapter advisory: a message plus a severity tier.
- ConcatA multi-part numeric state input: several roles packed into one tensor.
- ConstantA constant part of a
Concat:dimcopies offill. - CustomA custom input computed by host-language code.
- CustomEncodingA rotation packing layered on a known native
baseencoding. - EnvTagsDeclarative tags of an environment's observation and action.
- FieldOne contiguous field of a flat numeric observation leaf.
- ImageAn image input expected by a model.
- ImageTagA camera image entry in an environment observation.
- ModelSpecDeclarative description of a model's input payload tree and action output.
- ObservationRolesThe observation roles an environment declares, grouped by kind.
- RotationA literal rotation, authored as a model state part's
post_rotate. - SplitAn ordered split of one flat numeric observation leaf into role fields.
- StateA single-part numeric state input expected by a model.
- StateTagA numeric proprioception entry in an environment observation.
- TextA text input expected by a model.
- TextTagA text entry (typically the task instruction) in an observation.
Functions
- Previous()The model's own previous action as a state part.
- resolve()Derive an
Adapterfor an env/model pair. - resolve_from_contract()Derive an
Adapterfrom an env contract and a model spec.
Exceptions
Submodules
Constants
Show all 32Hide
- ACTION_DELTA_POSAction role for an end-effector Cartesian position delta (action/delta_eef_pos).
- ACTION_DELTA_ROTAction role for an end-effector rotation delta (action/delta_eef_rot).
- ACTION_EEF_POSAction role for an absolute end-effector position target (action/eef_pos).
- ACTION_EEF_ROTAction role for an absolute end-effector rotation target (action/eef_rot).
- ACTION_GRIPPERAction role for a gripper command (action/gripper).
- ACTION_JOINT_POSAction role for joint position targets (action/joint_pos).
- ACTION_JOINT_VELAction role for joint velocity targets (action/joint_vel).
- BASEBody part for the mobile base (base).
- BASE_ANG_VELObservation role for the base angular velocity, the IMU gyro (proprio/base_ang_vel).
- BASE_ROTObservation role for the base orientation (proprio/base_rot); read it with encoding="gravity_xyz" for projected gravity.
- COMMAND_BASE_VELCommand role for the base velocity setpoint [vx, vy, wz] the runner hands the policy (command/base_vel).
- EEF_POSObservation role for the end-effector Cartesian position (proprio/eef_pos).
- EEF_ROTObservation role for the end-effector rotation (proprio/eef_rot).
- EEF_WRENCHObservation role for the end-effector wrench [fx, fy, fz, tx, ty, tz] a wrist force/torque sensor reads (proprio/eef_wrench), framed.
- ENV_BRANCH_METADATA_KEYContract metadata key under which a branched environment publishes the discriminant binding its make() selected (rlmesh.adapters.v1.env_branch).
- ENV_METADATA_KEYContract metadata key under which an environment publishes its EnvTags (rlmesh.adapters.v1.env_tags).
- GRIPPER_POSObservation role for the gripper opening state (proprio/gripper).
- HEADBody part for the head (head), e.g. a head-mounted camera.
- IMAGE_PRIMARYObservation role for the primary scene camera (image/primary).
- IMAGE_SECONDARYObservation role for a secondary scene camera (image/secondary).
- IMAGE_WRISTObservation role for a wrist-mounted camera (image/wrist).
- INSTRUCTIONObservation role for the task instruction text (text/instruction).
- JOINT_POSObservation role for joint positions (proprio/joint_pos).
- JOINT_VELObservation role for joint velocities (proprio/joint_vel).
- LEFT_ARMBody part for the left arm (left_arm), where a role repeats across a bimanual body.
- LEFT_LEGBody part for the left leg (left_leg).
- MODEL_METADATA_KEYContract metadata key under which a model publishes its ModelSpec (rlmesh.adapters.v1.model_spec).
- PARTSThe registered body parts, in registry order.
- RIGHT_ARMBody part for the right arm (right_arm).
- RIGHT_LEGBody part for the right leg (right_leg).
- ROTATION_DIMSMapping from each rotation encoding to its dimension count.
- TORSOBody part for the torso (torso).
Type aliases
Show all 16Hide
- ConcatPartOne part of a Concat state input: a State leaf, a Constant block, or a bare role string.
- FitModeHow an image is fit to a declared size: 'stretch', 'letterbox', or 'crop'.
- FrameCoordinate frame an absolute pose is expressed in: 'world' or 'robot_base'.
- ImageLayoutImage axis-layout vocabulary: 'hwc' or 'chw'.
- InputNodeA node of the ModelSpec input tree: a leaf, a mapping, or a tuple of nodes.
- ModelLeafA model-input leaf: Image, State, Concat, Text, or Custom.
- ObsLeafAn observation tag leaf: ImageTag, StateTag, TextTag, or Split.
- ObsNodeA node of the observation tag tree: a leaf, a mapping, or a tuple of nodes.
- ObsTransformAn in-process callable mapping a raw observation to one payload slot (Custom transform).
- ProvenanceLiteral of where a state leaf's numbers come from: sensed, estimated, or privileged.
- ReferencePose a delta command is integrated against: 'current' (measured) or 'target' (last commanded).
- ResampleImage resampling filter vocabulary for declared resizes.
- RotationEncodingRotation encoding vocabulary (quat_xyzw, quat_wxyz, axis_angle, rot6d, rot6d_rowmajor, euler_xyz).
- RotationTransformAn in-process callable repacking a rotation block for a CustomEncoding.
- StackPadFrame-window padding vocabulary: replicate the first frame, or pad black.
- StackSpecA declared frame window: non-positive frame offsets from the current step.