Taula de continguts:

A Hearing MeArm, impulsat per Google Coral TPU Accelerator: 3 passos
A Hearing MeArm, impulsat per Google Coral TPU Accelerator: 3 passos

Vídeo: A Hearing MeArm, impulsat per Google Coral TPU Accelerator: 3 passos

Vídeo: A Hearing MeArm, impulsat per Google Coral TPU Accelerator: 3 passos
Vídeo: meArm Robot: Introduction 2024, Desembre
Anonim
A Hearing MeArm, impulsat per Google Coral TPU Accelerator
A Hearing MeArm, impulsat per Google Coral TPU Accelerator
A Hearing MeArm, impulsat per Google Coral TPU Accelerator
A Hearing MeArm, impulsat per Google Coral TPU Accelerator
A Hearing MeArm, impulsat per l’accelerador TPU de Google Coral
A Hearing MeArm, impulsat per l’accelerador TPU de Google Coral
A Hearing MeArm, impulsat per l’accelerador TPU de Google Coral
A Hearing MeArm, impulsat per l’accelerador TPU de Google Coral

A continuació, voldria descriure una versió controlada per veu del MeArm, un petit braç robot xyz amb una pinça. He utilitzat el MeArm Pi de les indústries MIME, però el sistema hauria de ser aplicable a qualsevol versió de He MeArm o dispositius servo-accionats similars.

L'ús de Google Coral TPU Accelerator permet executar ràpids scripts de reconeixement de veu TensorFlow fora de línia al Raspberry Pi i, per tant, controlar els dispositius físics per ordres parlats, amb una latència inferior a un segon.

El dispositiu que es descriu aquí és una combinació i extensió de conceptes descrits en dos instruccions anteriors. Es tracta d’una extensió d’una implementació anterior del control de veu de Google Coral, un Jumping Jack, descrit aquí i una gran millora d’un MeArm controlat per veu de Google AIY descrit aquí.

El MeArm controlat per veu que utilitzava el sistema AIY de Google Voice requeria accés en línia, no era fàcil d’implementar, calia prémer un botó per activar l’escolta de les ordres de veu i tenia un temps de latència llarg. L’accelerador de Google Coral TPU que s’utilitza ara permet executar els models TensorFlowLite fora de línia amb una velocitat elevada en un Raspberry Pi o en altres dispositius Linux. Entre els exemples de la pàgina de Google Coral Github hi ha un exemple anomenat "serp auditiva" per a un sistema de reconeixement de veu que pot entendre 140 frases clau (setembre de 2019), que després es mapen a pulsacions de tecles virtuals. Unir aquestes "pulsacions de tecles" amb l'execució d'algunes funcions programades a Python permet construir un dispositiu controlat per ordres de veu. Recentment havia descrit una primera implementació, una presa de salt electromecànica controlada per veu. La implementació aquí és una mica més complexa i permet controlar els quatre servos del MeArm per moure el MeArm contínuament o fer-lo passar a una sèrie de posicions, o per realitzar algunes tasques més complexes.

Utilitzant l’script que es proporciona aquí com a exemple, hauria de ser relativament senzill construir altres dispositius controlats per veu, per exemple. cotxes robòtics o unitats de tecnologia assistencial.

Subministraments

  • MeArm. S'utilitza aquí: MeArm Pi de MIME Industries
  • Raspberry Pi 4
  • Google Coral TPU Accelerator
  • Servo capó de 16 canals Adafruit
  • alguns cables de pont
  • opcional: condensador per servo capó, uns 400 µF per a 4 servos (recomanat per Adafruit)
  • Font d'alimentació de 5-6 V per al capó servo. Aquí he utilitzat un vell carregador de 6 V, també funciona un paquet de bateries de 4x AA
  • Micròfon. He utilitzat una antiga càmera web Microsoft HD3000 com a micròfon.

Pas 1: Configuració del sistema

Configuració del sistema
Configuració del sistema
Configuració del sistema
Configuració del sistema

Descarregueu la imatge Raspian preconfigurada de Google Coral TPU Accelerator des de la pàgina de Google Coral Github i instal·leu-la a una targeta µSD. La imatge també conté diversos exemples de scripts. Configureu el Pi tal com s’indica.

