Spisu treści:

Aparat słuchowy oparty na akceleratorze Google Coral TPU: 3 kroki
Aparat słuchowy oparty na akceleratorze Google Coral TPU: 3 kroki

Wideo: Aparat słuchowy oparty na akceleratorze Google Coral TPU: 3 kroki

Wideo: Aparat słuchowy oparty na akceleratorze Google Coral TPU: 3 kroki
Wideo: Beltone Amaze- Aparat słuchowy stworzony w oparciu o najnowszą i szybką technologię. 2024, Lipiec
Anonim
Hearing MeArm, napędzany akceleratorem Google Coral TPU
Hearing MeArm, napędzany akceleratorem Google Coral TPU
Hearing MeArm, napędzany akceleratorem Google Coral TPU
Hearing MeArm, napędzany akceleratorem Google Coral TPU
Hearing MeArm, napędzany akceleratorem Google Coral TPU
Hearing MeArm, napędzany akceleratorem Google Coral TPU
Hearing MeArm, napędzany akceleratorem Google Coral TPU
Hearing MeArm, napędzany akceleratorem Google Coral TPU

Poniżej chciałbym opisać sterowaną głosem wersję MeArm, małego ramienia robota xyz z chwytakiem. Użyłem MeArm Pi z branży MIME, ale system powinien mieć zastosowanie do dowolnej wersji MeArm lub podobnych urządzeń z serwonapędem.

Korzystanie z Google Coral TPU Accelerator umożliwia uruchamianie szybkich skryptów rozpoznawania głosu TensorFlow offline na Raspberry Pi, a tym samym sterowanie urządzeniami fizycznymi za pomocą poleceń głosowych, z opóźnieniem poniżej jednej sekundy.

Opisane tutaj urządzenie jest kombinacją i rozszerzeniem koncepcji opisanych w dwóch poprzednich instrukcjach. Jest to rozszerzenie wcześniejszej implementacji sterowania głosowego Google Coral, opisanego tu Jumping Jack oraz znaczne ulepszenie opisanego tutaj MeArm sterowanego głosem Google AIY.

Sterowany głosem MeArm wykorzystujący system Google Voice AIY wymagał dostępu online, nie był łatwy do wdrożenia, wymagał naciśnięcia przycisku, aby aktywować nasłuchiwanie poleceń głosowych i miał długi czas oczekiwania. Zastosowany akcelerator Google Coral TPU Accelerator umożliwia teraz uruchamianie modeli TensorFlowLite w trybie offline z dużą prędkością na Raspberry Pi lub innych urządzeniach z systemem Linux. Wśród przykładów na stronie Google Coral Github jest przykład zwany „wężem słuchowym” dla systemu rozpoznawania głosu, który potrafi zrozumieć 140 fraz kluczowych (wrzesień 2019), które są następnie mapowane na wirtualne naciśnięcia klawiszy. Połączenie tych „naciśnięć klawiszy” z wykonywaniem niektórych funkcji zaprogramowanych w Pythonie umożliwia zbudowanie urządzenia sterowanego głosowo. Niedawno opisałem pierwszą implementację, elektromechaniczny podnośnik sterowany głosem. Ta implementacja jest nieco bardziej złożona i umożliwia sterowanie wszystkimi czterema serwomechanizmami MeArm, aby albo poruszać MeArm w sposób ciągły, albo przesuwać je do określonej liczby predefiniowanych stanowiskach lub do wykonywania bardziej złożonych zadań.

Korzystając z podanego tutaj przykładu skryptu, konstruowanie innych urządzeń sterowanych głosem powinno być stosunkowo proste, np. zrobotyzowane samochody lub pomocnicze jednostki technologiczne.

Kieszonkowe dzieci

  • MeArm. Użyte tutaj: MeArm Pi od MIME Industries
  • Raspberry Pi 4
  • Akcelerator Google Coral TPU
  • 16-kanałowa maska serwomechanizmu Adafruit
  • niektóre kable rozruchowe
  • opcjonalnie: kondensator do maski serwa, ok. 400 µF na 4 serwa (rekomendowany przez Adafruit)
  • Źródło zasilania 5-6 V dla serwomechanizmu. Użyłem tutaj starej ładowarki 6V, działa też pakiet baterii 4x AA
  • Mikrofon. Jako mikrofonu użyłem starej kamery internetowej Microsoft HD3000.

