From 293870d0f617cfc20028a14810c677d4a327bb7c Mon Sep 17 00:00:00 2001 From: Simon Alibert Date: Thu, 8 May 2025 12:51:09 +0200 Subject: [PATCH] Update teleop features & naming --- lerobot/common/teleoperators/__init__.py | 3 +-- .../teleoperators/keyboard/teleop_keyboard.py | 11 +++++++---- .../{koch => koch_leader}/__init__.py | 0 .../{koch => koch_leader}/config_koch_leader.py | 0 .../{koch => koch_leader}/koch_leader.py | 11 ++++------- .../{so100 => so100_leader}/__init__.py | 0 .../config_so100_leader.py | 0 .../{so100 => so100_leader}/so100_leader.py | 11 ++++------- .../common/teleoperators/stretch3/__init__.py | 4 ---- .../teleoperators/stretch3_gamepad/__init__.py | 2 ++ .../configuration_stretch3.py | 0 .../stretch3_gamepad.py} | 4 ++-- lerobot/common/teleoperators/teleoperator.py | 4 ++-- lerobot/common/teleoperators/widowx/widowx.py | 17 +++++++++-------- 14 files changed, 31 insertions(+), 36 deletions(-) rename lerobot/common/teleoperators/{koch => koch_leader}/__init__.py (100%) rename lerobot/common/teleoperators/{koch => koch_leader}/config_koch_leader.py (100%) rename lerobot/common/teleoperators/{koch => koch_leader}/koch_leader.py (96%) rename lerobot/common/teleoperators/{so100 => so100_leader}/__init__.py (100%) rename lerobot/common/teleoperators/{so100 => so100_leader}/config_so100_leader.py (100%) rename lerobot/common/teleoperators/{so100 => so100_leader}/so100_leader.py (95%) delete mode 100644 lerobot/common/teleoperators/stretch3/__init__.py create mode 100644 lerobot/common/teleoperators/stretch3_gamepad/__init__.py rename lerobot/common/teleoperators/{stretch3 => stretch3_gamepad}/configuration_stretch3.py (100%) rename lerobot/common/teleoperators/{stretch3/teleop_stretch3.py => stretch3_gamepad/stretch3_gamepad.py} (97%) diff --git a/lerobot/common/teleoperators/__init__.py b/lerobot/common/teleoperators/__init__.py index 9dd9b962..ec93547f 100644 --- a/lerobot/common/teleoperators/__init__.py +++ b/lerobot/common/teleoperators/__init__.py @@ -1,4 +1,3 @@ from .config import TeleoperatorConfig from .teleoperator import Teleoperator - -__all__ = ["TeleoperatorConfig", "Teleoperator"] +from .utils import make_teleoperator_from_config diff --git a/lerobot/common/teleoperators/keyboard/teleop_keyboard.py b/lerobot/common/teleoperators/keyboard/teleop_keyboard.py index ecbda318..a72710e9 100644 --- a/lerobot/common/teleoperators/keyboard/teleop_keyboard.py +++ b/lerobot/common/teleoperators/keyboard/teleop_keyboard.py @@ -61,12 +61,15 @@ class KeyboardTeleop(Teleoperator): self.logs = {} @property - def action_feature(self) -> dict: - # TODO(Steven): Change this when we agree what should this return - ... + def action_features(self) -> dict: + return { + "dtype": "float32", + "shape": (len(self.arm),), + "names": {"motors": list(self.arm.motors)}, + } @property - def feedback_feature(self) -> dict: + def feedback_features(self) -> dict: return {} @property diff --git a/lerobot/common/teleoperators/koch/__init__.py b/lerobot/common/teleoperators/koch_leader/__init__.py similarity index 100% rename from lerobot/common/teleoperators/koch/__init__.py rename to lerobot/common/teleoperators/koch_leader/__init__.py diff --git a/lerobot/common/teleoperators/koch/config_koch_leader.py b/lerobot/common/teleoperators/koch_leader/config_koch_leader.py similarity index 100% rename from lerobot/common/teleoperators/koch/config_koch_leader.py rename to lerobot/common/teleoperators/koch_leader/config_koch_leader.py diff --git a/lerobot/common/teleoperators/koch/koch_leader.py b/lerobot/common/teleoperators/koch_leader/koch_leader.py similarity index 96% rename from lerobot/common/teleoperators/koch/koch_leader.py rename to lerobot/common/teleoperators/koch_leader/koch_leader.py index 58ba9f16..410796d1 100644 --- a/lerobot/common/teleoperators/koch/koch_leader.py +++ b/lerobot/common/teleoperators/koch_leader/koch_leader.py @@ -58,15 +58,11 @@ class KochLeader(Teleoperator): ) @property - def action_feature(self) -> dict: - return { - "dtype": "float32", - "shape": (len(self.arm),), - "names": {"motors": list(self.arm.motors)}, - } + def action_features(self) -> dict[str, type]: + return {f"{motor}.pos": float for motor in self.arm.motors} @property - def feedback_feature(self) -> dict: + def feedback_features(self) -> dict[str, type]: return {} @property @@ -158,6 +154,7 @@ class KochLeader(Teleoperator): start = time.perf_counter() action = self.arm.sync_read("Present_Position") + action = {f"{motor}.pos": val for motor, val in action.items()} dt_ms = (time.perf_counter() - start) * 1e3 logger.debug(f"{self} read action: {dt_ms:.1f}ms") return action diff --git a/lerobot/common/teleoperators/so100/__init__.py b/lerobot/common/teleoperators/so100_leader/__init__.py similarity index 100% rename from lerobot/common/teleoperators/so100/__init__.py rename to lerobot/common/teleoperators/so100_leader/__init__.py diff --git a/lerobot/common/teleoperators/so100/config_so100_leader.py b/lerobot/common/teleoperators/so100_leader/config_so100_leader.py similarity index 100% rename from lerobot/common/teleoperators/so100/config_so100_leader.py rename to lerobot/common/teleoperators/so100_leader/config_so100_leader.py diff --git a/lerobot/common/teleoperators/so100/so100_leader.py b/lerobot/common/teleoperators/so100_leader/so100_leader.py similarity index 95% rename from lerobot/common/teleoperators/so100/so100_leader.py rename to lerobot/common/teleoperators/so100_leader/so100_leader.py index 9610a158..4ca982c1 100644 --- a/lerobot/common/teleoperators/so100/so100_leader.py +++ b/lerobot/common/teleoperators/so100_leader/so100_leader.py @@ -55,15 +55,11 @@ class SO100Leader(Teleoperator): ) @property - def action_feature(self) -> dict: - return { - "dtype": "float32", - "shape": (len(self.arm),), - "names": {"motors": list(self.arm.motors)}, - } + def action_features(self) -> dict[str, type]: + return {f"{motor}.pos": float for motor in self.arm.motors} @property - def feedback_feature(self) -> dict: + def feedback_features(self) -> dict[str, type]: return {} @property @@ -133,6 +129,7 @@ class SO100Leader(Teleoperator): def get_action(self) -> dict[str, float]: start = time.perf_counter() action = self.arm.sync_read("Present_Position") + action = {f"{motor}.pos": val for motor, val in action.items()} dt_ms = (time.perf_counter() - start) * 1e3 logger.debug(f"{self} read action: {dt_ms:.1f}ms") return action diff --git a/lerobot/common/teleoperators/stretch3/__init__.py b/lerobot/common/teleoperators/stretch3/__init__.py deleted file mode 100644 index 9931e5fa..00000000 --- a/lerobot/common/teleoperators/stretch3/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from .configuration_stretch3 import Stretch3GamePadConfig -from .teleop_stretch3 import Stretch3GamePad - -__all__ = ["Stretch3GamePadConfig", "Stretch3GamePad"] diff --git a/lerobot/common/teleoperators/stretch3_gamepad/__init__.py b/lerobot/common/teleoperators/stretch3_gamepad/__init__.py new file mode 100644 index 00000000..ac45b6dd --- /dev/null +++ b/lerobot/common/teleoperators/stretch3_gamepad/__init__.py @@ -0,0 +1,2 @@ +from .configuration_stretch3 import Stretch3GamePadConfig +from .stretch3_gamepad import Stretch3GamePad diff --git a/lerobot/common/teleoperators/stretch3/configuration_stretch3.py b/lerobot/common/teleoperators/stretch3_gamepad/configuration_stretch3.py similarity index 100% rename from lerobot/common/teleoperators/stretch3/configuration_stretch3.py rename to lerobot/common/teleoperators/stretch3_gamepad/configuration_stretch3.py diff --git a/lerobot/common/teleoperators/stretch3/teleop_stretch3.py b/lerobot/common/teleoperators/stretch3_gamepad/stretch3_gamepad.py similarity index 97% rename from lerobot/common/teleoperators/stretch3/teleop_stretch3.py rename to lerobot/common/teleoperators/stretch3_gamepad/stretch3_gamepad.py index b23bd402..adc973ee 100644 --- a/lerobot/common/teleoperators/stretch3/teleop_stretch3.py +++ b/lerobot/common/teleoperators/stretch3_gamepad/stretch3_gamepad.py @@ -73,7 +73,7 @@ class Stretch3GamePad(Teleoperator): RobotParams.set_logging_formatter("brief_console_formatter") @property - def action_feature(self) -> dict: + def action_features(self) -> dict: return { "dtype": "float32", "shape": (len(GAMEPAD_BUTTONS),), @@ -81,7 +81,7 @@ class Stretch3GamePad(Teleoperator): } @property - def feedback_feature(self) -> dict: + def feedback_features(self) -> dict: return {} def connect(self) -> None: diff --git a/lerobot/common/teleoperators/teleoperator.py b/lerobot/common/teleoperators/teleoperator.py index d6285f5c..ee8fd5a1 100644 --- a/lerobot/common/teleoperators/teleoperator.py +++ b/lerobot/common/teleoperators/teleoperator.py @@ -34,11 +34,11 @@ class Teleoperator(abc.ABC): return f"{self.id} {self.__class__.__name__}" @abc.abstractproperty - def action_feature(self) -> dict: + def action_features(self) -> dict: pass @abc.abstractproperty - def feedback_feature(self) -> dict: + def feedback_features(self) -> dict: pass @abc.abstractproperty diff --git a/lerobot/common/teleoperators/widowx/widowx.py b/lerobot/common/teleoperators/widowx/widowx.py index e3887dff..0cec46f8 100644 --- a/lerobot/common/teleoperators/widowx/widowx.py +++ b/lerobot/common/teleoperators/widowx/widowx.py @@ -58,15 +58,11 @@ class WidowX(Teleoperator): ) @property - def action_feature(self) -> dict: - return { - "dtype": "float32", - "shape": (len(self.arm),), - "names": {"motors": list(self.arm.motors)}, - } + def action_features(self) -> dict[str, type]: + return {f"{motor}.pos": float for motor in self.arm.motors} @property - def feedback_feature(self) -> dict: + def feedback_features(self) -> dict[str, type]: return {} @property @@ -84,6 +80,10 @@ class WidowX(Teleoperator): self.configure() logger.info(f"{self} connected.") + @property + def is_calibrated(self) -> bool: + return self.arm.is_calibrated + def calibrate(self) -> None: raise NotImplementedError # TODO(aliberts): adapt code below (copied from koch) logger.info(f"\nRunning calibration of {self}") @@ -137,7 +137,8 @@ class WidowX(Teleoperator): raise DeviceNotConnectedError(f"{self} is not connected.") start = time.perf_counter() - action = self.arm.read("Present_Position") + action = self.arm.sync_read("Present_Position") + action = {f"{motor}.pos": val for motor, val in action.items()} dt_ms = (time.perf_counter() - start) * 1e3 logger.debug(f"{self} read action: {dt_ms:.1f}ms") return action