Instal·leu l'exemple de Keyword spotter del lloc de Google Coral GitHub, si no s'inclou a la imatge i de tots els programes necessaris. Connecteu el micròfon al Pi. Recomanaria jugar amb l'exemple "Serp que escolta" per assegurar-me que tot funciona.

Descarregueu i instal·leu el programari del capó Adafruit de 16 canals, tal com es descriu aquí. Instal·leu el capó i jugueu amb els exemples d’Adafruit per assegurar-vos que tot funciona correctament.

Baixeu-vos els fitxers adjunts a aquest instructiu i copieu-los a la carpeta "Project Keyword Spotter". El fitxer "commands_v1_MeArm.txt" s'ha de copiar a la subcarpeta "config".

Connecteu els servos de MeArm al capó del servo tal com s’indica. He utilitzat el port 15 per pujar / baixar, el port 11 per endavant / enrere, el port 7 per girar i el port 3 per als servos de la pinça.

Dins de l'script, és possible que hàgiu d'ajustar els valors mínim / centre / màxim de cada servo a la vostra configuració. Aquests paràmetres ajuden a evitar danys als servos. És possible que també hàgiu de modificar les llistes "posicions", "transport1" i "transport2" incloses.

Executeu l'script. Fins ara l’havia executat des de l’IDE.

En cas que vulgueu modificar les frases claus que evoquen una determinada funció segons les vostres necessitats, trobareu una llista completa de frases claus disponibles al fitxer "labels_gc2 raw.txt" de la subcarpeta de configuració.

El sistema té un temps de latència d’aproximadament 1 segon, però depèn de quines accions es realitzin. En alguns casos s’ha de repetir la fase clau, la precisió del reconeixement no sempre és del 100%.

Pas 2: utilitzar el dispositiu

Si tot està configurat i marcat, podeu executar el dispositiu.

Una limitació actual és que una ordre determinada s’executa de manera repetitiva sempre que no s’aturi (mitjançant el "joc de parada") o es doni una altra ordre. Tasques complexes de diversos passos, per exemple "transport1" (evocat per la frase "joc de llançament") sempre s'executa fins al pas final.

Per tant, "gireu a la dreta" el dispositiu es mourà en petits passos cap a la dreta fins que s'aturi o s'assoleixi el valor màxim predeterminat. "launch game", "next game" o "start_video" iniciarà una sèrie de moviments definits per llistes que contenen la configuració de cada servo en un pas determinat. "joc aleatori" farà saltar el dispositiu d'un pas a un altre, triat a l'atzar d'una llista de configuracions.

Com podeu veure al vídeo adjunt, havia construït un objecte de forma diabòlica de LEGO que el MeArm pot recollir i transportar d'un lloc a un altre mitjançant un conjunt de moviments predefinits. Podeu definir les vostres pròpies funcions modificant les llistes "transport1" o "transport2".

Pas 3: l'script

El guió que es mostra aquí és una modificació de l'exemple "Serp auditiva" de "Project Keyword Spotter". L'exemple s'ha reduït al mínim i, a continuació, es va afegir la peça per a la conducció dels servos, basada en el programari i els exemples proporcionats per al capot de servo Adafruit.

El guió encara no s’ha optimitzat. Utilitzeu-ho pel vostre compte i risc, no dubteu a modificar-lo i optimitzar-lo.

A més de l'script python, hi ha el fitxer d'ordres i el fitxer etiquetes utilitzat. Col·loqueu-lo a la carpeta de configuració.

Com s'ha esmentat anteriorment, és possible que siguin necessaris diversos ajustaments de paràmetres per adaptar l'script per al vostre MeArm especial o algun altre dispositiu.

# 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 # # href = "https://www.apache.org/licenses/LICENSE-2.0" href = "https://www.apache.org/licenses/LICENSE-2.0" https://www.apache.org/licenses/LICENSE-2.0 # # Llevat que la llei aplicable ho exigeixi o s’accepti per escrit, el programari # distribuït sota la llicència es distribueix en base “TAL COM ÉS”, # SENSE GARANTIES O CONDICIONS DE QUALSEVOL TIPUS, exprés o implícit. # Vegeu la Llicència per obtenir els idiomes específics que regulen els permisos i les # limitacions de la Llicència. # El codi original "hearing_snake" va ser modificat per una implementació del MeArm pel Dr H. '' 'Instruccions La meva implementació utilitza un Raspbery Pi 4 amb un accelerador de Google Coral i un servo capó Adafruit de 16 canals connectat. Els servos d'un MeArm (indústries MIME) estaven connectats als ports 3, 7, 11 i 15 del capó. Per obtenir informació detallada, consulteu la secció instructiva "Hearing MeArm". Ordres: "posició x", x = 0 a 9, mou el dispositiu a una posició predefinida determinada. "moure / pujar", "moure / baixar", "anar / girar endavant", "anar / girar enrere", "girar / anar a l'esquerra" i "girar / anar a la dreta" evoquen un moviment lent i pas a pas direcció, "atura el joc" atura els moviments. "obre pestanya" i "tancar pestanya" obre o tanca la pinça. "iniciar vídeo" evoca que el dispositiu vagi a seguir un ordre predeterminat de posicions, definit per la llista "posicions". "joc aleatori" dóna lloc a un patró aleatori de moviments, "atura el joc" acaba. "joc de llançament" inicia una altra sèrie de moviments predefinits per la llista "transport1", "joc següent" l'operació inversa predefinida per "transport2" Utilitzeu-ho pel vostre compte i risc. '' 'from _future_ import absolute_import from _future_ import divisió from _future_ import print_function import argparse import os from random random randint from threading import Temps d'importació del fil des edgetpu.basic.basic_engine importació BasicEngine importació model pygame des pygame.locals importació * cua d'importació des importació aleatòria randrange 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) # nombre de canals establert # kit.servo [0].actuation_range = 160 # kit.servo [0].set_pulse_width_range (1000, 2000) # configuració mínima, central i màxima up_l = 145 # servo pujada / baixada: amunt md_l = 95 dn_l = 45 up_r = 135 # servo endavant / enrere md_r = 90 dn_r = 50 ri_t = 30 # girant el braç a la dreta o esquerra: posició dreta md_t = 90 # girant el braç a la dreta o esquerra: posició central le_t = 150 op_g = 65 # pinça oberta md_g = 90 # pinça centrada cl _g = 130 # pinça tancada vert = 15 # nombre de port servo, servo pujada / baixada forw = 11 # nombre de port servo, gir servo endavant / enrere = 7 # port servo per girar servo grip = 3 # servo servo per grip servo # llista de paràmetres de braç per a nou posicions posició = [(md_l, md_r, md_t, op_g), (up_l, md_r, ri_t, op_g), (up_l, md_r, md_t, cl_g), (up_l, md_r, le_t, cl_g), (md_l, md_r, md_t, op_g), (md_l, md_r, md_t, md_g), (md_l, md_r, md_t, cl_g), (dn_l, dn_r, ri_t, op_g), (dn_l, dn_r, m,), (dn_l, dn_r, le_t, md_g)] # defineix 10 posicions base, indicades per enters 0-9 # procediments de transport [vert / endavant / gir / adherència] transport1 = [(140, 70, 65, op_g), (110, 50, 65, op_g), (65, 50, 65, op_g), (65, 70, 65, cl_g), (120, 70, 65, cl_g), object #get (100, 70, 135, cl_g), (100, 80, 135, cl_g), (100, 80, 135, md_g), (100, 80, 135, op_g), (140, 70, 135, op_g), (140, 70, 90, op_g), (140, 70, 65, op_g)]

transport2 = [(140, 70, 65, op_g), (140, 70, 135, op_g), (95, 70, 135, op_g), (95, 80, 135, op_g), (95, 80, 135, cl_g), (110, 70, 135, cl_g), (110, 70, 65, cl_g), (70, 70, 65, cl_g), (70, 70, 65, op_g), (80, 50, 65, op_g)]

ball1 = (0, 8, 7, 4, 1, 2, 3, 6, 9, 8, 5, 2, 1, 4, 7, 8, 9, 6, 3, 2, 0) # a "ball"

