在构建器的 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。到目前为止,我收集了以下信息:
- Psychopy 会将按钮框识别为操纵杆。
- 我需要在试用例程中使用代码组件。
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 处理。
我正在尝试将 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。到目前为止,我收集了以下信息:
- Psychopy 会将按钮框识别为操纵杆。
- 我需要在试用例程中使用代码组件。
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 处理。