Add teleop_left camera to observation

This commit is contained in:
glannuzel
2025-07-29 14:07:26 +02:00
parent 8b9fc0d2e9
commit 18e7232f88
3 changed files with 52 additions and 33 deletions
@@ -15,7 +15,8 @@
from dataclasses import dataclass, field from dataclasses import dataclass, field
from lerobot.cameras import CameraConfig from lerobot.cameras import CameraConfig
from lerobot.cameras.opencv import OpenCVCameraConfig # from lerobot.cameras.opencv import OpenCVCameraConfig
from lerobot.cameras.reachy2_camera import Reachy2CameraConfig
from lerobot.cameras.configs import ColorMode, Cv2Rotation from lerobot.cameras.configs import ColorMode, Cv2Rotation
from ..config import RobotConfig from ..config import RobotConfig
@@ -33,19 +34,23 @@ class Reachy2RobotConfig(RobotConfig):
# cameras # cameras
cameras: dict[str, CameraConfig] = field( cameras: dict[str, CameraConfig] = field(
default_factory=lambda: { default_factory=lambda: {
# "head": RealSenseCameraConfig( # "webcam": OpenCVCameraConfig(
# name="Intel RealSense D435I", # index_or_path="/dev/video0",
# fps=30, # fps=30,
# width=640, # width=640,
# height=480, # height=480,
# rotation=90, # color_mode=ColorMode.RGB,
# ), # rotation=Cv2Rotation.NO_ROTATION
# "wrist": RealSenseCameraConfig( # ),
# name="Intel RealSense D405", "teleop_left": Reachy2CameraConfig(
# fps=30, name="teleop",
# width=640, image_type="left",
# height=480, fps=30,
# ), width=640,
height=480,
color_mode=ColorMode.RGB,
rotation=Cv2Rotation.NO_ROTATION
),
} }
) )
+31 -17
View File
@@ -80,10 +80,11 @@ class Reachy2Robot(Robot):
@property @property
def observation_features(self) -> dict: def observation_features(self) -> dict:
return dict.fromkeys( return {**self.motors_features, **self.camera_features}
REACHY2_MOTORS.keys(), # return dict.fromkeys(
float, # REACHY2_MOTORS.keys(),
) # float,
# )
# return { # return {
# "dtype": "float32", # "dtype": "float32",
# "shape": len(REACHY2_MOTORS), # "shape": len(REACHY2_MOTORS),
@@ -92,18 +93,28 @@ class Reachy2Robot(Robot):
@property @property
def action_features(self) -> dict: def action_features(self) -> dict:
return self.observation_features return self.motors_features
@property @property
def camera_features(self) -> dict[str, dict]: def camera_features(self) -> dict[str, dict]:
cam_ft = {} return {
for cam_key, cam in self.cameras.items(): cam: (self.cameras[cam].height, self.cameras[cam].width, 3) for cam in self.cameras
cam_ft[cam_key] = { }
"shape": (cam.height, cam.width, cam.channels), # cam_ft = {}
"names": ["height", "width", "channels"], # for cam_key, cam in self.cameras.items():
"info": None, # cam_ft[cam_key] = {
} # "shape": (cam.height, cam.width, cam.channels),
return cam_ft # "names": ["height", "width", "channels"],
# "info": None,
# }
# return cam_ft
@property
def motors_features(self) -> dict:
return dict.fromkeys(
REACHY2_MOTORS.keys(),
float,
)
@property @property
def is_connected(self) -> bool: def is_connected(self) -> bool:
@@ -115,8 +126,8 @@ class Reachy2Robot(Robot):
print("Error connecting to Reachy 2.") print("Error connecting to Reachy 2.")
raise ConnectionError() raise ConnectionError()
# for cam in self.cameras.values(): for cam in self.cameras.values():
# cam.connect() cam.connect()
# if not self.is_connected: # if not self.is_connected:
# print("Could not connect to the cameras, check that all cameras are plugged-in.") # print("Could not connect to the cameras, check that all cameras are plugged-in.")
@@ -149,6 +160,9 @@ class Reachy2Robot(Robot):
# state = np.asarray(list(state.values())) # state = np.asarray(list(state.values()))
# obs_dict[OBS_STATE] = state # obs_dict[OBS_STATE] = state
for cam_key, cam in self.cameras.items():
obs_dict[cam_key] = cam.async_read()
# Capture images from cameras # Capture images from cameras
# for cam_key, cam in self.cameras.items(): # for cam_key, cam in self.cameras.items():
# before_camread_t = time.perf_counter() # before_camread_t = time.perf_counter()
@@ -178,5 +192,5 @@ class Reachy2Robot(Robot):
def disconnect(self) -> None: def disconnect(self) -> None:
self.reachy.turn_off_smoothly() self.reachy.turn_off_smoothly()
self.reachy.disconnect() self.reachy.disconnect()
# for cam in self.cameras.values(): for cam in self.cameras.values():
# cam.disconnect() cam.disconnect()
+2 -2
View File
@@ -34,8 +34,8 @@ dataset = LeRobotDataset.create(
fps=FPS, fps=FPS,
features=dataset_features, features=dataset_features,
robot_type=robot.name, robot_type=robot.name,
# use_videos=True, use_videos=True,
# image_writer_threads=4, image_writer_threads=4,
) )
# Initialize the keyboard listener and rerun visualization # Initialize the keyboard listener and rerun visualization