🧪 De nouveaux tutoriels arrivent — du bras robotique au capteur
Aller au contenu

Outils de bureau SCS0009 (GUI et CLI) ​

Cette page est le tutoriel de contrôle de bureau de la version à bus série SCS0009. Pour le contrôle web, voir Contrôle web SCS0009 ; pour le câblage matériel, voir Câblage SCS0009.

Démarrage rapide ​

  1. Installez Python 3.10+ et les dépendances : Installation.
  2. Connectez la carte de commande de bus et confirmez le port série : Prérequis.
  3. Lancez la GUI : amazing-hand-gui ou python amazing_hand_gui.py.
  4. Vérifiez main gauche/droite, angles et position médiane selon Calibration.
  5. Utilisez les curseurs doigt par doigt, les poses prédéfinies et les séquences pour exécuter des mouvements.

Outil de contrôle Python AmazingHand (compatible main gauche et droite) ​

Outil GUI et ligne de commande écrit en Python, pilotant 8 servos Feetech SCS0009 via une carte de commande de servos à bus série, pour la main dextre AmazingHand de Pollen Robotics.

Les deux mains sont prises en charge. Au démarrage, choisissez la main droite (ID de servo 1-8) ou la main gauche (ID de servo 11-18) ; --hand permet de sauter la question. La bibliothèque de poses est partagée entre les deux mains ; chaque main maintient dans data/config.yaml son propre mapping de servos, son décalage de montage et ses cibles en valeurs brutes. Voir la sélection gauche/droite.

Interface principale de l'outil de contrôle AmazingHand


Structure du projet ​

text
amazing_hand_gui.py   – programme principal GUI
amazing_hand_cmd.py   – outil en ligne de commande
hand_logic.py         – logique métier partagée (indépendante de l'UI)
pyproject.toml        – métadonnées du paquet, dépendances, configuration pytest
data/
  config.yaml         – paramètres de l'application (port série, limites, cibles en valeurs brutes)
  hand_config.yaml    – gestes et séquences enregistrés
docs/
  REQUIREMENTS.md       – exigences et critères d'acceptation
  CONFIG_FORMAT.md      – description du format des fichiers de configuration
  scs_servo_protocol.md – référence des registres SCS0009
  CHANGES.md            – modifications par rapport à la version d'origine et raisons
  user_manual.md        – page de redirection vers le tutoriel central
tests/
  test_hand_logic.py      – tests unitaires de hand_logic (155 éléments)
  test_gui_utils.py       – tests unitaires des fonctions utilitaires de la GUI (51 éléments)
  test_cmd.py             – tests unitaires de la CLI (42 éléments)
  test_integration.py     – tests d'intégration (14 éléments)
  test_system.py          – tests système par sous-processus (22 éléments)
  test_system_hardware.py – tests matériels (33 éléments, nécessite --hardware)
  test_cmd_hardware.py    – tests matériels de la CLI (21 éléments, nécessite --hardware)

Prérequis ​

  • Python 3.10 ou supérieur (la GUI nécessite Tkinter)
  • Une alimentation externe 5V indépendante pour les 8 servos
  • Un adaptateur USB-série à bus installé avec son pilote

Installation ​

Installation recommandée avec pip (lit pyproject.toml) :

bash
pip install -e .

Ou installez directement les dépendances :

bash
pip install -r requirements.txt

Environnement de développement et de test :

bash
pip install -r requirements-dev.txt

Calibration ​

Le système d'angles, les poses prédéfinies et la position médiane des servos dépendent de la main concrète. Tous ces paramètres sont centralisés dans data/config.yaml.

Sélection gauche/droite ​

Les deux mains n'utilisent ni les mêmes servos ni la même structure mécanique ; choisissez donc avant l'ouverture de l'interface :

text
  AmazingHand — which hand?
    1 = right hand  (servo IDs 1-8)
    2 = left hand   (servo IDs 11-18)
  Enter 1 or 2 [1]:
  LEFT hand — servo IDs 11-18
    Ring (11, 12)  Middle (13, 14)  Pointer (15, 16)  Thumb (17, 18)
    middle position raw: [571, 451, 571, 451, 571, 451, 571, 451]

Sauter la question :

bash
python amazing_hand_gui.py --hand left
python amazing_hand_cmd.py --pose victory --hand left

Sans --hand, la valeur hand: de data/config.yaml est utilisée.

Pourquoi une main ne se limite pas à changer de groupe d'ID. Outre la numérotation des servos (droite 1-8, gauche 11-18, avec une numérotation des doigts en miroir à gauche — annulaire en premier), la main gauche présente deux différences mécaniques que le programme gère automatiquement :

Main droiteMain gauche
ID de servo1-811-18
Doigt → IDIndex 1,2 / Majeur 3,4 / Annulaire 5,6 / Pouce 7,8Annulaire 11,12 / Majeur 13,14 / Index 15,16 / Pouce 17,18
MiddlePos constructeur[451, 571, …][571, 451, …]
Décalage de montage0°−35.16° (hands.left.angle_offset)
Deux servos d'un doigt(a, b)(b, a) (hands.left.mirror_pose)

Si l'un de ces deux derniers points est omis, tous les gestes seront déformés : le décalage de montage décale chaque doigt de 35°, et sans l'échange des deux servos du doigt, le sens d'ouverture s'inverse complètement (le geste en V referme les deux doigts concernés et ouvre les trois doigts qui devraient être serrés).

data/hand_config.yaml est partagé par les deux mains ; il stocke toujours l'ordre de la main droite ; la main gauche est convertie à la lecture et reconvertie à l'enregistrement.

Calibrer une nouvelle main. Prenez les valeurs de hands.left comme modèle, puis vérifiez dans cet ordre :

  1. Appuyez sur Middle position et vérifiez que la ligne Current (0-1023) lit les valeurs brutes attendues
  2. Appuyez sur Open All / Close All — la course doit atteindre les butées mécaniques sans blocage
  3. Essayez un geste d'ouverture (victory en V, greeting avec trois doigts serrés)

En cas d'écart, quel paramètre ajuster :

SymptômeOù modifier
Lecture de Middle position incorrectehands.<nom>.raw_positions.middle
Sens d'ouverture inverséhands.<nom>.mirror_pose
Course insuffisante ou excessivehands.<nom>.raw_positions.open / close

Système d'angles ​

La GUI et la CLI utilisent toutes deux des valeurs d'angle, converties en valeurs brutes internes du servo par le driver rustypot :

text
raw = 1024 × angle / 300° + 511        (0.29297°/pas, plage brute 0–1023)
AngleSignification
−35°complètement ouvert (tendu)
0°position médiane, doigts légèrement fléchis naturellement
+75°complètement serré (poing)

Les deux servos de chaque doigt sont côte à côte, axes colinéaires : une rotation dans le même sens produit l'écartement, une rotation en sens inverse produit la flexion. L'ID pair est inversé par rapport à l'ID impair, donc une même valeur d'ouverture/fermeture fait tourner les deux servos en sens opposés ; le programme gère cela automatiquement, aucune conversion manuelle n'est nécessaire.

Limites ​

text
limits:
  servo_min: -75      # limites de course absolues pour toute commande de servo
  servo_max: 75
  base_min: -75       # plage du curseur ouverture/fermeture
  base_max: 75
  side_min: -35       # plage du curseur gauche/droite
  side_max: 35

side_min/side_max contrôlent l'ouverture latérale. Comme le programme normalise (u = |side_offset| / |side_min|), modifier uniquement cette plage ne change pas l'amplitude réelle d'ouverture, mais comprime seulement l'échelle du curseur. Pour modifier réellement l'angle d'ouverture des doigts, il faut aussi modifier auto_extremes.

Cibles en valeurs brutes ​

Les trois boutons de position globale amènent les servos à des valeurs brutes exactes, sans passer par le modèle d'angle :

text
raw_positions:              # indice 0 -> servo ID 1 …… indice 7 -> servo ID 8
  open:   [260, 760, 260, 760, 260, 760, 260, 760]
  close:  [760, 260, 760, 260, 760, 260, 760, 260]
  middle: [451, 571, 451, 571, 451, 571, 451, 571]
  • open / close — les deux extrémités de la course mécanique. Mesurées en pilotant séparément les servos avec l'outil de débogage Feetech du constructeur.
  • middle — la position médiane mécanique après calibration (MiddlePos dans le programme de démonstration Arduino du constructeur). Attention : ce n'est pas le milieu entre open et close, mais un écart d'environ ±60 brut (±17.6°) par rapport à raw 511.

Ce sont des valeurs de calibration propres à chaque main. Le constructeur écrit : « replace values by your calibration results ».

Comment vérifier : le panneau Servo Feedback comporte une ligne Current (0-1023) qui affiche la position brute en temps réel. Après avoir appuyé sur Middle position, cette ligne doit lire 451, 571, 451, 571, ….

Aide-mémoire des plages de contrôle ​

ContrôlePlage
Curseur ouverture/fermeture (vertical)−75 … +75
Curseur gauche/droite (horizontal)−35 … +35
Vitesse1 (lent) … 6 (rapide)

La valeur de vitesse est transmise au servo par le driver en rad/s ; 1–6 correspond donc approximativement à 57–344 °/s. En charge, la vitesse réelle est d'environ 70 % de cette valeur — à prendre en compte lors du réglage des temporisations de séquence.


Lancer la GUI (amazing_hand_gui.py) ​

Interface principale AHC : contrôle doigt par doigt, boutons globaux, télémétrie et journal

L'interface se divise en quatre zones :

  • Colonne gauche : panneaux de contrôle doigt par doigt des quatre doigts, avec curseurs ouverture/fermeture et écartement, modes Auto/Raw, vitesse, Open/Close/Center.
  • Colonne centrale : boutons de contrôle globaux (Open All / Close All / Center All / Middle position) et gestion des poses.
  • Colonne droite : courbes de télémétrie et tableau Servo Feedback (position, charge, température, tension).
  • Bas : journal d'exécution et barre d'état, affichant l'état de connexion, la progression des mouvements et les erreurs.

Après installation via pip, appel direct :

text
amazing-hand-gui
amazing-hand-gui --port /dev/ttyUSB0

Ou exécution directe :

bash
python amazing_hand_gui.py
python amazing_hand_gui.py --port /dev/ttyUSB0

La liste déroulante des ports énumère les ports série réellement présents sur la machine (pyserial en priorité, sinon le registre Windows), de sorte que les adaptateurs aux numéros élevés apparaissent aussi. La liste permet la saisie directe du numéro de port. Si le port par défaut de la configuration n'est pas branché, la GUI démarre automatiquement sur le premier port réel ; pour fixer un port, passez --port explicitement.

Fonctionnalités ​

Panneau de contrôle doigt par doigt : modes Auto/Raw, vitesse et boutons rapides Open/Close/Center

  • Contrôle doigt par doigt de l'ouverture/fermeture et du gauche/droite, avec deux modes Auto (ouverture/fermeture + gauche/droite) et Raw (pilotage direct de l'angle des deux servos)

    Les deux curseurs du mode Auto sont des axes de commande ; le programme effectue automatiquement la composition différentielle. Le mode Raw envoie directement les angles des deux servos. Les deux servos de chaque doigt sont côte à côte, axes colinéaires : rotation dans le même sens = écartement, rotation en sens inverse = flexion.

  • Boutons rapides Open / Close / Center par doigt

  • Sélection de vitesse par doigt (1–6), plus une liste de synchronisation globale de vitesse

  • Raccourcis clavier pour les réglages fins précis

  • Boutons de position globale : Open All, Close All, Center All, Middle position

  • Gestion des gestes et séquences basée sur data/hand_config.yaml

  • Suppression directe des gestes enregistrés dans l'interface (bouton 🗑 Delete)

  • Courbes de télémétrie des servos en temps réel (position, charge, température, tension)

  • Tableau Servo Feedback avec position brute en temps réel (0–1023), utilisable pour vérifier la calibration

