Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende Überarbeitung | ||
| rollstuhlsteuerung_per_eyetracking [2019/06/19 14:17] – 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** | ||