class TurnListener(threading.Thread): def __init__(self, bareSignals, bareSignalsLock): threading.Thread.__init__(self) self.bareSignals = bareSignals self.bareSignalsLock = bareSignalsLock self.sm = IPCMemory() self.smCounter = 0 self.knob = powermate.Powermate(devicePath) def run(self): print('Starting Listening Thread') self.startListening() def startListening(self): self.sum = 0 while True: self.checkSharedMemory() pollResult = self.knob.read_event(0) if pollResult is None: continue (time, event, val) = pollResult time = Decimal('{}'.format(time)).normalize() val = Decimal('{}'.format(val)).normalize() if event == EVENT_ROTATE: self.sum = Decimal(self.sum) + val event = RotationEvent(time, val, self.sum) elif event == EVENT_BUTTON: event = ButtonEvent(time, val) self.bareSignalsLock.acquire() self.bareSignals.append(event) self.bareSignalsLock.release() self.cleanUp() def checkSharedMemory(self): import time if self.smCounter < self.sm.getSize(): message = self.sm.get(self.smCounter) self.smCounter = self.smCounter + 1 if message == IPCMemory.SHUTDOWN: print('I shall shutdown') time.sleep(2) self.cleanUp() sys.exit() elif message == IPCMemory.NEW_MOTION: self.sum = 0 def cleanUp(self): print('McListener wird beendet')
class MicroControllerListener(threading.Thread): def __init__(self, signals, signalsLock): threading.Thread.__init__(self) self.signals = signals self.signalsLock = signalsLock self.sm = IPCMemory() self.smCounter = 0 self.knob = powermate.Powermate(devicePath) def run(self): print('Starting Listening Thread') self.startListening() def startListening(self): tapTimeStamp = None timeout = 0.5 self.sum = 0 while True: self.checkSharedMemory() pollResult = self.knob.read_event(0) if pollResult is None: continue (time, event, val) = pollResult time = Decimal('{}'.format(time)).normalize() val = Decimal('{}'.format(val)).normalize() if event == EVENT_ROTATE: self.sum = Decimal(self.sum) + val event = RotationEvent(time, val, self.sum) elif event == EVENT_BUTTON: event = ButtonEvent(time, val) #Check For Double Tap if event.getEvent() == EVENT_BUTTON and event.getValue( ) == Decimal('0'): if tapTimeStamp != None and (event.getTime() - tapTimeStamp) <= Decimal( '{}'.format(timeout)): pass tapTimeStamp = event.getTime() self.signalsLock.acquire() self.signals.append(event) self.signalsLock.release() self.cleanUp() #ATTENTION NOT THREAD SAFE! LOCK ME REQUIRED BEFORE AND RELEASED AFTER def aboart(self): counter = 0 for i in range(len(self.signals) - 1, -1, -1): if self.signals[i].getEvent() == EVENT_BUTTON and counter < 3: self.signals[i] = None counter = counter + 1 elif counter == 3: break def checkSharedMemory(self): import time if self.smCounter < self.sm.getSize(): message = self.sm.get(self.smCounter) self.smCounter = self.smCounter + 1 if message == IPCMemory.SHUTDOWN: print('I shall shutdown') time.sleep(2) self.cleanUp() sys.exit() elif message == IPCMemory.RESET_ROTATION_SUM: print('I shall reset the rotation sum') self.sum = 0 def cleanUp(self): print('McListener wird beendet')
class Executioner(threading.Thread): def __init__(self, signals, signalsLock): threading.Thread.__init__(self) self.signals = signals self.signalsLock = signalsLock self.signalsCounter = 0 self.sm = IPCMemory() self.smCounter = 0 self.motionManager = MotionManager() self.firstMotion = False ### #Teil der Bachelorarbeit self.subscriptionService = SubscriptionService() ### def run(self): print('Executioner is running') #Wenn keine Motions vorhanden sind if not self.motionManager.getAllMotions(): self.firstMotion = True print("Bitte die erste Geste anlernen") self.startLearning() self.firstMotion = False self.startExecution() def startExecution(self): self.sm.put(IPCMemory.NEW_MOTION) #ggf kurze wartezeit um sicherzustellen dass der befehl auch ankommt? while True: self.checkSharedMemory() self.signalsLock.acquire() if not self.signalsCounter < len(self.signals): self.signalsLock.release() continue event = self.signals[self.signalsCounter] self.signalsCounter = self.signalsCounter + 1 self.signalsLock.release() if isinstance(event, AboartEvent): ### #Bachelorarbeit self.removeRedundance() ### self.signalsLock.acquire() signalsCopy = self.signals[:] self.signalsLock.release() self.sm.put(IPCMemory.NEW_MOTION) self.startRecognition(signalsCopy) else: continue def startRecognition(self, signalsCopy): motion = self.transformMotion(signalsCopy) #Vergleiche die Motion mit allen anderen calculator = Calculator() knownMotions = self.motionManager.getAllMotions() bestMatch = None bestScore = None print('') for knownMotionName in knownMotions: knownMotion = self.motionManager.getMotion(knownMotionName) score = calculator.getMatchingScore(motion, knownMotion) print('{} - {} %'.format(knownMotionName, score)) if bestMatch == None or score > bestScore: bestMatch = knownMotionName bestScore = score print('') print('Den besten Match gab es mit: {} - {} %'.format( bestMatch, bestScore)) #Funktionalität der erkannten Geste ausführen print('Hier wird nun function.execute ausgeführt') print('') if bestMatch == 'learningMotion': print('lerne') self.startLearning() ### #Teil der Bachelorarbeit else: print('Firing new event') topic = 'newMotionEvent' values = dict() values['name'] = bestMatch event = Event(topic, values) self.subscriptionService.onEvent(event) ### def startLearning(self): #Send all Signals to reset Inputs #Zur Sicherheit hier einmal zuviel, damit wirklich #erst mit beginn des lernens die Signale aufgenommen werden self.sm.put(IPCMemory.NEW_MOTION) while True: self.checkSharedMemory() self.signalsLock.acquire() if not self.signalsCounter < len(self.signals): self.signalsLock.release() continue event = self.signals[self.signalsCounter] self.signalsCounter = self.signalsCounter + 1 self.signalsLock.release() if isinstance(event, AboartEvent): ### #Bachelorarbeit self.removeRedundance() ### self.signalsLock.acquire() signalsCopy = self.signals[:] self.signalsLock.release() self.sm.put(IPCMemory.NEW_MOTION) self.transformAndSafeMotion(signalsCopy) break else: continue def transformAndSafeMotion(self, signalsCopy): motion = self.transformMotion(signalsCopy) if self.firstMotion: motion.setName('learningMotion') else: name = input('Wie heißt die Motion\n') motion.setName(name) self.motionManager.saveOrUpdateMotion(motion) def transformMotion(self, signalsCopy): del signalsCopy[len(signalsCopy) - 1] transformer = MotionTransformer() motion = transformer.transformMotion(signalsCopy) return motion ### #Bachelorarbeit def removeRedundance(self): self.signalsLock.acquire() #Remove aboartEvent del self.signals[-1] #Remove allAboartButtonEvents deleted = False i = -1 while not deleted: if isinstance(self.signals[i], ButtonEvent) and self.signals[i].value == 1: #print('Found ButtonEvent with Value {} @ {}'.format(self.signals[i].value, i)) del self.signals[i] deleted = True else: i = i - 1 deleted = False i = -1 while not deleted: if isinstance(self.signals[i], ButtonEvent) and self.signals[i].value == 0: #print('Found ButtonEvent with Value {} @ {}'.format(self.signals[i].value, i)) del self.signals[i] deleted = True else: i = i - 1 deleted = False i = -1 while not deleted: if isinstance(self.signals[i], ButtonEvent) and self.signals[i].value == 1: #print('Found ButtonEvent with Value {} @ {}'.format(self.signals[i].value, i)) del self.signals[i] deleted = True else: i = i - 1 self.signalsLock.release() ### def checkSharedMemory(self): import time if self.smCounter < self.sm.getSize(): message = self.sm.get(self.smCounter) self.smCounter = self.smCounter + 1 if message == IPCMemory.SHUTDOWN: print('I shall shutdown') time.sleep(2) sys.exit() elif message == IPCMemory.NEW_MOTION: self.signalsCounter = 0
class Verification(threading.Thread): def __init__(self, bareSignals, bareSignalsLock, signals, signalsLock): threading.Thread.__init__(self) self.bareSignals = bareSignals self.bareSignalsLock = bareSignalsLock self.bareSignalsCounter = 0 self.signals = signals self.signalsLock = signalsLock self.sm = IPCMemory() self.smCounter = 0 self.currentTouches = 0 #TouchCheckerStuff self.touchEventsMetaInfo = dict() self.threshhold = 0.2 ### #Bachelorarbeit self.lastButton = None self.intTimeout = 0.5 self.buttonTimeout = Decimal('{}'.format(self.intTimeout)).normalize() ### def run(self): print('Started Verification') self.startVerification() def startVerification(self): while True: self.checkSharedMemory() ### #Bachelorarbeit Auskommentiert!!! Muss wieder rein!!! #Braucht erstmal nur Rotation #self.updateObservedTouchEvents() ### #Read bareSignals self.bareSignalsLock.acquire() if not self.bareSignalsCounter < len(self.bareSignals): self.bareSignalsLock.release() continue event = self.bareSignals[self.bareSignalsCounter] self.bareSignalsCounter = self.bareSignalsCounter + 1 self.bareSignalsLock.release() #Stromabbruch checken ### #Bachelorarbeit Auskommentiert!!! Muss wieder rein!!! #if isinstance(event, TouchEvent): # self.observeTouchEvent(event) ### #CheckIfItIsCorrect isValid = False if isinstance(event, RotationEvent) or isinstance(event, ButtonEvent):# or isinstance(event, TouchEvent): isValid = True ### #Bachelorarbeit if isinstance(event, ButtonEvent) and isValid and event.value == 0: #print('New Button Event Release') if self.lastButton is None: self.lastButton = event.getTime() #print('Erstes Event') elif (Decimal('{}'.format(event.getTime())).normalize() - Decimal('{}'.format(self.lastButton)).normalize()) > self.buttonTimeout: self.lastButton = event.getTime() #print('Replaced Event') else: #Es handelt sich um ein Doppelklick und ein Aboart Event muss generiert werden #print('Removing') aboartEvent = AboartEvent(time.time()) self.signalsLock.acquire() self.signals.append(aboartEvent) #print('Put aboart') #print(self.signals) self.signalsLock.release() self.lastButton = None continue ### #Put it into queue or delete it if isValid: self.addEvent(event) #GGF in einen eigenen Event Thread? Achtung: Auf die Reihenfolge #der Events dann achten. Nicht dass das Aboart Event for dem Touch #Event auftritt und das Touch Release Event somit dann verloren geht #self.touchedAreasAndAboartEvent(event) self.cleanUp() def touchedAreasAndAboartEvent(self, event): tmpCurrentTouches = self.currentTouches if isinstance(event, TouchEvent): #print(event.getValue()) if event.getValue() == 0: self.currentTouches = self.currentTouches - 1 if self.currentTouches == 0: aboartEvent = AboartEvent(time.time()) self.signalsLock.acquire() self.signals.append(aboartEvent) self.signalsLock.release() else: self.currentTouches = self.currentTouches + 1 if tmpCurrentTouches != self.currentTouches: print("Anzahl der berührten Flächen: {}".format(self.currentTouches)) def addEvent(self, event): self.signalsLock.acquire() self.signals.append(event) self.signalsLock.release() def observeTouchEvent(self, event): subDic = None if event.getLocation() in self.touchEventsMetaInfo: subDic = self.touchEventsMetaInfo[event.getLocation()] else: subDic = {} subDic['lastEventValue'] = None subDic['event'] = None self.touchEventsMetaInfo[event.getLocation()] = subDic subDic['event'] = event #print('added') def updateObservedTouchEvents(self): for key in self.touchEventsMetaInfo: subDic = self.touchEventsMetaInfo[key] subDic['timeSinceLastEvent'] = Decimal(time.time()) - subDic['event'].getTime() for key in self.touchEventsMetaInfo: subDic = self.touchEventsMetaInfo[key] if subDic['timeSinceLastEvent'] > self.threshhold: if subDic['lastEventValue'] == None or subDic['lastEventValue'] != subDic['event'].getValue(): self.addEvent(subDic['event']) self.touchedAreasAndAboartEvent(subDic['event']) #print('finally') subDic['lastEventValue'] = subDic['event'].getValue() def checkSharedMemory(self): import time if self.smCounter < self.sm.getSize(): message = self.sm.get(self.smCounter) self.smCounter = self.smCounter + 1 if message == IPCMemory.SHUTDOWN: print('I shall shutdown') time.sleep(2) sys.exit() elif message == IPCMemory.NEW_MOTION: #print('A new Motion appeared') self.signalsLock.acquire() del self.signals[:] self.signalsLock.release() self.bareSignalsLock.acquire() del self.bareSignals[:] self.bareSignalsCounter = 0 self.bareSignalsLock.release() def cleanUp(self): print('Verfication finished')
class TouchListener(threading.Thread): usbPath = '/dev/ttyACM0' baudrate = 9600 def __init__(self, bareSignals, bareSignalsLock): threading.Thread.__init__(self) self.bareSignals = bareSignals self.bareSignalsLock = bareSignalsLock self.sm = IPCMemory() self.smCounter = 0 self.ser = serial.Serial(self.usbPath, self.baudrate) self.ser.flush() def run(self): print('TouchListener is running') self.startListening() def startListening(self): while True: self.checkSharedMemory() if (self.ser.inWaiting() <= 0): continue event = self.getEvent() if event == None: continue self.bareSignalsLock.acquire() self.bareSignals.append(event) self.bareSignalsLock.release() self.cleanUp() def getEvent(self): input = self.ser.readline() input = self.convertText(input) event = input[:input.find(';')] input = input[input.find(';') + 1:] location = input[:input.find(';')] input = input[input.find(';') + 1:] val = input[:input.find(';')] val = Decimal('{}'.format(val)).normalize() t = time.time() t = Decimal('{}'.format(t)).normalize() if event == EVENT_TOUCH: return TouchEvent(t, location, val) else: return None def convertText(self, text=None): text = text[:len(text) - 2] text = text.decode('utf-8') return text def checkSharedMemory(self): import time if self.smCounter < self.sm.getSize(): message = self.sm.get(self.smCounter) self.smCounter = self.smCounter + 1 if message == IPCMemory.SHUTDOWN: print('I shall shutdown') time.sleep(2) self.cleanUp() sys.exit() def cleanUp(self): print('TouchListener wurde beendet')
class MotionDetecter(threading.Thread): MODE_RECOGNITION = 'recognition' MODE_LEARNING = 'learning' def __init__(self, signals, signalsLock): threading.Thread.__init__(self) self.signals = signals self.signalsLock = signalsLock self.sm = IPCMemory() self.smCounter = 0 self.motionManager = MotionManager() def run(self): print("Motion Detecter is running") print(self.motionManager.getAllMotions()) if not self.motionManager.getAllMotions(): self.learnLearningMotion() self.startRecognition() def startRecognition(self): self.mode = self.MODE_RECOGNITION while True: self.waitForAboart() print('Geste wurde erkannt') self.sm.add(IPCMemory.RESET_ROTATION_SUM) transformer = MotionTransformer() motionToCompare = transformer.transformMotion(self.signalsCopy) c = Calculator() bestMotion = None bestScore = None for motion in self.motionManager.getAllMotions(): matchingScore = c.getMatchingScore(self.motionManager.getMotion(motion), motionToCompare) print("Matching Score with '{}': {}".format(self.motionManager.getMotion(motion).getName(), matchingScore)) if bestMotion == None: bestScore = matchingScore bestMotion = self.motionManager.getMotion(motion) continue if matchingScore > bestScore: bestScore = matchingScore bestMotion = self.motionManager.getMotion(motion) if bestMotion == None: print("Es sind noch keine Motions angelernt") else: print("Motion {} für Device {} erkannt".format(bestMotion.getName(), bestMotion.getAssignedDevice())) if bestMotion.getName() == 'startLearning': self.sm.add(IPCMemory.START_LEARNING) def startLearning(self): self.mode = self.MODE_LEARNING self.signalsLock.acquire() del self.signals[:] self.signalsLock.release() self.waitForAboart() self.sm.add(IPCMemory.RESET_ROTATION_SUM) transformer = MotionTransformer() try : motion = transformer.transformMotion(self.signalsCopy) except NotEnoughSignals: print("Die Geste beinhaltet keine Aktionen. Sie wird nicht gespeichert") return name = input('Wie soll die Motion heißen?') motion.setName(name) self.motionManager.addMotion(motion) self.mode = self.MODE_RECOGNITION def learnLearningMotion(self): self.mode = self.MODE_LEARNING self.signalsLock.acquire() del self.signals[:] self.signalsLock.release() print('Jetzt bitte Geste ausführen mit der später neue Gesten angelernt werden sollen') self.waitForAboart() self.sm.add(IPCMemory.RESET_ROTATION_SUM) transformer = MotionTransformer() try : motion = transformer.transformMotion(self.signalsCopy) except NotEnoughSignals: print("Die Geste beinhaltet keine Aktionen. Sie wird nicht gespeichert") return motion.setName('startLearning') self.motionManager.addMotion(motion) def waitForAboart(self): print('Jetzt bitte Geste ausführen und mit Doppelklick bestätigen') counter = 0 while True: self.checkSharedMemory() self.signalsLock.acquire() if len(self.signals) <= counter: self.signalsLock.release() continue event = self.signals[counter] if event != None and event.getEvent() == EVENT_ABOART: self.saveCopyOfSignals() self.removeAboartEvent(self.signalsCopy) self.removeNones(self.signalsCopy) del self.signals[:] self.signalsLock.release() break self.signalsLock.release() counter = counter + 1 def removeAboartEvent(self, signals): for i in range(len(signals)-1, -1, -1): if signals[i].getEvent() == EVENT_ABOART: del signals[i] break #Signales that triggered the aboart are marked as None def removeNones(self, signals): for i in range(len(signals)-1, -1, -1): if signals[i] == None: del signals[i] #ATTENTION! LOCK MUST BE REQUIRED FIRST!!! def saveCopyOfSignals(self): self.signalsCopy = self.signals[:] def clearDoubleClick(self, signals): removedButtonEvents = 0 for i in range(len(signals)-1, -1, -1): if removedButtonEvents == 4: break event = signals[i] if isinstance(event, ButtonEvent): del signals[i] removedButtonEvents = removedButtonEvents + 1 def checkSharedMemory(self): import time #print('Checking Size') #print('SmCounter = {}'.format(self.smCounter)) #print('SmSize = {}'.format(self.sm.getSize())) if self.smCounter < self.sm.getSize(): message = self.sm.get(self.smCounter) #print(message) self.smCounter = self.smCounter + 1 if message == IPCMemory.SHUTDOWN: print('I shall shutdown') time.sleep(2) sys.exit() elif message == IPCMemory.START_LEARNING: if self.mode == self.MODE_LEARNING: print("I'm already learning") else: print('I shall start learning') time.sleep(2) self.startLearning() elif message == IPCMemory.START_RECOGNIZING: if self.mode == self.MODE_RECOGNITION: print("I'm already recognizing") else: print('I shall start recognition') time.sleep(2) self.startRecognition()