Commandes clavier ​

  • 1-4 : sélection du doigt (Ring annulaire, Middle majeur, Pointer index, Thumb pouce)
  • Flèches : déplacer le doigt sélectionné
    • Haut/Bas : serrer / ouvrir
    • Gauche/Droite : déplacement latéral
  • Touches modificatrices :
    • Aucune : 1° par fois (réglage fin)
    • Shift : 5° par fois (normal)
    • Ctrl : 10° par fois (rapide)
  • Actions rapides :
    • Q : serrer complètement le doigt sélectionné
    • E : ouvrir complètement le doigt sélectionné
    • C : recentrer la position latérale

Boutons globaux ​

BoutonOuverture/fermetureGauche/droite
✋ Open AllTous les doigts à la valeur brute openRecentrage
✊ Close AllTous les doigts à la valeur brute closeRecentrage
⊙ Center AllInchangéRecentrage
⊙ Middle positionTous les doigts à la valeur brute middleRecentrage

La liste Global Speed (1–6) applique immédiatement la vitesse choisie à tous les contrôles de doigt et synchronise l'affichage des curseurs de chaque doigt.

Les trois boutons de valeur brute (Open All, Close All, Middle position) contournent le modèle d'angle ; après exécution, les curseurs affichent donc la valeur représentable la plus proche, et non la valeur exacte. Toucher ensuite un curseur écarte la main de la cible brute d'environ 0.3° au maximum — c'est un compromis assumé pour atteindre précisément la position calibrée.

