Taula de continguts:

A Hearing Jumping Jack, versió de Google Coral TPU Accelerator: 4 passos
A Hearing Jumping Jack, versió de Google Coral TPU Accelerator: 4 passos

Vídeo: A Hearing Jumping Jack, versió de Google Coral TPU Accelerator: 4 passos

Vídeo: A Hearing Jumping Jack, versió de Google Coral TPU Accelerator: 4 passos
Vídeo: George Hotz | Programming | tinygrad Google Edge TPU has a custom ISA?!? | reverse engineering part3 2024, Juliol
Anonim
A Hearing Jumping Jack, versió de Google Coral TPU Accelerator
A Hearing Jumping Jack, versió de Google Coral TPU Accelerator
Un auditori saltant, versió de Google Coral TPU Accelerator
Un auditori saltant, versió de Google Coral TPU Accelerator
Un auditori saltant, versió de Google Coral TPU Accelerator
Un auditori saltant, versió de Google Coral TPU Accelerator

Es mou les extremitats, escolta les teves comandes, està impulsat per l’última tecnologia d’aprenentatge automàtic

El "Hearing Jumping Jack" és un simple Jumping Jack electromecànic, impulsat per dos micro servos i un engranatge molt senzill, amb LEDs com a "ulls". Es controla mitjançant ordres de veu simples que indiquen quina de les nou posicions predefinides adoptarà, o si el LED s’ha d’encendre o apagar, o si realitzarà un "ball" predeterminat o un conjunt de moviments aleatoris.

L’element bàsic del sistema és l’accelerador TPU de Google Coral, que permet executar els models Tensorflow Lite fora de línia amb una velocitat molt alta, fins i tot en un equip “feble” com el Raspberry Pi. Això permet, per exemple, identificació i classificació ràpida d’objectes mitjançant la càmera RPi, però també per executar localment funcions de reconeixement de veu basades en l’aprenentatge automàtic.

Que jo sàpiga, aquest és el primer exemple publicat per a un dispositiu de bricolatge físic basat en la detecció de veu de Coral Accelerator, i l'exemple de codi adjunt també es podria utilitzar per a altres projectes més complexos.

El control de veu es basa en l'exemple "la serp auditiva" del "projecter keyword spotter" (https://github.com/google-coral/project-keyword-spotter) que recentment (setembre de 2019) es va col·locar a GitHub. A la meva configuració, el sistema està format per un Raspberry Pi 4 equipat amb un capó servo de 16 canals Adafruit, un accelerador de Google Coral TPU i una càmera web, que s’utilitza aquí com a micròfon. El Jumping Jack s’havia descrit anteriorment en una instrucció prèvia, on el kit de Google Voice conduïa el dispositiu per llegir ordres de veu, s’adjunta al Servo Bonnet a la versió 2.0 que es descriu a continuació.

La versió anterior de Google Voice Kit tenia tres limitacions centrals: depenia dels serveis de reconeixement de veu basats en web de Google i la configuració era relativament complicada, calia prémer algun tipus de botó abans de poder donar una ordre i es va produir un retard greu entre dir l'ordre i la resposta del sistema. L’ús de l’accelerador Google Coral redueix el temps de resposta a segons, és independent d’una connexió a Internet i està escoltant tot el temps. Amb algunes modificacions, podeu utilitzar-lo per controlar dispositius molt més complexos com un Jumping Jack, com a robots o cotxes, o qualsevol cosa que pugueu construir i controlar amb un Raspberry Pi.

A la seva versió actual, Keyword Spotter comprèn un conjunt d’unes 140 paraules clau / frases claus, definides al fitxer del model adjunt (“voice_commands_v0.7_egetpu.tflite”) i descrites en un fitxer d’etiquetes separat (“labels_gc2.raw.txt”). Definides per un fitxer modificable lliurement ("commands_v2_hampelmann.txt"), les paraules clau utilitzades específicament pel nostre script es mapen a les pulsacions de teclat en un teclat virtual, per exemple. per a lletres, números, amunt / avall / esquerra / dreta, crtl + c, etcètera.

