60 lines
2.6 KiB
Python
60 lines
2.6 KiB
Python
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."
|
|
)
|