Índice:

A Hearing Jumping Jack, versão do Google Coral TPU Accelerator: 4 etapas
A Hearing Jumping Jack, versão do Google Coral TPU Accelerator: 4 etapas

Vídeo: A Hearing Jumping Jack, versão do Google Coral TPU Accelerator: 4 etapas

Vídeo: A Hearing Jumping Jack, versão do Google Coral TPU Accelerator: 4 etapas
Vídeo: George Hotz | Programming | tinygrad Google Edge TPU has a custom ISA?!? | reverse engineering part3 2024, Julho
Anonim
A Hearing Jumping Jack, versão do Google Coral TPU Accelerator
A Hearing Jumping Jack, versão do Google Coral TPU Accelerator
A Hearing Jumping Jack, versão do Google Coral TPU Accelerator
A Hearing Jumping Jack, versão do Google Coral TPU Accelerator
A Hearing Jumping Jack, versão do Google Coral TPU Accelerator
A Hearing Jumping Jack, versão do Google Coral TPU Accelerator

Ele move seus membros, ouve suas ordens, é movido pela mais recente tecnologia de aprendizado de máquina

O „Hearing Jumping Jack” é um simples Jumping Jack eletromecânico, acionado por dois micro servos e uma engrenagem muito simples, tendo LEDs como “olhos”. É controlado por comandos de voz simples que indicam qual das nove posições predefinidas ele deve assumir, ou se o LED deve ser ligado ou desligado, ou se deve executar uma "dança" predefinida ou um conjunto aleatório de movimentos.

O elemento central do sistema é o acelerador Google Coral TPU, que permite rodar modelos Tensorflow Lite offline com velocidade muito alta, mesmo em um computador "fraco" como o Raspberry Pi. Isso permite, por exemplo, identificação e classificação rápida de objetos usando a câmera RPi, mas também para executar funções de reconhecimento de voz baseadas em aprendizado de máquina localmente.

Para meu conhecimento, este é o primeiro exemplo publicado para um dispositivo DIY físico dirigido por detecção de voz Coral Accelerator, e o exemplo de código anexado também pode ser usado para outros projetos mais complexos.

O controle de voz é baseado no exemplo “a cobra auditiva” no “localizador de palavras-chave do projeto” (https://github.com/google-coral/project-keyword-spotter) que recentemente (setembro de 2019) foi colocado no GitHub. Na minha configuração, o sistema é composto por um Raspberry Pi 4 equipado com um servo bonnet Adafruit de 16 canais, um Google Coral TPU Accelerator e uma webcam, aqui usada como microfone. O Jumping Jack já havia sido descrito em um instrutível anterior, onde era acionado pelo kit Google Voice para ler comandos de voz, está anexado ao Servo Bonnet na versão 2.0 descrita a seguir.

A versão anterior do Google Voice Kit tinha três limitações centrais: dependia dos serviços de reconhecimento de voz baseados na web do Google e a configuração era relativamente complicada, era necessário pressionar algum tipo de botão antes de poder dar um comando e havia um grande atraso entre dizer o comando e a resposta do sistema. Usar o acelerador Google Coral reduz o tempo de resposta para segundos, é independente de uma conexão com a internet e escuta o tempo todo. Com algumas modificações, você pode usá-lo para controlar dispositivos muito mais complexos como um Jumping Jack, como robôs ou carros, ou o que quer que você possa construir e controlar com um Raspberry Pi.

Em sua versão atual, o observador de palavras-chave entende um conjunto de cerca de 140 palavras-chave / frases-chave curtas, definidas no arquivo de modelo que o acompanha (“voice_commands_v0.7_egetpu.tflite”) e descritas em um arquivo de etiqueta separado (“labels_gc2.raw.txt”). Definido por um arquivo livremente modificável (“comandos_v2_hampelmann.txt”), as palavras-chave usadas especificamente por nosso script são então mapeadas para pressionamentos de tecla em um teclado virtual, por exemplo, para letras, números, cima / baixo / esquerda / direita, crtl + c, etc.

Então, por exemplo usando pygame.key, esses "pressionamentos de tecla" são lidos e usados para controlar quais ações um dispositivo, aqui o jack de salto, deve executar. Em nosso caso, isso significa acionar os dois servos para posições predefinidas ou ligar ou desligar os LEDs. Como o localizador de palavras-chave é executado em um passo separado, ele pode ouvir permanentemente seus pedidos.

Versão 21 de setembro de 2019

Suprimentos

Raspberry Pi 4, via Pimoroni

Acelerador Google Coral TPU, via Mouser Alemanha, 72 €

Adafruit 16 Servo Bonnet, via Pimoroni, cerca de 10 €

www.adafruit.com/product/3416

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

Cabeçalho do empilhador (se necessário)

www.adafruit.com/product/2223

4 baterias AA (ou outra fonte de alimentação 5-6V) para Servo Bonnet

Webcam antiga, como microfone

Jumping Jack servo dirigido, conforme descrito em um instrutível anterior. Os desenhos de layout são anexados à próxima etapa, mas podem exigir ajustes.

Peças necessárias para o macaco:

- Placa Forex de 3 mm

- 2 micro servos

- Parafusos e porcas de 2 e 3 mm

- 2 LEDs brancos e um resistor

- um pouco de cabo

Etapa 1: Configurando o dispositivo

Configurando o Dispositivo
Configurando o Dispositivo
Configurando o Dispositivo
Configurando o Dispositivo
Configurando o Dispositivo
Configurando o Dispositivo

Para construir o Jumping Jack, siga as indicações dadas em um instrutível anterior. Usei Forex para o meu protótipo, mas você pode usar placas de acrílico ou madeira compensada cortadas a laser. Você pode ter que ajustar o layout de acordo com o tamanho de seus servos, etc. Teste se os membros e a engrenagem podem se mover sem atrito.

Configure o seu Raspberry Pi. No site Coral Github, há uma imagem do Raspian disponível que contém tudo o que é necessário para rodar o acelerador Coral no Pi e contém muitos projetos, com todas as configurações já definidas.

Obtenha o identificador de palavras-chave do projeto na página Google Coral GitHub. Instale todo o software necessário conforme indicado.

Instale os arquivos fornecidos. Coloque o script jumping jack python na pasta do spotter de palavras-chave do projeto e o arquivo de comandos coresponding na subpasta config.

Anexe a tampa do servo Adafruit ao Pi. Como estou usando um invólucro RPI com um ventilador, precisei usar empilhadores GPIO (por exemplo, disponíveis na Pimoroni) para habilitar a conexão. Instale todas as bibliotecas necessárias, conforme indicado nas instruções da Adafruit para o servo bonnet.

Conecte uma fonte de alimentação de 5-6 V ao servo bonnet. Conecte servos e LEDs. No meu caso, usei a porta 0 para os LEDs e as portas 11 e 15 para os servos.

Para verificar tudo, eu recomendaria tentar primeiro o exemplo do localizador de palavras-chave do projeto "cobra ouvinte" e os exemplos de capô servo da Adafruit.

Etapa 2: Executando o Jumping Jack

Se todas as peças estiverem configuradas e funcionando, tente usá-lo. Você pode executar o script no IDE ou na linha de comando.

Gritar "posição 0" para "posição 9" fará com que o Jumping Jack assuma uma das posições predefinidas. Eu defini "1" como ambos os braços para cima (uu), "3" como esquerda para cima, direita para baixo (ud), "9" como ambos os braços para baixo (dd) e "5" como ambos os braços centrados (cc).

uu uc ud = 1 2 3

cu cc cd = 4 5 6

du dc dd = 7 8 9

"0" é idêntico a "5". "3" e "8" não são reconhecidos muito bem pelo observador de palavras-chave e podem ter que ser repetidos.

Você pode ter que ajustar os valores mínimo e máximo para cada servo / lado para que os servos não sejam bloqueados e consumam muita energia.

O "próximo jogo" iniciará a "dança", ou seja, uma sequência definida de posições, enquanto o "jogo aleatório" iniciará o Jumping Jack para realizar uma sequência aleatória de movimentos. Em ambos os casos, eles funcionarão para sempre, então você pode ter que interromper os movimentos, por ex. com um comando de "posição zero".

"parar o jogo" irá evocar um "ctrl + c" e interromper o processo.

"ligar" e "desligar" podem ser usados para ligar e desligar os LEDs.

Modificando os valores de time.sleep, você pode ajustar a velocidade dos movimentos.

Etapa 3: O Código e o Arquivo de Comandos

O código apresentado aqui é uma modificação do código "cobra ouvinte" que faz parte do pacote de localização de palavras-chave do projeto. Acabei de remover tudo o que não era necessário para a minha inscrição, sem qualquer compreensão real dos detalhes. Quaisquer melhorias são bem-vindas.

Em seguida, adicionei as peças necessárias para o Adafruit Servo Bonnet, com base em seus arquivos de exemplo.

Gostaria de agradecer aos programadores de ambas as partes.

O código pode ser encontrado anexado como arquivo. Use-o por sua própria conta e risco, modifique-o, melhore-o, brinque com ele.

# Copyright 2019 Google LLC

# # Licenciado sob a Licença Apache, Versão 2.0 (a "Licença"); # você não pode usar este arquivo, exceto em conformidade com a Licença. # Você pode obter uma cópia da Licença em # # https://www.apache.org/licenses/LICENSE-2.0 # # A menos que exigido pela lei aplicável ou acordado por escrito, o software # distribuído sob a Licença é distribuído em um BASE "COMO ESTÁ", # SEM GARANTIAS OU CONDIÇÕES DE QUALQUER TIPO, expressas ou implícitas. # Consulte a Licença para as permissões específicas que regem o idioma e # limitações sob a Licença. from _future_ importar absolute_import de _future_ importar divisão de _future_ importar print_function import argparse importar os de importação aleatória randint de threading importar Tempo de importação de thread de edgetpu.basic.basic_engine importar BasicEngine importar modelo importar pygame de pygame.locals importar * importar fila de aleatório importar 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 (canais = 16) # set number dos canais # kit.servo [0].actuation_range = 160 # kit.servo [0].set_pulse_width_range (1000, 2000) # configurações para cima, meio e para baixo para os braços esquerdo e direito up_l = 35 md_l = 90 dn_l = 160 up_r = 160 md_r = 90 dn_r = 35

lft = 15 # número da porta do servo, servo esquerdo (0-8)

rgt = 11 # número da porta servo, servo direito (0-8) led_channel_0 = hat.channels [0] # LED definido na porta 0 led_channel_0.duty_cycle = 0 # ligar LED 100% #lista de configurações de braço para posição de nove posições = [(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)] # define 9 posições JumpingJack, indicadas por números inteiros 0-9 dança1 = (0, 8, 7, 4, 1, 2, 3, 6, 9, 8, 5, 2, 1, 4, 7, 8, 9, 6, 3, 2, 0) # a classe "dance" Controler (objeto): #Callback function def _init _ (self, q): self._q = q def callback (self, comando): 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): # controla Jumping Jack, palavras-chave: "position x" key = int (keys) p = position [tecla] a = p [0] b = p [1] impressão ("Posição:", tecla, "esquerda / direita: ", a," / ", b," grau ") # sys.stdout.write (" Posição: ", tecla," esquerda / direita: ", a," / ", b," grau ") kit.servo [lft].angle = a kit.servo [rgt].angle = b time.sleep (0.1) def JumpingJack1 (self): # controls Jumping Jack dance, palavra-chave: "próximo jogo" dnce = dance1 sp = (len (dnce)) para r no intervalo (sp): # ordem de dança das posições, sp passos dc = dnce [r] if (dc fora do intervalo (10)): # print ("erro de entrada na posição", sp) dc = 4 p = posição [dc] a = p [0] b = p [1] kit.servo [lft].angle = a kit.servo [rgt].angle = b time.sleep (0,25) # define a velocidade de movimentos def JumpingJack2 (self, keys): # controla Jumping Jack LEDs, palavras-chave: "ligar / desligar" led = int (teclas) se led == 1: led_channel_0.duty_cycle = 0xffff #ligar LED 100% time.sleep (0.1) se led == 0: led_channel_0.duty_cycle = 0 # desligar LED time.sleep (0.1) se led == 2: # piscar led_channel_0.duty_cycle = 0xffff #ligar LED 100% time.sleep (0,5) led_channel_0.duty_cycle = 0 #ligar LED 100% time.sleep (0,5) led_channel_0.duty_cycle = 0xffff #ligar LED 100% time.sleep (0,5) led_channel_0.duty_cycle = 0 #ligar LED 100% time.sleep (0,5) led_channel_0.duty_cycle = 0xffff #ligar LED 100% time.sleep (0.1) def JumpingJack3 (self): # controla a dança do Jumping Jack, palavra-chave: "jogo aleatório" # para h no intervalo (10): dr = randrange (9) p = posição [dr] a = p [0] b = p [1] kit.servo [lft].angle = a kit.servo [rgt].angle = b time.sleep (0.25) # define a velocidade dos movimentos do observador (self, args): engine = BasicEngine (args.model_file) mic = args.mic if args.mic is None else int (args.mic) model.classify_audio (mic, engine, labels_file = "config / labels_gc2.raw.txt", command_file = "config / command_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):

se não self.on_init (): self._running = False q = model.get_queue () self._controler = Controler (q) se não 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 (Verdadeiro, 0,1) exceto queue. Empty: new_item = None se new_item não for None: item = new_item if (args.debug_keyboard e keys [pygame. K_ESCAPE]) ou item == "stop": self._running = False # if (args.debug_keyboard e keys [pygame. K_SPACE]) ou item == "go": # self. JumpingJack0 (7) # if (args.debug_keyboard and keys [pygame. K_RIGHT]) ou item == "right": self. JumpingJack0 (6) if (args.debug_keyboard and keys [pygame. K_LEFT]) ou item == "left": self. JumpingJack0 (4) if (args.debug_keyboard and keys [pygame. K_UP]) ou item == " up ": self. JumpingJack0 (1) if (args.debug_keyboard and keys [pygame. K_DOWN]) ou item ==" down ": self. JumpingJack0 (9) if (args.debug_keyboard and keys [pygam e. K_0]) ou item == "0": self. JumpingJack0 (0) if (args.debug_keyboard e keys [pygame. K_1]) ou item == "1": self. JumpingJack0 (1) if (args. debug_keyboard and keys [pygame. K_2]) ou item == "2": self. JumpingJack0 (2) if (args.debug_keyboard and keys [pygame. K_3]) ou item == "3": self. JumpingJack0 (3) if (args.debug_keyboard e keys [pygame. K_4]) ou item == "4": self. JumpingJack0 (4) if (args.debug_keyboard e keys [pygame. K_5]) ou item == "5": self. JumpingJack0 (5) if (args.debug_keyboard and keys [pygame. K_6]) ou item == "6": self. JumpingJack0 (6) if (args.debug_keyboard and keys [pygame. K_7]) ou item == "7 ": self. JumpingJack0 (7) if (args.debug_keyboard and keys [pygame. K_8]) ou item ==" 8 ": self. JumpingJack0 (8) if (args.debug_keyboard and keys [pygame. K_9]) ou item == "9": self. JumpingJack0 (9) if (args.debug_keyboard and keys [pygame. K_a]) ou item == "d": self. JumpingJack1 () #dancing Jack, em "next_game" if (args. debug_keyboard e keys [pygame. K_j]) ou item == "j": self. JumpingJack2 (0) #LED on, ON " switch_on "if (args.debug_keyboard and keys [pygame. K_k]) ou item ==" k ": self. JumpingJack2 (1) #LED off, on" swithch off "if (args.debug_keyboard e keys [pygame. K_l]) ou item == "l": self. JumpingJack2 (1) #LED pisca "target" if (args.debug_keyboard e keys [pygame. K_r]) ou item == "r": self. JumpingJack3 () # dança aleatória "jogo aleatório" time.sleep (0.05) self.on_cleanup () if _name_ == '_main_': parser = argparse. ArgumentParser () parser.add_argument ('- debug_keyboard', help = 'Use o teclado para controlar o JumpingJack. ', action =' store_true ', default = False) model.add_model_flags (parser) args = parser.parse_args () the_app = App () the_app.on_execute (args)

Também existe o arquivo de configuração de comando "command_v2_hampelmann.txt". Modifique como quiser. É apenas uma lista de combinações de "comando, chave, (força)", com base no arquivo de rótulo.

posição_zero, 0, posição_um, 1, posição_dois, 2, posição_três, 3, posição_quatro, 4, posição_five, 5, posição_eixo, 6, posição_espeito, 7, posição_eito, 8, posição_nina, 9, move_up, up, go_up, up, move_down, down, go_down, down, move_backwards, left, move_forwards, right, go_backwards, left, go_forwards, right, 0.8 target, l, mute, z, sim, y, não, n, switch_on, j, switch_off, k, volume_up, up, volume_down, down, next_game, d, random_game, r, start_game, s, stop_game, ctrl + c,

Etapa 4: Outras Idéias e Outros Exemplos

É bastante óbvio que essa configuração também pode ser usada para controlar robôs ou outros dispositivos. Basicamente, tudo o que pode ser controlado por um Raspberry Pi.

Estou trabalhando em uma extensão do script para conduzir um MeArm e espero poder apresentá-lo em outubro de 2019.

Também estou considerando usar o Jumping Jack como um semáforo, e usar o programa de reconhecimento da posição do membro "posenet de projeto" como uma ferramenta para ler as posições do Jumping Jack e traduzi-las de volta para um número. Desta forma pode até comunicar texto, dado que 2x 8 posições podem indicar 64 números diferentes, mais do que suficientes para alfabeto, números e sinais. Isso poderia permitir, embora ligeiramente modificado, uma realização física para o IETF proposto "A transmissão de datagramas IP sobre o sistema de sinalização de sinalização de semáforo (SFSS)" (https://tools.ietf.org/html/rfc4824).

Mas este será outro instrutível. E, como os primeiros experimentos indicaram que o jumping jack precisará de modificações significativas antes de ser reconhecido como humano pelo sistema de IA, pode levar algum tempo.

Gostaria de chamar sua atenção para o seguinte instrutível: Object-Finding-Personal-Assistant-Robot-Ft-Raspberry, onde um robô localizador de objetos usando uma combinação de Raspberry Pi e Google Coral TPU é descrito.

Recomendado: