From 67acccf778aa1e06b3c0f11249ffec3c38eedd33 Mon Sep 17 00:00:00 2001 From: glannuzel Date: Thu, 21 Aug 2025 15:00:53 +0200 Subject: [PATCH] Delete test files --- .../robots/reachy2/data_acquisition_server.py | 439 ------------------ src/lerobot/robots/reachy2/test_policy.py | 116 ----- src/lerobot/robots/reachy2/test_reachy2.py | 60 --- src/lerobot/robots/reachy2/test_recording.py | 104 ----- src/lerobot/robots/reachy2/test_replay.py | 65 --- .../robots/reachy2/test_robot_client.py | 46 -- 6 files changed, 830 deletions(-) delete mode 100644 src/lerobot/robots/reachy2/data_acquisition_server.py delete mode 100644 src/lerobot/robots/reachy2/test_policy.py delete mode 100644 src/lerobot/robots/reachy2/test_reachy2.py delete mode 100644 src/lerobot/robots/reachy2/test_recording.py delete mode 100644 src/lerobot/robots/reachy2/test_replay.py delete mode 100644 src/lerobot/robots/reachy2/test_robot_client.py diff --git a/src/lerobot/robots/reachy2/data_acquisition_server.py b/src/lerobot/robots/reachy2/data_acquisition_server.py deleted file mode 100644 index 61d3567ec..000000000 --- a/src/lerobot/robots/reachy2/data_acquisition_server.py +++ /dev/null @@ -1,439 +0,0 @@ -from pathlib import Path -import json -import os -import shutil - -from concurrent import futures -from typing import Dict -import threading - -import grpc -from logging import getLogger - -import torch.multiprocessing as mp - -from lerobot.datasets.lerobot_dataset import LeRobotDataset -from lerobot.datasets.utils import hw_to_dataset_features -from lerobot.robots.reachy2 import Reachy2Robot, Reachy2RobotConfig -from lerobot.teleoperators.reachy2_fake_teleoperator import Reachy2FakeTeleoperator, Reachy2FakeTeleoperatorConfig -from lerobot.utils.utils import log_say -from lerobot.record import record_loop - -from data_acquisition_api.data_acquisition_pb2 import ( - ActionAck, - EpisodeRating, - SessionParams, - Dataset, - DatasetList, - DatasetPushState, -) -from data_acquisition_api.data_acquisition_pb2_grpc import add_DataAcquisitionServiceServicer_to_server -from google.protobuf.empty_pb2 import Empty - - -class DataAcquisitionServicer(): - def __init__( - self, - ): - self._logger = getLogger(__name__) - self.play_sound = True - - self.thread: threading.Thread = None - self.events: Dict = {} - self.events["exit_early"] = False - - self.setup_over = False - - self.dataset_list_path = Path("datasets.json") - self.robot: Reachy2Robot = None - self.task: str = None - self.dataset: LeRobotDataset = None - - self.fps: int - self.episode_duration: int - self.break_time_duration: int - - self.episode_recording_in_progress: bool = False - self.episode_saved: bool = False - self.episode_recorded_in_session: bool = False - - self.run_compute_stats: bool = True - - def register_to_server(self, server): - add_DataAcquisitionServiceServicer_to_server(self, server) - - def GetDatasetList(self, request: Empty, context: grpc.ServicerContext) -> DatasetList: - dataset_list = self.read_datasets_from_json(self.dataset_list_path) - return dataset_list - - def RemoveDataset(self, request: Dataset, context: grpc.ServicerContext) -> ActionAck: - self.remove_dataset_by_name(request.dataset_name, self.dataset_list_path) - return ActionAck(success_ack=True) - - def AddDataset(self, request: Dataset, context: grpc.ServicerContext) -> ActionAck: - # Create a new dataset - dataset = self.create_dataset(request.dataset_name, DatasetPushState.PUSHED, 0) - # Add it to the JSON file - self.add_dataset_to_json_file(dataset, self.dataset_list_path) - return ActionAck(success_ack=True) - - def UpdateDataset(self, request: Dataset, context: grpc.ServicerContext) -> ActionAck: - self.update_dataset(request, self.dataset_list_path) - return ActionAck(success_ack=True) - - def ClearAllDatasets(self, request: Empty, context: grpc.ServicerContext) -> ActionAck: - # Clear all datasets from the JSON file - self.clear_all_datasets(self.dataset_list_path) - return ActionAck(success_ack=True) - - def RemoveSession(self, request: SessionParams, context: grpc.ServicerContext) -> ActionAck: - self.delete_folder(request.session_name) - return ActionAck(success_ack=True) - - def ClearAllSessions(self, request: Empty, context: grpc.ServicerContext) -> ActionAck: - pass - - # Session and Episode Management with LeRobot - - def StartSession(self, request: SessionParams, context: grpc.ServicerContext) -> ActionAck: - self._logger.error(f"Starting session with params: {request}") - try: - self.setup_recording_session(request, context) - self.setup_over = True - ack = ActionAck(success_ack=True) - except Exception as e: - self._logger.error(f"Error starting session: {e}") - ack = ActionAck(success_ack=False) - return ack - - def StopSession(self, request: Empty, context: grpc.ServicerContext) -> ActionAck: - self._logger.error("Stopping session") - try: - if self.thread and self.thread.is_alive(): - self.thread.join() # Wait for the thread to finish - log_say("Stop recording", play_sounds=self.play_sound, blocking=True) - self.robot.disconnect() - ack = ActionAck(success_ack=True) - self._logger.error("Session stopped") - except Exception as e: - self._logger.error(f"Error stopping session: {e}") - ack = ActionAck(success_ack=False) - return ack - - def StartEpisode(self, request: Empty, context: grpc.ServicerContext) -> ActionAck: - self._logger.error("Starting episode") - try: - if self.episode_recorded_in_session and not self.episode_saved: - self._logger.error("Episode not saved. Clearing episode buffer.") - self.dataset.clear_episode_buffer() - if not self.setup_over: - raise RuntimeError("Setup not completed. Please call StartSession first.") - if self.episode_recording_in_progress: - raise RuntimeError("Episode recording already in progress. Please stop it before starting a new one.") - self.episode_saved = False - self.thread = threading.Thread(target=self.record_episode) - self.thread.daemon = True - self.thread.start() - self.episode_recorded_in_session = True - ack = ActionAck(success_ack=True) - self._logger.error("Episode started") - except Exception as e: - self._logger.error(f"Error starting episode: {e}") - ack = ActionAck(success_ack=False) - return ack - - def StopEpisode(self, request: Empty, context: grpc.ServicerContext) -> ActionAck: - self._logger.error("Stopping episode") - try: - self.events["exit_early"] = True - if self.thread and self.thread.is_alive(): - self.thread.join() # Wait for the thread to finish - self.events["exit_early"] = False - ack = ActionAck(success_ack=True) - self._logger.error("Episode stopped") - except Exception as e: - self._logger.error(f"Error stopping session: {e}") - ack = ActionAck(success_ack=False) - return ack - - def SaveEpisode(self, request: EpisodeRating, context: grpc.ServicerContext) -> ActionAck: - self._logger.error("Saving episode") - try: - if self.episode_recording_in_progress: - raise RuntimeError("Episode recording in progress. Please stop it before saving.") - self.dataset.save_episode() - self.episode_saved = True - ack = ActionAck(success_ack=True) - self._logger.error("Episode saved") - except Exception as e: - self._logger.error(f"Error saving episode: {e}") - ack = ActionAck(success_ack=False) - return ack - - def UploadSession(self, request: Empty, context: grpc.ServicerContext) -> ActionAck: - try: - if self.episode_recording_in_progress: - raise RuntimeError("Episode recording in progress. Please stop it before uploading.") - self.dataset.push_to_hub() - ack = ActionAck(success_ack=True) - self._logger.error("Session uploaded") - except Exception as e: - self._logger.error(f"Error uploading session: {e}") - ack = ActionAck(success_ack=False) - return ack - - def setup_recording_session( - self, - request: SessionParams, - context: grpc.ServicerContext, - ): - # Create the robot and teleoperator configurations - self.robot_config = Reachy2RobotConfig( - ip_address=request.robot.ip_address, - id=request.robot.robot_id, - use_external_commands=True, - ) - self.teleop_config = Reachy2FakeTeleoperatorConfig( - ip_address=request.robot.ip_address, - ) - - # Initialize the robot and teleoperator - self.robot = Reachy2Robot(self.robot_config) - self.teleop = Reachy2FakeTeleoperator(self.teleop_config) - - self.fps = request.fps if request.HasField("fps") else 30 - self.task = request.task_description - self.episode_duration = request.episode_duration - self.break_time_duration = request.break_time_duration - - # Configure the dataset features - action_features = hw_to_dataset_features(self.robot.action_features, "action") - obs_features = hw_to_dataset_features(self.robot.observation_features, "observation") - dataset_features = {**action_features, **obs_features} - - print(f"Dataset name: {request.dataset_name}") - - if request.resume: - self.dataset = LeRobotDataset( - request.dataset_name, - root="/home/demo/.cache/huggingface/lerobot/" + request.dataset_name, - ) - if hasattr(self.robot, "cameras") and len(self.robot.cameras) > 0: - self.dataset.start_image_writer() - else: - # Create the dataset - self.dataset = LeRobotDataset.create( - repo_id=request.dataset_name, - fps=self.fps, - features=dataset_features, - robot_type=self.robot.name, - use_videos=True, - image_writer_threads=4, - ) - - current_dataset = self.create_dataset(request.dataset_name, DatasetPushState.LOCAL_ONLY, 0) - self.add_dataset_to_json_file(current_dataset, self.dataset_list_path) - - # Connect the robot and teleoperator - if not self.robot.is_connected: - self.robot.connect() - if not self.teleop.is_connected: - self.teleop.connect() - - def record_episode( - self, - display_cameras: bool = False, - play_sounds: bool = True, - ): - self.episode_recording_in_progress = True - record_loop( - robot=self.robot, - events=self.events, - fps=self.fps, - teleop=self.teleop, - dataset=self.dataset, - control_time_s=self.episode_duration, - single_task=self.task, - display_data=True, - ) - self.episode_recording_in_progress = False - - def create_dataset(self, dataset_name: str, pushed: DatasetPushState, nb_episodes: int) -> Dataset: - dataset = Dataset() - dataset.dataset_name = dataset_name - dataset.pushed = pushed - dataset.nb_episodes = nb_episodes - return dataset - - def dataset_to_dict(self, dataset: Dataset) -> dict: - """Convert Dataset proto to a dict manually.""" - return { - "dataset_name": dataset.dataset_name, - "pushed": DatasetPushState.Name(dataset.pushed), - "nb_episodes": dataset.nb_episodes - } - - def add_dataset_to_json_file(self, dataset: Dataset, json_filename: str): - if os.path.exists(json_filename): - with open(json_filename, "r") as f: - try: - data = json.load(f) - if not isinstance(data, list): - print("Warning: JSON root is not a list, resetting.") - data = [] - except json.JSONDecodeError: - print("Warning: Invalid JSON file, resetting.") - data = [] - else: - data = [] - - # Add the new dataset - data.append(self.dataset_to_dict(dataset)) - - # Save back to file - with open(json_filename, "w") as f: - json.dump(data, f, indent=2) - - def update_dataset(self, dataset: Dataset, json_filename: str): - """Update the 'pushed' field of a dataset in the JSON file.""" - if not os.path.exists(json_filename): - print(f"File '{json_filename}' does not exist.") - return - - with open(json_filename, "r") as f: - try: - data = json.load(f) - if not isinstance(data, list): - print("Warning: JSON root is not a list. No update performed.") - return - except json.JSONDecodeError: - print("Warning: JSON file is invalid. No update performed.") - return - - dataset_found = False - for d in data: - if d.get("dataset_name") == dataset.dataset_name: - d["pushed"] = DatasetPushState.Name(dataset.pushed) # Convert enum to string - dataset_found = True - break - - if not dataset_found: - print(f"No dataset with name '{dataset.dataset_name}' found.") - return - - with open(json_filename, "w") as f: - json.dump(data, f, indent=2) - - print(f"Dataset '{dataset.dataset_name}' updated successfully.") - - def dict_to_dataset(self, d: Dict) -> Dataset: - """Convert a dictionary to a Dataset proto.""" - dataset = Dataset() - dataset.dataset_name = d.get("dataset_name", "") - - pushed_str = d.get("pushed", "UNKNOWN") - if isinstance(pushed_str, str): - # Convert string to enum value - dataset.pushed = DatasetPushState.Value(pushed_str) - elif isinstance(pushed_str, int): - # Already an integer value - dataset.pushed = pushed_str - else: - dataset.pushed = DatasetPushState.UNKNOWN - - dataset.nb_episodes = d.get("nb_episodes", 0) - return dataset - - def read_datasets_from_json(self, json_filename: str) -> DatasetList: - dataset_list = DatasetList() - - if not os.path.exists(json_filename): - print(f"File {json_filename} does not exist.") - return dataset_list # Empty list - - with open(json_filename, "r") as f: - try: - data = json.load(f) - if not isinstance(data, list): - print("Warning: JSON root is not a list. Ignored.") - return dataset_list - except json.JSONDecodeError: - print("Warning: Invalid JSON file. Ignored.") - return dataset_list - - for d in data: - dataset = self.dict_to_dataset(d) - dataset_list.datasets.append(dataset) - - return dataset_list - - def remove_dataset_by_name(self, dataset_name: str, json_filename: str): - """Remove a dataset with a given name from the JSON file.""" - if not os.path.exists(json_filename): - print(f"File {json_filename} does not exist.") - return - - with open(json_filename, "r") as f: - try: - data = json.load(f) - if not isinstance(data, list): - print("Warning: JSON root is not a list. No action taken.") - return - except json.JSONDecodeError: - print("Warning: Invalid JSON file. No action taken.") - return - - original_length = len(data) - # Filter out datasets with the matching name - data = [d for d in data if d.get("dataset_name") != dataset_name] - - if len(data) == original_length: - print(f"No dataset found with name '{dataset_name}'. No action taken.") - return - - # Save the modified list back to the file - with open(json_filename, "w") as f: - json.dump(data, f, indent=2) - print(f"Dataset '{dataset_name}' removed successfully.") - - def clear_all_datasets(self, json_filename: str): - """Clear all datasets from the JSON file.""" - if not os.path.exists(json_filename): - print(f"File {json_filename} does not exist. Nothing to clear.") - return - - # Overwrite the file with an empty list - with open(json_filename, "w") as f: - json.dump([], f, indent=2) - print(f"All datasets have been cleared from '{json_filename}'.") - - def delete_folder(self, folder_path: str): - """Delete an entire folder and its content.""" - if not os.path.exists(folder_path): - print(f"Folder '{folder_path}' does not exist.") - return - - if not os.path.isdir(folder_path): - print(f"Path '{folder_path}' is not a folder.") - return - - try: - shutil.rmtree(folder_path) - print(f"Folder '{folder_path}' and all its contents have been deleted.") - except Exception as e: - print(f"Error while deleting folder '{folder_path}': {e}") - - -def main(): - mp.set_start_method('spawn', force=True) - server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) - - data_acquisition_servicer = DataAcquisitionServicer() - data_acquisition_servicer.register_to_server(server) - server.add_insecure_port('[::]:50062') - server.start() - server.wait_for_termination() - - -if __name__ == '__main__': - main() diff --git a/src/lerobot/robots/reachy2/test_policy.py b/src/lerobot/robots/reachy2/test_policy.py deleted file mode 100644 index 4e56b0bd7..000000000 --- a/src/lerobot/robots/reachy2/test_policy.py +++ /dev/null @@ -1,116 +0,0 @@ -from lerobot.cameras.opencv.configuration_opencv import OpenCVCameraConfig -from lerobot.datasets.lerobot_dataset import LeRobotDataset -from lerobot.datasets.utils import hw_to_dataset_features -from lerobot.policies.act.modeling_act import ACTPolicy -from lerobot.robots.reachy2 import Reachy2Robot, Reachy2RobotConfig -from lerobot.utils.control_utils import init_keyboard_listener -from lerobot.utils.utils import log_say -# from lerobot.utils.visualization_utils import _init_rerun -from lerobot.record import record_loop -from reachy2_sdk import ReachySDK -import numpy as np -import time - - -NUM_EPISODES = 2 -FPS = 15 -EPISODE_TIME_SEC = 4 -TASK_DESCRIPTION = "Grab a cube with Reachy 2" - - -# Create the robot configuration -robot_config = Reachy2RobotConfig( - ip_address="192.168.0.199", - id="reachy2-pvt02", - with_mobile_base=False, -) - -# Initialize the robot -robot = Reachy2Robot(robot_config) -# Instantiate a client for starting and intermediate positions -# reachy = ReachySDK(robot_config.ip_address) - -# Initialize the policy -policy = ACTPolicy.from_pretrained("pepijn223/grab_cube_2") - -# Get initial dataset first episode -initial_dataset = LeRobotDataset(repo_id="glannuzel/grab_cube_2", episodes=[0]) -actions = initial_dataset.hf_dataset.select_columns("action") - -# Configure the dataset features -action_features = hw_to_dataset_features(robot.action_features, "action") -obs_features = hw_to_dataset_features(robot.observation_features, "observation") -dataset_features = {**action_features, **obs_features} - -# Create the dataset -dataset = LeRobotDataset.create( - repo_id="glannuzel/eval_grab_cube_2.1", - fps=FPS, - features=dataset_features, - robot_type=robot.name, - use_videos=True, - image_writer_threads=4, -) - -# Initialize the keyboard listener and rerun visualization -_, events = init_keyboard_listener() -# _init_rerun(session_name="recording") - -# Connect the robot -robot.connect() - -# Go to the initial pose -action_array = actions[0]["action"] -action = {} -for i, name in enumerate(dataset.features["action"]["names"]): - action[name] = action_array[i].item() - -neck_goal = [action["neck_roll.pos"], action["neck_pitch.pos"], action["neck_yaw.pos"]] -r_arm_goal = [action["r_shoulder_pitch.pos"], - action["r_shoulder_roll.pos"], - action["r_elbow_yaw.pos"], - action["r_elbow_pitch.pos"], - action["r_wrist_roll.pos"], - action["r_wrist_pitch.pos"], - action["r_wrist_yaw.pos"]] -l_arm_goal = [action["l_shoulder_pitch.pos"], - action["l_shoulder_roll.pos"], - action["l_elbow_yaw.pos"], - action["l_elbow_pitch.pos"], - action["l_wrist_roll.pos"], - action["l_wrist_pitch.pos"], - action["l_wrist_yaw.pos"]] - -robot.reachy.head.goto(neck_goal) -robot.reachy.r_arm.goto(r_arm_goal) -robot.reachy.r_arm.gripper.goto(100.0) -robot.reachy.l_arm.goto(l_arm_goal, wait=True) -time.sleep(1.0) - -for episode_idx in range(NUM_EPISODES): - log_say(f"Running inference, recording eval episode {episode_idx + 1} of {NUM_EPISODES}") - - # Run the policy inference loop - record_loop( - robot=robot, - events=events, - fps=FPS, - policy=policy, - dataset=dataset, - control_time_s=EPISODE_TIME_SEC, - single_task=TASK_DESCRIPTION, - display_data=False, - ) - - # Set the robot back to the initial pose - robot.reachy.head.goto(neck_goal) - robot.reachy.r_arm.goto(r_arm_goal) - robot.reachy.r_arm.gripper.goto(100.0) - robot.reachy.l_arm.goto(l_arm_goal, wait=True) - time.sleep(1.0) - - dataset.save_episode() - -# Clean up -robot.disconnect() -dataset.push_to_hub() diff --git a/src/lerobot/robots/reachy2/test_reachy2.py b/src/lerobot/robots/reachy2/test_reachy2.py deleted file mode 100644 index 39a38df46..000000000 --- a/src/lerobot/robots/reachy2/test_reachy2.py +++ /dev/null @@ -1,60 +0,0 @@ -import time - -from lerobot.robots.reachy2 import Reachy2Robot, Reachy2RobotConfig - -# {lerobot_keys: reachy2_sdk_keys} -REACHY2_JOINTS = { - "neck_yaw.pos": "head.neck.yaw", - "neck_pitch.pos": "head.neck.pitch", - "neck_roll.pos": "head.neck.roll", - "r_shoulder_pitch.pos": "r_arm.shoulder.pitch", - "r_shoulder_roll.pos": "r_arm.shoulder.roll", - "r_elbow_yaw.pos": "r_arm.elbow.yaw", - "r_elbow_pitch.pos": "r_arm.elbow.pitch", - "r_wrist_roll.pos": "r_arm.wrist.roll", - "r_wrist_pitch.pos": "r_arm.wrist.pitch", - "r_wrist_yaw.pos": "r_arm.wrist.yaw", - "r_gripper.pos": "r_arm.gripper", - "l_shoulder_pitch.pos": "l_arm.shoulder.pitch", - "l_shoulder_roll.pos": "l_arm.shoulder.roll", - "l_elbow_yaw.pos": "l_arm.elbow.yaw", - "l_elbow_pitch.pos": "l_arm.elbow.pitch", - "l_wrist_roll.pos": "l_arm.wrist.roll", - "l_wrist_pitch.pos": "l_arm.wrist.pitch", - "l_wrist_yaw.pos": "l_arm.wrist.yaw", - "l_gripper.pos": "l_arm.gripper", - "l_antenna.pos": "head.l_antenna", - "r_antenna.pos": "head.r_antenna", -} - -REACHY2_VEL = { - "mobile_base.vx": "vx", - "mobile_base.vy": "vy", - "mobile_base.vtheta": "vtheta", -} - - -robot_config = Reachy2RobotConfig(ip_address="localhost") -robot = Reachy2Robot(robot_config) - -robot.connect() - -print(f"is_connected(): {robot.is_connected}\n") - -print(f"_get_state(): {robot._get_state()}\n") - -obs = robot.get_observation() -print(f"get_observation(): {obs}\n") -print(f"observation_features: {robot.observation_features}\n") -print(f"action_features: {robot.action_features}\n") - - -def get_action(robot): - pos_dict = {k: robot.reachy.joints[v].present_position for k, v in REACHY2_JOINTS.items()} - vel_dict = {k: robot.reachy.mobile_base.odometry[v] for k, v in REACHY2_VEL.items()} - return {**pos_dict, **vel_dict} - - -action = get_action(robot) -time.sleep(5) -robot.send_action(action) diff --git a/src/lerobot/robots/reachy2/test_recording.py b/src/lerobot/robots/reachy2/test_recording.py deleted file mode 100644 index 6dcb57172..000000000 --- a/src/lerobot/robots/reachy2/test_recording.py +++ /dev/null @@ -1,104 +0,0 @@ -from lerobot.datasets.lerobot_dataset import LeRobotDataset -from lerobot.datasets.utils import hw_to_dataset_features -from lerobot.robots.reachy2 import Reachy2Robot, Reachy2RobotConfig -from lerobot.teleoperators.reachy2_fake_teleoperator import Reachy2FakeTeleoperator, Reachy2FakeTeleoperatorConfig -from lerobot.utils.control_utils import init_keyboard_listener -from lerobot.utils.utils import log_say -from lerobot.utils.visualization_utils import _init_rerun -from lerobot.record import record_loop - -import time - -NUM_EPISODES = 35 -FPS = 20 -EPISODE_TIME_SEC = 10 -RESET_TIME_SEC = 5 -TASK_DESCRIPTION = "Grab a cube in Mujoco simulation" - -# Create the robot and teleoperator configurations -robot_config = Reachy2RobotConfig( - ip_address="192.168.0.199", - id="test_reachy", - with_mobile_base=False, -) -teleop_config = Reachy2FakeTeleoperatorConfig( - ip_address="192.168.0.199", - with_mobile_base=False, -) - -# Initialize the robot and teleoperator -robot = Reachy2Robot(robot_config) -teleop = Reachy2FakeTeleoperator(teleop_config) - -# Configure the dataset features -action_features = hw_to_dataset_features(robot.action_features, "action") -obs_features = hw_to_dataset_features(robot.observation_features, "observation") -dataset_features = {**action_features, **obs_features} - -# Create the dataset -dataset = LeRobotDataset.create( - repo_id="glannuzel/grab_cube", - fps=FPS, - features=dataset_features, - robot_type=robot.name, - use_videos=True, - image_writer_threads=4, -) - -# Initialize the keyboard listener and rerun visualization -_, events = init_keyboard_listener() -# _init_rerun(session_name="recording") - -# Connect the robot and teleoperator -robot.connect() -teleop.connect() - -episode_idx = 0 -while episode_idx < NUM_EPISODES and not events["stop_recording"]: - start_time = time.time() - log_say(f"Recording episode {episode_idx + 1} of {NUM_EPISODES}") - - print("########### RECORDING ###########") - - record_loop( - robot=robot, - events=events, - fps=FPS, - teleop=teleop, - dataset=dataset, - control_time_s=EPISODE_TIME_SEC, - single_task=TASK_DESCRIPTION, - display_data=False, - ) - - # Reset the environment if not stopping or re-recording - if not events["stop_recording"] and (episode_idx < NUM_EPISODES - 1 or events["rerecord_episode"]): - log_say("Reset the environment") - - print("------------- RESETTING -------------") - record_loop( - robot=robot, - events=events, - fps=FPS, - teleop=teleop, - control_time_s=RESET_TIME_SEC, - single_task=TASK_DESCRIPTION, - display_data=False, - ) - - if events["rerecord_episode"]: - log_say("Re-recording episode") - events["rerecord_episode"] = False - events["exit_early"] = False - dataset.clear_episode_buffer() - continue - - # episode_idx = NUM_EPISODES - dataset.save_episode() - episode_idx += 1 - print(time.time()-start_time) - -# Clean up -log_say("Stop recording") -robot.disconnect() -dataset.push_to_hub() diff --git a/src/lerobot/robots/reachy2/test_replay.py b/src/lerobot/robots/reachy2/test_replay.py deleted file mode 100644 index 6bcb3249b..000000000 --- a/src/lerobot/robots/reachy2/test_replay.py +++ /dev/null @@ -1,65 +0,0 @@ -from lerobot.datasets.lerobot_dataset import LeRobotDataset -from lerobot.robots.reachy2 import Reachy2Robot, Reachy2RobotConfig -from lerobot.utils.robot_utils import busy_wait -import time - - -# Create the robot configuration -robot_config = Reachy2RobotConfig( - ip_address="192.168.0.199", - id="reachy2-pvt02", -) - -# Initialize the robot -robot = Reachy2Robot(robot_config) - -# Create the dataset -dataset = LeRobotDataset(repo_id="glannuzel/store-rubiks-cube", episodes=[0]) -actions = dataset.hf_dataset.select_columns("action") - -# Connect the robot -robot.connect() - -# Go smoothly to the first action -action_array = actions[0]["action"] -action = {} -for i, name in enumerate(dataset.features["action"]["names"]): - action[name] = action_array[i].item() - -neck_goal = [action["neck_roll.pos"], action["neck_pitch.pos"], action["neck_yaw.pos"]] -r_arm_goal = [action["r_shoulder_pitch.pos"], - action["r_shoulder_roll.pos"], - action["r_elbow_yaw.pos"], - action["r_elbow_pitch.pos"], - action["r_wrist_roll.pos"], - action["r_wrist_pitch.pos"], - action["r_wrist_yaw.pos"]] -l_arm_goal = [action["l_shoulder_pitch.pos"], - action["l_shoulder_roll.pos"], - action["l_elbow_yaw.pos"], - action["l_elbow_pitch.pos"], - action["l_wrist_roll.pos"], - action["l_wrist_pitch.pos"], - action["l_wrist_yaw.pos"]] - -robot.reachy.head.goto(neck_goal) -robot.reachy.r_arm.goto(r_arm_goal) -robot.reachy.r_arm.gripper.goto(100.0, percentage=True) -robot.reachy.l_arm.gripper.goto(100.0, percentage=True) -robot.reachy.l_arm.goto(l_arm_goal, wait=True) - -for idx in range(dataset.num_frames): - start_episode_t = time.perf_counter() - - action_array = actions[idx]["action"] - - action = {} - for i, name in enumerate(dataset.features["action"]["names"]): - action[name] = action_array[i].item() - - robot.send_action(action) - dt_s = time.perf_counter() - start_episode_t - busy_wait(1 / dataset.fps - dt_s) - -# Clean up -robot.disconnect() diff --git a/src/lerobot/robots/reachy2/test_robot_client.py b/src/lerobot/robots/reachy2/test_robot_client.py deleted file mode 100644 index 773db2a2a..000000000 --- a/src/lerobot/robots/reachy2/test_robot_client.py +++ /dev/null @@ -1,46 +0,0 @@ -import threading - -from lerobot.robots.reachy2 import Reachy2Robot, Reachy2RobotConfig -from lerobot.scripts.server.configs import RobotClientConfig -from lerobot.scripts.server.helpers import visualize_action_queue_size -from lerobot.scripts.server.robot_client import RobotClient - -robot_config = Reachy2RobotConfig( - ip_address="192.168.0.199", - id="reachy2-pvt02", - with_mobile_base=False, - with_l_arm=False, - with_neck=False, - with_antennas=False, -) - -# 3. Create client configuration -client_cfg = RobotClientConfig( - robot=robot_config, - server_address="localhost:8080", - policy_device="cuda", - policy_type="act", - pretrained_name_or_path="CarolinePascal/pick_and_place_bottle", - chunk_size_threshold=0.5, - actions_per_chunk=20, # make sure this is less than the max actions of the policy -) - -# 4. Create and start client -client = RobotClient(client_cfg) - -# 5. Specify the task -task = "Don't do anything, stay still" - -if client.start(): - # Start action receiver thread - action_receiver_thread = threading.Thread(target=client.receive_actions, daemon=True) - action_receiver_thread.start() - - try: - # Run the control loop - client.control_loop(task) - except KeyboardInterrupt: - client.stop() - action_receiver_thread.join() - # (Optionally) plot the action queue size - visualize_action_queue_size(client.action_queue_size)