Problème connu : Center All ne saute pas les doigts en mode Raw et écrase les angles bruts réglés manuellement. Le bouton ⊙ Center d'un doigt individuel, lui, ne le fait pas.


Lancer la CLI (amazing_hand_cmd.py) ​

Outil en ligne de commande autonome, qui applique gestes et séquences sans lancer la GUI. Il lit le même data/hand_config.yaml que la GUI et envoie mot pour mot les valeurs de pose stockées — exactement ce que la GUI émet.

Linux : permissions du port série ​

L'adaptateur USB-série apparaît généralement comme /dev/ttyACM0 (Waveshare / CDC-ACM) ou /dev/ttyUSB0 (FTDI / CH340).

Pour les trouver :

bash
ls /dev/ttyACM* /dev/ttyUSB* 2>/dev/null
# ou
dmesg | grep -E 'ttyACM|ttyUSB' | tail -5

En cas de Permission denied, ajoutez l'utilisateur courant au groupe dialout puis reconnectez-vous :

bash
sudo usermod -aG dialout $USER

Après installation via pip ​

text
amazing-hand-cmd --list
amazing-hand-cmd --pose open
amazing-hand-cmd --sequence demo --loop
amazing-hand-cmd --pose open --speed 6
# remplacer le port si nécessaire :
amazing-hand-cmd --pose open --port /dev/ttyUSB0

Exécution directe ​

bash
python amazing_hand_cmd.py --list
python amazing_hand_cmd.py --pose open
python amazing_hand_cmd.py --pose close --speed 6
python amazing_hand_cmd.py --sequence demo
python amazing_hand_cmd.py --sequence wave --loop
python amazing_hand_cmd.py --port /dev/ttyUSB0 --pose open
python amazing_hand_cmd.py --list --config /path/to/hand_config.yaml

Paramètres ​

ParamètreValeur par défautDescription
--pose NAME–applique le geste nommé
--sequence NAME–joue la séquence nommée
--list–liste tous les gestes et séquences
--loopdésactivélecture en boucle de la séquence jusqu'à Ctrl+C
--speed N3vitesse des servos 1 (lent)… 6 (rapide)
--port PORTLinux /dev/ttyACM0
Windows COM9
numéro du port série
--baudrate N1000000débit
--config PATHdata/hand_config.yamlspécifie un autre fichier de configuration
--handhand de config.yamlmain à utiliser (droite 1-8, gauche 11-18)

À la sortie du script (Ctrl+C compris), le couple de tous les servos est automatiquement coupé.

La CLI n'a pas de paramètre --config correspondant à data/config.yaml ; ce fichier est toujours chargé depuis le répertoire du projet.


Fichiers de configuration ​

data/config.yaml ​

SectionRôle
serialport série par défaut selon la plateforme, débit, liste des débits possibles
servosID de servo correspondant à chaque doigt
limitsplages d'angle des servos et des deux curseurs
speedsvaleur par défaut/min/max de l'échelle de vitesse 1–6
auto_extremesposition des servos aux butées du curseur gauche/droite
raw_positionscibles exactes en valeurs brutes des boutons de position globale
pathsemplacement des fichiers de gestes/séquences

Correspondance servos / doigts ​

