Archive pour la catégorie ‘wiimote’

Controling the wiimote (I)

Mercredi 11 mars 2009

Creating the plugin for wminput

There are a lot of tutorials about how to configure cwiid. I let you follow them for getting a functionnal system for your wiimote. You can read the links at the end of this article. Be sure your system works well before continuing.

Thiis is a code that we’ll use as template for the creation of our driver. Used as main, it use pygame for displaying the infrared sources the wiimote can detect, but it is also compatible as plugin for wminput ( even if it does anything for now ).

You can get it here : wm_control.py ( This code is licenced under GPL 3+ )

About the code :

    import wmplugin

This import does not exist, but is created by wminput when executed. It provide the connexion with the wminput core. Just put ( or link ) the script in the wminput plugin path ( on my debian this is the /usr/lib/cwiid/plugins/ )

def wmplugin_init(id, wiimote_arg):
    wmplugin.set_rpt_mode(id, cwiid.RPT_IR | cwiid.RPT_BTN)
    return

def wmplugin_info():
    return [], \
      [("X", wmplugin.REL | wmplugin.ABS, 1024, 0, 0, 0), \
       ("Y", wmplugin.REL | wmplugin.ABS, 768, 0, 0, 0)], \
    []

We instanciate the wiimote object here and configure it in the IR mode. The name is choosen by wminput if we want to use it as plugin. We define that the plugin return the coordonates X and Y in a relative system ( you can get the signification of all the parameters here : actions list)

If we want to define new butons, we just have to name them in the first list, the’ll be accessible in the configuration file as plugin.[buton_name] = ACTION

def wmplugin_exec(messages):
    '''Wiimote callback managing method
    Recieves a message list, each element is different, see the libcwiid docs'''
    x = y = 0

    for msg in messages:
        if msg[0] == cwiid.MESG_IR:
            x, y = ir_sensor.get_movement(msg)
    return [], (x, y)

Here is the core of our driver. The name is choosen by wminput too, as the format value we return. We have in parameter the list of the messages the wiimote has sent.

If we have defined buton we need to return their state here. It is a boolean saying if the buton is pressed ( True ) or not ( False ).

This method doesn’t send any others parameters, and this is a problem when we need to store data between two calls ( ie for saving the cursor position ). One way for passing throught is to use global variables. But it is unelegant and can cause problems if we want to use our code in imports. So we’ill use a list as default parameter and let python save it as you can see here :

>>> def meth(a=[]):
...     a.append(1)
...     print a
...
>>> meth()
[1]
>>> meth()
[1, 1]
>>> meth()
[1, 1, 1]

So the ir_sensor.get_movement method is defined with each parameter we want to save as an optional list

def get_movement(msg, _old_points=[], _old_position = [0, 0]):
    return 0, 0

The get_movement method need to return the difference between the old position of the cursor and the new one in tuple : (0, 0) mean that the cursor didn’t move, (-10, 0) mean a deplacement to the left.

For now, the plugin doesn’t move the cursor, and doesn’t read what the wiimote has sent. But you know everything for creating your own plugin for controlling your wiimote.
You can use all the cwiid method for setting the led, activating the differents modes of your wiimote ( IR, Acc, rumble … ), and define here your own actions.
I’ll explain the core of the movement analysis in IR mode in the next article.

Links :
The cwiid project

Install Cwiid ( Ubuntu Documentation )

Un pilote wiimote sous Linux en python

Jeudi 19 février 2009

La wiimote est la manette de contrôle de la console wii de Nintendo, un outil merveilleux dont voici un petit résumé de ses fonctionnalités :

  • Accéléromètres
  • Caméra infrarouge
  • Émetteur/Récepteur Bluetooth
  • 11 boutons

( voir le détail sur la page de wikipédia )

En disposant d’un récepteur bluetooth, il est possible de se connecter à la télécommande et de récupérer ses informations, mieux, avec le projet cwiid, on peut transformer la wiimote en souris !

Ainsi selon le mode dans lequel se trouve la télécommande, on contrôle notre curseur en inclinant la télécommande, ou en la pointant vers une source infrarouge

La source infrarouge pouvant être la sensor bar fournie avec la console, ou une source externe, bougie lampe ou tout ce dont pouvez disposer diffusant de la chaleur à partir d’un point unique

Le pilote fourni avec cwiid fonctionne mais n’est pas optimisé. Il arrive que la souris parte dans une direction incontrôlée, ou de ne pas pouvoir accéder à certaines parties de l’écran.

La faute est due au pilote intégré qui se contente juste de placer le pointeur sur la source infrarouge, avec quelques petites optimisations.
En effet, le capteur de la wiimote nous indique quelle est la position de toutes les sources infrarouges perçues ( et nous fourni également des informations sur leur intensité ), mais la conversion en pointeur est laissée au pilote :
Quelle source choisir comme référence ?
Comment gérer les cas où une source est sortie du champ de vision ?
Comment réagir quand cette source revient dans le champ de vision ?

Tout ceci doit être pris en compte pour pouvoir offrir une ergonomie au curseur et faciliter le contrôle.

Heureusement pour nous le pilote nous donne la possibilité de réécrire nos propres moteurs, et donc de gérer nous même la manière dont on veut que la souris réagisse. Nous avons même le choix dans le langage ! En effet, nous pouvons choisir entre offrir un plugin compilé ( le pilote est écrit en C ), ou l’écrire en python. C’est cette deuxième option que je vais présenter dans les articles qui suivront.

Suite : mise en pace du plugin (EN)