L'idée ici est d'utiliser un joypad pour piloter un micro controller via sans fil (type bluetooth).
Je n'explique pas le bluetooth dans cet exemple, cela fera éventuellement l'objet d'un autre article, et je me contente juste d'attirer l'attention sur la partie joypad et utilisation d'une lib python.
La librairie python INPUTS permet de piloter des entrées tels que: Clavier, Souris, Joypad
Mes test ont été faits sous windows 10, avec python 2.7
Sous windows cette lib ne permet d'utiliser que le joypad XBox360
Je me suis basé sur cette image pour le mapping de mes variables:
![]() |
Joypad XBOX 360 |
En premier lieux: installer la lib; en CMD tapper : ( tout est expliqué ici : INPUTS )
pip install inputs
L'exemple de code qui va suivre, utilise les threads en python.
Pour mon projet j'ai utilisé les threads, car la commande principale qui lisait les événements du gamepad, interrompaient tout autre processus. Donc avec le muli-threads, cela ne pose plus de problème pour les taches annexes.
Code:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# gamepad.py | |
# | |
# Copyright 2018 Francois De Bue | |
# | |
# This program show how work with game pad and a thread | |
# This was used to drive a robot with arduino | |
from threading import Thread | |
from inputs import get_gamepad | |
class XPAD(Thread): # def class typr thread | |
def __init__(self): | |
Thread.__init__(self) # thread init class (don't forget this) | |
self.A = 0 # all vars of gamepad, set init val to 0 | |
self.B = 0 | |
self.X = 0 | |
self.Y = 0 | |
self.LBumper = 0 | |
self.RBumper = 0 | |
self.LThumb = 0 | |
self.RThumb = 0 | |
self.LTrigger = 0 | |
self.RTrigger = 0 | |
self.Back = 0 | |
self.Start = 0 | |
self.LStickX = 0 | |
self.LStickY = 0 | |
self.RStickX = 0 | |
self.RStickY = 0 | |
self.DPadX = 0 | |
self.DPadY = 0 | |
def run(self): # run is a default Thread function | |
while True: # loop for ever | |
for event in get_gamepad(): # check events of gamepads, if not event, all is stop | |
if event.ev_type == "Key": # category of binary respond values | |
if event.code == "BTN_SOUTH": | |
self.A = event.state | |
elif event.code == "BTN_EAST": | |
self.B = event.state | |
elif event.code == "BTN_WEST": | |
self.X = event.state | |
elif event.code == "BTN_NORTH": | |
self.Y = event.state | |
elif event.code == "BTN_TL": | |
self.LBumper = event.state | |
elif event.code == "BTN_TR": | |
self.RBumper = event.state | |
elif event.code == "BTN_THUMBL": | |
self.LThumb = event.state | |
elif event.code == "BTN_THUMBR": | |
self.RThumb = event.state | |
elif event.code == "BTN_START": | |
self.Back = event.state | |
elif event.code == "BTN_SELECT": | |
self.Start = event.state | |
elif event.ev_type == "Absolute": # category of analog values | |
# some values are from -32000 to 32000, or -256 to 256 | |
# here all values are mapped from -512 to 512 by bitshifting | |
if event.code[-1:] == "Z": | |
event.state = event.state<<1 # reduce range from 256 to 512 | |
else: | |
event.state = event.state>>6 # reduce range from 32000 to 512 | |
if event.state < 40 and event.state > -40: # dead zone of my joypad, check this one for yours | |
event.state = 0 | |
if event.code == "ABS_Z": | |
self.LTrigger = event.state | |
elif event.code == "ABS_RZ": | |
self.RTrigger = event.state | |
elif event.code == "ABS_X": | |
self.LStickX = event.state | |
elif event.code == "ABS_Y": | |
self.LStickY = event.state | |
elif event.code == "ABS_RX": | |
self.RStickX = event.state | |
elif event.code == "ABS_RY": | |
self.RStickY = event.state | |
elif event.code == "ABS_HAT0Y": | |
self.DPadX = event.state | |
elif event.code == "ABS_HAT0X": | |
self.DPadY = event.state | |
# sample to use 2 channels | |
# insert your code here, if you want to compute different mode from your joypad | |
if (self.LStickX+self.LStickY)>20: | |
print( "LstickX: {}, LStickY: {}".format (self.LStickX,self.LStickY)) | |
if (self.RStickX+self.RStickY)>20: | |
print( "RstickX: {}, RStickY: {}".format (self.RStickX,self.RStickY)) | |
def main(): | |
''' with gamepad thread, count continue all the time ''' | |
gamePad = XPAD() # creation thread joypad | |
count = 0 # count represent continuity of your code | |
gamePad.start() # start of gamepad thread, to read input of game pad (multitasking forever) | |
while True: | |
count = count + 1 # your code | |
if gamePad.A != 0: # your interaction | |
count = count - 100 | |
print ("Count value: {}").format(count) | |
print count | |
gamePad.joint() # wait the end of joypad thread | |
if __name__ == "__main__": | |
main() | |
Aucun commentaire:
Enregistrer un commentaire