LeRobot documentation
Moteurs
Moteurs
SerialMotorsBus est l’interface de bas niveau vers une chaîne de servomoteurs Feetech ou Dynamixel sur un bus série. Les robots l’utilisent
pour lire les positions et écrire les positions cibles ; vous n’y touchez presque jamais directement, sauf si vous ajoutez du matériel. Le modèle de chaque moteur
est recherché dans rustypot, qui contient les tables de contrôle et les
caractéristiques qui diffèrent entre les familles, et qui gère également le port série. FeetechMotorsBus et DynamixelMotorsBus sont
des alias obsolètes de celui-ci, conservés pour une seule version.
Migration depuis les bus basés sur le SDK
Les alias conservent les noms de classes, et non les anciens attributs du SDK et les tables de modèles :
bus.model_resolution_table[model]devientbus.resolution(model); les autres tables de modèles (model_ctrl_table,model_number_table, …) sont désormais les définitions de servos de rustypot.- Les modes de fonctionnement sont sélectionnés par leur nom,
bus.set_operating_mode("position"), au lieu d’écrire une valeurOperatingModedans le registreOperating_Mode. - Le port SDK et les gestionnaires de paquets ne sont plus exposés : rustypot possède le port série.
protocol_versionest ignoré : le modèle de chaque moteur fournit son protocole.
Consultez Bring Your Own Hardware pour ajouter un nouveau bus, ainsi que Updating Feetech Firmware et Damiao Motors and CAN Bus pour les notes spécifiques aux appareils.
SerialMotorsBus
classe lerobot.motors.SerialMotorsBus
< source >( port: strmotors: dict[str, Motor]calibration: dict[str, MotorCalibration] | None = None )
Lire et écrire une chaîne de servos connectés en cascade sur un port série unique, Feetech ou Dynamixel.
rustypot gère les métadonnées de chaque modèle (table de contrôle, résolution, débits, modes de fonctionnement) ainsi que l’entrée/sortie série ; LeRobot gère la normalisation, l’étalonnage et les paramètres recommandés. Les moteurs de plusieurs modèles, tels que STS et SCS ou XL430 et XL330, partagent le port.
Pour trouver le port, exécutez :
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.Exemple pour un seul Feetech sts3215 sur le 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 )
Paramètres
- return_delay_time (
int, facultatif, par défaut0) — Délai avant qu'un moteur ne réponde, en unités de 2 µs ; les moteurs quittent l'usine avec une valeur de 250 (500 µs). - maximum_acceleration (
int, facultatif, valeur par défaut254) — Plafond d'accélération, sur les servomoteurs qui en disposent (Feetech STS), une valeur élevée accélère l'accélération et le ralentissement. - acceleration (
int, facultatif, par défaut254) — Accélération, sur les servomoteurs qui en disposent (Feetech).
Écrivez les paramètres recommandés par LeRobot sur chaque moteur.
connect
< source >( handshake: bool = True )
Paramètres
- handshake (
bool, facultatif, par défautTrue) — Indique s'il faut vérifier que chaque moteur répond avec le numéro de modèle de son modèle, et que les moteurs Feetech d'une même définition exécutent un même firmware.
Lève
DeviceAlreadyConnectedError ou ConnectionError ou RuntimeError
DeviceAlreadyConnectedError— Si le port est déjà ouvert.ConnectionError— Si le port n’a pas pu être ouvert.RuntimeError— Si la poignée de main échoue ; le port est à nouveau fermé.
Ouvrez le port série et vérifiez les moteurs.
disable_torque
< source >( motors: NameOrID | Sequence[NameOrID] | None = Nonenum_retry: int = 0 )
Paramètres
- motors (
str | int | Sequence[str | int], facultatif) — Moteurs à libérer, par nom ou par identifiant.Nonesélectionne tous les moteurs. - num_retry (
int, facultatif, par défaut0) — Tentatives supplémentaires sur chaque moteur après un échec de communication.
Lève
ConnectionError
ConnectionError— Si certains moteurs n’ont pas pu être atteints ; le message les nomme.
Désactiver le couple des moteurs sélectionnés.
Avec le couple désactivé, l’EEPROM d’un moteur peut être écrite, et le verrouillage d’un moteur Feetech s’ouvre pour cela. Chaque moteur sélectionné est tenté ; les échecs sont signalés, et les moteurs sans réponse peuvent rester avec le couple activé.
déconnecter
< source >( disable_torque: bool = True )
Fermez le port série, par défaut avec le couple de chaque moteur désactivé.
Sûr à appeler sur un bus déjà déconnecté, et le port est libéré même si la désactivation du couple échoue.
enable_torque
< source >( motors: NameOrID | Sequence[NameOrID] | None = Nonenum_retry: int = 0 )
Paramètres
- motors (
str | int | Sequence[str | int], facultatif) — Moteurs à maintenir, par nom ou par identifiant.Nonesélectionne tous les moteurs. - num_retry (
int, facultatif, par défaut0) — Tentatives supplémentaires sur chaque moteur après un échec de communication.
Lève
ConnectionError
ConnectionError— Si certains moteurs n’ont pas pu être atteints ; le message les nomme.
Activez le couple des moteurs sélectionnés et fermez le verrouillage des moteurs Feetech.
ping
< source >( motor: NameOrIDnum_retry: int = 0 ) → int | None
Le numéro de modèle auquel un moteur répond.
Lit Model_Number plutôt que d’envoyer un ping : la présence et l’identité ne coûtent alors qu’un aller-retour au lieu de deux.
lecture
< source >( data_name: strmotor: strnormalize: bool = Truenum_retry: int = 0 ) → int | float
Paramètres
- data_name (
str) — Nom d’enregistrement, par ex."Present_Position"; la casse n’a pas d’importance. - motor (
str) — Nom du moteur. - normalize (
bool, facultatif, par défautTrue) — Indique s'il faut mettre à l'échelle une position dans l'intervalle défini par son mode de calibration et de norme. - num_retry (
int, facultatif, par défaut0) — Tentatives supplémentaires après un échec de communication.
Retourne
int | float
La valeur brute, ou la valeur normalisée.
Lève
ConnectionError ou RuntimeError
ConnectionError— Si le moteur ne répond pas.RuntimeError— Si le moteur refuse la lecture. Une alarme dans son état, comme une surcharge, ne déclenche pas d’exception.
Lire un registre d'un moteur.
read_calibration
< source >( ) → dict[str, MotorCalibration]
Retourne
dict[str, MotorCalibration]
La calibration de chaque moteur, par nom.
Lisez la calibration de chaque moteur.
Un moteur sans registre de décalage de position zéro (Feetech SCS) renvoie 0, et un moteur sans registre Drive_Mode (Feetech) renvoie le mode de conduite 0.
record_calibration
< source >( mode: strfull_turn_motors: Sequence[str]inverted_motors: Sequence[str] = ()motors: Sequence[str] | None = None ) → dict[str, MotorCalibration]
Paramètres
- mode (
str) — Mode de fonctionnement des moteurs, par exemple"position". - full_turn_motors (
Sequence[str]) — Moteurs qui reçoivent la plage complète de l'encodeur au lieu de la plage parcourue. - inverted_motors (
Sequence[str], facultatif, par défaut()) — Moteurs tournant dans le sens inverse. - motors (
Sequence[str], facultatif) — Moteurs à calibrer.Nonecalibre tous les moteurs.
Retourne
dict[str, MotorCalibration]
La calibration de chaque moteur, dans l'ordre du bus.
Lève
ValueError
ValueError— Si un moteur n'est pas sur le bus, ou si un moteur complet ou inversé n'est pas l'un des moteurs à calibrer ; aucun moteur n'a alors été modifié.
Calibrer les moteurs déplacés à la main.
Les moteurs sélectionnés sont libérés, placés en mode de fonctionnement et leur direction est définie : un moteur doté d'un registre Drive_Mode reçoit une écriture, inversée ou non, tandis que pour les autres, en tant que servomoteurs Feetech, une inversion est appliquée logiciellement lors de la normalisation. L'utilisateur maintient ensuite les articulations au milieu de leur plage de mouvement, ce qui correspond à un demi-tour de chaque moteur, et fait parcourir à chaque articulation toute sa plage, en enregistrant jusqu'à la touche ENTER. Un moteur à rotation complète n'est pas enregistré : il couvre l'ensemble de l'encodeur de son modèle.
Les moteurs ont besoin du mode de fonctionnement et d'un décalage de référence, dont le Feetech SCS0009 ne dispose pas. Leurs décalages de référence et limites de position sont réécrits, le calibration mis en cache est effacé et leur couple reste désactivé. La calibration renvoyée n'est ni écrite dans les limites de position ni sauvegardée : ~SerialMotorsBus.write_calibration l'écrit et l'appareil la sauvegarde.
record_ranges_of_motion
< source >( motors: NameOrID | Sequence[NameOrID] | None = Nonedisplay_values: bool = True ) → tuple[dict[str, int | float], dict[str, int | float]]
Paramètres
- motors (
str | int | Sequence[str | int], facultatif) — Moteurs à enregistrer, par nom ou par identifiant.Nonesélectionne tous les moteurs. - display_values (
bool, facultatif, par défautTrue) — Indique s'il faut afficher le tableau en direct.
Retourne
tuple[dict[str, int | float], dict[str, int | float]]
La position brute la plus basse et la plus haute de chaque moteur, par nom.
Lève
ValueError
ValueError— Si un moteur ne s'est pas déplacé : sa position la plus basse et sa position la plus haute sont égales.
Enregistrez la plage de déplacement parcourue manuellement par chaque moteur sélectionné, jusqu'à la touche ENTER.
Les articulations sont déplacées à la main, le couple étant désactivé, tandis qu'un tableau en direct affiche les positions.
reset_calibration
< source >( motors: NameOrID | Sequence[NameOrID] | None = None )
Restaurer l'étalonnage d'usine des moteurs sélectionnés.
Le décalage de retour à la position de référence est défini sur 0 pour les moteurs qui en sont équipés, et les limites de position couvrent l'ensemble de l'encodeur. Le calibration mis en cache est effacé.
résolution
< source >( model: str ) → int
Étapes de l'encodeur par tour d'un modèle de moteur.
set_baudrate
< source >( baudrate: int )
Modifiez le taux de bauds du port ouvert.
Le port s'ouvre à default_baudrate à chaque connexion.
set_half_turn_homings
< source >( motors: NameOrID | Sequence[NameOrID] | None = None ) → dict[str, int]
Paramètres
- motors (
str | int | Sequence[str | int], facultatif) — Moteurs à ramener à la position d'origine, par nom ou par identifiant.Nonesélectionne tous les moteurs.
Retourne
dict[str, int]
Le décalage de retour à la position zéro écrit sur chaque moteur, par nom.
Lève
ValueError
ValueError— Si un moteur sélectionné ne possède pas de décalage de mise à l'origine, comme le Feetech SCS.
Faire effectuer à chaque moteur sélectionné une demi-tour.
La calibration des moteurs est réinitialisée, puis chacun reçoit le décalage de référence qui amène sa position actuelle à la moitié de son encodeur, par exemple 2047 pour un encodeur sur 12 bits. Chaque moteur sélectionné doit avoir un décalage de référence, ce qui est vérifié avant l'écriture de tout registre.
set_operating_mode
< source >( mode: strmotors: NameOrID | Sequence[NameOrID] | None = None )
Paramètres
- mode (
str) — Nom du mode de fonctionnement, par exemple"position". - motors (
str | int | Sequence[str | int], facultatif) — Moteurs à définir, par nom ou par identifiant.Nonesélectionne tous les moteurs.
Lève
ValueError
ValueError— Si le moteur sélectionné ne possède pas ce mode ; aucun moteur n'a alors changé de mode.
Placez les moteurs sélectionnés dans un mode de fonctionnement, spécifié par son nom.
Les modes proviennent de la définition de chaque moteur, ils dépendent donc du modèle et pas seulement de la famille : le Feetech SCS0009 n’en possède aucun. Le mode doit exister pour chaque moteur sélectionné, ce qui est vérifié avant que n’importe quel moteur ne change de mode. Écrivez-le avec le couple désactivé.
position: contient une position cible au sein d'un tour ainsi que les limites de position.velocity: tourne en continu à une vitesse cible, comme une roue.pwm: pilote directement la tension du moteur, en boucle ouverte.step(Feetech) : se déplace du nombre d'étapes indiqué comme position cible.current(Dynamixel) : conserve un courant cible, c'est-à-dire un couple, quelle que soit la position.extended_position(Dynamixel) : maintient une position cible sur plusieurs tours. Les registresMin_Position_LimitetMax_Position_Limitsont ignorés dans ce mode.current_based_position(Dynamixel) : maintient une position cible sur plusieurs tours, avec le courant limité par le courant cible, comme une pince qui ne doit pas écraser ce qu’elle tient.
setup_motor
< source >( motor: strinitial_baudrate: int | None = Noneinitial_id: int | None = None )
Paramètres
- motor (
str) — Nom du moteur. - initial_baudrate (
int, facultatif) — Vitesse en bauds à laquelle le moteur répond actuellement. - initial_id (
int, facultatif) — Identifiant auquel le moteur répond actuellement, utilisé avecinitial_baudrate.
Lève
RuntimeError ou ConnectionError
RuntimeError— Si le moteur n'est pas trouvé, n'est pas de son modèle, ou ne répond pas comme configuré une fois mis en place.ConnectionError— Si la communication avec le moteur échoue.
Donnez à un moteur unique son identifiant et le taux de baud par défaut du bus.
Le moteur doit être le seul sur le bus. À moins que initial_baudrate et initial_id soient tous deux fournis, il est d’abord détecté : à initial_baudrate si seul celui-ci est fourni, sinon parmi les débits de son modèle ; un initial_id fourni seul est remplacé par l’id trouvé. rustypot désactive ensuite son couple, ouvre son EEPROM et y écrit l’id et le débit.
setup_motors
< source >( motors: Sequence[str] | None = None )
Configurez les moteurs un par un, en demandant à chacun d’être seul sur le bus.
sync_read
< source >( data_name: strmotors: NameOrID | Sequence[NameOrID] | None = Nonenormalize: bool = Truenum_retry: int = 0 ) → dict[str, int | float]
Paramètres
- data_name (
str) — Nom d’enregistrement, par ex."Present_Position"; la casse n’a pas d’importance. - motors (
str | int | Sequence[str | int], facultatif) — Moteurs à lire, par nom ou par identifiant.Nonelit tous les moteurs. - normalize (
bool, facultatif, par défautTrue) — Indique s'il faut mettre à l'échelle les positions selon l'intervalle défini par leur mode de calibration et de norme. - num_retry (
int, facultatif, par défaut0) — Tentatives supplémentaires après un échec de communication. Une nouvelle tentative renvoie tous les groupes, y compris ceux qui avaient réussi ; un moteur ou un registre inconnu n’est jamais retenté.
Retourne
dict[str, int | float]
La valeur de chaque moteur, par nom.
Lève
ConnectionError ou RuntimeError
ConnectionError— Si un moteur ne répond pas.RuntimeError— Si un moteur refuse la lecture. Une alarme dans un statut, comme une surcharge, ne lève pas d’exception.
Lire un registre de plusieurs moteurs.
rustypot envoie une lecture synchronisée par groupe de moteurs partageant un protocole ainsi que l’adresse et la taille du registre, et lit les moteurs d’un servomoteur sans lecture synchronisée, comme le Feetech SCS, l’un après l’autre. Les valeurs ne constituent donc pas un instantané simultané.
sync_write
< source >( data_name: strvalues: Value | dict[str, Value]normalize: bool = Truenum_retry: int = 0 )
Paramètres
- data_name (
str) — Nom d’enregistrement, par ex."Goal_Position"; la casse n’a pas d’importance. - values (
int | float | dict[str, int | float]) — Une valeur pour chaque moteur, ou une valeur par nom de moteur. - normalize (
bool, facultatif, par défautTrue) — Indique si les positions sont fournies dans l'intervalle défini par leur mode de calibration et de normalisation. - num_retry (
int, facultatif, par défaut0) — Tentatives supplémentaires après un échec du port. Une nouvelle tentative renvoie chaque groupe.
Lève
ConnectionError
ConnectionError— Si le port échoue.
Écrivez un registre de plusieurs moteurs, sans attendre de réponse.
Contrairement à ~SerialMotorsBus.write, aucun moteur ne répond à une écriture synchrone : plus rapide, adaptée aux boucles de contrôle, mais un paquet perdu passe inaperçu. rustypot envoie une écriture synchrone par groupe de moteurs partageant un protocole ainsi que l’adresse et la taille du registre.
torque_disabled
< source >( motors: NameOrID | Sequence[NameOrID] | None = None )
Désactiver le couple des moteurs sélectionnés pendant la durée d'un bloc with.
Le couple est réactivé à la sortie, même si le bloc lève une exception, ce qui convient à la configuration des moteurs.
write
< source >( data_name: strmotor: strvalue: Valuenormalize: bool = Truenum_retry: int = 0 )
Paramètres
- data_name (
str) — Nom d’enregistrement, par ex."Goal_Position"; la casse n’a pas d’importance. - motor (
str) — Nom du moteur. - value (
int | float) — Valeur à écrire, normalisée ou brute selonnormalize. - normalize (
bool, facultatif, par défautTrue) — Indique si une position est donnée dans l'intervalle défini par son mode de calibration et de normalisation. - num_retry (
int, facultatif, par défaut0) — Tentatives supplémentaires après un échec de communication.
Lève
ConnectionError ou RuntimeError
ConnectionError— Si le moteur ne répond pas.RuntimeError— Si le moteur refuse l'écriture. Une alarme dans son état, comme une surcharge, ne déclenche pas d'exception.
Écrivez dans le registre d'un moteur et attendez sa réponse.
Contrairement à ~SerialMotorsBus.sync_write, le moteur accuse réception de l’écriture, si bien qu’un échec est signalé : plus lent, mais adapté à la configuration des moteurs.
write_calibration
< source >( calibration_dict: dict[str, MotorCalibration]cache: bool = True )
Paramètres
Écrivez une calibration vers les moteurs et, par défaut, mettez-la en cache.
Les limites de position sont écrites sur chaque moteur, et le décalage de référence sur les moteurs qui en ont un. Ni l’id ni le mode de pilotage ne sont écrits : le mode de pilotage d’un Feetech est appliqué en logiciel lors de la normalisation, et le registre Drive_Mode d’un Dynamixel est configuré séparément.
Moteur
classe lerobot.motors.Motor
< source >( id: intmodel: strnorm_mode: MotorNormModemotor_type_str: str | None = Nonerecv_id: int | None = None )
MotorCalibration
classe lerobot.motors.MotorCalibration
< source >( id: intdrive_mode: inthoming_offset: intrange_min: intrange_max: int )
MotorNormMode
DriveMode
DriveMode possède deux membres, NON_INVERTED = 0 et INVERTED = 1. Utilisez .value là où un entier est attendu, dans un registre Drive_Mode ou dans MotorCalibration.drive_mode :
bus.write("Drive_Mode", "elbow_flex", DriveMode.INVERTED.value)Valeur du registre Drive_Mode d'un Dynamixel, et de MotorCalibration.drive_mode.