#moving MeArm to Zero position status = [md_l, md_r, md_t, md_g] kit.servo [vert].angle = status [0] kit.servo [forw].angle = status [1] kit.servo [turn]. angle = status [2] kit.servo [grip].angle = status [3] print (status) class Controler (object): #Callback function def _init _ (self, q): self._q = q def callback (self, command): 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 = False def MeArmPos (self, keys): # impulsa MeArm a posicions predeterminades, paraules clau: "position x" key = int (keys) p = posició [clau] a = p [0] b = p [1] c = p [2] d = p [3] imprimir ("Posicions:", clau, "vert / forw / turn / grip:", a, "/", b, "/", c, "/", d, "graus") estat = [a, b, c, d] # documents estat actual imprimeix (estat) # sys.stdout.write ("Posició: ", clau", esquerra / dreta: ", a," / ", b," grau ") kit.servo [vert].angle = a kit.servo [forw].angle = b kit.servo [turn].angle = c kit.servo [grip].angle = d time.sleep (0.5) def DancingMeArm (self): # controls MeArm dance, paraula clau: "start_video" dnce = dance1 sp = (len (dnce)) per a r en el rang (sp): #ordre de ball de les posicions, sp passos dc = dnce [r] p = posició [dc] a = p [0] b = p [1] c = p [2] d = p [3] kit.servo [vert].angle = a kit.servo [forw].angle = b kit.servo [turn].angle = c kit.servo [grip].angle = d time.sleep (1) # estableix la velocitat dels moviments time.sleep (0,5) # interrupció al final del procediment def TransMeArm1 (auto): # controla el transport MeArm 1, paraula clau: "joc de llançament" tr1 = transport1 sp = (len (tr1)) #calcular el nombre de passos per a r en el rang (sp): # anar a qualsevol pas p = tr1 [r] a = p [0] b = p [1] c = p [2] d = p [3] kit. servo [vert].angle = a kit.servo [forw].angle = b kit.servo [turn].angle = c kit.servo [grip].angle = d print (p) time.sleep (1) # sets velocitat de moviments time.sleep (0,5) def TransMeArm2 (self): # controls MeArm dance, paraula clau: "joc següent" tr2 = transport2 sp = (len (tr2)) per a r en el rang (sp): #ordre de ball de les posicions, sp passos p = tr2 [r] a = p [0] b = p [1] c = p [2] d = p [3] kit.servo [vert].angle = a kit.servo [forw].angle = b kit.servo [turn].angle = c kit.servo [grip].angle = d imprimir (p) time.sleep (1) # defineix la velocitat dels moviments time.sleep (0.5)) def RandomMoves (auto): # salta a l'atzar entre posicions predefinides, paraula clau: "joc aleatori" dr = randrange (9) # selecciona de forma aleatòria una posició p = posició [dr] # llegeix els paràmetres de posició a = p [0] b = p [1] c = p [2] d = p [3] kit.servo [vert].angle = a kit.servo [forw].angle = b kit.servo [turn].angle = c kit.servo [grip].angle = d time.sleep (1) # estableix la velocitat dels moviments def MoveUp (auto): # pinces elevadores en petits passos u0 = estat [0] # llegir estat actual u1 = u0 + 5 # més x graus si (u1 > up_l): # proves si no superen els paràmetres min / max u1 = up_l # en cas contrari s'estableix en el valor mínim / màxim kit.servo [vert].angle = u1 # move servo status [0] = u1 # ajusta el valor de l'estat print (" amunt ", estat) time.sleep (1) # defineix la velocitat def MoveDown (auto): d 0 = estat [0] d1 = d0 - 5 #minus x graus if (d1 up_r): f1 = up_r kit.servo [forw].angle = f1 # move servo status [1] = f1 print ("endavant", estat) time.sleep (1) def MoveBack (self): b0 = status [1] b1 = b0 - 5 #minus x graus if (b1 le_t): l1 = le_t kit.servo [turn].angle = l1 # move servo status [2] = l1 print ("left", status) time.sleep (0.2) def MoveRight (auto): r0 = status [2] r1 = r0 - 2 #minus x graus if (r1 <ri_t): r1 = ri_t kit.servo [turn].angle = r1 # move servo status [2] = r1 print ("right", status) time.sleep (0.2) def OpenGrip (self): kit.servo [grip].angle = op_g # set grip a position "open": "open_tab" time.sleep (0.5) status [3] = op_g def CloseGrip (self): kit.servo [grip].angle = cl_g # set grip a posició "tancada": " close_tab "time.sleep (0.5) status [3] = cl_g def StopMove (auto): # no fa res, però atura els moviments d'impressió (" stop ", estat) time.sleep (0.25) def spotter (auto, args): motor = BasicEngine (args.model_file) mic = args.mic si args.mic és None else int (args.mic) model.classify_audio (mic, engine, labels_file = "config / labels_gc2.raw.txt", commands_file = "config / commands_v1_MeArm.txt", dectection_callback = self._controler.callback, sample_rate_hz = int (args.sample_rate_hzes), num_fram = int (args.num_frames_hop)) def on_execute (self, args): si no self.on_init (): self._running = False q = model.get_queue () self._controler = Controler (q) si no args.debug_keyboard: t = Fil (objectiu = self.spotter, args = (args,)) t.daemon = True t.start () element = -1 mentre self._running: pygame.event.pump () si args.debug_keyboard: keys = pygame.key.get_pressed () else: try: new_item = q.get (True, 0.1) except a queue. Empty: new_item = None if new_item is not 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. MeArmPos (7) # if (args.debug_keyboard and keys [pygame. K_RIGHT]) o element == "dreta": # gireu a la dreta self. MoveRight () si (args.debug_ke yboard and keys [pygame. K_LEFT]) or item == "left": # turn left self. MoveLeft () if (args.debug_keyboard and keys [pygame. K_UP]) or item == "up": self. MoveUp () if (args.debug_keyboard and keys [pygame. K_DOWN]) or item == "down": self. MoveDown () if (args.debug_keyboard and keys [pygame. K_B]) or item == "b": # backwards self. MoveBack () if (args.debug_keyboard and keys [pygame. K_F]) or item == "f": # endavant self. MoveForw () if (args.debug_keyboard and keys [pygame. K_O]) or item == "o": # open grip: self. OpenGrip () if (args.debug_keyboard and keys [pygame. K_C]) or item == "c": # close grip: self. CloseGrip () if (args.debug_keyboard and keys [pygame. K_S]) or item == "s": # stop movement: "start_game" self. StopMove () if (args.debug_keyboard and keys [pygame. K_0]) or item == "0": self. MeArmPos (0) if (args.debug_keyboard and keys [pygame. K_1]) or item == "1": self. MeArmPos (1) if (args.debug_keyboard and keys [pygame. K_2]) or item == "2": self. MeArmPos (2) if (args.debug_keyboard and keys [pygame. K_3]) or it em == "3": self. MeArmPos (3) if (args.debug_keyboard and keys [pygame. K_4]) or item == "4": self. MeArmPos (4) if (args.debug_keyboard and keys [pygame. K_5]) o element == "5": self. MeArmPos (5) if (args.debug_keyboard and keys [pygame. K_6]) or item == "6": self. MeArmPos (6) if (args.debug_keyboard and keys [pygame. K_7]) or item == "7": self. MeArmPos (7) if (args.debug_keyboard and keys [pygame. K_8]) or item == "8": self. MeArmPos (8) if (args.debug_keyboard and keys [pygame. K_9]) or item == "9": self. MeArmPos (9) if (args.debug_keyboard and keys [pygame. K_a]) or item == "d": self. DancingMeArm () #dancing MeArm, a "next_game" if (args.debug_keyboard and keys [pygame. K_r]) or item == "r": self. RandomMoves () #random dance "random game" if (args.debug_keyboard and keys [arg. pygame. K_j]) o item == "j": self. TransMeArm1 () # transport object: "lunch_game" if (args.debug_keyboard and keys [pygame. K_k]) or item == "k": self. TransMeArm2 () # objecte de transport direcció inversa: "joc_pròxim" '' 'if (args.debug_keyboard i keys [pygame. K_l]) or item == "l": self. JumpingJack2 (1) #LED parpelleja "target" '' 'time.sleep (0.05) self.on_cleanup () if _name_ ==' _main_ ': parser = argparse. ArgumentParser () parser.add_argument ('- debug_keyboard', help = 'Utilitzeu el teclat per controlar MeArm.', action = 'store_true', per defecte = False) model.add_model_flags (parser) args = parser.parse_args () the_app = App () the_app.on_execute (args)

Recomanat: