[solved] mouse fails to register some clicks
Hi! I've had a lot of success with the inline python scripts in OS, however I have to have a program ready for an experiment next week, and it is still missing a click every now and then. (code will follow). I've got the mouse running within a 'while' loop... the code will display two circles, which the individual must click. on the majority of the trials this works fine, but for a few, the click will not get acknowledged until a second or third click. I need to get this fixed... i think it has something to do with the mouse refresh rate not giving enough time for the click to register - i've had some success with adding a timeout of up to 70ms to the mouse, but this makes the mouse cursor jerky and still doesn't fix the problem 100%.) Is there possibly another way of running the mouse and gathering clicks, that would ensure each and every click is registered? thanks for your time, and sorry for the hack-ish code, follows:
cheers and good aft!
martin
from openexp.canvas import canvas
from openexp.mouse import mouse
import random
import math
divisor = 12
centrex = self.get('width')/2
centrey = self.get('height')/2
size = self.get('size')
distance = self.get('distance')
print 'distance: ' + str(distance)
my_mouse = mouse(self.experiment)
my_canvas = canvas(exp)
xpos1 = (centrex - (distance / 2))
ypos1 = self.get('height')/2
xpos2 = (centrex + (distance / 2))
ypos2 = self.get('height')/2
RT1 = None
RT2 = None
#set up angle deviation of stimuli
def translate(angle, x, y):
print 'Angle: ' + str(angle) + '\n' + 'X: ' + str(x) + '\n' + 'Y: ' + str(y)
y1 = math.sin(angle) * x
x1 = math.cos(angle) * x
return [x1, y1]
sketchpadname = "sketchpad"
t0 = self.experiment.time()
running1 = True
while running1:
angle_step = (random.random() * 2 - 1) * (random.random()*6 / divisor)
coords = translate(math.pi/angle_step, distance/2, 0)
print coords
mouse_click = [False, False]
while ((not mouse_click[0]) or (not mouse_click[1])) :
if not mouse_click[0]:
my_canvas.circle(centrex + coords[0], centrey + coords[1], self.get("size"), fill=True, color='blue')
else:
my_canvas.circle(centrex + coords[0], centrey + coords[1], self.get("size"), fill=True, color='#000080')
if not mouse_click[1]:
my_canvas.circle(centrex - coords[0], centrey - coords[1], self.get("size"), fill=True, color='blue')
else:
my_canvas.circle(centrex - coords[0], centrey - coords[1], self.get("size"), fill=True, color='#000080')
pos, postime = my_mouse.get_pos()
my_canvas.fixdot(x=pos[0],y=pos[1])
my_canvas.show()
click, clickpos, clicktime = my_mouse.get_click(timeout=0)
# if button is clicked...
if click:
if RT1 == None:
RT1 = clicktime - t0
else:
RT2 = clicktime - t0
if (clickpos[0] > (centrex + coords[0] - (size))) and (clickpos[0] < (centrex + coords[0] + (size))):
if (clickpos[1] > (centrey + coords[1] - (size))) and (clickpos[1] < (centrey + coords[1] + (size))):
mouse_click[0] = True
my_canvas.circle(centrex + coords[0], centrey + coords[1], self.get("size"), fill=True, color='#000080')
if (clickpos[0] > (centrex - coords[0] - (size))) and (clickpos[0] < (centrex - coords[0] + (size))):
if (clickpos[1] > (centrey - coords[1] - (size))) and (clickpos[1] < (centrey - coords[1] + (size))):
mouse_click[1] = True
my_canvas.circle(centrex - coords[0], centrey - coords[1], self.get("size"), fill=True, color='#000080')
my_canvas.copy(exp.items[sketchpadname].canvas)
break
self.experiment.set("RT1", RT1)
self.experiment.set("RT2", RT2)
RTDIFF = (RT2 - RT1)
self.experiment.set("RTDIFF", RTDIFF)
Comments
hi, could you please format the code? i could try to help but it is unreadable...
Thanks Refuzee, I've used the multiple tilda method of indicating code to this wiki now... it looks better on my end (however the long lines still protrude past the white border... let me know if it is still unreadable, otherwise, I'll be super greatful for any input on the code! cheers/thanks!
Code looks fine here! What back-end are you using in your experiment? You will no-doubt experience delay in the running of your loop, because you do a lot of online drawing. PyGame (in the legacy and xpyriment back-ends), however, should still catch mouse clicks, even if they are made before
get_click
is called.ok, i was using xperyment, and now running psychopy it does collect all clicks in this version. in another version (more complex, using a 100 ms timer to register a click) it is still not functioning in either back end, plus my escape key doesn't work. I guess I'll have to go with simpler version for now (will post more complex code for interests sake).
if anyone sees another reason that the clicks are missed, let me know!
on another note, this psychopy backend has a problem with my use of mouse.set_pos... i use it to reset mouse position at the beginning of the trial, but in psychopy i get back this error:
response_error: Method set_pos not supported in pyglet environment
is there another way of resetting mouse position to center?!
thanks any help!
just an update... Here is a snippet of the code... in the first example, it misses clicks as i say above... in the second version, it seems to register all clicks... however its a very minor change, see below!
~
~~~
HOWEVER IF I COMMENT OUT THE ERROR LINE AND CHANGE ELIF TO IF, it registers every click!
~~~
~~
is there perhaps a way of collecting mouse clicks completely outside of this loop, like with a thread or something, so i can avoid Psychopy and therefore have access to the mouse.set_pos command?
well, thanks for the help... I solved it by using a longer delay on the mouse.get_click (10 second) this would halt the mouse entirely, however, i then simply enabled the windows mouse instead.
my_mouse = mouse(self.experiment, visible = True)
Hi,
Glad you solved this in the meantime. To answer your question on the setting of the mouse position: regrettably, this is not possible using the psycho back-end, due to the fact that PsychoPy's pyglet back-end does not support this.
On the commenting out of your
else
line: this helps, because you assume that every click was made in one of the regions. SoError = True
when there is a click outside of the regions you specify in theif
andelif
statements. This is probably not what you want.Depending on what you do with the
Error
variable, this could lead to a failure of registration of clicks.Good luck!