Innehållsförteckning:

A Hearing MeArm, Google Coral TPU Accelerator Driven: 3 steg
A Hearing MeArm, Google Coral TPU Accelerator Driven: 3 steg

Video: A Hearing MeArm, Google Coral TPU Accelerator Driven: 3 steg

Video: A Hearing MeArm, Google Coral TPU Accelerator Driven: 3 steg
Video: Gesture control Robot Arm MediaPipe MeArm 2024, November
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

I det följande skulle jag vilja beskriva en röststyrd version av MeArm, en liten xyz robotarm med en gripare. Jag använde MeArm Pi från MIME-industrier, men systemet bör vara tillämpligt på alla versioner av MeArm eller liknande servodrivna enheter.

Med hjälp av Google Coral TPU Accelerator kan du köra snabba offline TensorFlow -röstigenkänningsskript på Raspberry Pi och härmed styra fysiska enheter med talade order, med en latens under en sekund.

Anordningen som beskrivs häri är en kombination och förlängning av begrepp som beskrivs i två tidigare instruktioner. Det är en förlängning av en tidigare implementering av Google Coral röststyrning, en Jumping Jack, som beskrivs här och en stor förbättring av en Google AIY röststyrd MeArm som beskrivs här.

Den röststyrda MeArm som använde Google Voice AIY-systemet krävde onlineåtkomst, var inte lätt att implementera, krävde att trycka på en knapp för att aktivera lyssning efter röstorder och hade en lång latens. Google Coral TPU Accelerator som används nu gör det möjligt att köra TensorFlowLite -modeller offline med hög hastighet på en Raspberry Pi eller andra Linux -enheter. Bland exemplen på Google Coral Github -sidan finns ett exempel som heter "hörande orm" för ett röstigenkänningssystem som kan förstå 140 nyckelfraser (september 2019), som sedan mappas till virtuella tangenttryckningar. Koppling av dessa "tangenttryckningar" med utförandet av vissa funktioner programmerade i Python gör det möjligt att bygga en röstkommandostyrd enhet. Jag hade nyligen beskrivit en första implementering, en röststyrd elektromekanisk hoppjack. Implementeringen här är lite mer komplex och gör det möjligt att styra alla fyra servon i MeArm för att antingen flytta MeArm kontinuerligt eller få det att flytta till ett antal fördefinierade positioner, eller för att utföra några mer komplexa uppgifter.

Med manuset som tillhandahålls här som exempel bör det vara relativt enkelt att konstruera andra röststyrda enheter, t.ex. robotbilar eller hjälptekniska enheter.

Tillbehör

  • MeArm. Används här: MeArm Pi från MIME Industries
  • Hallon Pi 4
  • Google Coral TPU Accelerator
  • Adafruit 16 -kanals servomotorhuv
  • några bygelkablar
  • valfritt: kondensator för servomotorhuv, cirka 400 µF för 4 servon (rekommenderas av Adafruit)
  • 5-6 V strömkälla för servomotorhuven. Jag använde här en gammal 6V -laddare, ett 4x AA -batteri fungerar också
  • Mikrofon. Jag använde en gammal Microsoft HD3000 webbkamera som mikrofon.

Steg 1: Installera systemet

Installera systemet
Installera systemet
Installera systemet
Installera systemet

Ladda ner den förkonfigurerade Raspian -bilden för Google Coral TPU Accelerator från Google Coral Github -sidan och installera den på ett µSD -kort. Bilden innehåller också ett antal exempelskript. Ställ in Pi enligt anvisningarna.

Installera exemplet Keyword spotter från Google Coral GitHub -webbplatsen, om den inte ingår i bilden, och alla nödvändiga program. Anslut mikrofonen till Pi. Jag skulle rekommendera att spela med "Hearing Snake" -exemplet för att se till att allt fungerar.

Ladda ner och installera programvaran för Adafruit 16 -kanal motorhuv, enligt beskrivningen här. Installera motorhuven och lek med Adafruit -exemplen för att säkerställa att allt fungerar som det ska.

