OS: (Mac +) Win
PsychoPy version 2024.2.4 Py 3.8
Standard Standalone Installation? (y/n) y
Do you want it to also run online? (y/n) n
What are you trying to achieve?:
I have a routine in my experiment in which participants use up/down/left/right buttons to move a cursor on screen and a confirm button to choose a location. I want the cursor to move whenever a key is pressed and stop moving when it isn’t.
This is working, the issue is that sometimes some movement keys get stuck: even when I release the key, PsychoPy records it as being pressed (I see the print statement print out the key on every frame) and the cursor keeps moving in that direction until I press confirm (=end routine). On the next trial, if I press the same key again the same thing happens (for many trials, unclear why/when it stops).
This happens both on my local laptop and the windows machine I run the experiment on. I am not entirely sure what triggers it, but I think it has to do with pressing multiple keys at once.
What did you try to make it work?:
Adding an if statement checking if kb.getState(key):
in the loop through the keys seems to solve the issue on my Mac, but it leads to an error on the Windows machine, which is where I need the experiment to run (error related to KbCheck behind the scenes requiring a device_id, which is not available on win Psychtoolbox-3 - KbCheck).
The routine has 2 images (background image and cursor) and a code component. Below are the relevant parts of the code component.
Begin routine:
kb.clock.reset() # reset timer
kb.clearEvents(eventType='keyboard') # remove all previous key presses
Each frame:
# listen for keys
keys = kb.getKeys(keyList=[key_left, key_right, key_up, key_down, key_confirm, 'q'], waitRelease=False, clear=False)
if keys: # if a key is being pressed
# ========= allows to quit experiment by pressing Q =========
if 'q' in keys:
endExpNow = True
# ========= if press confirm, end trial =========
elif key_confirm in keys:
continueRoutine = False
# ========= Update movement for each directional key -- single speed =========
else:
cursor_pos_new = deepcopy(cursor_pos)
# move for each pressed key
for key in keys:
# if kb.getState(key):
print('pressed', key.name, key.rt)
if key == key_left:
cursor_pos_new[0] += -1 * speed
if key == key_right:
cursor_pos_new[0] += 1 * speed
if key == key_up:
cursor_pos_new[1] += 1 * speed
if key == key_down:
cursor_pos_new[1] += -1 * speed
# Prevent moving out of bounds
distance_to_center = math.sqrt(cursor_pos_new[0]**2 + cursor_pos_new[1]**2)
if distance_to_center <= max_radius:
cursor_pos[0] = cursor_pos_new[0]
cursor_pos[1] = cursor_pos_new[1]
# save sequence of pressed keys (even if the cursor is not moved because of bounds)
keypress_log.append({'key': key.name, 'time': key.rt})
# save cursor path
cursor_path.append({'time': key.rt, 'x': cursor_pos[0], 'y': cursor_pos[1]})
End routine:
kb.clearEvents()
Link to the most relevant existing thread you have found:
The issue is similar to the one here, but I don’t think it has been answered: Key release event missed occasionally
What specifically went wrong when you tried that?:
Error message on Win machine for kb.getState()
Psychtoolbox/hid.py line 141
Return PsychHID( KbCheck", Self device id, scan_Lis) AttributeError: keyboard object has no attribute device_id
I would really appreciate any help!