Différences
Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente | ||
|
openatelier:projet:tete_animatronique [2023/06/07 16:33] emoc [Impression résine] |
openatelier:projet:tete_animatronique [2025/10/07 15:45] (Version actuelle) emoc |
||
|---|---|---|---|
| Ligne 1: | Ligne 1: | ||
| {{tag>impression_3D animatronique marionnette raspberry-pi electronique em}} | {{tag>impression_3D animatronique marionnette raspberry-pi electronique em}} | ||
| - | ====== 🆕 Tête de marionnette animatronique ====== | + | ====== Tête de marionnette animatronique ====== |
| (**Cette tête fait partie du projet [[projets:barbichette:start|Barbichette]]**) | (**Cette tête fait partie du projet [[projets:barbichette:start|Barbichette]]**) | ||
| Ligne 452: | Ligne 452: | ||
| ===== Rpi + Python + PCA9685 ===== | ===== Rpi + Python + PCA9685 ===== | ||
| + | |||
| + | Le montage se compose d'un Raspberry Pi qui communique, via I2C sur ses broches GPIO, à un contrôleur de 16 servos basé sur la puce PCA9685. Les servosmoteurs sont reliés à ce circuit. | ||
| + | |||
| + | ==== Multiplexeur PCA9685 ==== | ||
| + | |||
| + | {{:openatelier:projet:tete_animatronique:16-channel-pwm-controller-pca9685-module-overview.jpg?direct&600|}} | ||
| + | |||
| + | ==== Montage ==== | ||
| + | |||
| + | {{:openatelier:projet:tete_animatronique:adafruit_raspi_pca9685_i2c_with_servo.png?direct&600|}} | ||
| + | |||
| + | Source du schéma : https://learn.adafruit.com/adafruit-16-channel-servo-driver-with-raspberry-pi/hooking-it-up | ||
| + | |||
| + | Pour le brochage du Raspberry Pi 4, voir : https://lesporteslogiques.net/wiki/materiel/raspberry_pi/start#raspberry_pi_4_model_b | ||
| + | |||
| + | === Préparation du Raspberry Pi pour I2C === | ||
| + | |||
| + | Installation de paquets | ||
| + | sudo apt-get install -y python-smbus # support d'I2C dans python | ||
| + | sudo apt-get install -y i2c-tools # entre autre pour scanner le port I2C | ||
| + | Configurer le support par le kernel | ||
| + | sudo raspi-config # choisir interface options/I2C/activer l'interface | ||
| + | Puis redémarrer | ||
| + | sudo reboot | ||
| + | |||
| + | Ensuite on peut tester que le module PCA9685 est bien branché | ||
| + | sudo i2cdetect -y 1 # Le port I2C numéro 1 est utilisé sur les rpi > 512 MB de RAM | ||
| + | Ce qui devrait afficher (les adresses des ports utilisés sont indiquées) | ||
| + | |||
| + | {{:openatelier:projet:tete_animatronique:i2cdetect_resultat.png|}} | ||
| ==== Circuit complet ==== | ==== Circuit complet ==== | ||
| Ligne 477: | Ligne 507: | ||
| # Set channels to the number of servo channels on your kit. | # Set channels to the number of servo channels on your kit. | ||
| # 8 for FeatherWing, 16 for Shield/HAT/Bonnet. | # 8 for FeatherWing, 16 for Shield/HAT/Bonnet. | ||
| - | kit = ServoKit(channels=8) | + | kit = ServoKit(channels=16) |
| kit.servo[0].angle = 180 | kit.servo[0].angle = 180 | ||
| Ligne 490: | Ligne 520: | ||
| </accordion> | </accordion> | ||
| + | ==== Test des servomoteurs ==== | ||
| + | |||
| + | Définir sur quelles broches sont reliés les servomoteurs, fixer minimum et maximum pour chacun. | ||
| + | |||
| + | <accordion> | ||
| + | <panel title="test_python_pca9685_servomoteurs.py (cliquer pour afficher le code)"> | ||
| + | <code python test_python_pca9685_servomoteurs.py> | ||
| + | import time | ||
| + | from adafruit_servokit import ServoKit | ||
| + | |||
| + | # Set channels to the number of servo channels on your kit. | ||
| + | # 8 for FeatherWing, 16 for Shield/HAT/Bonnet. | ||
| + | kit = ServoKit(channels=16) | ||
| + | |||
| + | # Correspondances (gauche/droite pour la tête) | ||
| + | # commands du côté droit inversées | ||
| + | # 0 : sourcil gauche (50, 135) | ||
| + | # 1 : sourcil droit (inv) (135, 50) | ||
| + | # 2 : machoire basse (?, ?) | ||
| + | # 3 : oeil gauche (50, 130) | ||
| + | # 4 : oeil droit (50, 130) | ||
| + | # 5 : paupière gauche () PROBLEME | ||
| + | # 6 : paupière droite () PROBLEME | ||
| + | # 7 : bouche gauche (50, 110) PROB : refaire mécanisme | ||
| + | # 8 : bouche droite (inv) (110, 50) PROB : refaire mécanisme | ||
| + | # 9 : yeux (50, 130) | ||
| + | |||
| + | for boucle in range(0, 3) : | ||
| + | kit.servo[0].angle = 135 | ||
| + | kit.servo[1].angle = 50 | ||
| + | kit.servo[2].angle = 50 | ||
| + | kit.servo[3].angle = 130 | ||
| + | kit.servo[4].angle = 130 | ||
| + | # ~ kit.servo[5].angle = 80 | ||
| + | # ~ kit.servo[6].angle = 80 | ||
| + | kit.servo[7].angle = 50 | ||
| + | kit.servo[8].angle = 110 | ||
| + | kit.servo[9].angle = 50 | ||
| + | time.sleep(1) | ||
| + | |||
| + | kit.servo[0].angle = 50 | ||
| + | kit.servo[1].angle = 135 | ||
| + | kit.servo[2].angle = 120 | ||
| + | kit.servo[3].angle = 50 | ||
| + | kit.servo[4].angle = 50 | ||
| + | # ~ kit.servo[5].angle = 100 | ||
| + | # ~ kit.servo[6].angle = 100 | ||
| + | kit.servo[7].angle = 110 | ||
| + | kit.servo[8].angle = 50 | ||
| + | kit.servo[9].angle = 130 | ||
| + | time.sleep(1) | ||
| + | |||
| + | kit.servo[0].angle = 90 | ||
| + | kit.servo[1].angle = 90 | ||
| + | kit.servo[2].angle = 90 | ||
| + | kit.servo[3].angle = 90 | ||
| + | kit.servo[4].angle = 90 | ||
| + | # ~ kit.servo[5].angle = 90 | ||
| + | # ~ kit.servo[6].angle = 90 | ||
| + | kit.servo[7].angle = 90 | ||
| + | kit.servo[8].angle = 90 | ||
| + | kit.servo[9].angle = 90 | ||
| + | time.sleep(2) | ||
| + | </code> | ||
| + | </panel> | ||
| + | </accordion> | ||
| + | |||
| + | ==== Expressions ==== | ||
| + | |||
| + | Test de quelques expressions du visage animatronique | ||
| + | |||
| + | <accordion> | ||
| + | <panel title="expressions.py (cliquer pour afficher le code)"> | ||
| + | <code python expressions.py> | ||
| + | import time | ||
| + | from adafruit_servokit import ServoKit | ||
| + | |||
| + | # Set channels to the number of servo channels on your kit. | ||
| + | # 8 for FeatherWing, 16 for Shield/HAT/Bonnet. | ||
| + | kit = ServoKit(channels=16) | ||
| + | |||
| + | # Correspondances (gauche/droite pour la tête) | ||
| + | # commands du côté droit inversées | ||
| + | # 0 : sourcil gauche (50, 135) | ||
| + | # 1 : sourcil droit (inv) (135, 50) | ||
| + | # 2 : machoire basse (?, ?) | ||
| + | # 3 : oeil gauche (50, 130) | ||
| + | # 4 : oeil droit (50, 130) | ||
| + | # 5 : paupière gauche () PROBLEME | ||
| + | # 6 : paupière droite () PROBLEME | ||
| + | # 7 : bouche gauche (50, 110) PROB : refaire mécanisme | ||
| + | # 8 : bouche droite (inv) (110, 50) PROB : refaire mécanisme | ||
| + | # 9 : yeux (50, 130) | ||
| + | |||
| + | def moue(): | ||
| + | kit.servo[0].angle = 50 | ||
| + | kit.servo[1].angle = 135 | ||
| + | kit.servo[2].angle = 120 | ||
| + | kit.servo[3].angle = 70 | ||
| + | kit.servo[4].angle = 110 | ||
| + | # ~ kit.servo[5].angle = 100 | ||
| + | # ~ kit.servo[6].angle = 100 | ||
| + | kit.servo[7].angle = 110 | ||
| + | kit.servo[8].angle = 50 | ||
| + | kit.servo[9].angle = 130 | ||
| + | time.sleep(2) | ||
| + | |||
| + | def sleep(): | ||
| + | kit.servo[0].angle = 90 | ||
| + | kit.servo[1].angle = 90 | ||
| + | kit.servo[2].angle = 90 | ||
| + | kit.servo[3].angle = 90 | ||
| + | kit.servo[4].angle = 90 | ||
| + | # ~ kit.servo[5].angle = 90 | ||
| + | # ~ kit.servo[6].angle = 90 | ||
| + | kit.servo[7].angle = 90 | ||
| + | kit.servo[8].angle = 90 | ||
| + | kit.servo[9].angle = 90 | ||
| + | time.sleep(2) | ||
| + | |||
| + | def louche(): | ||
| + | kit.servo[0].angle = 135 | ||
| + | kit.servo[1].angle = 50 | ||
| + | kit.servo[2].angle = 120 | ||
| + | kit.servo[3].angle = 130 | ||
| + | kit.servo[4].angle = 50 | ||
| + | # ~ kit.servo[5].angle = 100 | ||
| + | # ~ kit.servo[6].angle = 100 | ||
| + | kit.servo[7].angle = 110 | ||
| + | kit.servo[8].angle = 50 | ||
| + | kit.servo[9].angle = 130 | ||
| + | time.sleep(2) | ||
| + | |||
| + | louche() | ||
| + | moue() | ||
| + | sleep() | ||
| + | louche() | ||
| + | sleep() | ||
| + | |||
| + | </code> | ||
| + | </panel> | ||
| + | </accordion> | ||
| + | |||
| + | ==== Réception OSC ==== | ||
| + | |||
| + | Trouver l'adresse IP du RPi | ||
| + | hostname -I | ||
| + | Pour tester la réception OSC : écouter le traffic sur le port UDP 12345 | ||
| + | nc -l -u 12345 | ||
| + | Version du système/kernel installé | ||
| + | hostnamectl | ||
| + | | ||
| + | Installer python OSC : pip3 install python-osc | ||
| ==== Communication série avec le joystick arduino ==== | ==== Communication série avec le joystick arduino ==== | ||
| Ligne 633: | Ligne 816: | ||
| {{:openatelier:projet:tete_animatronique:20230302_barbichette.jpg?direct&1200|}} | {{:openatelier:projet:tete_animatronique:20230302_barbichette.jpg?direct&1200|}} | ||
| + | **14 juin 2023** : électronique ok, prototype construit et actionné par script python depuis le raspberry, une vidéo des premiers essais d'expression | ||
| + | |||
| + | {{:openatelier:projet:tete_animatronique:barbichette_20230614_175450.jpg?direct&800|}}{{:openatelier:projet:tete_animatronique:20230614_barbichette_prototype.mp4|}} | ||
| + | |||
| + | **15 juin 2023** scripts (à renommer en .gz) {{ :openatelier:projet:tete_animatronique:20230615_scripts_barbichette.gz.txt |}} | ||
| + | |||
| + | ==== Prototype 1 ==== | ||
| + | |||
| + | **16 juin 2023** scripts : {{ :openatelier:projet:tete_animatronique:20230616_scripts.gz.txt |}} (à renommer en .gz) | ||
| + | |||
| + | Quelques détails : | ||
| + | |||
| + | **ui_servo_expressions.py** contrôle par interface graphique (sliders, etc.) des servomoteurs de la tête animatronique | ||
| + | |||
| + | **osc_envoi_simulation.py** simulation d'envoi OSC (utile si l'ordi de détection n'est pas relié) | ||
| + | |||
| + | **osc_reception_test.py** vérification que les messages OSC sont bien reçus (pas d'action sur les servos) | ||
| + | |||
| + | **osc_reception_tracking_visage.py** script principal, reçoit les messages envoyés par l'ordi de détection et agit sur les servos en conséquence | ||
| + | |||
| + | **serie_read_test.py** réception des messages série d'arduino | ||
| + | |||
| + | **servo_expressions.py** (obsolète) quelques tests d'expressions | ||
| + | |||
| + | **servo_paupieres_test.py** (test seulement) | ||
| + | |||
| + | **servo_pca9685_test.py** (test seulement, I2C) | ||
| + | |||
| + | Parfois une erreur 121 dans I2C / Rpi / Python | ||
| + | * bus overloadé | ||
| + | * fils trop longs (30cm max pour I2C, capacitance maximum de 400 pF dépassée) | ||
| + | * pull ups trop forts (il y a déjà des pull-ups dans les broches GPIO du Pi) -> supprimer ceux de la carte | ||
| + | * cf. https://raspberrypi.stackexchange.com/questions/124453/error-121-remote-i-o-error-in-smbus-py-call | ||
| + | |||
| + | Et quelques notes | ||
| + | * TODO / code : ajouter la bouche dans le script ui_servo_expressions.py | ||
| + | * TODO / code : contrôle des mouvements par pure data (pratique pour séquencer) | ||
| + | * TODO / install : solidariser caméra et robot /!\ captation audio et moteurs | ||
| + | * TODO / install : enceinte derrière le robot | ||
| + | * TODO / tête : refixer paupière, limer quelques pièces | ||
| + | * TODO / install : mode veille ? | ||
| + | |||
| + | **Nécessite un réseau local dans cette version!** | ||
| ===== Ressources ===== | ===== Ressources ===== | ||