DoigtID de servoIndice dans le tableau de pose
Pointer index1, 24, 5
Middle majeur3, 42, 3
Ring annulaire5, 60, 1
Thumb pouce7, 86, 7

L'ordre du tableau de pose est annulaire, majeur, index, pouce, et non l'ordre des ID de servo. C'est le point le plus facile à se tromper lors de l'édition manuelle de hand_config.yaml.

Le commentaire en tête de amazing_hand_cmd.py dit « index 0→servo1 … 7→servo8 » ; ce commentaire est faux, c'est le tableau ci-dessus qui décrit le comportement réel du code.


Gestes et séquences ​

Panneau de gestion des poses

Tous les gestes et séquences sont enregistrés dans data/hand_config.yaml. Si le fichier n'existe pas, la GUI le crée automatiquement.

Enregistrer un geste ​

  1. Placez la main dans la pose cible avec les curseurs ou le clavier
  2. Saisissez un nom dans le champ « Name: »
  3. Cliquez sur « ➕ Add New » dans la zone Pose Management

La vitesse n'affecte que la vitesse de déplacement des curseurs ; le geste enregistré ne mémorise que les 8 positions de servos.

Charger / supprimer un geste ​

  • Après sélection dans la liste, cliquez sur ✓ Apply pour amener la main à cette pose
  • Cliquez sur 🗑 Delete à droite d'Apply ; après confirmation, suppression définitive

Gestion des séquences ​

  1. Dans Sequence Player, cliquez sur « 🔧 Manage » pour ouvrir le gestionnaire de séquences
  2. Saved Sequences (colonne de gauche)
  • Afficher, exécuter, éditer ou supprimer une séquence existante
  • Double-clic ou clic sur « ▶ Execute » pour l'exécuter une fois
  1. Sequence Builder (colonne de droite)
  • Double-cliquez sur un geste de « Available Poses » pour l'ajouter comme étape
  • Réglez la vitesse et le délai des 8 servos pour chaque étape ; les étapes sont enregistrées au format « pose:s1,s2,...,s8|delay »
  • Utilisez ↑/↓ pour réordonner, ou le bouton « ⏱ Delay » pour insérer une pause indépendante
  • Après avoir saisi un nom, cliquez sur « 💾 Save Sequence » pour enregistrer ; « ▶ Execute » permet d'essayer sans enregistrer
  1. De retour dans la fenêtre principale, cochez Loop dans Sequence Player pour une lecture continue

Éditeur de séquences

Format des étapes ​

text
pose_name:speed1,speed2,...,speed8|delay
  • speed1..speed8 — vitesses des 8 servos dans l'ordre de la pose (1–6)
  • delay — temps d'attente avant l'étape suivante, par exemple 0.6s. Facultatif ; s'il est omis, la GUI revient à une attente automatique fixe
  • Une pause indépendante s'écrit SLEEP:1.0s (sans liste de vitesses séparées par des virgules)

Choix des temporisations. Le driver sait lire si un servo est arrêté, mais la lecture de séquence utilise des temporisations fixes. Estimez grossièrement en secondes : angle de course / (vitesse × 57.3 × 0.7), en gardant une marge — sur une main en charge, un mouvement de plus d'environ 130° demande plus de 1.0 seconde à la vitesse 3.

Exemple de format YAML ​

text
poses:
  open:
    positions: [-35, -35, -35, -35, -35, -35, -35, -35]
  close:
    positions: [75, 75, 75, 75, 75, 75, 75, 75]
  ring_close:                 # annulaire serré, les autres ouverts
    positions: [75, 75, -35, -35, -35, -35, -35, -35]

sequences:
  demo:
    steps:
      - "open:3,3,3,3,3,3,3,3|2.0s"
      - "close:6,6,6,6,6,6,6,6|2.0s"
      - "ok:3,3,3,3,3,3,3,3|1.0s"
      - "victory:3,3,3,3,3,3,3,3|1.0s"
      - "greeting:3,3,3,3,3,3,3,3|1.5s"
      - "close:6,6,6,6,6,6,6,6|2.0s"
  wave:
    steps:
      - "open:6,6,6,6,6,6,6,6|0.8s"
      - "wave_r:5,5,5,5,5,5,5,5|0.6s"
      - "wave_l:5,5,5,5,5,5,5,5|0.6s"
      - "open:5,5,5,5,5,5,5,5|0.8s"
  finger_roll:
    steps:
      - "open:6,6,6,6,6,6,6,6|0.5s"
      - "ring_close:5,5,5,5,5,5,5,5|0.6s"
      - "open:5,5,5,5,5,5,5,5|0.5s"
      - "middle_close:5,5,5,5,5,5,5,5|0.6s"
      - "open:5,5,5,5,5,5,5,5|0.5s"

