diff --git a/lerobot/common/datasets/utils.py b/lerobot/common/datasets/utils.py index ef97231df..d6aef15f5 100644 --- a/lerobot/common/datasets/utils.py +++ b/lerobot/common/datasets/utils.py @@ -32,7 +32,7 @@ DATASET_CARD_TEMPLATE = """ --- # Metadata will go there --- -This dataset was created using [🤗 LeRobot](https://github.com/huggingface/lerobot). +This dataset was created using [LeRobot](https://github.com/huggingface/lerobot). """ diff --git a/lerobot/common/envs/utils.py b/lerobot/common/envs/utils.py index 32da00620..001973bc1 100644 --- a/lerobot/common/envs/utils.py +++ b/lerobot/common/envs/utils.py @@ -39,7 +39,7 @@ def preprocess_observation(observations: dict[str, np.ndarray]) -> dict[str, Ten # sanity check that images are channel last _, h, w, c = img.shape - assert c < h and c < w, f"expect channel first images, but instead {img.shape}" + assert c < h and c < w, f"expect channel last images, but instead got {img.shape=}" # sanity check that images are uint8 assert img.dtype == torch.uint8, f"expect torch.uint8, but instead {img.dtype=}" diff --git a/lerobot/configs/default.yaml b/lerobot/configs/default.yaml index 7945513ae..a3ff1d41b 100644 --- a/lerobot/configs/default.yaml +++ b/lerobot/configs/default.yaml @@ -120,7 +120,7 @@ eval: # `batch_size` specifies the number of environments to use in a gym.vector.VectorEnv. batch_size: 1 # `use_async_envs` specifies whether to use asynchronous environments (multiprocessing). - use_async_envs: true + use_async_envs: false wandb: enable: false diff --git a/lerobot/configs/env/aloha.yaml b/lerobot/configs/env/aloha.yaml index 6ea3cceda..296a4481c 100644 --- a/lerobot/configs/env/aloha.yaml +++ b/lerobot/configs/env/aloha.yaml @@ -2,11 +2,6 @@ fps: 50 -eval: - # `use_async_envs` specifies whether to use asynchronous environments (multiprocessing). - # set it to false to avoid some problems of the aloha env - use_async_envs: false - env: name: aloha task: AlohaInsertion-v0 diff --git a/lerobot/configs/env/xarm.yaml b/lerobot/configs/env/xarm.yaml index 8e3d9c51c..4320379ae 100644 --- a/lerobot/configs/env/xarm.yaml +++ b/lerobot/configs/env/xarm.yaml @@ -2,11 +2,6 @@ fps: 15 -eval: - # `use_async_envs` specifies whether to use asynchronous environments (multiprocessing). - # set it to false to avoid some problems of the aloha env - use_async_envs: false - env: name: xarm task: XarmLift-v0 diff --git a/lerobot/scripts/control_robot.py b/lerobot/scripts/control_robot.py index ea47e05b2..a6506a3fe 100644 --- a/lerobot/scripts/control_robot.py +++ b/lerobot/scripts/control_robot.py @@ -179,13 +179,18 @@ def none_or_int(value): def log_control_info(robot, dt_s, episode_index=None, frame_index=None, fps=None): log_items = [] if episode_index is not None: - log_items += [f"ep:{episode_index}"] + log_items.append(f"ep:{episode_index}") if frame_index is not None: - log_items += [f"frame:{frame_index}"] + log_items.append(f"frame:{frame_index}") def log_dt(shortname, dt_val_s): - nonlocal log_items - log_items += [f"{shortname}:{dt_val_s * 1000:5.2f} ({1/ dt_val_s:3.1f}hz)"] + nonlocal log_items, fps + info_str = f"{shortname}:{dt_val_s * 1000:5.2f} ({1/ dt_val_s:3.1f}hz)" + if fps is not None: + actual_fps = 1 / dt_val_s + if actual_fps < fps - 1: + info_str = colored(info_str, "yellow") + log_items.append(info_str) # total step time displayed in milliseconds and its frequency log_dt("dt", dt_s) @@ -210,10 +215,6 @@ def log_control_info(robot, dt_s, episode_index=None, frame_index=None, fps=None log_dt(f"dtR{name}", robot.logs[key]) info_str = " ".join(log_items) - if fps is not None: - actual_fps = 1 / dt_s - if actual_fps < fps - 1: - info_str = colored(info_str, "yellow") logging.info(info_str) @@ -320,7 +321,7 @@ def record( run_compute_stats=True, push_to_hub=True, tags=None, - num_image_writers=8, + num_image_writers_per_camera=4, force_override=False, ): # TODO(rcadene): Add option to record logs @@ -442,8 +443,8 @@ def record( # Save images using threads to reach high fps (30 and more) # Using `with` to exist smoothly if an execption is raised. - # Using only 4 worker threads to avoid blocking the main thread. futures = [] + num_image_writers = num_image_writers_per_camera * len(robot.cameras) with concurrent.futures.ThreadPoolExecutor(max_workers=num_image_writers) as executor: # Start recording all episodes while episode_index < num_episodes: @@ -803,10 +804,14 @@ if __name__ == "__main__": help="Add tags to your dataset on the hub.", ) parser_record.add_argument( - "--num-image-writers", + "--num-image-writers-per-camera", type=int, - default=8, - help="Number of threads writing the frames as png images on disk. Don't set too much as you might get unstable fps due to main thread being blocked.", + default=4, + help=( + "Number of threads writing the frames as png images on disk, per camera. " + "Too much threads might cause unstable teleoperation fps due to main thread being blocked. " + "Not enough threads might cause low camera fps." + ), ) parser_record.add_argument( "--force-override", diff --git a/lerobot/scripts/eval.py b/lerobot/scripts/eval.py index 482af786f..0aec84720 100644 --- a/lerobot/scripts/eval.py +++ b/lerobot/scripts/eval.py @@ -57,7 +57,7 @@ import gymnasium as gym import numpy as np import torch from huggingface_hub import snapshot_download -from huggingface_hub.utils._errors import RepositoryNotFoundError +from huggingface_hub.errors import RepositoryNotFoundError from huggingface_hub.utils._validators import HFValidationError from torch import Tensor, nn from tqdm import trange diff --git a/lerobot/templates/visualize_dataset_template.html b/lerobot/templates/visualize_dataset_template.html index 0a49fd5b6..4f0bd343e 100644 --- a/lerobot/templates/visualize_dataset_template.html +++ b/lerobot/templates/visualize_dataset_template.html @@ -82,13 +82,22 @@ Episode {{ episode_id }} + + +
-

Videos could NOT play because AV1 decoding is not available on your browser. Learn more about LeRobot video encoding.

{% for video_info in videos_info %}

{{ video_info.filename }}

-