|
|
@@ -0,0 +1,115 @@ |
|
|
|
# TODO für python3 anpassen und in gui mit einfügen |
|
|
|
|
|
|
|
# imports |
|
|
|
from socket import * |
|
|
|
import thread, threading, struct |
|
|
|
import Queue |
|
|
|
import time, datetime |
|
|
|
from time import clock |
|
|
|
import os |
|
|
|
import ctypes |
|
|
|
|
|
|
|
|
|
|
|
# connect to BCI2000 in a new thread |
|
|
|
class BCI2000ReceiverThread(threading.Thread): |
|
|
|
def __init__(self, id, phaseInSequenceQueue, StimulusCodeQueue): |
|
|
|
threading.Thread.__init__(self, name="BCI2000ReceiverThread%d" % (id,)) |
|
|
|
self.phaseInSequenceQueue=phaseInSequenceQueue |
|
|
|
self.StimulusCodeQueue=StimulusCodeQueue |
|
|
|
self.running=True |
|
|
|
self.firstData = True |
|
|
|
self.repeat = 0 |
|
|
|
#udp settings |
|
|
|
self.host = "localhost" |
|
|
|
self.port = 5003 # BCI2000 |
|
|
|
self.UNITY_PORT = 5002 # unity |
|
|
|
self.FEATHER_PORT = 5001 # feather gui |
|
|
|
self.go = True |
|
|
|
self.buf = 1024 |
|
|
|
self.addr = (self.host,self.port) |
|
|
|
#connect to udp socket |
|
|
|
self.UDPSock = socket(AF_INET,SOCK_DGRAM) |
|
|
|
self.UDPSock.bind(self.addr) # BIND to LISTEN |
|
|
|
print('%s initialized to %s at port %s' % (self.getName(), self.host, self.port)) |
|
|
|
print('Relaying SelectedTargerts to port -- %s ---' % self.UNITY_PORT) |
|
|
|
self.relay_unity = socket(AF_INET,SOCK_DGRAM) # UDP RELAY TO UNITY |
|
|
|
print('Relaying all to port -- %s ---' % self.FEATHER_PORT) |
|
|
|
self.relay_feather = socket(AF_INET,SOCK_DGRAM) # UDP RELAY TO FEATHER |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def kill(self): |
|
|
|
self.running=False |
|
|
|
log('%s terminated' % (self.getName())) |
|
|
|
|
|
|
|
def run(self): |
|
|
|
# define a new contains method comparing strings |
|
|
|
def contains(theString, theQueryValue): |
|
|
|
return theString.find(theQueryValue) > -1 |
|
|
|
|
|
|
|
while self.running: |
|
|
|
# try to receive from BCI2000 AppConnector |
|
|
|
try: |
|
|
|
self.data,self.addr = self.UDPSock.recvfrom(self.buf) |
|
|
|
#print(self.data) ##### |
|
|
|
if self.firstData: |
|
|
|
print ("UDP is receiving...") |
|
|
|
self.firstData=0 |
|
|
|
|
|
|
|
if "SelectedTarget 0" in self.data: |
|
|
|
self.go = True |
|
|
|
if "SelectedTarget" in self.data and "SelectedTarget 0" not in self.data and self.go == True: |
|
|
|
print "Relaying Command to Unity: ", self.data |
|
|
|
self.relay_unity.sendto(self.data, (self.host, self.UNITY_PORT)) |
|
|
|
self.go = False |
|
|
|
|
|
|
|
if contains(self.data, "PhaseInSequence"): |
|
|
|
phaseInSequence=int(self.data.replace('PhaseInSequence ','')) |
|
|
|
self.phaseInSequenceQueue.put(phaseInSequence) |
|
|
|
#print (phaseInSequence) |
|
|
|
|
|
|
|
if contains(self.data, "StimulusCode "): |
|
|
|
print "Relaying Command to Feather: ", self.data |
|
|
|
self.relay_feather.sendto(self.data, (self.host, self.FEATHER_PORT)) |
|
|
|
|
|
|
|
StimulusCode=int(self.data.replace('StimulusCode ','')) |
|
|
|
if not StimulusCode == 0 and self.repeat == 0: |
|
|
|
self.repeat = 1 |
|
|
|
self.StimulusCodeQueue.put(StimulusCode) |
|
|
|
self.Code = StimulusCode |
|
|
|
elif StimulusCode == 0: |
|
|
|
self.repeat = 0 |
|
|
|
# print (StimulusCode) |
|
|
|
|
|
|
|
# wait a short time and try again |
|
|
|
except error: |
|
|
|
time.sleep(0.0001) |
|
|
|
print('sleeping') |
|
|
|
continue |
|
|
|
|
|
|
|
# def run(self): |
|
|
|
# a = 1 |
|
|
|
|
|
|
|
def returnProgramStatus(self): |
|
|
|
return self.running |
|
|
|
|
|
|
|
def kill(self): |
|
|
|
self.running=False |
|
|
|
log('%s terminated' % (self.getName())) |
|
|
|
|
|
|
|
|
|
|
|
### M A I N P R O G R A M M ### |
|
|
|
|
|
|
|
|
|
|
|
# initialize queue |
|
|
|
phaseInSequenceQueue = Queue.Queue() |
|
|
|
StimulusCodeQueue = Queue.Queue() |
|
|
|
|
|
|
|
RunApplication = True |
|
|
|
|
|
|
|
#start BCI2000ReceiverThread |
|
|
|
BCI2000ReceiverThread1=BCI2000ReceiverThread(1, phaseInSequenceQueue, StimulusCodeQueue) |
|
|
|
BCI2000ReceiverThread1.start() |
|
|
|
|
|
|
|
|
|
|
|
|