import abc from dataclasses import dataclass from typing import Sequence import draccus from lerobot.common.cameras.configs import CameraConfig from lerobot.common.motors.configs import MotorsBusConfig, field @dataclass class RobotConfig(draccus.ChoiceRegistry, abc.ABC): @property def type(self) -> str: return self.get_choice_name(self.__class__) # TODO(rcadene, aliberts): remove ManipulatorRobotConfig abstraction @dataclass class ManipulatorRobotConfig(RobotConfig): leader_arms: dict[str, MotorsBusConfig] = field(default_factory=lambda: {}) follower_arms: dict[str, MotorsBusConfig] = field(default_factory=lambda: {}) cameras: dict[str, CameraConfig] = field(default_factory=lambda: {}) # Optionally limit the magnitude of the relative positional target vector for safety purposes. # 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 (assumes all follower arms have the same number of # motors). max_relative_target: list[float] | float | None = None # Optionally set the leader arm in torque mode with the gripper motor set to this angle. This makes it # possible to squeeze the gripper and have it spring back to an open position on its own. If None, the # gripper is not put in torque mode. gripper_open_degree: float | None = None mock: bool = False def __post_init__(self): if self.mock: for arm in self.leader_arms.values(): if not arm.mock: arm.mock = True for arm in self.follower_arms.values(): if not arm.mock: arm.mock = True for cam in self.cameras.values(): if not cam.mock: cam.mock = True if self.max_relative_target is not None and isinstance(self.max_relative_target, Sequence): for name in self.follower_arms: if len(self.follower_arms[name].motors) != len(self.max_relative_target): raise ValueError( f"len(max_relative_target)={len(self.max_relative_target)} but the follower arm with name {name} has " f"{len(self.follower_arms[name].motors)} motors. Please make sure that the " f"`max_relative_target` list has as many parameters as there are motors per arm. " "Note: This feature does not yet work with robots where different follower arms have " "different numbers of motors." )