在构建器的 PsychoPy2 中使用 DirectIN 旋转控制器

Using DirectIN Rotary Controller in PsychoPy2 in builder

我正在尝试将 DirectIN Rotary Controller on Mac OS X (yosemite) 与 PsychoPy2 (v. 1.82.01) 一起使用。我想做一个二选一的强制选择实验,使用按钮盒上的按钮来响应;但是,我无法让精神病患者识别该设备。

有类似问题的人能够使按钮框在编码器中工作(see here), and there is a similar question using a different game controller here。到目前为止,我收集了以下信息:

  1. Psychopy 会将按钮框识别为操纵杆。
  2. 我需要在试用例程中使用代码组件。

emprisoft 论坛的 post 提供了以下代码:

import pyglet
joysticks = pyglet.input.get_joysticks()


for joy in joysticks:
    if joy.device.name == 'Analog Scale Device':
        joy.open()
        break

def present_pair_joystick(trial,isi,curdata): #trial is a sound object, isis is the time to wait after response/end of sound, and curdata is a dictionary used to store response data
    event.clearEvents()
    while joy.buttons[0] or joy.buttons[1]:
        continue
    curdata['trial_start']=time.time()
    trial.play()
    dur = trial.getDuration()
    while True:
        if not (joy.buttons[0] and joy.buttons[1]):
            if joy.buttons[0]:
                curdata['rt'] = time.time() - curdata['trial_start']
                curdata['resp'] = 'Word'
                break
            elif joy.buttons[1]:
                curdata['rt'] = time.time() - curdata['trial_start']
                curdata['resp'] = 'Nonword'
                break
            if 'escape' in event.getKeys():
                core.quit()
    if time.time() - curdata['trial_start'] > dur:
        core.wait(isi)
    else:
        core.wait((dur - (time.time() - curdata['trial_start'])) + isi)
    curdata['dur'] = dur
    return

所以我相信,如果我将这段代码合并到生成器中的代码组件中,我可以让按钮框工作,但我没有成功(我能够 运行 没有实验错误,但未记录关键响应)。任何帮助将不胜感激。

你这么说"I cannot get PsychoPy to recognize the device"但实际上并没有说你做了什么,所以很难诊断问题。

简单地粘贴上面的代码不会为您做任何可见的事情,因为它创建了一个您没有明确调用的函数 (present_pair_joystick())。

第一段代码访问了操纵杆,但没有给您任何关于它是否成功的可见反馈,所以让我们来解决这个问题。我不熟悉操纵杆,所以只会修改您在上面找到的代码并假设它是合适的。例如将其放在代码组件的 "Begin Experiment" 选项卡中:

import pyglet
joysticks = pyglet.input.get_joysticks()

joystickFound = False

for joy in joysticks:
    if joy.device.name == 'Analog Scale Device':
        joy.open()
        joystickFound = True
        break

if joystickFound:
    print('Joystick found!')
else:
    print('Joystick NOT found.')
    core.quit() # no point continuing

假设连接成功,那么我们就可以在每次试验开始和每次屏幕刷新时开始处理响应。

似乎操纵杆按钮的按下即使在它们没有被释放时也可以保持注册,因此可以从一个试验延续到下一个试验。因此,我们需要确保至少有一段时间,在我们测试下一次实际按钮按下之前,在试验开始时按钮没有被按下。

所以把这样的东西放在代码组件的 "Begin Routine" 选项卡中:

buttonReleased = False

"Every frame" 选项卡中的类似内容:

# check that the buttons go through a period of NOT being pressed 
# before we check if they HAVE been pressed:
if not (joy.buttons[0] or joy.buttons[1]):
    buttonReleased = True # the previous trial's press has been released

if buttonReleased:
    response = ''
    if joy.buttons[0]:
        response = '0'
    elif joy.buttons[1]:
        response = response + '1' # allows you to capture if both buttons pressed simultaneously

    if response != '':
        thisExp.addData('buttonResponse', response) # save the response in the data
        thisExp.addData('buttonRT', t) # store current time since trial start
        continueRoutine = False # end trial once response received

event.clearEvents(eventType='joystick')

警告:我不完全确定 clearEvents 调用的位置,并且没有操纵杆来测试此按钮 press/release 处理。