From 67843db756f6d3d0402279100075f53b238ce190 Mon Sep 17 00:00:00 2001 From: glannuzel Date: Thu, 28 Aug 2025 17:44:23 +0200 Subject: [PATCH] Add check no part + test --- .../robots/reachy2/configuration_reachy2.py | 26 ++++++++++++++++--- .../config_reachy2_teleoperator.py | 14 ++++++++++ tests/robots/test_reachy2.py | 12 +++++++++ .../test_reachy2_teleoperator.py | 12 +++++++++ 4 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/lerobot/robots/reachy2/configuration_reachy2.py b/src/lerobot/robots/reachy2/configuration_reachy2.py index 432e48144..f43fb203e 100644 --- a/src/lerobot/robots/reachy2/configuration_reachy2.py +++ b/src/lerobot/robots/reachy2/configuration_reachy2.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from dataclasses import dataclass +from dataclasses import dataclass, field from lerobot.cameras import CameraConfig from lerobot.cameras.configs import ColorMode @@ -28,11 +28,17 @@ class Reachy2RobotConfig(RobotConfig): # Set this to a positive scalar to have the same value for all motors, or a list that is the same length as # the number of motors in your follower arms. max_relative_target: int | None = None + + # IP address of the Reachy 2 robot ip_address: str | None = "localhost" + # If True, turn_off_smoothly() will be sent to the robot before disconnecting. + disable_torque_on_disconnect: bool = True + # Tag for external commands control # Set to True if you use an external commands system to control the robot, # such as the official teleoperation application: https://github.com/pollen-robotics/Reachy2Teleoperation + # If True, robot.send_action() will not send commands to the robot. use_external_commands: bool = False # Robot parts @@ -51,9 +57,10 @@ class Reachy2RobotConfig(RobotConfig): with_right_teleop_camera: bool = True with_torso_camera: bool = False + cameras: dict[str, CameraConfig] = field(default_factory=dict) + def __post_init__(self) -> None: - # Add cameras - self.cameras: dict[str, CameraConfig] = {} + # Add cameras with same ip_address as the robot if self.with_left_teleop_camera: self.cameras["teleop_left"] = Reachy2CameraConfig( name="teleop", @@ -86,3 +93,16 @@ class Reachy2RobotConfig(RobotConfig): ) super().__post_init__() + + if not ( + self.with_mobile_base + or self.with_l_arm + or self.with_r_arm + or self.with_neck + or self.with_antennas + ): + raise ValueError( + "No Reachy2Robot part used.\n" + "At least one part of the robot must be set to True " + "(with_mobile_base, with_l_arm, with_r_arm, with_neck, with_antennas)" + ) diff --git a/src/lerobot/teleoperators/reachy2_teleoperator/config_reachy2_teleoperator.py b/src/lerobot/teleoperators/reachy2_teleoperator/config_reachy2_teleoperator.py index 4e1496a3c..4e615d363 100644 --- a/src/lerobot/teleoperators/reachy2_teleoperator/config_reachy2_teleoperator.py +++ b/src/lerobot/teleoperators/reachy2_teleoperator/config_reachy2_teleoperator.py @@ -35,3 +35,17 @@ class Reachy2TeleoperatorConfig(TeleoperatorConfig): with_r_arm: bool = True with_neck: bool = True with_antennas: bool = True + + def __post_init__(self): + if not ( + self.with_mobile_base + or self.with_l_arm + or self.with_r_arm + or self.with_neck + or self.with_antennas + ): + raise ValueError( + "No Reachy2Teleoperator part used.\n" + "At least one part of the robot must be set to True " + "(with_mobile_base, with_l_arm, with_r_arm, with_neck, with_antennas)" + ) diff --git a/tests/robots/test_reachy2.py b/tests/robots/test_reachy2.py index 9d6df77ab..121f7edcc 100644 --- a/tests/robots/test_reachy2.py +++ b/tests/robots/test_reachy2.py @@ -316,3 +316,15 @@ def test_send_action(reachy2): reachy2.reachy.send_goal_positions.assert_called_once() if reachy2.config.with_mobile_base: reachy2.reachy.mobile_base.send_speed_command.assert_called_once() + + +def test_no_part_declared(): + with pytest.raises(ValueError): + _ = Reachy2RobotConfig( + ip_address="192.168.0.200", + with_mobile_base=False, + with_l_arm=False, + with_r_arm=False, + with_neck=False, + with_antennas=False, + ) diff --git a/tests/teleoperators/test_reachy2_teleoperator.py b/tests/teleoperators/test_reachy2_teleoperator.py index 6fe5bda0f..98abdf480 100644 --- a/tests/teleoperators/test_reachy2_teleoperator.py +++ b/tests/teleoperators/test_reachy2_teleoperator.py @@ -142,3 +142,15 @@ def test_get_action(reachy2): if reachy2.config.with_mobile_base: for vel in REACHY2_VEL.keys(): assert action[vel] == reachy2.reachy.mobile_base.last_cmd_vel[REACHY2_VEL[vel]] + + +def test_no_part_declared(): + with pytest.raises(ValueError): + _ = Reachy2TeleoperatorConfig( + ip_address="192.168.0.200", + with_mobile_base=False, + with_l_arm=False, + with_r_arm=False, + with_neck=False, + with_antennas=False, + )