pythonpsychopy

Failure to Psychopy GetKeys


My task is to design a square block. It will run randomly from one side of the screen to the other. And a beep will be played sometime. One has to push the botton(Here is keyboard) as soon as he hears the beep. The question is, when I use the "getkeys" method, it always returns an empty list. The RT shows that it main get the very first input in the buffer. I also tried eventclear, but seemed useless.

Here is the code.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from psychopy import visual, core, event,gui
from psychopy import sound as sd
#from psychopy.iohub.client.keyboard import Keyboard as kbd
import random, math,time
from psychopy.iohub import launchHubServer
import numpy as np

win = visual.Window(fullscr = False, size = [960,540], color = 'black', units = 'pix')

io = launchHubServer()

kbd = io.devices.keyboard

x,y = win.size

ran = [random.randint(-400,400),random.randint(-400,400),random.randint(-150,150),random.randint(-150,150)]

mode = random.randint(0,3)

start_pos = [[ran[mode],-269],[ran[mode],269],[-479,ran[mode]],[479,ran[mode]]]

rect = visual.Rect(win, width = 50, height = 50, fillColor='white', pos = start_pos[mode], name = 'target')

timer = core.Clock()

dx = [0,0,1,-1]
dy = [1,-1,0,0]

def present(rect,t):
    timer.reset()
    while timer.getTime() < t:
        rect.draw()
        win.flip()

    
def movement(rect,time):
    event.clearEvents()
    x,y = win.size
    timer.reset()
    timer_2 = core.Clock()
    timer_2.reset()
    jump = True
    while timer.getTime() < time and (abs(rect.pos[0])< x/2 and abs(rect.pos[1])< y/2):
        timeUse = timer_2.getTime()
        timer_2.reset()
        a,b = rect.pos
        rect.pos += [dx[mode]*timeUse*100,dy[mode]*timeUse*100]

        if int(timer.getTime()) == 3 :
            if jump :
                sd.Sound('D', octave = 5).play()
            #print("D" , timer.getTime())
            if jump :
                timer_jump = core.Clock()
                timer_jump.reset()
            print(timer_jump.getTime(),'++++++++++')
            event.clearEvents()
            if timer.getTime() < time and jump :
                print('============')
                #k_1 = event.getKeys(keyList = ['a','z'])
                while event.getKeys() is not None:
                    
                    RT = timer_jump.getTime()
                    print(RT,'--------')
                    break
                jump = False
        
        #print([timer.getTime(),time])
        #print(rect.pos)
        rect.draw()
        win.flip()


present(rect,1)
movement(rect,15)

I would feel my very gratitude to who helps.

Messhiro


Solution

  • The question is, when I use the "getkeys" method, it always returns an empty list.

    event.getKeys() is an instantaneous check of the keyboard buffer. It will always return an empty list unless a key has been pressed since the last call to the function. So it is usually called in a loop, often once per screen refresh, to detect when a keypress has occurred. The result is that it will return an empty list many times, until a key is actually pressed.

    But PsychoPy's event module has actually been deprecated in favour of the newer Keyboard class. This has the advantage that it returns the actual time that the key was pressed: when using event.getKeys(), one just infers the reaction time from the time that the function was called. This is some time after the key is pressed - even if you are calling the function on every screen refresh (typically at 60 Hz), this limits the time resolution to 16.7 ms. The Keyboard class, meanwhile, runs in a separate process and continually checks the keyboard hardware, allowing a precision more at the millisecond level.

    Documentation on the Keyboard class is here: https://www.psychopy.org/api/hardware/keyboard.html