Sommario:

A Hearing Jumping Jack, versione dell'acceleratore TPU di Google Coral: 4 passaggi
A Hearing Jumping Jack, versione dell'acceleratore TPU di Google Coral: 4 passaggi

Video: A Hearing Jumping Jack, versione dell'acceleratore TPU di Google Coral: 4 passaggi

Video: A Hearing Jumping Jack, versione dell'acceleratore TPU di Google Coral: 4 passaggi
Video: George Hotz | Programming | tinygrad Google Edge TPU has a custom ISA?!? | reverse engineering part3 2024, Novembre
Anonim
A Hearing Jumping Jack, versione con acceleratore TPU di Google Coral
A Hearing Jumping Jack, versione con acceleratore TPU di Google Coral
A Hearing Jumping Jack, versione con acceleratore TPU di Google Coral
A Hearing Jumping Jack, versione con acceleratore TPU di Google Coral
A Hearing Jumping Jack, versione con acceleratore TPU di Google Coral
A Hearing Jumping Jack, versione con acceleratore TPU di Google Coral

Muove le sue membra, 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 LED come "occhi". È controllato da semplici comandi vocali che indicano quale delle nove posizioni predefinite deve assumere, o se il LED deve essere acceso o spento, o se deve eseguire una "danza" predefinita o un insieme casuale di mosse.

L'elemento centrale del sistema è l'acceleratore TPU Google Coral, che consente di eseguire modelli Tensorflow Lite offline con velocità molto elevate, anche su un computer "debole" come il Raspberry Pi. Ciò consente ad es. identificazione e classificazione rapida degli oggetti utilizzando la fotocamera RPi, ma anche per eseguire localmente funzioni di riconoscimento vocale basate sull'apprendimento automatico.

Per quanto ne so, questo è il primo esempio pubblicato per un dispositivo fisico fai-da-te basato sul rilevamento vocale Coral Accelerator e l'esempio di codice allegato potrebbe essere utilizzato anche per altri progetti più complessi.

Il controllo vocale si basa sull'esempio "il serpente dell'udito" nel "project keyword spotter" (https://github.com/google-coral/project-keyword-spotter) che di recente (settembre 2019) è stato inserito su GitHub. Nella mia configurazione, il sistema è composto da un Raspberry Pi 4 dotato di un servocofano Adafruit a 16 canali, un acceleratore TPU Google Coral e una webcam, qui utilizzata come microfono. Il Jumping Jack era stato descritto in precedenza in una precedente istruzione, in cui era guidato dal kit Google Voice per leggere i comandi vocali, è collegato al Servo Bonnet nella versione 2.0 descritta di seguito.

La precedente versione di Google Voice Kit aveva tre limitazioni principali: dipendeva dai servizi di riconoscimento vocale basati sul web di Google e la configurazione era relativamente complicata, era necessario premere un qualche tipo di pulsante prima di poter dare un comando e c'era un grave ritardo tra il dire il comando e la risposta del sistema. L'utilizzo dell'acceleratore Google Coral riduce i tempi di risposta a pochi secondi, è indipendente da una connessione Internet ed è sempre in ascolto. Con alcune modifiche potresti usarlo per controllare dispositivi molto più complessi come un Jumping Jack, come robot o automobili, o qualunque cosa tu possa costruire e controllare con un Raspberry Pi.

Nella sua versione attuale, Keyword Spotter comprende un insieme di circa 140 parole chiave/frasi chiave brevi, definite nel file del modello di accompagnamento ("voice_commands_v0.7_egetpu.tflite") e descritte in un file etichetta separato ("labels_gc2.raw.txt "). Definite da un file liberamente modificabile (“commands_v2_hampelmann.txt”), le parole chiave utilizzate in modo specifico dal nostro script vengono poi mappate alle sequenze di tasti su una tastiera virtuale, ad es. per lettere, numeri, su/giù/sinistra/destra, crtl+c, eccetera.

Quindi, ad es. usando pygame.key, queste "battute di tasti" vengono lette e utilizzate per controllare quali azioni deve eseguire un dispositivo, qui il jack di salto. Nel nostro caso questo significa portare i due servi in posizioni predefinite, oppure accendere o spegnere i LED. Poiché lo spotter di parole chiave viene eseguito in un battistrada separato, può ascoltare in modo permanente i tuoi ordini.

Versione 21 settembre 2019

Forniture

Raspberry Pi 4, via Pimoroni

Acceleratore TPU Google Coral, tramite Mouser Germania, 72€

Adafruit 16 Servo Bonnet, via Pimoroni, circa 10 €

www.adafruit.com/product/3416

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

Intestazione impilatore (se richiesto)

www.adafruit.com/product/2223

4x pacco batterie AA (o altra fonte di alimentazione 5-6V) per Servo Bonnet

Vecchia webcam, come microfono

Jumping Jack servocomandato, come descritto in una precedente istruzione. I disegni di layout sono allegati al passaggio successivo, ma potrebbero richiedere modifiche.

Parti necessarie per il Jumping Jack:

- Piastra Forex 3 mm

- 2 micro servi

- Viti e dadi da 2 e 3 mm

- 2 LED bianchi e un resistore

- un po' di cavo

Passaggio 1: configurazione del dispositivo

Configurazione del dispositivo
Configurazione del dispositivo
Configurazione del dispositivo
Configurazione del dispositivo
Configurazione del dispositivo
Configurazione del dispositivo

Per costruire il Jumping Jack, segui le indicazioni fornite in una precedente istruzione. Ho usato Forex per il mio prototipo, ma potresti usare lastre acriliche o compensato tagliate al laser. Potrebbe essere necessario regolare il layout in base alle dimensioni dei servi, ecc. Verificare se gli arti e l'ingranaggio possono muoversi senza attrito.

Configura il tuo Raspberry Pi. Sul sito Coral Github, è disponibile un'immagine Raspian che contiene tutto il necessario per eseguire l'acceleratore Coral sul Pi e contiene molti progetti, con tutte le impostazioni già in atto.

Ottieni lo spotter per le parole chiave del progetto dalla pagina di Google Coral GitHub. Installare tutto il software richiesto come indicato.

Installa i file forniti. Posiziona lo script python jumping jack nella cartella spotter delle parole chiave del progetto e il file dei comandi corrispondenti nella sottocartella config.

Attacca l'Adafruit Servo Bonnet al Pi. Poiché sto utilizzando un alloggiamento RPI con una ventola, avevo bisogno di utilizzare gli stacker GPIO (ad esempio disponibili da Pimoroni) per abilitare la connessione. Installare tutte le librerie richieste, come indicato nelle istruzioni di Adafruit per il cofano del servo.

Collegare una fonte di alimentazione 5-6V al cofano del servo. Collegare servi e LED. Nel mio caso, ho usato la porta 0 per i LED e le porte 11 e 15 per i servi.

Per controllare tutto, consiglierei di provare prima l'esempio della parola chiave del progetto spotter "ascoltare il serpente" e gli esempi del cofano servo Adafruit.

Passaggio 2: esecuzione del Jumping Jack

Se tutte le parti sono impostate e funzionanti, prova ad usarlo. Puoi eseguire lo script nell'IDE o dalla riga di comando.

Gridare "posizione 0" a "posizione 9" evocherà il Jumping Jack per assumere una delle posizioni predefinite. Ho definito "1" come entrambe le braccia in alto (uu), "3" come sinistra in alto, destra in basso (ud), "9" come entrambe le braccia in basso (dd) e "5" come entrambe le braccia centrate (cc).

uu uc ud = 1 2 3

cu cc cd = 4 5 6

du dc dd = 7 8 9

"0" è identico a "5". "3" e "8" non vengono riconosciuti molto bene dallo spotter di parole chiave e potrebbe essere necessario ripeterli.

Potrebbe essere necessario regolare i valori minimo e massimo per ciascun servo/lato in modo che i servi non vengano bloccati e quindi assorbano troppa potenza.

"prossima partita" avvierà la "danza", ovvero una sequenza definita di posizioni, mentre "gioco casuale" avvierà il Jumping Jack per eseguire una sequenza casuale di mosse. In entrambi i casi funzioneranno per sempre, quindi potrebbe essere necessario interrompere i movimenti, ad es. con un comando "posizione zero".

"stop game" evocherà un "ctrl + c" e interromperà il processo.

"Accensione" e "Spegnimento" possono essere utilizzati per accendere e spegnere i LED.

Modificando i valori di time.sleep è possibile regolare la velocità dei movimenti.

Passaggio 3: il file del codice e dei comandi

Il codice presentato qui è una modifica del codice "hearing snake" che fa parte del pacchetto spotter delle parole chiave del progetto. Ho appena rimosso tutto ciò che non era necessario per la mia domanda, senza una reale comprensione dei dettagli. Eventuali miglioramenti sono i benvenuti.

Ho quindi aggiunto le parti necessarie per Adafruit Servo Bonnet, in base ai loro file di esempio.

Vorrei ringraziare i programmatori di entrambe le parti.

Il codice può essere trovato allegato come file. Usalo a tuo rischio, modificalo, miglioralo, giocaci.

# 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 # # https://www.apache.org/licenses/LICENSE-2.0 # # A meno che non sia richiesto dalla legge applicabile o concordato per iscritto, il software # distribuito con la Licenza è distribuito su un BASE "COS COM'È", # SENZA GARANZIE O CONDIZIONI DI ALCUN TIPO, esplicite o implicite. # Vedere la Licenza per le autorizzazioni e le # limitazioni che regolano la lingua specifica sotto la Licenza. from _future_ import absolute_import from _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 random import randrange from 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) # set number di canali #kit.servo[0].actuation_range = 160 #kit.servo[0].set_pulse_width_range(1000, 2000) # impostazioni up, mid e down per i bracci sinistro e destro up_l = 35 md_l = 90 dn_l = 160 up_r = 160 md_r = 90 dn_r = 35

lft= 15 # numero di porta servo, servo sinistro (0-8)

rgt= 11 # numero della porta servo, servo destro (0-8) led_channel_0 = hat.channels[0] # LED impostato sulla porta 0 led_channel_0.duty_cycle = 0 #accendi LED 100% #elenco delle impostazioni del braccio per la posizione a nove posizioni = [(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)] # definisce 9 posizioni di JumpingJack, indicate da numeri interi 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 "dance" 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 JumpingJack0(self, keys): # controlla Jumping Jack, parole chiave: "position x" key = int(keys) p = position [tasto] a = p[0] b = p[1] print ("Posizione: ", tasto, " sinistra /destra: ", a, "/", b, "grado") # sys.stdout.write("Posizione: ", chiave, " sinistra/destra: ", a, "/", b, "grado") kit.servo[lft].angle = a kit.servo[rgt].angle = b time.sleep(0.1) def JumpingJack1(self): # controlla la danza di Jumping Jack, parola chiave: "prossima partita" dnce = dance1 sp=(len(dnce)) for r in range (sp): #ordine danzante delle posizioni, sp step dc = dnce[r] if (dc not in range(10)): # print ("errore di input in posizione ", sp) dc=4 p = posizione[dc] a = p[0] b = p[1] kit.servo[lft].angle = a kit.servo[rgt].angle = b time.sleep(0.25) # imposta la velocità di movimenti def JumpingJack2(self, keys): # controlla i LED Jumping Jack, parole chiave: "switch on/off" led = int(keys) if led == 1: led_channel_0.duty_cycle = 0xffff #accendi LED 100% time.sleep (0.1) se led == 0: led_channel_0.duty_cycle = 0 # spegni LED time.sleep (0.1) se led == 2: # lampeggia led_channel_0.duty_cycle = 0xffff #accendi LED 100% time.sleep (0.5) led_channel_0.duty_cycle = 0 #accendi LED 100% time.sleep (0.5) led_channel_0.duty_cycle = 0xffff #accendi LED 100% time.sleep (0.5) led_channel_0.duty_cycle = 0 #accendi LED 100% time.sleep (0.5) led_channel_0.duty_cycle = 0xffff #accendi LED 100% time.sleep (0.1) def JumpingJack3(self): # controlla la danza del Jumping Jack, parola chiave: "random game" # for h nell'intervallo (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) # imposta la velocità dei movimenti def spotter(self, args): engine = BasicEngine(args.model_file) mic = args.mic if args.mic è Nessun altro int(args.mic) model.classify_audio(mic, engine, label_file="config/labels_gc2.raw.txt", command_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):

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 (Vero, 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]) o 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]) o item == " up": self. JumpingJack0(1) if (args.debug_keyboard and keys[pygame. K_DOWN]) o item == "down": self. JumpingJack0(9) if (args.debug_keyboard and keys[pygam e. K_0]) o item == "0": self. JumpingJack0(0) if (args.debug_keyboard and keys[pygame. K_1]) o item == "1": self. JumpingJack0(1) if (args. debug_keyboard and keys[pygame. K_2]) o item == "2": self. JumpingJack0(2) if (args.debug_keyboard and keys[pygame. K_3]) o 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]) o item == "9": self. JumpingJack0(9) if (args.debug_keyboard and keys[pygame. K_a]) o item == "d": self. JumpingJack1() #dancing Jack, su "next_game" if (args. debug_keyboard and keys[pygame. K_j]) o item == "j": self. JumpingJack2(0) #LED acceso, ON " switch_on" if (args.debug_keyboard and keys[pygame. K_k]) o item == "k": self. JumpingJack2(1) #LED spento, acceso "swithch off" if (args.debug_keyboard and keys[pygame. K_l]) o item == "l": self. JumpingJack2(1) #LED lampeggia "target" if (args.debug_keyboard and keys[pygame. K_r]) o item == "r": self. JumpingJack3() #random dance "gioco casuale" time.sleep(0.05) self.on_cleanup() if _name_ == '_main_': parser = argparse. ArgumentParser() parser.add_argument('--debug_keyboard', help='Usa la tastiera per controllare il JumpingJack.', action='store_true', default=False) model.add_model_flags(parser) args = parser.parse_args() the_app = App() the_app.on_execute(args)

C'è anche il file di configurazione dei comandi "commands_v2_hampelmann.txt". Modifica come preferisci. È solo un elenco di combinazioni di "comando, chiave, (forza,)", basato sul file etichetta.

posizione_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, giù, move_backwards, sinistra, move_forwards, destra, go_backwards, sinistra, go_forwards, destra, 0.8 target, l, mute, z, sì, y, no, n, switch_on, j, switch_off, k, volume_up, su, volume_down, giù, next_game, d, random_game, r, start_game, s, stop_game, ctrl+c,

Passaggio 4: ulteriori idee e altri esempi

È abbastanza ovvio che questa impostazione può essere utilizzata anche per controllare robot o altri dispositivi. Fondamentalmente tutto ciò che potrebbe essere controllato da un Raspberry Pi.

Sto lavorando a un'estensione della sceneggiatura per guidare un MeArm e spero di poterlo presentare nell'ottobre 2019.

Sto anche valutando di utilizzare il Jumping Jack come semaforo, e di utilizzare il programma di riconoscimento della posizione degli arti "progetto posenet" come strumento per leggere le posizioni del Jumping Jack e tradurlo in un numero. In questo modo può anche comunicare del testo, date 2x 8 posizioni possono indicare 64 numeri diversi, più che sufficienti per alfabeto, numeri e segni. Ciò potrebbe consentire, sebbene leggermente modificato, una realizzazione fisica per la proposta IETF "The Transmission of IP Datagrams over the Semaphore Flag Signaling System (SFSS)" (https://tools.ietf.org/html/rfc4824).

Ma questo sarà un altro istruibile. E, poiché i primi esperimenti hanno indicato che il jump jack avrà bisogno di modifiche significative prima che venga riconosciuto come umano dal sistema di intelligenza artificiale, potrebbe richiedere del tempo.

Vorrei attirare la vostra attenzione sulla seguente istruzione: Object-Finding-Personal-Assistant-Robot-Ft-Raspberry, in cui viene descritto un robot per la ricerca di oggetti che utilizza una combinazione di Raspberry Pi e Google Coral TPU.

Consigliato: