Sommario:
- Forniture
- Passaggio 1: configurazione del sistema
- Passaggio 2: utilizzo del dispositivo
- Passaggio 3: la sceneggiatura
Video: Un Hearing MeArm, acceleratore TPU di Google Coral guidato: 3 passaggi
2024 Autore: John Day | [email protected]. Ultima modifica: 2024-01-30 10:02
Di seguito vorrei descrivere una versione a comando vocale del MeArm, un piccolo braccio robotico xyz con una pinza. Ho usato il MeArm Pi delle industrie MIME, ma il sistema dovrebbe essere applicabile a qualsiasi versione di lui MeArm, o dispositivi servo-guidati simili.
L'utilizzo dell'acceleratore TPU di Google Coral consente di eseguire script di riconoscimento vocale TensorFlow offline rapidi sul Raspberry Pi e di controllare i dispositivi fisici tramite ordini vocali, con una latenza inferiore a un secondo.
Il dispositivo qui descritto è una combinazione e un'estensione dei concetti descritti in due istruzioni precedenti. È un'estensione di una precedente implementazione del controllo vocale di Google Coral, un Jumping Jack, descritto qui e un grande miglioramento di un MeArm controllato dalla voce di Google AIY descritto qui.
Il MeArm a comando vocale che utilizzava il sistema AIY di Google Voice richiedeva l'accesso online, non era facile da implementare, richiedeva la pressione di un pulsante per attivare l'ascolto degli ordini vocali e aveva un lungo tempo di latenza. L'acceleratore TPU di Google Coral utilizzato ora consente di eseguire modelli TensorFlowLite offline ad alta velocità su un Raspberry Pi o altri dispositivi Linux. Tra gli esempi sulla pagina di Google Coral Github c'è un esempio chiamato "hearing snake" per un sistema di riconoscimento vocale in grado di comprendere 140 frasi chiave (settembre 2019), che vengono poi mappate su battute virtuali. L'abbinamento di queste "battute di tasti" con l'esecuzione di alcune funzioni programmate in Python consente di costruire un dispositivo controllato da comandi vocali. Di recente ho descritto una prima implementazione, un jack di salto elettromeccanico a comando vocale. L'implementazione qui è un po' più complessa e consente di controllare tutti e quattro i servi del MeArm per muovere il MeArm continuamente o farlo spostare su un numero predefinito di posizioni, o per eseguire alcuni compiti più complessi.
Utilizzando lo script fornito qui come esempio, dovrebbe essere relativamente semplice costruire altri dispositivi a comando vocale, ad es. automobili robotiche o unità di tecnologia assistiva.
Forniture
- MeArm. Usato qui: MeArm Pi di MIME Industries
- Lampone Pi 4
- Acceleratore TPU di Google Coral
- Cofano servo Adafruit a 16 canali
- alcuni cavi jumper
- opzionale: condensatore per servocofano, circa 400 µF per 4 servi (consigliato da Adafruit)
- Alimentazione 5-6 V per servocofano. Ho usato un vecchio caricabatterie da 6 V, funziona anche un pacco batterie AA 4x
- Microfono. Ho usato una vecchia webcam Microsoft HD3000 come microfono.
Passaggio 1: configurazione del sistema
Scarica l'immagine Raspian preconfigurata per Google Coral TPU Accelerator dalla pagina Google Coral Github e installala su una scheda µSD. L'immagine contiene anche una serie di script di esempio. Imposta il Pi come indicato.
Installa l'esempio Keyword Spotter dal sito Google Coral GitHub, se non incluso nell'immagine, e tutti i programmi richiesti. Collega il microfono al Pi. Consiglierei di giocare con l'esempio "Hearing Snake" per assicurarsi che tutto funzioni.
Scarica e installa il software del cofano Adafruit a 16 canali, come descritto qui. Installa il cofano e gioca con gli esempi di Adafruit per assicurarti che tutto funzioni correttamente.
Scarica i file allegati a questa istruzione e copiali nella cartella "Project Keyword Spotter". Il file "commands_v1_MeArm.txt" deve essere copiato nella sottocartella "config".
Collega i servi del tuo MeArm al cofano servo come indicato. Ho usato la porta 15 per su/giù, la porta 11 per avanti/indietro, la porta 7 per girare e la porta 3 per i servi della pinza.
All'interno dello script potresti dover regolare i valori min/center/max per ogni servo alla tua configurazione, queste impostazioni aiutano ad evitare danni ai servo. Potrebbe anche essere necessario modificare gli elenchi inclusi "posizioni", "trasporto1" e "trasporto2".
Esegui lo script. Finora l'avevo eseguito dall'IDE.
Nel caso in cui desideri modificare le frasi chiave che evocano una determinata funzione in base alle tue esigenze. Un elenco completo delle frasi chiave disponibili si trova nel file "labels_gc2 raw.txt" nella sottocartella di configurazione.
Il sistema ha un tempo di latenza di circa 1 secondo, ma dipende molto da quali azioni vengono eseguite. In alcuni casi la fase chiave deve essere ripetuta, l'accuratezza del riconoscimento non è sempre del 100%.
Passaggio 2: utilizzo del dispositivo
Se tutto è impostato e verificato, puoi eseguire il dispositivo.
Una limitazione attuale è che un dato ordine viene eseguito ripetutamente finché non viene interrotto (usando "stop game") o viene dato un altro ordine. Compiti complessi a più fasi, ad es. "transport1" (evocato dalla frase "launch game") vengono sempre eseguiti fino al passaggio finale.
Quindi "girando a destra" il dispositivo si sposterà a piccoli passi verso destra fino all'arresto o al raggiungimento del valore massimo preimpostato. "launch game", "next game" o "start_video" avvieranno una serie di mosse che sono definite da elenchi contenenti l'impostazione per ogni servo in un dato passo. "gioco casuale" consentirà al dispositivo di saltare da un passaggio all'altro, scelto casualmente da un elenco di impostazioni.
Come puoi vedere nel video allegato, avevo costruito un oggetto a forma di diabolo da LEGO che può essere raccolto dal MeArm ed essere trasportato da un luogo all'altro da una serie predefinita di movimenti. È possibile definire le proprie funzioni modificando gli elenchi 'transport1' o 'transport2'.
Passaggio 3: la sceneggiatura
Lo script qui elencato è una modifica dell'esempio "Hearing Snake" da "Project Keyword Spotter". L'esempio è stato ridotto al minimo, quindi è stata aggiunta la parte per il pilotaggio dei servi, basata sul software e sugli esempi forniti per il cofano servo Adafruit.
Lo script non è stato ottimizzato per ora. Usa a tuo rischio, sentiti libero di modificare e ottimizzare.
Oltre allo script python c'è il file comandi e il file etichette usato. Posizionalo nella sottocartella config.
Come accennato in precedenza, potrebbero essere necessarie diverse regolazioni dei parametri per adattare lo script al tuo MeArm speciale o a qualche altro dispositivo.
# Copyright 2019 Google LLC#
# Concesso in licenza con la licenza Apache, versione 2.0 (la "Licenza"); # non puoi usare questo file se non in conformità con la Licenza. # È possibile ottenere una copia della Licenza all'indirizzo # # 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 # # Se non richiesto dalla legge applicabile o concordato per iscritto, il software # distribuito ai sensi della Licenza è distribuito "COS COM'È", # SENZA GARANZIE O CONDIZIONI DI QUALSIASI TIPO, espresso o implicito. # Vedere la Licenza per le autorizzazioni e le # limitazioni che regolano la lingua specifica sotto la Licenza. # il codice originale "hearing_snake" è stato modificato per un'implementazione per il MeArm dal Dr H. ''' Istruzioni La mia implementazione utilizza un Raspbery Pi 4 con un acceleratore Google Coral e un servocofano Adafruit a 16 canali collegato. I servi di un MeArm (MIME Industries) erano collegati alle porte 3, 7, 11 e 15 del cofano. Per i dettagli si prega di dare un'occhiata al "Hearing MeArm" Instructable. Comandi: "posizione x", x= da 0 a 9, sposta il dispositivo in una data posizione predefinita. "sposta/vai su", "sposta/vai giù", "vai/gira avanti", "vai/gira indietro", "gira/vai a sinistra" e "gira/vai a destra" evocano un movimento lento e graduale nel dato direzione, "stop game" interrompe i movimenti. "apri scheda" e "chiudi scheda" aprono o chiudono la pinza. "start video" evoca il dispositivo per seguire un ordine prestabilito di posizioni, definito dall'elenco "posizioni". "gioco casuale" si traduce in uno schema casuale di movimenti, "stop game" lo termina. "launch game" avvia un'altra serie di mosse predefinite dalla lista 'transport1', "prossima partita" l'operazione inversa predefinita da 'transport2' Usa a tuo rischio e pericolo. ''' from _future_ import absolute_import da _future_ import division from _future_ import print_function import argparse import os from random import randint from threading import Tempo di importazione thread da edgetpu.basic.basic_engine import BasicEngine import modello import pygame from pygame.locals import * import coda da importazione casuale randrange da adafruit_servokit import ServoKit import board import busio import adafruit_pca9685 import time i2c = busio. I2C(board. SCL, board. SDA) hat = adafruit_pca9685. PCA9685(i2c) hat.frequency = 60 kit = ServoKit(channels=16) # imposta il numero di canali #kit.servo[0].actuation_range = 160 #kit.servo[0].set_pulse_width_range(1000, 2000) # impostazioni min, center e max up_l = 145 # servo up/down: up md_l = 95 dn_l = 45 up_r = 135 # servo avanti/indietro md_r = 90 dn_r = 50 ri_t = 30 # braccio girevole destra o sinistra: posizione destra md_t = 90 # braccio girevole destra o sinistra: posizione centrale le_t = 150 op_g = 65 # pinza aperta md_g = 90 # pinza centrata cl _g = 130 # pinza chiusa vert = 15 # numero di porte servo, servo su/giù avanti = 11 # numero di porte servo, rotazione servo in avanti/indietro = 7 # porta servo per girare la presa servo = 3 # porta servo per presa servo #elenco delle impostazioni del braccio per nove posizioni position = [(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, md), (dn_l, dn_r, le_t, md_g)] # definisce 10 posizioni base, indicate da interi 0-9 # procedure di trasporto [vert/forward/turn/grip] 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), #get object (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)]
trasporto2 = [(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)]
danza1 =(0, 8, 7, 4, 1, 2, 3, 6, 9, 8, 5, 2, 1, 4, 7, 8, 9, 6, 3, 2, 0) # a "danza"
#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]. angolo = stato[2] kit.servo[grip].angolo = stato[3] print (stato) classe Controler(oggetto): #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): # guida MeArm alle posizioni preimpostate, keywords: "position x" key = int(keys) p = position[key] a = p[0] b = p[1] c = p[2] d = p[3] print ("Positions: ", key, " vert/forw/turn/grip: ", a, "/", b, "/", c, "/", d, "gradi") status = [a, b, c, d] # document lo stato corrente print (status) # sys.stdout.write("Position: ", key, " left/right: ", a, "/", b, "degree") 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): # controlla MeArm dance, parola chiave: "start_video" dnce = dance1 sp=(len(dnce)) per r nell'intervallo (sp): #ordine danzante delle posizioni, passi sp dc = dnce[r] p = posizione[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) # imposta la velocità dei movimenti time.sleep(0.5) # break alla fine della procedura def TransMeArm1(self): # controlla il trasporto MeArm 1, parola chiave: "launch game" tr1 = transport1 sp=(len(tr1)) #calcola il numero di passaggi per r nell'intervallo (sp): #vai a qualsiasi passaggio 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) # set velocità dei movimenti time.sleep(0.5) def TransMeArm2(self): # controlla MeArm dance, parola chiave: "prossima partita" tr2 = transport2 sp=(len(tr2)) for r in range (sp): #ordine danzante delle posizioni, passi sp 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 print (p) time.sleep(1) # imposta la velocità dei movimenti time.sleep(0.5) def RandomMoves(self): # salta casualmente tra le posizioni predefinite, keyword: "random game" dr= randrange (9) #seleziona casualmente una posizione p = position[dr] # legge i parametri di posizione 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) # imposta la velocità dei movimenti def MoveUp(self): # solleva la pinza a piccoli passi u0 = status[0] # legge lo stato corrente u1 = u0 + 5 # più x gradi if (u1 > up_l): # verifica se non supera i parametri min/max u1 = up_l # altrimenti imposta il valore min/max kit.servo[vert].angle = u1 # sposta lo stato del servo[0] = u1 # regola il valore dello stato print (" up ", status) time.sleep (1) # imposta la velocità def MoveDown(self): d 0 = status[0] d1 = d0 - 5 #meno x gradi if (d1 up_r): f1 = up_r kit.servo[forw].angle = f1 # sposta servo status[1] = f1 print ("forward ", status) time.sleep (1) def MoveBack(self): b0 = status[1] b1 = b0 - 5 #meno x gradi 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(self): r0 = status[2] r1 = r0 - 2 #meno x gradi 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 # imposta il grip in posizione "aperto": "open_tab" time.sleep(0.5) status[3] = op_g def CloseGrip(self): kit.servo[grip].angle = cl_g # imposta il grip in posizione "chiuso": " close_tab" time.sleep(0.5) status[3] = cl_g def StopMove(self): # non fa nulla, ma interrompe i movimenti print ("stop ", status) time.sleep(0.25) def spotter(self, args): engine = BasicEngine(args.model_file) mic = args.mic se args.mic è Nessun altro int(args.mic) model.classify_audio(mic, engine, label_file="config/labels_gc2.raw.txt", command_file="config/commands_v1_MeArm.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): if not self.on_init(): self._running = False q = model.get_queue() self._controler = Controler(q) if not args.debug_keyboard: t = Thread(target=self.spotter, args=(args,)) t.daemon = True t.start() item = -1 while self._running: pygame.event.pump() if args.debug_keyboard: keys = pygame.key.get_pressed() else: try: new_item = q.get(True, 0.1) tranne queue. Empty: new_item = None se new_item non è 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 item == "right": # gira a destra self. MoveRight() if (args.debug_ke yboard and keys[pygame. K_LEFT]) or item == "left": # gira a sinistra 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": # all'indietro self. MoveBack() if (args.debug_keyboard and keys[pygame. K_F]) or item == "f": # inoltra self. MoveForw() if (args.debug_keyboard and keys[pygame. K_O]) o item == "o": # apri grip: self. OpenGrip() if (args.debug_keyboard and keys[pygame. K_C]) or item == "c": # chiudi grip: self. CloseGrip() if (args.debug_keyboard and keys [pygame. K_S]) or item == "s": # stop motion: "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]) o item == "2": self. MeArmPos(2) if (args.debug_keyboard and keys[pygame. K_3]) o it em == "3": self. MeArmPos(3) if (args.debug_keyboard and keys[pygame. K_4]) o item == "4": self. MeArmPos(4) if (args.debug_keyboard and keys[pygame. K_5]) o item == "5": self. MeArmPos(5) if (args.debug_keyboard and keys[pygame. K_6]) o item == "6": self. MeArmPos(6) if (args.debug_keyboard e keys[pygame. K_7]) o item == "7": self. MeArmPos(7) if (args.debug_keyboard and keys[pygame. K_8]) o item == "8": self. MeArmPos(8) if (args.debug_keyboard and keys[pygame. K_9]) o item == "9": self. MeArmPos(9) if (args.debug_keyboard and keys[pygame. K_a]) o item == "d": self. DancingMeArm() #dancing MeArm, su "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[pygame. K_j]) o item == "j": self. TransMeArm1() # oggetto di trasporto: "lunch_game" if (args.debug_keyboard and keys[pygame. K_k]) o item == "k": self. TransMeArm2() # oggetto di trasporto direzione inversa: "next_game" ''' if (args.debug_keyboard e keys[pygame. K_l]) o item == "l": self. JumpingJack2(1) #LED lampeggia "target" ''' time.sleep(0.05) self.on_cleanup() if _name_ == '_main_': parser = argparse. ArgumentParser() parser.add_argument('--debug_keyboard', help='Usa la tastiera per controllare MeArm.', action='store_true', default=False) model.add_model_flags(parser) args = parser.parse_args () the_app = App() the_app.on_execute(args)
Consigliato:
Panzer VIII Maus guidato da Microbit: 4 passaggi
Panzer VIII Maus guidato da Microbit: è stato in questo semestre che la classe dotata della nostra scuola ha tenuto un corso speciale: utilizzare BBC micro: bit per alimentare un'auto stampata in 3D. Ma non mi è piaciuto il telaio che il nostro insegnante ha realizzato per noi (sai , digita "BitCar Micro Bit" su Google e vedrai molti th
Veloce e sporco - Acceleratore di prova a 3 fili per scooter elettrico: 3 passaggi
Veloce e sporco - Acceleratore di prova a 3 fili per scooter elettrico: ho ordinato un nuovo controller del motore per scooter 36v senza un nuovo acceleratore a 3 fili. Mentre aspetto che arrivi il mio nuovo acceleratore, ho fatto un progetto veloce e sporco per simulare l'acceleratore per il mio nuovo controller. Ho fatto un altro progetto per convertire anche il mio attuale
Acceleratore Fidget Spinner fai-da-te per SOTTO $2!: 7 passaggi
Fai da te Fidget Spinner Accelerator per MENO di $ 2!: Ciao visitatori! Mi chiamo Youri e mi piace creare e pubblicare progetti di elettronica. Oggi ho un'istruzione basata su questa istruzione di tanner_tech. Mi ha ispirato a ricreare il suo design e creare un PCB effettivo di esso. È realizzato utilizzando t
A Hearing Jumping Jack, versione dell'acceleratore TPU di Google Coral: 4 passaggi
A Hearing Jumping Jack, versione Google Coral TPU Accelerator: muove i suoi arti, ascolta i tuoi ordini, è guidato dalla più recente tecnologia di apprendimento automatico! Il "Hearing Jumping Jack" è un semplice Jumping Jack elettromeccanico, azionato da due micro servi e un ingranaggio molto semplice, con i LED come "occhi". Esso
WIND - Acceleratore di progetto per la piuma di Adafruit: 9 passaggi (con immagini)
WIND - Acceleratore di progetto per Adafruit Feather: Ho lentamente raccolto i diversi microcontrollori e schede sensori Adafruit Feather che sono disponibili da Adafruit. Rendono la prototipazione e i test super facili e io sono un grande fan del layout della scheda. Da quando mi sono trovata a usare