LeRobot documentation
Motores
Motores
SerialMotorsBus es la interfaz de bajo nivel para una cadena de servomotores Feetech o Dynamixel en un bus serial. Los robots la utilizan
para leer posiciones y escribir posiciones objetivo; rara vez se manipula directamente a menos que se esté añadiendo hardware. El modelo de cada motor
se busca en rustypot, que contiene las tablas de control y los
hechos que difieren entre familias, y también posee el puerto serial. FeetechMotorsBus y DynamixelMotorsBus son
alias obsoletos de esta, mantenidos durante una sola versión.
Migración desde los buses basados en SDK
Los alias conservan los nombres de las clases, no los atributos del SDK antiguo ni las tablas de modelos:
bus.model_resolution_table[model]pasa a serbus.resolution(model); las otras tablas de modelos (model_ctrl_table,model_number_table, …) son ahora las definiciones de servos de rustypot.- Los modos de operación se seleccionan por nombre,
bus.set_operating_mode("position"), en lugar de escribir un valor deOperatingModeen el registroOperating_Mode. - El puerto del SDK y los manejadores de paquetes ya no están expuestos: rustypot posee el puerto serie.
protocol_versionse ignora: el modelo de cada motor proporciona su protocolo.
Consulte Bring Your Own Hardware para agregar un nuevo bus, y Updating Feetech Firmware y Damiao Motors and CAN Bus para notas específicas de cada dispositivo.
SerialMotorsBus
clase lerobot.motors.SerialMotorsBus
< source >( port: strmotors: dict[str, Motor]calibration: dict[str, MotorCalibration] | None = None )
Leer y escribir una cadena de servos conectados en cascada en un solo puerto serie, Feetech o Dynamixel.
rustypot gestiona los metadatos de cada modelo (tabla de control, resolución, tasas de baudios, modos de operación) y la E/S serial; LeRobot se encarga de la normalización, la calibración y la configuración recomendada. Los motores de varios modelos, como STS y SCS o XL430 y XL330, comparten el puerto.
Para encontrar el puerto, ejecuta:
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.Ejemplo para un solo Feetech sts3215 en el bus:
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 )
Parámetros
- return_delay_time (
int, opcional, valor predeterminado0) — Retraso antes de que un motor responda, en unidades de 2 µs; los motores salen de fábrica con un valor de 250 (500 µs). - maximum_acceleration (
int, opcional, valor predeterminado254) — Límite de aceleración, en los servos que lo tienen (Feetech STS), alto para acelerar la aceleración y la deceleración. - acceleration (
int, opcional, valor predeterminado254) — Aceleración, en los servos que la tienen (Feetech).
Escribe la configuración recomendada de LeRobot en cada motor.
connect
< source >( handshake: bool = True )
Parámetros
- handshake (
bool, opcional, valor predeterminadoTrue) — Si se debe comprobar que cada motor responde con el número de modelo de su modelo, y que los motores Feetech de una misma definición ejecutan un único firmware.
Lanza
DeviceAlreadyConnectedError o ConnectionError o RuntimeError
DeviceAlreadyConnectedError— Si el puerto ya está abierto.ConnectionError— Si no se pudo abrir el puerto.RuntimeError— Si el establecimiento de la conexión falla; el puerto se cierra de nuevo.
Abre el puerto serie y comprueba los motores.
disable_torque
< source >( motors: NameOrID | Sequence[NameOrID] | None = Nonenum_retry: int = 0 )
Parámetros
- motors (
str | int | Sequence[str | int], opcional) — Motores a liberar, por nombre o id.Noneselecciona todos los motores. - num_retry (
int, opcional, valor predeterminado0) — Intentos adicionales en cada motor tras un fallo de comunicación.
Lanza
ConnectionError
ConnectionError— Si algunos motores no se pudieron alcanzar; el mensaje los nombra.
Desactive el par de los motores seleccionados.
Con el par desactivado, se puede escribir en la EEPROM de un motor y se abre el bloqueo de un motor Feetech para ello. Se intenta con cada motor seleccionado; los fallos se informan y los motores sin respuesta pueden permanecer con el par activado.
desconectar
< source >( disable_torque: bool = True )
Cierre el puerto serie, por defecto con el par de cada motor desactivado.
Es seguro llamarlo en un bus que ya está desconectado, y el puerto se libera incluso si deshabilitar el par falla.
enable_torque
< source >( motors: NameOrID | Sequence[NameOrID] | None = Nonenum_retry: int = 0 )
Parámetros
- motors (
str | int | Sequence[str | int], opcional) — Motores que se deben mantener, por nombre o id.Noneselecciona todos los motores. - num_retry (
int, opcional, valor predeterminado0) — Intentos adicionales en cada motor tras un fallo de comunicación.
Lanza
ConnectionError
ConnectionError— Si algunos motores no se pudieron alcanzar; el mensaje los nombra.
Habilite el torque de los motores seleccionados y cierre el bloqueo de los motores Feetech.
ping
< source >( motor: NameOrIDnum_retry: int = 0 ) → int | None
El número de modelo con el que responde un motor.
Lee Model_Number en lugar de enviar un ping: la presencia y la identidad cuestan un solo viaje de ida y vuelta en lugar de dos.
leer
< source >( data_name: strmotor: strnormalize: bool = Truenum_retry: int = 0 ) → int | float
Parámetros
- data_name (
str) — Nombre de registro, p. ej."Present_Position"; no distingue entre mayúsculas y minúsculas. - motor (
str) — Motor name. - normalize (
bool, opcional, valor predeterminadoTrue) — Si se debe escalar una posición al rango que definen su calibración y su modo de normalización. - num_retry (
int, opcional, valor predeterminado0) — Intentos adicionales tras un fallo de comunicación.
Devuelve
int | float
El valor bruto o el normalizado.
Lanza
ConnectionError o RuntimeError
ConnectionError— Si el motor no responde.RuntimeError— Si el motor rechaza la lectura. Una alarma en su estado, como una sobrecarga, no la genera.
Leer un registro de un motor.
read_calibration
< source >( ) → dict[str, MotorCalibration]
Devuelve
dict[str, MotorCalibration]
La calibración de cada motor, por nombre.
Lee la calibración de cada motor.
Un motor sin un registro de desplazamiento de retorno al origen (Feetech SCS) informa 0, y uno sin un registro Drive_Mode (Feetech) informa modo de conducción 0.
record_calibration
< source >( mode: strfull_turn_motors: Sequence[str]inverted_motors: Sequence[str] = ()motors: Sequence[str] | None = None ) → dict[str, MotorCalibration]
Parámetros
- mode (
str) — Modo de operación de los motores, p. ej."position". - full_turn_motors (
Sequence[str]) — Motores que reciben el rango completo del codificador en lugar del rango por el que se desplazan. - inverted_motors (
Sequence[str], opcional, valor predeterminado()) — Motores que giran en la dirección opuesta. - motors (
Sequence[str], opcional) — Motores a calibrar.Nonecalibra todos los motores.
Devuelve
dict[str, MotorCalibration]
La calibración de cada motor, en el orden del bus.
Lanza
ValueError
ValueError— Si un motor no está en el bus, o un motor de vuelta completa o invertido no es uno de los motores a calibrar; en ese caso, no se ha tocado ningún motor.
Calibre los motores movidos a mano.
Los motores seleccionados se liberan, se ponen en modo de funcionamiento y se les asigna su dirección: a un motor con un registro Drive_Mode se le escribe, invertido o no, mientras que en los demás, como servos Feetech, se aplica una inversión en software al normalizar. A continuación, el usuario mantiene las articulaciones en el medio de su rango de movimiento, lo que equivale a media vuelta de cada motor, y mueve cada articulación a lo largo de su rango completo, registrando hasta presionar ENTER. Un motor de vuelta completa no se registra: abarca todo el codificador de su modelo.
Los motores necesitan el modo de operación y un desplazamiento de homing, y el Feetech SCS0009 no tiene ninguno de los dos. Sus desplazamientos de homing y límites de posición se reescriben, la calibration en caché se borra y su par se deja desactivado. La calibración devuelta no se escribe en los límites de posición ni se guarda: ~SerialMotorsBus.write_calibration la escribe y el dispositivo la guarda.
record_ranges_of_motion
< source >( motors: NameOrID | Sequence[NameOrID] | None = Nonedisplay_values: bool = True ) → tuple[dict[str, int | float], dict[str, int | float]]
Parámetros
- motors (
str | int | Sequence[str | int], opcional) — Motores a registrar, por nombre o id.Noneselecciona todos los motores. - display_values (
bool, opcional, valor predeterminadoTrue) — Si se debe imprimir la tabla en vivo.
Devuelve
tuple[dict[str, int | float], dict[str, int | float]]
La posición bruta más baja y la más alta de cada motor, por nombre.
Lanza
ValueError
ValueError— Si un motor no se movió: sus posiciones más baja y más alta son iguales.
Registre el rango a través del cual se mueve cada motor seleccionado manualmente, hasta presionar ENTER.
Las articulaciones se mueven a mano, con el par desactivado, mientras una tabla en vivo muestra las posiciones.
reset_calibration
< source >( motors: NameOrID | Sequence[NameOrID] | None = None )
Restaura la calibración de fábrica de los motores seleccionados.
El desplazamiento de retorno a casa se establece en 0 en los motores que lo tienen, y los límites de posición abarcan todo el codificador. Se borra la calibration en caché.
resolución de
< source >( model: str ) → int
Pasos del codificador por vuelta de un modelo de motor.
set_baudrate
< source >( baudrate: int )
Cambiar la velocidad en baudios del puerto abierto.
El puerto se abre a default_baudrate en cada conexión.
set_half_turn_homings
< source >( motors: NameOrID | Sequence[NameOrID] | None = None ) → dict[str, int]
Parámetros
- motors (
str | int | Sequence[str | int], opcional) — Motores a los que llevar a su posición inicial, por nombre o id.Noneselecciona todos los motores.
Devuelve
dict[str, int]
El desplazamiento de retorno a casa escrito en cada motor, por nombre.
Lanza
ValueError
ValueError— Si un motor seleccionado no tiene desplazamiento de homing, como el Feetech SCS.
Hacer que la posición actual de cada motor seleccionado sea media vuelta.
La calibración de los motores se restablece y luego cada uno recibe el desplazamiento de origen que lleva su posición actual a la mitad de su codificador, por ejemplo, 2047 en uno de 12 bits. Cada motor seleccionado debe tener un desplazamiento de origen, lo cual se verifica antes de escribir en cualquier registro.
set_operating_mode
< source >( mode: strmotors: NameOrID | Sequence[NameOrID] | None = None )
Parámetros
- mode (
str) — Nombre del modo de operación, p. ej."position". - motors (
str | int | Sequence[str | int], opcional) — Motores a configurar, por nombre o id.Noneselecciona todos los motores.
Lanza
ValueError
ValueError— Si un motor seleccionado no tiene dicho modo; en ese caso, ningún motor ha cambiado de modo.
Ponga los motores seleccionados en un modo de funcionamiento, indicado por nombre.
Los modos provienen de la definición de cada motor, por lo que dependen del modelo, no solo de la familia: el Feetech SCS0009 no tiene ninguno. El modo debe existir para cada motor seleccionado, lo cual se verifica antes de que ningún motor cambie de modo. Escríbelo con el par desactivado.
position: contiene una posición objetivo dentro de un turno y los límites de posición.velocity: gira de forma continua a una velocidad objetivo, como una rueda.pwm: controla directamente el voltaje del motor, en bucle abierto.step(Feetech): se mueve según el número de pasos escrito como posición objetivo.current(Dynamixel): mantiene una corriente objetivo, es decir, un par, independientemente de la posición.extended_position(Dynamixel): mantiene una posición objetivo durante varias vueltas. Los registrosMin_Position_LimityMax_Position_Limitse ignoran en este modo.current_based_position(Dynamixel): mantiene una posición objetivo durante varias vueltas con la corriente limitada por la corriente objetivo, como una pinza que no debe aplastar lo que sujeta.
setup_motor
< source >( motor: strinitial_baudrate: int | None = Noneinitial_id: int | None = None )
Parámetros
- motor (
str) — Nombre del motor. - initial_baudrate (
int, opcional) — Velocidad en baudios a la que responde el motor actualmente. - initial_id (
int, opcional) — Id al que responde el motor ahora, se usa coninitial_baudrate.
Lanza
RuntimeError o ConnectionError
RuntimeError— Si el motor no se encuentra, no es de su modelo o no responde según lo configurado una vez establecido.ConnectionError— Si la comunicación con el motor falla.
Asigna un id a un motor único y la velocidad de baudios predeterminada del bus.
El motor debe ser el único en el bus. A menos que se indiquen tanto initial_baudrate como initial_id, primero se localiza: a initial_baudrate si solo se indica ese, de lo contrario entre las tasas de baudios de su modelo; un initial_id indicado por separado se reemplaza por el id encontrado. rustypot luego desactiva su par, abre su EEPROM y escribe el id y la tasa de baudios.
setup_motors
< source >( motors: Sequence[str] | None = None )
Configura los motores uno a la vez, pidiendo que cada uno esté solo en el bus.
sync_read
< source >( data_name: strmotors: NameOrID | Sequence[NameOrID] | None = Nonenormalize: bool = Truenum_retry: int = 0 ) → dict[str, int | float]
Parámetros
- data_name (
str) — Nombre de registro, p. ej."Present_Position"; no distingue entre mayúsculas y minúsculas. - motors (
str | int | Sequence[str | int], opcional) — Motores a leer, por nombre o id.Nonelee todos los motores. - normalize (
bool, opcional, valor predeterminadoTrue) — Si se deben escalar las posiciones al rango que definen su modo de calibración y de norma. - num_retry (
int, opcional, valor predeterminado0) — Intentos adicionales tras un fallo de comunicación. Un reintento envía de nuevo a todos los grupos, incluidos aquellos que ya habían tenido éxito; un motor o registro desconocido nunca se reintenta.
Devuelve
dict[str, int | float]
El valor de cada motor, por nombre.
Lanza
ConnectionError o RuntimeError
ConnectionError— Si un motor no responde.RuntimeError— Si un motor rechaza la lectura. Una alarma en un estado, como una sobrecarga, no genera una excepción.
Leer un registro de varios motores.
rustypot envía una lectura sincronizada por cada grupo de motores que comparten un protocolo y la dirección y el tamaño del registro, y lee los motores de un servo sin lectura sincronizada, como el Feetech SCS, uno tras otro. Por lo tanto, los valores no constituyen una instantánea simultánea.
sync_write
< source >( data_name: strvalues: Value | dict[str, Value]normalize: bool = Truenum_retry: int = 0 )
Parámetros
- data_name (
str) — Nombre de registro, p. ej."Goal_Position"; no distingue entre mayúsculas y minúsculas. - values (
int | float | dict[str, int | float]) — Un valor para cada motor, o un valor por nombre de motor. - normalize (
bool, opcional, valor predeterminadoTrue) — Si las posiciones se dan en el rango que definen su calibración y modo de normalización. - num_retry (
int, opcional, valor predeterminado0) — Intentos adicionales tras un fallo del puerto. Un reintento envía de nuevo todos los grupos.
Lanza
ConnectionError
ConnectionError— Si el puerto falla.
Escribe un registro de varios motores, sin esperar una respuesta.
A diferencia de ~SerialMotorsBus.write, ningún motor responde a una escritura síncrona: es más rápida, apta para bucles de control, pero un paquete perdido pasa desapercibido. rustypot envía una Sync Write por cada grupo de motores que comparten un protocolo y la dirección y el tamaño del registro.
torque_disabled
< source >( motors: NameOrID | Sequence[NameOrID] | None = None )
Desactive el par de los motores seleccionados durante la duración de un bloque with.
El par se vuelve a habilitar al salir, incluso cuando el bloque lanza una excepción, lo cual es adecuado para configurar motores.
write
< source >( data_name: strmotor: strvalue: Valuenormalize: bool = Truenum_retry: int = 0 )
Parámetros
- data_name (
str) — Nombre de registro, p. ej."Goal_Position"; no distingue entre mayúsculas y minúsculas. - motor (
str) — Motor name. - value (
int | float) — Valor a escribir, normalizado o crudo según indiquenormalize. - normalize (
bool, opcional, valor predeterminadoTrue) — Indica si una posición se proporciona dentro del rango definido por su modo de calibración y normalización. - num_retry (
int, opcional, valor predeterminado0) — Intentos adicionales tras un fallo de comunicación.
Lanza
ConnectionError o RuntimeError
ConnectionError— Si el motor no responde.RuntimeError— Si el motor rechaza la escritura. Una alarma en su estado, como una sobrecarga, no la genera.
Escribe un registro de un motor y espera su respuesta.
A diferencia de ~SerialMotorsBus.sync_write, el motor confirma la escritura, por lo que se informa de un posible fallo: es más lento, pero está diseñado para configurar motores.
write_calibration
< source >( calibration_dict: dict[str, MotorCalibration]cache: bool = True )
Escribe una calibración para los motores y, de forma predeterminada, almacénala en caché.
Los límites de posición se escriben en cada motor, y el desplazamiento de homing en los motores que lo tienen. Ni el id ni el modo de conducción se escriben: el modo de conducción de un Feetech se aplica en software al normalizar, y el registro Drive_Mode de un Dynamixel se configura por separado.
Motor
clase lerobot.motors.Motor
< source >( id: intmodel: strnorm_mode: MotorNormModemotor_type_str: str | None = Nonerecv_id: int | None = None )
MotorCalibration
clase lerobot.motors.MotorCalibration
< source >( id: intdrive_mode: inthoming_offset: intrange_min: intrange_max: int )
MotorNormMode
DriveMode
DriveMode tiene dos miembros, NON_INVERTED = 0 y INVERTED = 1. Utilice .value donde se espera un entero, en un registro Drive_Mode o en MotorCalibration.drive_mode:
bus.write("Drive_Mode", "elbow_flex", DriveMode.INVERTED.value)Valor del registro Drive_Mode de un Dynamixel y de MotorCalibration.drive_mode.