Projet Poppy Humanoid
Abstract
Poppy Humanoid est une plate-forme humanoïde open-source basée sur l'impression 3D. Le projet aborde la mécanique, l’ électronique et le software du robot. Il regroupe une communauté multidisciplinaire de chercheurs, enseignants, artistes et amateurs de robotique qui peuvent partager leur travail et leurs idées. Le robot a été conçu pour qu’il ait une façon simple d’utilisation. Il a aussi un assemblage facile et modulable parce qu’il a un but pédagogique pour des élèves de lycée ou d’école d’ Ingénieurs.
Full text
Projet POPPY HUMANOID RIZZO Gabriele 1
ANNÉE%:"2015 CENTRE&DE&RATTACHEMENT&PE&:"Arts"et"Métiers"ParisTech"Bordeaux9 Talence"" AUTEURS&:"Gabriele"Rizzo! TITRE&:""Projet"Poppy"Humanoid TUTEUR:&Prof."Jean9Luc"CHARLES! ! NOMBRES&DE&PAGES&:&35& NOMBRE&DE&REFERENCES&BIBLIOGRAPHIQUES&:"9" 2
Table des matières I. REMERCIEMENTS 4 II. INTRODUTION 1. PRÉSENTATION DU ROBOT 5 2. PRÉSENTATION DU MATÉRIEL HARDWARE 5 3. DESCRIPTION DU ROBOT 6 4. PYPOT LIBRARY 7 5. INSTALLATION POPPYTOOLS 7 III. LE CÂBLAGE 1. HAUT DU CORPS 8 2. BAS DU CORPS 9 IV. DÉMARRAGE DU ROBOT 1. PREMIER DÉMARRAGE 10 2. CODE DE PRÉSENTATION DU ROBOT 15 V. CONCEPTION DES BATTERIES 17 VI. LA TÊTE DU ROBOT 1. DESCRIPTION DE LA TÊTE 21 2. CARTE ODROID U3 22 3 LA CAMÉRA JDEPC-OV05 23 VII. ALGORITHME DE RECONNAISSANCE DE VISAGE 24 VIII. CONCLUSIONS 1. BILAN DE L’EXPÉRIENCE 27 2. POUR POURSUIVRE, DES PISTES D’AMÉLIORATION 27 IX. RÉFÉRENCES BIBLIOGRAPHIQUES 28 X. ANNEXES 29 3
I. REMERCIEMENTS Mes remerciements vont tout d’abord à Mr. Jean-Luc CHARLES pour m’avoir permis de réaliser ce projet très enrichissant. Je remercie également Mr. Mathieu CREMOUX et Mr. Dominique DOROSZEWSKI pour leur présence et leur aide dans les phases des travaux. Enfin, merci à ma famille et mes amis qui sont une source continue de motivation. 4
II. INTRODUTION 1. PRÉSENTATION DU ROBOT Poppy Humanoid est une plate-forme humanoïde open-source basée sur l'impression 3D. Le projet aborde la mécanique, l’ électronique et le software du robot. Il regroupe une communauté multidisciplinaire de chercheurs, enseignants, artistes et amateurs de robotique qui peuvent partager leur travail et leurs idées. Le robot a été conçu pour qu’il ait une façon simple d’utilisation. Il a aussi un assemblage facile et modulable parce qu’il a un but pédagogique pour des élèves de lycée ou d’école d’ Ingénieurs. 2. PRÉSENTATION DU MATÉRIEL HARDWARE -Les pièces imprimées en impression 3D - Les servomoteurs Dynamixel -Carte de développement 5
3. DESCRIPTION DU ROBOT Poppy dispose de 25 servomoteurs Dynamixel et chaque moteur est identifié par un id. (Voir figure 1) Figure 1 - convention de référence des moteurs 6
4. PYPOT LIBRARY Pypot est un paquet développé dans l’équipe Flowers de l’Inria pour rendre facile et rapide le contrôle du robot basé sur les servomoteurs dynamixel. Le code a été écrit en langage Python pour faciliter le travail des développeurs pas experts et pour bénéficier des paquets scientifiques et de machine learning existants en Python. Pypot peut être utilisé avec Python 2.7 et 3.4 et exige le paquet pyserial (minimum 2.6) et numpy. Pour l’installation il suffit de taper la commande: pip install pypot 5. INSTALLATION POPPYTOOLS Le dossier poppytools dans poppy-software inclut la configuration du robot et plusieurs primitives indépendantes. Les primitives indépendantes permettent de créer des programmes complexes par leur combinaison. Pour l’installation: cd where-you-want git clone https://github.com/poppy-project/poppy-software.git cd poppy-software python setup.py develop 7
III. LE CÂBLAGE On peut diviser le robot en deux parties pour la description du câblage: le haut (en rouge) et le bas (en vert). Chaque partie utilise un Bioloid 3P Extension Board et un SMPS2 Dynamixel. Figure 2 - représentation des câbles 1. HAUT DU CORPS Le Bioloid 3P Extension Board du haut du corps est connecté au SMPS2 Dynamixel et aux moteurs “head_y (id=37)”, “head_z (id=36)”, “r_shoulder_y (id=51)”, “l_shoulder_y (id=41)” et “bust_x (id=35)”. Enfin, la partie supérieure du robot est attachée à l’USB HUB 4 PORTS par le moteur “head_y (id=37)”. 8
2. BAS DU CORPS Le Bioloid 3P Extension Board du bas du corps est connecté au SMPS2 Dynamixel et aux moteurs “r_hip_x (id=11)” et “l_hip_x (id=21)”. La partie inférieure du robot est attachée à l’USB HUB 4 PORTS par le SMPS2 Dynamixel. Pour connecter les moteurs “r_hip_y (id=23)” - “r_knee_y (id=24)” et “l_hip_y (id=13)” - “l_knee_y (id=14)” on a besoin d’un câble d'au moins 20cm de long (Voir figure 3a) et pour la connexion USB HUB 4 PORTS - SMPS2 Dynamixel d’un câble de 60cm. Figure 3 - a) hanche du robot, b) Bioloid 3P Extension Board et SMPS2 Dynamixel sur le bas du corps, c) haut du corps 9
Les images suivantes montrent les trois modes possibles: Figure 7 - a) mode Presentation, b) mode CopyArm, c) mode Recording 16 le mode Presentation effectue une série de mouvements. Une partie a été enregistré avant en déplaçant le robot et l'autre partie a été obtenue avec le code en déplaçant les moteurs du robot jusqu'à certaines positions. CopyArm permet au bras droit du robot d’imiter les mouvements qu’on fait avec son bras gauche. le mode Recording permet d'enregistrer un mouvement forcé par l’utilisateur et de le reproduire après de forme autonome avec PlayRecord.
V. CONCEPTION DES BATTERIES •Consommation d’énergie: -plage de tension: 10 ~14.8V (tension recommandée 12V) - courant électrique: minimum (les moteurs sont dans le mode ‘compliant’) 1.53A et le courant maximum enregistrée au cours de la présentation est 2A •Limites de couple (couple de décrochage): - MX-64 : 5.5 Nm (at 11.1V, 3.9A), 6.0N.m (at 12V, 4.1A) - MX-28 : 2.3N.m (at 11.1V, 1.3A), 2.5N.m (at 12V, 1.4A) •Poids des moteurs: -MX-64: 126g -MX-28: 72g •Temps d’autonomie: - théoriquement on a une heure de vie avec la batterie 2000mAh • Chimie disponibles: - Alkaline: pas considéré pour ce projet (constamment besoin d'acheter des remplacements) - Nickel: 1. NiCd: Ces batteries sont en train de disparaître à cause de leur mémoire effet 2. NiMh: ils sont rechargeables (il n'y a presque pas d'effet mémoire) et une bonne relation prix / capacité / poids. Temps de charge long. Principale solution: 12V pour 540g de poids. Prix: à partir de 40 $ 17
- Lead acid: ces batteries ont le problème d'être très volumineuses et lourdes, elles doivent toujours être maintenues, elles n’ont pas la vitesse de décharge élevée qu’ont les batteries plus modernes.! - Lithium: elles sont légères, le temps de décharge est élevé et elles ont relativement bonne capacité. La tension augmente dans les étapes de 3.7V. Par conséquent, les solutions possibles sont les suivantes: 1. trois batteries de 3.7V, poids: 45g chacune, prix de chaque batterie: 20€ 2. une batterie de 11.1V, poids: 150g, prix: 50 € •Emplacement: dans le cas d’une seule batterie, la seule solution est de la fixer au abs_x moteur (id = 32). Le problème de cette solution est que la partie supérieure du robot est déjà assez lourde et va faire la dynamique du robot plus difficile. Figure 8 - zoom abs_x moteur (id = 32) 18
Le deuxième cas est quand nous avons trois batteries. Dans cette solution, nous pouvons localiser une batterie de l'alimentation dans chaque jambe (entre la hanche et le genou) et l’autre batterie attaché aux moteurs r_hip_x (id = 11) et l_hip_x (id = 21). La seule limitation de cette solution pourrait être le couple maximal fournit par les moteurs r_hip_y (id = 23) et l_hip_y (id = 13). Sans la batterie, la dynamique de la jambe de Poppy est faite avec le 21% du couple maximal des moteurs l_hip_y (id = 13) et r_hip_y (id = 23). Par conséquent, on considère qu’une augmentation approximative de 100g pour chaque jambe ne va pas être un problème. Figure 9 - zoom r_hip_y (id = 23) et l_hip_y (id = 13) moteurs •Consommation d’énergie par Odroid U3: - puissance: 5V / 2A Il faut utiliser un transformateur de tension 5V-12V comme celui de l’image suivante. Figure 10 - convertisseur 5/12 V 19
Solution mise en œuvre: - 3 Accumulateurs LG Lithium-Ion en série avec les caractéristiques suivantes: Figure 11 - solution trois batteries Les images suivantes montrent le câblage pour les batteries Figure 12 - câblage pour les batteries 20 Tension (V) Consommation courant (mAh) Dimension (mm) Poids (gr) 3.6 2600 69/21/18.5 60
VI. LA TÊTE DU ROBOT 1. DESCRIPTION DE LA TÊTE Figure 13 - 3D tête du robot La tête de la version v1.0 de Poppy Humanoid a été conçue pour contenir: - carte Odroid U3 -moteur MX-28 -caméra JDEPC-OV05 -USB HUB 4 ports -EDIMAX Wireless 802.11b/g/n -J14 VISATON haut-parleur K 20.40 -Stereo Amplifier MAX 98306 modifications: -l'écran a été remplacé par une pièce en plastique -un petit trou a été ajouté pour la sortie des câbles à l'arrière de la tête 21
2. CARTE ODROID U3 Figure 14 - carte Odroid U3 mise en œuvre Caractéristiques: - The Powerful Linux Computer - 1.7GHz Quad-Core processor and 2GByte RAM - 10/100Mbps Ethernet with RJ-45 LAN Jack - 3 x High speed USB2.0 Host ports - Audio codec with headphone jack on board - GPIO/UART/I2C ports - XUbuntu 13.10 or Android 4.x Operating System - Taille : 83 x 48 mm, Poids : 48g including heat sink - Package includes the main board and the heat sink Figure 15 - détails Odroid U3 22
3. LA CAMÉRA Les caractéristiques que la caméra doit avoir sont: -connexion USB -un petit PCB (le ‘printed circuit board’ augmente la versatilité de la camera et réduit l'espace nécessaire) -une petite lentille qui n’est pas visible sur la tête de Poppy -facilement accessible Solution mise en œuvre: -Caméra JDEPC-OV05: - 1/4” CMOS capteur d’image avec haute qualité - interface USB 1.1/2.0 - pas besoin de driver pour Linux - fonction vision nocturne - caméra petite - haute fiabilité - taille: 60 * 8.0 * 6.6 mm Figure 16 - caméra JDEPC-OV05 23
VII. ALGORITHME DE RECONNAISSANCE DE VISAGE Le code suivant est utilisé pour ajouter un algorithme de reconnaissance de visage à la presentation du robot. Pour l’utilisation il faut avoir: -OpenCV installé sudo apt-get install python-opencv -caméra en service -le fichier haarcascade_frontalface_alt2.xml dans le même dossier où il y a le code cd Bureau/poppy/my_code python presentation_with_camera.py “presentation_with_camera.py” (code complet A.3.) def Recognition(): cascPath = os.getcwd()+'/haarcascades/haarcascade_frontalface_alt2.xml' # Name of the file from which the classifier is loaded. It is a trained classifier for detecting faces faceCascade = cv2.CascadeClassifier(cascPath) #Object detector video_capture = cv2.VideoCapture(0) #It sets the video source to the default webcam flag = 1 print 'Press Ctrl-C to stop the current program' try: while True: # Capture frame-by-frame ret, frame = video_capture.read() if not ret: continue gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) #Converts an image from one color space to another faces = faceCascade.detectMultiScale( gray, # Matrix of the type CV_8U containing an image where objects are detected scaleFactor=1.1, #Parameter specifying how much the image size is reduced at each image scale minNeighbors=5, #Parameter specifying how many neighbors each candidate rectangle should have to retain it minSize=(40, 40), #minSize=(30, 30),# Minimum possible object size. Objects smaller than that are ignored flags=cv2.cv.CV_HAAR_SCALE_IMAGE ) # It detects objects of different sizes in the input image. The detected objects are returned as a list of rectangles faces2= list(faces) # It changes the face object in list type to simplify the If loop. 24
if not faces2: print 'no face' else: print 'got face' flag = flag + 1 if flag is 10: #the robot move after 9 positive results k[idm54].goto_position(80, 2.0) k[idm51].goto_position(-100, 2.0) flag= 11 # Draw a rectangle around the faces for (x, y, w, h) in faces: cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2) # Display the resulting frame cv2.imshow('Video', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break # When everything is done, release the capture except KeyboardInterrupt: video_capture.release() cv2.destroyAllWindows() BackPosition() pass Le détecteur d'objet décrit a été initialement proposée par Paul Viola et développé par Rainer Lienhart. Tout d’abord, un classificateur est formé avec quelques images d’example d'un objet particulier (dans ce cas un visage) appelés exemples positifs qui ont tous la même taille (par exemple, 30x30), et des exemples négatifs qui sont images arbitraires de la même taille. Après que le classificateur est formé, il peut être appliqué à une région d’intérêt. Le classificateur est conçu de sorte qu'il peut être facilement redimensionné afin de trouver les objets d’intérêt des tailles différentes, ce qui est plus efficace que le redimensionnement de l'image elle-même. Le mot “cascade" signifie que le classificateur se compose de plusieurs classificateurs similaires (étapes) qui sont appliqués à une région d'intérêt jusqu'à que le candidat est rejeté ou toutes les étapes sont croisées. Les classificateurs de base sont classificateurs ‘decision-tree’ avec au moins 2 branches. 25
for m in poppy.motors: m.goto_position(0, 2.5) time.sleep(3.0) ############################################################ #variable definition k = poppy.motors idm23 = 22 idm24 = 23 idm25 = 24 idm13 = 17 idm14 = 18 idm15 = 19 idm51 = 11 idm41 = 7 idm54 = 14 idm44 = 10 idm52 = 12 idm42 = 8 idm53 = 13 idm43 = 9 char = None ############################################################# ## main program #starting presentation StartingPos() SittingPos() print 'sit down the robot and hold it from the handle pls' raw_input("press Enter if you are ready to continue..") print 'The presentation is starting..' ShakingLegs() time.sleep(0.5) Hands2tab() time.sleep(1) PlayHello() #ask different options AskWhat2Do1() while True: AskKeyPress() if char == 'r': Recording() AskWhat2Do2() char = None elif char == 'c': CopyArm() AskWhat2Do1() char = None elif char == 'p': Presentation() AskWhat2Do1() char = None elif char == 'm': PlayRecord() AskWhat2Do2() char = None else: break #final position time.sleep(1) FinalPos() print 'going to finish...' raw_input("press Enter if you want to make the motors compliant..") MotorsCompl() 32
A.2 “interaction.py” #my code add class MyArmsCopyMotion(pypot.primitive.LoopPrimitive): def start(self): for m in self.robot.arms: m.moving_speed = 0 for m in self.robot.l_arm: m.compliant = True for m in self.robot.r_arm: m.compliant = False pypot.primitive.LoopPrimitive.start(self) def update(self): for lm, rm in zip(self.robot.l_arm, self.robot.r_arm): rm.goal_position = lm.present_position * (1 if lm.direct else -1) def teardown(self): for m in self.robot.arms: m.compliant = False time.sleep(2) for m in self.robot.arms: m.moving_speed = 0 33
A.3 “presentation_with_camera.py” import thread import time import sys, tty, termios import cv2 import os import pypot.robot from pypot.primitive.move import MoveRecorder, Move, MovePlayer from poppytools.configuration.config import poppy_config from poppytools.primitive.interaction import MyArmsCopyMotion poppy = pypot.robot.from_config(poppy_config) poppy.start_sync() ############################################################## #functions definition . . . def Recognition(): cascPath = os.getcwd()+'/haarcascades/haarcascade_frontalface_alt2.xml' # Name of the file from which the classifier is loaded. It is a trained classifier for detecting faces faceCascade = cv2.CascadeClassifier(cascPath) #Object detector video_capture = cv2.VideoCapture(0) #It sets the video source to the default webcam flag = 1 print 'Press Ctrl-C to stop the current program' try: while True: # Capture frame-by-frame ret, frame = video_capture.read() if not ret: continue gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) #Converts an image from one color space to another faces = faceCascade.detectMultiScale( gray, # Matrix of the type CV_8U containing an image where objects are detected scaleFactor=1.1, #Parameter specifying how much the image size is reduced at each image scale minNeighbors=5, #Parameter specifying how many neighbors each candidate rectangle should have to retain it minSize=(40, 40), #minSize=(30, 30),# Minimum possible object size. Objects smaller than that are ignored flags=cv2.cv.CV_HAAR_SCALE_IMAGE ) # It detects objects of different sizes in the input image. The detected objects are returned as a list of rectangles faces2= list(faces) # It changes the face object in list type to simplify the If loop. if not faces2: print 'no face' else: print 'got face' flag = flag + 1 if flag is 10: #the robot move after 9 positive results k[idm54].goto_position(80, 2.0) k[idm51].goto_position(-100, 2.0) flag= 11 # Draw a rectangle around the faces for (x, y, w, h) in faces: cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2) # Display the resulting frame cv2.imshow('Video', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break # When everything is done, release the capture except KeyboardInterrupt: video_capture.release() cv2.destroyAllWindows() BackPosition() pass . . . ############################################################ #variable definition k = poppy.motors idm23 = 22 34
idm24 = 23 idm25 = 24 idm13 = 17 idm14 = 18 idm15 = 19 idm51 = 11 idm41 = 7 idm54 = 14 idm44 = 10 idm52 = 12 idm42 = 8 idm53 = 13 idm43 = 9 char = None ############################################################# ## main program #starting presentation StartingPos() SittingPos() print 'sit down the robot and hold it from the handle pls' raw_input("press Enter if you are ready to continue..") """ print 'The presentation is starting..' ShakingLegs() time.sleep(0.5) Hands2tab() time.sleep(1) PlayHello() #ask different options """ AskWhat2Do1() while True: AskKeyPress() if char == 'r': Recording() AskWhat2Do2() char = None elif char == 'c': CopyArm() AskWhat2Do1() char = None elif char == 'p': Presentation() AskWhat2Do1() char = None elif char == 'm': PlayRecord() AskWhat2Do2() char = None elif char == 'f': Recognition() AskWhat2Do1() char = None else: break #final position time.sleep(1) FinalPos() print 'going to finish...' raw_input("press Enter if you want to make the motors compliant..") MotorsCompl() 35