Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

Smart Face Tracking Robot Car

Componenten en benodigdheden

Creator Ci20
× 1
SparkFun Dual H-Bridge motordrivers L298
× 1
Li-ion batterij 1000mAh
× 1
Servo's (Tower Pro MG996R)
× 2
Camera (algemeen)
× 1
Dexter Industries GoPiGo-robotbasisset
× 1
Arduino Nano R3
× 1
Ultrasone sensor - HC-SR04 (algemeen)
× 1

Apps en online services

Arduino IDE
OpenCV

Over dit project

Het is een auto die je gezicht volgt, als ik weg ben komt hij!

U moet dit hebben geïnstalleerd (Ci20):

  • Opencv
  • Python
  • Machtigingen voor seriële poortcorrectie

Ik gebruikte de distro Debian 8 install &download

Ik gebruikte:

  • Oude laptopcamera (gerecycled)
  • Ultrasone bereikmodule HC - SR04
  • x2 batterij 3.7v 4000mah (gerecyclede oude laptop)
  • x2 servo
  • DC-DC-omzetter
  • Arduino nano
  • Robotbasiskit
  • x2 L298d

Gebruik voor de installatie de volgende commando's in de terminal.

Linux bijwerken.

sudo apt-get update # Haalt de lijst met beschikbare updates op sudo apt-get upgrade # Upgradet strikt de huidige pakkettensudo apt-get dist-upgrade # Installeert updates (nieuwe) 

Open CV. Het is de versie 2.4.9.1 die niet up-to-date is, maar het werkt prima.

sudo apt-get install libopencv-dev python-opencv 

Als je OpenCV vanaf de bron wilt compileren, heb ik deze tutorial gevonden.

Installeer PySerial.

sudo apt-get install python python-serial 

We wijzigen de machtigingen voor de seriële poort, als je de USB of een native hebt gebruikt.

sudo chown ci20:ci20 /dev/ttyUSB0 #Seriële poort USB van Arduinosudo chown ci20:ci20 /dev/ttyS1 #Seriële poort native in Ci20 

Voert het python-script uit (verandert de nul als je meer dan één videobron hebt, dit selecteert de bron).

sudo python facetrackingcar.py 0 

Om de prestaties enigszins te verbeteren, wordt de vastgelegde afbeelding niet weergegeven. Als u deze wilt zien, moet u deze regels zoeken en verwijderen.

#cv.ShowImage("result", img)#cv.NamedWindow("result", 1)#cv.DestroyWindow("result") 

U moet de haarcascade_frontalface_alt.xml . hebben bestand in dezelfde map als het script.

Video voor alleen volgcamera in Windows

Demovideo op Ci20

Feedback en verbeteringen zijn welkom.

Code

  • faceser.py
  • Car.ino
  • scanlinux.py
faceser.pyPython
Python scrip OpenCV face traking
#!/usr/bin/python"""Dit programma is een demonstratie voor gezichts- en objectdetectie met behulp van haar-achtige functies. Het programma vindt gezichten in een camerabeeld of videostream en geeft een rood kader weer om hen heen, centreert vervolgens de webcam via twee servo's zodat het gezicht in het midden van het scherm staat. Van de API:# De standaardparameters (scale_factor=2, min_neighbors=3, flags=0) zijn afgestemd# voor nauwkeurige maar langzame objectdetectie. Voor een snellere bewerking op echte video# afbeeldingen zijn de instellingen:# scale_factor=1.2, min_neighbors=2, flags=CV_HAAR_DO_CANNY_PRUNING,# min_size=>> servo.move(2, 90) ... # "move servo #2 to 90 graden"''' if (min_pwm <=hoek <=max_pwm):ser.write(chr(255)) ser.write(chr(servo)) ser.write(chr(angle)) else:print "Servo hoek moet een geheel getal zijn tussen 0 en 180.\n"if __name__ =='__main__':ser=serial.Serial(port='/dev/ttyUSB0',baudrate=115200,timeout=1) #ser=serial.Serial (port='/dev/ttyS0',baudrate=115200,timeout=1) #ser=serial.Serial(port='COM14',baudrate=115200,timeout=1) # ontleden cmd-regelopties, setup Haar classifier parser =OptionParser(usage ="usage:%prog [options] [camera_index]") parser.add_option("-c", "--cascade", action="store", dest="cascade", type="str", help="Haar-cascadebestand, standaard %default", default ="./haarcascade_frontalface_alt.xml") (opties, args) =parser.parse_args() cascade =cv.Load(options.cascade) if len(args) !=1:parser.print_help() sys.exit(1) input_name =arg s[0] if input_name.isdigit():capture =cv.CreateCameraCapture(int(input_name)) cv.SetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_WIDTH, 320) cv.SetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_HEIGHT ", 240) We hebben een camera-ingang nodig! Specificeer camera-index b.v. 0" sys.exit(0) # cv.NamedWindow("result", 1) if capture:frame_copy =Geen move(panGpioPin, servoPanPosition) move(tiltGpioPin, servoTiltPosition) while True:start =time.time() frame =cv .QueryFrame(capture) indien niet frame:cv.WaitKey(0) break indien niet 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, cascade) als midFace niet Geen is:midFaceX =midFace[0] midFaceY =midFace[1] #Zoek uit of de X-component van het gezicht zich links van het midden van het scherm bevindt. if(midFaceX <(midScreenX - midScreenWindow)):#Werk de pan-positievariabele bij om de servo naar rechts te verplaatsen servoPanPosition +=panStepSize print str(midFaceX) + "> " + str(midScreenX) + ":Pan Right :" + str(servoPanPosition) #Zoek uit of de X onderdeel van het gezicht is naar de r rechts van het midden van het scherm. elif(midFaceX> (midScreenX + midScreenWindow)):#Update de pan-positievariabele om de servo naar links te verplaatsen. 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) #Zoek uit of de Y-component van het gezicht zich onder het midden van het scherm bevindt. if(midFaceY <(midScreenY - midScreenWindow)):if(servoTiltPosition <=90):#Update de kantelpositievariabele om de kantelservo te verlagen. servoTiltPosition -=tiltStepSize print str(midFaceY) + "> " + str(midScreenY) + " :Tilt Down :" + str(servoTiltPosition) #Zoek uit of de Y-component van het gezicht zich boven het midden van het scherm bevindt. elif(midFaceY> (midScreenY + midScreenWindow)):if(servoTiltPosition>=1):#Update de kantelpositievariabele om de kantelservo te verhogen. servoTiltPosition +=tiltStepSize print str(midFaceY) + " <" + str(midScreenY) + " :Tilt Up :" + str(servoTiltPosition) start =1; einde =1; else:print str(midFaceY) + " ~ " + str(midScreenY) + ":" + str(servoTiltPosition) servoTiltPosition =min(servoTiltPosition, max_pwm) servoTiltPosition =max(servoTiltPosition, min_pwm) move(tiltGpioPin) else einde meten tijd einde =time.time()+0.1 var +=0.1 # ophalen van verstreken tijd time_elapsed =int(end - start + var) # printinformatie 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 vertragingspauze #cv.DestroyWindow("resultaat")
Car.inoArduino
#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// Gebruikersinvoer voor servo en positionServo servoy;Servo servox;int x =90, prevX;int y =45, prevY;int userInput[3]; // onbewerkte invoer van seriële buffer, 3 bytes in startbyte; // start byte, begin inputint servo te lezen; // welke servo moet pulseren?int pos; // servohoek 0-180int i; // iteratorint State =LAAG; unsigned long previousMillis =0 , val =100;;const long interval =100; bool scana =false; unsigned long currentMillis; void setup () { inicializate (); currentMillis =millis();}void loop() {// Wacht op seriële invoer (min 3 bytes in buffer) if (Serial.available()> 2) { // Lees de eerste byte startbyte =Serial.read(); // Als het echt de startbyte is (255) ... if (startbyte ==255) { // ... haal dan de volgende twee bytes op voor (i =0; i <2; i++) {userInput[i] =Serieel.lezen(); } // Eerste byte =servo om te verplaatsen? servo =gebruikersinvoer [0]; // Tweede byte =welke positie? pos =gebruikersinvoer [1]; // Pakketfoutcontrole en herstel als (pos ==255) {servo =255; } // Wijs een nieuwe positie toe aan de juiste servoschakelaar (servo) { geval 1:servoy.write (pos); // verplaats servo1 naar 'pos' break; geval 2:servox.write(pos); bereik (pos); pauze; geval 3:scannen(45); scannen(65); pauze; standaard:pauze; } } }} ongeldige scan (int val) { while (Serial.available() ==0) { servoy.write(val); unsigned long currentMillis =millis(); if (currentMillis - previousMillis>=interval) { previousMillis =currentMillis; servox.write(pos); if (Status ==LAAG) { pos +=1; if (pos ==130) { Staat =HOOG; } } else { pos -=1; if (pos ==40) { Staat =LAAG; pauze; } } } }}lange afstand() { lange duur, afstand; digitalWrite(trigPin, LAAG); // Toegevoegd deze regel vertraging Microseconden (2); // Deze regel toegevoegd digitalWrite (trigPin, HIGH); vertraging Microseconden (10); // Deze regel toegevoegd digitalWrite (trigPin, LOW); duur =pulseIn(echoPin, HOOG); afstand =(duur / 2) / 29,1; retourafstand;} ongeldig bereik (int pos) { if ((pos>=80 ) &(pos <=100)) { moves(); } else if ((pos>=100 ) &(pos <=180)) { left(); vertraging(10); Stoppen(); } else if ((pos>=1 ) &(pos <=80)) { right(); vertraging(10); Stoppen(); }}void moves() { long distance, previusdistance; afstand =afstand(); if (val <=80) { reverse(); vertraging (50); Stoppen(); } else if (val>=140) { forward(); vertraging (50); Stoppen(); } if (afstand>=vorige afstand) { val =(afstand - vorige afstand); } else if (afstand <=vorige afstand) { val =(vorige afstand - afstand); } previusdistance =afstand;}void inicializate() { Serial.begin(115200); pinMode(MA_1, UITGANG); pinMode (MA_2, UITGANG); pinMode(MB_1, UITGANG); pinMode (MB_2, UITGANG); pinMode (MC_1, UITGANG); pinMode (MC_2, UITGANG); pinMode(MD_1, UITGANG); pinMode (MD_2, UITGANG); pinMode (trigPin, UITGANG); pinMode (echoPin, INPUT); servox.attach (SERVOX_PIN); servoy.attach(SERVOY_PIN);}void forward() {digitalWrite(MA_1, HIGH); digitalWrite (MA_2, LAAG); digitalWrite(MB_1, HOOG); digitalWrite (MB_2, LAAG); digitalWrite(MC_1, HOOG); digitalWrite (MC_2, LAAG); digitalWrite(MD_1, HOOG); digitalWrite (MD_2, LAAG);} ongeldig omgekeerd () { digitalWrite (MA_1, LAAG); digitalWrite (MA_2, HOOG); digitalWrite(MB_1, LAAG); digitalWrite(MB_2, HOOG); digitalWrite(MC_1, LAAG); digitalWrite (MC_2, HOOG); digitalWrite(MD_1, LAAG); digitalWrite (MD_2, HOOG);} ongeldig recht () { digitalWrite (MA_1, LAAG); digitalWrite (MA_2, HOOG); digitalWrite(MB_1, LAAG); digitalWrite(MB_2, HOOG); digitalWrite(MC_1, HOOG); digitalWrite (MC_2, LAAG); digitalWrite(MD_1, HOOG); digitalWrite(MD_2, LOW);}void left() { digitalWrite(MA_1, HIGH); digitalWrite (MA_2, LAAG); digitalWrite(MB_1, HOOG); digitalWrite (MB_2, LAAG); digitalWrite(MC_1, LAAG); digitalWrite (MC_2, HOOG); digitalWrite(MD_1, LAAG); digitalWrite(MD_2, HIGH);}void Stop() {digitalWrite(MA_1, LOW); digitalWrite (MA_2, LAAG); digitalWrite(MB_1, LAAG); digitalWrite (MB_2, LAAG); digitalWrite(MC_1, LAAG); digitalWrite (MC_2, LAAG); digitalWrite(MD_1, LAAG); digitalWrite(MD_2, LOW);}void StopH() {digitalWrite(MA_1, HIGH); digitalWrite (MA_2, HOOG); digitalWrite(MB_1, HOOG); digitalWrite(MB_2, HOOG); digitalWrite(MC_1, HOOG); digitalWrite (MC_2, HOOG); digitalWrite(MD_1, HOOG); digitalWrite(MD_2, HIGH);}
scanlinux.pyPython
Scan linux seriële poorten
#! /usr/bin/env python"""\Scannen naar seriële poorten. Linux-specifieke variant die ook USB/Serialadapters bevat. Onderdeel van pySerial (http://pyserial.sf.net)(C) 2009 """import serialimport globdef scan():"""scan naar beschikbare poorten. retourneer een lijst met apparaatnamen. pvergain@houx:~/PDEV1V160_CodesRousseau/Soft/PC/test_boost/serialport/pyserial$ python scanlinux.py Poorten gevonden :/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__':print "Found ports:" voor naam in scan():print naam

Aangepaste onderdelen en behuizingen

Python-script OpenCV face traking en Arduino-code FaceTrakingCar.rar

Schema's

Als u de Arduino gebruikt om motoren en servo's te besturen, kan de pin-out variëren.

Productieproces

  1. Arduino digitale dobbelstenen
  2. DIY 37 LED Roulette Game
  3. ATtiny85 Mini Arcade:Snake
  4. Draagbare afstandsdetector
  5. MobBob:doe-het-zelf Arduino-robot bestuurd door Android-smartphone
  6. Arduino-gestuurde pianorobot:PiBot
  7. galvaniseren met koper
  8. NeoMatrix Arduino Pong
  9. Omnidirectionele mensen volgen vriendelijke robot
  10. Light Sequence Creator
  11. Slimme deur met gezichtsontgrendeling