Skip to content

Add energy rewards and MujocoStyleActuatorCfg (closes S4) - #179

Merged
KraHsu merged 2 commits into
dev/bump-genesis-1.0from
feat/genesis-1.0-s4-actuator-and-energy
May 29, 2026
Merged

KraHsu merged 2 commits into
dev/bump-genesis-1.0from
feat/genesis-1.0-s4-actuator-and-energy

Conversation

@KraHsu

@KraHsu KraHsu commented May 29, 2026 •

Copy link
Copy Markdown
Owner

Summary

Phase S4 of the Genesis 1.0 migration (ADR-0001). Ships the two S4
sub-tasks that have a clean v1.0 implementation: the energy rewards and
a Mujoco-style actuator cfg helper. The remaining two boxes
(SimulationCfg.actuator_model selector, zero-copy writer refactor)
are explicitly closed as not applicable on v1.0 — see the drift
table below.

Changes

Energy rewards

  • src/genelab/mdp/rewards/energy.py — three new reward primitives
    wrapping Genesis 1.0's per-entity energy accessors:
    • kinetic_energy_l2(env, asset_cfg=None) — T² per env, non-negative.
    • potential_energy(env, asset_cfg=None) — signed potential energy.
    • energy_budget(env, target_total=0.0, asset_cfg=None) — squared
      deviation of total mechanical energy from a target.
  • tests/test_mdp_rewards_energy.py — synthetic _FakeGsHandle
    exercises every reward path (4 tests).

Mujoco-style actuator cfg

  • src/genelab/actuator/mujoco_style.py — MujocoStyleActuatorCfg
    accepts Mujoco's (gear, bias_prm, dyntype="none", gaintype="fixed", biastype="affine") shape and translates it into
    (stiffness=-gear*bias_prm[1], damping=-gear*bias_prm[2]) on top of
    IdealPDActuator. Every other dyntype / gaintype / biastype
    combination raises with the same wording Genesis's own MJCF parser
    uses; non-zero bias_prm[0] also raises because IdealPDActuator
    has no constant-offset force term.
  • Registered in src/genelab/actuator/__init__.py.
  • tests/test_mujoco_style_actuator.py — 8 cfg-translation tests
    (sign convention, every rejection path, pass-through fields).
  • docs/concepts/actuators.{en,zh}.md — new "MJCF-style actuator
    configuration" section + table-row pointer at the top.

Shared

  • CHANGELOG.md — ### Added entries for both the energy rewards
    and the actuator cfg.

v1.0 drift on the closed S4 sub-tasks

Probing real Genesis 1.0 surfaced that two of the four S4 ADR
sub-tasks don't apply as the ADR scoped them, even after this PR:

ADR sub-task v1.0 reality This PR closes it as
New mujoco_general.py runtime actuator class No runtime "general actuator" class in v1.0. dyntype/gaintype/biastype only appear in genesis/utils/mjcf.py as XML-parse-time concepts; the parser already translates them into the existing setters at load time. There's no separate Genesis class to wrap. Reinterpreted as MujocoStyleActuatorCfg — a thin Python-side cfg helper that mirrors the same translation MJCF does, so robots configured in Python rather than from an MJCF can use the same named knobs.
SimulationCfg.actuator_model selector Becomes meaningful only if a new actuator runtime type lands. Without one, the existing ArticulationCfg.actuators field already routes per-joint actuator selection. Closed as n/a. MujocoStyleActuatorCfg slots into the same ArticulationCfg.actuators dict as every other actuator cfg; no new selector needed.
Zero-copy set_pos / set_quat in _articulation_writer.py The writer already calls Genesis setters directly with no copies on the hot path (S1 dropped the historical try/except envs_idx fallback). Remaining .contiguous() / .clone() in reset() exist for semantic reasons (Genesis expects contiguous; clone breaks aliasing with _joint_pos_target). Closed as "no work to do on v1.0". Recommend re-opening only if a profiler under high reset frequency surfaces these as a hot path.
Comparison reference run dc_motor vs mujoco_general Hinged on the runtime general-actuator class that v1.0 doesn't have. With the cfg-helper interpretation, MujocoStyleActuatorCfg produces an IdealPDActuator — the same runtime the comparison would have been against. Closed as redundant. A dc_motor vs MujocoStyleActuatorCfg → IdealPDActuator comparison is dc_motor vs IdealPDActuator, which is well-trodden ground in the locomotion best-practices guide.

