Reward Terms¶
Reward terms return one value per env per step; the reward manager multiplies each by its weight, sums them and
scales the sum by the control step dt. The
rewards and terminations guide explains weights, groups and logging; the term catalog lists every parameter.
The base classes RewardTerm and RewardTermFuncWrapper are on the managers page.
Common penalties¶
Action rate and magnitude, joint-limit, torque and contact penalties.
Common reward/penalty terms (action rate/magnitude, joint limits, torques, contacts, metric and success rewards).
Attributes¶
Classes¶
UndesiredContacts
¶
UndesiredContacts(env: EnvBase, options: _TermOptionsT)
Bases: RewardTerm
Penalty count of links whose net contact-force magnitude exceeds threshold.
links_name accepts the same regex / glob patterns as
:func:eden.utils.string.resolve_matching_names. Use a negative reward
weight to penalise (e.g. -0.1 per offending link).
Source code in eden/managers/base.py
Attributes¶
Methods:¶
build
¶
Source code in eden/managers/terms/rewards/common.py
compute
¶
Source code in eden/managers/terms/rewards/common.py
ActionRateL2Smooth
¶
ActionRateL2Smooth(env: EnvBase, options: _TermOptionsT)
Bases: RewardTerm
Penalize the 1st and 2nd derivatives of the actions using an L2 squared kernel.
The 2nd-derivative term needs the action from two steps ago. This term owns that buffer
(the previous step's prev_action), zeroed per env on reset.
Source code in eden/managers/base.py
Attributes¶
Methods:¶
build
¶
Source code in eden/managers/terms/rewards/common.py
compute
¶
Source code in eden/managers/terms/rewards/common.py
DofsAccL2
¶
DofsAccL2(env: EnvBase, options: _TermOptionsT)
Bases: RewardTerm
Penalize joint accelerations approximated as velocity differences.
Computes sum((vel - prev_vel)^2) where prev_vel is the joint velocity
from the previous step; this term owns that buffer, zeroed per env on reset. The config
weight should account for the 1/dt^2 factor compared to raw simulator accelerations.
Source code in eden/managers/base.py
MetricReward
¶
MetricReward(env: EnvBase, options: _TermOptionsT)
Bases: RewardTerm
Use a :class:~eden.managers.metric_manager.MetricTerm's cached value as the reward.
Reads the per-env value the metric manager already computed this step
(metric_manager runs before the reward manager in env.step()), so a quantity
shared across reward / observation / termination terms is computed once as a
metric and pulled here by name — instead of being recomputed in every term or stashed
on the env object. The configured reward weight scales it as usual (use a
negative weight for a penalty).
Rejects a cumulative metric by default: its value is the running episode sum, so using
it directly as a per-step reward re-integrates that sum and balloons over the episode —
almost never intended. Pass allow_cumulative=True to opt in if you really want the
running sum as the reward.
A missing metric manager, an unset or unknown metric_name (the error lists the active
metrics) and a rejected cumulative metric all raise in :meth:build, i.e. at env construction.
Source code in eden/managers/base.py
Attributes¶
Methods:¶
build
¶
Source code in eden/managers/terms/rewards/common.py
TaskSuccess
¶
TaskSuccess(env: EnvBase, options: _TermOptionsT)
Bases: RewardTerm
1 on a step where every success metric holds.
The bonus for finishing, the reward counterpart of the on_success termination. Dense progress terms pay
little for the last few percent of a task (the last cells of a stain, the final centimetres of a placement),
so without it a policy settles just short of the success threshold. Pays metric_manager.success_buf, and
raises in :meth:build when the task declares no per-step (INTERVAL) metric that contributes to success,
since that buffer then never turns True.
Source code in eden/managers/base.py
Methods:¶
build
¶
Source code in eden/managers/terms/rewards/common.py
Functions:¶
action_rate_l2
¶
Penalize the rate of change of the actions using L2 squared kernel.
Source code in eden/managers/terms/rewards/common.py
action_l2
¶
Penalize the actions using L2 squared kernel.
Source code in eden/managers/terms/rewards/common.py
dofs_pos_limits
¶
Penalize joint positions if they cross the soft limits.
Source code in eden/managers/terms/rewards/common.py
dofs_vel_limits
¶
Quadratic hinge penalty on joint velocities exceeding a symmetric limit.
Penalizes only the amount by which |v| exceeds max_vel. Returns the (non-negative) squared L2 norm of the excess velocities; use a negative weight to penalise.
Source code in eden/managers/terms/rewards/common.py
self_collision_cost
¶
Penalize self collisions.
Source code in eden/managers/terms/rewards/common.py
dofs_torques
¶
Penalize joint torques: sqrt(sum(tau^2)) + sum(|tau|).
Source code in eden/managers/terms/rewards/common.py
similar_to_default
¶
Penalize joint poses far away from the entity's default pose.
Source code in eden/managers/terms/rewards/common.py
Locomotion¶
Reward terms for locomotion and velocity tracking tasks.
Most terms here are stateful class terms: they resolve their entity/command refs, link indices, and constant
tensors (gravity, per-joint std, pose weights) once in :meth:build and reuse them every step, never stashing
caches on the env object. Trivial penalties with nothing to cache are plain functions.
Attributes¶
Classes¶
TrackingLinVel
¶
TrackingLinVel(env: EnvBase, options: _TermOptionsT)
Bases: _VelocityTracking
Tracking of linear velocity commands (xy axes).
Body frame: exp(-||cmd_xy - v_xy||^2 / sigma); sigma divides the squared error directly, so it
is a variance, not a std.
Source code in eden/managers/base.py
TrackingAngVel
¶
TrackingAngVel(env: EnvBase, options: _TermOptionsT)
Bases: _VelocityTracking
Tracking of angular velocity commands (yaw).
Body frame: exp(-(cmd_wz - w_z)^2 / sigma).
Source code in eden/managers/base.py
FlatOrientationL2
¶
FlatOrientationL2(env: EnvBase, options: _TermOptionsT)
Bases: RewardTerm
Penalize non-flat base orientation (projected gravity deviation in xy).
Source code in eden/managers/base.py
Upright
¶
Upright(env: EnvBase, options: _TermOptionsT)
Bases: RewardTerm
Reward for keeping a body link upright.
Projects gravity into the link's frame and returns exp(-sum(gravity_xy^2) / std^2) (matches mjlab's
upright). Shared by the stand and velocity-tracking tasks. The link index and the constant world-frame
gravity vector are resolved once in :meth:build.
Source code in eden/managers/base.py
Attributes¶
Methods:¶
build
¶
Source code in eden/managers/terms/rewards/locomotion.py
compute
¶
Source code in eden/managers/terms/rewards/locomotion.py
BodyAngVelXYPenalty
¶
BodyAngVelXYPenalty(env: EnvBase, options: _TermOptionsT)
Bases: RewardTerm
Penalize body angular velocity in xy (allow z rotation).
Source code in eden/managers/base.py
VariablePosture
¶
VariablePosture(env: EnvBase, options: _TermOptionsT)
Bases: RewardTerm
Speed-dependent posture reward.
Uses per-joint standard deviations to control how much each joint can deviate from default pose. The
reward is exp(-mean(error^2 / std^2)). Three speed regimes select the std set:
- standing (speed < walking_threshold)
- walking (walking_threshold <= speed < running_threshold)
- running (speed >= running_threshold)
Each std dict must cover every DOF of the robot (a ".*" entry is the explicit "everything else"
catch-all); DOFs no pattern matches raise at :meth:build instead of silently training against a
default tolerance.
Source code in eden/managers/base.py
Attributes¶
Methods:¶
build
¶
Source code in eden/managers/terms/rewards/locomotion.py
compute
¶
Source code in eden/managers/terms/rewards/locomotion.py
FeetClearance
¶
FeetClearance(env: EnvBase, options: _TermOptionsT)
Bases: RewardTerm
Penalize deviation from target clearance height, weighted by foot xy velocity.
Source code in eden/managers/base.py
Attributes¶
Methods:¶
build
¶
Source code in eden/managers/terms/rewards/locomotion.py
compute
¶
Source code in eden/managers/terms/rewards/locomotion.py
FeetSlip
¶
FeetSlip(env: EnvBase, options: _TermOptionsT)
Bases: RewardTerm
Penalize foot sliding (xy velocity while in contact with ground).
Source code in eden/managers/base.py
Attributes¶
contact_height_threshold
class-attribute
instance-attribute
¶
contact_height_threshold: float = 0.05
Methods:¶
build
¶
Source code in eden/managers/terms/rewards/locomotion.py
compute
¶
Source code in eden/managers/terms/rewards/locomotion.py
FeetAirTime
¶
FeetAirTime(env: EnvBase, options: _TermOptionsT)
Bases: RewardTerm
Legged-gym style feet air-time reward for aperiodic gaits.
Tracks per-foot air time; on the control step a foot first makes contact it
credits (air_time - target_s) (summed over feet), gated to when a movement
command is active. Rewards proper swing cycles, so it discourages a leg that
stays permanently planted or permanently airborne ("dragging" limps). Use a
POSITIVE weight.
Source code in eden/managers/base.py
Attributes¶
Methods:¶
build
¶
Source code in eden/managers/terms/rewards/locomotion.py
compute
¶
Source code in eden/managers/terms/rewards/locomotion.py
reset
¶
FeetContactBalancePenalty
¶
FeetContactBalancePenalty(env: EnvBase, options: _TermOptionsT)
Bases: RewardTerm
Penalize uneven foot usage (a limp) via the variance of per-foot contact duty.
Keeps an EMA of each foot's contact state and returns the variance across the feet: a healthy gait uses all legs (~equal duty) -> low variance; a leg that is always planted or always in the air spikes the variance. Complements a mirror / symmetry loss by also catching front/rear imbalance. Use a NEGATIVE weight.
Source code in eden/managers/base.py
Attributes¶
Methods:¶
build
¶
Source code in eden/managers/terms/rewards/locomotion.py
compute
¶
Source code in eden/managers/terms/rewards/locomotion.py
FeetPhase
¶
FeetPhase(env: EnvBase, options: _TermOptionsT)
Bases: RewardTerm
Reward for tracking desired foot height based on gait phase.
Uses a smoothstep profile to define the expected swing trajectory.
Source code in eden/managers/base.py
Attributes¶
Methods:¶
build
¶
Source code in eden/managers/terms/rewards/locomotion.py
compute
¶
Source code in eden/managers/terms/rewards/locomotion.py
CloseFeetPenalty
¶
CloseFeetPenalty(env: EnvBase, options: _TermOptionsT)
Bases: RewardTerm
Penalize when feet are too close together in the xy plane.
Returns 1.0 (penalty active) when the smallest pairwise xy distance between feet is < threshold, else 0.0.
Source code in eden/managers/base.py
Attributes¶
Methods:¶
build
¶
Source code in eden/managers/terms/rewards/locomotion.py
compute
¶
Source code in eden/managers/terms/rewards/locomotion.py
FeetOrientationPenalty
¶
FeetOrientationPenalty(env: EnvBase, options: _TermOptionsT)
Bases: RewardTerm
Penalize feet orientation deviation from flat (projected gravity in foot frame).
Source code in eden/managers/base.py
Attributes¶
Methods:¶
build
¶
Source code in eden/managers/terms/rewards/locomotion.py
compute
¶
Source code in eden/managers/terms/rewards/locomotion.py
WeightedPosePenalty
¶
WeightedPosePenalty(env: EnvBase, options: _TermOptionsT)
Bases: RewardTerm
Penalize deviation from default pose with per-joint weights.
Source code in eden/managers/base.py
Attributes¶
Methods:¶
build
¶
Source code in eden/managers/terms/rewards/locomotion.py
StumblePenalty
¶
StumblePenalty(env: EnvBase, options: _TermOptionsT)
Bases: RewardTerm
Compute an indicator penalty for feet hitting vertical surfaces (e.g. stairs riser, walls).
Returns 1.0 when any foot's lateral contact force exceeds
horizontal_to_vertical_ratio * |z contact|, else 0.0. Mirrors
holosoma/.../reward/terms/locomotion.py:316-329.
Source code in eden/managers/base.py
Attributes¶
horizontal_to_vertical_ratio
class-attribute
instance-attribute
¶
horizontal_to_vertical_ratio: float = 4.0
Methods:¶
build
¶
compute
¶
Source code in eden/managers/terms/rewards/locomotion.py
CloseFeetYawProjectedPenalty
¶
CloseFeetYawProjectedPenalty(env: EnvBase, options: _TermOptionsT)
Bases: RewardTerm
Penalize feet closer than a lateral distance in the base's yaw frame.
Unlike the naive xy distance in :class:CloseFeetPenalty, this rotates the foot-pair offset into the
robot's yaw-aligned frame and measures only the lateral component. This is more robust during in-place
turns where the naive metric flips sign as the body yaws. Requires exactly two feet — humanoid
convention. Mirrors holosoma/.../reward/terms/locomotion.py:191-215.
Source code in eden/managers/base.py
Attributes¶
Methods:¶
build
¶
Source code in eden/managers/terms/rewards/locomotion.py
compute
¶
Source code in eden/managers/terms/rewards/locomotion.py
Functions:¶
constant_base_height
¶
constant_base_height(env: EnvBase, *, entity_name: str, target_height: float, terrain_entity_name: str | None = None, relative: bool = False) -> Tensor
Penalize base height away from target — :func:base_height_l2 without velocity gating.
terrain_entity_name and relative mean what they do there, and are forwarded unchanged.
Source code in eden/managers/terms/rewards/locomotion.py
lin_vel_z
¶
Penalize z axis base linear velocity.
Source code in eden/managers/terms/rewards/locomotion.py
track_lin_vel_with_z_penalty
¶
track_lin_vel_with_z_penalty(env: EnvBase, *, command_name: str, entity_name: str, std: float) -> Tensor
Track commanded linear velocity with additional z-velocity penalty.
reward = exp(-(xy_error + 2 * z_vel^2) / std^2)
Source code in eden/managers/terms/rewards/locomotion.py
track_ang_vel_with_xy_penalty
¶
track_ang_vel_with_xy_penalty(env: EnvBase, *, command_name: str, entity_name: str, std: float) -> Tensor
Track commanded angular velocity with additional xy angular velocity penalty.
reward = exp(-(z_error + 0.05 * xy_error) / std^2)
Source code in eden/managers/terms/rewards/locomotion.py
base_height_l2
¶
base_height_l2(env: EnvBase, *, entity_name: str, target_height: float, command_name: str | None = None, zero_vel_penalty_scale: float = 1.0, zero_vel_threshold: float = 0.1, terrain_entity_name: str | None = None, relative: bool = False) -> Tensor
L2 base-height penalty with optional zero-velocity amplification.
Squared deviation of the base height from target_height. When command_name
is provided and the commanded planar velocity is below zero_vel_threshold,
the penalty is multiplied by zero_vel_penalty_scale so the policy is held
more strictly to the target height while standing. Mirrors
holosoma/.../reward/terms/locomotion.py:218-250.
Height is read through :func:~eden.managers.terms.utils.base_height_above_ground, the same
helper as the :func:~eden.managers.terms.observations.locomotion.base_height observation and
the :func:~eden.managers.terms.terminations.locomotion.root_height_below_minimum termination,
and it takes their two parameters for the same reasons. terrain_entity_name names a
:class:~eden.entities.terrain.Terrain to measure against instead of the world-frame z:
without it a target height on a heightfield is unreachable in a valley and undershot on a hill,
and — the reason it belongs on this term rather than only on those two — a config that sets it
on the observation and the termination but not here trains a policy whose reward pulls toward a
height its own feature and its episode boundary do not measure. relative selects the frame
the base pose is read in (see
:func:~eden.managers.terms.observations.proprio.base_pos); the default False is the solver
frame.
Equivalent to :func:constant_base_height when command_name is None.
The stance-mode amplification from holosoma's variant is intentionally not
ported here — that path reaches into env-set boolean attributes with no clear
producer contract. If you need it, add a dedicated term that consumes a typed
stance source (e.g. a phase-aware command term).
Source code in eden/managers/terms/rewards/locomotion.py
Motion tracking¶
Rewards that score the robot against env.motion_manager reference data.
Reward terms that score robot state against env.motion_manager data.
All terms read motion-ref data through env.motion_manager.data[entity_name]
(filled once per step at the start of MimicRLEnvBase.step()) — NOT
reference_frame, which would force a recompute pass and a GPU sync.
Two families:
- Direct world-frame tracking (function-style, registry keys
motion_{base,link,dofs}_*_tracking_exp): scores robot state directly against world-frame motion-ref data. Use for free-floating objects (where world xy / yaw is meaningful), fixed-base entities, and DexMachina-style bimanual hand-object tasks. - Anchor-yaw-warped tracking (class-style, registry keys
motion_{relative_body,global_body}_*): warps the motion targets through a yaw-only delta computed at an anchor link before scoring. Makes the reward invariant to the robot's heading drift on the floor — useful for free-floating humanoid imitation where absolute world yaw / xy is not the optimisation target. Requires bothlinks_pos_wandlinks_quat_w.
Exp-kernel parameter convention: these terms use std with the form
exp(-error / std**2), matching beyondmimic's tracking rewards. Two other
conventions exist in the codebase that newcomers should be aware of:
locomotion.tracking_lin_velusessigmawith the formexp(-error / sigma)(linear, not squared).- DexMachina papers use
betawithexp(-beta * error). Mapping:std = 1 / sqrt(beta).
Each term calls :func:assert_motion_field_present at first read so a
dataset that doesn't supply the required field (e.g. a fixed-base motion
sequence with no base_pos_w, or an Arctic hand sequence with no
links_quat_w) fails fast instead of silently scoring against the
make-empty default (zeros / identity quat).
Attributes¶
Classes¶
MotionRelativeBodyPositionErrorExp
¶
MotionRelativeBodyPositionErrorExp(env: EnvBase, options: _TermOptionsT)
Bases: RewardTerm
Yaw-warped multi-link position tracking (exp kernel, link mean).
The yaw-warp uses both anchor positions and quaternions (via
:func:get_anchor_state / :func:get_links_state), so the dataset must
populate both links_pos_w and links_quat_w. Use the direct
:func:motion_link_position_tracking_exp for datasets that only have
positions.
frame_offsets defaults to (0,) (current frame only). Multi-frame
averages per-future-frame exp(...) masked by validity so past-clip
frames contribute zero — pair with the obs-side
:func:~eden.managers.terms.observations.tracking.motion_future_links_pos_b set to the same offsets.
Source code in eden/managers/base.py
Attributes¶
Methods:¶
build
¶
compute
¶
Source code in eden/managers/terms/rewards/tracking.py
MotionRelativeBodyOrientationErrorExp
¶
MotionRelativeBodyOrientationErrorExp(env: EnvBase, options: _TermOptionsT)
Bases: RewardTerm
Yaw-warped multi-link orientation tracking (exp kernel, link mean).
Reads both links_pos_w and links_quat_w for the same reason as
:class:MotionRelativeBodyPositionErrorExp.
frame_offsets matches :class:MotionRelativeBodyPositionErrorExp.
Source code in eden/managers/base.py
Attributes¶
Methods:¶
build
¶
compute
¶
Source code in eden/managers/terms/rewards/tracking.py
MotionGlobalBodyLinearVelocityErrorExp
¶
MotionGlobalBodyLinearVelocityErrorExp(env: EnvBase, options: _TermOptionsT)
MotionGlobalBodyAngularVelocityErrorExp
¶
MotionGlobalBodyAngularVelocityErrorExp(env: EnvBase, options: _TermOptionsT)
Functions:¶
exp_kernel
¶
exp_kernel(error: Tensor, std: float, *, mode: Literal['mean_of_exp', 'exp_of_mean', 'exp_of_sum'] = 'exp_of_mean') -> Tensor
Gaussian tracking kernel reducing the last (per-item) axis of error.
error is the squared per-item error (..., M) where M is the link
or DOF axis; returns (...) with that axis collapsed. mode names the
one valid way the exp and the per-item reduction compose — each value is the
literal formula, so there is no silently-ignored argument:
"mean_of_exp"(DexMachinaexp_kpt_first): per-itemexp(-e/std²)then mean over items — soft per-item credit."exp_of_mean"(default): oneexpon the mean per-item error — a single soft pass on the average."exp_of_sum"(DexMachinaobj_arti_rew): oneexpon the summed per-item error — a single hard pass/fail.
Mirrors the exp(-error / std²) convention documented at module top.
Source code in eden/managers/terms/rewards/tracking.py
validity_weighted_frame_mean
¶
Average a per-frame reward (N, K) over the K future frames.
Each frame is weighted by its valid mask (N, K) — 1.0 inside the
clip, 0.0 for frames past the clip end (the buffer holds the last valid
frame there, so an unmasked mean would score against a fake target). The
denominator is clamped at 1 so an all-invalid row returns 0 rather than
NaN. valid=None (no validity available) falls back to a plain mean over
K. Returns (N,).
Source code in eden/managers/terms/rewards/tracking.py
motion_base_position_tracking_exp
¶
motion_base_position_tracking_exp(env: MimicRLEnvBase, *, entity_name: str, std: float) -> Tensor
Exp-kernel reward on world-frame base position vs motion ref.
DexMachina equivalent: obj_pos_rew.
Source code in eden/managers/terms/rewards/tracking.py
motion_base_orientation_tracking_exp
¶
motion_base_orientation_tracking_exp(env: MimicRLEnvBase, *, entity_name: str, std: float) -> Tensor
Exp-kernel reward on quat-error magnitude of the base vs motion ref (wxyz).
DexMachina equivalent: obj_rot_rew.
Source code in eden/managers/terms/rewards/tracking.py
motion_link_position_tracking_exp
¶
motion_link_position_tracking_exp(env: MimicRLEnvBase, *, entity_name: str, links_name: list[str], std: float, exp_first: bool = True, frame_offsets: Sequence[int] = (0,)) -> Tensor
Exp-kernel reward on world-frame link positions vs motion ref.
Single-link (links_name=["wrist"]) gives DexMachina wrist-pos /
object-pos tracking; multi-link gives DexMachina fingertip imitation.
exp_first=True (default, matches DexMachina exp_kpt_first=True):
mean over links of exp(-d² / std²).
exp_first=False: exp(-mean(d²) / std²) — one soft pass on the
average error.
frame_offsets=(0,) (default) scores only the current motion frame.
Multi-frame (e.g. (0, 4, 8)) averages the per-frame reward over the
listed buffer indices, masked by MotionReferenceData.validity so
frames past the clip end contribute zero. Pair with the obs-side
:func:~eden.managers.terms.observations.tracking.motion_future_links_pos_b
lookahead set to the same offsets so the reward scores what the policy sees.
Source code in eden/managers/terms/rewards/tracking.py
motion_link_orientation_tracking_exp
¶
motion_link_orientation_tracking_exp(env: MimicRLEnvBase, *, entity_name: str, links_name: list[str], std: float, exp_first: bool = True, frame_offsets: Sequence[int] = (0,)) -> Tensor
Exp-kernel reward on world-frame link orientations vs motion ref (wxyz).
Single-link gives DexMachina wrist-rot / object-rot tracking; multi-link reduces the same way as the position variant.
frame_offsets matches :func:motion_link_position_tracking_exp —
default (0,) is the current frame; multi-frame masks past-clip
frames via validity.
Source code in eden/managers/terms/rewards/tracking.py
motion_dofs_pos_tracking_exp
¶
motion_dofs_pos_tracking_exp(env: MimicRLEnvBase, *, entity_name: str, std: float, dofs_name: list[str] | None = None, reduction: Literal['sum', 'per_dof_mean', 'mean'] = 'sum', frame_offsets: Sequence[int] = (0,)) -> Tensor
Exp-kernel reward on per-DOF qpos vs motion ref.
reduction="sum" (default): exp(-Σ(q − q_ref)² / std²). Single
hard pass/fail; matches DexMachina obj_arti_rew.
reduction="per_dof_mean": mean over dofs of
exp(-(q − q_ref)² / std²). Each DOF gets independent credit;
matches DexMachina bc_rew for hand qpos behavior cloning.
reduction="mean": exp(-mean((q − q_ref)²) / std²) — one soft
pass on the MSE; matches ConTrack arm/finger joint tracking.
dofs_name=None tracks every DOF the motion ref exposes for the
entity.
frame_offsets defaults to (0,) (current frame only). Multi-frame
averages the per-frame exp(...) weighted by validity.
Source code in eden/managers/terms/rewards/tracking.py
Contact matching¶
Contact-cloud Chamfer reward.
Scores policy-vs-demo per-link-pair contact configurations via masked
Chamfer distance, in either world / object / wrist frame, with exp or
sigmoid kernels. Builds on :meth:RigidEntity.get_grouped_contacts
(the policy contact-cloud aggregator) and :func:eden.utils.pc.chamfer_distance
(the distance kernel).
Reads the demo-side contact target from the motion manager
(env.motion_manager.data[hand_entity_name].contact_points_w /
contact_points_valid). A dataset packs them through add_motion_sequence;
when the loaded motion data does not carry them,
:meth:MotionContactChamferReward.build raises via :func:assert_motion_field_present.
Mirrors DexMachina RewardModule.compute_hand_contact_reward
(dexmachina/envs/rewards.py:293) at single-frame, single-part
granularity. Per-part / multi-frame composition is left to the config
layer (one term per part / frame), keeping the reward kernel composable.
Attributes¶
EMPTY_DISTANCE_SENTINEL
module-attribute
¶
Per-direction Chamfer distance returned when one cloud is empty and the
other is not. Mirrors DexMachina reward_utils.chamfer_distance
(dexmachina/envs/reward_utils.py:44) — large
enough that exp(-100/std**2) ≈ 0 turns "policy contacts but demo does
not" (or vice-versa) into a hard penalty. chamfer_distance itself
defaults to 0.0 (no signal); this term overrides to the DexMachina
value.
Classes¶
MotionContactChamferReward
¶
MotionContactChamferReward(env: EnvBase, options: _TermOptionsT)
Bases: RewardTerm
Exp/sigmoid reward on the policy-vs-demo contact Chamfer distance.
Per-step semantics:
- Policy contacts:
hand.get_grouped_contacts(object, links_a, links_b)—(B, n_a, n_b, 3)weighted-mean positions plus(B, n_a, n_b)validity mask. - Demo contacts:
env.motion_manager.data[hand_entity_name].contact_points_w[:, lookahead_index]— same shape. Validity fromcontact_points_valid[:, lookahead_index]. -
Each cloud is transformed by its own anchor before the Chamfer comparison (matches DexMachina
rewards.py:321-328): -
frame="object": policy usesobj.get_pos()/get_quat(); demo usesmotion_manager.data[object_entity_name].base_pos_w/base_quat_watlookahead_index. frame="wrist": policy uses the named wrist link's current pose on the hand; demo useslinks_pos_w/links_quat_won the hand's motion data atlookahead_indexand the motion-side wrist index.frame="world": no transform.
Two instances composed at the config layer (frame="object"
and frame="wrist", summed via term weights) reproduce
DexMachina's multiply_frame_contact=True once weights are
set up — the dual-anchor frame transform is what makes the
composition meaningful.
4. chamfer_distance over the flattened (n_a, n_b) →
N clouds with empty_distance=EMPTY_DISTANCE_SENTINEL
(DexMachina sentinel, 100.0).
5. Distance → reward via the configured kernel.
6. Both-empty mask: per zero_contact_mode.
| PARAMETER | DESCRIPTION |
|---|---|
hand_entity_name
|
Active entity (usually the hand). Indexes axis 1 of the grouped-contact tensors.
|
object_entity_name
|
Contact partner (usually the manipulated object). Indexes axis 2.
|
hand_links_name
|
:func:
|
object_links_name
|
Same, on the object side.
|
frame
|
Frame the Chamfer distance is measured in.
|
wrist_link_name
|
Required iff
|
lookahead_index
|
Frame index into the per-env motion-reference window.
|
kernel
|
|
std
|
Exp-kernel scale;
|
sigmoid_a
|
Sigmoid-kernel constants; ignored unless
|
sigmoid_b
|
Sigmoid-kernel constants; ignored unless
|
zero_contact_mode
|
|
empty_distance
|
Passed to :func:
|
Notes
The demo-side fields contact_points_w and contact_points_valid of
:class:MotionReferenceData are optional. When the loaded motion data does
not carry them, :meth:build raises via :func:assert_motion_field_present,
so the reward cannot silently score against zeros.
The term assumes a free-floating hand and free-floating object — typical for dexterous manipulation. Arm-mounted hand setups are supported because the hand sub-tree remains free relative to the (possibly fixed) arm; the wrist anchor still resolves correctly.
Source code in eden/managers/base.py
Attributes¶
zero_contact_mode
class-attribute
instance-attribute
¶
zero_contact_mode: Literal['zero', 'one'] = 'zero'
Methods:¶
build
¶
Source code in eden/managers/terms/rewards/contact.py
compute
¶
Source code in eden/managers/terms/rewards/contact.py
MotionContactMatchReward
¶
MotionContactMatchReward(env: EnvBase, options: _TermOptionsT)
Bases: _MotionContactTermBase
Fraction of links whose contact state matches the demo's contact-ON links.
ConTrack's contact-event overlap reward: per tracked link, credit 1 iff
some partner column has BOTH the demo annotation and simulated contact
(same-partner matching — ConTrack's per-object (ref & sim).any);
mean over the tracked links. Links the demo marks contact-free contribute
0 either way — the term rewards making annotated contacts, not avoiding
spurious ones (ConTrack contact_reward).
Source code in eden/managers/base.py
Methods:¶
compute
¶
Source code in eden/managers/terms/rewards/contact.py
MotionContactDistanceReward
¶
MotionContactDistanceReward(env: EnvBase, options: _TermOptionsT)
Bases: _MotionContactTermBase
Exp-kernel reward on per-link contact-point distance in the object frame.
ConTrack's contact-point distance reward (contact_distance_reward):
for each link in joint contact (demo AND sim), the simulated contact point
is expressed in the CURRENT object frame and the demo point in the DEMO
object frame (dual anchor — the comparison measures where on the object
the link touches, decoupled from object tracking error), then scored with
exp(-d² / std²) and averaged over jointly-contacting links. Returns 0
when no link is jointly in contact.