Source code for wbc_mjlab.env.mdp.actions

"""Tracking-specific action terms."""

from __future__ import annotations

from dataclasses import dataclass
from typing import TYPE_CHECKING

from mjlab.actuator.actuator import TransmissionType
from mjlab.envs.mdp.actions.actions import BaseAction, BaseActionCfg
from mjlab.managers.action_manager import ActionTermCfg

from wbc_mjlab.env.mdp.commands import MotionCommand

if TYPE_CHECKING:
  from mjlab.envs import ManagerBasedRlEnv


[docs] @dataclass(kw_only=True) class ReferenceJointPositionActionCfg(BaseActionCfg): """Joint position targets as motion reference plus scaled residual actions. Implements Zest-style control: q_cmd = q_ref + scale * a_t (minus encoder bias). """ command_name: str = "motion" def __post_init__(self): self.transmission_type = TransmissionType.JOINT if self.offset != 0.0: raise ValueError( "ReferenceJointPositionActionCfg does not support 'offset'. " "Reference joint positions come from the motion command." )
[docs] def build(self, env: ManagerBasedRlEnv) -> ReferenceJointPositionAction: return ReferenceJointPositionAction(self, env)
[docs] class ReferenceJointPositionAction(BaseAction): """Control joints via position targets relative to the motion reference.""" cfg: ReferenceJointPositionActionCfg _command: MotionCommand def __init__(self, cfg: ReferenceJointPositionActionCfg, env: ManagerBasedRlEnv): super().__init__(cfg=cfg, env=env) command = env.command_manager.get_term(cfg.command_name) if not isinstance(command, MotionCommand): raise TypeError( f"ReferenceJointPositionAction requires MotionCommand, " f"got {type(command).__name__} for '{cfg.command_name}'." ) self._command = command
[docs] def apply_actions(self) -> None: ref_joint_pos = self._command.tracked_joint_pos encoder_bias = self._entity.data.encoder_bias[:, self._target_ids] target = ref_joint_pos + self._processed_actions - encoder_bias self._entity.set_joint_position_target(target, joint_ids=self._target_ids)