Pygame + Joystick

Return to Code Snippets

Pygame + Joystick

Postby mushu » Mon Jan 15, 2007 5:45 pm

Hi,

Has anyone used Pygame's Joystick to read joystick input?
I've augmented the Basic Tutorial to init pygame and a joystick, but I can't seem to properly read the buttons.

E.g.
self.mJoystick.get_button(0) is never pygame.JOYBUTTONDOWN. But I am pushing on the button (I pushed every button just to be safe).

In fact, querying all the buttons on my joystick never results in a button down event (pygame returns 10 buttons were found with my controller).

I'm pretty sure I'm missing something since I'm new to Python and I'm jumping straight into Panda 3D. For example, I don't know how Tutorial 1 lesson (the solar system) constantly updates! More than likely my code is not frequently calling the function that polls the joystick buttons.

Any help would be appreciated!!! Thanks!
mushu
 
Posts: 1
Joined: Mon Jan 15, 2007 5:34 pm

Postby lettier » Mon Jan 15, 2007 6:08 pm

-
Last edited by lettier on Fri Mar 15, 2013 3:17 pm, edited 1 time in total.
lettier
 
Posts: 154
Joined: Tue Oct 18, 2005 7:28 pm

Postby Laurens » Tue Jan 16, 2007 4:32 am

I got my joystick to work using pygame. First I tried following the joystick part of the Panda3D manual on this site. However, that did not work. Like you, I did not receive the events when you press a button.

Next I tried this code snippet on the forum:
http://panda3d.org/phpbb2/viewtopic.php?t=1288
Works for me :) .
Laurens
 
Posts: 145
Joined: Sat Sep 23, 2006 5:08 am

pygame video system not initialized error

Postby ateene » Thu Jan 29, 2009 1:39 am

I'm getting the pygame "video system not initialized" error with the event.get() statement in the example code. Any idea what is casuing this?

Code: Select all
#Setup event information and print data from joystick
while 1:
    for e in event.get():
        if e.type != QUIT:
            print '%s: %s' % (event.event_name(e.type), e.dict)


Traceback (most recent call last):
File "foo.py", line 34, in <module>
for e in event.get():
pygame.error: video system not initialized
ateene
 
Posts: 3
Joined: Sat Jan 24, 2009 12:15 am

Postby Shaba1 » Thu Jan 29, 2009 11:37 am

From my perspective the problem with getting a joystick read in panda seems to be that panda and pygames have two seperate event systems. The problem seems to be getting the events from pygames into the event list of panda.

Yes I know that this does not add anything to the solution. If I were a better programmer I could add to it. But I will watch this thread to see if anyone has any ideas.
Shaba1
 
Posts: 195
Joined: Sat Sep 24, 2005 1:26 pm

Postby ateene » Thu Jan 29, 2009 12:43 pm

I found the problem; I had to initialize the pygame display

Code: Select all
from pygame import *

init()
display.init()

#Setup and init joystick
j=joystick.Joystick(0)
j.init()

#Check init status
if j.get_init() == 1: print "Joystick is initialized"

#Setup event information and print data from joystick
while 1:
    for e in event.get():
        if e.type != QUIT:
            print '%s: %s' % (event.event_name(e.type), e.dict)
ateene
 
Posts: 3
Joined: Sat Jan 24, 2009 12:15 am

Postby rwhughst » Thu Jan 29, 2009 2:04 pm

display.init()

Does this bring up a pygame window? I didnt have to do this to get pygame up and running.

Snippet from my Codes

Code: Select all
#way before other codes
pygame.init()


#in constructor
self.currentJoystick = pygame.joystick.Joystick(0)
self.currentJoystick.init()
numAxes = self.currentJoystick.get_numaxes()
---other logic here for what axes does what but oh well ---


#some other class file
for e in pygame.event.get():
            self.newR = self.currentJoystick.get_axis(self.X)
            self.newP = self.currentJoystick.get_axis(self.Y)
            self.newH = -self.currentJoystick.get_axis(self.RotateAxis)
rwhughst
 
Posts: 91
Joined: Tue Feb 26, 2008 6:30 pm

Postby Shaba1 » Thu Jan 29, 2009 3:02 pm

yeah but neither of those addresses how to get that info recognized by panda. You are both still working within pygame.
Shaba1
 
Posts: 195
Joined: Sat Sep 24, 2005 1:26 pm

Postby zuck » Thu Jan 29, 2009 4:55 pm

Well, this is my yesterday written snippet:

Code: Select all
__author__ = 'Emanuele Bertoldi <zuck@fastwebnet.it>'
__copyright__ = 'Copyright (c) 2009 Emanuele Bertoldi'

import pygame
from direct.showbase import DirectObject
from direct.showbase.MessengerGlobal import messenger

class JoystickHandler(DirectObject.DirectObject):
    def __init__(self):
        pygame.init()
       
        count = pygame.joystick.get_count()
        self.__joysticks = []
        for i in range(count):
            js = pygame.joystick.Joystick(i)
            js.init()
            self.__joysticks.append(js)

        taskMgr.add(self.__on_joystick_polling, 'Joystick Polling')
       
    def destroy(self):
        pygame.quit()
       
    def get_joysticks(self):
        return self.__joysticks
       
    def get_count(self):
        return len(self.__joysticks)
       
    def __on_joystick_polling(self, task):
        for ev in pygame.event.get():
       
            if ev.type is pygame.JOYBUTTONDOWN:
                name = 'joystick%d-button%d' % (ev.joy, ev.button)
                messenger.send(name)
               
            elif ev.type is pygame.JOYBUTTONUP:
                name = 'joystick%d-button%d-up' % (ev.joy, ev.button)
                messenger.send(name)
               
            elif ev.type is pygame.JOYAXISMOTION:
                name = 'joystick%d-axis%d' % (ev.joy, ev.axis)
                messenger.send(name, [ev.value])
               
            elif ev.type is pygame.JOYBALLMOTION:
                name = 'joystick%d-ball%d' % (ev.joy, ev.hat)
                messenger.send(name, [ev.rel])
               
            elif ev.type is pygame.JOYHATMOTION:
                name = 'joystick%d-hat%d' % (ev.joy, ev.hat)
                messenger.send(name, [ev.value])
   
        return task.cont


Now you can accept joystick input with the classical approach. For instance:

Code: Select all
class Player(JoystickHandler):
    def __init__(self):
        JoystickHandler.__init__(self)

        self.accept('joystick0-axis2', self.steer)
        self.accept('joystick0-button1', self.brake, [True])
        self.accept('joystick0-button1-up', self.brake, [False])
        self.accept('joystick1-button2', self.do_something)
        ...


It works for me ;)
Last edited by zuck on Sun Feb 01, 2009 2:49 pm, edited 3 times in total.
Emanuele Bertoldi
zuck
 
Posts: 115
Joined: Wed Dec 10, 2008 12:37 pm
Location: Udine, ITA

Postby kampfgnu » Fri Jan 30, 2009 3:24 pm

i also used pygame to support joypad input.
this class adds support for all buttons and sticks, which you can then accept to do something.
there is the dict "self.mapping", where i define some mappings, the first one is default. you could modify its values to set the right buttons/sticks to the right value.

Code: Select all
from pandac.PandaModules import *
import pygame as pg
from string import strip as strip

class joypad:
    def __init__(self):
        pg.init()
        self.padsConnected = False
        self.controllerType = []
        self.setupGamepads()
        self.runPads()
       
    def setupGamepads(self):       
        #Get the number of controllers so we know how many to init
        count = pg.joystick.get_count()
        if count == 0:
            self.padsConnected = False
#            print "no pads connected"
            return
        else: self.padsConnected = True
        #Initialize the controllers
        if count > 0:
            self.c1=pg.joystick.Joystick(0)
            self.c1.init()
            self.controllerType.append(strip(self.c1.get_name()))
        if count > 1:
            self.c2=pg.joystick.Joystick(1)
            self.c2.init()
            self.controllerType.append(strip(self.c2.get_name()))
        if count > 2:
            self.c3=pg.joystick.Joystick(2)
            self.c3.init()         
            self.controllerType.append(strip(self.c3.get_name()))
        if count > 3:
            self.c4=pg.joystick.Joystick(3)
            self.c4.init()
            self.controllerType.append(strip(self.c4.get_name()))
        #print "%i joypads inited" % count
       
        self.mapping = { "default" : {"NORTH-BUTTON":0, "EAST-BUTTON":1, "SOUTH-BUTTON":2, "WEST-BUTTON":3,
                                        "L1-BUTTON" : 4, "R1-BUTTON" : 5, "L2-BUTTON" : 6, "R2-BUTTON" : 7,
                                        "SELECT-BUTTON":8, "START-BUTTON":9,
                                        "L-STICK-BUTTON":10, "R-STICK-BUTTON":11,
                                        "L-STICK-X" : 0, "L-STICK-Y" : 1, "R-STICK-X" : 2, "R-STICK-Y" : 3,
                                        "HAT-WEST":(-1,0), "HAT-EAST":(1,0), "HAT-NORTH":(0,1), "HAT-SOUTH":(0,-1),
                                        "HAT-SOUTH-WEST":(-1,-1), "HAT-NORTH-WEST":(-1,1), "HAT-NORTH-EAST":(1,1), "HAT-SOUTH-EAST":(1,-1),
                                        "HATS-UP":(0,0)
                                        },
                        #my speedlink
                         "USB  Joystick" : {"NORTH-BUTTON":0, "EAST-BUTTON":1, "SOUTH-BUTTON":2, "WEST-BUTTON":3,
                                        "L1-BUTTON" : 4, "R1-BUTTON" : 5, "L2-BUTTON" : 6, "R2-BUTTON" : 7,
                                        "SELECT-BUTTON":8, "START-BUTTON":9,
                                        "L-STICK-BUTTON":10, "R-STICK-BUTTON":11,
                                        "L-STICK-X" : 0, "L-STICK-Y" : 1, "R-STICK-X" : 2, "R-STICK-Y" : 3,
                                        "HAT-WEST":(-1,0), "HAT-EAST":(1,0), "HAT-NORTH":(0,1), "HAT-SOUTH":(0,-1),
                                        "HAT-SOUTH-WEST":(-1,-1), "HAT-NORTH-WEST":(-1,1), "HAT-NORTH-EAST":(1,1), "HAT-SOUTH-EAST":(1,-1),
                                        "HATS-UP":(0,0)
                                        },
                         #my impact
                         "USB Game Controllers" : {"NORTH-BUTTON":1, "EAST-BUTTON":3, "SOUTH-BUTTON":2, "WEST-BUTTON":0,
                                        "L1-BUTTON" : 4, "R1-BUTTON" : 6, "L2-BUTTON" : 5, "R2-BUTTON" : 7,
                                        "SELECT-BUTTON":8, "START-BUTTON":9,
                                        "L-STICK-BUTTON":10, "R-STICK-BUTTON":11,
                                        "L-STICK-X" : 0, "L-STICK-Y" : 1, "R-STICK-X" : 3, "R-STICK-Y" : 2,
                                        "HAT-WEST":(-1,0), "HAT-EAST":(1,0), "HAT-NORTH":(0,1), "HAT-SOUTH":(0,-1),
                                        "HAT-SOUTH-WEST":(-1,-1), "HAT-NORTH-WEST":(-1,1), "HAT-NORTH-EAST":(1,1), "HAT-SOUTH-EAST":(1,-1),
                                        "HATS-UP":(0,0)
                                        },
                                       
                         "USB Joystick" : {"NORTH-BUTTON":0, "EAST-BUTTON":1, "SOUTH-BUTTON":2, "WEST-BUTTON":3,
                                        "L1-BUTTON" : 4, "R1-BUTTON" : 5, "L2-BUTTON" : 6, "R2-BUTTON" : 7,
                                        "SELECT-BUTTON":8, "START-BUTTON":9,
                                        "L-STICK-BUTTON":10, "R-STICK-BUTTON":11,
                                        "L-STICK-X" : 0, "L-STICK-Y" : 1, "R-STICK-X" : 2, "R-STICK-Y" : 3,
                                        "HAT-WEST":(-1,0), "HAT-EAST":(1,0), "HAT-NORTH":(0,1), "HAT-SOUTH":(0,-1),
                                        "HAT-SOUTH-WEST":(-1,-1), "HAT-NORTH-WEST":(-1,1), "HAT-NORTH-EAST":(1,1), "HAT-SOUTH-EAST":(1,-1),
                                        "HATS-UP":(0,0)
                                        }
                         }
   
    def runPads(self):
        if self.padsConnected:
            taskMgr.add(self.gamepadPollingTask, "gamepadPollingTask")
                               
    def gamepadPollingTask(self, task):
        for e in pg.event.get():
#            print e
            #Get which controller this is and add it to the eventName
            if e.dict["joy"] == 0:
                c_number = "C1_"
                c_type = 0
            elif e.dict["joy"] == 1:
                c_number = "C2_"
                c_type = 1
            elif e.dict["joy"] == 2:
                c_number = "C3_"
                c_type = 2
            elif e.dict["joy"] == 3:
                c_number = "C4_" 
                c_type = 3
           
            if self.mapping.has_key(self.controllerType[c_type]):
                type = self.controllerType[c_type]
            else:
                type = "default"
            #Handle the BUTTON DOWN events
            if e.type == pg.JOYBUTTONDOWN:
                if (e.dict["button"] == self.mapping[type]["NORTH-BUTTON"]):
                    eventName = c_number +  "NORTH-BUTTON_DOWN"
                    messenger.send(eventName, [])
                elif (e.dict["button"] == self.mapping[type]["EAST-BUTTON"]):
                    eventName = c_number +  "EAST-BUTTON_DOWN"
                    messenger.send(eventName, [])
                elif (e.dict["button"] == self.mapping[type]["SOUTH-BUTTON"]):
                    eventName = c_number +  "SOUTH-BUTTON_DOWN"
                    messenger.send(eventName, [])
                elif (e.dict["button"] == self.mapping[type]["WEST-BUTTON"]):
                    eventName = c_number +  "WEST-BUTTON_DOWN"
                    messenger.send(eventName, [])
                elif (e.dict["button"] == self.mapping[type]["L1-BUTTON"]):
                    eventName = c_number +  "L1-BUTTON_DOWN"
                    messenger.send(eventName, [])
                elif (e.dict["button"] == self.mapping[type]["R1-BUTTON"]):
                    eventName = c_number +  "R1-BUTTON_DOWN"
                    messenger.send(eventName, [])
                elif (e.dict["button"] == self.mapping[type]["L2-BUTTON"]):
                    eventName = c_number +  "L2-BUTTON_DOWN"
                    messenger.send(eventName, [])
                elif (e.dict["button"] == self.mapping[type]["R2-BUTTON"]):
                    eventName = c_number +  "R2-BUTTON_DOWN"
                    messenger.send(eventName, [])
                elif (e.dict["button"] == self.mapping[type]["SELECT-BUTTON"]):
                    eventName = c_number +  "SELECT-BUTTON_DOWN"
                    messenger.send(eventName, [])
                elif (e.dict["button"] == self.mapping[type]["START-BUTTON"]):
                    eventName = c_number +  "START-BUTTON_DOWN"
                    messenger.send(eventName, [])
                elif (e.dict["button"] == self.mapping[type]["L-STICK-BUTTON"]):
                    eventName = c_number +  "L-STICK-BUTTON_DOWN"
                    messenger.send(eventName, [])
                elif (e.dict["button"] == self.mapping[type]["R-STICK-BUTTON"]):
                    eventName = c_number +  "R-STICK-BUTTON_DOWN"
                    messenger.send(eventName, [])       
                             
#                                                                                                                                               
            #Handle the BUTTONUP events
            elif e.type == pg.JOYBUTTONUP:
                if (e.dict["button"] == self.mapping[type]["NORTH-BUTTON"]):
                    eventName = c_number +  "NORTH-BUTTON_UP"
                    messenger.send(eventName, [])
                elif (e.dict["button"] == self.mapping[type]["EAST-BUTTON"]):
                    eventName = c_number +  "EAST-BUTTON_UP"
                    messenger.send(eventName, [])
                elif (e.dict["button"] == self.mapping[type]["SOUTH-BUTTON"]):
                    eventName = c_number +  "SOUTH-BUTTON_UP"
                    messenger.send(eventName, [])
                elif (e.dict["button"] == self.mapping[type]["WEST-BUTTON"]):
                    eventName = c_number +  "WEST-BUTTON_UP"
                    messenger.send(eventName, [])
                elif (e.dict["button"] == self.mapping[type]["L1-BUTTON"]):
                    eventName = c_number +  "L1-BUTTON_UP"
                    messenger.send(eventName, [])
                elif (e.dict["button"] == self.mapping[type]["R1-BUTTON"]):
                    eventName = c_number +  "R1-BUTTON_UP"
                    messenger.send(eventName, [])
                elif (e.dict["button"] == self.mapping[type]["L2-BUTTON"]):
                    eventName = c_number +  "L2-BUTTON_UP"
                    messenger.send(eventName, [])
                elif (e.dict["button"] == self.mapping[type]["R2-BUTTON"]):
                    eventName = c_number +  "R2-BUTTON_UP"
                    messenger.send(eventName, [])
                elif (e.dict["button"] == self.mapping[type]["SELECT-BUTTON"]):
                    eventName = c_number +  "SELECT-BUTTON_UP"
                    messenger.send(eventName, [])
                elif (e.dict["button"] == self.mapping[type]["START-BUTTON"]):
                    eventName = c_number +  "START-BUTTON_UP"
                    messenger.send(eventName, [])
                elif (e.dict["button"] == self.mapping[type]["L-STICK-BUTTON"]):
                    eventName = c_number +  "L-STICK-BUTTON_UP"
                    messenger.send(eventName, [])
                elif (e.dict["button"] == self.mapping[type]["R-STICK-BUTTON"]):
                    eventName = c_number +  "R-STICK-BUTTON_UP"
                    messenger.send(eventName, [])
                                                   
            #Handle the directional pad
            elif e.type == pg.JOYHATMOTION:
                if (e.dict["value"] == self.mapping[type]["HAT-NORTH"]):
                    eventName = c_number +  "HAT-NORTH_DOWN"
                    messenger.send(eventName, [])
                elif (e.dict["value"] == self.mapping[type]["HAT-EAST"]):
                    eventName = c_number +  "HAT-EAST_DOWN"
                    messenger.send(eventName, [])
                elif (e.dict["value"] == self.mapping[type]["HAT-SOUTH"]):
                    eventName = c_number +  "HAT-SOUTH_DOWN"
                    messenger.send(eventName, [])
                elif (e.dict["value"] == self.mapping[type]["HAT-WEST"]):
                    eventName = c_number +  "HAT-WEST_DOWN"
                    messenger.send(eventName, [])
                elif (e.dict["value"] == self.mapping[type]["HAT-SOUTH-WEST"]):
                    eventName = c_number +  "HAT-SOUTH-WEST_DOWN"
                    messenger.send(eventName, [])
                elif (e.dict["value"] == self.mapping[type]["HAT-NORTH-WEST"]):
                    eventName = c_number +  "HAT-NORTH-WEST_DOWN"
                    messenger.send(eventName, [])
                elif (e.dict["value"] == self.mapping[type]["HAT-NORTH-EAST"]):
                    eventName = c_number +  "HAT-NORTH-EAST_DOWN"
                    messenger.send(eventName, [])
                elif (e.dict["value"] == self.mapping[type]["HAT-SOUTH-EAST"]):
                    eventName = c_number +  "HAT-SOUTH-EAST_DOWN"
                    messenger.send(eventName, [])
                elif (e.dict["value"] == self.mapping[type]["HATS-UP"]):
                    eventName = c_number +  "HATS-UP"
                    messenger.send(eventName, [])
                 
                   
            #Handle the analog sticks
            elif e.type == pg.JOYAXISMOTION:
                #Handle the left analog stick X axis
                if (e.dict["axis"] == self.mapping[type]["L-STICK-X"]):
                    if (e.dict["value"] != 0):
                        eventName = c_number +  "L-STICK-X"
                        messenger.send(eventName, [e.dict["value"]])
                                                                                                     
                #Handle the left analog stick Y axis
                elif (e.dict["axis"] == self.mapping[type]["L-STICK-Y"]):
                    if (e.dict["value"] != 0):
                        eventName = c_number +  "L-STICK-Y"
                        messenger.send(eventName, [e.dict["value"]])             
#                       
                #Handle the right analog stick X axis
                elif (e.dict["axis"] == self.mapping[type]["R-STICK-X"]):
                    if (e.dict["value"] != 0):
                        eventName = c_number +  "R-STICK-X"
                        messenger.send(eventName, [e.dict["value"]])   
                                                                               
                #Handle the right analog stick Y axis
                elif (e.dict["axis"] == self.mapping[type]["R-STICK-Y"]):
                    if (e.dict["value"] != 0):
                        eventName = c_number +  "R-STICK-Y"
                        messenger.send(eventName, [e.dict["value"]])
                                                                             
        return task.cont


then import the class into your code and initialze it:
Code: Select all
self.controllers = joypad()

and to accept events, for example for controller1:
Code: Select all
self.accept('C1_NORTH-BUTTON_UP', self.doSomething)

to read the stick-values constantly, start a task and just read the stick-axis-value:
Code: Select all
x = self.controllers.c1.get_axis(0)
User avatar
kampfgnu
 
Posts: 94
Joined: Thu Nov 22, 2007 10:29 pm
Location: austria, vienna

Postby Shaba1 » Fri Feb 06, 2009 10:26 am

Thank you zuck and kampfgnu: This took the mystery out of getting pygames recongized in panda.,
Shaba1
 
Posts: 195
Joined: Sat Sep 24, 2005 1:26 pm

Postby fax8 » Wed Feb 22, 2012 5:36 am

Thanks zuck and kampfgnu, great work here!
fax8
 
Posts: 11
Joined: Mon Jun 13, 2011 10:15 am
Location: Torino, Italy


Return to Code Snippets

Who is online

Users browsing this forum: No registered users and 1 guest