Drift findings recorded in saved memory
genesis-1.0-migration/s4-api-drift for future phases / the
promotion-PR discussion.

Test plan

  • ruff check
  • ruff format --check
  • pyright — 0 errors, 0 warnings
  • pytest — 598 passed (+12: 4 energy + 8 mujoco-style), 0 failed
  • mkdocs build --strict

Risks

  • MujocoStyleActuatorCfg is stricter than the underlying MJCF
    shape.
    A non-zero bias_prm[0] raises rather than approximating
    the constant offset as a static torque. Genesis's parser logs a
    warning for the same shape; this cfg promotes that warning to a
    hard error so the user knows the cfg isn't faithful to the MJCF.
  • Energy semantics depend on the world-frame z = 0 convention.
    Rewards that want base-height tracking should still prefer
    base_height_l2. Documented in the per-function docstring.

Notes

  • ADR-0001 Phase S4 sub-task table updated: actuator + energy boxes
    ticked; actuator_model selector and zero-copy refactor closed as
    n/a-on-v1.0 with the rationale in the row footers. Comparison
    reference-run box closed as redundant given the cfg-helper
    reinterpretation. After this merges, S5 is the only remaining
    phase
    before the dev/bump-genesis-1.0 → main promotion PR.

KraHsu added 2 commits May 29, 2026 13:27
Wraps Genesis 1.0's per-entity energy accessors —
``Articulation.gs_handle.{get_kinetic_energy, get_potential_energy,
get_total_energy}`` — into three reward terms that follow the same
``(env, asset_cfg=None)`` calling convention as the existing
``mdp.rewards`` primitives:

- ``kinetic_energy_l2`` returns ``T²`` per env. Non-negative; pair with
  a negative weight to discourage high-energy motion.
- ``potential_energy`` returns the signed potential energy directly.
  Genesis follows the conventional sign (negative below z = 0); pair
  with the weight that matches the task intent.
- ``energy_budget(target_total=0.0)`` returns ``(total − target)²`` per
  env. Non-negative; pair with a negative weight to keep the
  articulation's total mechanical energy near a target.

The energy methods on every Genesis entity (validated via a real-scene
probe on ``gs.Scene + add_entity + build``) return ``(num_envs,)``
tensors; the wrappers stay shape-preserving and let the reward manager
apply weights / combine with other terms downstream.

Tests use a synthetic ``_FakeGsHandle`` exposing only the three energy
methods — same shape as the existing mdp-reward fakes; no real-Genesis
integration needed because the call surface is a single method per
function and the Genesis-side return shape was already validated by
the probe.
A convenience cfg for actuators whose parameters live in Mujoco's
``(gear, gain_prm, bias_prm)`` form. Only the canonical
``dyntype=none / gaintype=fixed / biastype=affine`` shape is supported
(every other combination raises with the same wording Genesis's own
MJCF parser uses when logging warnings) and ``bias_prm[0]`` must be
zero (``IdealPDActuator`` has no constant-offset force term).

Translation:

  kp = -gear * bias_prm[1]
  kv = -gear * bias_prm[2]

The result is a plain ``IdealPDActuatorCfg`` with ``class_type =
IdealPDActuator``, so the cfg integrates with the existing actuator
registry, DR hooks, and tests without new runtime code.

Genesis 1.0 has no separate "general actuator" runtime — the MJCF
parser at ``genesis/utils/mjcf.py`` translates the same Mujoco
attributes into ``set_dofs_kp`` / ``set_dofs_kv`` /
``set_dofs_force_range`` at load time. This cfg is the GeneLab-side
mirror: same named knobs for tasks that configure actuators in Python
rather than loading from an MJCF.

Docs: a new section on ``docs/concepts/actuators.{en,zh}.md`` covers
the translation table and a worked example. CHANGELOG ``### Added``.
@KraHsu KraHsu changed the title Add energy reward primitives (kinetic / potential / budget) Add energy rewards and MujocoStyleActuatorCfg (closes S4) May 29, 2026
@KraHsu
KraHsu merged commit 1439bed into dev/bump-genesis-1.0 May 29, 2026
3 checks passed
@KraHsu
KraHsu deleted the feat/genesis-1.0-s4-actuator-and-energy branch May 29, 2026 05:40
KraHsu added a commit that referenced this pull request Jun 5, 2026
…energy

Add energy rewards and MujocoStyleActuatorCfg (closes S4)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant