Inhaltsverzeichnis:

Ein Hearing MeArm, Google Coral TPU Accelerator-gesteuert - Gunook
Ein Hearing MeArm, Google Coral TPU Accelerator-gesteuert - Gunook

Video: Ein Hearing MeArm, Google Coral TPU Accelerator-gesteuert - Gunook

Video: Ein Hearing MeArm, Google Coral TPU Accelerator-gesteuert - Gunook
Video: Complete guide to PCA9685 16 channel Servo controller for Arduino with code Version of 5 ( V1) 2024, Juli
Anonim
A Hearing MeArm, Google Coral TPU Accelerator Driven
A Hearing MeArm, Google Coral TPU Accelerator Driven
A Hearing MeArm, Google Coral TPU Accelerator Driven
A Hearing MeArm, Google Coral TPU Accelerator Driven
A Hearing MeArm, Google Coral TPU Accelerator Driven
A Hearing MeArm, Google Coral TPU Accelerator Driven
A Hearing MeArm, Google Coral TPU Accelerator Driven
A Hearing MeArm, Google Coral TPU Accelerator Driven

Im Folgenden möchte ich eine sprachgesteuerte Version des MeArm beschreiben, einem kleinen xyz-Roboterarm mit Greifer. Ich habe den MeArm Pi von MIME-Industrien verwendet, aber das System sollte auf jede Version des MeArm oder ähnliche servogesteuerte Geräte anwendbar sein.

Die Verwendung des Google Coral TPU Accelerator ermöglicht es, schnelle Offline-TensorFlow-Spracherkennungsskripte auf dem Raspberry Pi auszuführen und hiermit physische Geräte durch gesprochene Befehle mit einer Latenzzeit von unter einer Sekunde zu steuern.

Die hierin beschriebene Vorrichtung ist eine Kombination und Erweiterung von Konzepten, die in zwei vorherigen Anleitungen beschrieben wurden. Es ist eine Erweiterung einer früheren Implementierung der hier beschriebenen Google Coral-Sprachsteuerung, eines Jumping Jack, und eine enorme Verbesserung eines hier beschriebenen sprachgesteuerten MeArms von Google AIY.

Der sprachgesteuerte MeArm mit dem Google Voice AIY-System erforderte einen Online-Zugang, war nicht einfach zu implementieren, musste per Knopfdruck das Hören auf Sprachbefehle aktivieren und hatte eine lange Latenzzeit. Der verwendete Google Coral TPU Accelerator ermöglicht es nun, TensorFlowLite-Modelle offline mit hoher Geschwindigkeit auf einem Raspberry Pi oder anderen Linux-Geräten auszuführen. Unter den Beispielen auf der Google Coral Github-Seite gibt es ein Beispiel namens "Hearing Snake" für ein Spracherkennungssystem, das 140 Schlüsselsätze verstehen kann (Sept. 2019), die dann auf virtuelle Tastenanschläge abgebildet werden. Die Kopplung dieser "Tastendrücke" mit der Ausführung einiger in Python programmierter Funktionen ermöglicht es, ein durch Sprachbefehle gesteuertes Gerät zu bauen. Ich hatte vor kurzem eine erste Implementierung beschrieben, einen sprachgesteuerten elektromechanischen Jumping Jack. Die Implementierung hier ist etwas komplexer und ermöglicht es, alle vier Servos des MeArm zu steuern, um den MeArm entweder kontinuierlich zu bewegen oder ihn auf eine Reihe von vordefinierten bewegen zu lassen Positionen oder komplexere Aufgaben zu erfüllen.

Am Beispiel des hier bereitgestellten Skripts soll es relativ einfach sein, andere sprachgesteuerte Geräte zu konstruieren, z. B. Roboterautos oder assistierende Tech-Einheiten.

Lieferungen

  • MeArm. Hier verwendet: MeArm Pi von MIME Industries
  • Raspberry Pi 4
  • Google Coral TPU-Beschleuniger
  • Adafruit 16-Kanal-Servohaube
  • einige Überbrückungskabel
  • optional: Kondensator für Servohaube, ca. 400 µF für 4 Servos (empfohlen von Adafruit)
  • 5-6 V Stromquelle für Servohaube. Ich habe hier ein altes 6V-Ladegerät verwendet, ein 4x AA-Akku funktioniert auch
  • Mikrofon. Als Mikrofon habe ich eine alte Microsoft HD3000 Webcam verwendet.

Schritt 1: Einrichten des Systems

Einrichten des Systems
Einrichten des Systems
Einrichten des Systems
Einrichten des Systems

Laden Sie das vorkonfigurierte Raspian-Image für den Google Coral TPU Accelerator von der Google Coral Github-Seite herunter und installieren Sie es auf einer µSD-Karte. Das Bild enthält auch eine Reihe von Beispielskripten. Richten Sie den Pi wie angegeben ein.

Installieren Sie den Beispiel-Keyword-Spotter von der Google Coral GitHub-Site, falls nicht im Bild enthalten, und alle erforderlichen Programme. Befestigen Sie das Mikrofon am Pi. Ich würde empfehlen, mit dem Beispiel "Hearing Snake" zu spielen, um sicherzustellen, dass alles funktioniert.

Laden Sie die Adafruit 16-Kanal-Motorhaubensoftware herunter und installieren Sie sie, wie hier beschrieben. Installieren Sie die Motorhaube und spielen Sie mit den Adafruit-Beispielen, um sicherzustellen, dass alles richtig funktioniert.

Laden Sie die an diese Anleitung angehängten Dateien herunter und kopieren Sie sie in den Ordner "Project Keyword Spotter". Die Datei „commands_v1_MeArm.txt“muss in den Unterordner „config“kopiert werden.

Verbinden Sie die Servos Ihres MeArms wie angegeben mit der Servohaube. Ich habe Port 15 für Up/Down, Port 11 für Vorwärts/Rückwärts, Port 7 für Turn und Port 3 für die Greiferservos verwendet.

Innerhalb des Skripts müssen Sie möglicherweise die Min/Center/Max-Werte für jedes Servo an Ihre Konfiguration anpassen. Diese Einstellungen helfen, Schäden an den Servos zu vermeiden. Eventuell müssen Sie auch die enthaltenen Listen "Positionen", "Transport1" und "Transport2" ändern.

Führen Sie das Skript aus. Bisher hatte ich es von der IDE ausgeführt.

Falls Sie die Schlüsselphrasen, die eine bestimmte Funktion hervorrufen, nach Ihren Bedürfnissen ändern möchten. Eine vollständige Liste der verfügbaren Schlüsselphrasen finden Sie in der Datei "labels_gc2 raw.txt" im Unterordner config.

Das System hat eine Latenzzeit von etwa 1 Sekunde, hängt jedoch stark davon ab, welche Aktionen ausgeführt werden. In manchen Fällen muss die Schlüsselphase wiederholt werden, die Erkennungsgenauigkeit beträgt nicht immer 100 %.

Schritt 2: Verwenden des Geräts

Wenn alles eingerichtet und überprüft ist, können Sie das Gerät ausführen.

Eine aktuelle Einschränkung besteht darin, dass eine gegebene Order wiederholt ausgeführt wird, solange sie nicht gestoppt wird (mittels "Spiel stoppen") oder eine andere Order gegeben wird. Komplexe Mehrschrittaufgaben, z. B. "transport1" (hervorgerufen durch die Phrase "Spiel starten") werden immer bis zum letzten Schritt ausgeführt.

Durch „rechts abbiegen“fährt das Gerät also in kleinen Schritten nach rechts, bis es anhält oder der voreingestellte Maximalwert erreicht ist. "launch game", "next game" oder "start_video" startet eine Reihe von Zügen, die durch Listen definiert sind, die die Einstellung für jeden Servo bei einem bestimmten Schritt enthalten. "Random Game" wird das Gerät von einem zum anderen Schritt springen, der zufällig aus einer Liste von Einstellungen ausgewählt wird.

Wie Sie im begleitenden Video sehen können, habe ich ein diaboloförmiges Objekt aus LEGO bauen lassen, das vom MeArm aufgenommen und durch vordefinierte Bewegungen von einem Ort zum anderen transportiert werden kann. Durch Modifikation der Listen 'transport1' oder 'transport2' können Sie eigene Funktionen definieren.

Schritt 3: Das Skript

Das hier aufgeführte Skript ist eine Modifikation des "Hearing Snake"-Beispiels aus "Project Keyword Spotter". Das Beispiel wurde auf ein Minimum reduziert, dann wurde der Teil zum Antrieb der Servos hinzugefügt, basierend auf der Software und Beispielen, die für die Adafruit Servohaube bereitgestellt wurden.

Das Skript wurde noch nicht optimiert. Nutzung auf eigenes Risiko, Änderungen und Optimierungen vorbehalten.

Neben dem Python-Skript gibt es die Befehlsdatei und die verwendete Etikettendatei. Legen Sie es in den config-Unterordner.

Wie bereits erwähnt, sind möglicherweise mehrere Parameteranpassungen erforderlich, um das Skript für Ihren speziellen MeArm oder ein anderes Gerät anzupassen.

# Copyright 2019 Google LLC#

# Lizenziert unter der Apache-Lizenz, Version 2.0 (die "Lizenz"); # Sie dürfen diese Datei nur in Übereinstimmung mit der Lizenz verwenden. # Eine Kopie der Lizenz erhalten Sie unter # # 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 # # Sofern nicht durch geltendes Recht vorgeschrieben oder schriftlich vereinbart, wird Software, # die unter der Lizenz vertrieben wird, "wie besehen" verteilt, # OHNE GEWÄHRLEISTUNGEN ODER BEDINGUNGEN VON JEDE ART, sei es ausdrücklich oder stillschweigend. # Siehe die Lizenz für die spezifische Sprache, die Berechtigungen und # Einschränkungen unter der Lizenz regelt. # der ursprüngliche "hearing_snake"-Code wurde von Dr. H. für eine Implementierung für den MeArm modifiziert. ''' Anleitung Meine Implementierung verwendet einen Raspbery Pi 4 mit einem Google Coral-Beschleuniger und einer angebrachten Adafruit 16-Kanal-Servohaube. An den Ports 3, 7, 11 und 15 der Motorhaube wurden die Servos eines MeArms (MIME Industries) angeschlossen. Für Details werfen Sie bitte einen Blick auf das Instructable "Hearing MeArm". Befehle: "position x", x= 0 bis 9, fährt das Gerät in eine vorgegebene vordefinierte Position. "bewegen/gehen hoch", "bewegen/gehen runter", "gehen/drehen vorwärts", "gehen/drehen rückwärts", "drehen/gehen links" und "drehen/gehen rechts" evozieren eine langsame, schrittweise Bewegung im Gegebenen Richtung, "Spiel stoppen" stoppt die Bewegungen. „Tab öffnen“und „Tab schließen“öffnet bzw. schließt den Greifer. "Video starten" ruft das Gerät dazu auf, einer voreingestellten Reihenfolge von Positionen zu folgen, die durch die Liste "Positionen" definiert ist. "Zufallsspiel" führt zu einem zufälligen Bewegungsmuster, "Spiel stoppen" beendet es. "Spiel starten" startet eine weitere Zugfolge, die durch die Liste 'transport1' vorgegeben wird, "nächstes Spiel" die umgekehrte Operation, die durch 'transport2' vorgegeben wird Benutzung auf eigene Gefahr. ''' 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 Thread import time from edgetpu.basic.basic_engine import BasicEngine import model import pygame from pygame.locals import * import queue from 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) # Anzahl der Kanäle einstellen #kit.servo[0].actuation_range = 160 #kit.servo[0].set_pulse_width_range(1000, 2000) # Min-, Center- und Max-Einstellungen up_l = 145 # Servo up/down: up md_l = 95 dn_l = 45 up_r = 135 # Servo vorwärts/rückwärts md_r = 90 dn_r = 50 ri_t = 30 # Dreharm rechts oder links: rechte Position md_t = 90 # Dreharm rechts oder links: Mittelstellung le_t = 150 op_g = 65 # Greifer offen md_g = 90 # Greifer zentriert cl _g = 130 # Greifer geschlossen vert = 15 # Anzahl Servoanschlüsse, Servo oben/unten vorwärts = 11 # Anzahl Servoanschlüsse, Vorwärts-/Rückwärtsbewegung Servodrehung = 7 # Servoanschluss zum Drehen Servogriff = 3 # Servoanschluss für Griff Servo #Liste der Armeinstellungen für neun Positionen 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,), (dn_l, dn_r, le_t, md_g)] # definiert 10 Basispositionen, angegeben durch ganze Zahlen 0-9 # Transportverfahren [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)]

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)]

dance1 =(0, 8, 7, 4, 1, 2, 3, 6, 9, 8, 5, 2, 1, 4, 7, 8, 9, 6, 3, 2, 0) # ein "Tanz"

#MeArm in Nullposition bewegen 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): # fährt MeArm auf voreingestellte Positionen, Schlüsselwörter: "position x" key = int(keys) p = position[key] a = p[0] b = p[1] c = p[2] d = p[3] print ("Positionen: ", Taste, " vert/forw/turn/grip: ", a, "/", b, "/", c, "/", d, "degrees") status = [a, b, c, d] # Dokumente aktueller Status print (status) # sys.stdout.write("Position: ", Taste, " links/rechts: ", a, "/", b, "Grad") 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): # steuert MeArm-Tanz, Schlüsselwort: "start_video" dnce = dance1 sp=(len(dnce)) für r im Bereich (sp): #tanzende Reihenfolge der Positionen, sp Schritte dc = dnce[r] p = Position[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) # setzt Bewegungsgeschwindigkeit time.sleep(0.5) # Pause am Ende der Prozedur def TransMeArm1(self): # steuert MeArm Transport 1, Stichwort: "Spiel starten" tr1 = transport1 sp=(len(tr1)) #berechne die Anzahl der Schritte für r im Bereich (sp): #gehe zu einem beliebigen Schritt 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 Bewegungsgeschwindigkeit time.sleep(0.5) def TransMeArm2(self): # steuert MeArm-Tanz, Stichwort: "nächstes Spiel" tr2 = transport2 sp=(len(tr2)) für r in Reichweite (sp): #tanzende Reihenfolge der Positionen, sp Schritte 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) # setzt Bewegungsgeschwindigkeit time.sleep(0.5) def RandomMoves(self): # springt zufällig zwischen vordefinierten Positionen, Stichwort: "random game" dr= randrange (9) #wählt zufällig eine Position p = position[dr] # liest Positionsparameter 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) # setzt Bewegungsgeschwindigkeit def MoveUp(self): # Greifer in kleinen Schritten anheben u0 = status[0] # aktuellen Status lesen u1 = u0 + 5 # plus x Grad if (u1 > up_l): # testet ob min/max Parameter nicht überschritten werden u1 = up_l # ansonsten auf min/max Wert gesetzt kit.servo[vert].angle = u1 # Servo Status[0] = u1 bewegen # Statuswert anpassen print (" up", status) time.sleep (1) # setzt die Geschwindigkeit def MoveDown(self): d 0 = status[0] d1 = d0 - 5 #minus x Grad if (d1 up_r): f1 = up_r kit.servo[forw].angle = f1 # move servo status[1] = f1 print ("vorwärts", status) time.sleep (1) def MoveBack(self): b0 = status[1] b1 = b0 - 5 #minus x Grad 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 #minus x Grad if (r1 < ri_t): r1 = ri_t kit.servo[turn].angle = r1 # move servo status[2] = r1 print ("rechts", status) time.sleep (0.2) def OpenGrip(self): kit.servo[grip].angle = op_g # Griff auf "open" Position setzen: "open_tab" time.sleep(0.5) status[3] = op_g def CloseGrip(self): kit.servo[grip].angle = cl_g # Griff auf "closed" Position setzen: " close_tab" time.sleep(0.5) status[3] = cl_g def StopMove(self): # tut nichts, aber stoppt Bewegungen print ("stop", status) time.sleep(0.25) def spotter(self, args): engine = BasicEngine(args.model_file) mic = args.mic if args.mic ist 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_hz), num_frames_hop= int(args.num_frames_hop)) def on_execute(self, args): falls nicht self.on_init(): self._running = False q = model.get_queue() self._controler = Controler(q) falls nicht args.debug_keyboard: t = Thread(target=self.spotter, args=(args,)) t.daemon = True t.start() item = -1 während self._running: pygame.event.pump() if args.debug_keyboard: keys = pygame.key.get_pressed() else: try: new_item = q.get(True, 0.1) außer queue. Empty: new_item = None wenn new_item nicht None ist: 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]) oder item == "right": # rechts abbiegen self. MoveRight() if (args.debug_ke yboard and keys[pygame. K_LEFT]) oder item == "left": # links drehen 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": # rückwärts self. MoveBack() if (args.debug_keyboard and keys[pygame. K_F]) or item == "f": # leitet self. MoveForw() weiter if (args.debug_keyboard and keys[pygame. K_O]) or item == "o": # Griff öffnen: self. OpenGrip() if (args.debug_keyboard and keys[pygame. K_C]) or item == "c": # Griff schließen: self. CloseGrip() if (args.debug_keyboard and keys [pygame. K_S]) oder item == "s": # Bewegung stoppen: "start_game" self. StopMove() if (args.debug_keyboard and keys[pygame. K_0]) oder 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]) oder es 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]) oder item == "5": self. MeArmPos(5) if (args.debug_keyboard and keys[pygame. K_6]) oder 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, on "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]) oder item == "j": self. TransMeArm1() # Transportobjekt: "lunch_game" if (args.debug_keyboard and keys[pygame. K_k]) or item == "k": self. TransMeArm2() # Transportobjekt umgekehrte Richtung: "next_game" ''' if (args.debug_keyboard and keys[pygame. K_l]) oder item == "l": self. JumpingJack2(1) #LED blinkt "target" ''' time.sleep(0.05) self.on_cleanup() if _name_ == '_main_': parser = argparse. ArgumentParser() parser.add_argument('--debug_keyboard', help='Benutze die Tastatur, um den MeArm zu steuern.', action='store_true', default=False) model.add_model_flags(parser) args = parser..parse_args () the_app = App() the_app.on_execute(args)

Empfohlen: