diff --git a/docs/source/unitree_g1.mdx b/docs/source/unitree_g1.mdx index a7a25c73b..69965a561 100644 --- a/docs/source/unitree_g1.mdx +++ b/docs/source/unitree_g1.mdx @@ -274,7 +274,8 @@ python src/lerobot/scripts/lerobot_train.py \ Once trained, we recommend deploying policies using inference-time RTC: ```bash -python examples/rtc/eval_with_real_robot.py \ +lerobot-rollout \ + --strategy.type=base \ --policy.path=your-username/your-repo-id \ --policy.device=cuda \ --robot.type=unitree_g1 \ diff --git a/src/lerobot/rollout/configs.py b/src/lerobot/rollout/configs.py index 46f46eae1..d1527dc08 100644 --- a/src/lerobot/rollout/configs.py +++ b/src/lerobot/rollout/configs.py @@ -142,7 +142,9 @@ class DAggerStrategyConfig(RolloutStrategyConfig): windows, where each correction becomes its own episode. """ - num_episodes: int = 10 + # Number of correction episodes to collect (corrections-only mode). + # When None, falls back to ``--dataset.num_episodes``. + num_episodes: int | None = None record_autonomous: bool = False upload_every_n_episodes: int = 5 # Target video file size in MB for episode rotation (record_autonomous @@ -258,6 +260,19 @@ class RolloutConfig: "--dataset.streaming_encoding=true --dataset.encoder_threads=2" ) + # DAgger: resolve num_episodes from dataset config when not explicitly set. + if isinstance(self.strategy, DAggerStrategyConfig) and self.strategy.num_episodes is None: + if self.dataset is not None: + self.strategy.num_episodes = self.dataset.num_episodes + logger.info( + "DAgger num_episodes not set — using --dataset.num_episodes=%d", + self.strategy.num_episodes, + ) + else: + raise ValueError( + "DAgger num_episodes must be set either via --strategy.num_episodes or --dataset.num_episodes" + ) + # --- Policy loading --- if self.robot is None: raise ValueError("--robot.type is required for rollout") diff --git a/tests/policies/rtc/test_rtc_relative_actions.py b/tests/policies/rtc/test_rtc_relative_actions.py index fa888ec05..14c115764 100644 --- a/tests/policies/rtc/test_rtc_relative_actions.py +++ b/tests/policies/rtc/test_rtc_relative_actions.py @@ -187,7 +187,7 @@ class TestRTCDenoiseWithRelativeLeftovers: class TestFullPipelineRelativeRTC: - """End-to-end test of the RTC + relative actions pipeline matching eval_with_real_robot.py flow.""" + """End-to-end test of the RTC + relative actions pipeline matching lerobot-rollout flow.""" def test_preprocessor_caches_state_for_postprocessor(self): """Preprocessor's relative step should cache state so postprocessor can convert back.""" @@ -240,7 +240,7 @@ class TestFullPipelineRelativeRTC: torch.testing.assert_close(recovered, actions, atol=1e-5, rtol=1e-5) def test_eval_loop_simulation(self): - """Simulate the eval_with_real_robot.py loop with relative actions. + """Simulate the lerobot-rollout loop with relative actions. Iteration 1: No leftovers → model generates relative actions → store for RTC Iteration 2: Use leftovers as RTC guidance → model generates new relative actions @@ -401,12 +401,12 @@ class TestStateRebasingApproximation: def _detect_relative_actions(preprocessor) -> bool: - """Mirror of the helper in eval_with_real_robot.py for testing without importing it.""" + """Mirror of the helper in lerobot-rollout for testing without importing it.""" return any(isinstance(step, RelativeActionsProcessorStep) and step.enabled for step in preprocessor.steps) class TestDetectRelativeActions: - """Test the _detect_relative_actions helper logic used by eval_with_real_robot.py.""" + """Test the _detect_relative_actions helper logic used by lerobot-rollout.""" def test_detects_enabled_relative_step(self): class FakePipeline: