Observation Terms¶
Observation terms read the simulation, commands and motion reference into the tensors a policy sees. Observation
compute() is a read, not a tick: it runs at build, at reset, in several step phases and from
get_observations(), so per-step state advances in post_physics_refresh(). The
observations guide covers groups, noise, history and modifiers; the
term catalog lists every parameter.
The base classes ObservationTerm and ObservationTermFuncWrapper are on the
managers page.
Proprioception¶
Proprioceptive observation terms (base pose/velocity; joint position, velocity and force).
Attributes¶
Classes¶
DofsPos
¶
DofsPos(env: EnvBase, options: ObservationTermOptions)
Bases: _DofsObservation
Joint positions (angles; positions for linear actuators) of an entity's DOFs.
| PARAMETER | DESCRIPTION |
|---|---|
entity_name
|
The entity whose DOFs are read.
|
dofs_name
|
Joints to read, in output order;
|
terms_idx
|
Positions in the entity's
|
offset_from_default
|
Subtract the entity's default positions (
|
Source code in eden/managers/observation_manager.py
DofsVel
¶
DofsVel(env: EnvBase, options: ObservationTermOptions)
Bases: _DofsObservation
Joint velocities of an entity's DOFs.
| PARAMETER | DESCRIPTION |
|---|---|
entity_name
|
The entity whose DOFs are read.
|
dofs_name
|
Joints to read, in output order;
|
terms_idx
|
Positions in the entity's
|
Source code in eden/managers/observation_manager.py
DofsForce
¶
DofsForce(env: EnvBase, options: ObservationTermOptions)
Bases: _DofsObservation
Generalized force the solver applied to each of an entity's DOFs (get_dofs_force).
| PARAMETER | DESCRIPTION |
|---|---|
entity_name
|
The entity whose DOFs are read.
|
dofs_name
|
Joints to read, in output order;
|
terms_idx
|
Positions in the entity's
|
Source code in eden/managers/observation_manager.py
DofsControlForce
¶
DofsControlForce(env: EnvBase, options: ObservationTermOptions)
Bases: _DofsObservation
Control force the actuators applied on each of an entity's DOFs over the last physics step
(get_dofs_control_force).
| PARAMETER | DESCRIPTION |
|---|---|
entity_name
|
The entity whose DOFs are read.
|
dofs_name
|
Joints to read, in output order;
|
terms_idx
|
Positions in the entity's
|
Source code in eden/managers/observation_manager.py
Functions:¶
base_pos
¶
base_pos(env: EnvBase, *, entity_name: str, envs_idx: slice | Tensor | None = None, relative: bool = False) -> Tensor
Return the position of the entity's base link.
| PARAMETER | DESCRIPTION |
|---|---|
env
|
The environment instance.
TYPE:
|
entity_name
|
The name of the entity.
TYPE:
|
envs_idx
|
The indices of the environments. If None, all environments will be considered. Defaults to None.
TYPE:
|
relative
|
Frame the position is reported in.
TYPE:
|
Source code in eden/managers/terms/observations/proprio.py
base_quat
¶
base_quat(env: EnvBase, *, entity_name: str, envs_idx: slice | Tensor | None = None, relative: bool = False) -> Tensor
Return the quaternion of the entity's base link.
| PARAMETER | DESCRIPTION |
|---|---|
env
|
The environment instance.
TYPE:
|
entity_name
|
The name of the entity.
TYPE:
|
envs_idx
|
The indices of the environments. If None, all environments will be considered. Defaults to None.
TYPE:
|
relative
|
Frame the orientation is reported in — see :func:
TYPE:
|
Source code in eden/managers/terms/observations/proprio.py
base_rpy
¶
base_rpy(env: EnvBase, *, entity_name: str, envs_idx: slice | Tensor | None = None, terms_idx: Tensor | None = None) -> Tensor
Return the roll, pitch, and yaw of the entity's base link.
| PARAMETER | DESCRIPTION |
|---|---|
env
|
The environment instance.
TYPE:
|
entity_name
|
The name of the entity.
TYPE:
|
envs_idx
|
The indices of the environments. If None, all environments will be considered. Defaults to None.
TYPE:
|
terms_idx
|
The indices of the terms to return. If None, all terms will be returned. Defaults to None.
TYPE:
|
Source code in eden/managers/terms/observations/proprio.py
base_lin_vel
¶
base_lin_vel(env: EnvBase, *, entity_name: str, envs_idx: slice | Tensor | None = None, frame: Literal['world', 'body'] = 'world') -> Tensor
Source code in eden/managers/terms/observations/proprio.py
base_ang_vel
¶
base_ang_vel(env: EnvBase, *, entity_name: str, envs_idx: slice | Tensor | None = None, frame: Literal['world', 'body'] = 'world') -> Tensor
Source code in eden/managers/terms/observations/proprio.py
links_pos
¶
links_pos(env: EnvBase, *, entity_name: str, ls_idx_local: Tensor | None = None, envs_idx: slice | Tensor | None = None) -> Tensor
Source code in eden/managers/terms/observations/proprio.py
links_quat
¶
links_quat(env: EnvBase, *, entity_name: str, ls_idx_local: Tensor | None = None, envs_idx: slice | Tensor | None = None) -> Tensor
Source code in eden/managers/terms/observations/proprio.py
links_vel
¶
links_vel(env: EnvBase, *, entity_name: str, ls_idx_local: Tensor | None = None, envs_idx: slice | Tensor | None = None) -> Tensor
Source code in eden/managers/terms/observations/proprio.py
links_ang
¶
links_ang(env: EnvBase, *, entity_name: str, ls_idx_local: Tensor | None = None, envs_idx: slice | Tensor | None = None) -> Tensor
Source code in eden/managers/terms/observations/proprio.py
Locomotion¶
Locomotion observation terms (gait phase, projected gravity, base height, height scan).
Attributes¶
Classes¶
ProjectedGravity
¶
ProjectedGravity(env: EnvBase, options: ObservationTermOptions)
Bases: ObservationTerm
Gravity direction expressed in the entity's base frame.
Caches only the constant world-frame gravity vector in :meth:build; the entity handle is
resolved each :meth:compute via resolve_entity so the deployment's sim→RobotStateEntity
swap is picked up automatically (a cached handle would keep reading the simulated robot on hardware).
Source code in eden/managers/observation_manager.py
ScaledCommands
¶
ScaledCommands(env: EnvBase, options: ObservationTermOptions)
Bases: ObservationTerm
Command vector multiplied by a per-component scale; prefer the built-in scale=[...] modifier.
For plain per-component scaling prefer the built-in scale=[...] post-compute modifier
(ObsTerm.configure(func=..., scale=[2.0, 1.0])). command_scale is the per-component
multiplier (named to avoid colliding with the inherited post-compute scale modifier). Both
the command ref and the scale tensor are resolved once in :meth:build.
The swap is exact only when the term configures no noise and no clip. This class
scales inside compute(), so the manager's noise and clip see the scaled command; the
scale modifier is applied after both (compute_group runs noise -> clip -> scale). So
migrating a term that also sets noise divides the effective noise std by the per-component
factor, and one that sets clip reinterprets the bounds from scaled units into raw ones.
Rescale those two alongside the swap, or keep this class.
Source code in eden/managers/observation_manager.py
VelocityTrackingErrorIntegral
¶
VelocityTrackingErrorIntegral(env: EnvBase, options: ObservationTermOptions)
Bases: ObservationTerm
Running integral of the base-velocity tracking error (N, 3).
The worked example of a stateful observation term.
∫ (commanded − measured) dt over [vx, vy, wz] in the base frame, against a velocity
command laid out [vx, vy, wz] (:class:~eden.managers.terms.commands.velocity.UniformVelocityCommand).
Zero at reset, exactly k increments after k control steps, and clamped per component to
±max_abs so a persistent error (a robot that cannot reach the commanded speed) saturates the
feature instead of growing without bound — the anti-windup clamp of a PI controller.
This term exists as much to be copied as to be used. It is the reference for per-step state on an
observation term, which the manager's compute() cannot hold because that call is a read and
runs several times a step (:class:~eden.managers.observation_manager.ObservationTerm):
- :meth:
buildresolves the command (a bad name raises at env construction), touches the entity, and allocates the buffer — outside any inference-mode region, so every hook may write it. - :meth:
post_physics_refreshis the once-per-step tick: it reads the post-physics robot and adds the increment in place. It runs at phase 7 — after the command caches and metrics, above the graded layer and the auto-reset — so the final-observation snapshot carries this step's increment andreset()zeroes it for the envs that restart before their first fresh observation. The deploy loop ticks it once per control tick. - :meth:
resetzeroes the rows of the restarting envs. - :meth:
computereturns the buffer, live — like a metric buffer, not a copy; the manager's snapshot paths copy what they keep. Nothing else.
The entity is resolved in the hook, not cached in build — the deployment swaps
env.entities[name] for a RobotStateEntity and a cached handle would keep integrating the
simulated robot on hardware. self._env.dt is the control dt, so the integral is in
m / rad regardless of decimation.
Source code in eden/managers/observation_manager.py
Attributes¶
Methods:¶
build
¶
Source code in eden/managers/terms/observations/locomotion.py
post_physics_refresh
¶
Source code in eden/managers/terms/observations/locomotion.py
GridScanDots
¶
GridScanDots(env: EnvBase, options: ObservationTermOptions)
Bases: ObservationTerm
Height scan of the terrain at the given xy coordinates.
This is specifically used for Terrain entity. For the general LiDAR sensor, use the LiDAR observation term.
| PARAMETER | DESCRIPTION |
|---|---|
entity_name
|
The name of the entity where the grid is "attached" to. Defaults to "robot".
TYPE:
|
terrain_entity_name
|
The name of the terrain entity. Defaults to "terrain".
TYPE:
|
measured_points_x
|
The x coordinates (m) of the measured points, in the base's yaw-aligned frame. Defaults to the values in the class. |
measured_points_y
|
The y coordinates (m) of the measured points, in the base's yaw-aligned frame. Defaults to the values in the class. |
flatten_measured_points
|
Whether to flatten the heights per env. Defaults to True: shape
TYPE:
|
offset_from_base
|
If True (default), return each terrain height relative to the base height (
TYPE:
|
clamp_offset_range
|
The |
Source code in eden/managers/terms/observations/locomotion.py
Attributes¶
measured_points_x
class-attribute
instance-attribute
¶
measured_points_x: list[float] = [-0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]
measured_points_y
class-attribute
instance-attribute
¶
Methods:¶
build
¶
Source code in eden/managers/terms/observations/locomotion.py
compute
¶
Source code in eden/managers/terms/observations/locomotion.py
Functions:¶
sin_phase
¶
Sine of the gait phase for each foot. Shape (num_envs, num_feet).
Source code in eden/managers/terms/observations/locomotion.py
cos_phase
¶
Cosine of the gait phase for each foot. Shape (num_envs, num_feet).
Source code in eden/managers/terms/observations/locomotion.py
base_height
¶
base_height(env: EnvBase, *, entity_name: str = 'robot', terrain_entity_name: str | None = None, relative: bool = False) -> Tensor
Height of the entity's base above the ground, shape (num_envs, 1).
The locomotion counterpart of Isaac Lab's base_pos_z, and the observation half of
:func:~eden.managers.terms.terminations.locomotion.root_height_below_minimum — the two read the
same :func:~eden.managers.terms.utils.base_height_above_ground helper, so an observation and a
termination configured alike cannot disagree about what "height" means.
| PARAMETER | DESCRIPTION |
|---|---|
env
|
The environment instance.
TYPE:
|
entity_name
|
Entity whose base height is reported. Defaults to
TYPE:
|
terrain_entity_name
|
Terrain entity to measure against.
TYPE:
|
relative
|
Frame the base pose is read in — see
:func:
TYPE:
|
Source code in eden/managers/terms/observations/locomotion.py
Commands, actions and episode state¶
Common observation terms (commands, last action, episode phase).
Attributes¶
Classes¶
MetricObservation
¶
MetricObservation(env: EnvBase, options: ObservationTermOptions)
Bases: ObservationTerm
Expose a :class:~eden.managers.metric_manager.MetricTerm's cached value as a (num_envs, 1) observation.
Pulls the per-env value the metric manager computed this step (metric_manager runs
before the observation manager in env.step()). Same rationale as metric_reward:
compute a shared quantity once as a metric and read it here by name rather than
recomputing it or stashing it on env. The standard obs modifiers (scale/clip/noise/
history) still apply. Observations are computed after env resets, so an environment that
reset this step reads the metric's post-reset value (0 until its next compute),
consistent with Eden's post-reset observation convention.
A missing metric manager or an unset or unknown metric_name (the error lists the active
metrics) raises in :meth:build, i.e. at env construction. :meth:compute is a pure read of
the manager-owned buffer, so the extra calls an observation term receives (build-time shape
probe, reset(), the final-observation snapshot) are harmless.
Source code in eden/managers/observation_manager.py
Functions:¶
generated_commands
¶
last_action
¶
Source code in eden/managers/terms/observations/common.py
episode_phase
¶
Return normalized episode time as a (num_envs, 1) tensor.
centered=False (default): t / max_episode_length in [0, 1].
centered=True: 2 * t / max_episode_length - 1 in [-1, 1].
Source code in eden/managers/terms/observations/common.py
Privileged dynamics¶
Per-env domain-randomized quantities (gain and motor-strength scales, added mass, foot friction, CoM offset) for a critic or a teacher policy.
Privileged observation terms exposing per-env domain-randomized dynamics.
These read the realized randomized physical parameters relative to their nominal defaults, so an asymmetric (privileged) critic can condition on the domain randomization the actor cannot observe — the standard sim-to-real privileged-critic technique. The actor sees only proprioception; the critic additionally sees terms like these.
Each term reads back exactly one domain_rand event:
=========================== =======================================================================
term event it reads back
=========================== =======================================================================
:class:GainScale :class:~eden.managers.terms.events.domain_rand.RandomizeKpKdGains
:class:MotorStrengthScale :class:~eden.managers.terms.events.domain_rand.RandomizeMotorStrength
:class:AddedMass :class:~eden.managers.terms.events.domain_rand.RandomizeMassShift
:class:FootFriction :class:~eden.managers.terms.events.domain_rand.RandomizeFrictionRatio
:class:ComOffset :class:~eden.managers.terms.events.domain_rand.RandomizeComShift
=========================== =======================================================================
Convention: the shift/deviation terms are 0 at nominal (GainScale,
MotorStrengthScale, AddedMass, ComOffset); FootFriction is a
ratio, 1.0 at nominal.
Inspired by TWIST2's critic_extras (critic_motor_scales /
critic_added_mass / critic_foot_friction / critic_base_com_offset).
Attributes¶
Classes¶
GainScale
¶
GainScale(env: EnvBase, options: ObservationTermOptions)
Bases: ObservationTerm
Per-DOF relative deviation of the realized PD gains from their defaults.
Returns concat([kp/kp0 - 1, kd/kd0 - 1]) over the entity's actuated DOFs
(in dofs_name order); 0 means nominal, so it is all zeros when
there is no gain randomization. Pairs with
:class:~eden.managers.terms.events.domain_rand.RandomizeKpKdGains.
Output shape (num_envs, 2 * num_dofs).
Notes
Reads the gains held on the entity (get_dofs_kp / get_dofs_kd), so
it only reflects gain randomization written to the entity — i.e.
RandomizeKpKdGains with action_term_name=None (the default, Genesis
built-in PD path). RandomizeKpKdGains with action_term_name set
writes the PD-controller's _kp / _kd caches instead and never touches
the entity, so this term would read all zeros; :meth:build raises if such
an event targets the same entity. (The controller mirrors the entity gains
into its caches on every action reset, but that mirror is one-way
entity→controller, so it does not carry controller-side randomization back
to the entity.) Per-env gains require batch_dofs_info=True in
env_options; otherwise the gains are shared across envs and the term is
uniformly zero (still valid, just uninformative).
This is the gain deviation, distinct from
:class:MotorStrengthScale (the actuator torque-scale modifier).
| PARAMETER | DESCRIPTION |
|---|---|
entity_name
|
Name of the articulated entity whose actuator gains to read.
TYPE:
|
Source code in eden/managers/observation_manager.py
Attributes¶
Methods:¶
build
¶
Source code in eden/managers/terms/observations/privileged.py
compute
¶
Source code in eden/managers/terms/observations/privileged.py
MotorStrengthScale
¶
MotorStrengthScale(env: EnvBase, options: ObservationTermOptions)
Bases: ObservationTerm
Per-DOF deviation of the realized actuator torque-scale from its nominal.
Returns motor_strength - motor_strength_baseline over the controller's
DOFs (0 means the configured nominal strength), read from the
:class:~eden.managers.modifiers.actions.actuators.MotorStrength action
modifier that
:class:~eden.managers.terms.events.domain_rand.RandomizeMotorStrength
writes. All zeros without motor-strength randomization. Output shape
(num_envs, num_dofs).
The baseline is the modifier's configured strength row (usually 1.0 but
honoring a non-unity motor_strength config), so the term stays 0 at
the deterministic nominal regardless of that configured value.
This is the actuator torque-scale (a multiplier on the PD output torque),
distinct from :class:GainScale (the kp/kd gain deviation).
| PARAMETER | DESCRIPTION |
|---|---|
action_term_name
|
Name of the PD-controller action term hosting the
TYPE:
|
Source code in eden/managers/observation_manager.py
Attributes¶
Methods:¶
build
¶
Source code in eden/managers/terms/observations/privileged.py
AddedMass
¶
AddedMass(env: EnvBase, options: ObservationTermOptions)
Bases: _LinkDrTerm
Per-env mass shift (kg) of the named links vs nominal — 0 without mass DR.
Ports TWIST2's critic_added_mass. Pairs with
:class:~eden.managers.terms.events.domain_rand.RandomizeMassShift
(or :class:~eden.managers.terms.events.domain_rand.RandomizeLinkMassScale).
Output shape (num_envs, len(links_name)).
Source code in eden/managers/observation_manager.py
FootFriction
¶
FootFriction(env: EnvBase, options: ObservationTermOptions)
Bases: _LinkDrTerm
Mean per-env friction ratio over the named links — 1.0 without friction DR.
Ports TWIST2's critic_foot_friction. Pairs with
:class:~eden.managers.terms.events.domain_rand.RandomizeFrictionRatio.
Output shape (num_envs, 1).
Source code in eden/managers/observation_manager.py
ComOffset
¶
ComOffset(env: EnvBase, options: ObservationTermOptions)
Bases: _LinkDrTerm
Per-env COM shift (m) of the named links vs nominal — 0 without COM DR.
Ports TWIST2's critic_base_com_offset. Pairs with
:class:~eden.managers.terms.events.domain_rand.RandomizeComShift.
Output shape (num_envs, 3 * len(links_name)).
Source code in eden/managers/observation_manager.py
Functions:¶
Manipulation¶
Manipulation observation terms: end-effector pose, gripper state, object distances.
Attributes¶
RotationFormat
module-attribute
¶
RotationFormat = Literal['quat', 'euler_xyz', 'axis_angle', 'rot6d']
Classes¶
EndEffectorToObjectDistance
¶
EndEffectorToObjectDistance(env: EnvBase, options: ObservationTermOptions)
Bases: ObservationTerm
End-effector-to-object vector (N, 3).
From the mean of the two end-effector links to the object (or its link). Expressed in the robot's base frame
(frame="robot", the default) or the world frame.
Source code in eden/managers/observation_manager.py
Attributes¶
Methods:¶
build
¶
Source code in eden/managers/terms/observations/manipulation.py
compute
¶
Source code in eden/managers/terms/observations/manipulation.py
ObjectToOracleDistance
¶
ObjectToOracleDistance(env: EnvBase, options: ObservationTermOptions)
Bases: ObservationTerm
Object-to-oracle vector (N, 3).
From the object (or its link) to the oracle target. The target is the first three components of command
command_name, a position in the robot's base frame. The result is expressed in the robot's base frame
(frame="robot", the default) or the world frame.
Source code in eden/managers/observation_manager.py
Attributes¶
Methods:¶
build
¶
Source code in eden/managers/terms/observations/manipulation.py
compute
¶
Source code in eden/managers/terms/observations/manipulation.py
EndEffectorPose
¶
EndEffectorPose(env: EnvBase, options: ObservationTermOptions)
Bases: ObservationTerm
End-effector pose [pos(3), rotation(k)] of a link, in the base or world frame.
| PARAMETER | DESCRIPTION |
|---|---|
entity_name
|
Robot entity owning the link.
|
ee_link_name
|
The end-effector link.
|
frame
|
Frame the pose is expressed in.
|
offset_pos
|
Virtual tool frame relative to the link (position in m, wxyz quaternion).
|
offset_quat
|
Virtual tool frame relative to the link (position in m, wxyz quaternion).
|
frame_correction_quat
|
Fixed wxyz rotation right-multiplied onto the orientation (
|
rotation
|
Output rotation format; the term is 7-, 6-, 6- or 9-D accordingly.
|
Source code in eden/managers/observation_manager.py
Attributes¶
offset_pos
class-attribute
instance-attribute
¶
offset_quat
class-attribute
instance-attribute
¶
frame_correction_quat
class-attribute
instance-attribute
¶
Methods:¶
build
¶
Source code in eden/managers/terms/observations/manipulation.py
compute
¶
Source code in eden/managers/terms/observations/manipulation.py
GripperState
¶
GripperState(env: EnvBase, options: ObservationTermOptions)
Bases: ObservationTerm
Gripper DOF positions as raw values, openness or closedness.
| PARAMETER | DESCRIPTION |
|---|---|
entity_name
|
Entity owning the gripper DOFs (the arm, or a separately mounted gripper).
|
dofs_name
|
Gripper DOFs to report (one driver, or both fingers for a raw two-finger state).
|
normalize
|
|
open_pos
|
DOF positions of the fully open / fully closed gripper (required unless
|
close_pos
|
DOF positions of the fully open / fully closed gripper (required unless
|
scale
|
Multiplier for
|
Source code in eden/managers/observation_manager.py
Attributes¶
Methods:¶
build
¶
Source code in eden/managers/terms/observations/manipulation.py
compute
¶
Source code in eden/managers/terms/observations/manipulation.py
Functions:¶
rotation_as
¶
rotation_as(quat_wxyz: Tensor, rotation: RotationFormat) -> Tensor
Express a batch of wxyz quaternions (N, 4) in rotation format.
euler_xyz is extrinsic roll/pitch/yaw (scipy "xyz"), axis_angle a rotation
vector, rot6d the first two rows of the rotation matrix (Zhou et al.).
Source code in eden/managers/terms/observations/manipulation.py
end_effector_pose
¶
end_effector_pose(entity, link_idx: Tensor, *, frame: Literal['base', 'world'] = 'base', offset_pos: Tensor | None = None, offset_quat: Tensor | None = None, correction_quat: Tensor | None = None) -> tuple[Tensor, Tensor]
(pos (N, 3), quat_wxyz (N, 4)) of one link, optionally re-expressed and corrected.
offset_pos / offset_quat (1, 3) / (1, 4) place a virtual tool frame on
the link (RobotArena's ee_gripper_link sits 9.36 cm ahead of WidowX's
gripper_link). frame="base" expresses the result in the entity's base frame.
correction_quat (1, 4) is a fixed rotation right-multiplied onto the
orientation (R_out = R @ R_corr), as the DROID rot6d convention or a hardware
tool-frame yaw offset require.
Source code in eden/managers/terms/observations/manipulation.py
gripper_state
¶
gripper_state(dofs_pos: Tensor, *, normalize: GripperNormalize = 'raw', open_pos: float | None = None, close_pos: float | None = None, scale: float = 1.0) -> Tensor
Map gripper DOF positions (N, k) to raw (scaled) values, openness or closedness.
closedness = (pos - open_pos) / (close_pos - open_pos) and
openness = 1 - closedness, so a WidowX finger (open at 0.037, closed at 0) and a
Robotiq driver (open at 0, closed at 0.8) both read 0 = open, 1 = closed for
closedness without per-robot special cases.
Source code in eden/managers/terms/observations/manipulation.py
Contact¶
Per-link contact-force-norm observation.
Reads :meth:RigidEntity.get_links_net_contact_force (Genesis-aggregated
per-link net force; (num_envs, n_links, 3) in world frame), slices to
the configured link set, and returns the per-link force magnitude.
Trade-off vs. gs.sensors.ContactForce: the Genesis sensor binds to
one link per SensorOptions declaration, so a 14-link hand needs
14 sensor entries plus 14 obs-term entries to do what
:class:ContactForceNorm does in a single declaration. The cost is no
NoisySensorMixin noise / delay / decimation modeling; that path is
reachable via the :class:~eden.managers.terms.observations.sensors.SensorRead term plus a
per-link sensor declaration if a config wants noise on a small subset
of links.
Attributes¶
Classes¶
ContactForceNorm
¶
ContactForceNorm(env: EnvBase, options: ObservationTermOptions)
Bases: ObservationTerm
Per-link contact-force magnitude (Euclidean, world frame).
Returns (num_envs, K) where K = len(matched links), each
entry being ‖f_link‖ at the most recent scene.step().
| PARAMETER | DESCRIPTION |
|---|---|
entity_name
|
Entity to read forces from (must be a
|
links_name
|
:func:
|
Notes
Output scaling, noise, clipping, and history are controlled via
the inherited :class:ObservationTermOptions fields (scale,
noise, clip, history_length) — pass e.g. scale=0.01
on the term options when forces are in newtons and the policy
expects roughly-unit observations.
The underlying force is in world frame — Genesis's
get_links_net_contact_force returns the world-frame net force per
link. gs.sensors.ContactForce (the noise-aware path reachable via
the generic :class:~eden.managers.terms.observations.sensors.SensorRead obs term) returns the same vector
in the link's local frame. Magnitudes are equal under any choice
of frame, so this term's per-link norm is unaffected by the choice;
a config swapping between this term and a sensor-reading-plus-norm
composition gets identical scalar values but watch the frame if a
downstream consumer uses the raw force vector.
Source code in eden/managers/observation_manager.py
Attributes¶
Methods:¶
build
¶
Source code in eden/managers/terms/observations/contact.py
GroupedContactFlags
¶
GroupedContactFlags(env: EnvBase, options: ObservationTermOptions)
Bases: ObservationTerm
Per-(link, partner-link) boolean contact flags with a specific entity.
Wraps :meth:RigidEntity.get_grouped_contacts and returns its valid
mask as floats in {0, 1}, flattened to (num_envs, n_a * n_b) —
the simulated counterpart of :func:motion_contact_flags for
contact-annotated mimic tasks (ConTrack xhand_contact).
| PARAMETER | DESCRIPTION |
|---|---|
entity_name
|
Active entity (usually the hand); its links index the first axis.
|
object_entity_name
|
Contact partner (usually the manipulated object).
|
links_name
|
Link patterns on
|
object_links_name
|
Link patterns on the partner (columns). Empty selects all links.
|
force_threshold
|
|
Source code in eden/managers/observation_manager.py
Attributes¶
Methods:¶
build
¶
Source code in eden/managers/terms/observations/contact.py
compute
¶
Source code in eden/managers/terms/observations/contact.py
Functions:¶
motion_contact_flags
¶
motion_contact_flags(env: MimicRLEnvBase, *, entity_name: str, links_name: list[str]) -> Tensor
Demo per-(link, partner) contact flags at the current motion frame.
Reads motion_manager.data[entity_name].contact_points_valid (frame 0)
for the named motion links; returns floats in {0, 1} flattened to
(num_envs, L * num_partners) — the reference counterpart of
:class:GroupedContactFlags (ConTrack ref_xhand_contact).
Source code in eden/managers/terms/observations/contact.py
motion_future_contact_label
¶
motion_future_contact_label(env: MimicRLEnvBase, *, entity_name: str, frame_offsets: Sequence[int], links_name: list[str] | None = None, flatten: bool = True) -> Tensor
Demo tri-state per-link contact labels (+1 contact / -1 no contact / 0 unlabelled) at future frames.
Shape (N, K*L) (or (N, K, L) if flatten=False), as floats. Reads
motion_manager.data[entity_name].contact_label; links_name=None returns every motion link of the entity.
The reference counterpart of :class:GroupedContactFlags for a dataset whose contact annotation distinguishes
"must not touch" from "don't care" (e.g. Weave's G1-Inspire-HOI labels).
Source code in eden/managers/terms/observations/contact.py
Sensors¶
Observation term that concatenates configured sensor readings.
Attributes¶
Classes¶
SensorRead
¶
SensorRead(env: EnvBase, options: ObservationTermOptions)
Bases: ObservationTerm
Concatenate selected sensor readings into a single observation tensor.
Sensors return a tensor or NamedTuple of tensors; a tensor with more than two dimensions is flattened to
(num_envs, -1), and every tensor is cast to float before concatenation along the last dimension.
| PARAMETER | DESCRIPTION |
|---|---|
sensor_names
|
Sensor names, regexes or globs to include, in output order. If None, all sensors are included. |
read_ground_truth
|
If True, read from the sensors' ground truth values instead of their noisy readings.
TYPE:
|
post_process_func
|
An optional function to apply to each sensor reading before concatenation.
TYPE:
|
Source code in eden/managers/observation_manager.py
Attributes¶
Methods:¶
build
¶
Source code in eden/managers/terms/observations/sensors.py
compute
¶
Source code in eden/managers/terms/observations/sensors.py
Functions:¶
Cameras¶
Camera observation terms (RGB, depth, segmentation, normals, point cloud).
Attributes¶
Classes¶
Functions:¶
rgb_image
¶
rgb_image(env: RLEnvBase, *, camera_name: str, normalize: bool = False, channels_first: bool = False) -> Tensor
RGB image from a camera, optionally CNN-ready.
By default returns the renderer's native output ((N, H, W, C), uint8).
For feeding a CNN policy (rsl_rl's ActorCriticCNN expects float
(N, C, H, W)), set normalize=True (uint8 -> float in [0, 1]) and
channels_first=True. Either flag also drops an alpha channel (the
madrona batch renderer returns RGBA).
Source code in eden/managers/terms/observations/camera.py
depth_image
¶
segmentation_image
¶
normal_image
¶
pointcloud_image
¶
Source code in eden/managers/terms/observations/camera.py
Motion tracking¶
Terms that expose env.motion_manager reference state on a MimicRLEnvBase.
Observation terms exposing motion-reference state to the policy.
Reads env.motion_manager.data[entity_name] (filled per step at the start
of MimicRLEnvBase.step() and refilled per env on reset) — NOT
reference_frame, which would force a recompute pass and a GPU sync.
Current vs future frames
The motion-reference buffer is shaped (num_envs, num_frames, ...) where
num_frames comes from :attr:MotionManagerOptions.num_frames. Terms in
this module split into two families:
- Current-frame terms (
motion_base_*_w,motion_dofs_*,motion_links_*_b) index[:, 0, ...]. With the defaultdata_start_from="one_frame_interval"frame 0 is one tick ahead; withdata_start_from="current_time"frame 0 is the current step. - Future-frame terms (
motion_future_*) index a caller-suppliedframe_offsetstuple into the same buffer. They are intended for policies that consume a short lookahead (e.g. ProtoMotions'(1, 2, 4, 8)-step target poses on top of the current frame). The caller must sizenum_framesto covermax(frame_offsets) + 1; the term raises a clear error on the first call otherwise.
Shape convention
- Single-target terms (
motion_base_*_w,motion_dofs_*) return(num_envs, F). - Multi-link terms (
motion_links_*) return(num_envs, K*F)by default — flat, so they slot into rank-2 obs concat groups (the common case for MLP policies) without the caller having to passflatten=Trueevery time. Passflatten=Falseto keep the link axis as a separate(num_envs, K, F)dimension for structured policies (transformer / per-link MLP). - Future-frame terms add a leading
K = len(frame_offsets)axis:(num_envs, K*D)flat /(num_envs, K, D)unflattened for DOF terms;(num_envs, K*L*F)/(num_envs, K, L, F)for link terms.
Each term calls :func:assert_motion_field_present for the field(s) it
actually reads, so a dataset that doesn't supply the required field
(e.g. a fixed-base motion sequence with no base_pos_w, or a hand
sequence with no links_quat_w) fails fast on first read instead of
silently feeding the MotionReferenceData.make_empty default
(zeros / identity quat) to the policy. Position-only and orientation-only
terms intentionally assert only on the field they consume — a dataset
with only positions can still feed motion_links_pos_w /
motion_links_pos_b.
Attributes¶
Classes¶
Functions:¶
motion_base_pos_w
¶
motion_base_pos_w(env: MimicRLEnvBase, *, entity_name: str) -> Tensor
World-frame motion-ref base position. Shape (num_envs, 3).
Free-base entities only — fixed-base motion sequences leave
base_pos_w at the make-empty default and this term raises.
Source code in eden/managers/terms/observations/tracking.py
motion_base_quat_w
¶
motion_base_quat_w(env: MimicRLEnvBase, *, entity_name: str) -> Tensor
World-frame motion-ref base quaternion (wxyz). Shape (num_envs, 4).
Quat is unit-norm — guaranteed by MotionSequence.__post_init__.
Source code in eden/managers/terms/observations/tracking.py
motion_links_pos_w
¶
motion_links_pos_w(env: MimicRLEnvBase, *, entity_name: str, links_name: list[str], flatten: bool = True) -> Tensor
Return world-frame motion-ref link positions.
Shape (num_envs, K*3) (or (num_envs, K, 3) if flatten=False).
Single-link (links_name=["wrist"]) gives e.g. dexmachina ref wrist
position; multi-link gives ref keypoints (fingertips, etc.).
Source code in eden/managers/terms/observations/tracking.py
motion_links_quat_w
¶
motion_links_quat_w(env: MimicRLEnvBase, *, entity_name: str, links_name: list[str], flatten: bool = True) -> Tensor
Return world-frame motion-ref link quaternions (wxyz).
Shape (num_envs, K*4) (or (num_envs, K, 4) if flatten=False).
Quats are unit-norm — guaranteed by MotionSequence.__post_init__.
Source code in eden/managers/terms/observations/tracking.py
motion_dofs_pos
¶
motion_dofs_pos(env: MimicRLEnvBase, *, entity_name: str, dofs_name: list[str] | None = None) -> Tensor
Motion-ref qpos. Shape (num_envs, D).
dofs_name=None returns every motion-ref DOF for the entity.
Otherwise returns just the named DOFs (motion-ref-axis order).
Sibling of :class:eden.managers.terms.observations.proprio.DofsPos,
which reads the robot's own state.
Source code in eden/managers/terms/observations/tracking.py
motion_dofs_vel
¶
motion_dofs_vel(env: MimicRLEnvBase, *, entity_name: str, dofs_name: list[str] | None = None) -> Tensor
Motion-ref qvel. Symmetric to :func:motion_dofs_pos.
Sibling of :class:eden.managers.terms.observations.proprio.DofsVel.
Source code in eden/managers/terms/observations/tracking.py
motion_links_pos_b
¶
motion_links_pos_b(env: MimicRLEnvBase, *, entity_name: str, links_name: list[str], anchor_link_name: str, flatten: bool = True) -> Tensor
Return motion-ref links_name positions in the robot's anchor_link_name frame.
Shape (num_envs, K*3) (or (num_envs, K, 3) if flatten=False).
Position-only — reads links_pos_w (motion side) plus the robot's
anchor link pose. Does not require links_quat_w from the
motion sequence (a dataset with only positions still works here).
To reproduce beyondmimic's motion_anchor_pos_b,
pass links_name=[anchor_link_name] (e.g.
links_name=["torso_link"], anchor_link_name="torso_link") — that
reproduces the original anchor-vs-anchor numerics and the
(num_envs, 3) flat shape.
Source code in eden/managers/terms/observations/tracking.py
motion_links_ori_b
¶
motion_links_ori_b(env: MimicRLEnvBase, *, entity_name: str, links_name: list[str], anchor_link_name: str, flatten: bool = True) -> Tensor
Return motion-ref links_name orientations in the robot's anchor_link_name frame.
Expressed as 2-column rotation matrices, shape (num_envs, K*6)
(or (num_envs, K, 6) if flatten=False).
Orientation-only — reads links_quat_w (motion side) plus the
robot's anchor link orientation. Does not require links_pos_w.
To reproduce beyondmimic's motion_anchor_ori_b, pass
links_name=[anchor_link_name]. The 2-column rotation matrix
output (not quaternion) is beyondmimic's representation, so its
pretrained policies work unchanged; configs that prefer quat can read
:func:motion_links_quat_w instead.
Source code in eden/managers/terms/observations/tracking.py
robot_body_pos_b
¶
robot_body_pos_b(env: MimicRLEnvBase, *, entity_name: str, anchor_link_name: str, tracked_link_names: list[str], flatten: bool = True) -> Tensor
Return robot body positions relative to its own anchor link.
Shape (N, K*3) (or (N, K, 3) if flatten=False).
Symmetric to :func:motion_links_pos_b but reads the robot's own state
instead of the motion reference. Useful as a critic-only observation that
sees the policy's body geometry in the same frame as the motion targets.
Source code in eden/managers/terms/observations/tracking.py
robot_body_ori_b
¶
robot_body_ori_b(env: MimicRLEnvBase, *, entity_name: str, anchor_link_name: str, tracked_link_names: list[str], flatten: bool = True) -> Tensor
Return robot body orientations relative to its own anchor, as 2-column rotation matrices.
Shape (N, K*6) (or (N, K, 6) if flatten=False).
Symmetric to :func:motion_links_ori_b.
Source code in eden/managers/terms/observations/tracking.py
motion_future_dofs_pos
¶
motion_future_dofs_pos(env: MimicRLEnvBase, *, entity_name: str, frame_offsets: Sequence[int], dofs_name: list[str] | None = None, flatten: bool = True) -> Tensor
Return motion-ref qpos at multiple future buffer frames.
Shape (N, K*D) (or (N, K, D) if flatten=False).
frame_offsets are interpreted as buffer indices into
env.motion_manager.data[entity_name].dofs_pos (shape (N, F, D)).
With data_start_from="current_time" offset 0 is the current step
and (1, 2, 4, 8) are 1/2/4/8 buffer ticks ahead; with the default
data_start_from="one_frame_interval" offset 0 is already one tick
ahead. The per-tick wall-clock duration is
:attr:MotionManagerOptions.frame_interval_s_range.
dofs_name=None returns every motion-ref DOF for the entity.
Source code in eden/managers/terms/observations/tracking.py
motion_future_dofs_vel
¶
motion_future_dofs_vel(env: MimicRLEnvBase, *, entity_name: str, frame_offsets: Sequence[int], dofs_name: list[str] | None = None, flatten: bool = True) -> Tensor
Return motion-ref qvel at multiple future buffer frames.
Symmetric to :func:motion_future_dofs_pos.
Source code in eden/managers/terms/observations/tracking.py
motion_future_links_ori_b
¶
motion_future_links_ori_b(env: MimicRLEnvBase, *, entity_name: str, links_name: list[str], anchor_link_name: str, frame_offsets: Sequence[int], representation: Literal['rot6d', 'tan_norm'] = 'rot6d', flatten: bool = True) -> Tensor
Return future-frame motion-ref link orientations in the robot's current anchor frame.
Shape (N, K*L*6) (or (N, K, L, 6) if flatten=False).
The relative rotation is R_rel = R_robot_anchor⁻¹ · R_motion_future
— i.e. the motion future orientation is brought into the robot's
current anchor frame, matching the ProtoMotions reduced-coords target
pose formulation. Two output representations:
representation="rot6d": 2-column rotation matrix[R_rel·x̂, R_rel·ŷ](Zhou et al. 2019). Same convention as :func:motion_links_ori_b, so a config can swap the current-frame and future-frame variants without retraining the head.representation="tan_norm": ProtoMotionsquat_to_tan_normoutput[R_rel·x̂, R_rel·ẑ]. Use this when feeding a checkpoint trained against ProtoMotions' target-poses obs (e.g. theg1-bones-deployactor).
Set links_name=[anchor_link_name] to reproduce the ProtoMotions
"anchor-relative anchor future rotation" channel (single link, K
futures).
Source code in eden/managers/terms/observations/tracking.py
motion_future_links_pos_b
¶
motion_future_links_pos_b(env: MimicRLEnvBase, *, entity_name: str, links_name: list[str], anchor_link_name: str, frame_offsets: Sequence[int], flatten: bool = True) -> Tensor
Return future-frame motion-ref links_name positions in the robot's current anchor frame.
Shape (N, K*L*3) (or (N, K, L, 3) if flatten=False).
Position-only sibling of :func:motion_future_links_ori_b. The position
delta is rotated into the robot's current anchor frame
(R_robot_anchor⁻¹ · (p_motion_future − p_robot_anchor)), matching the
ProtoMotions reduced-coords target-position formulation. Reads
links_pos_w (motion side) plus the robot's anchor link pose.
Set links_name=[anchor_link_name] to reproduce the ProtoMotions
"anchor-relative anchor future position" channel (single link, K
futures). The current-frame counterpart is :func:motion_links_pos_b.
Source code in eden/managers/terms/observations/tracking.py
motion_future_base_pos_w
¶
motion_future_base_pos_w(env: MimicRLEnvBase, *, entity_name: str, frame_offsets: Sequence[int], flatten: bool = True) -> Tensor
World-frame motion-ref base position at multiple buffer frames.
Shape (N, K*3) (or (N, K, 3) if flatten=False). The base-pose
counterpart of :func:motion_future_dofs_pos — used e.g. for future
object-pose targets in hand-object mimic tasks.
Source code in eden/managers/terms/observations/tracking.py
motion_future_base_quat_w
¶
motion_future_base_quat_w(env: MimicRLEnvBase, *, entity_name: str, frame_offsets: Sequence[int], flatten: bool = True) -> Tensor
World-frame motion-ref base quaternion (wxyz) at multiple buffer frames.
Shape (N, K*4) (or (N, K, 4) if flatten=False).
Source code in eden/managers/terms/observations/tracking.py
motion_future_base_pos_b
¶
motion_future_base_pos_b(env: MimicRLEnvBase, *, entity_name: str, anchor_entity_name: str, anchor_link_name: str, frame_offsets: Sequence[int], flatten: bool = True) -> Tensor
Future-frame motion-ref base position of entity_name in another entity's live anchor-link frame.
Shape (N, K*3) (or (N, K, 3) if flatten=False). R_anchor⁻¹ · (p_ref_future − p_anchor) with
the anchor read from the simulation at the current step — the full 6-DoF anchor frame, like
:func:motion_future_links_pos_b. The object-in-humanoid-frame target of a humanoid-object tracker:
entity_name="object", anchor_entity_name="robot", anchor_link_name="pelvis".
Source code in eden/managers/terms/observations/tracking.py
motion_future_base_ori_b
¶
motion_future_base_ori_b(env: MimicRLEnvBase, *, entity_name: str, anchor_entity_name: str, anchor_link_name: str, frame_offsets: Sequence[int], representation: Literal['rot6d', 'tan_norm'] = 'rot6d', flatten: bool = True) -> Tensor
Future-frame motion-ref base orientation of entity_name in another entity's live anchor-link frame.
Shape (N, K*6) (or (N, K, 6) if flatten=False). R_anchor⁻¹ · R_ref_future as a 6-D rotation,
representation as in :func:motion_future_links_ori_b. The orientation sibling of
:func:motion_future_base_pos_b.
Source code in eden/managers/terms/observations/tracking.py
entity_base_pos_b
¶
entity_base_pos_b(env: MimicRLEnvBase, *, entity_name: str, anchor_entity_name: str, anchor_link_name: str) -> Tensor
Live base position of entity_name in another entity's live anchor-link frame. Shape (N, 3).
The simulated counterpart of :func:motion_future_base_pos_b — e.g. where the object is relative to the
humanoid's pelvis. Reads get_pos(), the entity's solver root frame: for a free rigid object that is its
centre of mass unless the object is built with align=False (then the authored body frame, the frame a
reference object pose is recorded in).
Source code in eden/managers/terms/observations/tracking.py
entity_base_ori_b
¶
entity_base_ori_b(env: MimicRLEnvBase, *, entity_name: str, anchor_entity_name: str, anchor_link_name: str, representation: Literal['rot6d', 'tan_norm'] = 'rot6d') -> Tensor
Live base orientation of entity_name in another entity's live anchor-link frame, 6-D. Shape (N, 6).
The orientation sibling of :func:entity_base_pos_b.
Source code in eden/managers/terms/observations/tracking.py
motion_phase
¶
motion_phase(env: MimicRLEnvBase, *, entity_name: str) -> Tensor
Normalized clip playback phase in [0, 1]. Shape (num_envs, 1).
frame / (clip_length - 1) at the current reference frame — unlike
:func:eden.managers.terms.observations.common.episode_phase, a mid-clip
RSI start reports its true position in the clip.
:meth:MotionManager.get_motion_phase raises when no motion term tracks
entity_name, so a misspelled entity fails on the first compute instead of
feeding the policy a constant-zero column.