Krok 1: Konfiguracja systemu

Konfiguracja systemu
Konfiguracja systemu
Konfiguracja systemu
Konfiguracja systemu

Pobierz wstępnie skonfigurowany obraz Raspian dla Google Coral TPU Accelerator ze strony Google Coral Github i zainstaluj go na karcie µSD. Obraz zawiera również szereg przykładowych skryptów. Ustaw Pi jak wskazano.

Zainstaluj przykładowy spotter słów kluczowych ze strony Google Coral GitHub, jeśli nie jest zawarty w obrazie, oraz wszystkie wymagane programy. Podłącz mikrofon do Pi. Polecam pobawić się przykładem „Węża słuchowego”, aby upewnić się, że wszystko działa.

Pobierz i zainstaluj oprogramowanie 16-kanałowej maski Adafruit, jak opisano tutaj. Zainstaluj maskę i baw się przykładami Adafruit, aby upewnić się, że wszystko działa poprawnie.

Pobierz pliki dołączone do tej instrukcji i skopiuj je do folderu „Project Keyword Spotter”. Plik „commands_v1_MeArm.txt” należy skopiować do podfolderu „config”.

Podłącz serwa MeArm do maski serwomechanizmu, jak pokazano. Użyłem portu 15 do góra/dół, portu 11 do przodu/do tyłu, portu 7 do skrętu i portu 3 do serw chwytaków.

W skrypcie może być konieczne dostosowanie wartości min/centrum/maks dla każdego serwa do swojej konfiguracji. Te ustawienia pomagają uniknąć uszkodzenia serwomechanizmów. Może być również konieczna modyfikacja dołączonych list „pozycje”, „transport1” i „transport2”.

Uruchom skrypt. Do tej pory uruchamiałem go z IDE.

W przypadku, gdy chcesz zmodyfikować frazy kluczowe, które wywołują określoną funkcję, zgodnie ze swoimi potrzebami. Pełną listę dostępnych KeyFraz znajdziesz w pliku „labels_gc2 raw.txt” w podfolderze config.

System ma czas oczekiwania około 1 sekundy, ale w zależności od tego, jakie działania są wykonywane. W niektórych przypadkach kluczowa faza musi zostać powtórzona, dokładność rozpoznawania nie zawsze wynosi 100%.

Krok 2: Korzystanie z urządzenia

Jeśli wszystko jest skonfigurowane i sprawdzone, możesz uruchomić urządzenie.

Aktualnym ograniczeniem jest to, że dane zlecenie jest wykonywane powtarzalnie, dopóki nie zostanie zatrzymane (za pomocą „zatrzymaj grę”) lub zostanie wydane inne zlecenie. Złożone, wieloetapowe zadania, m.in. „transport1” (wywoływany frazą „uruchom grę”) są zawsze wykonywane do ostatniego kroku.

Tak więc przez "skręt w prawo" urządzenie będzie się poruszać małymi krokami w prawo, aż do zatrzymania lub osiągnięcia ustawionej wartości maksymalnej. "uruchom grę", "następna gra" lub "start_video" rozpocznie serię ruchów, które są zdefiniowane przez listy zawierające ustawienia dla każdego serwa na danym kroku. "losowa gra" sprawi, że urządzenie będzie przeskakiwać z jednego do drugiego kroku, wybieranego losowo z listy ustawień.

Jak widać na załączonym filmie, zbudowałem z LEGO obiekt w kształcie diabolo, który może zostać podniesiony przez MeArm i przeniesiony z jednego miejsca do drugiego za pomocą predefiniowanego zestawu ruchów. Możesz zdefiniować własne funkcje poprzez modyfikację list 'transport1' lub 'transport2'.

Krok 3: Skrypt

Wymieniony tutaj skrypt jest modyfikacją przykładu „Węża słuchowego” z „Project Keyword Spotter”. Przykład został okrojony do minimum, następnie dodano część do napędzania serw na podstawie oprogramowania i przykładów dostarczonych dla maski serwomechanizmu Adafruit.

Skrypt nie został do tej pory zoptymalizowany. Używaj na własne ryzyko, możesz modyfikować i optymalizować.

Oprócz skryptu Pythona istnieje plik poleceń i używany plik etykiet. Umieść go w podfolderze config-subfolder.

Jak wspomniano wcześniej, w celu dostosowania skryptu do specjalnego urządzenia MeArm lub innego urządzenia może być konieczne dokonanie kilku korekt parametrów.

# Prawa autorskie 2019 Google LLC#

# Licencjonowane na podstawie licencji Apache w wersji 2.0 („Licencja”); # nie możesz używać tego pliku, chyba że zgodnie z Licencją. # Kopię Licencji można uzyskać pod adresem # # 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 # # O ile nie jest to wymagane przez obowiązujące prawo lub nie zostało to uzgodnione na piśmie, oprogramowanie # rozpowszechniane w ramach Licencji jest rozpowszechniane na PODSTAWIE „TAK JAK JEST”, # BEZ GWARANCJI LUB WARUNKÓW JAKIEGOKOLWIEK RODZAJU, wyraźnego lub dorozumianego. # Zapoznaj się z Licencją, aby zapoznać się z określonymi uprawnieniami dotyczącymi języka i # ograniczeniami w ramach Licencji. # oryginalny kod "hearing_snake" został zmodyfikowany do implementacji MeArm przez dr H. ''' Instrukcje Moja implementacja używa Raspbery Pi 4 z akceleratorem Google Coral i dołączoną 16-kanałową maską serwomechanizmu Adafruit. Serwa MeArm (przemysł MIME) zostały przymocowane do portów 3, 7, 11 i 15 maski. Aby uzyskać szczegółowe informacje, zapoznaj się z instrukcją „Hearing MeArm”. Komendy: "pozycja x", x= 0 do 9, przesuwa urządzenie do zadanej predefiniowanej pozycji. „przesuń/idź w górę”, „przesuń/idź w dół”, „idź/skręć do przodu”, „idź/skręć w tył”, „skręć/idź w lewo” i „skręć/idź w prawo” wywołują powolny, krokowy ruch w danym kierunek, „zatrzymaj grę” zatrzymuje ruchy. "otwórz zakładkę" i "zamknij zakładkę" otwiera lub zamyka chwytak. „start wideo” powoduje, że urządzenie podąża zgodnie z ustaloną kolejnością pozycji, określoną przez listę „pozycje”. „losowa gra” powoduje losowy wzorzec ruchów, „zatrzymanie gry” ją kończy. "uruchom grę" rozpoczyna kolejną serię ruchów predefiniowaną przez listę 'transport1', "następną grę" odwrotną operację predefiniowaną przez 'transport2' Używaj na własne ryzyko. ''' z _future_ import absolute_import z _future_ import dzielenie z _future_ import print_function import argparse import os z losowego import randint z wątków import import wątku czas importu z edgetpu.basic.basic_engine import BasicEngine import modelu import pygame z pygame.locals import * import kolejki z losowy import randrange z adafruit_servokit import ServoKit import tablicy import busio import adafruit_pca9685 czas importu i2c = busio. I2C(board. SCL, board. SDA) hat = adafruit_pca9685. PCA9685(i2c) hat.frequency = 60 kit = ServoKit(kanały=16) # ustawienie liczby kanałów #kit.servo[0].actuation_range = 160 #kit.servo[0].set_pulse_width_range(1000, 2000) # ustawienia min, center i max up_l = 145 # serwa góra/dół: góra md_l = 95 dn_l = 45 up_r = 135 # serwo przód/tył md_r = 90 dn_r = 50 ri_t = 30 # ramię obrotowe prawe lub lewe: pozycja prawa md_t = 90 # ramię obrotowe prawe lub lewe: pozycja środkowa le_t = 150 op_g = 65 # chwytak otwarty md_g = 90 # chwytak wyśrodkowany cl _g = 130 # chwytak zamknięty vert = 15 # numer portu serwa, góra/dół do przodu = 11 # numer portu serwa, ruch serwa do przodu/do tyłu = 7 # port serwa do obracania manetki = 3 # port serwa do manetki serwo #lista ustawień ramienia dla dziewięciu pozycji pozycja = [(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, md_t, m), (dn_l, dn_r, le_t, md_g)] # definiuje 10 pozycji bazowych, wskazanych przez liczby całkowite 0-9 # procedury transportu [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), #pobierz obiekt (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)]

taniec1 =(0, 8, 7, 4, 1, 2, 3, 6, 9, 8, 5, 2, 1, 4, 7, 8, 9, 6, 3, 2, 0) # "taniec"

#przenoszenie MeArm do pozycji zerowej 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 Kontroler(obiekt): #Funkcja wywołania zwrotnego def _init_(self, q): self._q = q def callback(self, polecenie): self._q.put(polecenie) class Aplikacja: 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): # ustawia MeArm na zaprogramowane pozycje, słowa kluczowe: "position x" key = int(keys) p = pozycja[klawisz] a = p[0] b = p[1] c = p[2] d = p[3] drukuj ("Pozycje: ", klawisz, " pion/przód/obrót/chwyt: ", a, "/", b, "/", c, "/", d, "stopnie") status = [a, b, c, d] # aktualny status dokumentów print (status) # sys.stdout.write("Pozycja: ", klawisz, " lewo/prawo: ", a, "/", b, "stopień") kit.servo[vert].angle = kit.servo[forw].angle = b kit.servo[turn].angle = c kit.servo[grip].angle = d time.sleep(0.5) def DancingMeArm(self): # kontroluje taniec MeArm, słowo kluczowe: "start_video" dnce = dance1 sp=(len(dnce)) dla r w zakresie (sp): #kolejność taneczna pozycji, sp kroki dc = dnce[r] p = pozycja[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 czas.sen (1) # ustawia prędkość ruchów time.sleep(0.5) # przerwa na końcu procedury def TransMeArm1(self): # steruje transportem MeArm 1, słowo kluczowe: "uruchom grę" tr1 = transport1 sp=(len(tr1)) #oblicz liczbę kroków dla r w zakresie (sp): #przejdź do dowolnego kroku 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) # zestawy prędkość ruchów time.sleep(0.5) def TransMeArm2(self): # kontroluje taniec MeArm, słowo kluczowe: "następna gra" tr2 = transport2 sp=(len(tr2)) for r w zakresie (sp): #kolejność pozycji, sp kroki 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) # ustawia prędkość ruchów time.sleep(0.5) def RandomMoves(self): # przeskakuje losowo między predefiniowanymi pozycjami, słowo kluczowe: "losowa gra" dr= randrange (9) #losowo wybiera pozycję p = position[dr] # odczytuje parametry pozycji 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) # ustawia prędkość ruchów def MoveUp(self): # podnoszenie chwytaka małymi krokami u0 = status[0] # odczyt bieżącego stanu u1 = u0 + 5 # plus x stopni if (u1 > up_l): # sprawdza, czy nie przekracza parametrów min/max u1 = up_l # w przeciwnym razie ustaw wartość min/max kit.servo[vert].angle = u1 # przesuń status serwa[0] = u1 # dostosuj wartość statusu drukuj (" up ", status) time.sleep (1) # ustawia prędkość def MoveDown(self): d 0 = status[0] d1 = d0 - 5 #minus x stopnie jeśli (d1 góra_r): f1 = góra_r kit.servo[forw].angle = f1 # ruch serwa status[1] = f1 print ("do przodu", status) time.sleep (1) def MoveBack(self): b0 = status[1] b1 = b0 - 5 #minus x stopnie if (b1 le_t): l1 = le_t kit.servo[turn].angle = l1 # move servo status[2] = l1 print ("lewo", status) time.sleep (0.2) def MoveRight(self): r0 = status[2] r1 = r0 - 2 #minus x stopnie if (r1 < ri_t): r1 = ri_t kit.servo[turn].angle = r1 # ruch serwa status[2] = r1 print ("prawo", status) time.sleep (0.2) def OpenGrip(self): kit.servo[grip].angle = op_g # ustaw uchwyt w pozycji „otwarty”: „open_tab” time.sleep(0.5) status[3] = op_g def CloseGrip(self): kit.servo[grip].angle = cl_g # ustaw uchwyt w pozycji „zamknięty”: " close_tab" time.sleep(0.5) status[3] = cl_g def StopMove(self): # nic nie robi, ale zatrzymuje ruchy print ("stop", status) time.sleep(0.25) def spotter(self, args): engine = BasicEngine(args.model_file) mic = args.mic jeśli args.mic to None else int(args.mic) model.classify_audio(mikrofon, silnik, label_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_hz), num_frames_hzhop int(args.num_frames_hop)) def on_execute(self, args): jeśli nie self.on_init(): self._running = False q = model.get_queue() self._controler = Controler(q) jeśli nie 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) z wyjątkiem kolejki. Empty: new_item = None jeśli new_item nie jest None: item = new_item if (args.debug_keyboard and keys[pygame. K_ESCAPE]) lub item == "stop": self._running = False # if (args.debug_keyboard and keys[pygame. K_SPACE]) lub item == "go": # self. MeArmPos(7) # if (args.debug_keyboard and keys [pygame. K_RIGHT]) lub item == "right": # skręć w prawo self. MoveRight() if (args.debug_ke yboard i keys[pygame. K_LEFT]) lub 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": # wstecz self. MoveBack() if (args.debug_keyboard and keys[pygame. K_F]) or item == "f": # przekazuje 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]) lub item == "c": # close grip: self. CloseGrip() if (args.debug_keyboard and keys [pygame. K_S]) lub item == "s": # zatrzymaj ruch: "start_game" self. StopMove() if (args.debug_keyboard and keys[pygame. K_0]) lub item == "0": self. MeArmPos (0) if (args.debug_keyboard and keys[pygame. K_1]) lub 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]) lub to em == "3": self. MeArmPos(3) if (args.debug_keyboard and keys[pygame. K_4]) lub item == "4": self. MeArmPos(4) if (args.debug_keyboard and keys[pygame. K_5]) lub item == "5": self. MeArmPos(5) if (args.debug_keyboard and keys[pygame. K_6]) lub item == "6": self. MeArmPos(6) if (args.debug_keyboard and keys[pygame. K_7]) lub item == "7": self. MeArmPos(7) if (args.debug_keyboard i keys[pygame. K_8]) lub item == "8": self. MeArmPos(8) if (args.debug_keyboard and keys[pygame. K_9]) lub item == "9": self. MeArmPos(9) if (args.debug_keyboard and keys[pygame. K_a]) or item == "d": self. DancingMeArm() #dancing MeArm, w "next_game" if (args.debug_keyboard and keys[pygame. K_r]) lub item == "r": self. RandomMoves() #random dance "losowa gra" if (args.debug_keyboard and keys[pygame. K_j]) lub item == "j": self. TransMeArm1() # transport object: "lunch_game" if (args.debug_keyboard and keys[pygame. K_k]) or item == "k": self. TransMeArm2() # odwrotny kierunek transportu obiektu: "next_game" ''' if (args.debug_keyboard i keys[pygame. K_l]) lub item == "l": self. JumpingJack2(1) #LED miga "target" ''' time.sleep(0.05) self.on_cleanup() if _name_ == '_main_': parser = argparse. ArgumentParser() parser.add_argument('--debug_keyboard', help='Użyj klawiatury do sterowania MeArm.', action='store_true', default=False) model.add_model_flags(parser) args = parser.parse_args () the_app = App() the_app.on_execute(args)

Zalecana: