Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

Carro robô rastreador Smart Face

Componentes e suprimentos

Criador Ci20
× 1
Drivers de motor SparkFun Dual H-Bridge L298
× 1
Bateria Li-Ion 1000mAh
× 1
Servos (Tower Pro MG996R)
× 2
Câmera (genérica)
× 1
Kit de base do robô GoPiGo Dexter Industries
× 1
Arduino Nano R3
× 1
Sensor ultrassônico - HC-SR04 (genérico)
× 1

Aplicativos e serviços online

Arduino IDE
OpenCV

Sobre este projeto


É um carro que rastreia seu rosto, se eu for embora ele vem!

Você precisa ter instalado este (Ci20):
  • Opencv
  • Python
  • Permissões de correção de porta serial

Usei a distro Debian 8 install & download

Eu usei:
  • Câmera de laptop antiga (reciclada)
  • Módulo de alcance ultrassônico HC - SR04
  • Bateria x2 3.7v 4000mah (laptop velho reciclado)
  • x2 Servo
  • conversor DC-DC
  • Arduino nano
  • Kit de base do robô
  • x2 L298d

Para instalação, use os seguintes comandos no terminal.

Para atualizar o Linux.
  sudo apt-get update # Busca a lista de atualizações disponíveis. 

OpenCV. É a versão 2.4.9.1 que não está atualizada, mas funciona bem.
  sudo apt-get install libopencv-dev python-opencv  

Se você deseja compilar o OpenCV a partir do código-fonte, encontrei este tutorial.

Instale o PySerial.
  sudo apt-get install python python-serial  

Mudamos as permissões da porta serial, se você usou o USB ou um nativo.
  sudo chown ci20:ci20 / dev / ttyUSB0 #Porta serial USB de Arduinosudo chown ci20:ci20 / dev / ttyS1 #Porta serial nativa em Ci20  

Executa o script python (muda o zero se você tiver mais de uma fonte de vídeo, isso seleciona a fonte).
  sudo python facetrackingcar.py 0  

Para melhorar um pouco o desempenho, a imagem capturada não é exibida se você quiser ver, você deve pesquisar e descomentar essas linhas.
  # cv.ShowImage ("result", img) # cv.NamedWindow ("result", 1) # cv.DestroyWindow ("result")  

Você precisa ter o haarcascade_frontalface_alt.xml arquivo no mesmo diretório que o script.

Vídeo apenas para câmera de rastreamento no Windows

Vídeo de demonstração no Ci20

Feedback e melhorias são bem-vindos.

Código

  • faceser.py
  • Car.ino
  • scanlinux.py
faceser.py Python
Script Python OpenCV face traking
 #! / Usr / bin / python "" "Este programa é uma demonstração para detecção de rosto e objeto usando recursos do tipo haar. O programa encontra rostos em uma imagem de câmera ou vídeo e exibe uma caixa vermelha em torno deles, em seguida, centraliza a webcam por meio de dois servos de modo que o rosto fique no centro da telaBaseado emidedetect.py no diretório de amostras OpenCV "" "import sysfrom optparse import OptionParserimport serialimport cv2.cv como cvimport time # Parâmetros para detecção de haar # Da API:# Os parâmetros padrão (scale_factor =2, min_neighbors =3, flags =0) são ajustados # para detecção de objetos precisa, porém lenta. Para uma operação mais rápida no vídeo real # imagens, as configurações são:# scale_factor =1.2, min_neighbors =2, flags =CV_HAAR_DO_CANNY_PRUNING, # min_size =>> servo.move (2, 90) ... # "move o servo # 2 a 90 graus "'' 'if (min_pwm <=ângulo <=max_pwm):ser.write (chr (255)) ser.write (chr (servo)) ser.write (chr (ângulo)) else:print" Servo ângulo deve ser um número inteiro entre 0 e 180. \ n "if __name__ =='__main__':ser =serial.Serial (port ='/ dev / ttyUSB0', baudrate =115200, tempo limite =1) # ser =serial.Serial (port ='/ dev / ttyS0', baudrate =115200, timeout =1) # ser =serial.Serial (port ='COM14', baudrate =115200, timeout =1) # parse cmd line options, setup Haar classifier parser =OptionParser (usage ="usage:% prog [options] [camera_index]") parser.add_option ("- c", "--cascade", action ="store", dest ="cascade", type ="str", help ="Arquivo em cascata Haar, default% default", default ="./haarcascade_frontalface_alt.xml") (options, args) =parser.parse_args () cascade =cv.Load (options.cascade) if len (args)! =1:parser.print_help () sys.exit (1) input_name =arg s [0] se input_name.isdigit ():capture =cv.CreateCameraCapture (int (input_name)) cv.SetCaptureProperty (capture, cv.CV_CAP_PROP_FRAME_WIDTH, 320) cv.SetCaptureProperty (captura, cv.CV_CAPTREP_FRAME) Precisamos de uma entrada de câmera! Especifique o índice da câmera, por exemplo 0 "sys.exit (0) # cv.NamedWindow (" result ", 1) if capture:frame_copy =None move (panGpioPin, servoPanPosition) move (tiltGpioPin, servoTiltPosition) enquanto True:start =time.time () frame =cv .QueryFrame (captura) se não for frame:cv.WaitKey (0) break se não frame_copy:frame_copy =cv.CreateImage ((frame.width, frame.height), cv.IPL_DEPTH_8U, frame.nChannels) if frame.origin ==cv.IPL_ORIGIN_TL:cv.Copy (frame, frame_copy) else:cv.Flip (frame, frame_copy, 0) midScreenX =(frame.width / 2) midScreenY =(frame.height / 2) midFace =detect_and_draw (frame_copy, cascata) se midFace não for Nenhum:midFaceX =midFace [0] midFaceY =midFace [1] #Descubra se o componente X do rosto está à esquerda do meio da tela. if (midFaceX <(midScreenX - midScreenWindow)):#Atualize a variável de posição panorâmica para mover o servo para a direita. ServoPanPosition + =panStepSize print str (midFaceX) + ">" + str (midScreenX) + ":Pan Right:" + str (servoPanPosition) #Descubra se o X componente da face é para r direito do meio da tela. elif (midFaceX> (midScreenX + midScreenWindow)):#Atualize a variável de posição panorâmica para mover o servo para a esquerda. servoPanPosition - =panStepSize print str (midFaceX) + "<" + str (midScreenX) + ":Pan Left:" + str (servoPanPosition) else:print str (midFaceX) + "~" + str (midScreenX) + ":" + str (servoPanPosition) servoPanPosition =min (servoPanPosition, max_pwm) servoPanPosition =max (servoPanPosition, min_pwm) move (panGpioPin, servoPanPosition) #Descubra se o componente Y da face está abaixo do meio da tela. if (midFaceY <(midScreenY - midScreenWindow)):if (servoTiltPosition <=90):#Atualize a variável de posição de inclinação para diminuir o servo de inclinação. servoTiltPosition - =tiltStepSize print str (midFaceY) + ">" + str (midScreenY) + ":Tilt Down:" + str (servoTiltPosition) #Descubra se o componente Y do rosto está acima do meio da tela. elif (midFaceY> (midScreenY + midScreenWindow)):if (servoTiltPosition> =1):#Atualize a variável de posição de inclinação para aumentar o servo de inclinação. servoTiltPosition + =tiltStepSize imprimir str (midFaceY) + "<" + str (midScreenY) + ":Inclinação para cima:" + str (servoTiltPosition) start =1; fim =1; else:print str (midFaceY) + "~" + str (midScreenY) + ":" + str (servoTiltPosition) servoTiltPosition =min (servoTiltPosition, max_pwm) servoTiltPosition =max (servoTiltPosition, min_pwm) move (tiltGpiltPosition) elseTos:fim do tempo de medição end =time.time () + 0.1 var + =0.1 # obtendo o tempo decorrido time_elapsed =int (end - start + var) # imprimindo informações print 'time elapsed:\ t {}'. format (time_elapsed) print ' var:\ t {} '. format (var) if time_elapsed ==20:move (3, servoTiltPosition) servoPanPosition =90 servoTiltPosition =45 var =0; if cv.WaitKey (1)> =0:# 1ms de intervalo de atraso # cv.DestroyWindow ("result") 
