jueves, 17 de mayo de 2012

Modificaciones en la aplicación Android para el reconocimiento de gestos

Para integrar el sistema de reconocimiento de gestos en la aplicación Android, hemos tenido que realizar ciertas modificaciones en su software. En esta entrada explicaremos cuáles son los cambios que ha sufrido la aplicación.


Actividad SettingsActivity.java

El cambio más significativo es la creación de una nueva clase: SettingsActivity.java. Con ella, la estructura del software de la aplicación queda de la siguiente manera:

 


La clase SettingsActivity es una actividad encargada del menú de la aplicación, desde el cual se lleva a cabo la fase de entrenamiento para el reconocimiento de gestos.

Cuando la actividad se inicia, se invoca al método onCreate(), que crea:

  • Una lista desplegablesp” de la clase “Spinner”, que contiene todos los posibles comandos a los que se les puede asociar un gesto.
  • Cuatro botonesstartLeartingBtn”, “startIterationBtn”, “stopIterationBtn” y “stopLearningBtn” para poder realizar el entrenamiento (inicialmente sólo estará habilitado el de “Empezar Entrenamiento”.
Además, este método define cómo debe responder la actividad al evento de hacer click sobre uno de los botones:
  • Empezar entrenamiento:
    Llama al método public void startLearning(int type, int iterations, int idGesture) de la clase GestureFactory, pasándole como parámetro que el tipo de sensor con el que tiene que trabajar es el acelerómetro (type=0), que se han de realizar 3 iteraciones para completar el entrenamiento (iterations=3) y el número de identificación idGesture asociado al comando que se ha seleccionado en la lista desplegable “sp”.
    Además, al hacer click sobre este botón se habilita el de “Empezar gesto” y se inhabilita él mismo, pues ya se entra en la fase de entrenamiento.
  • Empezar gesto:
    Simplemente invoca al método public void startIteration() de la clase GestureFactory, para que asocie un listener al acelerómetro y almacene las coordenadas de la aceleración que sufre el dispositivo Android al realizar el gesto.
    Tras hacer click sobre él, él mismo se inhabilita y sólo queda habilitado el botón de “Finalizar gesto”.

  • Finalizar gesto:
    Llama al método public void stopIteration() de la clase GestureFactory para eliminar la asociación entre el listener y el acelerómetro.
    Además de inhabilitarse a sí mismo, si el número de iteraciones realizadas de un mismo gesto ya es 3, habilita el botón “Finalizar entrenamiento”; si es inferior a 3, vuelve a habilitar el de “Empezar gesto”.

  • Finalizar entrenamiento:
    En primer lugar, resetea el contador de iteraciones e inhabilita todos los botones excepto el de “Empezar entrenamiento”.
    Invoca al método public Gesture stopLearning() de la clase GestureFactory y añade el objeto de la clase Gesture que este método devuelve a nuestro ArrayList de gestos patrón.
    La aplicación queda preparada para comenzar un nuevo entrenamiento o pasar a la fase de realización de gestos y comparación con los patrones.


Cambios en NXJAndroidActivity.java

Hemos tenido que introducir algunas modificaciones en la actividad principal NXJAndroidActivity.java para poder comenzar la detección de movimientos del usuario y enviar los comandos correspondientes al robot.

Ahora esta actividad crea un objeto “ad” de la clase AndroidDevice, que se encargará de eliminar el efecto de la gravedad en las lecturas que tome el acelerómetro en la fase de realización de gestos.

Inicializa los dos nuevos botones que antes no teníamos en nuestra aplicación (que se encuentran en la nueva página de “Gestos”) y define cómo deben responder al evento de que el usuario haga click sobre ellos:
  • Iniciar gesto:
    Añade un GestureListener asociado al acelerómetro y entramos en la fase de realización de gestos. A partir de aquí, es la clase GestureManager la que se encarga de comparar los movimientos detectados con sus umbrales de energía y de tiempo para establecer en qué momento se está realizando un gesto, tal y como explicamos en la entrada “Software para el reconocimiento de gestos (parte II)”.
    Cuando la clase GestureManager detecta que se ha terminado de realizar el gesto, compara sus coordenadas con las de todos los patrones mediante el algoritmo DTW y decide cuál de ellos se parece más, calculando la distancia mínima; se almacena en una variable el número de identificación  del gesto patrón más parecido.
    Al finalizar el gesto, se invoca al método onGestureDetected() de la interfaz GestureListener, al que se le pasa como parámetro el número de identificación “idGesture”. Dependiendo de este número, se le enviará por Bluetooth al robot Kigo un comando u otro a través del método public static void send(byte[] bytearray) de la clase Robot. En esta tabla podemos ver la correspondencia establecida:

  • Detener gesto:
    El listener de gestos estará continuamente detectando posibles movimientos del dispositivo Android en busca de nuevos gestos hasta que hagamos click sobre este botón. Lo único que hace al detectar que el usuario ha hecho click sobre él es inhabilitar el AndroidDevice y, por consecuencia, eliminar la asociación entre el SensorEventListener y el acelerómetro.
    Con él salimos del sistema de reconocimiento de gestos.

2 comentarios:

  1. Soy un antiguo alumno de LSED y aunque estoy ya un poco desvinculado de la carrera, me gusta seguir informándome sobre lo que se hace en esta asignatura en concreto. Comencé a leer este blog hace un tiempo y la verdad es que me deja fascinado su buena organización y su sencillez para transmitir conceptos para nada sencillos. Enhorabuena y mucha suerte!

    ResponderEliminar
    Respuestas
    1. En días en los que la vida te intenta dar 88 razones para estar triste y arrastrarte a una espiral de pesimismo, hay pequeños detalles que te sacan tus fuerzas sobrenaturales para intentar volar alto. Merci beaucoup!

      Eliminar