ev3dev – wireless gamepad

This post is part 3 of 9 of  AD4M4ST0R - um rover LEGO

O gamepad utilizado no AD4M4ST0R é um “Gioteck VX-2 Wireless Controller” comprado na FNAC por €19.99. Qualquer modelo compatível com PC deverá funcionar, desde que use um dongle USB (os modelos por cabo USB também funcionarão mas não servem para o caso). Quando o stack bluetooth estiver funcional no ev3dev também deverão funcionar gamepads desse tipo

gamepadO gamepad é reconhecido automaticamente como um gamepad e como um disposito de classe OHCI:

root@ev3dev:~# dmesg
(...)
usb 1-1.4: new full-speed USB device number 4 using ohci
hid-generic 0003:25F0:83C2.0001: usb_submit_urb(ctrl) failed: -1
hid-generic 0003:25F0:83C2.0001: timeout initializing reports
input: Goodbetterbest Ltd Gioteck VX2 2.4G Wireless Controller as /devices/platform/ohci.0/usb1/1-1/1-1.4/1-1.4:1.0/0003:25F0:83C2.0001/input/input2
hid-generic 0003:25F0:83C2.0001: input: USB HID v1.10 Gamepad [Goodbetterbest Ltd Gioteck VX2 2.4G Wireless Controller] on usb-ohci.0-1.4/input0

Mas a implementação USB deixa um bocado a desejar:

root@ev3dev:~# lsusb
Bus 001 Device 004: ID 25f0:83c2

Bela porcaria, nem um descritivo? Vamos inspeccionar com mais detalhe:

root@ev3dev:~#  lsusb -d 25f0:83c2 -v

Bus 001 Device 004: ID 25f0:83c2  
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        16
  idVendor           0x25f0
  idProduct          0x83c2
  bcdDevice            3.15
  iManufacturer           1 Goodbetterbest Ltd
  iProduct                2 Gioteck VX2 2.4G Wireless Controller
  iSerial                 0
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           41
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              500mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              0
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.10
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength     137
         Report Descriptors:
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0010  1x 16 bytes
        bInterval              10
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval               1
Device Status:     0x0000
  (Bus Powered)

Sendo OHCI temos também:

root@ev3dev:~# ls /dev/input/by-id/ -la
total 0
drwxr-xr-x 2 root root  60 Aug 15 07:16 .
drwxr-xr-x 4 root root 140 Aug 15 07:16 ..
lrwxrwxrwx 1 root root   9 Aug 15 07:16 usb-Goodbetterbest_Ltd_Gioteck_VX2_2.4G_Wireless_Controller-event-joystick -> ../event2

No Ubuntu consigo ver o estado dos vários botões e joysticks do gamepad com o comando ‘jstest’ do pacote ‘joystick’ por isso:

root@ev3dev:~# apt-get install joystick
root@ev3dev:~# jstest --normal /dev/input/by-id/usb-Goodbetterbest_Ltd_Gioteck_VX2_2.4G_Wireless_Controller-event-joystick
Driver version is 0.8.0.
jstest is not fully compatible with your kernel. Unable to retrieve button map!
Joystick (Unknown) has 2 axes and 2 buttons.
Testing ... (interrupt to exit)

jstest: error reading: Invalid argument

“Not fully compatible with your kernel”… Oops!

Podemos sempre aceder directamente:

root@ev3dev:~# cat /dev/input/by-id/usb-Goodbetterbest_Ltd_Gioteck_VX2_2.4G_Wireless_Controller-event-joystick
�S�z    �S�z0�S�z�S��    �S��0�S��

carregar um botão apenas gerou esta sequência de caracteres estranha… pelo menos sabemos que funciona só falta entender o formato. Como sou preguiçoso fui buscar o PyGame, um módulo de python muito usado na comunidade Raspberry Pi que já faz isso – a semelhança do EV3 com o Raspberry Pi é tão impressionante que lhe podemos ir buscar ideias para quase tudo.

root@ev3dev:~# apt-get install python-pygame
root@ev3dev:~# nano joystick.py
root@ev3dev:~# chmod +x joystick.py
root@ev3dev:~# python joystick.py

O script python ‘joystick.py’:

import traceback, os

os.environ['SDL_VIDEODRIVER'] = 'dummy'

from pygame import joystick, event, display

def main():
  try:

    display.init()
    joystick.init()
    js=joystick.Joystick(0)
    js.init()

    num_axes=js.get_numaxes()
    num_buttons=js.get_numbuttons()
    num_hats=js.get_numhats()

    print 'Axes:', num_axes
    print 'Buttons:', num_buttons
    print 'Hats:', num_hats

    while True:
      event.pump()

      for i in range(0, num_axes):
        print 'Axis %i: %6.3f' % (i, js.get_axis(i))

      for i in range(0, num_buttons):
        print 'Button %i: %r' % (i, js.get_button(i))

      for i in range(0, num_hats):
        print 'Hat %i: %s' % (i, js.get_hat(i))

  except (KeyboardInterrupt, SystemExit):
    print "Exiting..."
  except Exception:
    traceback.print_exc(file=sys.stdout)

  sys.exit(0)

if __name__ == "__main__":
    main()

À custa deste script fiquei a saber que o gamepad tem 4 axes (2 por cada joystick analógico), 13 buttons e 1 hat (o hat é o conjunto de 4 teclas direccionais à esquerda do gamepad) que quando accionados devolvem:

Para cada um dos 13 botões:

gatilho esquerdo = 6
botão sobre gatilho esquerdo = 4
gatilho direito = 7
botão sobre gatilho direito = 5
select = 8
start = 9
home = 12
triangulo = 0
circulo = 1
cruz = 2
quadrado = 3
botão do joystick esquerdo = 10
botão do joystick direito = 11

(o botão “Turbo’ ao centro do gamepad parece não funcionar)

Para cada um dos 4 botões do hat:

cima = (0,1)
direita = (1,0)
baixo = (0,-1)
esquerda = (-1,0)

Para o joystick da direita:

todo para cima: Eixo 3 = -1
todo para baixo: Eixo 3 = 1
todo para direita: Eixo 2 = 1
todo para esquerda: Eixo 2 = -1
=> (x,y) = (axis2,-axis3)

Para o joystick da esquerda:

todo para cima: Eixo 1 = -1
todo para baixo: Eixo 1 = 1
todo para direita: Eixo 0 = 1
todo para esquerda: Eixo 0 = -1
=> (x,y) = (axis0,-axis1)

O gamepad tem também um motor interno para vibração (force feedback?) mas que só funciona com Playstation 3. Curiosamente de vez em quando acontece-me poucos minutos depois de desligar o EV3 o gamepad desatar a vibrar.

Series Navigation<< ev3dev – webcamAD4M4ST0R – o código >>

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *