test dagger

This commit is contained in:
Steven Palma
2026-04-17 16:46:38 +02:00
parent 35bb2c7459
commit a76874f35e
3 changed files with 35 additions and 19 deletions
+2 -2
View File
@@ -96,8 +96,8 @@ class DAggerKeyboardConfig:
""" """
pause_resume: str = "space" pause_resume: str = "space"
correction: str = "c" correction: str = "tab"
upload: str = "h" upload: str = "enter"
@dataclass @dataclass
+11 -9
View File
@@ -236,15 +236,17 @@ def build_rollout_context(
# DAgger requires teleop with motor control capabilities (enable_torque, # DAgger requires teleop with motor control capabilities (enable_torque,
# disable_torque, write_goal_positions). # disable_torque, write_goal_positions).
if isinstance(cfg.strategy, DAggerStrategyConfig) and teleop is not None: # TODO(Steven): either enforce this (meaning all teleop must implement these methods) or
required_teleop_methods = ("enable_torque", "disable_torque", "write_goal_positions") # user is responsible for moving the teleop to the same position as the robot when starting the correction.
missing = [m for m in required_teleop_methods if not callable(getattr(teleop, m, None))] # if isinstance(cfg.strategy, DAggerStrategyConfig) and teleop is not None:
if missing: # required_teleop_methods = ("enable_torque", "disable_torque", "write_goal_positions")
teleop.disconnect() # missing = [m for m in required_teleop_methods if not callable(getattr(teleop, m, None))]
raise ValueError( # if missing:
f"DAgger strategy requires a teleoperator with motor control methods " # teleop.disconnect()
f"{required_teleop_methods}. '{type(teleop).__name__}' is missing: {missing}" # raise ValueError(
) # f"DAgger strategy requires a teleoperator with motor control methods "
# f"{required_teleop_methods}. '{type(teleop).__name__}' is missing: {missing}"
# )
# --- 4. Features + action-key reconciliation --------------------- # --- 4. Features + action-key reconciliation ---------------------
all_obs_features = robot.observation_features all_obs_features = robot.observation_features
+22 -8
View File
@@ -165,7 +165,8 @@ class DAggerEvents:
# Teleoperator helpers # Teleoperator helpers
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# TODO(Steven): either enforce this (meaning all teleop must implement these methods) or
# user is responsible for moving the teleop to the same position as the robot when starting the correction.
def _teleop_smooth_move_to( def _teleop_smooth_move_to(
teleop: Teleoperator, target_pos: dict, duration_s: float = 2.0, fps: int = 50 teleop: Teleoperator, target_pos: dict, duration_s: float = 2.0, fps: int = 50
) -> None: ) -> None:
@@ -375,7 +376,9 @@ class DAggerStrategy(RolloutStrategy):
engine.reset() engine.reset()
interpolator.reset() interpolator.reset()
events.reset() events.reset()
teleop.disable_torque() # TODO(Steven): either enforce this (meaning all teleop must implement these methods) or
# user is responsible for moving the teleop to the same position as the robot when starting the correction.
# teleop.disable_torque()
engine.resume() engine.resume()
last_action: dict[str, Any] | None = None last_action: dict[str, Any] | None = None
@@ -469,7 +472,9 @@ class DAggerStrategy(RolloutStrategy):
finally: finally:
engine.pause() engine.pause()
teleop.disable_torque() # TODO(Steven): either enforce this (meaning all teleop must implement these methods) or
# user is responsible for moving the teleop to the same position as the robot when starting the correction.
# teleop.disable_torque()
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
with self._episode_lock: with self._episode_lock:
dataset.save_episode() dataset.save_episode()
@@ -503,7 +508,9 @@ class DAggerStrategy(RolloutStrategy):
engine.reset() engine.reset()
interpolator.reset() interpolator.reset()
events.reset() events.reset()
teleop.disable_torque() # TODO(Steven): either enforce this (meaning all teleop must implement these methods) or
# user is responsible for moving the teleop to the same position as the robot when starting the correction.
# teleop.disable_torque()
engine.resume() engine.resume()
last_action: dict[str, Any] | None = None last_action: dict[str, Any] | None = None
@@ -586,7 +593,9 @@ class DAggerStrategy(RolloutStrategy):
finally: finally:
engine.pause() engine.pause()
teleop.disable_torque() # TODO(Steven): either enforce this (meaning all teleop must implement these methods) or
# user is responsible for moving the teleop to the same position as the robot when starting the correction.
# teleop.disable_torque()
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
with self._episode_lock: with self._episode_lock:
dataset.save_episode() dataset.save_episode()
@@ -609,13 +618,18 @@ class DAggerStrategy(RolloutStrategy):
if old_phase == DAggerPhase.AUTONOMOUS and new_phase == DAggerPhase.PAUSED: if old_phase == DAggerPhase.AUTONOMOUS and new_phase == DAggerPhase.PAUSED:
engine.pause() engine.pause()
obs = robot.get_observation() obs = robot.get_observation()
robot_pos = { _robot_pos = {
k: v for k, v in obs.items() if k.endswith(".pos") and k in robot.observation_features k: v for k, v in obs.items() if k.endswith(".pos") and k in robot.observation_features
} }
_teleop_smooth_move_to(teleop, robot_pos, duration_s=2.0, fps=50) # TODO(Steven): either enforce this (meaning all teleop must implement these methods) or
# user is responsible for moving the teleop to the same position as the robot when starting the correction.
# _teleop_smooth_move_to(teleop, robot_pos, duration_s=2.0, fps=50)
elif new_phase == DAggerPhase.CORRECTING: elif new_phase == DAggerPhase.CORRECTING:
teleop.disable_torque() # TODO(Steven): either enforce this (meaning all teleop must implement these methods) or
# user is responsible for moving the teleop to the same position as the robot when starting the correction.
# teleop.disable_torque()
pass
elif new_phase == DAggerPhase.AUTONOMOUS: elif new_phase == DAggerPhase.AUTONOMOUS:
interpolator.reset() interpolator.reset()