diff --git a/lerobot/common/motors/dynamixel/tables.py b/lerobot/common/motors/dynamixel/tables.py index 4634d4a7..5589b224 100644 --- a/lerobot/common/motors/dynamixel/tables.py +++ b/lerobot/common/motors/dynamixel/tables.py @@ -119,3 +119,23 @@ MODEL_BAUDRATE_TABLE = { "xm540-w270": X_SERIES_BAUDRATE_TABLE, "xc430-w150": X_SERIES_BAUDRATE_TABLE, } + +AVAILABLE_BAUDRATES = [ + 9600, + 19200, + 38400, + 57600, + 115200, + 230400, + 460800, + 500000, + 576000, + 921600, + 1000000, + 1152000, + 2000000, + 2500000, + 3000000, + 3500000, + 4000000, +] diff --git a/lerobot/common/motors/feetech/tables.py b/lerobot/common/motors/feetech/tables.py index 7e7e7e9d..a947611d 100644 --- a/lerobot/common/motors/feetech/tables.py +++ b/lerobot/common/motors/feetech/tables.py @@ -83,4 +83,16 @@ MODEL_BAUDRATE_TABLE = { "sts3215": SCS_SERIES_BAUDRATE_TABLE, } -CALIBRATION_REQUIRED = ["Goal_Position", "Present_Position"] +AVAILABLE_BAUDRATES = [ + 4800, + 9600, + 14400, + 19200, + 38400, + 57600, + 115200, + 128000, + 250000, + 500000, + 1000000, +] diff --git a/lerobot/common/motors/motors_bus.py b/lerobot/common/motors/motors_bus.py index 1d9e1af1..1dde8e77 100644 --- a/lerobot/common/motors/motors_bus.py +++ b/lerobot/common/motors/motors_bus.py @@ -29,6 +29,7 @@ from typing import Protocol, TypeAlias, overload import serial from deepdiff import DeepDiff +from tqdm import tqdm from lerobot.common.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError @@ -379,6 +380,26 @@ class MotorsBus(abc.ABC): self.set_timeout() logger.debug(f"{self.__class__.__name__} connected.") + @classmethod + def scan_port(cls, port: str) -> dict[int, list[int]]: + bus = cls(port, {}) + try: + bus.port_handler.openPort() + except (FileNotFoundError, OSError, serial.SerialException) as e: + raise ConnectionError( + f"Could not connect to port '{port}'. Make sure you are using the correct port." + "\nTry running `python lerobot/scripts/find_motors_bus_port.py`\n" + ) from e + baudrate_ids = {} + for baudrate in tqdm(bus.available_baudrates, desc="Scanning port"): + bus.set_baudrate(baudrate) + ids_models = bus.broadcast_ping() + if ids_models: + tqdm.write(f"Motors found for {baudrate=}: {pformat(ids_models, indent=4)}") + baudrate_ids[baudrate] = list(ids_models) + + return baudrate_ids + @abc.abstractmethod def _configure_motors(self) -> None: pass