Howdy, Stranger!

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

Supported by

[solved] using joystick axis and using it's input to alter the sketchpad

edited May 2014 in OpenSesame

Hi, I'm extremely new to opensesame, and I'm trying to make an Approach Avoidance task.
This means that I need to increase the font size (got that working) based on participant input (question 2) from the y-axis of a Logitech ATT3 (question 1).

so here are my questions:

  1. How do I find the number for the Y-axis, and how do set this as the only correct response?

  2. How do I set any participant input (and in this case the Y-axis) to increase/alter anything on the sketchpad?
    Ive figured out how to log it, or set it as correct etc, but not how to move to a different state in a loop fashion.

Any help is appreciated!

Comments

  • edited February 2013

    Hi,

    1 Try this script (add it to the run phase of an inline_script, placed after a joystick item) and mess about with the joystick:

    from openexp.canvas import canvas
    from libjoystick import libjoystick
    
    # create canvas object
    canvas = canvas(exp)
    canvas.clear()
    
    # create joystick object
    joystick = libjoystick(exp,joybuttonlist=None,timeout=None)
    
    # create basic canvas
    joyinputs = joystick.input_options() # returns: [buttons, axes, balls, hats]
    joyinputtypes = ["buttons", "axes", "balls", "hats"]
    for i in range(0,len(joyinputtypes)):
        disptext = "You have <b>" + str(joyinputs[i]) + "</b> " + joyinputtypes[i]
        canvas.text(disptext, center=True, y=100+i*50,html=True)
    canvas.show()
    
    # joystick interaction
    stop = False
    timeout = 20000 # ms
    t0 = self.time()
    while not stop:
        # get input
        eventtype, value, time = joystick.get_joyinput(timeout=10)
        # present input
        if eventtype != None:
            # reset canvas
            canvas.rect(0, self.get("height")/2, self.get("width"), self.get("height")/2, fill=True, color=self.get("background"))
            # update canvas
            canvas.text(eventtype, center=True, y=self.get("height")/2+50)
            canvas.text(value, center=True, y=self.get("height")/2+100)
            canvas.show()
        # stop
        if self.time() - t0 > timeout:
            stop=True
    

    It should give you the number of buttons, axes, hats and balls you have on your joystick, as well as giving you the opportunity to mess about with the joystick for 20 seconds, while showing which buttons or axes you are moving (i.e.: when you move the stick, it could read something like "joyaxes motion [0.88989 0.122332 -1]", where the changing number in between the brackets is the axis you are currently moving).

    2 You should use an inline_script as above. Accessing the axes is easy if you use:
    eventtype, value, time = joystick.get_joyinput()

    This will provide you with an eventtype (a string, which tells you what kind of input has been given (e.g. 'joybuttonpress' or 'joyaxismotion' etc.), a value for that eventtype (e.g. 4 or [0.5 0.3 -1]) and a timestamp for the input. A little sample script (for an inline_script item), for increasing a text size:

    from openexp.canvas import canvas
    from libjoystick import libjoystick
    
    # create canvas object
    canvas = canvas(exp)
    canvas.clear()
    
    # create joystick object
    joystick = libjoystick(exp,joybuttonlist=None,timeout=None)
    axisnr = 1 # (position of the relevant axis, start counting at 0: [0 1 2])
    
    # text
    textsize = 20 # starting size
    sizegain = 10 # factor to multiply axis state with (growth speed)
    
    # joystick interaction
    stop = False
    prevvalue = 0
    while not stop:
        # get input
        eventtype, value, time = joystick.get_joyinput(timeout=10)
        # use input
        if eventtype == 'joybuttonpress':
            stop = True
        elif eventtype == 'joyaxismotion':
            textsize += value[axisnr]*sizegain # add axis value to textsize (i.e.: add a number between -1 and 1)
            prevvalue = value[:]
        elif prevvalue and eventtype == None:
            textsize += prevvalue[axisnr]*sizegain # add axis value to textsize (i.e.: add a number between -1 and 1)
        canvas.set_font(size=int(textsize))
        # prevent textsize from going under 0
        if textsize < 0:
            textsize = 0
        # present text
        canvas.text("Textsize = " + str(int(textsize)), center=True)
        canvas.show()
        # reset canvas
        canvas.clear()
    
    # save textsize variable
    exp.set("textsize", textsize)
    

    For a sample experiment (that is, this inline_script at work in an opensesame-file), see here.

    Good luck!

  • edited February 2013

    Thank you for the clear instructions, I've started from the .opensesame file you linked and am happily coding away. sorted my error aswell. Using t_text = exp.get("t_text") to import the not automatically available text string that is in the master loop. So now my participants (me atm) can see the stimulus text instead of something fixed :)

  • edited January 2014

    Hi, I'm also extremely new to opensesame, and I'm trying to make an Approach Avoidance task.

    I have questions :

    1. How I can import some words and/or pictures ?
    2. I would like that the position when words or pictures appears is 0 and if people pull the Joystick the score will be positive and if people push the joystick, the score will be negative. How I can have it?
    3. is it possible to have a picture as background ?

    I'm sorry maybe it's easy questions.

    All help is appreciated!
    Thank you !

  • edited 12:24PM

    Hi Marie,

    Welcome to the forum! Building an Approach Avoidance task is certainly possible with OpenSesame.

    Did you already go through the step-by-step tutorial? I think by doing that, you'll already find an answer to the 1st and 3rd question.

    Did you already try to build something yourself? And if so, where did it go wrong?

    If you have any more specific questions, perhaps you could provide us with your experimental script, and we could have a closer look at it.

    To upload your experiment you could do the following:

    • Open the "General properties" tab, click "Script editor" and copy the whole script,
    • go to http://pastbin.com, upload your script there (simply paste and submit)
    • and provide us with the resulting link in your forum post.

    Cheers,

    Lotje

    Did you like my answer? Feel free to Buy Me A Coffee :)

  • edited 12:24PM

    Hi Ivanderlinden,

    Thank you very much for your help.
    I read the tutorial. for the question 1, I see that I can use the function .get but I don't know where I must to put it in the script.
    I base on the script of Edwin (see his answer just before my question).
    I try to adapt this script.
    http://pastebin.com/pABPVRA1

    More precisely, in the "'define inline_script inline_script", I try to put a function .get but when I run the words list don't move.

    For the question 2, I would like that the initial position of words is 0. How is possible to have the coordinates of each words?

    Thank you !

  • edited 12:24PM

    Hi Marie,

    The tricky part in your case is to collect the joystick movement. Other than that, you probably won't need any inline coding. So let's get to the joystick part, and from there you'll probably be able to figure things out with help from the tutorial.

    Basically, you want to wait until the participant pushes the joystick up or down, and then set an experimental variable (move_joystick) to 'up' or 'down' depending on the participant's response. Once this variable has been set, you can simply use it in the OpenSesame GUI, for example in a Run-if statement that determines which sketchpad comes next. Again, that's all explained in the tutorials, the hard part is collecting the joystick response.

    So ... you can collect joystick movement with the script below. You should put this code in the run phase of an inline_script that follows the presentation of the target word. In addition, you should insert a joystick plug-in item somewhere in your experiment, because that is needed to initialize the joystick. Even if you don't use the plug-in, it still has to be there, and you can disable it by setting its run-if statement to 'never'. Does that make sense?

    # Loop until a response is given
    while True:
        # Get a joystick movement
        movement, timestamp = exp.joystick.get_joyaxes()
        # `movement` is a tuple indicating the horizontal and vertical movement.
        dx, dy = movement
        # If there is vertical movement, set the variable `move_joystick` to up or
        # down, and break the loop.
        if dy < 0:
            exp.set('move_joystick', 'up')
            break
        elif dy > 0:
            exp.set('move_joystick', 'down')
            break
    

    Cheers!
    Sebastiaan

  • edited 12:24PM

    Hi Sebastiaan,

    Thank you very much for your answer.

    But I need to see the size of word or picture increased when participants push and decreased when they pull.

    When I try this code, I had a error message. ("Python: too many values to unpack")

    I don't know where is the problem.

    Thank you for your help !

  • edited February 2014

    The error most likely comes from this line:

    dx, dy = movement
    

    As a lot of joysticks will have an output of three axes, the following line should fix this:

    dx, dy, dz = movement
    

    Alternatively, you could simply use the second axis without bothering to unpack the rest:

    # Loop until a response is given
    while True:
        # Get a joystick movement
        movement, timestamp = exp.joystick.get_joyaxes()
        # `movement` is a tuple indicating the movement over all axes,
        # but we only need the second (index 1, as Python starts counting at 0)
        dy = movement[1]
        # If there is vertical movement, set the variable `move_joystick` to up or
        # down, and break the loop.
        if dy < 0:
            exp.set('move_joystick', 'up')
            break
        elif dy > 0:
            exp.set('move_joystick', 'down')
            break
    

    Regarding your original question: my sample script already increases the text on pushing, and decreases on pulling, right? If you want to apply this to a picture, you can use the canvas' image function, which allows you to use the keyword scale.

    In my sample script the variable name textsize is used for the textsize, but you could easily do a similar thing with a variable you name picsize. Keep in mind that this should have a lower value that the textsize, as the scale is a proportion of the original image! So you'll likely want to use values between 0.5 (half size) and 2 (twice the size).

    Alternatively, as Sebastiaan suggests, you could use the variable move_joystick to change something via OpenSesame's graphical interface. E.g. using the show if statement of a sketchpad in which you have drawn a small image: show if [move_joystick] = 'down'.

    Does that help you at all?

  • edited 12:24PM

    Hi Edwin,

    Thank you for your help. I have no error message. It's a interesting alternative. I add it in my script.

    In your sample script, can you say me how and where I can import automatically a text variable that is in the precedent loop ?

    I try : t_text = self.get("t_text") but It's doesn't work.
    I'm too bad :-(

    Thank you.

  • edited 12:24PM

    Hi Marie,

    That's good news!

    You are in fact using the right code, so I wonder if you are using the correct variable name and if it is defined in the preceding loop.

    Example:

    1. Define a variable called disptext in a loop.

    2. In the sequence attached to that loop, place the sample script above.

    3. Adjust the following line from the example:

    original:

    canvas.text("Textsize = " + str(int(textsize)), center=True)
    

    replace with:

    canvas.text(self.get("disptext"), center=True)
    

    Does that do the trick?

  • edited 12:24PM

    Hi Edwin,

    Thank you so much. I had just a mistake in my script. Now it's ok.

    A last question, I want to specify the joystick response (button 1) and that this response is the end of my trial.

    eventtype, value, time = joystick.get_joyinput(joybuttonlist=[1], timeout=10)

    But I have this message :
    TypeError: argument of type 'int' is not iterable

    I forget someting ?

  • edited February 2014

    Hi Marie,

    The error suggests that the joybuttonlist is not passed as a list (i.e. in square brackets: [1]), but rather as an integer (i.e. as a single number: 1).

    I've checked the source code of the plug-in, and I don't see any reason for why this happens if you, as you indicate, pass the joybuttonlist as a list: joybuttonlist=[1]. I can't test this in practice either, since I do not have a joystick around.

    What you could try, is an alternative approach, in which you handle the recognition of the correct button yourself. See the code snippet below for an example of what I mean.

    # get the joystick input
    eventtype, value, time = joystick.get_joyinput(joybuttonlist, timeout=10)
    
    # check the eventtype for buttonpresses
    if eventtype == 'joybuttonpress':
        # check if the button is button 1
        if value == 1:
            # we have now established the button was 1,
            # so now you can do what you want, e.g.:
            exp.set("response", value)
    

    Alternatively, the more elegant solution would be to check for both conditions at once:

    # get the joystick input
    eventtype, value, time = joystick.get_joyinput(joybuttonlist, timeout=10)
    
    # check the eventtype for presses of button 1
    if eventtype == 'joybuttonpress' and value == 1:
            exp.set("response", value)
    

    Does this resolve your issue?

  • edited 12:24PM

    Hi Edwin,

    I'll try and I'll let you know.

    Thank you very much,

  • edited May 2014

    Hi, this was very helpful:

    image

    but i have problems to get my 'move_joystick' logged. logger is not working anymore.
    debug windows says:

    image

    as u see i have figured out how to log time, but i want to log also variables like move_joystick, cr, fname... dont know how.

    pls tell asap, thanks a lot

    Best greetings
    Gregor

  • edited 12:24PM

    Have you defined a variable name using only numerical values? E.g. "10".

    Also, why are you using self.log in the inline_script to log a timestamp? Wouldn't it make more sense to set the timestamp as on OpenSesame variable, so that it will get picked up by the logger straight away? Like so:

    exp.set("t0", self.time())
    
    # rest of code
    
    exp.set("t1", self.time())
    exp.set("response_time", exp.get("t1") - exp.get("t0"))
    
