miércoles, 20 de marzo de 2013

Script para conectar wiimote a PC en Python

No he probado nada de lo siguiente en Windows, así que aviso que todo fue probado en Ubuntu 12.10.

Me compré un dongle USB Bluetooth para conectar los Wiimotes a la computadora, lo primero que hice fue instalar el wiican, hay explicaciones de cómo hacerlo por internet y lo pueden instalar desde los repositorios de getdeb, así que no voy a explicar eso. El wiican funciona bien, se puede usar las configuraciones por defecto o se pueden crear las propias pero ya empecé a encontrar problemas cuando no encontré cómo hacer que un botón presione dos teclas del teclado a la vez, no sé si es posible de hacer con el wiican pero tampoco es muy libre lo que se puede hacer con él, así que decidí averiguar cómo hacerlo desde algún punto anterior, antes de llegar al GUI. No me costó mucho encontrar que se podía hacer en python, encontré que ya hay un módulo que se encarga de lo más importante, cwiid (es parte de una herramienta general de ubuntu, aquí se explica cómo instalarlo). Averigüé un poco cómo usarlo y desarrollé un script simple que conecta el wiimote y obtiene la información de qué botones se están presionando.

El script en si:
No he hecho nada más, pienso usarlo para controlar el teclado y el mouse, probablemente para jugar juegos y quizás para controlar ciertos programas. Dejo el script para que cualquier persona que quiera programar algo usando un wiimote, pueda mandarse derecho a la parte entretenida.

El script es bastante simple en su funcionamiento, al principio pregunta cuántos wiimotes se van a conectar, corre un loop en el cual se fija qué botones están siendo presionados (esto no es trivial, está explicado más adelante.

Explicación:
La primera línea es un import del módulo en el que nos estamos basando.

Entre la línea 3 y la 9 se hace la conexión de los wiimotes. Primero se pide que se ingrese la cantidad de wiimotes que se conectarán y después se realiza las conexiones creando las variables de clase cwiid.Wiimote(), esas variables son guardadas en en una lista y contienen todo lo relacionado con el wiimote, desde los botones que están siendo presionados hasta los leds que están encendidos. Además en la línea 9 se enciende el led que corresponde al número de wiimote conectado. Esa variable puede tomar valores entre 0 y 16, 0 significa que todos los leds están apagados, entre 1 y 4 se enciende sólo el led indicado y entre 5 y 16 son combinaciones entre los cuatro leds, se podría usar por ejemplo para marcar la batería restante en el wiimote.

Si revisan la variable state['buttons'] del wiimote, verán que toma distintos valores dependiendo del botón que se esté presionando, estos valores son potencias de 2 y se suman si se está presionando más de uno a la vez, esto hace que teniendo el número correspondiente a esa variable, hay una sola combinación de botones posible, aunque conseguirla no es tan trivial.
En la línea 11 simplemente hice un diccionario asignando el valor correspondiente a cada botón, en las siguientes dos líneas creé una lista con esos valores y los ordené de manera descendiente.

Lo siguiente es la función que revisa qué botones están siendo presionados. Cómo dije, a partir de ese único número se puede averiguar qué botones están siendo presionados, para eso lo que hay que hacer es ir revisando desde el número más alto de la lista si éste es menor o igual que el número (llamémoslo n), si eso se cumple, se guarda ese botón en la lista de los que están siendo presionados, se resta a n y se pasa al siguiente botón. De esa manera se obtiene una lista de sólo los botones que están siendo presionados que es lo que se devuelve.

La última parte es una demostración, se trata de un loop infinito que muestra en cada iteración qué botones están siendo presionados, notarán si conectan más de un wiimote que se trata de una lista con varias listas adentro, una por cada wiimote y en cada una aparecerán los botones que están siendo presionados.

Lo más básico ya está listo, faltarían algunas cosas cómo continuar el algoritmo para el nunchuck y el classic controller, cosa que pienso hacer en el futuro.

Además se pueden usar los datos de los acelerómetros y el sensor infrarrojo, para eso se usan las variables acc e ir_src dentro de state. Un ejemplo de cómo se ve el diccionario state es:
{'acc': (117, 118, 143), 'led': 1, 'ir_src': [None, None, None, None], 'rpt_mode': 14, 'ext_type': 0, 'buttons': 0, 'rumble': 0, 'error': 0, 'battery': 62}

Revisen el script y hagan sus propios programas, si tienen alguna duda pregunten y si quieren compartir algún programa genial.

No hay comentarios:

Publicar un comentario

Related Posts Plugin for WordPress, Blogger...