La lecture en boucle est contrôlée au runtime (case à cocher de la GUI) et n'est plus écrite dans le YAML.


Tests ​

Le projet contient 284 tests unitaires/intégration/système et 54 tests matériels.

Exécuter tous les tests (sans matériel) ​

text
pytest

Exécuter les tests matériels GUI + CLI (servos connectés) ​

text
pytest tests/test_system_hardware.py --hardware --port /dev/ttyACM0
pytest tests/test_cmd_hardware.py --hardware --port /dev/ttyACM0
# ou les deux ensemble :
pytest tests/test_system_hardware.py tests/test_cmd_hardware.py --hardware

test_system_hardware.py vérifie la connexion, l'application des gestes, la lecture de télémétrie, l'ouverture/fermeture et le salut d'un doigt, le contrôle de vitesse, l'exécution de séquences et la détection de mouvement.

test_cmd_hardware.py vérifie de bout en bout la couche CLI : positions de pose, paramètres de vitesse, étapes de séquence, wait_for_motion, sortie de --list, et coupure du couple à la sortie.

Les critères d'acceptation complets sont dans Exigences d'acceptation et tests.

Note : les tests non matériels valident les valeurs de repli de hand_logic.py, qui restent l'échelle d'origine −40…110. Au runtime, data/config.yaml les remplace, donc les tests passent quelle que soit votre calibration — mais cela signifie aussi que les tests ne vérifient pas vos paramètres de calibration actuels.


Configuration des ID de servo ​

Tutoriel de configuration des ID de servo avec le logiciel officiel Feetech et la carte de commande de bus série : https://www.robot-maker.com/forum/tutorials/article/168-brancher-et-controler-le-servomoteur-feetech-sts3032-360/

Téléchargement du logiciel Feetech : https://github.com/Robot-Maker-SAS/FeetechServo



Télémétrie et retour ​

  • Sélection des métriques : position, charge, vitesse, température, tension, indicateur de mouvement.
  • Modes de graphique : Multi-Servo (courbes multi-servos) et Scope (oscilloscope monocanal).
  • Zoom/déplacement : Y Zoom / Pan, Time Zoom / Pan.
  • Tableau de retour : Goal, Position, Speed, Load, Voltage, Temperature, Status, Moving.

Courbes de télémétrie

Tableau de retour des servos

Éditeur de séquences ​

  1. Dans Sequence Player, cliquez sur Manage.
  2. Ajoutez des étapes avec Available Poses, ajustez la vitesse par doigt, le délai des étapes ou insérez un sommeil.
  3. Réordonnez avec ↑/↓, saisissez un nom et enregistrez ; vous pouvez aussi essayer avec Execute.
  4. De retour dans la fenêtre principale, sélectionnez une séquence et cliquez sur Play ; activez Loop pour une lecture continue.

La définition des séquences se trouve sous la clé sequences de data/hand_config.yaml.

Dépannage ​

SymptômeConseil
Aucun port série listéRebranchez l'adaptateur USB, installez le pilote ou redémarrez la GUI.
Bouton Connect griséDéjà connecté ; cliquez d'abord sur Disconnect.
Saccades lors du redimensionnementFermez les fenêtres inutiles ; le resize est déjà anti-rebond/limité.
La séquence n'entraîne pas tous les doigtsVérifiez la vitesse de chaque étape et assurez-vous que chaque pose contient les 8 valeurs de servos.
Indicateur de blocage persistantVérifiez un blocage mécanique ; un écart important entre cible et position réelle sans mouvement déclenche un blocage.

Documentation de développement associée ​

Remerciements ​

Projet d'origine : Betatester777 — Matériel et firmware de référence : Pollen Robotics