Ladda ner filerna som bifogas den här instruerbara filen och kopiera dem till mappen "Project Keyword Spotter". "Command_v1_MeArm.txt" -filen måste kopieras till undermappen "config".

Anslut din MeArms servon till servohuven enligt anvisningarna. Jag använde port 15 för upp/ner, port 11 för fram/bakåt, port 7 för sväng och port 3 för gripservon.

Inom skriptet kan du behöva justera värdena min/center/max för varje servo till din konfiguration. Dessa inställningar hjälper till att undvika skador på servon. Du kan också behöva ändra de inkluderade "positionerna", "transport1" och "transport2" listorna.

Kör skriptet. Hittills hade jag kört det från IDE.

Om du vill ändra nyckelfraserna som framkallar en viss funktion enligt dina behov. En fullständig lista över tillgängliga nyckelfraser finns i filen "labels_gc2 raw.txt" i undermappen config.

Systemet har en latens på cirka 1 sekund, men mycket beroende på vilka åtgärder som utförs. I vissa fall måste nyckelfasen upprepas, igenkänningens noggrannhet är inte alltid 100%.

Steg 2: Använda enheten

Om allt är inställt och kontrollerat kan du köra enheten.

En aktuell begränsning är att en given order utförs repetitivt så länge den inte stoppas (med hjälp av "stoppspel") eller en annan order ges. Komplexa flerstegsuppgifter, t.ex. "transport1" (framkallad av frasen "lanseringsspel") körs alltid till det sista steget.

Så genom att "sväng höger" rör sig enheten i små steg till höger tills den stoppas, eller det förinställda maxvärdet uppnås. "lanseringsspel", "nästa spel" eller "start_video" startar en serie drag som definieras av listor som innehåller inställningen för varje servo vid ett givet steg. "slumpmässigt spel" kommer enheten att hoppa från ett till ett annat steg, plockat slumpmässigt från en lista med inställningar.

Som ni kanske ser i den medföljande videon hade jag byggt ett diaboloformat föremål från LEGO som kan plockas upp av MeArm och transporteras från en plats till en annan med en fördefinierad uppsättning rörelser. Du kan definiera dina egna funktioner genom att ändra listorna "transport1" eller "transport2".

Steg 3: Skriptet

Skriptet som listas här är en ändring av exemplet "Hearing Snake" från "Project Keyword Spotter". Exemplet har avskalats till ett minimum, sedan tillkom delen för att köra servon, baserat på mjukvaran och exemplen som tillhandahålls för Adafruit servo motorhuven.

Skriptet har inte optimerats nu. Använd på egen risk, modifiera och optimera gärna.

Förutom python-skriptet finns kommandofilen och den använda etikettfilen. Placera den i config-undermappen.

Som nämnts tidigare kan flera justeringar av parametrar krävas för att anpassa skriptet för din speciella MeArm eller någon annan enhet.

# Copyright 2019 Google LLC#

# Licensierad under Apache -licensen, version 2.0 ("licensen"); # du får inte använda den här filen förutom i enlighet med licensen. # Du kan få en kopia av licensen på # # 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 # # Om inte krävs enligt tillämplig lag eller skriftligt överenskommet, distribueras programvara # som distribueras enligt licensen på en "SOM ÄR" -BASIS, # UTAN GARANTIER ELLER VILLKOR FÖR NÅGOT SORT, antingen uttryckligt eller underförstått. # Se licensen för det specifika språket för behörigheter och # begränsningar under licensen. # den ursprungliga "hearing_snake" -koden ändrades för en implementering för MeArm av Dr H. '' 'Instruktioner Min implementering använder en Raspbery Pi 4 med en Google Coral -accelerator och en Adafruit 16 -kanalig servohuva fäst. Servoerna för en MeArm (MIME -industrier) var anslutna till portarna 3, 7, 11 och 15 på motorhuven. För mer information, ta en titt på "Hearing MeArm" Instructable. Kommandon: "position x", x = 0 till 9, flyttar enheten till en given fördefinierad position. "flytta/gå upp", "flytta/gå ner", "gå/sväng framåt", "gå/sväng bakåt", "sväng/gå vänster" och "sväng/gå åt höger" framkallar en långsam, stegvis rörelse i den givna riktning, "stoppspel" stoppar rörelserna. "öppna fliken" och "stäng fliken" öppnar eller stänger griparen. "start video" framkallar att enheten följer en förinställd position, definierad av listan "positioner". "slumpmässigt spel" resulterar i ett slumpmässigt rörelsemönster, "stoppspel" avslutar det. "lanseringsspel" startar ytterligare en serie drag som är fördefinierade av listan "transport1", "nästa spel" den omvända operationen som fördefinierats av "transport2" Använd på egen risk. '' 'från _future_ import absolut_import från _future_ import division från _future_ import print_function import argparse import os från slumpmässig import randint från threading import Trådimporttid från edgetpu.basic.basic_engine import BasicEngine importmodell import pygame från pygame.locals import * importkö från slumpmässig import randrange från adafruit_servokit import ServoKit importkort import busio import adafruit_pca9685 importtid i2c = busio. I2C (board. SCL, board. SDA) hat = adafruit_pca9685. PCA9685 (i2c) hat.frekvens = 60 kit = ServoKit (kanaler = 16) # inställt antal kanaler # kit.servo [0].actuation_range = 160 # kit.servo [0].set_pulse_width_range (1000, 2000) # min, center och max inställningar up_l = 145 # servo upp/ner: upp md_l = 95 dn_l = 45 upp_r = 135 # servo framåt/bakåt md_r = 90 dn_r = 50 ri_t = 30 # svängarm höger eller vänster: höger position md_t = 90 # vridarm höger eller vänster: mittläge le_t = 150 op_g = 65 # öppning gripare md_g = 90 # greppcentrerad kl _g = 130 # gripare stängd vert = 15 # antal servoport, servo upp/ner framåt = 11 # antal servoport, fram/bakåt rörande servovridning = 7 # servoport för att vrida servogrepp = 3 # servoport för grepp servo #lista med arminställningar för nio positioner 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, mn,), (dn_l, dn_r, le_t, md_g)] # definierar 10 baslägen, indikerade med heltal 0-9 # transportprocedurer [vert/framåt/sväng/grepp] 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 objekt (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) # en "dans"

