Experimentando con WiiRemoteJ en Linux Ubuntu 9.04

Introducción.

Hace un tiempo (parte 1 y parte 2) hice algunas pruebas acerca de como utilizar el control del Wii (wiimote) desde el PC desarrollando aplicaciones con C# utilizando la librería WiimoteLib de Brian Peek.  Desafortunadamente ni esta librería ni ninguna otra de C# que pudiera encontrar son de plataforma cruzada y por lo tanto no se pueden utilizar desde Linux así que me vi obligado a cambiarme nuevamente a mi lenguaje preferido: Java.

Después de revisar las librerías disponibles obtuve tres candidatos: WiiRemoteJ, WiiUseJ, MoteJ y WiiMote-Simple.

A pesar de que la página de WiiRemoteJ parece haber desaparecido es una de las mas mencionadas y parece ser una de las mas estables.  Requiere de una pila Bluetooth como Avetana o Bluecove para ejecutarse sobre ella.

Implementación.

Básicamente el uso de la librería se basa en la manipulación de un objeto WiiRemote y en la implementación de la interfaz WiiRemoteListener encargada de manejar los eventos provenientes del Wiimote y de sus extensiones.

Las clases se encuentran almacenadas en los siguientes paquetes.

import wiiremotej.*;
import wiiremotej.event.*;

Al implementar la mencionada interfaz es necesario especificar la implementación de los siguientes métodos.

Método Evento
buttonInputReceived Se presionó un botón del wiimote.
disconnected Se desconectó el wiimote.
extensionConnected Se conectó una extensión al wiimote.
extensionPartiallyInserted La extensión recién conectada quedó mal insertada.
extensionUnknown La extensión recién conectada es desconocida.
extensionInputReceived La extensión envía datos al wiimote.
extensionDisconnected La extensión ha sido desconectada del wiimote.
accelerationInputReceived El wiimote ha generado información de aceleración.
IRInputReceived El wiimote ha generado información de su cámara infrarroja.
statusReported Ha sucedido un reporte de estado.
combinedInputReceived Suceso de eventos combinados.

Evento de presión de botones.

 public void buttonInputReceived(WRButtonEvent evt)
 {
     // boolean     isAnyPressed(int buttonMask)    Returns true if any of the given buttons are pressed; otherwise false.
     // boolean     isOnlyPressed(int buttonMask)   Returns true if all of the given buttons are pressed and no others are; otherwise false.
     // boolean     isPressed(int buttonMask)       Returns true if all of the given buttons are pressed; otherwise false.
     // boolean     wasOnlyPressed(int buttonMask)  Returns true if all of the given buttons were pressed and no others are; otherwise false.
     // boolean     wasPressed(int buttonMask)      Returns true if all of the given buttons were pressed; otherwise false.
     // boolean     wasReleased(int buttonMask)     Returns true if one of the given buttons was released; otherwise false.

     if (evt.wasPressed(WRButtonEvent.TWO))
         this.log("2");

     if (evt.wasPressed(WRButtonEvent.ONE))
         this.log("1");

     if (evt.wasPressed(WRButtonEvent.B))
         this.log("B");

     if (evt.wasPressed(WRButtonEvent.A))
         this.log("A");

     if (evt.wasPressed(WRButtonEvent.MINUS))
         this.log("Minus");

     if (evt.wasPressed(WRButtonEvent.HOME))
         this.log("Home");

     if (evt.wasPressed(WRButtonEvent.LEFT))
         this.log("Left");

     if (evt.wasPressed(WRButtonEvent.RIGHT))
         this.log("Right");

     if (evt.wasPressed(WRButtonEvent.DOWN))
         this.log("Down");

     if (evt.wasPressed(WRButtonEvent.UP))
         this.log("Up");

     if (evt.wasPressed(WRButtonEvent.PLUS))
         this.log("Plus");
 }

Evento de desconexión del control.

 public void disconnected()
 {
     this.log("The remote controller was disconnected.");
     wiimote = null;
 }

