I am trying to use pygame with the raspberry pi to use a PlayStation 3 controller as an input for a car. I have tested the controller with a demo code, and everything works fine. Then when I try to use it in my program, it reads 0.0 as the input, when the joysticks are moved. attached is my current code:
import pygame
class controller:
def __init__(self):
pygame.init()
pygame.joystick.init()
global joystick
joystick = pygame.joystick.Joystick(0)
joystick.init()
def get_value(self, axis):
value = joystick.get_axis(axis)
return value
control = controller()
val = control.get_value(0)
while True:
print(val)
I am aware that this test is only for axis 0, but the output is still 0.0 for all axes.
Below, i have attached the demo code, where all the values are properly read.
import pygame, sys, time #Imports Modules
from pygame.locals import *
pygame.init()#Initializes Pygame
pygame.joystick.init()
joystick = pygame.joystick.Joystick(0)
joystick.init()#Initializes Joystick
# get count of joysticks=1, axes=27, buttons=19 for DualShock 3
joystick_count = pygame.joystick.get_count()
print("joystick_count")
print(joystick_count)
print("--------------")
numaxes = joystick.get_numaxes()
print("numaxes")
print(numaxes)
print("--------------")
numbuttons = joystick.get_numbuttons()
print("numbuttons")
print(numbuttons)
print("--------------")
loopQuit = False
while loopQuit == False:
# test joystick axes and prints values
outstr = ""
for i in range(0,4):
axis = joystick.get_axis(i)
outstr = outstr + str(i) + ":" + str(axis) + "|"
print(outstr)
# test controller buttons
outstr = ""
for i in range(0,numbuttons):
button = joystick.get_button(i)
outstr = outstr + str(i) + ":" + str(button) + "|"
print(outstr)
for event in pygame.event.get():
if event.type == QUIT:
loopQuit = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
loopQuit = True
# Returns Joystick Button Motion
if event.type == pygame.JOYBUTTONDOWN:
print("joy button down")
if event.type == pygame.JOYBUTTONUP:
print("joy button up")
if event.type == pygame.JOYBALLMOTION:
print("joy ball motion")
# axis motion is movement of controller
# dominates events when used
if event.type == pygame.JOYAXISMOTION:
# print("joy axis motion")
time.sleep(0.01)
pygame.quit()
sys.exit()
any feedback will be much appreciated.
The code is losing the reference to the initialised joystick. It needs to maintain an internal link to it. Note the use of self.
in the class below. This keeps the reference inside the class, making "self.joystick" a member variable of the class. Python classes need the self.
notation (unlike lots of (all?) other object orientated languages). While editing I changed some of the names to match the Python PEP-8 style guide, I hope that's OK ;)
class Controller:
def __init__( self, joy_index=0 ):
pygame.joystick.init() # is it OK to keep calling this?
self.joystick = pygame.joystick.Joystick( joy_index )
self.joystick.init()
def getAxisValue( self, axis ):
value = self.joystick.get_axis( axis )
return value
Maybe you left the extra code out of the question, but a PyGame program without an event loop will eventually lock up.
import pygame
# Window size
WINDOW_WIDTH = 300
WINDOW_HEIGHT = 300
class Controller:
""" Class to interface with a Joystick """
def __init__( self, joy_index=0 ):
pygame.joystick.init()
self.joystick = pygame.joystick.Joystick( joy_index )
self.joystick.init()
def getAxisValue( self, axis ):
value = self.joystick.get_axis( axis )
return value
### initialisation
pygame.init()
window = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ) )
clock = pygame.time.Clock()
pygame.display.set_caption( "Any Joy?" )
# Talk to the Joystick
control = controller()
# Main loop
done = False
while not done:
for event in pygame.event.get():
if ( event.type == pygame.QUIT ):
done = True
# Query the Joystick
val = control.getAxisValue( 0 )
print( "Joystick Axis: " + str( val ) )
# Update the window, but not more than 60fps
window.fill( (0,0,0) )
pygame.display.flip()
clock.tick_busy_loop(60)
pygame.quit()