Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Supported by

[solved] mouse fails to register some clicks

edited May 2014 in OpenSesame

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

  • edited 11:11AM

    hi, could you please format the code? i could try to help but it is unreadable...

  • edited 11:11AM

    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!

  • edited 11:11AM

    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.

  • edited 11:11AM

    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!

  • edited 11:11AM

    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!

    ~

        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))):
                elif (clickpos[1] > (centrey - coords[1] - (size))) and (clickpos[1] < (centrey - coords[1] + (size))):
                    if mouse_click[0]:
                        mouse_click[1] = True
                        my_canvas.circle(centrex - coords[0], centrey - coords[1], self.get("size"), fill=True, color='#000080')
            else:
                Error = True
    

    ~~~
    HOWEVER IF I COMMENT OUT THE ERROR LINE AND CHANGE ELIF TO IF, it registers every click!
    ~~~

        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))):
                    if mouse_click[0]:
                        mouse_click[1] = True
                        my_canvas.circle(centrex - coords[0], centrey - coords[1], self.get("size"), fill=True, color='#000080')
            #else:
            #   Error = True
    

    ~~
    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?

  • edited 11:11AM

    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)

  • edited 11:11AM

    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. So Error = True when there is a click outside of the regions you specify in the if and elif 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!

Sign In or Register to comment.