psychopy.org | Reference | Downloads | Github

Udp data handling

Hi, I am working no a cursor based task where the subject interfaces with some external non-classical computer interface hardware (as in no keyboard/mouse etc) and I want to use the data to update what is on the screen. Currently, I have the data available on a udp port and I use standard socket module to read from it.

The problem that I am facing is that the data comes in at 100Hz, and when I draw on received udp data I very quickly accumulate a massive lag. It seems to me that the iohub could be a solution to deal with events that happen at a different rate than the screen refresh rate, but I could not find or understand a matching example.

Here is some example code:

from psychopy import visual, core, monitors
import socket
import struct

mon = monitors.Monitor(name="display",width=10,distance=5)
win = visual.Window(size=[1024,768], monitor=mon, screen=0, fullscr=False, useFBO=True)
gabor = visual.GratingStim(win, tex='sin', mask='gauss', sf=5, name='gabor', autoLog=False, size=2)

def update(x,y):
    gabor.pos = [x,y]
    gabor.draw()
    win.flip()

UDP_IP, UDP_PORT = "127.0.0.1", 4002

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
sock.bind((UDP_IP, UDP_PORT))
sock.setblocking(False) 

while True:
    try:
        raw_read = sock.recv(8)
        x,y = struct.unpack('ff',raw_read)
        update(x,y)       

    except BlockingIOError:
        pass

What is the correct place to look, or how else should I approach this? Thanks for help!

Anyone? Thanks …

It shouldn’t matter if the sender is generating packets faster than you are checking for them: if you are just wanting to update the screen, then all you want is the latest packet. All of the others can be ignored.

Depending on the size of the receiving socket buffer size, older packets will get dropped as new ones arrive. So you could set the size of the buffer to be just a bit larger than you expect one packet to be, and then you should only get access to the latest one by default I guess.

Thank you for your reply Michael. Do you have an idea where else the accumulative lag that I see could be coming from?

Really hard to speculate without knowing more detail, but I suspect that this is a problem with the buffer, where you are having to deal with old packets before getting to the latest one (maybe my guidance above was off).

Try looking at a couple of answers to this StackOverflow post (in this case I suspect the accepted answer is not the one you want):

That question is about C, but socket programming is basically the same between C and Python I think. Having said that, if you need further guidance, you might get more useful responses from the much larger StackOverflow community, particularly if you pose it as a generic Python rather than PsychoPy-specific question.