Després, per exemple utilitzant pygame.key, aquestes “pulsacions de tecles” es llegeixen i s’utilitzen per controlar quines accions realitzarà un dispositiu, aquí el saltador. En el nostre cas, això significa conduir els dos servos a posicions predefinides o encendre o apagar els LED. Com que el localitzador de paraules clau s'executa en una banda de rodament independent, pot escoltar permanentment les vostres comandes.

Versió el 21 de setembre de 2019

Subministraments

Raspberry Pi 4, a través de Pimoroni

Google Coral TPU Accelerator, a través de Mouser Germany, 72 €

Adafruit 16 Servo Bonnet, via Pimoroni, uns 10 €

www.adafruit.com/product/3416

learn.adafruit.com/adafruit-16-channel-pwm…

Capçalera de l'apilador (si cal)

www.adafruit.com/product/2223

Paquet de bateries 4x AA (o una altra font d'alimentació de 5-6V) per Servo Bonnet

Càmera web antiga, com a micròfon

Jumping Jack servomotor, tal com es descriu en una instrucció prèvia. Els dibuixos de disseny s’adjunten al pas següent, però poden requerir ajustos.

Peces necessàries per al Jumping Jack:

- Placa Forex de 3 mm

- 2 micro servos

- Cargols i femelles de 2 i 3 mm

- 2 LEDs blancs i una resistència

- una mica de cable

Pas 1: Configuració del dispositiu

Configuració del dispositiu
Configuració del dispositiu
Configuració del dispositiu
Configuració del dispositiu
Configuració del dispositiu
Configuració del dispositiu

Per construir el Jumping Jack, seguiu les indicacions donades en una instrucció prèvia. He utilitzat Forex per al meu prototip, però és possible que utilitzeu plaques acríliques o contraxapades tallades amb làser. És possible que hagueu d’ajustar el disseny segons la mida dels servos, etc. Proveu si les extremitats i l’engranatge es poden moure sense friccions.

Configureu el vostre Raspberry Pi. Al lloc de Coral Github, hi ha disponible una imatge de Raspian que conté tot el necessari per executar l’accelerador de Coral al Pi i conté molts projectes, amb tots els paràmetres establerts.

Obteniu el localitzador de paraules clau del projecte a la pàgina de Google Coral GitHub. Instal·leu tot el programari necessari tal com s’indica.

Instal·leu els fitxers proporcionats. Col·loqueu l'script de jumping jack python a la carpeta localitzadora de paraules clau del projecte i al fitxer d'ordres corresponents a la subcarpeta de configuració.

Col·loqueu el Servo Bonnet Adafruit al Pi. Com que estic fent servir una carcassa RPI amb un ventilador, necessitava apiladors GPIO (per exemple, disponibles a Pimoroni) per habilitar la connexió. Instal·leu totes les biblioteques necessàries, tal com s’indica a les instruccions d’Adafruit per al capó del servo.

Connecteu una font d'alimentació de 5-6V al capó del servo. Connecteu servos i LED. En el meu cas, he utilitzat el port 0 per als LEDs i els ports 11 i 15 per als servos.

Per comprovar-ho tot, us recomanaria provar primer l'exemple de detectador de paraules clau del projecte "serp d'oïda" i els exemples del capó de servo Adafruit.

Pas 2: Execució del Jumping Jack

Si totes les parts estan configurades i funcionen, proveu d'utilitzar-les. Podeu executar l'script a l'IDE o des de la línia d'ordres.

Cridar "posició 0" a "posició 9" evocarà el Jumping Jack per prendre una de les posicions predefinides. He definit "1" com ambdós braços cap amunt (uu), "3" com a esquerra cap amunt, dret cap avall (ud), "9" com ambdós braços cap avall (dd) i "5" com ambdós braços centrats (cc).

uu uc ud = 1 2 3

cu cc cd = 4 5 6

du dc dd = 7 8 9

"0" és idèntic a "5". "3" i "8" no són molt reconeguts per la paraula clau localitzadora i és possible que s'hagi de repetir.

És possible que hagueu d’ajustar els valors mínim i màxim per a cada servo / costat perquè els servos no es bloquegin i, a continuació, extreu massa energia.

el "joc següent" iniciarà el "ball", és a dir, una seqüència definida de posicions, mentre que "joc aleatori" iniciarà el Jumping Jack per realitzar una seqüència aleatòria de moviments. En ambdós casos funcionaran per sempre, de manera que és possible que hagueu d’aturar els moviments, p. amb una ordre "posició zero".

"stop game" evocarà un "ctrl + c" i aturarà el procés.

"encendre" i "apagar" es pot utilitzar per encendre i apagar els LED.

Mitjançant la modificació dels valors time.sleep podeu ajustar la velocitat dels moviments.

Pas 3: el codi i el fitxer d’ordres

El codi que es presenta aquí és una modificació del codi "serp auditiva" que forma part del paquet de localitzador de paraules clau del projecte. Acabo d’eliminar qualsevol cosa que no fos necessària per a la meva sol·licitud, sense cap comprensió real dels detalls. Qualsevol millora és benvinguda.

A continuació, he afegit les parts necessàries per al Servo Bonnet Adafruit, basant-me en els seus fitxers d'exemple.

M'agradaria donar les gràcies als programadors d'ambdues parts.

El codi es pot trobar adjunt com a fitxer. Utilitzeu-lo sota els vostres propis riscos, modifiqueu-lo, milloreu-lo, jugueu amb ell.

# Copyright 2019 Google LLC

# # Llicenciat sota la llicència Apache, versió 2.0 (la "llicència"); # No podeu utilitzar aquest fitxer tret que compleixi la Llicència. # Podeu obtenir una còpia de la llicència a # # https://www.apache.org/licenses/LICENSE-2.0 # # A no ser que la llei aplicable ho exigeixi o s’acordi per escrit, el programari # distribuït sota la llicència es distribueix en un BASE "TAL COM ÉS", # SENSE GARANTIES O CONDICIONS DE CAP TIPUS, expressa o implícita. # Vegeu la Llicència per obtenir els idiomes específics que regulen els permisos i les # limitacions de la Llicència. de _future_ importació absolut_import de _future_ importació divisió de _future_ importació funció d'impressió importació d'argparse importació de la importació aleatòria randint de la importació de filaments Temps d'importació del fil des de edgetpu.basic.basic_engine importació Model d'importació BasicEngine importació del model pygame de pygame.locals importació * cua d'importació de la importació aleatòria randrange des d’adafruit_servokit importació ServoKit importació placa importació busio importació adafruit_pca9685 temps d’importació i2c = busio. I2C (board. SCL, board. SDA) hat = adafruit_pca9685. PCA9685 (i2c) hat.frequency = 60 kit = ServoKit (canals = 16) # número de conjunt de canals # kit.servo [0].actuation_range = 160 # kit.servo [0].set_pulse_width_range (1000, 2000) # configuració amunt, mitja i baixa per als braços esquerre i dret up_l = 35 md_l = 90 dn_l = 160 up_r = 160 md_r = 90 dn_r = 35

lft = 15 # nombre de port servo, servo esquerre (0-8)

rgt = 11 # número de port servo, servo dret (0-8) led_channel_0 = hat.channels [0] # LED configurat al port 0 led_channel_0.duty_cycle = 0 # encendre el LED 100% # llista de paràmetres de braç per a nou posicions = [(md_l, md_r), (up_l, up_r), (up_l, md_r), (up_l, dn_r), (md_l, up_r), (md_l, md_r), (md_l, dn_r), (dn_l, up_r), (dn_l, md_r), (dn_l, dn_r)] # defineix 9 posicions de JumpingJack, indicades pels enters 0-9 dance1 = (0, 8, 7, 4, 1, 2, 3, 6, 9, 8, 5, 2, 1, 4, 7, 8, 9, 6, 3, 2, 0) # una classe de "ball" Controlador (objecte): # Funció de devolució def _init _ (self, q): self._q = q def callback (self, ordre): self._q.put (command) class App: def _init _ (self): self._running = True def on_init (self): pygame.init () self.game_started = True self._running = True return True def on_event (self, event): if event.type == pygame. QUIT: self._running = Fals def JumpingJack0 (self, keys): # controls Jumping Jack, paraules clau: "position x" key = int (keys) p = position [tecla] a = p [0] b = p [1] imprimir ("Posició:", tecla "esquerra / dreta: ", a," / ", b," grau ") # sys.stdout.write (" Posició: ", clau," esquerra / dreta: ", a," / ", b," grau ") kit.servo [lft].angle = a kit.servo [rgt].angle = b time.sleep (0.1) def JumpingJack1 (self): # controls Jumping Jack dance, paraula clau: "proper joc" dnce = dance1 sp = (len (dnce)) per a r en el rang (sp): #ordre de posició de ball, sp passos dc = dnce [r] si (dc no està en el rang (10)): # print ("error d'entrada a la posició", sp) dc = 4 p = posició [dc] a = p [0] b = p [1] kit.servo [lft].angle = a kit.servo [rgt].angle = b time.sleep (0.25) # sets speed de moviments def JumpingJack2 (self, keys): # controls Jumping Jack LEDs, keywords: "switch on / off" led = int (keys) if led == 1: led_channel_0.duty_cycle = 0xffff #turn on LED 100% time.sleep (0.1) if led == 0: led_channel_0.duty_cycle = 0 # apaga LED time.sleep (0.1) si led == 2: # parpelleja led_channel_0.duty_cycle = 0xffff #turn on LED 100% time.sleep (0.5) led_channel_0.duty_cycle = 0 # encendre el LED 100% time.sleep (0,5) led_channel_0.duty_cycle = 0xffff #turn on LED 100% time.sleep (0,5) led_channel_0.duty_cycle = 0 # Turn on LED 100% time.sleep (0,5) led_channel_0.duty_cycle = 0xffff #turn on LED 100% time.sleep (0,1) def JumpingJack3 (auto): # controls Jumping Jack dance, paraula clau: "joc aleatori" # per h en el rang (10): dr = randrange (9) p = position [dr] a = p [0] b = p [1] kit.servo [lft].angle = a kit.servo [rgt].angle = b time.sleep (0.25) # defineix la velocitat dels moviments def spotter (auto, args): engine = BasicEngine (args.model_file) mic = args.mic if args.mic és None else int (args.mic) model.classify_audio (micro, motor, labels_file = "config / labels_gc2.raw.txt", commands_file = "config / commands_v2_hampelmann.txt", dectection_callback = self._controler.callback, sample_rate_hz = int (args.sample_rate_hz), num_frames_hop = int (args.num_frames_hop))

def on_execute (self, args):

si no self.on_init (): self._running = Fals q = model.get_queue () self._controler = Controlador (q) si no args.debug_keyboard: t = Fil (target = self.spotter, args = (args,)) t.daemon = True t.start () item = -1 mentre self._running: pygame.event.pump () if args.debug_keyboard: keys = pygame.key.get_pressed () else: try: new_item = q.get (True, 0,1) excepte queue. Empty: new_item = Cap si new_item no és None: item = new_item if (args.debug_keyboard and keys [pygame. K_ESCAPE]) or item == "stop": self._running = False # if (args.debug_keyboard and keys [pygame. K_SPACE]) or item == "go": # self. JumpingJack0 (7) # if (args.debug_keyboard and keys [pygame. K_RIGHT]) or item == "right": self. JumpingJack0 (6) if (args.debug_keyboard and keys [pygame. K_LEFT]) or item == "left": self. JumpingJack0 (4) if (args.debug_keyboard and keys [pygame. K_UP]) or item == " amunt ": self. JumpingJack0 (1) if (args.debug_keyboard and keys [pygame. K_DOWN]) or item ==" down ": self. JumpingJack0 (9) if (args.debug_keyboard and keys [pygam e. K_0]) o element == "0": self. JumpingJack0 (0) if (args.debug_keyboard and keys [pygame. K_1]) or item == "1": self. JumpingJack0 (1) if (args. debug_keyboard and keys [pygame. K_2]) or item == "2": self. JumpingJack0 (2) if (args.debug_keyboard and keys [pygame. K_3]) or item == "3": self. JumpingJack0 (3) if (args.debug_keyboard and keys [pygame. K_4]) or item == "4": self. JumpingJack0 (4) if (args.debug_keyboard and keys [pygame. K_5]) or item == "5": self. JumpingJack0 (5) if (args.debug_keyboard and keys [pygame. K_6]) or item == "6": self. JumpingJack0 (6) if (args.debug_keyboard and keys [pygame. K_7]) or item == "7 ": self. JumpingJack0 (7) if (args.debug_keyboard and keys [pygame. K_8]) or item ==" 8 ": self. JumpingJack0 (8) if (args.debug_keyboard and keys [pygame. K_9]) or item == "9": self. JumpingJack0 (9) if (args.debug_keyboard and keys [pygame. K_a]) or item == "d": self. JumpingJack1 () #dancing Jack, on "next_game" if (args. debug_keyboard and keys [pygame. K_j]) or item == "j": self. JumpingJack2 (0) #LED on, ON " switch_on "if (args.debug_keyboard and keys [pygame. K_k]) or item ==" k ": self. JumpingJack2 (1) #LED off, on" swithch off "if (args.debug_keyboard and keys [pygame. K_l]) o item == "l": self. JumpingJack2 (1) #LED parpelleja "target" si (args.debug_keyboard and keys [pygame. K_r]) or item == "r": self. JumpingJack3 () #random dance "joc aleatori" time.sleep (0,05) self.on_cleanup () si _name_ == '_main_': parser = argparse. ArgumentParser () parser.add_argument ('- debug_keyboard', help = 'Utilitzeu el teclat per controlar el JumpingJack. ', action =' store_true ', default = False) model.add_model_flags (parser) args = parser.parse_args () the_app = App () the_app.on_execute (args)

També hi ha el fitxer de configuració de l'ordre "commands_v2_hampelmann.txt". Modifiqueu com vulgueu. És només una llista de combinacions "ordre, tecla, (força,)", basada en el fitxer etiqueta.

posició_zero, 0, position_one, 1, position_two, 2, position_three, 3, position_four, 4, position_five, 5, position_six, 6, position_seven, 7, position_eight, 8, position_nine, 9, move_up, up, go_up, up, move_down, down, go_down, avall, move_backwards, left, move_forwards, right, go_backwards, left, go_forwards, right, 0,8 target, l, mute, z, yes, y, no, n, switch_on, j, switch_off, k, volume_up, up, volume_down, down, joc_pròxim, d, joc_atzar, r, joc_inici, s, joc_atur, ctrl + c,

Pas 4: idees addicionals i altres exemples

És bastant obvi que aquesta configuració també es pot utilitzar per controlar robots o altres dispositius. Bàsicament tot el que podria controlar un Raspberry Pi.

Estic treballant en una extensió de l'script per generar un MeArm i espero poder presentar-lo a l'octubre del 2019.

També estic plantejant utilitzar el Jumping Jack com a semàfor i utilitzar el programa de reconeixement de posició de les extremitats "project posenet" com a eina per llegir les posicions del Jumping Jack i tornar-lo a un número. D'aquesta manera, fins i tot pot comunicar text, ja que 2x 8 posicions poden indicar 64 números diferents, més que suficients per a alfabet, números i signes. Això podria permetre, encara que lleugerament modificat, una realització física per al IETF proposat "La transmissió de datagrames IP a través del sistema de senyalització de bandera de semàfor (SFSS)" (https://tools.ietf.org/html/rfc4824).

Però aquest serà un altre instructiu. I, com els primers experiments van indicar que el gat saltador necessitarà modificacions significatives abans que el sistema d’intel·ligència artificial pugui reconèixer-lo com a humà, pot requerir un cert temps.

M'agradaria cridar la vostra atenció sobre el següent documentable: Object-Finding-Personal-Assistant-Robot-Ft-Raspberry, on es descriu un robot de recerca d'objectes que utilitza una combinació d'un TPU Raspberry Pi i Google Coral.

Recomanat: