mirror of
https://github.com/huggingface/lerobot.git
synced 2026-07-24 18:26:11 +00:00
fix(envs): set LiberoEnvConfig.fps default to 20 to match robosuite (#4124)
* fix(envs): set LiberoEnvConfig.fps default to 20 to match robosuite LiberoEnvConfig.fps was set to 30, but the underlying robosuite OffScreenRenderEnv always runs at its default control_freq of 20 Hz since fps is never passed through. This mismatch silently decouples the dataset/eval loop rate from the actual simulation step rate. Set the default to 20 to match the real sim rate and avoid the footgun. Fixes #3368 * fix(libero): apply configured control frequency --------- Co-authored-by: xinmotlanthua <275663218+xinmotlanthua@users.noreply.github.com>
This commit is contained in:
@@ -322,7 +322,7 @@ class HILSerlRobotEnvConfig(EnvConfig):
|
|||||||
class LiberoEnv(EnvConfig):
|
class LiberoEnv(EnvConfig):
|
||||||
task: str = "libero_10" # can also choose libero_spatial, libero_object, etc.
|
task: str = "libero_10" # can also choose libero_spatial, libero_object, etc.
|
||||||
task_ids: list[int] | None = None
|
task_ids: list[int] | None = None
|
||||||
fps: int = 30
|
fps: int = 20 # Must match robosuite's default control_freq (20 Hz)
|
||||||
episode_length: int | None = None
|
episode_length: int | None = None
|
||||||
obs_type: str = "pixels_agent_pos"
|
obs_type: str = "pixels_agent_pos"
|
||||||
render_mode: str = "rgb_array"
|
render_mode: str = "rgb_array"
|
||||||
@@ -354,6 +354,9 @@ class LiberoEnv(EnvConfig):
|
|||||||
control_mode: str = "relative" # or "absolute"
|
control_mode: str = "relative" # or "absolute"
|
||||||
|
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
|
if self.fps <= 0:
|
||||||
|
raise ValueError(f"fps must be positive, got {self.fps}")
|
||||||
|
|
||||||
if self.obs_type == "pixels":
|
if self.obs_type == "pixels":
|
||||||
self.features[LIBERO_KEY_PIXELS_AGENTVIEW] = PolicyFeature(
|
self.features[LIBERO_KEY_PIXELS_AGENTVIEW] = PolicyFeature(
|
||||||
type=FeatureType.VISUAL, shape=(self.observation_height, self.observation_width, 3)
|
type=FeatureType.VISUAL, shape=(self.observation_height, self.observation_width, 3)
|
||||||
@@ -412,6 +415,7 @@ class LiberoEnv(EnvConfig):
|
|||||||
"render_mode": self.render_mode,
|
"render_mode": self.render_mode,
|
||||||
"observation_height": self.observation_height,
|
"observation_height": self.observation_height,
|
||||||
"observation_width": self.observation_width,
|
"observation_width": self.observation_width,
|
||||||
|
"control_freq": self.fps,
|
||||||
}
|
}
|
||||||
if self.task_ids is not None:
|
if self.task_ids is not None:
|
||||||
kwargs["task_ids"] = self.task_ids
|
kwargs["task_ids"] = self.task_ids
|
||||||
|
|||||||
@@ -125,10 +125,13 @@ class LiberoEnv(gym.Env):
|
|||||||
n_envs: int = 1,
|
n_envs: int = 1,
|
||||||
camera_name_mapping: dict[str, str] | None = None,
|
camera_name_mapping: dict[str, str] | None = None,
|
||||||
num_steps_wait: int = 10,
|
num_steps_wait: int = 10,
|
||||||
|
control_freq: int = 20,
|
||||||
control_mode: str = "relative",
|
control_mode: str = "relative",
|
||||||
is_libero_plus: bool = False,
|
is_libero_plus: bool = False,
|
||||||
):
|
):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
if control_freq <= 0:
|
||||||
|
raise ValueError(f"control_freq must be positive, got {control_freq}")
|
||||||
self.task_id = task_id
|
self.task_id = task_id
|
||||||
self.is_libero_plus = is_libero_plus
|
self.is_libero_plus = is_libero_plus
|
||||||
self.obs_type = obs_type
|
self.obs_type = obs_type
|
||||||
@@ -154,6 +157,7 @@ class LiberoEnv(gym.Env):
|
|||||||
}
|
}
|
||||||
self.camera_name_mapping = camera_name_mapping
|
self.camera_name_mapping = camera_name_mapping
|
||||||
self.num_steps_wait = num_steps_wait
|
self.num_steps_wait = num_steps_wait
|
||||||
|
self.control_freq = control_freq
|
||||||
self.episode_index = episode_index
|
self.episode_index = episode_index
|
||||||
self.episode_length = episode_length
|
self.episode_length = episode_length
|
||||||
# Load once and keep
|
# Load once and keep
|
||||||
@@ -260,6 +264,7 @@ class LiberoEnv(gym.Env):
|
|||||||
bddl_file_name=self._task_bddl_file,
|
bddl_file_name=self._task_bddl_file,
|
||||||
camera_heights=self.observation_height,
|
camera_heights=self.observation_height,
|
||||||
camera_widths=self.observation_width,
|
camera_widths=self.observation_width,
|
||||||
|
control_freq=self.control_freq,
|
||||||
)
|
)
|
||||||
env.reset()
|
env.reset()
|
||||||
self._env = env
|
self._env = env
|
||||||
|
|||||||
@@ -35,6 +35,17 @@ def test_unknown_type():
|
|||||||
make_env_config("nonexistent")
|
make_env_config("nonexistent")
|
||||||
|
|
||||||
|
|
||||||
|
def test_libero_fps_controls_simulator_frequency():
|
||||||
|
cfg = LiberoEnv(fps=17)
|
||||||
|
|
||||||
|
assert cfg.gym_kwargs["control_freq"] == 17
|
||||||
|
|
||||||
|
|
||||||
|
def test_libero_rejects_nonpositive_fps():
|
||||||
|
with pytest.raises(ValueError, match="fps must be positive"):
|
||||||
|
LiberoEnv(fps=0)
|
||||||
|
|
||||||
|
|
||||||
def test_identity_processors():
|
def test_identity_processors():
|
||||||
"""Base class get_env_processors() returns identity pipelines."""
|
"""Base class get_env_processors() returns identity pipelines."""
|
||||||
cfg = make_env_config("aloha")
|
cfg = make_env_config("aloha")
|
||||||
|
|||||||
Reference in New Issue
Block a user