#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]. vinkel = status [2] kit.servo [grepp].angle = status [3] utskrift (status) klass Kontroller (objekt): #Callback -funktion def _init _ (self, q): self._q = q def callback (self, kommando): self._q.put (kommando) klass 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): # driver MeArm till förinställda positioner, sökord: "position x" key = int (nycklar) p = position [nyckel] a = p [0] b = p [1] c = p [2] d = p [3] utskrift ("Positioner:", tangent, "vert/framåt/sväng/grepp:", a, "/", b, "/", c, "/", d, "grader") status = [a, b, c, d] # dokument nuvarande statusutskrift (status) # sys.stdout.write ("Position: ", nyckel," vänster/höger: ", 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): # kontroller MeArm dance, sökord: "start_video" dnce = dance1 sp = (len (dnce)) för r i intervall (sp): #dansordning av positioner, sp -steg 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) # ställer in rörelsens hastighet time.sleep (0.5) # break i slutet av proceduren def TransMeArm1 (self): # kontrollerar MeArm transport 1, nyckelord: "launch game" tr1 = transport1 sp = (len (tr1)) #calculate antal steg för r i intervall (sp): #gå till valfritt steg 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 rörelsens hastighet time.sleep (0,5) def TransMeArm2 (self): # kontrollerar MeArm dance, nyckelord: "nästa spel" tr2 = transport2 sp = (len (tr2)) för r i intervall (sp): #dansordning av positioner, sp -steg 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) # ställer in rörelsens hastighet time.sleep (0,5) def RandomMoves (self): # hoppar slumpmässigt mellan fördefinierade positioner, sökord: "random game" dr = randrange (9) # väljer slumpmässigt en position p = position [dr] # läser positionsparametrar 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 [grepp].angle = d tid. sömn (1) # ställer in rörelsens hastighet def MoveUp (själv): # lyftgripare i små steg u0 = status [0] # läs aktuell status u1 = u0 + 5 # plus x grader om (u1 > up_l): # testar om inte parametrarna min/max överstiger u1 = up_l # i annat fall satt till min/max -värde kit.servo [vert].angle = u1 # flytta servostatus [0] = u1 # justera statusvärdesutskrift (" upp ", status) time.sleep (1) # anger hastighet def MoveDown (själv): d 0 = status [0] d1 = d0 - 5 #minus x grader om (d1 up_r): f1 = up_r kit.servo [forw].angle = f1 # flytta servostatus [1] = f1 -utskrift ("framåt", status) time.sleep (1) def MoveBack (self): b0 = status [1] b1 = b0 - 5 #minus x grader om (b1 le_t): l1 = le_t kit.servo [turn].angle = l1 # move servo status [2] = l1 print ("vänster", status) time.sleep (0.2) def MoveRight (self): r0 = status [2] r1 = r0 - 2 #minus x grader if (r1 <ri_t): r1 = ri_t kit.servo [turn].angle = r1 # move servo status [2] = r1 print ("höger", status) time.sleep (0.2) def OpenGrip (self): kit.servo [grip].angle = op_g # ställ in grepp till "öppet" läge: "öppet_tab" tid. sov (0,5) status [3] = op_g def Stänggrepp (själv): kit.servo [grepp].hörn = cl_g # ställ in grepp till "stängt" läge: " close_tab "time.sleep (0.5) status [3] = cl_g def StopMove (self): # gör ingenting, men stoppar rörelser print (" stop ", status) time.sleep (0.25) def spotter (self, args): motor = BasicEngine (args.model_file) mic = args.mic om args.mic är Ingen annan int (args.mic) model.classify_audio (mikrofon, motor, 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), 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) utom queue. Empty: new_item = None om new_item inte är None: item = new_item if (args.debug_keyboard och nycklar [pygame. K_ESCAPE]) eller 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]) eller item == "right": # sväng höger self. MoveRight () if (args.debug_ke yboard och nycklar [pygame. K_LEFT]) eller item == "vänster": # sväng vänster self. MoveLeft () if (args.debug_keyboard och nycklar [pygame. K_UP]) eller 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 och nycklar [pygame. K_F]) eller item == "f": # vidarebefordrar self. MoveForw () if (args.debug_keyboard och nycklar [pygame. K_O]) eller item == "o": # öppet grepp: self. OpenGrip () if (args.debug_keyboard och nycklar [pygame. K_C]) eller item == "c": # close grip: self. CloseGrip () if (args.debug_keyboard och nycklar [pygame. K_S]) eller 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 och nycklar [pygame. K_3]) eller det 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_4]) or item == "4": self. MeArmPos (4) if (args.debug_keyboard and keys [pygame. K_5]) eller item == "5": self. MeArmPos (5) if (args.debug_keyboard och nycklar [pygame. K_6]) eller item == "6": self. MeArmPos (6) if (args.debug_keyboard och nycklar [pygame. K_7]) eller item == "7": self. MeArmPos (7) if (args.debug_keyboard och nycklar [pygame. K_8]) eller 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, på "next_game" if (args.debug_keyboard and keys [pygame. K_r]) or item == "r": self. RandomMoves () #randomom dance "random game" if (args.debug_keyboard and keys [pygame. K_j]) eller item == "j": self. TransMeArm1 () # transportobjekt: "lunch_game" if (args.debug_keyboard och nycklar [pygame. K_k]) eller item == "k": self. TransMeArm2 () # transportobjekt omvänd riktning: "next_game" '' 'if (args.debug_keyboard och nycklar [pygame. K_l]) eller item == "l": self. JumpingJack2 (1) #LED blinkar "target" '' 'time.sleep (0.05) self.on_cleanup () if _name_ ==' _main_ ': parser = argparse. ArgumentParser () parser.add_argument ('-debug_keyboard', help = 'Använd tangentbordet för att styra MeArm.', action = 'store_true', default = False) model.add_model_flags (parser) args = parser.parse_args () the_app = App () the_app.on_execute (args)

Rekommenderad: