LeRobot documentation
Téléphone
Téléphone
Utilisez votre téléphone (iOS ou Android) pour contrôler votre robot.
Dans ce guide, vous apprendrez :
- Comment connecter un téléphone iOS/Android
- Comment la pose du téléphone est mappée sur les cibles de l'effecteur terminal (EE) du robot
- Comment ajuster les limites de sécurité, le contrôle de la pince et les paramètres IK
Pour utiliser votre téléphone afin de contrôler votre robot, installez les dépendances pertinentes avec :
pip install 'lerobot[phone,kinematics,feetech,core_scripts]'kinematics fournit la cinématique inverse utilisée dans les exemples, feetech les moteurs SO-100/SO-101, et core_scripts les outils d’enregistrement et de visualisation.
Commencer
Plateformes prises en charge
- iOS : Utilise l’application HEBI Mobile I/O (pose ARKit + boutons). Téléchargez d’abord l’application, ouvrez-la et les exemples la détecteront sur votre réseau pour diffuser la pose du téléphone et les entrées.
- Android : utilise le package
teleop(WebXR). Lorsque vous démarrez le processus Python, il affiche une URL locale. Ouvrez le lien sur votre téléphone, appuyez sur Start, puis utilisez Move pour diffuser la pose.
Liens :
- Bibliothèque WebXR pour Android :
teleopsur PyPI - Application iOS : HEBI Mobile I/O
Orientation du téléphone et commandes
- Orientation : tenez le téléphone à l’horizontale, écran vers le haut, avec le bord supérieur pointant dans la même direction que la pince du robot. Cela garantit que l’étalonnage aligne le repère du téléphone avec le repère du robot, afin que le mouvement paraisse naturel. Reportez-vous à l’image ci-dessous pour référence.
- Activer/désactiver — il s'agit d'un interrupteur de sécurité, vous devez le maintenir enfoncé pendant tout le mouvement:
- iOS : Maintenez
B1pour déplacer le robot, relâchez pour figer le bras à sa position actuelle. Chaque appui ré-ancore le téléphone à la pose actuelle du bras, vous pouvez donc relâcher, ramener votre main à une position confortable, appuyer à nouveau et continuer — le robot ne saute pas. - Android : idem avec le bouton
Movesur la page WebXR.
- iOS : Maintenez
- Contrôle de la pince (fonctionne que le bouton d'activation soit maintenu ou non) :
- iOS : le curseur analogique
A3contrôle la pince en tant qu'entrée de vitesse — poussez vers le haut pour ouvrir, tirez vers le bas pour fermer, relâchez au centre pour maintenir. - Android : les boutons
AetBfonctionnent comme des incréments/décréments (A ouvre, B ferme). Vous pouvez régler la vitesse dans l'étapeGripperVelocityToJoint.
- iOS : le curseur analogique
- Prise : tenez le téléphone à deux mains, un pouce sur le bouton d’activation (
B1) et l’autre sur le curseur de la pince (A3), afin de piloter le bras et la pince simultanément sans changer de prise. Gardez le téléphone à plat pendant l’opération — sa position constitue la commande, donc le repositionner en cours de mouvement déplace le robot. - Pose de départ du robot :
teleoperate.pydéplace le bras vers sa pose de retour à la base au démarrage (avant la calibration du téléphone), et au Ctrl+C le ramène à la position où il se trouvait au lancement du script. Les commandes de retour à la base orientent chaque articulation du corps vers la valeur de demi-tour centrée parset_half_turn_homings()lors de la calibration — la pose représentée sur le schéma de calibration — tandis que la pince est laissée en place afin que le retour à la base ne la referme jamais sur un objet. Ce point est important car les cibles sont résolues par IK à partir de la position du bras au moment où vous appuyez sur le bouton d’activation — un bras replié ou entièrement tendu a peu de marge restante et atteint rapidement ses limites articulaires. Les autres scripts d’exemple (record.py,evaluate.py,replay.py) ne ramènent pas le bras à sa base, placez-le donc vous-même à cet endroit avant de les lancer.
Étape 1 : Choisir la plateforme
Modifiez les exemples pour utiliser PhoneOS.IOS ou PhoneOS.ANDROID dans PhoneConfig. L’API est identique sur toutes les plateformes, seule la source d’entrée diffère. Tous les exemples se trouvent dans examples/phone_to_so100/ : teleoperate.py, record.py, replay.py, evaluate.py et rollout.py.
Exemple de téléopération :
from lerobot.teleoperators.phone import Phone, PhoneConfig
from lerobot.teleoperators.phone.config_phone import PhoneOS
teleop_config = PhoneConfig(phone_os=PhoneOS.IOS) # or PhoneOS.ANDROID
teleop_device = Phone(teleop_config)Étape 2 : Connecter et calibrer
Lorsque Phone(teleop_config) est créé et que connect() est appelé, la calibration est demandée automatiquement. Tenez le téléphone dans l’orientation décrite ci-dessus, puis :
- iOS : appuyez longuement sur
B1pour capturer la pose de référence. - Android : appuyez sur le bouton
Movede la page WebXR pour capturer la pose de référence.
Pourquoi calibrer ? Nous capturons la pose actuelle afin que les poses suivantes soient exprimées dans un repère aligné sur le robot. Lorsque vous appuyez à nouveau sur le bouton pour activer le contrôle, la position est recapturée afin d'éviter tout dérive lorsque votre téléphone est repositionné pendant qu'il était désactivé.
Étape 3 : Exécuter un exemple
Exécutez l'un des scripts d'exemple pour téléopérer, enregistrer un jeu de données, rejouer un jeu de données ou évaluer une politique.
Tous les scripts supposent que vous avez configuré et calibré votre robot (par exemple, un suiveur SO-100).
Vous devez fournir le URDF du robot. Chaque exemple résout la cinématique inverse, qui nécessite un modèle cinématique du bras, et le URDF n’est pas fourni avec LeRobot.
Pour le SO-100/SO-101 utilisé dans ce tutoriel, copiez le dossier
SO101depuis le dépôt SO-ARM100 versexamples/phone_to_so100/, de sorte que le fichier se trouve àexamples/phone_to_so100/SO101/so101_new_calib.urdf, en étant dans le dépôt LeRobot :git clone --depth 1 https://github.com/TheRobotStudio/SO-ARM100.git /tmp/SO-ARM100 cp -r /tmp/SO-ARM100/Simulation/SO101 examples/phone_to_so100/SO101Utilisez
--urdfpour indiquer un autre fichier si vous le stockez ailleurs, ou si vous pilotez un autre bras robotique.
Exécutez cet exemple pour téléopérer, en passant le port série de votre bras suiveur (trouvez-le avec
lerobot-find-port) :cd examples/phone_to_so100 python teleoperate.py --port /dev/tty.usbmodem5A460814411--idsélectionne la calibration stockée à utiliser, et--urdfpointe vers le fichier URDF ci-dessus.
Après avoir exécuté l'exemple :
- Android : après avoir lancé le script, ouvrez l’URL locale affichée sur votre téléphone, appuyez sur Start, puis maintenez enfoncé Move.
- iOS : ouvrez d'abord HEBI Mobile I/O ; maintenez B1 enfoncé pour déplacer le robot. A3 contrôle la pince.
De plus, vous pouvez personnaliser le mapping ou les limites de sécurité en modifiant les étapes du processeur présentées dans les exemples. Vous pouvez également remapper les entrées (par exemple, utiliser une entrée analogique différente) ou adapter le pipeline à d'autres robots (par exemple, LeKiwi) en modifiant les étapes d'entrée et de cinématique. En savoir plus à ce sujet dans le guide Processors for Robots and Teleoperators.
Exécutez cet exemple pour enregistrer un jeu de données, qui sauvegarde les observations et les actions absolues de l'effecteur final :
cd examples/phone_to_so100 python record.pyExécutez cet exemple pour rejouer les épisodes enregistrés :
cd examples/phone_to_so100 python replay.pyExécutez cet exemple pour évaluer une politique pré-entraînée :
cd examples/phone_to_so100 python evaluate.py
Étapes et options importantes du pipeline
La cinématique est utilisée à plusieurs étapes. Nous utilisons Placo, un wrapper autour de Pinocchio pour gérer notre cinématique. Nous construisons l'objet cinématique en passant l'URDF du robot et le repère cible. Nous définissons
target_frame_namesur le repère de la pince.kinematics_solver = RobotKinematics( urdf_path="./SO101/so101_new_calib.urdf", target_frame_name="gripper_frame_link", joint_names=list(robot.bus.motors.keys()), )L'étape
MapPhoneActionToRobotActionconvertit la pose du téléphone calibrée et les entrées en deltas cibles et commandes de pince ; ci-dessous sont présentées les sorties de l'étape.action["enabled"] = enabled action["target_x"] = pos[1] if enabled else 0.0 action["target_y"] = -pos[0] if enabled else 0.0 action["target_z"] = pos[2] if enabled else 0.0 action["target_wx"] = rotvec[1] if enabled else 0.0 action["target_wy"] = -rotvec[0] if enabled else 0.0 action["target_wz"] = rotvec[2] if enabled else 0.0 action["gripper_vel"] = gripper_vel # Still send gripper action when disabledL'étape
EEReferenceAndDeltaconvertit les deltas de cible en une pose EE absolue souhaitée, en stockant une référence lors de l'activation. Lesend_effector_step_sizessont les tailles de pas pour la pose EE et peuvent être modifiées pour changer la vitesse du mouvement.EEReferenceAndDelta( kinematics=kinematics_solver, end_effector_step_sizes={"x": 0.5, "y": 0.5, "z": 0.5}, motor_names=list(robot.bus.motors.keys()), use_latched_reference=True, ),L'étape
EEBoundsAndSafetylimite le mouvement de l'EE à un espace de travail et vérifie les sauts de pas importants de l'EE pour garantir la sécurité. Lesend_effector_boundssont les limites de la pose de l'EE et peuvent être modifiées pour changer l'espace de travail. Lesmax_ee_step_msont les limites de pas de la pose de l'EE et peuvent être modifiées pour changer les limites de sécurité.EEBoundsAndSafety( end_effector_bounds={"min": [-1.0, -1.0, -1.0], "max": [1.0, 1.0, 1.0]}, max_ee_step_m=0.10, )L'étape
GripperVelocityToJointconvertit une entrée de pince de type vitesse en position absolue de pince à l'aide de l'état mesuré actuel. Lespeed_factorest le facteur par lequel la vitesse est multipliée.GripperVelocityToJoint(speed_factor=20.0)
Différentes estimations initiales IK
Nous utilisons différentes estimations initiales IK dans les étapes cinématiques. En tant qu'estimation initiale, on utilise soit les articulations mesurées actuelles, soit la solution IK précédente.
Boucle fermée (utilisée dans record/eval) : définit
initial_guess_current_joints=Trueafin que l'IK démarre des articulations mesurées à chaque image.InverseKinematicsEEToJoints( kinematics=kinematics_solver, motor_names=list(robot.bus.motors.keys()), initial_guess_current_joints=True, # closed loop )Boucle ouverte (utilisée lors de la rejouissance) : définit
initial_guess_current_joints=Falseafin que l'IK reprenne depuis la solution IK précédente plutôt que depuis l'état mesuré. Cela préserve la stabilité des actions lors d'une rejouissance sans retour d'information.InverseKinematicsEEToJoints( kinematics=kinematics_solver, motor_names=list(robot.bus.motors.keys()), initial_guess_current_joints=False, # open loop )
Explication des étapes du pipeline
- MapPhoneActionToRobotAction : convertit la pose et les entrées du téléphone calibrés en deltas cibles et en commande de pince. Le mouvement est conditionné par un signal d'activation (B1 sur iOS, Move sur Android).
- EEReferenceAndDelta : verrouille une pose de référence de l'effecteur sur activation et la combine avec les deltas de cible pour produire une pose absolue souhaitée de l'effecteur à chaque image. Lorsqu'il est désactivé, il continue d'envoyer la dernière pose commandée.
- EEBoundsAndSafety : limite la pose de l'EE à un espace de travail et limite le taux des sauts pour la sécurité. Déclare également les fonctionnalités
action.ee.*. - InverseKinematicsEEToJoints : convertit une pose d'effecteur terminal en positions articulaires par IK.
initial_guess_current_joints=Trueest recommandé pour la commande en boucle fermée ; définissezFalsepour la lecture en boucle ouverte afin d'assurer la stabilité. - GripperVelocityToJoint : intègre une entrée de pince de type vitesse en une position absolue de pince à l'aide de l'état mesuré actuel.
- ForwardKinematicsJointsToEE : calcule
observation.state.ee.*à partir des articulations observées pour la journalisation et l’entraînement sur l’état de l’effecteur terminal.
Dépannage
- iOS non détecté : assurez-vous que HEBI Mobile I/O est ouvert et que votre ordinateur portable et votre téléphone sont sur le même réseau.
- Impossible d’accéder à l’URL Android : vérifiez que vous avez utilisé
httpsau lieu dehttp, utilisez l’IP exacte affichée par le script et autorisez votre navigateur à entrer et à ignorer le problème de certificat. - Le mouvement semble inversé : vérifiez un axe à la fois, puis ajustez les inversions de signe dans
MapPhoneActionToRobotActionou échangez les axes pour correspondre à votre configuration. - Le bras bouge à peine ou bute sur ses limites : redémarrez depuis une pose de départ intermédiaire (voir ci-dessus) — la cinématique inverse est résolue à partir de la configuration actuelle du bras.