Eventos de la extensión.

 public void extensionConnected(WiiRemoteExtension extension)
 {
     this.log("An extension has been connected! (" +
     extension.getCode() + "): " +
     this.getExtensionTypeName(extension));

     try
     {
         wiimote.setExtensionEnabled(true);
     }
     catch(Exception e)
     {
         this.log(e.getMessage());
     }
 }

 public void extensionPartiallyInserted()
 {
     this.log("An extension was partially inserted, push it harder next time");
 }

 public void extensionUnknown()
 {
     this.log("The extension is unknown, what are you putting into me ?");
 }

 public void extensionInputReceived(WRExtensionEvent evt)
 {
     // this.log("The extension is sending me some kind of data ... ");
 }

 public void extensionDisconnected(WiiRemoteExtension extension)
 {
     this.log("An extension has been disconnected! (" +
     extension.getCode() + "): " +
     this.getExtensionTypeName(extension));
 }

Evento de aceleración.

 public void accelerationInputReceived(WRAccelerationEvent evt)
 {
     // double     getPitch()         Returns the pitch of the remote, in radians from -PI to PI.
     // double     getRoll()          Returns the roll of the remote, in radians from 0 to 2PI.
     // double     getXAcceleration() Returns the X-Acceleration of the remote, in terms of G's.
     // double     getYAcceleration() Returns the Y-Acceleration of the remote, in terms of G's.
     // double     getZAcceleration() Returns the Z-Acceleration of the remote, in terms of G's.
     // boolean    isStill()          Returns true if the remote is not being moved; otherwise false.
 }

Evento de la cámara infrarroja.

 public void IRInputReceived(WRIREvent evt)
 {
     // IRLight[] getIRLights()       Returns the array of IR lights seen by the IR sensor.
     // int          getMode()        Returns the mode of the IR sensor.    
 }

Evento de reporte de estado.

 public void statusReported(WRStatusEvent evt)
 {
     // double      getBatteryLevel()       Returns the battery level of the remote.
     // boolean[]   getLEDStatus()          Returns the status of the LED lights.
     // boolean     getLEDStatus(int light) Returns the status of the specified light.
     // boolean     isContinuousEnabled()   Returns the status of continuous reporting.
     // boolean     isExtensionConnected()  Returns the status of the extension port.
     // boolean     isSpeakerEnabled()      Returns the status of the speaker.    
 }

Reporte de recepción combinada de eventos.

 public void combinedInputReceived(WRCombinedEvent evt)
 {
     // WRAccelerationEvent getAccelerationEvent()  Returns the acceleration event of this combined event.
     // WRButtonEvent       getButtonEvent()        Returns the button event of this combined event.
     // WRExtensionEvent    getExtensionEvent()     Returns the extension event of this combined event.
     // WRIREvent           getIREvent()            Returns the IR event of this combined event.
 }

Ejecución.

Para el desarrollo de esta aplicación de demostración se utilizó la librería de BlueCove, en este caso en la versión 2.10.  Es obligatorio obtener el paquete bluecove-*.jar mientras que bluecove-gpl-*.jar sólo es requerido bajo Linux.

$ wget http://bluecove.googlecode.com/files/bluecove-2.1.0.jar

$ wget http://bluecove.googlecode.com/files/bluecove-gpl-2.1.0.jar

Además se requiere de la librería WiiRemoteJ.jar, en este caso en la versión 1.6.

$ wget http://www.world-of-cha0s.hostrocket.com/WiiRemoteJ/WiiRemoteJ%20v1.6.zip.gz

$ cp WiiRemoteJ v1.6/WiiRemoteJ.jar .

Se compila el programa de demostración.

$ javac -classpath bluecove-2.1.0.jar:bluecove-gpl-2.1.0.jar:WiiRemoteJ.jar:. WiiRemoteJTest.java

Se ejecuta.

$ java  -classpath bluecove-2.1.0.jar:bluecove-gpl-2.1.0.jar:WiiRemoteJ.jar:. WiiRemoteJTest

Al iniciar la aplicación se debe presionar el botón que dice “Buscar Wiimote” y presionar los botones 1 y 2 del control para ponerlo en modo de descubrimiento.  Después de encontrado los eventos (botón, extensión y desconexión) generados en él deberán ser documentados en la ventana de la aplicación.

WiiRemoteJTest 0.1
WiiRemoteJTest 0.1

Enlaces.

http://www.world-of-cha0s.hostrocket.com/WiiRemoteJ/WiiRemoteJ%20v1.6.zip.gz
http://www.world-of-cha0s.hostrocket.com/WiiRemoteJ/WiiRemoteJ%20v1.6.zip.gz

2 thoughts on “Experimentando con WiiRemoteJ en Linux Ubuntu 9.04”

Leave a Reply

Your email address will not be published. Required fields are marked *