123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 |
- '''--------------------------------------------------------------------------------------------------
- Im Controller wird in der Init eine View erstellt und gestartet. Zudem wird der Acquisitionserver
- gestartet, die shared Librarz geladen, die Konstanten Initialtisiert.
- Mittels der Funktion Action Performed wird die jeweilige Reaktion auf die Benutyeraktion ausgeloest.
- Hierfuer stehen die verschiedenen eigenen Funktionen die die Reaktion in der richtigen reihenfolge
- an ein neu instanizieertes Modell weitergibt.
- Zudem stehen einige Funktionen zur Informationsuebergabe an die View oder das Modell zur Verfuegung
- '''
-
-
- from UIModellVisuell import *
- from UIModellTaktil import *
- from UIModell import *
- import UIViewTKinter as viewTkinter
- from shutil import copyfile
- import ctypes
- import os
-
-
-
- class Controller():
-
- def __init__(self):
- '''--------------------------------------------------------------------------------------------------
- In der Init wird die shared Library geladen, die View erstellt und geoeffnet und die verschiedenen
- Konstanten gesetzt
- '''
-
- self.getSharedLibrary()
-
- self.view = viewTkinter.View(self, self.dll.getDefaultPath_visuell())
- self.modi = "visuellesBCI"
- self.pathOVFile = self.dll.getPathOVFile_visuell()
- self.pathSpatialCfg = self.dll.getSpatialCFGFile_visuell()
- self.pathClassifierCfg = self.dll.getClassifierCFGFile_visuell()
- self.infotext = ""
-
- self.commands = {
- "copySpelling": self.commandoCopySpelling,
- "stop": self.commandStop,
- "freeSpelling": self.commandFreeSpelling,
- "test": self.test,
- "wechsel": self.wechsel,
- "speicherort": self.setDataset
- }
-
- self.nexts = {
- "filterXdawn" : self.filterXdawn,
- "filterClassic": self.filterClassic,
- "save": self.speichern
- }
-
- self.pagesTaktil = {
- "stop": "StartPage",
- "copySpelling": "WorkingPageTaktil",
- "freeSpelling": "WorkingPageTaktil",
- "test": "WorkingPageTaktil"
- }
- self.pagesVisuell = {
- "stop": "StartPage",
- "copySpelling": "WorkingPageVisuell",
- "freeSpelling": "WorkingPageVisuell",
- "test": "WorkingPageVisuell"
- }
- self.acquisitionServer = Modell(self, self.dll)
- self.acquisitionServer.start()
-
- self.model = None
- self.view.mainloop()
-
- def getSharedLibrary(self):
- '''--------------------------------------------------------------------------------------------------
- Laedt die shared Library (diese muss sich im gleichen Ordner wie die ausfuehrunde Datei befinden)
- und setzt die Eingabe und Rueckgabewerte.
- '''
-
- path = os.path.abspath(".")
- path = path + "/dll.so"
- self.dll = ctypes.CDLL(path)
-
- self.dll.getCommandFreespellingTaktil.argtypes = []
- self.dll.getCommandFreespellingTaktil.restype = ctypes.c_char_p
-
- self.dll.getCommandFreespellingVisuell.argtypes = []
- self.dll.getCommandFreespellingVisuell.restype = ctypes.c_char_p
-
- self.dll.getCommandCopyspellingTaktil.argtypes = []
- self.dll.getCommandCopyspellingTaktil.restype = ctypes.c_char_p
-
- self.dll.getCommandCopyspellingVisuell.argtypes = []
- self.dll.getCommandCopyspellingVisuell.restype = ctypes.c_char_p
-
- self.dll.getCommandXDawn_taktil.argtypes = []
- self.dll.getCommandXDawn_taktil.restype = ctypes.c_char_p
-
- self.dll.getCommandXDawn_visuell.argtypes = []
- self.dll.getCommandXDawn_visuell.restype = ctypes.c_char_p
-
- self.dll.getCommandClassifier_visuell.argtypes = []
- self.dll.getCommandClassifier_visuell.restype = ctypes.c_char_p
-
- self.dll.getCommandClassifier_taktil.argtypes = []
- self.dll.getCommandClassifier_taktil.restype = ctypes.c_char_p
-
- self.dll.getDefaultPath_visuell.argtypes = []
- self.dll.getDefaultPath_visuell.restype = ctypes.c_char_p
-
- self.dll.getDefaultPath_taktil.argtypes = []
- self.dll.getDefaultPath_taktil.restype = ctypes.c_char_p
-
- self.dll.getPathOVFile_visuell.argtypes = []
- self.dll.getPathOVFile_visuell.restype = ctypes.c_char_p
-
- self.dll.getSpatialCFGFile_visuell.argtypes = []
- self.dll.getSpatialCFGFile_visuell.restype = ctypes.c_char_p
-
- self.dll.getClassifierCFGFile_visuell.argtypes = []
- self.dll.getClassifierCFGFile_visuell.restype = ctypes.c_char_p
-
- self.dll.getPathOVFile_taktil.argtypes = []
- self.dll.getPathOVFile_taktil.restype = ctypes.c_char_p
-
- self.dll.getSpatialCFGFile_taktil.argtypes = []
- self.dll.getSpatialCFGFile_taktil.restype = ctypes.c_char_p
-
- self.dll.getClassifierCFGFile_taktil.argtypes = []
- self.dll.getClassifierCFGFile_taktil.restype = ctypes.c_char_p
-
- self.dll.getCommandStartAquisitionServer.argtypes = []
- self.dll.getCommandStartAquisitionServer.restype = ctypes.c_char_p
-
- def actionPerformed(self, action):
- '''--------------------------------------------------------------------------------------------------
- Wird aufgerufen wenn ein Button in der Init gedrueckt wird zuerst wird kontrolliert ob die Seite
- gewechselt werden muss, dann nach dem Buttonnamen die Funktion zugeordnert. Der Funktion zum
- Buttomnamen wird in der Init festgelegt
- '''
-
- self.changePage(action)
- func = self.commands.get(action)
- if(func is not None):
- func()
- else:
- print("Kommado existiert nicht")
-
-
- def changePage(self,action):
- '''--------------------------------------------------------------------------------------------------
- Change Page ruft je nach Aktion und Modi die jeweilige Seite auf
- '''
-
- if(self.modi == "taktilesBCI"):
- page = self.pagesTaktil.get(action)
- elif(self.modi == "visuellesBCI"):
- page = self.pagesVisuell.get(action)
- if(page is not None):
- self.view.changeFrame(page)
-
- def wechsel(self):
- '''--------------------------------------------------------------------------------------------------
- Wechsel aendert den Modi. Dafuer wird zuerst der aktuelle Modi ueberprueft und dann auf den anderen
- Modi gesetzt.
- '''
-
- self.resetInfo()
- self.addInfoText("")
- if(self.modi == "taktilesBCI"):
- self.view.setChangeBtnText("Wechsel zu taktilen BCI")
- self.view.setTitleText("visuelles BCI")
- self.view.setDefaultPath(self.dll.getDefaultPath_visuell())
- self.pathOVFile = self.dll.getPathOVFile_visuell()
- self.pathSpatialCfg = self.dll.getSpatialCFGFile_visuell()
- self.pathClassifierCfg = self.dll.getClassifierCFGFile_visuell()
- self.modi = "visuellesBCI"
- elif(self.modi == "visuellesBCI"):
- self.setTitle("taktiles BCI")
- self.view.setChangeBtnText("Wechsel zu visuellen BCI")
- self.view.setDefaultPath(self.dll.getDefaultPath_taktil())
- self.pathOVFile = self.dll.getPathOVFile_taktil()
- self.pathSpatialCfg = self.dll.getSpatialCFGFile_taktil()
- self.pathClassifierCfg = self.dll.getClassifierCFGFile_taktil()
- self.modi = "taktilesBCI"
-
- def speichern(self):
- '''--------------------------------------------------------------------------------------------------
- wird nach dem Classifier Training aufgerufen und speichert die erstellte .ov Datei und die
- spatial.cfg, classifier.cgf-Dateine unter dem ausgewaehlten Ordnername.
- (Ordnername wird zu Beginn des CopySpellings festgelegt)
- '''
- print("saveFile")
- print(self.file)
- if not os.path.exists(self.file):
- os.mkdir(self.file)
- copyfile(self.pathOVFile, (self.file + "/p300-xdawn-train.ov"))
- copyfile(self.pathClassifierCfg, (self.file + "/p300-classifier.cfg"))
- copyfile(self.pathSpatialCfg, (self.file + "/p300-spatial-filter.cfg"))
-
- self.changeScreen("StartPage")
-
- #copyfile(self.pathOVFile, self.file)
-
- def setDataset(self):
- '''--------------------------------------------------------------------------------------------------
- Legt fest welches Datenset fuer das Freestelling genutzt wird
- '''
-
- file = self.view.openfiledialog()
- print(file)
- if not file:
- print("nichts ausgewaehlt")
- else:
- if os.path.exists((file + "/p300-classifier.cfg")):
- print("classifier kopiert")
- copyfile((file + "/p300-classifier.cfg"), self.pathClassifierCfg)
- if os.path.exists((file + "/p300-spatial-filter.cfg")):
- print("spatialfilter kopiert")
- copyfile((file + "/p300-spatial-filter.cfg"), self.pathSpatialCfg)
- if os.path.exists((file + "/p300-xdawn-train.ov")):
- print(".ov kopiert")
- copyfile((file + "/p300-xdawn-train.ov"), self.pathOVFile)
-
-
-
- def test(self):
- '''--------------------------------------------------------------------------------------------------
- Funktion zum testen von xDawn und ClassifierTraining
- '''
- self.file = self.view.savefiledialog()
- if(self.modi == "taktilesBCI"):
- self.model = ModellTaktil(self, dll=self.dll)
- elif(self.modi == "visuellesBCI"):
- self.model = ModellVisuell(self, dll=self.dll)
- self.model.setFunktion(self.model.trainXDawn)
- self.model.start()
-
- def commandoCopySpelling(self):
- self.view.savefiledialog()
-
-
- def copyspelling(self, path):
- '''--------------------------------------------------------------------------------------------------
- Speichert den gewuenschte Pfad und erstellt anschliessend ein Model (als Thread) und fuehrt die
- Funktion CopySpelling aus.
- '''
- self.file = path
- print(path)
- if self.file == "-1":
- print("kein gueltiger Pfad")
- self.view.changeFrame("StartPage")
- else:
- if(self.modi == "taktilesBCI"):
- self.model = ModellTaktil(self, dll=self.dll)
- elif(self.modi == "visuellesBCI"):
- self.model = ModellVisuell(self, dll=self.dll)
- self.model.setFunktion(self.model.startCopySpelling)
- self.model.start()
-
- def filterXdawn(self):
- '''--------------------------------------------------------------------------------------------------
- wird nach dem CopySpelling gestartet. Die Funktion erstellt ein Model (als Thread) und fuehrt die
- Funktion trainXDawn aus.
- '''
-
- if(self.modi == "taktilesBCI"):
- self.model = ModellTaktil(self, dll=self.dll)
- elif(self.modi == "visuellesBCI"):
- self.model = ModellVisuell(self, dll=self.dll)
- self.model.setFunktion(self.model.trainXDawn)
- self.model.start()
-
- def filterClassic(self):
- '''--------------------------------------------------------------------------------------------------
- wird nach dem xDawn-Training gestartet. Die Funktion erstellt ein Model (als Thread) und fuehrt die
- Funktion trainClassifier aus.
- '''
-
- if(self.modi == "taktilesBCI"):
- self.model = ModellTaktil(self, dll=self.dll)
- elif(self.modi == "visuellesBCI"):
- self.model = ModellVisuell(self, dll=self.dll)
- self.model.setFunktion(self.model.trainClassifier)
- self.model.start()
-
- def commandFreeSpelling(self):
- '''--------------------------------------------------------------------------------------------------
- startet nach Benutzeraktion das Freespelling: ie Funktion erstellt ein Model (als Thread) und fuehrt die
- Funktion freespelling aus.
- '''
- print("freespelling")
- if(self.modi == "taktilesBCI"):
- self.model = ModellTaktil(self, dll=self.dll)
- elif(self.modi == "visuellesBCI"):
- self.model = ModellVisuell(self, dll=self.dll)
- self.model.setFunktion(self.model.freeSpelling)
- self.model.start()
-
-
- def commandStop(self):
- '''--------------------------------------------------------------------------------------------------
- Wird nach Benutzeraktion aufgerufen und stopt, falls vorhanden, den ablaufenden Thread und schliesst
- Openvibe
- '''
- if(self.model is not None):
- self.addInfoText("Aktion: STOP-Befehl\n")
- self.model.stop()
- self.model.join()
- self.model.killProzess()
- self.mode = None
-
- def stopAcquisitionServer(self):
- '''--------------------------------------------------------------------------------------------------
- Wird nur beim schliessen der GUI aufgerufen und stopt und schliesst den Acquisitionserver
- '''
- self.acquisitionServer.stop()
- self.acquisitionServer.join()
- self.acquisitionServer.killAcquisitionServer()
- self.acquisitionServer = None
-
- def stop(self, next=None):
- '''--------------------------------------------------------------------------------------------------
- Wird aus dem Modell nach Ablauf oder bei Fehler aufgerufen und stopt den aktuellen Thread.
- Anschliessend wird je nach Prozess die naechste Funktion (XDawn-Training oder Classifier) aufgerufen
- '''
- print("Stop aus Modell")
- self.model.stop()
- self.model.join()
- self.model.killProzess()
- self.mode = None
- if(next is not None):
- func = self.nexts.get(next)
- func()
-
-
- def addInfoText(self,text):
- '''--------------------------------------------------------------------------------------------------
- Fuegt dem Infotext den Text hinzu und schreibt es in die Ausgabe
- '''
- self.infotext = self.infotext + text
- self.view.setInfoText(self.infotext)
-
- def resetInfo(self):
- self.infotext = ""
-
- def setTitle(self,text):
- self.view.setTitleText(text)
-
- def changeScreen(self, pageName):
- self.view.changeFrame(pageName=pageName)
-
- def getModi(self):
- return self.modi
-
- def getWindowSize(self):
- return self.view.getWindowSize()
-
-
-
|