Sign In or Register to comment.

agen judi bola , sportbook, casino, togel, number game, singapore, tangkas, basket, slot, poker, dominoqq, agen bola. Semua permainan bisa dimainkan hanya dengan 1 ID. minimal deposit 50.000 ,- bonus cashback hingga 10% , diskon togel hingga 66% bisa bermain di android dan IOS kapanpun dan dimana pun. poker , bandarq , aduq, domino qq , dominobet. Semua permainan bisa dimainkan hanya dengan 1 ID. minimal deposit 10.000 ,- bonus turnover 0.5% dan bonus referral 20%. Bonus - bonus yang dihadirkan bisa terbilang cukup tinggi dan memuaskan, anda hanya perlu memasang pada situs yang memberikan bursa pasaran terbaik yaitu http://45.77.173.118/ Bola168. Situs penyedia segala jenis permainan poker online kini semakin banyak ditemukan di Internet, salah satunya TahunQQ merupakan situs Agen Judi Domino66 Dan BandarQ Terpercaya yang mampu memberikan banyak provit bagi bettornya. Permainan Yang Di Sediakan Dewi365 Juga sangat banyak Dan menarik dan Peluang untuk memenangkan Taruhan Judi online ini juga sangat mudah . Mainkan Segera Taruhan Sportbook anda bersama Agen Judi Bola Bersama Dewi365 Kemenangan Anda Berapa pun akan Terbayarkan. Tersedia 9 macam permainan seru yang bisa kamu mainkan hanya di dalam 1 ID saja. Permainan seru yang tersedia seperti Poker, Domino QQ Dan juga BandarQ Online. Semuanya tersedia lengkap hanya di ABGQQ. Situs ABGQQ sangat mudah dimenangkan, kamu juga akan mendapatkan mega bonus dan setiap pemain berhak mendapatkan cashback mingguan. ABGQQ juga telah diakui sebagai Bandar Domino Online yang menjamin sistem FAIR PLAY disetiap permainan yang bisa dimainkan dengan deposit minimal hanya Rp.25.000. DEWI365 adalah Bandar Judi Bola Terpercaya & resmi dan terpercaya di indonesia. Situs judi bola ini menyediakan fasilitas bagi anda untuk dapat bermain memainkan permainan judi bola. Didalam situs ini memiliki berbagai permainan taruhan bola terlengkap seperti Sbobet, yang membuat DEWI365 menjadi situs judi bola terbaik dan terpercaya di Indonesia. Tentunya sebagai situs yang bertugas sebagai Bandar Poker Online pastinya akan berusaha untuk menjaga semua informasi dan keamanan yang terdapat di POKERQQ13. Kotakqq adalah situs Judi Poker Online Terpercayayang menyediakan 9 jenis permainan sakong online, dominoqq, domino99, bandarq, bandar ceme, aduq, poker online, bandar poker, balak66, perang baccarat, dan capsa susun. Dengan minimal deposit withdraw 15.000 Anda sudah bisa memainkan semua permaina pkv games di situs kami. Jackpot besar,Win rate tinggi, Fair play, PKV Games