Car.ino Arduino
 #include  #define MA_1 2 # define MA_2 3 # define MB_1 4 # define MB_2 5 # define MC_1 6 # define MC_2 7 # define MD_1 8 # define MD_2 9 # define SERVOX_PIN 11 # define SERVOY_PIN 10 # define trigPin 13 # define echoPin 12 // Entrada do usuário para servo e positionServo servoy; Servo servox; int x =90, prevX; int y =45, prevY; int userInput [3]; // entrada bruta do buffer serial, 3 bytesint startbyte; // inicia o byte, começa a ler inputint servo; // qual servo deve ser pulsado? int pos; // ângulo do servo 0-180int i; // iteratorint State =LOW; unsigned long previousMillis =0, val =100;; const long interval =100; bool scana =false; unsigned long currentMillis; void setup () {inicializate (); currentMillis =millis ();} void loop () {// Espera pela entrada serial (mín. 3 bytes no buffer) if (Serial.available ()> 2) {// Lê o primeiro byte startbyte =Serial.read (); // Se for realmente o byte inicial (255) ... if (byte inicial ==255) {// ... então obtenha os próximos dois bytes para (i =0; i <2; i ++) {userInput [i] =Serial.read (); } // Primeiro byte =servo para mover? servo =userInput [0]; // Segundo byte =qual posição? pos =userInput [1]; // Verificação de erro de pacote e recuperação if (pos ==255) {servo =255; } // Atribuir uma nova posição ao servo switch (servo) apropriado {case 1:servoy.write (pos); // move servo1 para 'pos' break; caso 2:servox.write (pos); alcance (pos); pausa; caso 3:varredura (45); digitalizar (65); pausa; padrão:break; }}}} void scan (int val) {while (Serial.available () ==0) {servoy.write (val); currentMillis longo sem sinal =millis (); if (currentMillis - previousMillis> =intervalo) {previousMillis =currentMillis; servox.write (pos); if (Estado ==BAIXO) {pos + =1; if (pos ==130) {State =HIGH; }} else {pos - =1; if (pos ==40) {State =LOW; pausa; }}}}} longa distancia () {longa duração, distância; digitalWrite (trigPin, LOW); // Adicionada esta linha delayMicroseconds (2); // Adicionada esta linha digitalWrite (trigPin, HIGH); atrasoMicrosegundos (10); // Adicionada esta linha digitalWrite (trigPin, LOW); duração =pulseIn (echoPin, HIGH); distância =(duração / 2) / 29,1; distância de retorno;} intervalo vazio (int pos) {if ((pos> =80) &(pos <=100)) {moves (); } else if ((pos> =100) &(pos <=180)) {left (); atraso (10); Pare(); } else if ((pos> =1) &(pos <=80)) {right (); atraso (10); Pare(); }} movimentos void () {longa distância, distância anterior; distância =distancia (); if (val <=80) {reverse (); atraso (50); Pare(); } else if (val> =140) {forward (); atraso (50); Pare(); } if (distance> =previusdistance) {val =(distance - previusdistance); } else if (distance <=previusdistance) {val =(previusdistance - distance); } previusdistance =distance;} void inicializado () {Serial.begin (115200); pinMode (MA_1, SAÍDA); pinMode (MA_2, OUTPUT); pinMode (MB_1, SAÍDA); pinMode (MB_2, SAÍDA); pinMode (MC_1, SAÍDA); pinMode (MC_2, SAÍDA); pinMode (MD_1, OUTPUT); pinMode (MD_2, SAÍDA); pinMode (trigPin, OUTPUT); pinMode (echoPin, INPUT); servox.attach (SERVOX_PIN); servoy.attach (SERVOY_PIN);} void forward () {digitalWrite (MA_1, HIGH); digitalWrite (MA_2, LOW); digitalWrite (MB_1, HIGH); digitalWrite (MB_2, LOW); digitalWrite (MC_1, HIGH); digitalWrite (MC_2, LOW); digitalWrite (MD_1, HIGH); digitalWrite (MD_2, LOW);} void reverse () {digitalWrite (MA_1, LOW); digitalWrite (MA_2, HIGH); digitalWrite (MB_1, BAIXO); digitalWrite (MB_2, HIGH); digitalWrite (MC_1, LOW); digitalWrite (MC_2, HIGH); digitalWrite (MD_1, LOW); digitalWrite (MD_2, HIGH);} void right () {digitalWrite (MA_1, LOW); digitalWrite (MA_2, HIGH); digitalWrite (MB_1, BAIXO); digitalWrite (MB_2, HIGH); digitalWrite (MC_1, HIGH); digitalWrite (MC_2, LOW); digitalWrite (MD_1, HIGH); digitalWrite (MD_2, BAIXO);} vazio à esquerda () {digitalWrite (MA_1, ALTO); digitalWrite (MA_2, LOW); digitalWrite (MB_1, HIGH); digitalWrite (MB_2, LOW); digitalWrite (MC_1, LOW); digitalWrite (MC_2, HIGH); digitalWrite (MD_1, LOW); digitalWrite (MD_2, HIGH);} void Stop () {digitalWrite (MA_1, LOW); digitalWrite (MA_2, LOW); digitalWrite (MB_1, BAIXO); digitalWrite (MB_2, LOW); digitalWrite (MC_1, LOW); digitalWrite (MC_2, LOW); digitalWrite (MD_1, LOW); digitalWrite (MD_2, LOW);} void StopH () {digitalWrite (MA_1, HIGH); digitalWrite (MA_2, HIGH); digitalWrite (MB_1, HIGH); digitalWrite (MB_2, HIGH); digitalWrite (MC_1, HIGH); digitalWrite (MC_2, HIGH); digitalWrite (MD_1, HIGH); digitalWrite (MD_2, HIGH);} 
scanlinux.py Python
Faça a varredura das portas seriais do Linux
 #! / usr / bin / env python "" "\ Procura por portas seriais. Variante específica do Linux que também inclui USB / Serialadapters.Part of pySerial (http://pyserial.sf.net) (C) 2009  "" "import serialimport globdef scan ():" "" verifica as portas disponíveis. retorna uma lista de nomes de dispositivos. pvergain @ houx:~ / PDEV1V160_CodesRousseau / Soft / PC / test_boost / serialport / pyserial $ python scanlinux.py Portas encontradas :/ dev / ttyS0 / dev / ttyS3 / dev / ttyS2 / dev / ttyS1 / dev / ttyACM0 / dev / serial / by-id / usb-id3_semiconductors_MEABOARD_00000000-if00 "" "return glob.glob ('/ dev / ttyS *' ) + glob.glob ('/ dev / ttyUSB *') + glob.glob ('/ dev / ttyACM *') + glob.glob ('/ dev / serial / by-id / *') if __name __ ==' __main__ ':imprime "Portas encontradas:" para o nome em scan ():imprime o nome 

Peças personalizadas e gabinetes

Python scrip OpenCV face traking e código Arduino FaceTrakingCar.rar

Esquemas

Usando o arduino para controlar motores e servos, a pinagem pode variar.

Processo de manufatura

  1. Dados digitais Arduino
  2. DIY 37 LED Roulette Game
  3. ATtiny85 Mini Arcade:Snake
  4. Detector de alcance portátil
  5. MobBob:DIY Arduino Robot Controlado por Smartphone Android
  6. Robô de piano controlado por Arduino:PiBot
  7. Galvanoplastia com cobre
  8. NeoMatrix Arduino Pong
  9. Robô Omni-Direcional para Rastreamento de Pessoas
  10. Criador de sequência de luzes