Indholdsfortegnelse:

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

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

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

I det følgende vil jeg beskrive en stemmestyret version af MeArm, en lille xyz robotarm med en griber. Jeg brugte MeArm Pi fra MIME-industrier, men systemet skulle være gældende for enhver version af MeArm eller lignende servodrevne enheder.

Brug af Google Coral TPU Accelerator gør det muligt at køre hurtige offline TensorFlow -stemmegenkendelsesscripter på Raspberry Pi og hermed kontrollere fysiske enheder ved talte ordrer med en latens på under et sekund.

Enheden beskrevet heri er en kombination og forlængelse af begreber beskrevet i to tidligere instruktioner. Det er en forlængelse af en tidligere implementering af Google Coral stemmestyring, en Jumping Jack, beskrevet her og en stor forbedring af en Google AIY stemmestyret MeArm beskrevet her.

Den stemmestyrede MeArm, der brugte Google Voice AIY-systemet, krævede onlineadgang, var ikke let at implementere, krævede at trykke på en knap for at aktivere lytning efter stemmebestillinger og havde en lang ventetid. Den anvendte Google Coral TPU Accelerator gør det nu muligt at køre TensorFlowLite -modeller offline med en høj hastighed på en Raspberry Pi eller andre Linux -enheder. Blandt eksemplerne på Google Coral Github -siden er der et eksempel kaldet "høringsslange" til et stemmegenkendelsessystem, der kan forstå 140 nøglesætninger (september 2019), som derefter bliver kortlagt til virtuelle tastetryk. Kobling af disse "tastetryk" med udførelsen af nogle funktioner programmeret i Python gør det muligt at bygge en stemmekommando -styret enhed. Jeg havde for nylig beskrevet en første implementering, et stemmestyret elektromekanisk springstik. Implementeringen heri er lidt mere kompleks og gør det muligt at styre alle fire servoer i MeArm for enten at flytte MeArm kontinuerligt eller få det til at flytte til et antal foruddefinerede stillinger, eller for at udføre nogle mere komplekse opgaver.

Ved at bruge scriptet her som eksempel, bør det være relativt enkelt at konstruere andre stemmestyrede enheder, f.eks. robotbiler eller hjælpende teknologiske enheder.

Forbrugsvarer

  • MeArm. Brugt her: MeArm Pi fra MIME Industries
  • Hindbær Pi 4
  • Google Coral TPU Accelerator
  • Adafruit 16 kanals servo motorhjelm
  • nogle springkabler
  • valgfri: kondensator til servo motorhjelm, ca. 400 µF til 4 servoer (anbefalet af Adafruit)
  • 5-6 V strømkilde til servo motorhjelm. Jeg brugte her en gammel 6V oplader, en 4x AA batteripakke fungerer også
  • Mikrofon. Jeg brugte et gammelt Microsoft HD3000 webcam som mikrofon.

Trin 1: Opsætning af systemet

Opsætning af systemet
Opsætning af systemet
Opsætning af systemet
Opsætning af systemet

Download det forudkonfigurerede Raspian -billede til Google Coral TPU Accelerator fra Google Coral Github -siden, og installer det på et µSD -kort. Billedet indeholder også en række eksempler på scripts. Indstil Pi som angivet.

Installer eksemplet Keyword spotter fra Google Coral GitHub -webstedet, hvis det ikke er inkluderet i billedet, og alle nødvendige programmer. Sæt mikrofonen på Pi. Jeg vil anbefale at lege med eksemplet "Hearing Snake" for at sikre, at alt fungerer.

Download og installer Adafruit 16 kanals motorhjelmssoftware, som beskrevet her. Installer motorhjelmen, og spil med Adafruit -eksemplerne for at sikre, at alt fungerer korrekt.

Download de vedhæftede filer til denne instruks, og kopier dem til mappen "Project Keyword Spotter". Filen "commands_v1_MeArm.txt" skal kopieres til undermappen "config".

Tilslut din MeArms servoer til servo motorhjelmen som angivet. Jeg brugte port 15 til op/ned, port 11 til frem/tilbage, port 7 til drejning og port 3 til griber servoer.

