mirror of
https://github.com/huggingface/lerobot.git
synced 2026-07-27 19:56:09 +00:00
feat(rollout): add smooth_handover flag to DAgger strategy config
The DAgger phase transitions run blocking smooth handovers: on pause the leader is driven to the follower (~2 s), and on correction start the follower is slid to the teleop pose (~1 s), both inside the record loop. For clutch-style teleoperators (e.g. VR controllers) that re-reference their command frame at the current robot pose on engage, the handover is already continuous — the interpolation only delays the start of the correction and eats its first frames. Add --strategy.smooth_handover (default true, existing behavior unchanged) to let such setups skip it, mirroring the episodic strategy's smooth_leader_to_follower_handover flag. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
committed by
Maxime Ellerbach
parent
0d383d09f2
commit
124d03608c
@@ -155,6 +155,7 @@ Foot pedal input is also supported via `--strategy.input_device=pedal`. Configur
|
||||
| `--strategy.record_autonomous` | Record autonomous frames too (default: false) |
|
||||
| `--strategy.upload_every_n_episodes` | Push to Hub every N episodes (default: 5) |
|
||||
| `--strategy.input_device` | Input device: `keyboard` or `pedal` (default: keyboard) |
|
||||
| `--strategy.smooth_handover` | Smoothly hand control over at pause / correction start (default: true). Disable for clutch-style teleops that re-reference at the current robot pose on engage |
|
||||
| `--teleop.type` | **Required.** Teleoperator type |
|
||||
|
||||
### Episodic (`--strategy.type=episodic`)
|
||||
|
||||
@@ -180,6 +180,14 @@ class DAggerStrategyConfig(RolloutStrategyConfig):
|
||||
# Target video file size in MB for episode rotation (record_autonomous
|
||||
# mode only). Defaults to DEFAULT_VIDEO_FILE_SIZE_IN_MB when None.
|
||||
target_video_file_size_mb: int | None = None
|
||||
# Whether to turn on or off the smooth handover behavior at phase transitions:
|
||||
# the leader is driven to the follower position on pause (teleops with
|
||||
# `send_feedback` capability), and the follower is slid to the teleop pose when
|
||||
# a correction starts (non-actuated teleops). Disable for clutch-style
|
||||
# teleoperators (e.g. VR controllers) that re-reference at the current robot
|
||||
# pose on engage: the handover is already continuous there, and the blocking
|
||||
# interpolation only delays the start of the correction.
|
||||
smooth_handover: bool = True
|
||||
input_device: str = "keyboard"
|
||||
keyboard: DAggerKeyboardConfig = field(default_factory=DAggerKeyboardConfig)
|
||||
pedal: DAggerPedalConfig = field(default_factory=DAggerPedalConfig)
|
||||
|
||||
@@ -623,8 +623,8 @@ class DAggerStrategy(RolloutStrategy):
|
||||
# State-machine transition side-effects
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
@staticmethod
|
||||
def _apply_transition(
|
||||
self,
|
||||
old_phase: DAggerPhase,
|
||||
new_phase: DAggerPhase,
|
||||
engine,
|
||||
@@ -634,6 +634,10 @@ class DAggerStrategy(RolloutStrategy):
|
||||
) -> None:
|
||||
"""Execute side-effects for a validated phase transition, including smooth handovers.
|
||||
|
||||
The smooth handovers below can be disabled with
|
||||
``--strategy.smooth_handover=false`` (useful for clutch-style teleops
|
||||
that re-reference at the current robot pose on engage).
|
||||
|
||||
AUTONOMOUS -> PAUSED (actuated teleop):
|
||||
Pause the engine, then drive the leader arm to the follower's last
|
||||
commanded position so the operator takes over without a jerk.
|
||||
@@ -657,7 +661,7 @@ class DAggerStrategy(RolloutStrategy):
|
||||
logger.info("Pausing engine - robot holds position")
|
||||
engine.pause()
|
||||
|
||||
if teleop_supports_feedback(teleop) and prev_action is not None:
|
||||
if self.config.smooth_handover and teleop_supports_feedback(teleop) and prev_action is not None:
|
||||
# TODO(Maxime): prev_action is in robot action key space (output of robot_action_processor).
|
||||
# send_feedback expects teleop feedback key space. For homogeneous setups (e.g. SO-101
|
||||
# leader + SO-101 follower) the keys are identical so this works. If the processor pipeline
|
||||
@@ -668,7 +672,11 @@ class DAggerStrategy(RolloutStrategy):
|
||||
|
||||
elif old_phase == DAggerPhase.PAUSED and new_phase == DAggerPhase.CORRECTING:
|
||||
logger.info("Entering correction mode - human teleop control")
|
||||
if not teleop_supports_feedback(teleop) and prev_action is not None:
|
||||
if (
|
||||
self.config.smooth_handover
|
||||
and not teleop_supports_feedback(teleop)
|
||||
and prev_action is not None
|
||||
):
|
||||
logger.info("Smooth handover: sliding follower to teleop position")
|
||||
obs = robot.get_observation()
|
||||
teleop_action = teleop.get_action()
|
||||
|
||||
Reference in New Issue
Block a user