LeRobot documentation
모터
모터
SerialMotorsBus는 시리얼 버스 상의 Feetech 또는 Dynamixel 서보 체인에 대한 저레벨 인터페이스입니다. 로봇은 이를 통해 위치를 읽고 목표 위치를 작성하며, 하드웨어를 추가하는 경우가 아니면 직접 다루는 일이 거의 없습니다. 각 모터의 모델은 제어 테이블과 패밀리 간에 다른 사실들을 포함하는 rustypot에서 조회되며, 시리얼 포트도 소유합니다. FeetechMotorsBus와 DynamixelMotorsBus는 이를 대체하는 비권장 별칭으로, 릴리스 하나 동안 유지됩니다.
SDK 기반 버스에서 마이그레이션
에이리어스는 클래스 이름을 유지하며, 이전 SDK 속성 및 모델 테이블은 유지하지 않습니다:
bus.model_resolution_table[model]은bus.resolution(model)으로 변경되며, 다른 모델 테이블(model_ctrl_table,model_number_table, …)은 이제 rustypot의 servo 정의입니다.- 작동 모드는
OperatingMode값을Operating_Mode레지스터에 쓰는 대신 이름으로 선택합니다.bus.set_operating_mode("position") - SDK 포트 및 패킷 핸들러는 더 이상 노출되지 않습니다. rustypot이 시리얼 포트를 관리합니다.
protocol_version는 무시됩니다. 각 모터의 모델이 프로토콜을 제공합니다.
See Bring Your Own Hardware for adding a new bus, and Updating Feetech Firmware and Damiao Motors and CAN Bus for device-specific notes.
SerialMotorsBus
class lerobot.motors.SerialMotorsBus
< source >( port: strmotors: dict[str, Motor]calibration: dict[str, MotorCalibration] | None = None )
Feetech 또는 Dynamixel 서보 모터를 하나의 시리얼 포트에 다이지 체인 방식으로 연결하여 읽기 및 쓰기 작업을 수행합니다.
rustypot은 각 모델의 메타데이터(컨트롤 테이블, 해상도, 보드레이트, 동작 모드)와 시리얼 I/O를 처리하고, LeRobot은 정규화, 보정 및 권장 설정을 처리합니다. STS와 SCS 또는 XL430과 XL330과 같은 여러 모델의 모터는 포트를 공유합니다.
포트를 찾으려면 다음을 실행하세요:
lerobot-find-port
>>> Finding all available ports for the MotorsBus.
>>> ["/dev/tty.usbmodem575E0032081", "/dev/tty.usbmodem575E0031751"]
>>> Remove the usb cable from your MotorsBus and press Enter when done.
>>> The port of this MotorsBus is /dev/tty.usbmodem575E0031751.
>>> Reconnect the usb cable.버스에 연결된 단일 Feetech sts3215의 예시:
from lerobot.motors import Motor, MotorNormMode, SerialMotorsBus
bus = SerialMotorsBus(
port="/dev/tty.usbmodem575E0031751",
motors={"my_motor": Motor(1, "sts3215", MotorNormMode.RANGE_M100_100)},
)
bus.connect()
position = bus.read("Present_Position", "my_motor", normalize=False)
# Move a few motor steps as an example
bus.write("Goal_Position", "my_motor", position + 30, normalize=False)
bus.disconnect()configure_motors
< source >( return_delay_time: int = 0maximum_acceleration: int = 254acceleration: int = 254 )
매개변수
모든 모터에 LeRobot의 권장 설정을 작성합니다.
connect
< source >( handshake: bool = True )
매개변수
- handshake (
bool, 선택 사항, 기본값True) — 모든 모터가 해당 모델의 모델 번호로 응답하는지, 그리고 하나의 정의에 속한 Feetech 모터들이 동일한 펌웨어를 실행하는지 확인할지 여부입니다.
다음 예외를 발생시킵니다
DeviceAlreadyConnectedError 또는 ConnectionError 또는 RuntimeError
DeviceAlreadyConnectedError— 포트가 이미 열려 있는 경우.ConnectionError— 포트를 열 수 없는 경우.RuntimeError— 핸드셰이크가 실패하면 포트가 다시 닫힙니다.
시리얼 포트를 열고 모터를 확인합니다.
disable_torque
< source >( motors: NameOrID | Sequence[NameOrID] | None = Nonenum_retry: int = 0 )
선택한 모터의 토크를 비활성화합니다.
토크가 꺼진 상태에서 모터의 EEPROM에 데이터를 기록할 수 있으며, Feetech 모터의 경우 잠금이 해제됩니다. 선택된 모든 모터에 대해 기록을 시도하며, 실패 사항은 보고되고 응답하지 않는 모터는 여전히 토크가 활성화된 상태로 남아 있을 수 있습니다.
연결 해제
< source >( disable_torque: bool = True )
기본적으로 모든 모터의 토크를 끄고 시리얼 포트를 닫습니다.
이미 연결이 해제된 버스에 대해 호출해도 안전하며, 토크 비활성화가 실패하더라도 포트는 해제됩니다.
enable_torque
< source >( motors: NameOrID | Sequence[NameOrID] | None = Nonenum_retry: int = 0 )
선택한 모터의 토크를 활성화하고 Feetech 모터의 잠금을 해제합니다.
핑
< source >( motor: NameOrIDnum_retry: int = 0 ) → int | None
모터가 응답하는 모델 번호
Model_Number을 읽는 대신 ping을 보내지 않습니다. 이렇게 하면 존재 확인과 신원 확인에 왕복 2회 대신 1회만 소요됩니다.
읽기
< source >( data_name: strmotor: strnormalize: bool = Truenum_retry: int = 0 ) → int | float
매개변수
- data_name (
str) — 등록 이름, 예:"Present_Position". 대소문자는 구분되지 않습니다. - motor (
str) — 모터 이름. - normalize (
bool, 선택 사항, 기본값True) — 해당 위치를 보정(calibration) 및 노름(norm) 모드가 정의하는 범위로 스케일링할지 여부. - num_retry (
int, 선택 사항, 기본값0) — 통신 실패 후 추가 시도 횟수.
반환값
int | float
raw 값 또는 정규화된 값.
다음 예외를 발생시킵니다
ConnectionError 또는 RuntimeError
ConnectionError— 모터가 응답하지 않는 경우.RuntimeError— 모터가 읽기를 거부하는 경우. 과부하와 같은 상태의 알람은 예외를 발생시키지 않습니다.
모터 하나의 레지스터를 읽습니다.
read_calibration
< source >( ) → dict[str, MotorCalibration]
반환값
dict[str, MotorCalibration]
이름별로 각 모터의 보정.
모든 모터의 보정을 읽습니다.
homing offset 레지스터가 없는 모터(Feetech SCS)는 0을 보고하며, Drive_Mode 레지스터가 없는 모터(Feetech)는 drive mode 0을 보고합니다.
record_calibration
< source >( mode: strfull_turn_motors: Sequence[str]inverted_motors: Sequence[str] = ()motors: Sequence[str] | None = None ) → dict[str, MotorCalibration]
매개변수
- mode (
str) — 모터의 작동 모드, 예:"position". - full_turn_motors (
Sequence[str]) — 이동하는 범위 대신 인코더 전체 범위를 부여받은 모터. - inverted_motors (
Sequence[str], 선택 사항, 기본값()) — 반대 방향으로 회전하는 모터입니다. - motors (
Sequence[str], 선택 사항) — 교정할 모터입니다.None이면 모든 모터를 교정합니다.
반환값
dict[str, MotorCalibration]
버스 순서대로 각 모터의 보정입니다.
다음 예외를 발생시킵니다
ValueError
ValueError— 모터가 버스에 연결되어 있지 않거나, 전체 회전 또는 반전된 모터가 보정 대상 모터 중 하나가 아닌 경우; 이 경우 어떤 모터도 변경되지 않습니다.
수동으로 이동한 모터를 보정합니다.
선택된 모터는 해제되고 동작 모드로 전환되며 방향이 지정됩니다. Drive_Mode 레지스터가 있는 모터에는 반전 여부와 관계없이 해당 값이 기록되고, Feetech 서보인 나머지 모터들은 정규화 시 소프트웨어에서 반전이 적용됩니다. 사용자는 각 관절을 동작 범위의 중간에 위치시킵니다. 이는 각 모터의 반 회전(180도)에 해당합니다. 그런 다음 각 관절을 전체 범위로 움직이며 ENTER 키를 누를 때까지 기록합니다. 전체 회전(full-turn) 모터는 기록되지 않습니다. 해당 모터는 모델의 인코더 전체 범위를 차지하기 때문입니다.
모터에는 작동 모드와 호밍 오프셋이 필요하지만, Feetech SCS0009에는 이 두 가지가 모두 없습니다. 해당 모터의 호밍 오프셋과 위치 한계값은 다시 작성되고, 캐시된 calibration은 삭제되며, 토크는 꺼진 상태로 유지됩니다. 반환되는 캘리브레이션은 위치 한계값에 기록되지도 않고 저장되지도 않습니다: ~SerialMotorsBus.write_calibration이 이를 기록하고, 장치가 이를 저장합니다.
record_ranges_of_motion
< source >( motors: NameOrID | Sequence[NameOrID] | None = Nonedisplay_values: bool = True ) → tuple[dict[str, int | float], dict[str, int | float]]
매개변수
- motors (
str | int | Sequence[str | int], 선택 사항) — 이름 또는 id로 기록할 모터.None을(를) 사용하면 모든 모터를 선택합니다. - display_values (
bool, 선택 사항, 기본값True) — 실시간 테이블을 출력할지 여부입니다.
반환값
tuple[dict[str, int | float], dict[str, int | float]]
모터 이름별로 각 모터의 가장 낮은 원시 위치와 가장 높은 원시 위치.
다음 예외를 발생시킵니다
ValueError
ValueError— 모터가 움직이지 않은 경우: 최저 위치와 최고 위치가 같습니다.
ENTER를 누를 때까지, 각 선택된 모터가 수동으로 이동하는 범위를 기록합니다.
관절은 토크를 끄고 손으로 움직이며, 라이브 테이블에 위치가 표시됩니다.
reset_calibration
< source >( motors: NameOrID | Sequence[NameOrID] | None = None )
선택한 모터의 공장 캘리브레이션을 복원합니다.
호밍 오프셋은 해당 오프셋을 가진 모터에서 0으로 설정되며, 위치 한계는 인코더 전체 범위를 포함합니다. 캐시된 calibration은 삭제됩니다.
해상도
< source >( model: str ) → int
모터 모델의 회전당 인코더 단계 수.
열린 포트의 baud rate를 변경합니다.
포트는 모든 연결 시 default_baudrate로 열립니다.
set_half_turn_homings
< source >( motors: NameOrID | Sequence[NameOrID] | None = None ) → dict[str, int]
각 선택된 모터의 현재 위치를 반 바퀴로 만듭니다.
모터의 보정이 리셋된 후, 각 모터는 현재 위치를 인코더의 절반(예: 12비트 인코더의 경우 2047)으로 가져오는 홈링 오프셋을 받습니다. 선택된 모든 모터에는 홈링 오프셋이 있어야 하며, 이는 레지스터에 값이 기록되기 전에 확인됩니다.
set_operating_mode
< source >( mode: strmotors: NameOrID | Sequence[NameOrID] | None = None )
이름으로 지정된 동작 모드로 선택된 모터를 설정합니다.
모드는 각 모터의 정의에서 가져오므로, 모터 패밀리뿐 아니라 모델에 따라 달라집니다. 예를 들어 Feetech SCS0009에는 모드가 없습니다. 선택한 모든 모터에 해당 모드가 존재해야 하며, 이는 모터의 모드가 변경되기 전에 확인됩니다. 토크를 꺼둔 상태로 작성하십시오.
position: 한 턴(turn) 내의 목표 위치와 위치 한계를 포함합니다.velocity: 바퀴처럼 목표 속도로 끝없이 회전합니다.pwm: 모터 전압을 직접 제어하며, 오픈 루프 방식입니다.step(Feetech): 목표 위치로 기록된 단계 수만큼 이동합니다.current(Dynamixel): 위치와 무관하게 목표 전류, 즉 토크를 유지합니다.extended_position(Dynamixel): 여러 턀 동안 목표 위치를 유지합니다. 이 모드에서는Min_Position_Limit및Max_Position_Limit레지스터가 무시됩니다.current_based_position(Dynamixel): 목표 전류로 전류를 제한하면서 여러 턀에 걸쳐 목표 위치를 유지합니다. 쥐고 있는 물체를 부수지 않아야 하는 그립퍼처럼 동작합니다.
setup_motor
< source >( motor: strinitial_baudrate: int | None = Noneinitial_id: int | None = None )
매개변수
- motor (
str) — 모터의 이름. - initial_baudrate (
int, 선택 사항) — 모터가 현재 응답하는 baud rate입니다. - initial_id (
int, 선택 사항) — 현재 모터가 응답하는 Id로,initial_baudrate와 함께 사용됩니다.
다음 예외를 발생시킵니다
RuntimeError 또는 ConnectionError
RuntimeError— 모터가 발견되지 않거나, 해당 모델이 아니거나, 설정 후 구성된 대로 응답하지 않는 경우.ConnectionError— 모터와의 통신이 실패한 경우.
모터 하나에 id와 버스의 기본 baud rate를 지정합니다.
모터는 버스에서 유일한 모터여야 합니다. initial_baudrate와 initial_id가 모두 지정되지 않는 한, 먼저 해당 모터를 찾습니다. initial_baudrate만 지정된 경우 해당 initial_baudrate에서, 그렇지 않은 경우 해당 모델의 baud rate 범위에서 찾습니다. initial_id만 단독으로 지정된 경우, 찾은 id로 대체됩니다. 이후 rustypot은 토크를 끄고 EEPROM을 열어 id와 baud rate를 기록합니다.
setup_motors
< source >( motors: Sequence[str] | None = None )
모터를 하나씩 설정하고, 각 모터가 버스에서 단독으로 동작하도록 요청합니다.
sync_read
< source >( data_name: strmotors: NameOrID | Sequence[NameOrID] | None = Nonenormalize: bool = Truenum_retry: int = 0 ) → dict[str, int | float]
매개변수
- data_name (
str) — 등록 이름, 예:"Present_Position". 대소문자는 구분되지 않습니다. - motors (
str | int | Sequence[str | int], 선택 사항) — 이름 또는 id로 읽을 모터.None이면 모든 모터를 읽습니다. - normalize (
bool, 선택 사항, 기본값True) — 교정 및 norm 모드가 정의하는 범위로 위치를 스케일링할지 여부입니다. - num_retry (
int, 선택 사항, 기본값0) — 통신 실패 후 추가 시도 횟수입니다. 재시도는 성공한 그룹을 포함하여 모든 그룹을 다시 전송하며, 알려지지 않은 모터나 레지스터는 절대 재시도하지 않습니다.
반환값
dict[str, int | float]
이름별 각 모터의 값.
다음 예외를 발생시킵니다
ConnectionError 또는 RuntimeError
ConnectionError— 모터가 응답하지 않는 경우.RuntimeError— 모터가 읽기를 거부하는 경우. 과부하와 같은 상태의 알람은 예외를 발생시키지 않습니다.
여러 개의 모터 레지스터를 읽습니다.
rustypot은 프로토콜과 레지스터의 주소 및 크기를 공유하는 모터 그룹마다 Sync Read를 한 번씩 보내고, Feetech SCS와 같은 서보 모터의 경우 Sync Read 없이 모터를 하나씩 순서대로 읽습니다. 따라서 값들은 하나의 동시 스냅샷이 아닙니다.
sync_write
< source >( data_name: strvalues: Value | dict[str, Value]normalize: bool = Truenum_retry: int = 0 )
매개변수
- data_name (
str) — 등록 이름, 예:"Goal_Position". 대소문자는 구분되지 않습니다. - values (
int | float | dict[str, int | float]) — 모든 모터에 대한 하나의 값 또는 모터 이름별 값. - normalize (
bool, 선택 사항, 기본값True) — 위치 값이 보정(calibration) 및 norm mode가 정의하는 범위 내에 있는지 여부입니다. - num_retry (
int, 선택 사항, 기본값0) — 포트 실패 후 추가 시도 횟수. 재시도는 모든 그룹을 다시 전송합니다.
다음 예외를 발생시킵니다
ConnectionError
ConnectionError— 포트가 실패하는 경우.
응답을 기다리지 않고 여러 모터의 레지스터를 작성합니다.
~SerialMotorsBus.write와 달리, 동기화 쓰기에는 모터가 응답하지 않습니다. 더 빠르고 제어 루프에 적합하지만, 패킷이 유실되면 감지되지 않습니다. rustypot은 프로토콜과 레지스터의 주소 및 크기를 공유하는 모터 그룹마다 하나의 동기화 쓰기를 전송합니다.
torque_disabled
< source >( motors: NameOrID | Sequence[NameOrID] | None = None )
with 블록이 실행되는 동안 선택된 모터의 토크를 비활성화합니다.
블록이 예외를 발생시키더라도 종료 시 토크가 다시 활성화되므로, 모터 구성에 적합합니다.
write
< source >( data_name: strmotor: strvalue: Valuenormalize: bool = Truenum_retry: int = 0 )
매개변수
- data_name (
str) — 등록 이름, 예:"Goal_Position". 대소문자는 구분되지 않습니다. - motor (
str) — 모터 이름. - value (
int | float) —normalize에 따라 정규화되거나 원본 값으로 기록할 값. - normalize (
bool, 선택 사항, 기본값True) — 해당 위치가 보정 및 정규화 모드가 정의하는 범위 내에 있는지 여부입니다. - num_retry (
int, 선택 사항, 기본값0) — 통신 실패 후 추가 시도 횟수.
다음 예외를 발생시킵니다
ConnectionError 또는 RuntimeError
ConnectionError— 모터가 응답하지 않는 경우.RuntimeError— 모터가 쓰기를 거부하는 경우 발생합니다. 과부하와 같은 상태 알람은 예외를 발생시키지 않습니다.
모터 1대의 레지스터를 작성하고, 응답을 기다립니다.
~SerialMotorsBus.sync_write와 달리, 모터가 쓰기를 확인하므로 실패가 보고됩니다. 속도는 느리지만 모터 설정에 적합합니다.
write_calibration
< source >( calibration_dict: dict[str, MotorCalibration]cache: bool = True )
모터에 캘리브레이션을 작성하고 기본적으로 캐시합니다.
위치 한도는 모든 모터에 기록되며, 홈링 오프셋은 해당 오프셋을 가진 모터에만 기록됩니다. id와 드라이브 모드는 기록되지 않습니다. Feetech의 드라이브 모드는 정규화 시 소프트웨어에서 적용되며, Dynamixel의 Drive_Mode 레지스터는 별도로 설정됩니다.
Motor
class lerobot.motors.Motor
< source >( id: intmodel: strnorm_mode: MotorNormModemotor_type_str: str | None = Nonerecv_id: int | None = None )
MotorCalibration
class lerobot.motors.MotorCalibration
< source >( id: intdrive_mode: inthoming_offset: intrange_min: intrange_max: int )
MotorNormMode
DriveMode
DriveMode에는 두 개의 멤버, NON_INVERTED = 0과 INVERTED = 1가 있습니다. 정수가 필요한 Drive_Mode 레지스터 또는 MotorCalibration.drive_mode에서는 .value를 사용하세요:
bus.write("Drive_Mode", "elbow_flex", DriveMode.INVERTED.value)Dynamixel의 Drive_Mode 레지스터 값 및 MotorCalibration.drive_mode 값.