Inden for scriptet skal du muligvis justere min/center/max værdierne for hver servo til din konfiguration. Disse indstillinger hjælper med at undgå skader på servoer. Du skal muligvis også ændre de inkluderede "positioner", "transport1" og "transport2" lister.

Kør scriptet. Indtil videre havde jeg kørt det fra IDE.

Hvis du vil ændre nøglesætningerne, der fremkalder en bestemt funktion efter dit behov. En komplet liste over tilgængelige nøglefraser findes i filen "labels_gc2 raw.txt" i undermappen config.

Systemet har en latenstid på ca. 1 sekund, men afhænger meget af hvilke handlinger der udføres. I nogle tilfælde skal nøglefasen gentages, genkendelsens nøjagtighed er ikke altid 100%.

Trin 2: Brug af enheden

Hvis alt er konfigureret og kontrolleret, kan du køre enheden.

En aktuel begrænsning er, at en given ordre udføres gentagne gange, så længe den ikke stoppes (ved hjælp af "stop game") eller der gives en anden ordre. Komplekse flertrinsopgaver, f.eks. "transport1" (fremkaldt af udtrykket "lanceringsspil") udføres altid til det sidste trin.

Så ved at "dreje til højre" bevæger enheden sig i små trin til højre, indtil den stoppes, eller den forudindstillede maksimumværdi er nået. "lanceringsspil", "næste spil" eller "start_video" starter en række træk, der er defineret af lister, der indeholder indstillingen for hver servo på et givet trin. "tilfældigt spil" vil enheden til at hoppe fra et til et andet trin, tilfældigt valgt fra en liste med indstillinger.

Som du måske ser i den ledsagende video, havde jeg bygget en diaboloformet genstand fra LEGO, der kan hentes af MeArm og transporteres fra et sted til et andet ved et foruddefineret sæt bevægelser. Du kan definere dine egne funktioner ved at ændre listerne 'transport1' eller 'transport2'.

Trin 3: Scriptet

Scriptet, der er angivet her, er en ændring af "Hearing Snake" -eksemplet fra "Project Keyword Spotter". Eksemplet er blevet fjernet til et minimum, derefter blev delen til at køre servoer tilføjet, baseret på softwaren og eksempler til Adafruit servo motorhjelm.

Scriptet er ikke blevet optimeret nu. Brug på egen risiko, du er velkommen til at ændre og optimere.

Ud over python-scriptet er der kommandofilen og den brugte etiket-fil. Placer det i config-undermappen.

Som nævnt før kan det være nødvendigt med flere justeringer af parametre for at tilpasse scriptet til din specielle MeArm eller en anden enhed.

# Copyright 2019 Google LLC#

# Licenseret under Apache -licensen, version 2.0 ("licensen"); # du må ikke bruge denne fil, undtagen i overensstemmelse med licensen. # Du kan få en kopi af 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 # # Medmindre det kræves i henhold til gældende lov eller skriftligt er aftalt, distribueres software #, der distribueres under licensen, på en "AS IS" -BASIS, # UDEN GARANTIER ELLER BETINGELSER FOR ALLE Slag, enten udtrykkelige eller underforståede. # Se licensen for det specifikke sprog for tilladelser og # begrænsninger under licensen. # den originale "earing_snake "-kode blev ændret til en implementering af MeArm af Dr. H. '' 'Instruktioner Min implementering bruger en Raspbery Pi 4 med en Google Coral -accelerator og en Adafruit 16 -kanals servo -motorhjelm påsat. Servoerne til en MeArm (MIME -industrier) blev fastgjort til port 3, 7, 11 og 15 på motorhjelmen. For detaljer, se venligst "Hearing MeArm" Instructable. Kommandoer: "position x", x = 0 til 9, flytter enheden til en given foruddefineret position. "bevæg/gå op", "bevæg/gå ned", "gå/drej fremad", "gå/drej baglæns", "drej/gå til venstre" og "drej/gå til højre" fremkalder en langsom, trinvis bevægelse i den givne retning, "stop game" stopper bevægelserne. "åben fane" og "luk fane" åbner eller lukker griberen. "start video" får enheden til at følge en forudindstillet rækkefølge af positioner, defineret af listen 'positioner'. "tilfældigt spil" resulterer i et tilfældigt bevægelsesmønster, "stopspil" ender det. "lanceringsspil" starter endnu en række træk foruddefineret af listen 'transport1', 'næste spil' den omvendte operation foruddefineret af 'transport2' Brug på egen risiko. '' 'fra _future_ import absolut_import fra _future_ import division fra _future_ import print_function import argparse import os fra random import randint fra threading import Thread import tid fra edgetpu.basic.basic_ engine import BasicEngine import model import pygame fra pygame.locals import * import kø fra import tilfældig import randrange fra adafruit_servokit import ServoKit import board 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) # sæt antal kanaler # kit.servo [0].actuation_range = 160 # kit.servo [0].set_pulse_width_range (1000, 2000) # min, center og max indstillinger up_l = 145 # servo op/ned: op md_l = 95 dn_l = 45 op_r = 135 # servo fremad/bagud md_r = 90 dn_r = 50 ri_t = 30 # drejearm til højre eller venstre: højre position md_t = 90 # drejearm til højre eller venstre: midterposition le_t = 150 op_g = 65 # åben griber md_g = 90 # griber centreret cl _g = 130 # griber lukket vert = 15 # antal servo port, servo op/ned forw = 11 # antal servo port, frem/tilbage bevægende servo drejning = 7 # servo port til at dreje servo greb = 3 # servo port til greb servo #liste med armindstillinger for ni 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, d_,), (dn_l, dn_r, le_t, md_g)] # definerer 10 basispositioner, angivet med heltal 0-9 # transportprocedurer [vert/frem/drej/greb] 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 [greb].angle = status [3] print (status) klasse Controler (objekt): #Callback -funktion def _init _ (self, q): self._q = q def callback (self, kommando): self._q.put (kommando) klasse 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): hvis event.type == pygame. QUIT: self._running = False def MeArmPos (self, keys): # driver MeArm til forudindstillede positioner, søgeord: "position x" key = int (keys) p = position [nøgle] a = p [0] b = p [1] c = p [2] d = p [3] print ("Positioner:", nøgle, "vert/forw/turn/greb:", a, "/", b, "/", c, "/", d, "grader") status = [a, b, c, d] # dokumenter nuværende status udskriv (status) # sys.stdout.write ("Position: ", nøgle," venstre/højre: ", a,"/", b," grad ") kit.servo [vert].angle = et kit.servo [forw].angle = b kit.servo [turn].angle = c kit.servo [greb].angle = d time.sleep (0,5) def DancingMeArm (self): # styrer MeArm dance, søgeord: "start_video" dnce = dance1 sp = (len (dnce)) for r inden for rækkevidde (sp): #danseres rækkefølge, sp trin dc = dnce [r] p = position [dc] a = p [0] b = p [1] c = p [2] d = p [3] kit.servo [vert].angle = et kit.servo [forw].angle = b kit.servo [turn].angle = c kit.servo [greb].angle = d time.sleep (1) # indstiller bevægelseshastighed time.sleep (0.5) # pause ved afslutning af proceduren def TransMeArm1 (self): # styrer MeArm transport 1, søgeord: "lanceringsspil" tr1 = transport1 sp = (len (tr1)) #beregne antal trin for r i område (sp): #gå til ethvert trin p = tr1 [r] a = p [0] b = p [1] c = p [2] d = p [3] kit. servo [vert].angle = et kit.servo [forw].angle = b kit.servo [turn].angle = c kit.servo [greb].angle = d print (p) time.sleep (1) # sæt bevægelseshastighed time.sleep (0.5) def TransMeArm2 (self): # styrer MeArm dance, søgeord: "næste spil" tr2 = transport2 sp = (len (tr2)) for r inden for rækkevidde (sp): #dans rækkefølge af positioner, sp trin 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) # indstiller bevægelseshastighed time.sleep (0,5) def RandomMoves (self): # hopper tilfældigt mellem foruddefinerede positioner, søgeord: "tilfældigt spil" dr = randrange (9) # vælger tilfældigt en position p = position [dr] # læser positionsparametre 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 [greb].angle = d tid. søvn (1) # indstiller bevægelseshastighed def MoveUp (selv): # løfte griber i små trin u0 = status [0] # læs nuværende status u1 = u0 + 5 # plus x grader hvis (u1 > up_l): # test, hvis de ikke overstiger min/max parametre u1 = up_l # ellers indstillet til min/max værdi kit.servo [vert].angle = u1 # flyt servostatus [0] = u1 # juster statusværdi udskrivning (" op ", status) time.sleep (1) # indstiller hastighed def MoveDown (self): d 0 = status [0] d1 = d0 - 5 #minus x grader hvis (d1 up_r): f1 = up_r kit.servo [forw].angle = f1 # flytte servostatus [1] = f1 print ("frem", status) time.sleep (1) def MoveBack (self): b0 = status [1] b1 = b0 - 5 #minus x grader, hvis (b1 le_t): l1 = le_t kit.servo [turn].angle = l1 # flytte servo status [2] = l1 print ("venstre", 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øjre", status) time.sleep (0.2) def OpenGrip (self): kit.servo [greb].angle = op_g # sæt greb til "åben" position: "open_tab" time.sleep (0.5) status [3] = op_g def CloseGrip (self): kit.servo [greb].angle = cl_g # sæt greb til "lukket" position: " close_tab "time.sleep (0.5) status [3] = cl_g def StopMove (self): # gør ingenting, men stopper bevægelser print (" stop ", status) time.sleep (0.25) def spotter (self, args): motor = BasicEngine (args.model_file) mic = args.mic hvis args.mic er Intet andet 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): hvis ikke self.on_init (): self._running = False q = model.get_queue () self._controler = Controler (q) hvis ikke 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: prøv: new_item = q.get (True, 0.1) undtagen queue. Empty: new_item = None hvis new_item ikke er None: item = new_item if (args.debug_keyboard og nøgler [pygame. K_ESCAPE]) eller item == "stop": self._running = Falsk # hvis (args.debug_keyboard og nøgler [pygame. K_SPACE]) eller item == "go": # self. MeArmPos (7) # if (args.debug_keyboard og nøgler [pygame. K_RIGHT]) eller element == "højre": # drej til højre selv. MoveRight () hvis (args.debug_ke yboard og nøgler [pygame. K_LEFT]) eller element == "venstre": # drej til venstre self. MoveLeft () hvis (args.debug_keyboard og nøgler [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 () hvis (args.debug_keyboard og nøgler [pygame. K_F]) eller element == "f": # videresender self. MoveForw () if (args.debug_keyboard og nøgler [pygame. K_O]) eller element == "o": # åbent greb: self. OpenGrip () if (args.debug_keyboard og nøgler [pygame. K_C]) eller item == "c": # close grip: self. CloseGrip () if (args.debug_keyboard and keys [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 og nøgler [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 og nøgler [pygame. K_6]) eller item == "6": self. MeArmPos (6) if (args.debug_keyboard og nøgler [pygame. K_7]) eller item == "7": self. MeArmPos (7) if (args.debug_keyboard og nøgler [pygame. K_8]) eller item == "8": self. MeArmPos (8) hvis (args.debug_keyboard og nøgler [pygame. K_9]) eller item == "9": self. MeArmPos (9) if (args.debug_keyboard og nøgler [pygame. K_a]) eller item == "d": self. DancingMeArm () #dancing MeArm, på "next_game" if (args.debug_keyboard og nøgler [pygame. K_r]) eller item == "r": self. RandomMoves () #randomom "random game" if (args.debug_keyboard og nøgler [pygame. K_j]) eller item == "j": self. TransMeArm1 () # transportobjekt: "lunch_game" if (args.debug_keyboard og nøgler [pygame. K_k]) eller item == "k": self. TransMeArm2 () # transportobjekt omvendt retning: "next_game" '' 'if (args.debug_keyboard og nøgler [pygame. K_l]) eller item == "l": self. JumpingJack2 (1) #LED blink "target" '' 'time.sleep (0,05) self.on_cleanup () hvis _name_ ==' _main_ ': parser = argparse. ArgumentParser () parser.add_argument ('-debug_keyboard', help = 'Brug tastaturet til at styre MeArm.', action = 'store_true', default = False) model.add_model_flags (parser) args = parser.parse_args () the_app = App () the_app.on_execute (args)

Anbefalede: