Source code for wbc_mjlab.presets.end_effector

"""Actor overlay: keybody pose refs instead of joint references.

Compose on top of ``apply_wbc``. Does **not** reweight rewards, RSI, or
terminations. Actor drops ``ref_joint_*`` and uses ``ref_body_pos`` /
``ref_body_ori`` (optionally restricted to a body subset, e.g. end-effectors).
Critic keeps joint refs and full keybody refs. Actions leave the motion joint
residual so deploy does not need ``q_ref``.
"""

from __future__ import annotations

from mjlab.envs import ManagerBasedRlEnvCfg
from mjlab.managers.observation_manager import ObservationTermCfg
from mjlab.utils.noise import UniformNoiseCfg as Unoise

from wbc_mjlab.env.mdp.actions import DefaultOffsetJointPositionActionCfg
from wbc_mjlab.env.mdp.observations import ref_body_ori_b, ref_body_pos_b

_MOTION = "motion"


[docs] def apply_end_effector( cfg: ManagerBasedRlEnvCfg, *, body_names: tuple[str, ...] | None = None, ) -> None: """Swap actor joint-reference command for keybody pose refs. Leaves rewards, RSI, and terminations untouched. Critic keeps ``ref_joint_pos`` and full ``ref_body_*``. Args: body_names: Bodies included in actor ``ref_body_pos`` / ``ref_body_ori``. ``None`` uses all motion-command bodies. Pass end-effector names to restrict the actor command to EEs only. """ params: dict = {"command_name": _MOTION} if body_names is not None: params["body_names"] = body_names actor = cfg.observations["actor"] actor.terms.pop("ref_joint_pos", None) actor.terms.pop("ref_joint_vel", None) actor.terms.update( { "ref_body_pos": ObservationTermCfg( func=ref_body_pos_b, params=params, noise=Unoise(n_min=-0.05, n_max=0.05), ), "ref_body_ori": ObservationTermCfg( func=ref_body_ori_b, params=params, noise=Unoise(n_min=-0.02, n_max=0.02), ), } ) old = cfg.actions["joint_pos"] cfg.actions["joint_pos"] = DefaultOffsetJointPositionActionCfg( entity_name=getattr(old, "entity_name", "robot"), actuator_names=getattr(old, "actuator_names", (".*",)), scale=old.scale, use_default_offset=True, command_name=_MOTION, )