LeRobot documentation

Téléphone

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.7.0).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

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 :

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 B1 pour 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 Move sur la page WebXR.
  • Contrôle de la pince (fonctionne que le bouton d'activation soit maintenu ou non) :
    • iOS : le curseur analogique A3 contrô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 A et B fonctionnent comme des incréments/décréments (A ouvre, B ferme). Vous pouvez régler la vitesse dans l'étape GripperVelocityToJoint.
  • 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.py dé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 par set_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.
Phone teleop orientation

É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 B1 pour capturer la pose de référence.
  • Android : appuyez sur le bouton Move de 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 SO101 depuis le dépôt SO-ARM100 vers examples/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/SO101

Utilisez --urdf pour 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

    --id sélectionne la calibration stockée à utiliser, et --urdf pointe 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.py
  • Exécutez cet exemple pour rejouer les épisodes enregistrés :

    cd examples/phone_to_so100
    python replay.py
  • Exé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_name sur 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 MapPhoneActionToRobotAction convertit 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 disabled
  • L'étape EEReferenceAndDelta convertit les deltas de cible en une pose EE absolue souhaitée, en stockant une référence lors de l'activation. Les end_effector_step_sizes sont 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 EEBoundsAndSafety limite 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é. Les end_effector_bounds sont les limites de la pose de l'EE et peuvent être modifiées pour changer l'espace de travail. Les max_ee_step_m sont 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 GripperVelocityToJoint convertit une entrée de pince de type vitesse en position absolue de pince à l'aide de l'état mesuré actuel. Le speed_factor est 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=True afin 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=False afin 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=True est recommandé pour la commande en boucle fermée ; définissez False pour 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é https au lieu de http, 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 MapPhoneActionToRobotAction ou é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.
Update on GitHub