Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen RevisionVorhergehende Überarbeitung | |||
rollstuhlsteuerung_per_eyetracking [2019/06/19 14:52] – student | rollstuhlsteuerung_per_eyetracking [2023/07/03 10:16] (aktuell) – Externe Bearbeitung 127.0.0.1 | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
+ | ====== Rollstuhlsteuerung per Eye-Tracking ====== | ||
+ | |||
+ | ==== Beschreibung: | ||
+ | Eine Kamerabrille, | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ==== Bauteile: ==== | ||
+ | **• Raspberry Pi 3\\ | ||
+ | • Raspicam\\ | ||
+ | • DC Motoren\\ | ||
+ | • 12V Batterie\\ | ||
+ | • Powerbank\\ | ||
+ | • Taster\\ | ||
+ | • Potentiometer\\ | ||
+ | • ADC\\ | ||
+ | • Brille mit Kamerahalterung\\ | ||
+ | • H-Brücke** | ||
+ | |||
+ | ==== Fritzing: ==== | ||
+ | {{: | ||
+ | |||
+ | ==== Code-Ausschnitte: | ||
+ | <file python eye_tracking.py> | ||
+ | import cv2 | ||
+ | import numpy as np | ||
+ | |||
+ | |||
+ | def get_position(x_value, | ||
+ | cap = cv2.VideoCapture(0)# | ||
+ | cap.set(11, 200)# kontrast | ||
+ | | ||
+ | while True: | ||
+ | cap.set(10, brightness.value)# | ||
+ | ret, frame = cap.read() # | ||
+ | if ret is False: | ||
+ | break | ||
+ | | ||
+ | roi = frame[100: | ||
+ | #roi = frame[269: 795, 537: 1416] | ||
+ | | ||
+ | #zur Suche der Koordinaten, | ||
+ | rows, cols, _ = roi.shape | ||
+ | gray_roi = cv2.cvtColor(roi, | ||
+ | gray_roi = cv2.GaussianBlur(gray_roi, | ||
+ | | ||
+ | #mit Hile von openCV koordinaten der Pupille ermitteln | ||
+ | _, threshold = cv2.threshold(gray_roi, | ||
+ | contours,_ = cv2.findContours(threshold, | ||
+ | contours = sorted(contours, | ||
+ | |||
+ | for cnt in contours: | ||
+ | (x, y, w, h) = cv2.boundingRect(cnt)# | ||
+ | | ||
+ | x_value.value = int(x) #x koordinate der Pupille an die Steuerung uebergeben | ||
+ | | ||
+ | #zeichnen der vertikalen und horizontalen | ||
+ | # | ||
+ | cv2.rectangle(roi, | ||
+ | cv2.line(roi, | ||
+ | cv2.line(roi, | ||
+ | break | ||
+ | | ||
+ | # | ||
+ | # | ||
+ | cv2.imshow(" | ||
+ | #anzeigen des Eyetrackings | ||
+ | | ||
+ | key = cv2.waitKey(30) | ||
+ | if key == 27: | ||
+ | break | ||
+ | </ | ||
+ | |||
+ | <file python Steuerung.py> | ||
+ | import Eye_tracking as et | ||
+ | import Taster | ||
+ | from time import sleep | ||
+ | import multiprocessing as mp | ||
+ | from ctypes import c_bool | ||
+ | import Rover | ||
+ | import Poti | ||
+ | import RPi.GPIO as GPIO | ||
+ | |||
+ | try: | ||
+ | x = mp.Value(' | ||
+ | taster_value = mp.Value(c_bool, | ||
+ | v = mp.Array(' | ||
+ | brightness = mp.Value(' | ||
+ | |||
+ | # | ||
+ | tracking = mp.Process(target=et.get_position, | ||
+ | taster = mp.Process(target=Taster.switch_OnOff, | ||
+ | rover = mp.Process(target=Rover.rover, | ||
+ | poti = mp.Process(target=Poti.get_value, | ||
+ | |||
+ | poti.start() | ||
+ | tracking.start() | ||
+ | taster.start() | ||
+ | |||
+ | |||
+ | #Motoren mit v=0 starten | ||
+ | v[0] = 0 | ||
+ | v[1] = 0 | ||
+ | rover.start() | ||
+ | |||
+ | #" | ||
+ | #50 160 290 | ||
+ | #max wert rechts: 50 | ||
+ | #max wert links: 290 | ||
+ | |||
+ | while True: | ||
+ | while taster_value.value == True: #sobald start/ | ||
+ | if(x.value > 0 and x.value > 50 and x.value < 290): #Wenn Position der Pupille erkannt wird | ||
+ | if(x.value < 140): | ||
+ | # | ||
+ | v[0] = 50 | ||
+ | v[1] = 25 | ||
+ | # | ||
+ | elif(x.value > 180): | ||
+ | # fahre nach links | ||
+ | v[0] = 25 | ||
+ | v[1] = 50 | ||
+ | # | ||
+ | elif(x.value > 140 and x.value < 180): | ||
+ | #fahre geradeaus | ||
+ | v[0] = 50 | ||
+ | v[1] = 50 | ||
+ | print(" | ||
+ | else:# | ||
+ | v[0] = 0 | ||
+ | v[1] = 0 | ||
+ | #anhalten wenn start/ | ||
+ | v[0] = 0 | ||
+ | v[1] = 0 | ||
+ | except KeyboardInterrupt: | ||
+ | print(" | ||
+ | poti.terminate() | ||
+ | taster.terminate() | ||
+ | tracking.terminate() | ||
+ | rover.terminate() | ||
+ | GPIO.cleanup() | ||
+ | </ | ||
+ | |||
+ | <file python Poti.py> | ||
+ | import spidev | ||
+ | from time import sleep | ||
+ | import RPi.GPIO as gpio | ||
+ | |||
+ | gpio.setmode(gpio.BCM) | ||
+ | gpio.setup(18, | ||
+ | gpio.output(18, | ||
+ | |||
+ | spi = spidev.SpiDev() | ||
+ | spi.open(0, | ||
+ | spi.max_speed_hz=1000000 | ||
+ | |||
+ | def readMCP3008(channel):# | ||
+ | adc=spi.xfer2([1, | ||
+ | wert = ((adc[1]& | ||
+ | return wert | ||
+ | |||
+ | def get_value(value): | ||
+ | while True: #frage zweimal pro Sekunde den Wert des Reglers ab | ||
+ | v=readMCP3008(0) # A/D Wandler auf Channel 0 auslesen; v entspricht einer Zahl zwischen 0 und 1023 | ||
+ | p = int((v/ | ||
+ | value.value = p # | ||
+ | sleep (0.5) | ||
+ | |||
+ | </ | ||
+ | |||
+ | ==== Anmerkung: ==== | ||
+ | ** Die Motoren werden per PWM gesteuert. Anleitungen dazu sind im Wiki vorhanden.\\ | ||
+ | Die Methode erwartet ein Array v. v[0] = Geschwindigkeit linker Motor; v[1] = Geschwindigkeit rechter Motor\\ | ||
+ | Im Array v ist der Wert für die Steuerung per PWM gespeichert.\\ | ||
+ | |||
+ | |||
+ | Anleitungen für den Taster befinden sich ebenfalls im Wiki. Hierbei ist ein Pulldown Widerstand zu verwenden\\ | ||
+ | Darüber hinaus sollte der Taster entprellt werden** |