Está en la página 1de 122

S ISTEMA DE ASISTENCIA AL ENTRENAMIENTO

DEPORTIVO MEDIANTE DISPOSITIVOS DE VIDEOJUEGOS

S R . D IEGO E MILIANO M ARTINO

S R . S EBASTIÁN M IGUEL S ERRITELLA

T RABAJO F INAL - I NGENIERÍA DE S ISTEMAS


FACULTAD DE C IENCIAS E XACTAS
U NIVERSIDAD N ACIONAL DEL C ENTRO DE LA P ROVINCIA DE B UENOS A IRES

Director: D R . C RISTIAN G ARCÍA B AUZA


Codirector: D R . J UAN D’A MATO

J UNIO 2016
R ESUMEN

n los últimos años se ha observado una evolución en los dispositivos utilizados para

E los videojuegos cambiando la forma de interacción entre el usuario y la consola. Estos


dispositivos contienen sensores que capturan los movimientos que realiza el jugador.
Existen bibliotecas que permiten leer los sensores y usar esos datos posteriormente. Mediante un
conjunto de repeticiones del gesto es posible entrenar una herramienta.
En esa línea, el proyecto presentado contiene una plataforma que permite capturar los gestos,
almacenarlos y analizarlos. Además, el proyecto comprende una aplicación que facilita la carga
de los gestos y provee una interfaz para poder visualizar de forma gráfica los distintos sensores
para el golpe capturado. Por último, el trabajo también incluye una aplicación interactiva donde
el jugador puede realizar los golpes utilizando el Wiimote en una cancha de tenis en 3D con el
comportamiento físico real de la pelota de tenis.

i
D EDICATORIAS Y RECONOCIMIENTOS

n primer lugar queremos dedicar esta tesis a nuestras familias que nos han acompañado

E en cada uno de los momentos de nuestras vidas, que nos han guiado por un buen camino
y por sobre todo que nos han ayudado a levantarnos en nuestras caídas.
A nuestros amigos, con los cuales hemos compartido momentos desde la niñez y a los que
hemos ido conociendo a lo largo de nuestras vidas.
Agradecemos a nuestros compañeros de trabajo, por su buena disposición a colaborar con el
desarrollo del trabajo. En especial, a los chicos de diseño 3D, sin ellos hubiera sido más largo y
complicado el proceso de llevar a cabo esta tesis.
Agradecemos a nuestro director Cristian y a nuestro co-director Juan que desde un principio
nos han brindado su apoyo, sus conocimiento y nos han sabido guiar a lo largo de este trabajo.

iii
Í NDICE DE C ONTENIDOS

Página

Índice de Figuras ix

1 Introducción 1
1.1 Motivación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 Objetivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3 Organización del documento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

2 Marco Teórico 5
2.1 Nuevos enfoques de interación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2 Tecnología en el deporte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2.1 Raqueta de tenis de Babolat . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.2.2 Smartball de Adidas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.3 Nintendo Wii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.3.1 Wii Remote . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.3.2 Wiimotion Plus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.3.3 Reconocimiento de gestos con Wiimote . . . . . . . . . . . . . . . . . . . . . . 12
2.4 Oculus Rift . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.5 Motor gráfico: Ogre 3D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.5.1 Conceptos básicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.6 Motor físico: Bullet Physics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.6.1 Conceptos básicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

3 Diseño e Implementación 19
3.1 Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.2 Vista general del sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.2.1 Módulo Devices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.2.1.1 DeviceManager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.2.1.2 DeviceWiimote . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.2.1.3 Device WiiMotionPlus . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.2.1.4 Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

v
ÍNDICE DE CONTENIDOS

3.2.2 Módulo Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28


3.2.2.1 ValueStroke . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3.2.2.2 Stroke . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3.2.2.3 Template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3.2.2.4 TemplateTools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3.2.2.5 DataManager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
3.2.2.6 Profile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.2.2.7 AppManager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.2.3 Módulo Strategies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.2.3.1 Strategy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.2.3.2 StrategyDTW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.2.3.3 StrategyInside . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.2.4 ResultStrategy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.2.4.1 ResultStrategyDTW . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
3.2.4.2 ResultStrategyInside . . . . . . . . . . . . . . . . . . . . . . . . . . 42
3.2.5 Módulo Controllers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
3.2.5.1 Módulo Command . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
3.2.5.2 Presentación de datos: Módulo ChartHandler . . . . . . . . . . . . 45
3.3 Diagrama de clases del sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

4 Instanciación 49
4.1 Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
4.2 Aplicación Editor de Perfiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
4.2.1 Administración de Perfiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
4.2.2 Definición de tipos de golpe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
4.2.3 Captura de un nuevo golpe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
4.2.4 Generación de un nuevo Template . . . . . . . . . . . . . . . . . . . . . . . . 54
4.2.5 Estrategias de comparación . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
4.2.5.1 Comparación Golpe-Template . . . . . . . . . . . . . . . . . . . . . 57
4.2.5.2 Mejor coincidencia Golpe-Templates . . . . . . . . . . . . . . . . . 61
4.2.6 Configuraciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
4.2.6.1 Configuración de estrategias . . . . . . . . . . . . . . . . . . . . . . 64
4.2.6.2 Configuraciones de dispositivo . . . . . . . . . . . . . . . . . . . . . 65
4.3 Visualizador 3D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
4.3.1 Carga de escenas 3D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
4.3.2 Configuración del escenario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
4.3.3 Integración del motor gráfico con el motor físico . . . . . . . . . . . . . . . . 71
4.3.4 Instructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
4.3.4.1 Comunicación Instructor-Servidor-Visualizador . . . . . . . . . . 75

vi
ÍNDICE DE CONTENIDOS

4.3.5 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
4.3.5.1 Configurador de ejercicios . . . . . . . . . . . . . . . . . . . . . . . . 78
4.3.5.2 Ejercicio libre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
4.3.5.3 Ejercicio de potencia . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
4.3.5.4 Ejercicio de precisión . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
4.3.5.5 Ejecución del ejercicio . . . . . . . . . . . . . . . . . . . . . . . . . . 86
4.3.5.6 Mostrar trayectoria de la pelota . . . . . . . . . . . . . . . . . . . . 88
4.3.5.7 Ojo de halcón . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
4.3.6 Visualizador en Oculus Rift . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
4.3.6.1 Proceso de inicialización y configuración de la aplicación con
Oculus Rift . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

5 Conclusiones y trabajos futuros 93


5.1 Conclusiones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
5.2 Limitaciones del sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
5.3 Trabajos futuros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95

A Apéndice 97
A.1 Captura de datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
A.1.1 Saturación de sensores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
A.2 Biblioteca Wiiyourself . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
A.3 Algoritmo DTW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99

Bibliografía 103

vii
Í NDICE DE F IGURAS

F IGURAS Página

1.1 Simuladores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

2.1 La tecnología en los deportes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6


2.2 Raqueta inteligente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.3 Pelota inteligente de Adidas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.4 Consola de VideoJuegos Nintendo Wii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.5 Hardware del Wii Remote . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.6 Barra del Wii Remote . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.7 Sensor Wiimotion Plus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.8 Dispositivo Oculus Rift . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.9 Sensores de rotación del Oculus Rift . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.10 Sensores de tracking del Oculus Rift . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

3.1 Vistal general del sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20


3.2 Diagrama de flujo de los distintos módulos . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.3 Clase Abstracta IDevice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.4 Clase Device Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.5 Clase Device Wiimote . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.6 Diagrama de secuencia de conexión del dispositivo Wiimote . . . . . . . . . . . . . . . . 24
3.7 Diagrama de secuencia de la captura de los gestos mediante el dispositivo Wiimote . 25
3.8 Clase DeviceWiiMotionPlus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.9 Clase Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.10 Módulo Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3.11 Clase ValueStroke . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3.12 Clase Stroke . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3.13 Clase Template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3.14 Clase TemplateTools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
3.15 Clase DataManager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.16 Clase Profile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.17 Clase AppManager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

ix
Í NDICE DE F IGURAS

3.18 Clase Strategy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35


3.19 Diferencias entre distancia euclidiana y DTW . . . . . . . . . . . . . . . . . . . . . . . . 36
3.20 Clase Strategy DTW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.21 Esquematización del canal de aceptación y los intervalos extendidos para un margen
de error del 50 % de la estrategia Inside . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.22 Esquematización del canal de aceptación y los intervalos extendidos para un margen
de error del 25 % de la estrategia Inside . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
3.23 Clase Strategy Inside . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
3.24 Clase ResultStrategy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.25 Clase ResultStrategyDTW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
3.26 Clase ResultStrategyInside . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
3.27 Módulo Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
3.28 Clase Command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
3.29 Clase ChartHandler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
3.30 Módulo ChartHandlers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
3.31 Diagrama de clases del sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

4.1 Aplicación Editor de Perfiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50


4.2 Cuadro de diálogo para la creación de un perfil . . . . . . . . . . . . . . . . . . . . . . . . 52
4.3 Cuadro de diálogo para la edición de tipos de golpes . . . . . . . . . . . . . . . . . . . . 53
4.4 Control del asistente para la creación de un nuevo golpe . . . . . . . . . . . . . . . . . . 55
4.5 Control del asistente para la creación de un nuevo template . . . . . . . . . . . . . . . . 56
4.6 Control del asistente para la creación de un nuevo template capturando golpes dirigi-
dos a la esquina izquierda del lado destino de la cancha. . . . . . . . . . . . . . . . . . . 57
4.7 Comparación entre un Golpe y un Template mediante la estrategia Inside . . . . . . . 59
4.8 Comparación entre un Golpe y un Template mediante la estrategia DTW . . . . . . . 60
4.9 Mejor coincidencia mediante estrategia Inside . . . . . . . . . . . . . . . . . . . . . . . . 62
4.10 Mejor coincidencia mediante estrategia DTW . . . . . . . . . . . . . . . . . . . . . . . . 63
4.11 Ventana de configuración general de las estrategias . . . . . . . . . . . . . . . . . . . . . 64
4.12 Ventana Configuración de estrategias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
4.13 Vista aérea del estadio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
4.14 Clase SceneManager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
4.15 Posiciones relativas de los límites de una cancha singles . . . . . . . . . . . . . . . . . . 69
4.16 Cancha de tenis a escala . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
4.17 Comunicación de datos entre un motor gráfico y un motor físico . . . . . . . . . . . . . 71
4.18 Visualización física de los objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
4.19 Diagrama de Actividades de Estados de la Aplicación . . . . . . . . . . . . . . . . . . . . 75
4.20 Vista esperando Servidor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
4.21 Clase Exercise . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77

x
Í NDICE DE F IGURAS

4.22 Pantalla de Configuración de Nuevo Ejercicio . . . . . . . . . . . . . . . . . . . . . . . . 78


4.23 Pantalla de Configuración de Nuevo Ejercicio . . . . . . . . . . . . . . . . . . . . . . . . 79
4.24 Pantalla de Configuración de Ejercicio Potencia . . . . . . . . . . . . . . . . . . . . . . . 80
4.25 Visualizador en ejercicio de potencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
4.26 Acelerómetros en un golpe con potencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
4.27 Pantalla de Configuración de Ejercicio Potencia . . . . . . . . . . . . . . . . . . . . . . . 82
4.28 Vectores de dirección de los templates complementarios . . . . . . . . . . . . . . . . . . 83
4.29 Pantalla del ejercicio en ejecución . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
4.30 Visualizador en ejercicio de precisión mostrando trayectoria de la pelota . . . . . . . . 88
4.31 Visualizador en ejercicio de precisión mostrando las trayectorias de las pelotas . . . . 89
4.32 Visualizador en ejercicio de precisión mostrando el pique de la pelota, luego de ejecutar
la animación del ojo de halcón . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
4.33 Visualizador en Oculus Rift . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92

A.1 Imagen mostrando saturación en uno de los sensores giróscopos . . . . . . . . . . . . . 98

xi
Í NDICE DE A LGORITMOS

A LGORITMOS Página
3.1 Wiimote::Wiimote . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.2 WiiMotionPlus::WiiMotionPlus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.3 Wiimote::CaptureStroke . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3.4 StrategyInside::Inside . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.5 ResultStrategy::ResultStrategy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.6 StrategyInside::Execute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
4.1 NewProfile::Execute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
4.2 EditTypeStroke::Execute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
4.3 NewStroke::Execute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
4.4 NewTemplate::Execute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
4.5 ExecuteComparisonInside::Execute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
4.6 ExecuteComparisonDTW::Execute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
4.7 ExecuteBestAgreementInside::Execute . . . . . . . . . . . . . . . . . . . . . . . . . . 61
4.8 ExecuteBestAgreementDTW::Execute . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
4.9 CustomMotionState::SetWorldTransform . . . . . . . . . . . . . . . . . . . . . . . . . 72
4.10 Algoritmo para crear representación visual y física de la pelota . . . . . . . . . . . . 73
4.11 TennisCourt::isContainDestinationSide . . . . . . . . . . . . . . . . . . . . . . . . . . 79
4.12 VisualExercise::startExercise . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
A.1 Algoritmo DTW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101

xiii
CAPÍTULO
1
I NTRODUCCIÓN

n los últimos años se han realizado nuevos avances revolucionarios en tecnología, es-

E pecialmente en la interfaz básica entre el humano y los sistemas de computación [1].


Estas nuevas tecnologías permiten formas alternativas de las tradicionales técnicas de
interacción (mouse y teclado), mediante capturas de gestos, uso de acelerómetros y otros sensores.
En particular, existen diversos dispositivos que permiten capturar los movimientos que el
usuario realiza con el brazo que han sido desarrollados para diferentes consolas de videojuegos,
tales como Wiimote [2] y el PS3Move [3]. Ambos dispositivos se conectan vía protocolo Bluetooth
y brinda una nueva experiencia en el uso de estos, como se propone en [4]. Por otro lado, se han
desarrollado dispositivos que permiten capturar gestos de cualquier extremidad del jugador, por
ejemplo Kinect [5].
Este tipo de dispositivos cuentan con la conjugación de proveer información precisa y su
valor es de muy bajo costo. En especial, los controles Wiimote y PS3Move cuentan con sensores
acelerómetros, giróscopos y magnetómetros [6]. Si bien el muestreo de estos sensores es limitado,
se puede recrear el movimiento realizado y proyectarlo en espacio y tiempo.
Por otra parte, la forma de visualización 3D ha mejorado en los últimos tiempos proporcio-
nando un nivel de realismo ideal. Uno de los mercados que más lo utilzia es en el cine, donde
generan escenas imposibles de realizarse en la realidad o que exista algún factor que lo amerite,
como por ejemplo una escena de la serie Game Of Thrones en la que se visualice ejército.

1
CAPÍTULO 1. INTRODUCCIÓN

(a) Detrás de escena de filmación (b) Escena renderizada

Además del nivel de detalle también se ha logrado que el usuario se sienta inmerso en el
entorno tridimensional, el cual se manipula a través de dispositivos como cascos, guantes, entre
otros, que capturan la posición y rotación de las diferentes partes del cuerpo humano.

(a) Simulador de vuelo de pájaro usando Oculus Rift (b) Simulador de Fórmula 1 del equipo Mc Laren

(c) Simulador de vuelo Boeing 787 (d) Cabina de un simulador de vuelo

Figura 1.1: Simuladores

En este caso, el campo que ha incorporado esta tecnología es el de los simuladores, tal como los

2
1.1. MOTIVACIÓN

de vuelo y los de Fórmula 1 entre los más destacados. Muchas otras disciplinas han incorporado
simuladores para realizar sus prácticas ya que el usuario puede aprender sin poner en riesgo su
vida o la de terceros, incluso poder realizar situaciones difíciles de replicar.

1.1 Motivación

Actualmente en muchas aplicaciones la interacción del usuario se está alejando del uso de
mouse, teclado o lápices ópticos, y se está convirtiendo en algo mucho más físico y tangible.
Nuevas tecnologías emergentes, permiten desarrollar y experimentar con nuevos métodos de
interacción para proporcionar una intuitiva comunicación humano-computadora.
Existen diversos trabajos académicos, comerciales y personales centrados en la interacción
del Wiimote-PC y PS3Move. Sin embargo, en el marco de la simulación de deportes como el tenis,
no se registran aplicaciones correspondientes ya que las existentes pertenecen a la categoría de
arcade.
En [7] se desarrolló un prototipo para captura de golpes de tenis. Si bien este sistema integraba
un control Wiimote y utilizaba un entorno 3D con distintos escenarios de prueba, permitiendo
reconocer distintos golpes e interactuar con objetos; el sistema es mejorable. Para ello se propone
continuar la línea iniciada con dicho trabajo buscando mejoras en la precisión de captura de
los movimientos y en la visualización de los escenarios. Además, realizar una plataforma en la
que puedan participar distintos dispositivos para la captura de los movimientos y generar una
abstracción para utilizar distintas estrategias de comparación.

1.2 Objetivo

La meta de este trabajo es diseñar una solución que mejore la detección de movimientos de la
herramienta existente aplicada en golpes de tenis. Para ello se pretende capturar movimientos
del brazo a través de dispositivos de captura [8], tales como Wiimote y PS3Move; recreando luego
el golpe en un escenario 3D virtual [9]. Básicamente la idea es desarrollar una nueva aplicación
que ofrezca más y mejores características de acuerdo a las tecnologías actuales.
Además de realizar la captura de los movimientos, la utilidad fundamental que se ofre-
ce mediante la herramienta es la posibilidad de generar un historial del jugador y realizar
comparaciones a lo largo del tiempo evaluando la evolución propia del jugador [10] o también
comparándolo con otros jugadores de su misma categoría o incluso con jugadores profesionales de
primer nivel.
Para realizar la captura de los movimientos se debieron estudiar los datos que ofrecen los
distintos dispositivos, teniendo en cuenta que difieren entre ellos en la cantidad de valores que
entregan. Cada movimiento del jugador es una lectura del dispositivo que puede ser vista como
un conjunto de puntos que recrea una curva en el espacio como se explica en [11]. Para las

3
CAPÍTULO 1. INTRODUCCIÓN

comparaciones de estas curvas, primero se debe remuestrear el conjunto para obtener datos
uniformes.
Para ello, se estudiaron diversos algoritmos para interpretar los datos y comparar los resulta-
dos obtenidos en casos de uso reales. Para realizar estas comparaciones se utiliza el algoritmo
propuesto en [8] llamado DTW (Dynamic Time Warping), el cual mide las similitudes entre dos
secuencias en las que el tiempo y la velocidad pueden variar. Se evaluaron otras alternativas
donde la precisión tome un lugar más protagónico y comparar los resultados obtenidos con los
diferentes algoritmos.
En cuanto al desarrollo del entorno tridimensional, se estudiarán distintas alternativas de
motores gráficos existentes de manera detallada. Para la simulación de las interacciones físicas
de la aplicación, también se estudiarán distintos motores de simulación de comportamiento físico
como se cita en [12] donde se pueden apreciar distintas alternativas, ya sean privativas o Licencia
Pública General (GPL).
También está la posibilidad de proveer el prototipo a las escuelas locales de tenis, con la
intención de ofrecerles una alternativa para sus entrenamientos y capacitaciones. Además, por
otra parte, podremos obtener resultados cuantitativos y cualitativos, para además saber si los
valores obtenidos de las distintas pruebas mantienen un patrón con el cual se podrán realizar
futuras comparaciones.

1.3 Organización del documento

La organización del trabajo, está dada de la siguiente manera:


El Capítulo 2 introduce todos los conceptos teóricos aplicados en el presente trabajo, para ello
se presentan las tecnologías utilizadas, tanto los dispositivos como los motores físicos y gráficos.
En el Capítulo 3, se detalla el diseño y la implementación de la plataforma junto con todas las
decisiones de diseño que se tomaron para su desarrollo.
En el Capítulo 4, se presenta y detalla la instanciación que se realizó sobre el modelo de datos,
de la que se desprenden dos aplicaciones.
Finalmente, en el Capítulo 5, se presentan las conclusiones finales del trabajo, junto con
posibles extensiones.
Además, en el Apéndice se detallaron algunas explicaciones que incidieron en el diseño y en
la implementación del sistema.
Por último, se listan las referencias bibliográficas consultadas durante la implementación del
presente trabajo.

4
CAPÍTULO
2
M ARCO T EÓRICO

omo se viene observando en los últimos años, existe en el mercado una gran cantidad de

C dispositivos reconocedores de gestos realizados por el ser humano. Algunos proveen la


capacidad de reconocer gestos realizados con todo el cuerpo y otros permiten reconocer
con mayor precisión tan sólo alguna extremidad. Estos dispositivos fueron creados especialmente
para utilizarse mediante alguna consola de videojuegos, creando así una nueva era de interacción
entre el usuario y la consola.

2.1 Nuevos enfoques de interación

En los últimos años han surgido diferentes enfoques que utilizan sensores y dispositivos para
capturar los movimientos de los usuarios. Los dispositivos portátiles de mano, como guantes
sensores han sido utilizados, aunque suelen ser caros e intrusivos para los usuarios. Otros
dispositivos inalámbricos no intrusivos, como el controlador de la consola Nintendo Wii han
aparecido para superar estos inconvenientes.
Adicionalmente, otros sensores libres de contacto (es decir, aquellos en los que no es necesario
que el usuario los toque o los tenga en su mano) han aparecido para detectar movimientos, como
el sensor Leap Motion [13] que detecta movimientos de dedos o sensores para detectar gestos
corporales como el sensor Kinect [14].
En la actualidad, los gestos son utilizados en diversas aplicaciones tales como control y
navegación en CAVEs (Cave Automatic Virtual Environments) [15] y otros ambientes virtuales
como habitaciones inteligentes, ambientes virtuales de trabajo y espacios de interpretación y
actuación utilizados para efectos especiales en cine o para brindar más realidad a los personajes
de videojuegos.

5
CAPÍTULO 2. MARCO TEÓRICO

Además, otro dispositivo que está en fases finales de desarrollo es el Oculus Rift [16]. El
Oculus es un casco de realidad virtual que cuenta con una pantalla de gran resolución que se
sitúa muy cerca de los ojos. Además, contiene ciertos sensores que detectan el movimiento de la
cabeza.

2.2 Tecnología en el deporte

En los últimos años, el avance tecnológico ha sido el más importante de la historia. Se


crearon diversos sensores y dispositivos que están siendo utilizados por jugadores profesionales.
Estos sensores captan información del profesional realizando su actividad. Esta información
generalmente es analizada con especialistas del área junto al jugador para indicarle ciertas
recomendaciones al momento de realizar la actividad.

(a) Ciclismo (b) Golf

(c) Running (d) Natación

Figura 2.1: La tecnología en los deportes

Los científicos han creado, por ejemplo, para los nadadores trajes que disminuyen la fuerza de
rozamiento del agua. Otro caso, en el mundo del ciclismo, donde se crean distintos componentes

6
2.2. TECNOLOGÍA EN EL DEPORTE

que sean ultralivianos y lo suficientemente fuertes. Han trabajado también en la aerodinámica


de los autos, motos y bicicletas buscando la mayor eficiencia posible.
Pero no sólo han trabajado en mejorar la performance, sino también se ha instalado la
tecnología para fiscalizar los deportes, como la toma de tiempos o revisar un video en el caso del
rugby.

2.2.1 Raqueta de tenis de Babolat

Es una raqueta de tenis que cuenta con sensores que detectan las vibraciones y movimientos
de las cuerdas. Estos sensores están ubicados en el interior del mango y se pueden obtener los
datos capturados a través de un cable USB o bluetooth.

Figura 2.2: Raqueta inteligente

Contiene sensores acelerómetros, giróscopos y un sensor piezoeléctrico. Mientras los aceleró-


metros calculan la dirección de la raqueta y los giróscopos determinan qué golpe realiza, el sensor
piezoeléctrico analiza la vibración de la raqueta para encontrar el punto de impacto entre las
cuerdas y la pelota.
Mediante los sensores y procesamiento que realiza un microprocesador en la raqueta se puede
obtener el número de golpes, dónde se produce el impacto, el nivel de efecto de la pelota y la
distancia recorrida por el jugador.
Si bien la aplicación provee de numerosas funcionalidades, la información no es precisa.
Además, a esta información se puede acceder únicamente mediante la aplicación.

7
CAPÍTULO 2. MARCO TEÓRICO

2.2.2 Smartball de Adidas

Es una pelota de tamaño reglamentario N◦ 5 que tiene integrado unos sensores ubicados y
suspendidos en el centro de la pelota. Permiten analizar las fuerzas ejercidas sobre la pelota
mientras se desplaza.

Figura 2.3: Pelota inteligente de Adidas

Mediante los sensores propios de la pelota y una serie de algoritmos, provee la información
de la velocidad, la flexión, la posición del impacto pie-pelota y la trayectoria del disparo. Ésta se
envía por bluetooth a un smartphone que tenga instalada la aplicación que provee la empresa.
Los datos generados por la pelota pueden ser obtenidos únicamente mediante la aplicación,
por lo tanto, no se puede hacer ningún análisis acerca de los mismos.

8
2.3. NINTENDO WII

2.3 Nintendo Wii

Es una consola de videojuegos lanzada en 2006. Pertenece a la séptima generación, junto a


Play Station 3 de Sony y Xbox 360 de Microsoft, las que introdujeron controles inalámbricos y
detección de movimientos.
La principal virtud que contó esta consola es su dispositivo de interacción hombre-consola, el
Wiimote, que cambió de manera innovadora el paradigma para los videojuegos.
En la Figura 2.4, se puede apreciar la consola Nintendo Wii con su respectivo control.

Figura 2.4: Consola de VideoJuegos Nintendo Wii

2.3.1 Wii Remote

El sensor Wiimote [17], desarrollado por Nintendo en 2006 para su consola de videojuegos
Nintendo Wii, tiene como característica más destacada la capacidad de detectar movimientos en
tres dimensiones y apuntar a objetos en la pantalla. Tiene la particularidad de ser un dispositivo
de bajo costo.
Y como dato más relevante, este dispositivo puede de usarse con la PC conectándose vía
Bluetooth.
Se diferencia de los mandos tradicionales de consolas anteriores por tener que ser utilizado
con una sola mano.

9
CAPÍTULO 2. MARCO TEÓRICO

Figura 2.5: Hardware del Wii Remote

El control puede ser tomado de dos formas: vertical (con una mano) y horizontal (con dos
manos). Esta última está diseñada para usarse en juegos de conducción y vuelo, además de ser
usada para algunos juegos de la consola virtual. El diseño del Wiimote es simétrico, por lo que
puede tomarse tanto con la mano derecha como con la izquierda.

En la Figura 2.5 se observa la distribución de los componentes que componen al dispositivo.


En la vista perteneciente al frente se destaca el sensor acelerómetro de tres ejes. En la otra, el
chip bluetooth, la cámara perteneciente al tracking visual y el conector de expansión.

La cámara de tracking trabaja conjuntamente con una barra que contiene LEDs infrarrojos
en los extremos. La barra no genera ningún tipo de información hacia la consola, sino que el
dispositivo a través de la cámara de tracking realiza un cálculo trigonométrico, como se ve en la
Figura 2.6 y provee a la consola el punto en donde se encuentra apuntando. Para que esto sea
efectivo es necesario tener el Wiimote apuntando a la barra, por lo que los usuarios la sitúan
debajo o encima de su televisor.

10
2.3. NINTENDO WII

Figura 2.6: Barra del Wii Remote

2.3.2 Wiimotion Plus

Wii Motion Plus es un accesorio que incorpora tres sensores de movimiento giroscópicos
correspondientes a los ejes vertical, longitudinal y lateral, añadiendo precisión extra al Wiimote.
En 2010 salió a la venta el Wii RemotePlus, una versión del mando que integra la tecnología
del Wii MotionPlus y hereda el tamaño del mando original la compatibilidad con todos los
periféricos de la consola.

Figura 2.7: Sensor Wiimotion Plus

11
CAPÍTULO 2. MARCO TEÓRICO

2.3.3 Reconocimiento de gestos con Wiimote

El dispositivo no reconoce gestos por sí solo. Su capacidad es la de capturar los movimientos


del usuario mediante el control, que contiene los sensores, y proveer a la aplicación de esos valores
[18] para analizarlos. Para ello, se debe utilizar una biblioteca [19] que permite capturar los
valores de los sensores.
Los sensores del dispositivo se encuentran trabajando todo el tiempo. Otros dispositivos
además de proveer los datos sin procesar, contienen un software que detecta el movimiento
realizado. Estos movimientos detectados son básicos como por ejemplo, realizar un círculo, un
movimiento lateral o vertical.

2.4 Oculus Rift

Figura 2.8: Dispositivo Oculus Rift

El Oculus Rift es un casco de realidad virtual. Contiene una serie de sensores, tales como
acelerómetros, giroscopios y magnetómetros. A partir de la versión DK2, lanzada en 2015, se
incluyó una cámara externa para trackear la posición de la cabeza del usuario. La información de
cada uno de estos sensores se combina para determinar el movimiento de la cabeza del usuario
en el mundo real y así, sincronizar la vista virtual del usuario en tiempo real.
La orientación del dispositivo se obtiene como una rotación en un sistema de coordenadas de
mano derecha como se ve en la Figura 2.9. Este sistema utiliza las siguientes configuraciones de
ejes:

• Y es positivo en la dirección hacia arriba.

• X es positivo en la dirección hacia la derecha.

• Z es positivo en la dirección hacia atrás.

Las rotaciones positivas son en sentido antihorario y se almacenan en un cuaternión.

12
2.4. OCULUS RIFT

Figura 2.9: Sensores de rotación del Oculus Rift

• Pitch: rotación alrededor del eje X. Es positivo cuando inclina la cabeza hacia arriba.

• Yaw: rotación alrededor del eje Y. Es positivo cuando gira hacia la izquierda.

• Roll: rotación alrededor del eje Z. Es positivo cuando inclina la cabeza hacia la izquierda,
en el plano XZ.

La cámara es necesaria y se utiliza para el tracking de la posición. En la Figura 2.10 se


muestra una cámara montada en un monitor de una PC. El frustum representa una figura
geométrica, en este caso una pirámide, comprendida entre dos planos paralelos. Se usa como la
representación del volumen de visualización de una cámara. Está definido por el campo de visión
horizontal y vertical, conocido como FOV (field of view) y los planos de recortes cercano (near) y
lejano (far). Los valores del frustum de la cámara del Oculus son los siguientes (datos obtenidos
de la documentación del SDK 0.4.4 del Oculus Rift DK2):

• Campo de visión horizontal (FOVh): 74 grados.

• Campo de visión vertical (FOVv): 54 grados.

• Plano de recorte cercano (near) = 0.4 metros.

13
CAPÍTULO 2. MARCO TEÓRICO

• Plano de recorte lejano (far) = 2.5 metros.

Figura 2.10: Sensores de tracking del Oculus Rift

La Figura 2.10 muestra también el origen de tracking por defecto y el sistema de coordenadas
asociado. Aunque el eje de la cámara (y por lo tanto el tracking del frustum) se muestran inclinados
ligeramente hacia abajo, el sistema de coordenadas siempre está orientado horizontalmente, de
manera que los ejes X y Z son paralelos al suelo.
Por defecto, el origen del seguimiento de la posición está situado a 1 metro de la cámara en la
dirección del eje óptico, es decir, en el eje Z, pero con la misma altura de la cámara. La orientación
de origen por defecto es el nivel con el suelo en la dirección del eje Z negativo. En otras palabras,
la orientación corresponde con el usuario mirando hacia la cámara, a una distancia de 1 metro y
a la misma altura de la cámara.

2.5 Motor gráfico: Ogre 3D

OGRE (Object-oriented Graphics Rendering Engine) [20] es un motor 3D flexible y orientado


a la escena escrito en C++ diseñado para hacer más fácil e intuitivo para los desarrolladores
producir aplicaciones que utilicen gráficos 3D acelerados por hardware. La biblioteca de clases
abstrae todos los detalles del uso de las bibliotecas de sistemas subyacentes, como DirectX y
OpenGL, y provee una interfaz basada en objetos del mundo y otras clases intuitivas.
OGRE está diseñado para proveer una solución gráfica que se adapte a la mayoría de los
casos; y se pueden encontrar varios frameworks o wrappers que permiten integrar rápidamente
distintas bibliotecas para funcionalidad adicional como audio, interacción, etc. Provee un diseño
orientado a objetos, minimizando el esfuerzo de renderizar escenas 3D, además se permite

14
2.5. MOTOR GRÁFICO: OGRE 3D

extender la funcionalidad a través de plugins y subclases. Ofrece soporte para el manejo de


materiales y texturas, manejo de mallas 3D, luces, sombras, entre otros y permite definir el
comportamiento de la parte programable de la GPU mediante la definición de shaders.

2.5.1 Conceptos básicos

Existen una serie de conceptos mínimos que se deben comprender a la hora de trabajar con
OGRE:

• Root: es el objeto principal dentro de OGRE. Internamente está implementado mediante


un Singleton de forma que no sea posible crear más de una instancia de ese objeto. Sirve
como fachada a través de la cual realizar cualquier operación dentro de OGRE.

• Ventanas: OGRE permite crear y configurar ventanas sobre la que se renderizarán las
imágenes del videojuego o aplicación de desarrollo. Para ello, es necesario la utilización de
una cámara. Este objeto es imprescindible ya que representa un punto de vista desde el
cual será mostrado el escenario.

• Gestor de recursos: permite leer y cargar en memoria los recursos gráficos necesarios,
organizados jerárquicamente por grupos.

• Gestor de escena: se encarga de gestionar todos los objetos que intervienen dentro de la
escena: entidades, luces, sombras, etc.

• Grafo de escena: es la estructura de datos que utiliza el motor de renderizado para gestionar
elementos dentro de la escena. Dicha estructura está formada por nodos, cada uno de
ellos representa un elemento de la escena y se encarga de gestionar las transformaciones
geométricas que sufran dichos elementos. Permite hacer optimizaciones sobre el proceso
de renderizado, de forma que se desestimen determinados nodos que no van a mostrarse
atendiendo a un criterio dado; por ejemplo, que no estén dentro del área que enfoca la
cámara (el frustum).

Un gran punto a favor del motor de renderizado OGRE es la documentación disponible ya que
cuenta con una vasta cantidad de tutoriales, foros de discusión, ejemplos y una gran comunidad
activa de desarrolladores y usuarios que contribuyen al crecimiento y actualización permanente
del motor gráfico. Esto hace que un sistema programado sobre OGRE sobreviva en el tiempo y
pueda ser extendido o modificado en el futuro.
El motor ha sido utilizado en muchos proyectos de manera exitosa, desde simuladores de
entrenamiento, videojuegos hasta aplicaciones de negocios. En la sección de Testimonios del sitio
web se detallan algunos de estos casos.

15
CAPÍTULO 2. MARCO TEÓRICO

2.6 Motor físico: Bullet Physics

Un motor físico es un software que permite resolver diferentes situaciones de simulación


computacional, principalmente cuestiones como la dinámica de cuerpos rígidos (incluyendo
detección de colisiones), de cuerpos blandos, e incluso de fluidos. Su principal aplicación es en
videojuegos y simuladores, en cuyo caso las simulaciones deben ser resueltas con bajo costo
computacional, permitiendo el tiempo real.
Un motor físico permite también aplicar impulsos, fuerzas o velocidades en los objetos, de
manera tal que se puede recrear un modelo matemático de comportamiento. Es necesario el uso
de un motor físico por las siguientes razones:

• Si no se controlan las colisiones entre los cuerpos, éstos se atravesarían entre sí, restando
realismo.

• Parte de la mecánica de un juego o simulador puede consistir en hacer chocar unos objetos
con otros. Por ejemplo, en nuestra aplicación, la pelota debe chocar contra los ladrillos,
donde éstos deben derribarse en la ejecución del ejercicio de potencia.

• Puede ser necesario modelar propiedades físicas. Por ejemplo, en nuestra aplicación, es
necesario configurar el coeficiente de restitución de la pelota, el cual indica una medida del
grado de conservación de la energía cinética en una colisión.

Existen varios motores físicos disponibles para uso libre o comercial. Entre los más reconocidos
se pueden mencionar a Newton Game Dynamics, Open Dynamics Engine, Bullet Physics Library,
Havok y PhysX. Adicionalmente, Bullet Physics Library[21] es uno de los motores físicos más
reconocidos y ampliamente utilizados en videojuegos comerciales, películas y aplicaciones de
diseño. En el sitio web se muestran muchos casos de uso exitoso del motor.

2.6.1 Conceptos básicos

El elemento más importante en Bullet es el World. El World dentro de Bullet tiene varias
responsabilidades, entre las que se puede destacar:

• Servir como estructura de datos donde almacenar los cuerpos físicos que lo conforman y
aplicar una serie de restricciones a estos cuerpos, como la fuerza de gravedad.

• Detectar y aplicar colisiones entre estos cuerpos.

• Actualizar su posición automáticamente cuando se aplique cualquier tipo de fuerza sobre


estos.

Un cuerpo físico comprende dos categorías. El primero es cuerpo rígido y el segundo, cuerpo
blando. Un cuerpo rígido se caracteriza por tener una forma inmutable. Si se aplica alguna fuerza

16
2.6. MOTOR FÍSICO: BULLET PHYSICS

sobre un cuerpo rígido, su forma no variará. En contrapunto, los cuerpos blandos se caracterizan
por tener formas de colisión que pueden variar cuando se aplica una fuerza sobre éstas. Los
cuerpos rígidos tienen comportamientos menos realistas que los cuerpos blandos; sin embargo,
simular un cuerpo blando es computacionalmente más complejo que simular un cuerpo rígido,
debido a las implicaciones que tiene la variabilidad de su forma física.
Los cuerpos físicos cuentan con una forma de colisión. Típicamente, una forma de colisión suele
ser un cuerpo convexo con unas determinadas propiedades en función de su forma geométrica,
un coeficiente de fricción, de restitución, una inercia, etc. Bullet ofrece unas cuantas formas
primitivas de colisión, que pueden ser simples o complejas. Entre las primitivas simples se
encuentran cajas, planos, cilindros y esferas.
A su vez, ofrece formas de colisión más complejas, pudiendo combinar múltiples formas
convexas en una única. El costo de detección de colisiones para primitivas complejas es mucho
más complejo que para primitivas simples, aunque el grado de realismo alcanzado es mucho
mejor. El usuario es el responsable de establecer la correspondencia entre los objetos 3D y sus
representaciones físicas. Cada objeto visual tendrá su correspondencia en el mundo físico, o no,
según sea necesario para la lógica de la aplicación.
Bullet interpreta que un cuerpo con una masa de 0 kg es un cuerpo que no interacciona con
ninguna fuerza, es decir, permanecerá inamovible en su posición y orientación inicial, por lo que
será un cuerpo estático. De lo contrario, un cuerpo con masa mayor a 0, será un cuerpo dinámico.
Una de las formas de colisión complejas que se utilizará en la aplicación, además de las
primitivas simples, será btBvhTriangleMeshShape. La clase crea una forma de colisión estática a
partir de la geometría de la malla de la entidad de Ogre3D. De esta forma, podemos crear una
representación física donde el volumen de colisión es idéntico al objeto 3D, es decir, el cuerpo
físico comparte la forma geométrica del objeto 3D. Es importante destacar que un cuerpo estático
está pensado para colisionar contra cuerpos dinámicos, y nunca contra otros cuerpos estáticos.

17
CAPÍTULO
3
D ISEÑO E I MPLEMENTACIÓN

3.1 Introducción

ediante las tecnologías mencionadas en el Capítulo 2, se creó una plataforma que a

M través de dispositivos creados para usarse en consolas de videojuegos, brinda asistencia


al entrenamiento deportivo.
La plataforma tiene la capacidad de realizar la conexión de dispositivos preparados para
reconocer gestos realizados por el usuario. Se desarrolló una capa de abstracción ideada para
que sea fácil poder incorporar nuevos dispositivos a esta plataforma ya que en este caso fue
instanciada con el dispositivo Wiimote y Wii Motion Plus.
La idea de este trabajo es poder evaluar los datos generados por los dispositivos y posterior-
mente compararlos. Para ello, se tuvo en cuenta la posibilidad de tener diferentes estrategias
para comparar los gestos realizados por el usuario.
A continuación en este capítulo se desarrollará el proceso de diseño e implementación de la
plataforma, priorizando los puntos anteriormente comentados.

19
CAPÍTULO 3. DISEÑO E IMPLEMENTACIÓN

3.2 Vista general del sistema

Para el diseño e implementación del sistema se ha realizado la división en módulos para


reducir la complejidad y prevenir cambios.
A grandes rasgos se han identificado los siguientes módulos:

• Devices: En éste se implementó una clase que administra los dispositivos conectados, las
clases de los distintos dispositivos con los respectivos métodos para realizar la conexión/-
desconexión con la PC y la captura de los datos.

• Model: En este módulo se implementaron las clases correspondientes para organizar los
datos capturados.

• Strategies: Aquí se implementan los distintos algoritmos para realizar las comparaciones
de los golpes.

Figura 3.1: Vistal general del sistema

Cada uno de estos módulos se explicarán a lo largo del capítulo. A continuación se muestra en
la Figura 3.2, un diagrama de flujo de los diferentes módulos.

Figura 3.2: Diagrama de flujo de los distintos módulos

20
3.2. VISTA GENERAL DEL SISTEMA

Tal como se muestra en la Figura, el sistema comienza por el Módulo Devices con la conexión
de los dispositivos con la PC. Una vez establecido el enlace se procede a la captura de los datos
que genera el usuario y se almacenan siguiendo la estructura implementada en el Módulo Model.
Por último, se utiliza el Módulo Strategies para realizar la comparación entre los golpes.

3.2.1 Módulo Devices

Es importante que la plataforma sea capaz de poder utilizar nuevos dispositivos que asistan
al entrenamiento deportivo, aún cuando éstos puedan ser mejores, peores o diferentes a los ya
utilizados. Lo importante en este módulo es la capacidad de agregar un nuevo dispositivo al
sistema con el menor esfuerzo.
Entonces para realizar la administración de los dispositivos se diseñó e implementó el Módulo
Devices, basándonos en el atributo de calidad Extensibilidad [22]. Como se puede observar en la
Figura 3.3 se implementó una clase abstracta llamada IDevice que provee la extensibilidad de
agregar nuevos dispositivos a la aplicación.

Figura 3.3: Clase Abstracta IDevice

Los métodos Connect, Disconnect, IsConnected, IsCaptureStart y CaptureStroke son abstractos,


por lo tanto son implementados por las clases que se extiendan de IDevice.
El método CaptureStroke tiene la característica de retornar un tipo Stroke que será explicado
en el transcurso del capítulo.
Dada la situación que se quiera agregar un nuevo dispositivo a la plataforma se debe extender
de la clase IDevice e implementar los métodos abstractos que se ven en la imagen. Principalmente
estos métodos son los encargados de administrar la conexión y la captura de los gestos.

3.2.1.1 DeviceManager

Frente a la posibilidad de tener varios dispositivos conectados al mismo tiempo es necesario


tener un administrador. También es importante saber cuál está en uso.
Este administrador de dispositivos se implementó siguiendo el patrón Singleton [22], que
nos asegura que habrá una sola instancia del objeto en el marco de la ejecución, y aún mejor

21
CAPÍTULO 3. DISEÑO E IMPLEMENTACIÓN

nos confirma un punto de acceso global a la única instancia de esa clase y por tanto a toda su
funcionalidad.

Figura 3.4: Clase Device Manager

Como mencionamos anteriormente, se puede obtener la instancia del objeto DeviceManager


a través del método GetSingleton. Por otra parte, los métodos SetDeviceInUse se utilizan para
establecer cuál es el dispositivo que está en uso. Se puede obtener la lista de dispositivos
conectados mediante GetListConnectDevices.

3.2.1.2 DeviceWiimote

Se creó la clase DeviceWiimote para que la plataforma soporte el dispositivo Wiimote. Esta
clase implementa los métodos que fueron declarados como abstractos en IDevice. Como el disposi-
tivo en cuestión tiene características y comportamientos propios, como es el caso de los sensores,
se tomó la decisión de crear un módulo aparte, llamado Módulo Wiimote, para administrar de
manera más ordenada y eficiente el dispositivo.

Figura 3.5: Clase Device Wiimote

A continuación, en el Algoritmo 1 se puede observar un pseudo-código de cómo se realizó la

22
3.2. VISTA GENERAL DEL SISTEMA

implementación del método correspondiente a la conexión del dispositivo.


initialization;
if No esta conectado then
Crear nuevo hilo para realizar la conexión;
end
Algorithm 1: DeviceWiimote::Connect
Se puede apreciar en el Algoritmo 1 que se crea un nuevo hilo que realiza la ejecución del
sistema. Cuando el usuario solicita conectar el dispositivo, el hilo entra a este método donde ahí
mismo crea un nuevo hilo que se encarga de realizar la conexión del dispositivo con el sistema.

Funcionamiento basado en hilos

La utilización de estos hilos se debe principalmente a cuestiones de diseño de interfaz gráfica.


Se sabe que una interfaz gráfica se ejecuta sobre el hilo principal de la aplicación, y que cualquier
procedimiento que se ejecute lo hará sobre ese mismo hilo, haciendo que quede bloqueado durante
ese lapso de tiempo. En los casos en que esos procedimientos requieran un mayor procesamiento,
o en su defecto un mayor tiempo, es necesario que ese procedimiento se realice en un hilo aparte.
De esta forma, se deja la responsabilidad de ese proceso en un hilo secundario y cuando el proceso
finaliza debe comunicarle al hilo principal de tal hecho.
También es importante mencionar las prioridades asignadas en los hilos. Este manejo de
configuración sirve en un entorno donde el hardware es capaz de manejar múltiples hilos o
múltiples procesos. Entonces, como el procesador ejecutará el hilo durante un tiempo determinado
según la técnica de planificación de CPU que implemente (Round Robin, FCFS, SJF [23] entre
otras), al tener definida una prioridad alta hace que le dé mayor tiempo para ejecutarse o que
vuelva a estar en ejecución más pronto que otros procesos.
Para nuestro caso, la prioridad asignada al hilo secundario creado es normal. Esta asignación
es el resultado de diferentes pruebas debido al nivel de atención necesario para poder capturar
los datos y sabiendo que no es demasiado procesamiento como para asignarle una prioridad más
alta.

Secuencia de conexión del dispositivo Wiimote

A continuación, en la Figura 3.6 se puede observar la secuencia de ejecución de estos hilos y


la interacción entre las distintas clases mediante la conexión del dispositivo Wiimote.
La secuencia comienza en el primer hilo, llamado t1, con una invocación al método Connect
del objeto DeviceWiimote que tiene la instancia del dispositivo. Este método es quien crea un
nuevo hilo, al que se llama t2. En el Algoritmo 1 es el hilo t1 el que lleva a cabo la ejecución del
método.
El hilo t2 es el encargado de llevar a cabo la conexión. Su objetivo es realizar la conexión del
dispositivo, por lo que luego de intentar conectarlo consultará si verdaderamente está conectado;

23
CAPÍTULO 3. DISEÑO E IMPLEMENTACIÓN

de ser así, finaliza el método encendiendo las luces led del dispositivo Wiimote. Sino, vuelve a
intentarlo.

Figura 3.6: Diagrama de secuencia de conexión del dispositivo Wiimote

Secuencia de captura de datos del dispositivo Wiimote

A partir de que la conexión del dispositivo está establecida, los sensores se encuentran
funcionando todo el tiempo; por ende, están capturando valores. Entonces, se necesita que cuando
el usuario desee cargar un nuevo golpe se genere un evento donde se identifique el comienzo, y
luego también un evento donde indique la finalización correspondiente.
Para la implementación de la captura de los gestos se ha realizado de una manera similar a
la conexión de los dispositivos. Dicha implementación se ha realizado utilizando la funcionalidad
orientada a eventos. En la Figura 3.7, se muestra particularmente cómo se capturan los gestos
mediante el dispositivo Wiimote.
La captura del gesto comienza mediante un evento, llamado StartAsyncCaptureStroke, que se
invoca desde la interfaz visual al objeto IDevice. Este método es ejecutado dentro de un hilo t1,
que crea un nuevo hilo t2.
Luego, mediante una pre-configuración se selecciona la cantidad de gestos a capturar. Enton-
ces, según esta configuración se invoca esa cantidad de veces al método CaptureStroke propio
del dispositivo que se encuentre conectado, DeviceWiimote en este caso, como se refleja en el
diagrama.
El proceso de captura del gesto comienza y termina mediante un evento que se definió con el
botón B del Wiimote. Éste se inicia cuando se oprime y termina cuando se suelta. Mientras el
botón se encuentre presionado, el dispositivo capturará los valores de cada uno de los sensores.
Cuando se suelta el botón se devuelve un objeto Stroke que contiene los valores capturados de
esa muestra.

24
3.2. VISTA GENERAL DEL SISTEMA

Figura 3.7: Diagrama de secuencia de la captura de los gestos mediante el dispositivo Wiimote

3.2.1.3 Device WiiMotionPlus

También como hemos hecho en la clase Device Wiimote, se implementaron los métodos que se
encontraban abstractos en la interfaz IDevice. Si bien es una extensión del dispositivo Wiimote
posee ciertas diferencias como, por ejemplo, la conexión del dispositivo con la PC.

Figura 3.8: Clase DeviceWiiMotionPlus

Otra de las diferencias es al momento de dar de alta el objeto, donde se deben especificar las
características correspondientes al WiiMotionPlus, que además de tener los sensores aceleró-
metros, cuenta con los sensores giróscopos a los que debe configurarles el nombre, el rango de
valores que aceptan los nuevos sensores y también la agrupación por tipo de sensor. Por lo tanto,
el método de captura deberá considerar también los giróscopos e ir almacenando los valores que
capturen.
Todas estas características se explican mejor en la sección 3.2.1.4 perteneciente a la configu-
ración particular de cada dispositivo.

25
CAPÍTULO 3. DISEÑO E IMPLEMENTACIÓN

El método IsConnected requiere que tanto el dispositivo como su extensión estén conectados,
si al menos alguno de ellos pierde la conexión entonces la función indicará que no está conectado.

3.2.1.4 Properties

Luego de haber implementado el módulo Devices se pueden utilizar diferentes dispositivos


que difieren en cuanto a conexiones y capturas de los sensores. Sabiendo que cada dispositivo
está compuesto por sensores diferentes y a su vez que éstos juntos forman un conjunto especial.
Es necesario tener un diseño que pueda soportar definir cada uno de los sensores y la manera en
que se agrupan.

Figura 3.9: Clase Properties

Se creó la clase Properties para definir las propiedades de los dispositivos. Esta clase contiene
el nombre del dispositivo, la configuración y la cantidad de sensores que lo componen. A cada uno
de los sensores se le debe definir el rango de valores que es capaz de reconocer.
1 Wiimote : : Wiimote ( void ) : IDevice ( " wiimote " ) {
2 [ ... ]
3 vector < P r o p e r t i e s : : Sensor * > * sensors = new vector < P r o p e r t i e s : : Sensor * >(3) ;
4 sensors −>at ( 0 ) = new P r o p e r t i e s : : Sensor ( " A c e l e r a c i o n en X" , − 6.0 , 6 . 0 ) ;
5 sensors −>at ( 1 ) = new P r o p e r t i e s : : Sensor ( " A c e l e r a c i o n en Y" , − 6.0 , 6 . 0 ) ;
6 sensors −>at ( 2 ) = new P r o p e r t i e s : : Sensor ( " A c e l e r a c i o n en Z" , − 6.0 , 6 . 0 ) ;
7 P r o p e r t i e s : : GroupSensors * groupAccel = new P r o p e r t i e s : : GroupSensors ( ) ;
8 groupAccel −>groupName = " Acelerometros " ;
9 groupAccel −>indexs . push_back ( 0 ) ;
10 groupAccel −>indexs . push_back ( 1 ) ;
11 groupAccel −>indexs . push_back ( 2 ) ;
12 groupAccel −>ponderation = 1 . 0 ;
13

14 vector < P r o p e r t i e s : : GroupSensors * > * groups = new vector < P r o p e r t i e s : : GroupSensors * >(1) ;
15 groups −>at ( 0 ) = groupAccel ;
16 S e t P r o p i e r t e s ( new P r o p e r t i e s ( " Wiimote " , sensors , groups ) ) ;
17 }

Algoritmo 3.1: Wiimote::Wiimote

26
3.2. VISTA GENERAL DEL SISTEMA

También es posible agruparlos por tipo de sensor, por ejemplo, los sensores acelerómetros estarán
dentro del mismo conjunto y los sensores giróscopos en su grupo correspondiente.
En el Algoritmo 3.1 se puede ver cómo se realiza la configuración de las propiedades para
el dispositivo Wiimote. Primero, se crea cada sensor, se define el nombre correspondiente y el
rango de aceptación para sus valores. Luego, se puede ver cómo se define un grupo llamado
Acelerómetros al que se le asignan los sensores anteriormente declarados.
Por último, se puede observar que al grupo de los acelerómetros se le configura una pondera-
ción en 1 porque es el único grupo que existe. Esta ponderación será utilizada luego para realizar
las comparaciones en el Módulo Strategies.
A continuación, se observa el Algoritmo 3.2 para configurar las propiedades del dispositivo
WiiMotionPlus. A diferencia del algoritmo anterior, en este caso se cuenta con dos grupos de
sensores. Por un lado, están los acelererómetros y por otro, los giróscopos.
En el Algoritmo 3.2 se puede ver antes de la línea 5 se realiza la configuración del dispositivo
Wiimote. Luego, a partir de esa línea se definen los sensores correspondientes al grupo de los
giróscopos, como se hizo el grupo de acelerómetros. Por último, se realiza la ponderación para cada
grupo en 0.5. Por lo tanto, cada grupo tendrá el mismo peso cuando se realicen las comparaciones.
1 WiiMotionPlus ( void ) : IDevice ( " wiimotionplus " ) {
2 [ ... ]
3 vector < P r o p e r t i e s : : Sensor * > * sensors = new vector < P r o p e r t i e s : : Sensor * >(6) ;
4 [ ... ]
5 sensors −>at ( 3 ) = new P r o p e r t i e s : : Sensor ( "Yaw" , − 2050.0 , 2 0 5 0 . 0 ) ;
6 sensors −>at ( 4 ) = new P r o p e r t i e s : : Sensor ( " Pitch " , − 2050.0 , 2 0 5 0 . 0 ) ;
7 sensors −>at ( 5 ) = new P r o p e r t i e s : : Sensor ( " R o l l " , − 2050.0 , 2 0 5 0 . 0 ) ;
8

9 P r o p e r t i e s : : GroupSensors * groupGyros = new P r o p e r t i e s : : GroupSensors ( ) ;


10 groupGyros −>groupName = " G i r o s c o p i o s " ;
11 groupGyros −>indexs . push_back ( 3 ) ;
12 groupGyros −>indexs . push_back ( 4 ) ;
13 groupGyros −>indexs . push_back ( 5 ) ;
14 groupGyros −>ponderation = 0 . 5 ;
15

16 vector < P r o p e r t i e s : : GroupSensors * > * groups = new vector < P r o p e r t i e s : : GroupSensors * >(2) ;
17 groups −>at ( 0 ) = groupAccel ;
18 groups −>at ( 1 ) = groupGyros ;
19

20 S e t P r o p i e r t e s ( new P r o p e r t i e s ( " WiiMotionPlus " , sensors , groups ) ) ;


21 }

Algoritmo 3.2: WiiMotionPlus::WiiMotionPlus

27
CAPÍTULO 3. DISEÑO E IMPLEMENTACIÓN

3.2.2 Módulo Model

Para poder administrar los datos que reconocen los dispositivos es necesario encapsularlos de
manera adecuada para que estén ordenados. Se debe considerar la idea que el dispositivo está
compuesto por una cierta cantidad de sensores y que éstos están continuamente captando valores
sin la capacidad de diferenciar el comienzo y el fin de un gesto.
Como se dijo anteriormente, los sensores se encuentran obteniendo valores continuamente;
sin embargo, se quiere capturar desde que el usuario inicia su golpe hasta que lo termina. Por
ello es que la captura del golpe comienza cuando el usuario oprime un botón y cuando lo suelta,
finaliza la captura.

Figura 3.10: Módulo Model

Dependiendo de cuán rápido o lento lo realice la cantidad de muestras censadas variará.


Supongamos que desde que oprimió el botón hasta que lo soltó transcurrió 1 segundo, sabiendo
que cada sensor tiene la capacidad de tomar 100 muestras y que el dispositivo tiene 3 sensores,
tendremos que almacenar de alguna manera 300 muestras del golpe. Entonces es conveniente que
cada muestra a la que se llamará ValueStroke contenga las muestras obtenidas por los sensores
en un instante de tiempo.
Luego, el conjunto de muestras capturadas conformarán al golpe representado por la clase
Stroke. Cabe destacar que el golpe estará compuesto por más información que será explicada en
detalle en la sección 3.2.2.2.
Se implementó la clase Template para generar patrones a partir de golpes similares que haya
cargado el usuario. Ese patrón generado lo usamos luego como el golpe ideal por parte de ese
usuario.
Como este sistema tiene la finalidad que sea utilizado por diferentes jugadores y poder

28
3.2. VISTA GENERAL DEL SISTEMA

analizarlos se creó la clase Profile, que contendrá sus Templates, la información personal y la
información física.

3.2.2.1 ValueStroke

La clase ValueStroke está compuesta principalmente por un vector de valores decimales,


donde cada ítem del vector representa un valor correspondiente a un sensor. De esta manera, es
capaz de almacenar los valores capturados independientemente de la cantidad de sensores que el
dispositivo tenga.

Figura 3.11: Clase ValueStroke

Como podemos ver en la Figura 3.11 en el método constructor se debe poner el valor correspon-
diente a la cantidad de sensores del dispositivo. Además, tenemos un método para modificar cada
uno de los valores del ValueStroke llamado SetValue y otro, para obtenerlos mediante GetValue.
También podemos saber de qué tamaño es la estructura a través del método GetAmount.
En el siguiente Algoritmo 3.3 se puede observar cómo la clase Wiimote se encarga de realizar
la captura del golpe. Este método se encarga de capturar todos los valores correspondientes al
golpe mientras el usuario lo desee, por ejemplo, para el caso del dispositivo Wiimote mientras
mantenga apretado el botón B. Mientras tanto, creará un objeto ValueStroke que le asignará los
valores correspondientes de cada sensor en ese momento.

1 Stroke * CaptureStroke ( ) {
2 Stroke * s t r o k e = new Stroke ( ) ;
3 while ( mWiimoteManager−>IsPressedButton ( "BUTTON_B" ) ) {
4 ValueStroke * value = new ValueStroke ( 3 ) ;
5 value −>SetValue ( 0 , mWiimoteManager−>W i i A c c e l e r a t i o n . x ) ;
6 value −>SetValue ( 1 , mWiimoteManager−>W i i A c c e l e r a t i o n . y ) ;
7 value −>SetValue ( 2 , mWiimoteManager−>W i i A c c e l e r a t i o n . z ) ;
8 stroke −>AddStrokeValue ( value ) ;
9 }
10 return s t r o k e ;
11 }

Algoritmo 3.3: Wiimote::CaptureStroke

29
CAPÍTULO 3. DISEÑO E IMPLEMENTACIÓN

Luego de que el ValueStroke es creado es añadido a una estructura que lo mantenga y


administre; en este caso, se agrega a Stroke.

3.2.2.2 Stroke

Una vez que se haya capturado el golpe, compuesto por una cantidad de muestras, a las que
llamamos anteriormente ValueStroke, se debe almacenar dentro de una estructura que lo soporte.
Esta estructura es una clase a la que llamamos Stroke.
Si bien puede creerse que lo más importante del golpe son sus muestras ya que sin ellas no
existe golpe; también, es importante darle un contexto. Para ello se debe definir un nombre, saber
a partir de qué dispositivo fue capturado, o también decir de qué tipo es.

Figura 3.12: Clase Stroke

Por las razones que se explicaron anteriormente se implementó esta funcionalidad dentro de
esta clase.
Cabe destacar que particularmente en el tenis, de un golpe a otro puede variar tanto su
velocidad como su trayectoria. Por ejemplo, comparemos el golpe conocido como smash con un
golpe llamado globo. El primero es un golpe que se inicia colocando la raqueta por encima de
la cabeza de manera vertical para impactar a la pelota y que golpee directamente en el piso
de forma rápida y potente generando una trayectoria lo más recta posible. En cambio, el globo
comienza con la raqueta por debajo de la cintura impactando desde abajo hacia arriba y con una
potencia mucho menor que la del smash.
Otro ejemplo, es comparar un drive con un revés. Entonces los valores obtenidos por los
sensores serán muy distintos entre sí. Por eso es que se debe dar más contexto al golpe que se
realiza.
Como mencionamos anteriormente nuestro objeto Stroke contiene una lista en la que se
guardan las diferentes muestras que fueron capturadas para el golpe. El golpe debe tener

30
3.2. VISTA GENERAL DEL SISTEMA

un nombre, una variable donde se diga la cantidad de muestras que debería tener y con qué
dispositivo fue capturado.

3.2.2.3 Template

A partir del desarrollo que se fue contando hasta el momento, se puede capturar los golpes
con sus respectivas muestras. El objetivo principal de estos golpes capturados es compararlos.
Para ello es que creamos una clase llamada Template que guardará los golpes capturados
por el usuario. Esta clase sirve para generar un patrón a patir de los gestos que componen el
Template; en este caso, como la aplicación se centró en el deporte tenis estos gestos van a ser
golpes propios del deporte.
Además, esta forma de generar templates permite al usuario cargar una cantidad de golpes
significativa, realizados de la misma manera, y si por cierta razón uno de ellos no es efectuado de
forma similar no afectará a la posterior comparación.

Figura 3.13: Clase Template

Como vemos en la Figura 3.13, también es necesario describir con qué dispositivo se va a
realizar la captura de los diferentes golpes que comprenden el Template. Además, es importante
que el Template tenga su nombre y que éste sea descriptivo para facilitarle al usuario una
búsqueda más rápida. También el Template tiene asignado un perfil, explicado posteriormente.

3.2.2.4 TemplateTools

Como se dijo, la idea es poder comparar un golpe contra otro. Por ello es que se generó una
clase que se llama TemplateTools. Ésta tiene diversos mecanismos para tratar a los templates,
como, por ejemplo, a partir de un template obtener la curva máxima generada a partir los valores
máximos de los golpes para cada instante. También se puede obtener el promedio de un template,
es decir, obtener un golpe que sea el promedio de todos los golpes dentro del template. Se han
implementado los métodos para obtener el desvío estandar, tanto el superior como el inferior.
Uno de las principales funcionalidades implementadas en esta clase es el método llamado
ResamplingStroke, que genera una normalización del golpe dado el número de muestras preten-

31
CAPÍTULO 3. DISEÑO E IMPLEMENTACIÓN

Figura 3.14: Clase TemplateTools

dido. En caso de que el golpe tenga más muestras que el valor sugerido se procede, mediante el
criterio propuesto, a eliminar algunas hasta alcanzar ese valor. Caso contrario, se deben agregar
muestras. Tanto quitar como agregar muestras hace que el golpe no sea exactamente el mismo,
por eso es que se realiza una interpolación lineal para generar una independencia de la cantidad
de muestras, y que quitar o agregar no termine modificando la esencia del golpe. También se ha
implementado el método ResamplingTemplate, que realiza la misma normalización anteriormente
descripta pero aplica a todos los golpes que contiene el Template.
Todas estas funcionalidades descriptas se van a utilizar luego en las diferentes estrategias de
comparación.

3.2.2.5 DataManager

A partir de la generación de diferentes Templates y Strokes, decidimos que sería una buena
decisión proveerle al usuario la posibilidad de poder almacenarlos físicamente mediante archivos.
Esta solución hace que los golpes y templates permanezcan no sólo en la ejecución de la aplicación
sino también poder utilizarlos en otra ejecución, o en otro momento o también, si se copian esos
archivos, hasta en otra computadora.
Mediante archivos de tipo CSV, que se utilizan en diversas áreas para la representación de
tablas de manera sencilla, ya que los separa por fila y para separarlos por columna agrega un
separador que puede ser una coma, o punto y coma.
Entonces, si podemos guardar esos archivos de manera ordenada también podemos leerlos.
Pero, además de guardar los datos que fueron capturados por el dispositivo tenemos que guardar
información del Template o del Golpe, como su nombre, su tipo y demás descripciones que
comentamos en cada una de las secciones correspondientes.

32
3.2. VISTA GENERAL DEL SISTEMA

Figura 3.15: Clase DataManager

3.2.2.6 Profile

Frente a la posibilidad de plantear un sistema que sea usado en un grupo de estudiantes


de tenis, ya sea amateur o profesional, se presenta la idea de poder almacenar el registro de
cada jugador por separado. Tengamos en cuenta que los jugadores pueden tener innumerables
diferencias, por ello es que es necesario detallar al menos las más significativas.

Figura 3.16: Clase Profile

El tenis es un deporte en el que hay atributos físicos del jugador que influyen de manera
drástica en el desenvolvimiento en el juego. El atributo más significativo es la mano hábil, donde
un jugador la utiliza para tomar la raqueta y realizar los golpes. La raqueta es un objeto que se
puede tomar con cualquiera de las manos, y los golpes se realizan de la misma manera con ambas
manos, diferenciando el perfil. Además existen otros atributos, como la edad del jugador, el peso,
la altura.
A partir de estas características se llevó a cabo la implementación de una clase llamada
Profile, que administrará los Template asociados a cada jugador.

33
CAPÍTULO 3. DISEÑO E IMPLEMENTACIÓN

3.2.2.7 AppManager

Ahora que se ha diseñado e implementado todo el modelo de datos y la administración de los


dispositivos, donde el primero nos provee de facilidades para el almacenamiento y procesamiento
de la información, y el segundo es el que captura esa información, necesitamos llevar el control
de estas capacidades. Por ello, se creó la clase AppManager, que se encarga de llevar a cabo cada
una de capacidades de los módulos anteriormente descriptos.

Figura 3.17: Clase AppManager

Esta clase está implementada utilizando el patrón Singleton ya que sólo existirá una ins-
tancia durante toda la ejecución. Además, debe ser accesible desde diversos procedimientos
pertenecientes a otros objetos.
La clase cargará las distintas configuraciones iniciales que usará la aplicación y se encargará
la administración de los perfiles. Además, proveerá la funcionalidad de obtener los perfiles que
existan dentro del directorio de trabajo como así también agregará y guardará nuevos perfiles.
Además, facilita la administración de los golpes, desde la captura de uno nuevo, el guardado y la
carga de uno anteriormente capturado.

34
3.2. VISTA GENERAL DEL SISTEMA

Comparación de gestos

3.2.3 Módulo Strategies

Para poder evaluar a los jugadores es necesario poder comparar sus golpes. Frente a esta
necesidad se introducen las estrategias de comparación entre golpes y templates.
En este módulo se centralizan las distintas estrategias comparativas. Diseñado e implemen-
tado pensando en la posibilidad de agregar nuevas estrategias a lo largo del desarrollo y en un
futuro también, se realizó una interfaz de la que se extiendan las nuevas estrategias.
La comparación se realiza comparando dos curvas. Estas curvas pueden proceder desde
distintos golpes; donde cada golpe estará representado por curvas generadas por los sensores del
dispositivo de captura. También es posible que una de las curvas, o ambas, procedan a partir de
templates. Como los golpes capturados difieren en la cantidad de muestras según cuánto tiempo
duró la captura, es necesario para realizar la comparación que ambas curvas tengan la misma
cantidad de muestras y estén comprendidas en el mismo espacio temporal, por lo que es necesario
realizar una normalización de alguna de ellas con respecto a la otra.
Las diferentes estrategias implementadas son las siguientes:

• Estrategia DTW

• Estrategia Inside

3.2.3.1 Strategy

Al plantear el uso de, al menos, dos estrategias es necesario proveer una clase abstracta, el
cual tenga métodos pasibles de redefinirlos de acuerdo a las necesidades. Esta clase contiene
atributos que son comunes a las estrategias y existe al menos la implementación de uno de sus
métodos.

Figura 3.18: Clase Strategy

En la Figura 3.18 podemos observar que el método Execute se encuentra sin implementar y
las clases que extiendan de IStrategy lo deberán implementar. Sin embargo, el método GetAverage
se encuentra implementado por esta clase.

35
CAPÍTULO 3. DISEÑO E IMPLEMENTACIÓN

También podemos observar que se han declarado unas variables. Éstas pertenecen a valores
que se usan dentro del método de GetAverage, pero que tienen un valor válido cuando se carga un
nuevo template.

3.2.3.2 StrategyDTW

Como comentamos anteriormente, la idea es crear diferentes alternativas para realizar


comparaciones entre golpes y templates. La primer estrategia de comparación que presentamos
es el algoritmo de Alineamiento Temporal Dinámico, más conocido como DTW .
Si tenemos dos series de tiempo X = (X 1 , X 2 ...X n ) y Y = (Y1 , Y2 ...Yn ) una manera natural de
medir la similaridad entre ambas es a través de la distancia euclídea:
s
n
X
d(X , Y ) = (X i − Yi )2
i =1

Un primer inconveniente, radica en la imposibilidad de comparar dos series de tiempo de


distinto tamaño. Pero incluso, en el caso de series de igual largo, una dificultad que presenta
la distancia euclídea radica en que es muy sensible a distorsiones en el eje del tiempo, aun
cuando éstas sean pequeñas. Por ejemplo, si dos señales son iguales, salvo por un desplazamiento
en el tiempo, la distancia euclidiana las reconocería como distintas por su característica de
alineamiento punto a punto. En este sentido, se introdujo el algoritmo DTW explicado en A.3.

Figura 3.19: Diferencias entre distancia euclidiana y DTW

Lo anterior se puede apreciar gráficamente en la Figura 3.19, donde se representan dos series
con la misma forma general. En la parte superior se muestra el alineamiento que produce la
distancia euclidiana, el punto i-ésimo de la primera con el i-ésimo de la segunda. En la parte

36
3.2. VISTA GENERAL DEL SISTEMA

inferior se muesta un alineamiento no lineal, que permite una medida de similaridad más
sofisticada [24].
El algoritmo DTW (Dynamic Time Warping) se utiliza en nuestro sistema para medir la
similitud de los gestos realizados por el usuario, que pueden diferir en tiempo y espacio. Esta
comparación puede ser mediante un gesto que realice (gesto de test) contra otro previamente
almacenado o contra un conjunto de golpes que definimos como template (gesto de referencia).
Para realizar la comparación mediante DTW se analiza cada serie de datos generada por los
sensores del dispositivo. Por ejemplo, para la comparación de un gesto de test contra un gesto de
referencia, ambos capturados con el dispositivo Wiimote, se analizan las curvas que describen
las aceleraciones en el eje X, luego en el eje Y y finalmente en el eje Z. Se utiliza como criterio
cuantitativo para la comparación entre cada par de curvas, la suma de las distancias del camino
óptimo que recorre la matriz de distancias acumuladas de más bajo costo, obtenido al finalizar el
algoritmo DTW implementado en A.1. En resumen, en cada comparación se ejecuta el algoritmo
DTW tantas veces como número de sensores tiene el dispositivo de captura de los gestos.
En la comparación de un golpe (gesto de test) contra un template utilizando DTW, se utiliza
el golpe promedio del template como gesto de referencia. La ejecución del algoritmo retornará la
distancia entre los gestos alineados en el tiempo. Luego para determinar si el gesto de test es
"similar" al gesto de referencia, cada uno de los valores DTW obtenidos deberá estar por debajo
de un valor límite. Ese valor puede ser obtenido de las siguientes maneras:

• A partir de las curvas mínimas y máximas del template, y para las curvas generadas
por cada sensor del dispositivo de captura, se calcula el valor límite utilizando distancia
euclídea o DTW.

• A partir de los desvíos superior e inferior del template, y para las curvas generadas por cada
sensor del dispositivo de captura, se calcula el valor límite utilizando distancia euclídea o
DTW.

Por lo tanto, existe la posibilidad de realizar la comparación entre un golpe y un template


mediante diferentes combinaciones. La cantidad total de estas combinaciones es de 4 (cuatro). Si
bien sabemos que las configuraciones de la estrategia son similares, una pequeña diferencia en el
resultado puede ser significativa.
Como podemos observar en la Figura 3.20 se implementó el método Execute de la clase
heredada de acuerdo a las propiedades y características correspondientes de la estrategia.
El método Execute perteneciente a la estrategia DTW es el encargado de realizar la compara-
ción entre un Template y un Stroke. El método SetUseLimitValue establece cómo se calculará el
valor límite entre las curvas superior e inferior, donde se puede optar por elegir entre el DTW y
la forma euclídea. Esto quiere decir que el cálculo de ese valor límite entre las curvas superior e
inferior lo hará usando el algoritmo DTW o la distancia Euclídea. El SetUseLimitCurve establece

37
CAPÍTULO 3. DISEÑO E IMPLEMENTACIÓN

Figura 3.20: Clase Strategy DTW

el tipo de curva límite que se usará en la búsqueda del valor límite, ya sea desvío superior y
desvío inferior o máximos y mínimos.

3.2.3.3 StrategyInside

La técnica utilizada en esta ocasión es más sencilla que la anterior en cuanto a su imple-
mentación. Se trata de un algoritmo que fue diseñado e implementado desde cero contemplando
nuevas estrategias y puntos de vista para realizar la comparación.
Se basa en la generación de dos curvas, una a la que llamaremos Inferior y la otra Superior.
La curva Inferior se construye a partir del conjunto de muestras que tiene el template. Para cada
instante de la curva, a partir del subconjunto obtenido de las muestras según un instante de
tiempo, se selecciona el menor de ellos. Para la generación de la curva Superior se mantiene la
misma lógica con la variación de que se busca el mayor valor.
Luego, con estas dos curvas ya calculadas se genera un canal de aceptación, es decir, para
cada instante de la curva existe un intervalo que se encuentra entre la curva Superior e Inferior.
El algoritmo comprobará, para cada instante de tiempo, si el valor de la muestra se encuentra
dentro del canal de aceptación. En este sentido, el porcentaje de similitud estará dado por la
cantidad de muestras incluidas dentro del canal de aceptación, dividido por la cantidad total.
No obstante, también es posible considerar el valor de la muestra como contenido dentro de
estas curvas sin que realmente sea así. Esto es posible dado que existe un margen de error que
hace que este punto sea aún considerado. El margen de error extiende el intervalo de aceptación.
Si el valor de la muestra no se encuentra dentro del canal, entonces mediante la extensión del
valor límite se calculará un porcentaje de alejanía entre la muestra y el límite, teniendo en cuenta
el margen de error establecido. El Algoritmo 3.4 implementa esta lógica.

38
3.2. VISTA GENERAL DEL SISTEMA

1 double S t r a t e g y I n s i d e : : I n s i d e ( double value , double lower , double upper ) {


2 i f ( lower <= value && value <= upper ) {
3 return 1 . 0 ;
4 }
5

6 / / Calculo l a extension d e l i n t e r v a l o
7 double margin = ( upper − lower ) * mMarginOfError ;
8

9 i f ( value < lower ) {


10 i f ( value >= lower − margin ) {
11 return abs ( 1 − ( lower − value ) / margin ) ;
12 }
13 }
14 e l s e i f ( value > upper ) {
15 i f ( value <= upper + margin ) {
16 return abs ( 1 − ( value − upper ) / margin ) ;
17 }
18 }
19 return 0 . 0 ;
20 }

Algoritmo 3.4: StrategyInside::Inside

Supongamos un intervalo de aceptación entre los valores 3 y 9, con un margen de error


del 50 %, para un cierto instante de tiempo t. La Figura 3.21 esquematiza esta configuración.
El rectángulo central corresponde al canal de aceptación, donde el rango del intervalo es de 6
unidades. Los rectángulos laterales corresponden a los intervalos extendidos por el margen de
error. Como el margen de error es del 50 %, entonces el rango de los intervalos laterales serán de
3 unidades.

Figura 3.21: Esquematización del canal de aceptación y los intervalos extendidos para un margen
de error del 50 % de la estrategia Inside

En este contexto, si un valor no se encuentra dentro del canal de aceptación pero sí en un


intervalo lateral, el Algoritmo 3.4 calculará el coeficiente de inclusión del valor con respecto al
límite del canal de aceptación. Por ejemplo, si el valor de la muestra es de 7 unidades, entonces se
localizará dentro del canal de aceptación y el coeficiente será 1. Pero si el valor de la muestra es 1,

39
CAPÍTULO 3. DISEÑO E IMPLEMENTACIÓN

se encontrará dentro del intervalo de error izquierdo, de acuerdo a la Figura 3.21. El porcentaje
de alejanía es del 66,66 %, por ende el coeficiente de inclusión será 0,33.
Si se modifica el margen de error al 25 %, entonces los rangos de los intervalos laterales del
canal de aceptación serán de 1,5 unidades (Figura 3.22). El valor 1 de la muestra no estará dentro
del intervalo de error izquierdo, a diferencia de la configuración con un margen de error de 50 %.
En tal caso, el coeficiente de inclusión será 0.

Figura 3.22: Esquematización del canal de aceptación y los intervalos extendidos para un margen
de error del 25 % de la estrategia Inside

De esta manera, el porcentaje de similitud estará dado por la suma de los coeficientes de
inclusión de los valores de las muestras en cada instante de tiempo, dividido por la cantidad de
muestras total.

Figura 3.23: Clase Strategy Inside

Como se ve en la Figura 3.23, el método SetMarginOfError define el valor correspondiente


al margen de error anteriormente comentado. En cuanto al método SetUseLimitCurve, permite
establecer el tipo de curva límite que se usará en la estrategia, que pueden ser desvíos superiores
e inferiores o máximos y mínimos del conjunto de golpes del template.

40
3.2. VISTA GENERAL DEL SISTEMA

3.2.4 ResultStrategy

Como cada una de las estrategias maneja diferentes mecanismos de comparación es necesario
mostrar sus resultados aunque difieran en su estructura. Para ello, la forma de mostrar y generar
los resultados de forma ordenada es crear una estructura extensible mediante el uso de una
interfaz. En este caso, la clase ResultStrategy es quien contiene los atributos y métodos comunes
de las clases generadoras de resultados de las estrategias.

Figura 3.24: Clase ResultStrategy

Además, este diseño extensible y modificable posibilita en un futuro agregar nuevas es-
trategias con sus resultados acordes a su formato de manera que implique el menor esfuerzo
posible.
Esta clase contiene el Golpe y el Template que se desean comparar y un vector que se
utilizará para ir almacenando los resultados parciales. También contiene los métodos que obtienen
los resultados de las estrategias. Estos últimos serán generados por las clases de estrategias
correspondientes a cada una.
En el Algoritmo 3.5 se puede observar la abstracción que se ha identificado, en la que se
desarrolla operaciones donde intervienen sólo el Golpe y el Template.

1 double ResultStrategy : : GetResultComparison ( ) {


2 double percentage = 0 . 0 ;
3 / / obtener e l grupo de sensores d e l d i s p o s i t i v o
4 f o r ( / / cada uno de l o s grupos de sensores ) {
5 double sum = 0 . 0 ;
6 f o r ( / / cada uno de l o s sensores d e l grupo ) {
7 suma += mResults −>at ( / / sensor d e l grupo ) ;
8 }
9 percentage += (sum * ponderacion d e l grupo de sensores ) / ( tamano d e l grupo ) ;
10 }
11 return percentage ;
12 }

Algoritmo 3.5: ResultStrategy::ResultStrategy

41
CAPÍTULO 3. DISEÑO E IMPLEMENTACIÓN

3.2.4.1 ResultStrategyDTW

Como mencionamos anteriormente, cada estrategia tiene su forma de guardar los datos,
por ello es que para la estrategia DTW hay que generar los resultados. Esta clase se encarga,
mediante las configuraciones estipuladas y obtenidas, de generar los resultados para la aplicación.

Figura 3.25: Clase ResultStrategyDTW

La clase ResultStrategyDTW extiende de ResultStrategy heredando comportamiento y atribu-


tos. Almacena las configuraciones establecidas y los resultados obtenidos de las ejecuciones del
algoritmo DTW para la comparación del template con el golpe de test.
En la Figura 3.25 podemos observar que la clase contiene dos vectores. El tamaño de cada
vector estará dado por la cantidad de sensores del dispositivo de captura de los gestos a comparar.
Uno, mDTWStrokeAverage, contiene los resultados de aplicar el algoritmo DTW para la serie
de datos de cada sensor. Entonces, para la curva generada por cada sensor del dispositivo de
captura del template (donde el golpe promedio se utiliza como gesto de referencia) y del golpe
de test, se obtienen y almacenan las distancias entre las series de datos alineadas en el tiempo.
El otro, mLimitValueUpperLower, contiene los valores límites calculados para cada serie de
datos del template. Habrá una correspondencia entre los vectores, donde la posición i del vector
mDTWStrokeAverage se corresponde con la posición i del vector mLimitValueUpperLower.

3.2.4.2 ResultStrategyInside

Figura 3.26: Clase ResultStrategyInside

42
3.2. VISTA GENERAL DEL SISTEMA

Para la estrategia StrategyInside se debe hacer lo mismo con la presentación de los resultados.
En este caso, se declara la variable que guarda la configuración para el margen de error elegido y
la variable que se usó en la ejecución de la estrategia de comparación donde almacena el tipo de
curvas límites.
A continuación en el segmento del Algoritmo 3.6 podemos observar cómo se arma el Resul-
tStrategyInside mientras se va ejecutando la estrategia. Una vez finalizada la comparación que
realiza esta estrategia, el método retorna el objeto con los valores del resultado de la ejecución.
1 ResultStrategy * S t r a t e g y I n s i d e : : Execute ( Template * _template , Stroke * s t r o k e ) {
2 ...
3 R e s u l t S t r a t e g y I n s i d e * r e s u l t = new R e s u l t S t r a t e g y I n s i d e ( _template , strokeToCompare ,
mUseLimitCurve , mMarginOfError ) ;
4

5 f o r ( i n t i = 0 ; i < strokeToCompare −>Size ( ) ; ++ i ) {


6 ValueStroke * valueToCompare = strokeToCompare −>GetValueStroke ( i ) ;
7 ValueStroke * upperValue = upperCurve −>GetValueStroke ( i ) ;
8 ValueStroke * lowerValue = lowerCurve −>GetValueStroke ( i ) ;
9 f o r ( i n t index = 0 ; index < valueToCompare −>GetAmount ( ) ; ++index ) {
10 r e s u l t −>SetResultComparison ( index , r e s u l t −>GetResultComparison ( index ) +
I n s i d e ( valueToCompare −>GetValue ( index ) , lowerValue −>GetValue ( index ) ,
upperValue −>GetValue ( index ) ) ) ;
11 }
12 }
13 f o r ( i n t index = 0 ; index < stroke −>GetAmountOfSamplesValues ( ) ; ++index ) {
14 r e s u l t −>SetResultComparison ( index , r e s u l t −>GetResultComparison ( index ) /
s t a t i c _ c a s t <double >( strokeToCompare −>Size ( ) ) ) ;
15 }
16 return r e s u l t ;
17 }

Algoritmo 3.6: StrategyInside::Execute

43
CAPÍTULO 3. DISEÑO E IMPLEMENTACIÓN

3.2.5 Módulo Controllers

Con la intención de seguir el patrón Model View Controller, para hacer que la vista sea un
reflejo de lo que el modelo representa se debe administrar mediante el módulo Controller. Este
módulo conecta la vista con el modelo mediante eventos. Este tipo de eventos se realizó por medio
del patrón de diseño Command que se explicará a continuación.

Figura 3.27: Módulo Controller

También existe un controlador para la vista que se encarga de la manipulación de la interfaz


gráfica, que se llama ViewHandler. En esta clase se implementaron una gran cantidad de métodos
principalmente para poder abrir, manipular y cerrar la interfaz de usuario. También coordina las
dependencias entre las vistas y organiza sus actualizaciones.

3.2.5.1 Módulo Command

Para conectar la lógica, en donde intervienen los diferentes módulos, con la interfaz se ha
pensado en realizarla mediante el patrón de diseño Command [22]. Este patrón permite:

• Encapsular una petición en un objeto

• La parametrización de los clientes con diferentes solicitudes

• Guardar las solicitudes en una cola para ir ejecutándose en orden y sin que se pierda
ninguna

Como en nuestra interfaz de usuario, esperamos que se puedan realizar múltiples acciones
para mantener los atributos de calidad que venimos usando los que hacen que nuestro sistema sea
mantenible y modificable. Para esto se crea una interfaz para que cada comando se reimplemente.
El método execute de la Figura 3.28 es el que se debe implementar en cada una de las clases
que correspondan a comandos.
A continuación enunciaremos algunas de las clases implementadas extendiendo de la interfaz
Commnad:

44
3.2. VISTA GENERAL DEL SISTEMA

Figura 3.28: Clase Command

• Crear nuevo Perfil (Clase CommandNewProfile)

• Crear nuevo Template (Clase CommandNewTemplate)

• Crear nuevo Golpe (Clase CommandNewStroke)

• Ejecutar estrategia de comparación entre un golpe y un template mediante DTW (Clase


CommandExecuteComparisonDTW)

• Encontrar el template que más se asemeje al golpe realizado (Clase CommandExecuteBes-


tAgreement)

3.2.5.2 Presentación de datos: Módulo ChartHandler

Manteniendo los mismos conceptos de diseño que se han utilizado a lo largo del trabajo y
cómo se deben mostrar una cantidad significativa de gráficos, se realizó una estructura que pueda
ser extensible y modificable.
Recordemos que tenemos diferentes configuraciones a las que tenemos que representar, como
son los golpes y los templates. También tenemos que graficar los diferentes resultados de las
distintas estrategias.
Se diseñó e implementó una clase padre en la que se sitúan los comportamientos comunes a
las clases hijas. A continuación en la Figura 3.29 podemos observar la declaración de las variables
y los métodos de la clase padre ChartHandler.

Figura 3.29: Clase ChartHandler

45
CAPÍTULO 3. DISEÑO E IMPLEMENTACIÓN

Como se dijo anteriormente, se deberán mostrar cuatro tipos de gráficos. Estos son:

• Golpe

• Template

• Resultados de Estrategia DTW

• Resultados de Estrategia Inside

Por ello, para cada uno de estos gráficos se debe crear una clase en la que se realicen los
procedimientos de armado y muestreo de los mismos.
En la Figura 3.30 se observa la herencia de las clases ChartHandlerViewStroke, Chart-
HandlerViewTemplate, ChartHandlerViewStrategyDTW y ChartHandlerViewStrategyInside. Se
aprecia también la implementación de los métodos que habían sido declarados como abstractos
en la clase padre tales como CreateSeries, GetNumberOfChartsToDisplay y GetTitle.

Figura 3.30: Módulo ChartHandlers

46
3.3. DIAGRAMA DE CLASES DEL SISTEMA

3.3 Diagrama de clases del sistema

Figura 3.31: Diagrama de clases del sistema

47
CAPÍTULO
4
I NSTANCIACIÓN

4.1 Introducción

andil se ha convertido en los últimos años como la principal cuna de tenistas debido

T a exitosos jugadores como Máximo González, Juan Mónaco, Juan Martín del Potro y
Mariano Zabaleta, entre los más destacados. Por esta razón, muchos jóvenes de distintas
partes del país e incluso del extranjero se acercan a tomar clases en la ciudad de Tandil. En base
a esto, surgió la posibilidad de proveer un sistema de asistencia al entrenamiento a las escuelas
locales de tenis.
Se desarrolló un sistema que cuenta con dos módulos principales. El primero es un módulo
llamado Editor de Perfiles, que permite que cada usuario tenga su propio perfil en el que puede
capturar sus golpes, almacenarlos y realizar comparaciones con templates. El segundo módulo
denominado Visualizador 3D, se encarga de recrear escenarios virtuales de entrenamientos,
renderizando las escenas, administrando el manejo del comportamiento físico de los objetos
involucrados, la interacción con los dispositivos, la vinculación con el Editor de Perfiles, etc.
En las siguientes secciones se detallarán las principales funcionalidades de los módulos del
sistema y cómo interactúan entre ellos.

4.2 Aplicación Editor de Perfiles

Este componente de software es una aplicación de escritorio que encapsula la lógica referida
a la administración de golpes y perfiles de usuario, incluyendo: definición de tipos de golpes,
generación de nuevos templates con un dispositivo en particular, comparación y reconocimiento
de golpes mediante la utilización de algoritmos específicos. Además, provee la visualización de los
datos capturados y la de los resultados de las comparaciones.

49
CAPÍTULO 4. INSTANCIACIÓN

Figura 4.1: Aplicación Editor de Perfiles

La Figura 4.1 corresponde a la primer pantalla de la aplicación desde que se inicia. Cuenta
con un menú principal donde se pueden acceder a las diferentes funcionalidades que ofrece la
aplicación. En la parte inferior se encuentra una franja naranja que describe el estado de la
conexión de los dispositivos.
Como se ve en la Figura 4.1, la aplicación está dividida en tres columnas. La columna de
la izquierda mostrará la información correspondiente al perfil seleccionado, tanto información
personal como la de sus templates. En la parte inferior de la columna se puede capturar o
seleccionar un golpe para compararlo o reconocerlo entre los templates del perfil. Tanto los
templates como el golpe tienen un botón en la derecha que permite visualizar los valores de los
sensores del dispositivo de captura, en los gráficos que se encuentran en la columna derecha de la
aplicación.
Una vez seleccionados el template y el golpe es posible realizar la comparación mediante
el algoritmo que se selecciona en la columna central. Luego de ejecutarse esta estrategia, esta
última arroja los resultados correspondientes. A su vez, en la zona baja de la columna central,
la ejecución de la estrategia seleccionada retornará el template de mejor coincidencia con el
golpe seleccionado. De igual manera, los resultados de las ejecuciones se podrán visualizar en los
gráficos de la columna derecha.

50
4.2. APLICACIÓN EDITOR DE PERFILES

4.2.1 Administración de Perfiles

La inclusión de perfiles surge ante la necesidad de que cada usuario posea un perfil con su
propia base de golpes, pudiendo definir la cantidad de golpes deseados y, a su vez, la posibilidad
de realizar reconocimientos o comparaciones contra golpes de otros usuarios.
En primer lugar, para cargar un nuevo perfil se implementó un formulario que se corresponde
con las variables que componen la clase Profile. Como se implementó siguiendo el patrón Com-
mand [22], existe un comando que se encarga de dar de alta a un nuevo perfil. Este comando es
NewProfile que implementa la interfaz Command.
Como se ve en el Algoritmo 4.1, desde este comando se crea el formulario NewProfileForm.
Una vez que el usuario presiona el botón Aceptar se procede a obtener los valores de cada
componente del formulario y generar con ellos una instancia de Profile. Luego, la instancia creada
se agrega al administrador de la aplicación AppManager.
1 v i r t u a l void NewProfile : : Execute ( ) o v e r r i d e {
2 NewProfileForm^ mForm = gcnew NewProfileForm ( ) ;
3 DialogResult r e s u l t = mForm−>ShowDialog ( ) ;
4 i f ( r e s u l t == DialogResult : :OK) {
5 ResultNewProfile^ r e s u l t P r o f i l e = mForm−>GetResult ( ) ;
6 AppManager * appManager = AppManager : : GetSingletonPtr ( ) ;
7 s t r i n g firstName = r e s u l t P r o f i l e −>firsName ( ) ;
8 s t r i n g lastName = r e s u l t P r o f i l e −>lastName ( ) ;
9 P r o f i l e : : Sex sex = r e s u l t P r o f i l e −>sex ( ) ;
10 P r o f i l e : : SkillfulHand s k i l l f u l H a n d = r e s u l t P r o f i l e −>s k i l l f u l H a n d ( ) ;
11 P r o f i l e : : Birthdate b i r t h d a t e = r e s u l t −>b i r t h d a t e ( ) ;
12 f l o a t height = r e s u l t P r o f i l e −>height ( ) ;
13 s t r i n g * imageLocationAvatar = r e s u l t P r o f i l e −>imageLocation ( ) ;
14 P r o f i l e * p r o f i l e = new P r o f i l e ( firstName + " " + lastName , birthdate , sex ,
skillfulHand , height , imageLocationAvatar ) ;
15 appManager−>AddProfile ( p r o f i l e ) ;
16 }
17 }

Algoritmo 4.1: NewProfile::Execute

A continuación se muestra la Figura 4.2 correspondiente al formulario para cargar un nuevo


perfil.

51
CAPÍTULO 4. INSTANCIACIÓN

Figura 4.2: Cuadro de diálogo para la creación de un perfil

4.2.2 Definición de tipos de golpe

Para construir un template, el usuario deberá elegir el tipo de golpe. La definición de los
tipos de golpes se implementó en EditTypeStroke. Esta clase implementa el método Execute de la
interfaz padre Command.
A continuación en el Algoritmo 4.2 se puede observar un segmento del código donde se
reimplementa el método Execute.

1 v i r t u a l void EditTypeStroke : : Execute ( ) o v e r r i d e {


2 AppManager * appManager = AppManager : : GetSingletonPtr ( ) ;
3 vector < s t r i n g > l i s t T y p e s S t r o k e s = appManager−>GetTypesStrokes ( ) ;
4

5 / / Se crea e l formulario y l a s f i l a s de l a t a b l a de t i p o s de g o l p e s a mostrar


6 TypeStrokeForm^ mForm = gcnew TypeStrokeForm ( ) ;
7 f o r ( s t r i n g typeStroke : l i s t T y p e s S t r o k e s ) {
8 mForm−>CreateRow ( typeStroke , ! appManager−>IsTemplatesAssociated ( typeStroke ) ) ;
9 }
10 DialogResult r e s u l t = mForm−>ShowDialog ( ) ;
11 i f ( r e s u l t == DialogResult : :OK) {
12 / / Se obtienen l o s t i p o s de g o l p e s agregados y removidos
13 ArrayList adds = mForm−>GetTypeStrokeAdds ( ) ;
14 ArrayList removes = mForm−>GetTypeStrokeRemoves ( ) ;
15

16 appManager−>removeTypesStrokes ( removes ) ;
17 appManager−>addTypesStrokes ( adds ) ;
18 }
19 }

Algoritmo 4.2: EditTypeStroke::Execute

52
4.2. APLICACIÓN EDITOR DE PERFILES

Se crea el formulario correspondiente y se inicializa la tabla de la interfaz con los tipos de


golpes cargados en la aplicación. El segundo parámetro del método TypeStrokeForm::CreateRow
indica si la fila de la tabla puede ser eliminada o no. En caso de existir templates asociados con el
tipo de golpe, se impuso como restricción que el usuario no pueda eliminar dicho golpe, ya que
dejaría el modelo de datos en un estado inconsistente.
El formulario guarda dos listas, una para los tipos de golpes que agrega el usuario y otra para
los que quita. Luego, se sincronizan los tipos de golpes existentes con la lista de tipos de golpes
agregados y removidos por el usuario durante la interacción con el formulario.
La Figura 4.3 muestra el formulario generado por el comando descripto en el Algoritmo 4.2.
Mediante el botón + se permite agregar un nuevo tipo de golpe y mediante el botón -, quitarlo. A su
vez, se puede apreciar que el botón - se encuentra deshabilitado para el tipo de golpe seleccionado
"Drive". Esto se debe a la restricción impuesta de que un tipo de golpe no puede ser eliminado si
existen templates asociados con dicho tipo de golpe.

Figura 4.3: Cuadro de diálogo para la edición de tipos de golpes

53
CAPÍTULO 4. INSTANCIACIÓN

4.2.3 Captura de un nuevo golpe

La comparación de dos golpes involucra por un lado un golpe de referencia, el cual se encuentra
almacenado en la base de golpes del usuario (templates) y, por otro lado, el golpe a testear, obtenido
con un dispositivo específico. Siguiendo con la implementación mediante el patrón Command,
para realizar la captura de un nuevo golpe se creó la clase CommandNewStroke. El Algoritmo 4.3
corresponde a la implementación del método Execute.
1 v i r t u a l void NewStroke : : Execute ( ) o v e r r i d e {
2 AssistentForm^ mForm = gcnew AssistentForm ( ) ;
3

4 / / Se crean l o s paneles d e l a s i s t e n t e y se configuran l a s t r a n s i c i o n e s


5 I A s s i s t a n t C o n t r o l ^ mControlStart = gcnew NewStrokeControl (mForm) ;
6 I A s s i s t a n t C o n t r o l ^ mControlEnd = gcnew CaptureStrokeControl (mForm) ;
7 mControlStart −>SetNextAssistant ( mControlEnd ) ;
8 mControlEnd−>SetBackAssistant ( mControlStart ) ;
9 ...
10 DialogResult r e s u l t = mForm−>ShowDialog ( ) ;
11 i f ( r e s u l t == DialogResult : :OK) {
12 Stroke * strokeCaptured = GetStrokeCaptured ( ) ;
13 AppManager : : GetSingletonPtr ( ) −>AddStroke ( strokeCaptured ) ;
14 }
15 }

Algoritmo 4.3: NewStroke::Execute

Una vez que la aplicación detecta que se encuentra un dispositivo conectado habilita la opción
de capturar un nuevo golpe. Como se puede observar en el Algoritmo 4.3 se crea un formulario
asistente. El asistente incluye controles enlazados y guía al usuario a lo largo del proceso de
creación y captura de un nuevo golpe.
Los controles son objetos contenidos dentro de un formulario. Cada tipo de control tiene su
propio conjunto de propiedades, métodos y eventos que lo hacen adecuado para un propósito en
particular. El asistente, implementado en la clase AssistentForm, agregará a la superficie del
formulario el control correspondiente de acuerdo a la secuencia de acciones realizadas por el
usuario.
La Figura 4.4 corresponde al control que muestra la configuración de creación de un nuevo
golpe. Según los dispositivos que estén conectados existirá la posibilidad de cambiar entre ellos
para la captura del mismo. Luego de elegir un dispositivo y asignar un nombre al nuevo golpe, se
visualizará en el asistente el segundo control, encargado de realizar la captura del gesto con el
dispositivo seleccionado.

4.2.4 Generación de un nuevo Template

La funcionalidad de creación de templates de la aplicación permitirá al usuario registrar


y almacenar cada uno de sus golpes. El usuario construye el template realizando el golpe una

54
4.2. APLICACIÓN EDITOR DE PERFILES

Figura 4.4: Control del asistente para la creación de un nuevo golpe

cantidad finita de veces. Este paso es importante para el sistema porque genera el patrón de un
golpe a partir de un Template. Luego, utiliza este patrón para compararlo con un golpe que realiza
un jugador. Esta sección está relacionada con los Templates explicados en el capítulo anterior.
La generación de un nuevo Template se implementó en la clase CommandNewTemplate, que
implementa Command. A continuación, en el Algoritmo 4.4 se observa la implementación de la
interfaz. Análogamente al comando de captura de un golpe, se crea un asistente para guiar al
usuario durante la creación de un template.
1 v i r t u a l void NewTemplate : : Execute ( ) o v e r r i d e {
2 / / Se crean l o s paneles d e l a s i s t e n t e y se configuran l a s t r a n s i c i o n e s
3 AssistentForm^ mForm = gcnew AssistentForm ( ) ;
4 ...
5 DialogResult r e s u l t = mForm−>ShowDialog ( ) ;
6 i f ( r e s u l t == DialogResult : :OK) {
7 / / Se obtienen l o s templates capturados y se vinculan
8 Template * firstTemplateCaptured = GetFirstTemplateCaptured ( ) ;
9 Template * secondTemplateCaptured = GetSecondTemplateCaptured ( ) ;
10 LinkedTemplates ( firstTemplate , secondTemplate ) ;
11

12 / / Se agregan a l p e r f i l y se almacenan
13 Profile * p r o f i l e = GetSelectedProfile ( ) ;
14 p r o f i l e −>AddTemplate ( mFirstTemplate ) ;
15 p r o f i l e −>AddTemplate ( mSecondTemplate ) ;
16 appManager−>S a v e P r o f i l e ( p r o f i l e ) ;
17 }
18 }

Algoritmo 4.4: NewTemplate::Execute

55
CAPÍTULO 4. INSTANCIACIÓN

La opción de creación de un nuevo template estará disponible en la aplicación cuando exista


al menos un dispositivo conectado. Mediante el Asistente para la creación de un nuevo template
se conduce al usuario a seleccionar los parámetros de configuración para la creación de un nuevo
template (Figura 4.5) y a la captura de los golpes que lo componen (Figura 4.6).

Figura 4.5: Control del asistente para la creación de un nuevo template

Como se detalló en la sección 4.2.3, un control es un componente de un formulario que se


utiliza para mostrar información o aceptar los datos introducidos por el usuario. En la Figura 4.5,
se muestra el primer control del asistente. El control contiene los componentes necesarios para
que un usuario seleccione el perfil del jugador al que se le desea agregar un nuevo template y
elegir el dispositivo de captura y el tipo de golpe a realizar. Recordemos que estos tipos de golpes
fueron añadidos anteriormente y pueden ser editados, como se explicó en 4.2.2. Por último, existe
una entrada de texto para asignar un nombre al template. En este campo, es aconsejable que el
template a crear tenga un nombre significativo, como por ejemplo el tipo de golpe asociado y la
velocidad de éste (rápido, normal, lento).
Una vez introducidos los datos correspondientes y que el usuario presione el botón Siguiente,
se visualizará la interfaz de captura de golpes (Figura 4.6). El asistente eliminará el control de su
formulario y agregará el siguiente de la lista, el cual recibirá los datos introducidos por el usuario
para configurar la captura de los golpes que conformarán el template.
Tal y como se muestra en la Figura 4.6, primero se deben cargar los golpes orientados hacia
la esquina izquierda de la cancha; es decir, el usuario debe realizar el tipo de golpe de tal manera
que la pelota salga dirigida a la esquina izquierda del lado destino de la cancha. Luego, deberá
realizar el mismo tipo de golpe pero orientado hacia la esquina derecha del lado destino de la
cancha. Este proceso de captura generará dos templates, los cuales estarán relacionados. El

56
4.2. APLICACIÓN EDITOR DE PERFILES

Figura 4.6: Control del asistente para la creación de un nuevo template capturando golpes
dirigidos a la esquina izquierda del lado destino de la cancha.

conjunto de muestras de cada template estará conformado por golpes del mismo tipo, pero se
diferenciarán el uno del otro por sus orientaciones. Este tipo de restricción tiene sus razones y
serán comentadas y detalladas en el transcurso del capítulo.
Para comenzar con la captura de un golpe, se debe presionar un botón específico del dispositivo.
Los valores de los sensores del dispositivo se irán almacenando mientras el botón esté presionado.
Al soltar el botón, se concluirá con la captura del gesto. El proceso se repite de la misma manera
hasta que se llegue a la cantidad de golpes deseada. Se impuso como requisito que el template
tenga una cantidad mínima de 5 muestras.
En el caso del dispositivo seleccionado de la Figura 4.6, mientras el botón B del WiiMotionPlus
se encuentre presionado, se obtendrán los valores de los sensores y, consecuentemente, se irá
armando el golpe. Cada muestreo de los sensores es guardado en un objeto ValueStroke y, al soltar
el botón B y concluir con la captura del golpe, estarán almacenados en un Stroke. Luego, cada
instancia Stroke creada será agregada a un objeto Template. Estas estructuras corresponden al
modelo de datos que se explicó en el capítulo anterior.

4.2.5 Estrategias de comparación

4.2.5.1 Comparación Golpe-Template

Con el fin de evaluar la capacidad de la plataforma de contar con varios algoritmos de recono-
cimientos de gestos y tener variedad de resultados, fueron desarrolladas diferentes estrategias de
comparación. La aplicación permite comparar un golpe con un template mediante un algoritmo

57
CAPÍTULO 4. INSTANCIACIÓN

específicado por el usuario. Se estableció como restricción que tanto el golpe como el template
debieron ser capturados con el mismo dispositivo.

Comparación Golpe-Template con estrategia Inside

Siguiendo con la implementación del patrón Command para cada una de las acciones que
puede realizar el usuario, se creó la clase CommandExecuteComparisonInside.
En el segmento mostrado en el Algoritmo 4.5, se puede observar cómo se obtiene el template y
el golpe que fueron seleccionados en la interfaz de usuario. Luego se ejecuta la estrategia Inside,
invocando el método ExecuteStrategy de AppManager, cuyo primer argumento corresponde al
nombre de la estrategia a utilizar para la comparación del golpe con el template.
1 v i r t u a l void ExecuteComparisonInside : : Execute ( ) o v e r r i d e {
2 AppManager * appManager = AppManager : : GetSingletonPtr ( ) ;
3 / / Se o b t i e n e e l template y s t r o k e s e l e c c i o n a d o s en l o s ComboBox c o r r e s p o n d i e n t e s
4 Template * _template = GetSelectedComboBoxTemplates ( ) ;
5 Stroke * s t r o k e = GetSelectedComboBoxStrokes ( ) ;
6 / / Se e j e c u t a l a e s t r a t e g i a I n s i d e
7 Strategy : : R e s u l t S t r a t e g y I n s i d e * r e s u l t = appManager−>ExecuteStrategy (STRATEGY_INSIDE,
_template , s t r o k e ) ;
8 / / Se o b t i e n e e l p o r c e n t a j e de s i m i l i t u d entre e l golpe y e l template
9 double resultValue = r e s u l t −>GetResultComparison ( ) * 100;
10 ...
11 }

Algoritmo 4.5: ExecuteComparisonInside::Execute

Finalmente, el resultado será mostrado en la aplicación, como se ve en la Figura 4.7. En la


figura se observa una comparación entre el golpe capturado al que llamamos Drive Rápido y el
template cargado como Revés con dirección izquierda. Al pertenecer a tipos de golpes diferentes,
es correcto que los porcentajes de similitud obtenidos por el algoritmo sean tan bajos.

58
4.2. APLICACIÓN EDITOR DE PERFILES

Figura 4.7: Comparación entre un Golpe y un Template mediante la estrategia Inside

Es importante aclarar que tanto el golpe como el template fueron creados con el dispositivo
WiiMotion Plus, utilizando los seis sensores. La estrategia realiza la comparación por cada
sensor de manera independiente, obteniendo un porcentaje. Luego, el porcentaje general de la
comparación estará dado por las ponderaciones impuestas a cada sensor del dispositivo.

Comparación Golpe-Template con estrategia DTW

Para realizar la comparación entre un golpe y un template utilizando la estrategia de com-


paración de DTW, se implementó la clase ExecuteComparisonDTW, extendiendo de la clase
Command e implementando el método Execute.
La implementación del Algoritmo 4.6 maneja una lógica similar al Algoritmo 4.5, con la
única diferencia que, al momento de realizar la invocación de la ejecución de la estrategia, el
primer argumento es el nombre de la estrategia DTW. Otras diferencias menos considerables se
encuentran en la presentación de los resultados, que se omitió detallar.

59
CAPÍTULO 4. INSTANCIACIÓN

1 v i r t u a l void ExecuteComparisonDTW : : Execute ( ) o v e r r i d e {


2 AppManager * appManager = AppManager : : GetSingletonPtr ( ) ;
3

4 / / Se o b t i e n e e l template y s t r o k e s e l e c c i o n a d o s en l o s ComboBox c o r r e s p o n d i e n t e s
5 Template * _template = GetSelectedComboBoxTemplates ( ) ;
6 Stroke * s t r o k e = GetSelectedComboBoxStrokes ( ) ;
7

8 / / Se e j e c u t a l a e s t r a t e g i a DTW
9 Strategy : : ResultStrategyDTW * r e s u l t = appManager−>ExecuteStrategy (STRATEGY_DTW,
_template , s t r o k e ) ;
10

11 / / Se o b t i e n e e l p o r c e n t a j e de s i m i l i t u d entre e l golpe y e l template


12 double resultValue = r e s u l t −>GetResultComparison ( ) * 100;
13 ...
14 }

Algoritmo 4.6: ExecuteComparisonDTW::Execute

En la Figura 4.8 se pueden observar los resultados de la ejecución de la estrategia DTW.


Al igual que la estrategia Inside, DTW realiza la comparación por cada sensor de manera
independiente. Se pueden apreciar las distancias obtenidas de las curvas generadas por cada
sensor, así como también el valor límite considerado para determinar si el golpe es aceptado como
reconocido.

Figura 4.8: Comparación entre un Golpe y un Template mediante la estrategia DTW

60
4.2. APLICACIÓN EDITOR DE PERFILES

Si bien el objetivo del trabajo no es realizar un análisis comparativo del desempeño de los
diversos algoritmos, un detalle interesante es el tiempo de ejecución de cada estrategia. El
algoritmo Inside tiene una duración de procesamiento de 1 ms, mientras que DTW lo realiza
en 2 ms. Aunque estos tiempos son despreciables, a priori podemos considerar que el segundo
algoritmo es el doble de lento que el primero.

4.2.5.2 Mejor coincidencia Golpe-Templates

Así como existe la posibilidad de comparar un golpe contra un template específico la aplicación
permite, además, buscar entre todos los templates de un perfil, el template que mejor coincide
con el golpe. El algoritmo para realizar este procedimiento ejecuta una estrategia determinada
utilizando el golpe capturado y cada uno de los templates del perfil activo que fueron creados con
el mismo dispositivo de captura del golpe de test. Luego, compara cada uno de los resultados y el
template de mejor coincidencia será el de mayor porcentaje general de similitud.

Mejor coincidencia Golpe-Templates mediante estrategia Inside

Con el propósito de instanciar la búsqueda del template que más parecido sea al golpe, se
implementó la clase ExecuteBestAgreementInside que extiende de Command.
Como se ve en el Algoritmo 4.7, se obtiene el perfil del usuario y el golpe seleccionado en la
interfaz de usuario. Luego se ejecuta la estrategia Inside, invocando el método FindBestAgreement
de AppManager, cuyo primer argumento corresponde al nombre de la estrategia a utilizar para
la búsqueda del template de mejor coincidencia.

1 v i r t u a l void ExecuteBestAgreementInside : : Execute ( ) o v e r r i d e {


2 AppManager * appManager = AppManager : : GetSingletonPtr ( ) ;
3

4 / / Se o b t i e n e e l p e r f i l y s t r o k e s e l e c c i o n a d o s en l o s ComboBox c o r r e s p o n d i e n t e s
5 P r o f i l e * p r o f i l e = GetSelectedComboBoxProfile ( ) ;
6 Stroke * s t r o k e = GetSelectedComboBoxStrokes ( ) ;
7

8 / / Se e j e c u t a l a e s t r a t e g i a I n s i d e para encontrar e l template de mejor c o i n c i d e n c i a


9 Strategy : : R e s u l t S t r a t e g y I n s i d e * r e s u l t = appManager−>FindBestAgreement (
STRATEGY_INSIDE, p r o f i l e , s t r o k e ) ;
10

11 / / Se o b t i e n e e l p o r c e n t a j e de s i m i l i t u d entre e l golpe y e l template


12 double resultValue = r e s u l t −>GetResultComparison ( ) * 100;
13 ...
14 }

Algoritmo 4.7: ExecuteBestAgreementInside::Execute

La Figura 4.9 muestra los resultados obtenidos de la ejecución de la estrategia Inside para
el reconocimiento del golpe nombrado como "Drive rápido". Para una mejor identificación de los

61
CAPÍTULO 4. INSTANCIACIÓN

gestos de test, las capturas fueron nombradas de acuerdo al tipo y velocidad con la que se realizó
el golpe. Se observa que la estrategia Inside detectó que el template que más parecido es al golpe
es del mismo tipo.

Figura 4.9: Mejor coincidencia mediante estrategia Inside

Mejor coincidencia Golpe-Templates mediante estrategia DTW

La clase ExecuteBestAgreementDTW fue implementada para utilizar la estrategia DTW en la


búsqueda del template que mejor coincide con un golpe en concreto. La clase obedece al patrón
Command. En el Algoritmo 4.8 se observa la implementación del método Execute.
1 v i r t u a l void ExecuteBestAgreementDTW : : Execute ( ) o v e r r i d e {
2 AppManager * appManager = AppManager : : GetSingletonPtr ( ) ;
3 / / Se o b t i e n e e l p e r f i l y s t r o k e s e l e c c i o n a d o s en l o s ComboBox c o r r e s p o n d i e n t e s
4 P r o f i l e * p r o f i l e = GetSelectedComboBoxProfile ( ) ;
5 Stroke * s t r o k e = GetSelectedComboBoxStrokes ( ) ;
6 / / Se e j e c u t a l a e s t r a t e g i a DTW para encontrar e l template de mejor c o i n c i d e n c i a
7 Strategy : : ResultStrategyDTW * r e s u l t = appManager−>FindBestAgreement (STRATEGY_DTW,
p r o f i l e , stroke ) ;
8 / / Se o b t i e n e e l p o r c e n t a j e de s i m i l i t u d entre e l golpe y e l template
9 double resultValue = r e s u l t −>GetResultComparison ( ) * 100;
10 ...
11 }

Algoritmo 4.8: ExecuteBestAgreementDTW::Execute

62
4.2. APLICACIÓN EDITOR DE PERFILES

Equivalente al algoritmo 4.7, en 4.8 se ejecuta la estrategia DTW para encontrar el template
del perfil seleccionado que mejor coincide con el golpe realizado. En la Figura 4.10 se observan los
resultados de la ejecución, con los valores de distancia y límites de cada sensor. El porcentaje de
similitud general corresponde a un promedio entre los resultados de los sensores. Estos sensores
están agrupados en dos grupos segmentando los acelerómetros de los giróscopos. Con estos grupos
se puede realizar una ponderación para que un grupo tenga más influencia por sobre el otro en el
resultado general.

Figura 4.10: Mejor coincidencia mediante estrategia DTW

Un detalle importante es que la ejecución de este algoritmo tiene una duración de 46 ms, un
tiempo muy superior comparado con la ejecución de la estrategia Inside.

63
CAPÍTULO 4. INSTANCIACIÓN

4.2.6 Configuraciones

Como el sistema está compuesto por muchas funcionalidades, de las cuales el entrenador
puede elegir, se realizó una interfaz para que las pueda administrar.
Ya que la aplicación se ha diseñado e implementado con la intención de proveerle al usuario
que realice las configuraciones que desee, se le tiene que permitir que desde una interfaz amigable
las pueda realizar.
Existen diversas configuraciones que se pueden realizar, ya sea en los dispositivos como en
las estrategias. Por ello, es que a continuación se explicarán en detalle las mismas.

4.2.6.1 Configuración de estrategias

Se han definido varias estrategias con diferentes mecanismos para poder comparar los golpes
y los templates. El usuario puede disponer de estas estrategias a gusto, con el objetivo de probar
distintas alternativas.

Figura 4.11: Ventana de configuración general de las estrategias

Como se han definido en el modelo, las estrategias pueden utilizar diferentes cálculos para
llegar al resultado. Para DTW, existe la variante entre:

• Desvío superior y desvío inferior

64
4.2. APLICACIÓN EDITOR DE PERFILES

• Máximos y mínimos

Estas dos alternativas son con el fin de encontrar la distancia lḿite utilizando las curvas
seleccionadas. Luego, el calculo del valor límite utilizando las curvas seleccionadas para considerar
si un gesto es reconocido o no puede ser mediante:

• Distancia euclídea

• Distancia mínima usando DTW

Posteriormente, para la estrategia Inside se puede calcular el límite superior y el límite


inferior a partir del conjunto de golpes del template mediante:

• Desvío superior e inferior del Template

• Mínimos y máximos del Template

También se puede configurar el margen de error que utilizará la estrategia. La estrategia


Inside verifica que los puntos de la curva generada por cada sensor del golpe se encuentre
dentro del canal de aceptación, donde los límites se obtendrán a partir de la opción anterior
seleccionada. El margen de error permite extender los límites del canal de aceptación, aunque el
valor considerado será inversamente proporcional al desvío de la muestra con respecto al límite.
Es decir, la magnitud del valor a considerar para el recuento final disminuirá proporcionalmente
si la distancia de la muestra aumenta con respecto al valor límite.

4.2.6.2 Configuraciones de dispositivo

Figura 4.12: Ventana Configuración de estrategias

Dado que existen ciertos dispositivos que contienen más de un grupo de sensores, se realizó
en la interfaz una configuración para manejar las ponderaciones entre los grupos de sensores
disponibles según el dispositivo. Las ponderaciones de cada grupo de sensores son utilizadas para

65
CAPÍTULO 4. INSTANCIACIÓN

el cálculo del porcentaje general de similitud de un golpe con respecto a un template. De esta
manera, variando las ponderaciones se modificará el peso o relevancia del grupo de sensores en
la obtención del resultado final de la comparación de gestos.
En particular, el dispositivo WiiMotionPlus contiene dos grupos de sensores. A continuación,
en la Figura 4.12 se pueden ver a los sensores acelerómetros y los sensores giróscopos reunidos
en dos grupos.
En la parte inferior de la ventana se puede aumentar o disminuir esa ponderación. Acla-
remos que los grupos de sensores conforman el 100 %. Entonces, si se aumenta alguna de las
ponderaciones de esos grupos, el otro se va a ver afectado directamente disminuyendo su valor.

66
4.3. VISUALIZADOR 3D

4.3 Visualizador 3D

El módulo Visualizador 3D consiste en un sistema de entrenamiento de tenis establecido en


un entorno 3D, el cual presenta un estadio y cancha de tenis donde el usuario puede realizar
y entrenar distintos golpes de tenis con los dispositivos disponibles. A diferencia del Editor de
Perfiles, en este caso, se simula el impacto de una pelota de tenis luego de cada golpe realizado.
En las siguientes subsecciones se presentarán los componentes de software que posibilitan
la administración y representación visual de las escenas 3D junto a los objetos gráficos que las
componen, así como también la simulación del comportamiento físico de estos objetos durante la
ejecución en el tiempo.

Figura 4.13: Vista aérea del estadio

4.3.1 Carga de escenas 3D

Una escena 3D está compuesta por distintos objetos gráficos, los cuales constituyen el escena-
rio de la aplicación. Estos objetos se definen mediante modelos 3D constituidos por un conjunto
de primitivas geométricas simples, tales como puntos, líneas y triángulos, además de otro tipo de
información necesaria para ser dibujados correctamente por pantalla. Todos estos objetos 3D son
manejados por el administrador de escenas de Ogre, la clase SceneManager, el cual define una
interfaz que permite organizar y gestionar la representación de modelos 3D.
Los objetos están definidos en mallas 3D. Una malla es una serie de triángulos que, por lo
general, contiene una textura. Representa la geometría visible de un objeto en una aplicación
3D. Para cargar una malla en una escena, es necesario crear una entidad. Esto último es una

67
CAPÍTULO 4. INSTANCIACIÓN

Figura 4.14: Clase SceneManager

instancia de una malla y es el objeto más común en una aplicación de Ogre. Varias entidades
pueden tener diferentes materiales y texturas, aunque compartan la misma malla.
A su vez, es posible crear entidades con diferentes mallas. Una entidad se crea llamando al
método createEntity, dándole un nombre y especificando el nombre de la malla en que se basará.
El SceneManager se asegurará de que la malla se cargue mediante una llamada al gestor de
recursos.
Las entidades no se consideran como parte de una escena hasta que no se conecten a un objeto
SceneNode. Es decir, una entidad no se renderiza en la escena hasta que no sea acoplada a un
SceneNode. Este nodo es un elemento lógico de la jerarquía del escenario gráfico que se puede
utilizar para organizar los objetos de una escena.
Puede tener varios nodos secundarios y entidades (entre otros objetos, como luces y cámaras)
conectados a él. Un SceneNode guarda la posición, orientación y escala de todos los objetos
acoplados. De esta manera, sólo cuando se crea una entidad y se conecta a un SceneNode, ésta
se podrá mostrar en la pantalla. Un concepto mayor a tener en cuenta es que el SceneManager
contiene un nodo raíz, mRootSceneNode, al cual todos los otros nodos están conectados. A partir
del SceneManager se crearán luces, cámaras y se configurará la luz ambiente, sombras y demás
aspectos de la escena.

4.3.2 Configuración del escenario

La creación y configuración del escenario se realiza desde el archivo court.scene. Contiene la


organización de la escena, es decir, las mallas 3D que se deben cargar, las entidades para crear y
la configuración de nodos y sus elementos conectados. De esta manera, a partir del archivo se
crearán las entidades y nodos necesarios a través del SceneManager para visualizar el estadio de
tenis en la aplicación 3D.
Cada modelo 3D que se representa en el visualizador tiene una correspondencia con un archivo
de este tipo. Por ejemplo, la cancha utilizada, la pelota, los ladrillos en ejercicio de potencia son
cargados desde archivos con extensión .scene.
Mediante el motor gráfico Ogre, se realizará el renderizado de cada uno de estos objetos que
componen la escena. A su vez, al estar inmersos en una simulación física, los objetos deben estar
ligados a un entorno físico, en estructuras apropiadas, actualizando la posición, orientación y

68
4.3. VISUALIZADOR 3D

fuerzas resultantes luego de colisiones. Para ello, comúnmente se utiliza un motor físico, el cual
se define como un programa o parte de un programa encargado de simular comportamiento físico.

Bullet se encargará de calcular las colisiones y relaciones entre los objetos de la escena.
Simulará los movimientos de los cuerpos rígidos que conforman el mundo físico y sus interacciones
ante la influencia de fuerzas. Para ello, es necesario proporcionar una forma geométrica a cada
cuerpo rígido, a través de primitivas de colisión simples o complejas. Cada objeto visual tendrá su
correspondencia con un cuerpo rígido, representado por una primitiva de colisión, el cual será
cargado y configurado desde el archivo physics.config.

Los límites de la cancha de tenis se cargan desde el archivo court.config. Se establecen los
límites del lado origen y el lado destino en el plano XZ de Ogre, tanto para la cancha singles como
la de dobles. El lado origen de la cancha es donde el jugador realizará los golpes y el lado destino
es donde se dirigirán los golpes. La configuración representa las medidas reales de una cancha de
tenis [25]. La Figura 4.16 muestra a escala las dimensiones de una cancha singles de tenis. Para
abstraernos de las posiciones absolutas de los límites, se implementó un mecanismo para utilizar
posiciones relativas. Entonces, para cada lado de la cancha, la esquina izquierda inferior será la
posición (0, 0) de la cancha y la esquina superior derecha será la posición (1, 1), como se muestra
en la Figura 4.15. La clase TennisCourt implementa esta lógica. Existen métodos que, a partir
de una posición absoluta en el plano XZ de Ogre, retorna la posición relativa en el plano de la
cancha. Y viceversa, a partir de una posición relativa en el plano de la cancha, retorna la posición
absoluta en el plano XZ de Ogre.

Figura 4.15: Posiciones relativas de los límites de una cancha singles

69
CAPÍTULO 4. INSTANCIACIÓN

Detalles de la cancha

• El piso de la cancha es un plano, donde en Ogre está representado por el plano XZ, el cual
el valor de la coordenada Y es siempre 0.

• El lado origen y destino de la cancha está representado por un rectángulo, en el plano XZ


de Ogre. Cada rectángulo es creado a partir de una coordenada mínima y una coordenada
máxima.

• El centro de la cancha es el punto (0, 0, 0) siendo las coordenadas (X, Y, Z).

• Desde el centro hacia la derecha tenemos valores positivos en la coordenada de X, quedando


(+, Y, Z), hacia la izquierda los valores son negativos (-, Y, Z).

• Desde el centro hacia arriba están los valores negativos de la coordenada Z, (X, Y, -) y (X, Y,
+) desde el centro hacia abajo.

Figura 4.16: Cancha de tenis a escala

El tipo de cancha, single o doble, es configurable. Las dimensiones de estas canchas ya están
cargadas por lo que sólo se debe seleccionar cuál se desea utilizar.

70
4.3. VISUALIZADOR 3D

4.3.3 Integración del motor gráfico con el motor físico

El estado de cada primitiva física está definido por su posición y orientación en un tiempo
determinado. El motor físico es el encargado de calcular el nuevo estado de los objetos luego de
cada actualización; y el motor gráfico, el de visualizar los objetos en la posición correcta. Entonces,
el motor físico realiza la actualización del estado para un tiempo determinado, el motor gráfico
solicita los datos asociados a cada objeto al motor físico, aplica los nuevos valores de posición y
orientación y los dibuja en pantalla [26]. En la Figura 4.17 se esquematiza la interacción entre
los motores.

Figura 4.17: Comunicación de datos entre un motor gráfico y un motor físico

El detalle de las transiciones se describen a continuación:

1. El motor físico calcula el próximo estado del mundo virtual.

2. El motor gráfico solicita los datos de los objetos al motor físico.

3. El motor físico devuelve los datos solicitados al motor gráfico.

4. El motor gráfico aplica los valores de posición y rotación a los objetos 3D.

5. El motor gráfico dibuja los objetos en pantalla.

71
CAPÍTULO 4. INSTANCIACIÓN

Integración de Ogre3D con Bullet Physics

Los objetos gráficos de Ogre3D y los cuerpos físicos de Bullet son entidades completamente
distintas y separadas. Si no se implementa algún mecanismo mediante el cual Bullet actualice
la posición y rotación de dicho objeto gráfico, se creará una situación de incoherencia en la
cual la posición del objeto gráfico permanecerá estática, al contrario que la del cuerpo físico
que se verá actualizada. Esto provocará que la simulación no se actualice, ya que Ogre es el
encargado de renderizar los objetos 3D, mientras que Bullet tiene la responsabilidad de modelar
un comportamiento realista sobre los cuerpos.
Para resolver el problema de la integración entre Bullet Physics y Ogre3D, los cuerpos
rígidos de Bullet cuentan con un atributo llamado estado de movimiento MotionState [27]. Este
MotionState abstrae de las operaciones de bajo nivel que se realiza cuando el cuerpo físico recibe la
influencia de alguna fuerza. De esta forma, se puede trabajar directamente con los cuerpos físicos,
sabiendo que las posiciones de los elementos de la escena serán adecuadamente actualizadas en
función del movimiento del cuerpo físico.
En resumen, la clase MotionState nos permite actualizar la posición de los nodos de escena
de Ogre. Para ello, se requiere adoptar una implementación, dado que se trata de una clase
abstracta. Dicha interfaz se encuentra implementada en la clase CustomMotionState.
1 void CustomMotionState : : SetWorldTransform ( const btTransform& worldTrans ) {
2 / / A c t u a l i z o l a o r i e n t a c i o n d e l o b j e t o 3D, a p a r t i r de l a o r i e n t a c i o n d e l cuerpo
fisico
3 btQuaternion r o t = worldTrans . getRotation ( ) ;
4 mSceneNode−>s e t O r i e n t a t i o n ( r o t .w( ) , r o t . x ( ) , r o t . y ( ) , r o t . z ( ) ) ;
5

6 / / A c t u a l i z o l a p o s i c i o n d e l o b j e t o 3D, a p a r t i r de l a p o s i c i o n d e l cuerpo f i s i c o
7 btVector3 pos = worldTrans . getOrigin ( ) ;
8 mSceneNode−>s e t P o s i t i o n ( pos . x ( ) , pos . y ( ) , pos . z ( ) ) ;
9 }

Algoritmo 4.9: CustomMotionState::SetWorldTransform

Bullet invoca de forma automática el método SetWorldTransform de cada uno de los cuerpos
físicos que forman el mundo. El método recibe un objeto de tipo btTransform. La clase btTransform
encapsula un cuaternio, que almacena la rotación del cuerpo físico; y un vector, que almacena su
posición. Dado que la clase MotionState almacena un puntero a un nodo de escena de Ogre3D,
en el momento en que Bullet invoque el método SetWorldTransform, se actualizará la rotación y
posición de dicho nodo de escena; es decir, se actualizará la posición y rotación del cuerpo gráfico
a partir de la nueva información recibida.
Por ejemplo, creamos la representación visual y física de la pelota de tenis:

72
4.3. VISUALIZADOR 3D

1 / / Creamos e l o b j e t o 3D de l a p e l o t a de t e n i s
2 Entity * e n t i t y T e n n i s B a l l = mSceneManager−>c r e a t e E n t i t y ( ’ EntityTennisBall ’ , ’ b a l l . mesh ’ ) ;
3 SceneNode * sceneNodeTennisBall = mSceneManager−>createSceneNode ( ’ NodeTennisBall ’ ) ;
4 sceneNodeTennisBall −>attachObject ( e n t i t y T e n n i s B a l l ) ;
5

6 / / Creamos e l cuerpo f i s i c o de l a p e l o t a de t e n i s , e l cual sera una e s f e r a .


7 / / Por parametro , se i n d i c a e l r a d i o de l a es fe ra , en metros .
8 btSphereShape * sphere = new btSphereShape ( 0 . 0 4 )
9

10 / / btTransform c o n t i e n e l a transformacion i n i c i a l d e l o b j e t o f i s i c o
11 btTransform transform ;
12 transform . s e t I d e n t i t y ( ) ;
13

14 f l o a t mass = 0 . 1 7 ;
15 btVector3 i n e r t i a ( 0 , 0 , 0 ) ;
16 sphere −>C a l c u l a t e L o c a l I n e r t i a ( mass , i n e r t i a ) ;
17

18 / / Unimos e l o b j e t o 3D con su cuerpo f i s i c o para s i n c r o n i z a r sus p o s i c i o n e s y


orientaciones
19 MotionState * motionState = new CustomMotionState ( transform , sceneNodeTennisBall ) ;
20

21 btRigidBodyConstructionInfo r b I n f o ( mass , motionState , sphere , i n e r t i a ) ;


22 rbInfo . m_friction = 0 . 5 ;
23 rbInfo . m_rollingFriction = 0 . 6 ;
24 rbInfo . m_restitution = 0 . 7 ;
25

26 / / Creamos e l cuerpo r i g i d o y l o a\~nadimos a l mundo f i s i c o


27 btRigidBody * r i g i d b o d y = new btRigidBody ( r b I n f o ) ;
28 mDynamicsWorld−>addRigidBody ( rigidBody ) ;

Algoritmo 4.10: Algoritmo para crear representación visual y física de la pelota

El constructor de la clase btRigidBody recibe un objeto btRigidBodyConstructionInfo. Este


objeto sirve para inyectar al constructor de la clase información relativa al cuerpo rígido que se va
a crear. Los argumentos que recibe son la masa del objeto, el estado del cuerpo (CustomMotionS-
tate), la forma física del cuerpo (btSphereShape) y el vector de inercia. A partir de la forma del
cuerpo y de la masa de éste, Bullet calcula la inercia del cuerpo físico que estamos construyendo
a través del método btCollisionShape::CalculateLocalInertia. Una vez creado el cuerpo rígido,
hay que añadirlo al mundo físico a través del método btDiscreteDynamicsWorld::addRigidBody.
En la Figura 4.18 se pueden apreciar los distintos objetos que están situados en el escenario,
los cuales contienen unas líneas verdes en sus bordes. Estas líneas representan los objetos físicos
dentro del escenario, que como se observa se corresponden con la visual. Por ejemplo, un ladrillo
es una caja y en la imagen está representado por las líneas verdes que forman sus aristas.
Además de las líneas verdes hay unas de color azul y otras rojas. Estas corresponden al eje de

73
CAPÍTULO 4. INSTANCIACIÓN

Figura 4.18: Visualización física de los objetos

coordenadas para objetos dinámicos, que significa que tienen un comportamiento físico que al
aplicarle una fuerza cobran movimiento.
Otra observación que se puede hacer con los objetos es comparar una silla con un ladrillo.
Como dijimos anteriormente, el ladrillo es una caja, una primitiva simple del motor físico; en
cambio, la silla está creada a partir de una primitiva compleja llamada btBvhTriangleMeshShape,
donde el cuerpo físico comparte la forma geométrica del objeto 3D.

4.3.4 Instructor

El módulo instructor cumple la función de configurador y administrador del visualizador 3D.


En el instructor se realizan las siguientes acciones:

• Elegir el ejercicio a realizar.

• Realizar la configuración del ejercicio.

• Posicionar la pelota para darle el golpe.

• Seleccionar el perfil del jugador que hará el golpe.

• Identificar con qué dispositivo hará el golpe.

• Seleccionar la estrategia de comparación para reconocer los golpes del jugador.

Esta funcionalidad se realiza mediante una comunicación con un servidor que hace de
intermediario. Esto se realizó siguiendo la arquitectura Cliente-Servidor [28].

74
4.3. VISUALIZADOR 3D

4.3.4.1 Comunicación Instructor-Servidor-Visualizador

Se ha utilizado un servidor que fue realizado por Pladema para distintos proyectos. El servidor
cuenta con librerías que utilizan el protocolo UDP para mayor eficiencia e implementan una capa
de software transparente al usuario para mantener la comunicación activa y detectar si la misma
se ha caído.
El servidor mantiene un diccionario de clave/valor, siendo este último una estructura compleja
donde también tiene una lista de qué clientes están suscriptos a esa clave. Tanto en el Instructor
como en el Visualizador se sitúa el cliente y se incorpora como una biblioteca al proyecto.
Este tipo de comunicación entre el visualizador y el instructor permite que se encuentren en
computadoras distintas. Incluso puede instalarse el servidor en una tercer computadora. Sólo
basta con realizar la configuración de las direcciones IP’s, los puertos y el nombre del host para
establecer la conexión con el servidor.
Luego para el instructor se debe configurar el nombre del receptor, en este caso será el nombre
del host del visualizador y viceversa.

Estados de la aplicación

La aplicación del visualizador atraviesa diferentes estados a lo largo de su ejecución. Por ello,
a través de la Figura 4.19 se observa el flujo que realiza el visualizador.

Figura 4.19: Diagrama de Actividades de Estados de la Aplicación

75
CAPÍTULO 4. INSTANCIACIÓN

El estado inicial de la aplicación es Conectando con el Servidor. Luego de realizar la conexión


la aplicación se encuentra en el estado Esperando Instructor para proceder a realizar las configu-
raciones del ejercicio que el instructor seleccione. Una vez que se elige el ejercicio y se configura,
se espera que el dispositivo de captura de datos se encuentre conectado. Después de conectarse el
dispositivo el simulador queda ejecutándose hasta que el instructor decida finalizarlo.
Además, ciertos estados consideran la desconexión con el servidor. De ser el caso, se vuelve al
estado inicial donde se intenta restablecer la conexión.
Las transiciones de un estado a otro tienen una numeración que se detalla a continuación.

1. Conexión Establecida.

2. Variables de Configuración del Ejercicio.

3. Simulador Configurado.

4. Dispositivo Conectado.

5. Ejercicio Finalizado.

6. Conexión Perdida.

7. Dispositivo Desconectado.

En la Figura 4.20 se puede ver en el visualizador uno de los estados de la aplicación, particu-
larmente en el estado inicial.

Figura 4.20: Vista esperando Servidor

76
4.3. VISUALIZADOR 3D

4.3.5 Ejercicios

Para la implementación de los ejercicios se realizó una interfaz llamada Exercise como se ve
en la Figura 4.21. Esta clase tiene dos métodos. El primero, Start, que se encarga de posicionar
dónde estará la pelota al momento del golpe y de dar inicio al ejercicio. El segundo, Configure,
que realiza la configuración propia de cada tipo de ejercicio.

Figura 4.21: Clase Exercise

Se definieron los siguientes tipos de ejercicios:

• Libre

• Potencia

• Precisión

Cuando se inicia un ejercicio, se espera por la captura de un golpe por parte del jugador. Luego
se buscará el template que mejor coincide con el golpe capturado y se aplicará un impulso a la
pelota de tenis a través del motor físico. El impulso estará dado por los valores de un vector de 3
coordenadas (X, Y, Z), donde:

• X representa la dirección destino de la pelota

• Y representa la altura que tomará la pelota

• Z representa la velocidad o potencia con la que saldrá la pelota

El vector de impulso será calculado a partir del análisis de los valores de los sensores del
dispositivo que se utilizó para capturar el gesto y el análisis de los datos del perfil que realizó el
golpe. En las siguientes secciones, se verá en mayor detalle el cálculo de la dirección y potencia
del golpe, representado por las coordenadas del vector de impulso X y Z respectivamente.

77
CAPÍTULO 4. INSTANCIACIÓN

4.3.5.1 Configurador de ejercicios

Estos ejercicios se definen desde el instructor y se ejecutan en el visualizador. Por esto, existe
una interfaz de configuración del ejercicio que le permite al instructor definir el ejercicio a realizar.
En la Figura 4.22 se observa la pantalla de configuración donde se selecciona el perfil del
jugador, el dispositivo con el que se va a realizar, la estrategia de comparación, el golpe a realizar
y el tipo de ejercicio.

Figura 4.22: Pantalla de Configuración de Nuevo Ejercicio

Luego de completar la configuración inicial del ejercicio el instructor debe ubicar dónde quiere
colocar la pelota y la altura de la misma como se ve en la Figura 4.23.

78
4.3. VISUALIZADOR 3D

Figura 4.23: Pantalla de Configuración de Nuevo Ejercicio

4.3.5.2 Ejercicio libre

En este ejercicio el jugador deberá realizar un golpe y se evaluará si el pique es dentro de


los límites de la cancha para darlo como correcto. El Algoritmo 4.11, un método de la clase
TennisCourt, es utilizado para saber si la pelota picó dentro o fuera de los límites del lado destino
de la cancha.
1 b o o l TennisCourt : : isContainDestinationSide ( Vector3 v e c t o r ) {
2 / / Obtengo l a s coordenadas minimas y maximas d e l lado d e s t i n o de l a cancha que se
esta usando ( puede ser s i n g l e s o dobles )
3 Vector2 min = mCurrentInfoCourt −>d e s t i n a t i o n −>planeMin ;
4 Vector2 max = mCurrentInfoCourt −>d e s t i n a t i o n −>planeMax ;
5 / / Como e l p i s o de l a cancha es e l plano XZ y por ende Y = 0 , no chequeo con l a
coordenada Y de v e c t o r
6 b o o l valueReturn = min . x <= v e c t o r . x && v e c t o r . x <= max . x && min . y <= v e c t o r . z &&
v e c t o r . z <= max . y ;
7 return valueReturn ;
8 }

Algoritmo 4.11: TennisCourt::isContainDestinationSide

79
CAPÍTULO 4. INSTANCIACIÓN

4.3.5.3 Ejercicio de potencia

Para el ejercicio de potencia se ideó tener que derribar algún tipo de obstáculo. Se plantearon
distintas alternativas y se eligió una pared de ladrillos.
En este ejercicio puede cambiarse su dificultad realizando dos cambios. El primero, a medida
que aumenta la dificultad también lo hace el peso del ladrillo. El segundo, a medida que aumenta
la dificultad disminuye el tamaño de la pared.

Figura 4.24: Pantalla de Configuración de Ejercicio Potencia

En la Figura 4.24, se observa la configuración del ejercicio de potencia donde se le permite


al instructor que cambie dicha dificultad y además sitúe la pared en la zona de la cancha que
desea. La Figura 4.25 muestra el ejercicio de potencia ejecutandóse en el visualizador, con la
configuracón establecida por el instructor.

80
4.3. VISUALIZADOR 3D

Figura 4.25: Visualizador en ejercicio de potencia

Cálculo de la potencia del golpe

Luego de analizar los comportamientos de los sensores de los dispositivos de captura al


ejecutar un golpe, se logró encontrar un patrón para detectar la potencia que efectuó el jugador.
El valor de la potencia corresponde al valor de la coordenada Z del vector de impulso. Para ello
se analizaron los acelerómetros de los ejes X e Y. Se detectó que cuanto mayor es la aceleración,
cuanto más rápido se realiza el golpe, se produce un pico de aceleración positivo en Y y uno
negativo en X en el mismo instante. Entonces se busca el instante t donde se producen esos
picos. Luego, se calcula la distancia entre la aceleración positiva de Y y la negativa de X. Cuanto
mayor es el valor de la distancia se concluye que el impulso es más fuerte, por ende el valor de la
coordenada Z del vector de impulso será alto. En caso contrario, cuando la distancia es cercana a
0, la coordenada Z tendrá un valor bajo.
La Figura 4.26 muestra los valores de los acelerómetros en los ejes X e Y del dispositivo
Wiimote en un golpe con potencia. Se puede apreciar que existe un rango de valores positivos altos
de aceleración en Y mientras que, en el mismo instante, la aceleración en X es negativa y la más
baja. El rango de valores de la coordenada Z del vector de impulso se estableció empíricamente
durante distintas pruebas realizadas.
Cabe aclarar que cada dispositivo debe implementar una estrategia específica para calcular la
potencia del golpe capturado. En nuestra aplicación, ambos dispositivos de uso, tanto el Wiimote
como el WiiMotionPlus, contienen sensores acelerómetros. En caso de existir otro dispositivo que
no tiene esos sensores, se debe implementar una estrategia diferente para obtener el valor de la
coordenada Z del vector de impulso.

81
CAPÍTULO 4. INSTANCIACIÓN

Figura 4.26: Acelerómetros en un golpe con potencia

4.3.5.4 Ejercicio de precisión

En el ejercicio de precisión se creó un círculo en el piso. La pelota deberá picar dentro del
círculo para establecer como correcto el ejercicio. El diámetro del círculo variará en base a la
dificultad elegida por el instructor en el configurador del ejercicio. El tamaño del círculo es
inversamente proporcional a la dificultad del ejercicio.

Figura 4.27: Pantalla de Configuración de Ejercicio Potencia

82
4.3. VISUALIZADOR 3D

Además, el instructor puede mover el círculo en cualquier posición de la cancha mediante la


configuración del ejercicio como se muestra en la Figura 4.27.

Cálculo de la dirección del golpe

Antes de comenzar con la ejecución de un ejercicio se realiza un preprocesamiento sobre


el perfil del jugador, más específicamente sobre los datos de los templates. Es por ello que, al
momento de la creación de un template, el usuario debe efectuar el golpe de dos maneras:

• Realizar golpes dirigidos a la esquina izquierda del lado destino de la cancha (Figura 4.6)

• Realizar golpes dirigidos a la esquina derecha del lado destino de la cancha.

Recordemos que un template está compuesto por un conjunto de golpes. Además, con la
incorporación de la orientación de los golpes del conjunto, el template estará representado por un
vector de dirección [29]. Entonces, como se explicó anteriormente la cancha en coordenadas, para
un determinado tipo de golpe tendremos un template cuyo vector de dirección estará orientado
hacia el X positivo, representado por el conjunto de golpes dirigidos a la esquina derecha del lado
destino de la cancha.
Asimismo, existirá otro template donde su vector de dirección tendrá un sentido hacia el X
negativo, constituido por capturas dirigidas a la esquina izquierda del lado destino de la cancha.
Estos templates los llamaremos complementarios y serán utilizados para el cálculo de la dirección
del golpe en el visualizador 3D. La Figura 4.28 esquematiza los vectores de dirección de los
templates complementarios. La línea punteada verde representa la dirección central, donde el
valor de X es 0.

Figura 4.28: Vectores de dirección de los templates complementarios

83
CAPÍTULO 4. INSTANCIACIÓN

De esta manera, al comparar un golpe contra los templates complementarios, sabremos


en qué dirección se realizó a partir de mejor coincidencia con un template. Si el golpe coincide
mayormente con el template cuyo vector director está orientado al X positivo, entonces la dirección
del golpe tendrá una tendencia hacia la derecha. En caso contrario, será hacia la izquierda.
La dirección corresponde al valor de la coordenada X del vector de impulso. Análogamente, si
el valor de la coordenada X es positivo, la pelota saldrá hacia la derecha. Si el valor es negativo,
la dirección será hacia la izquierda. Resta encontrar el valor de esa coordenada, a partir de los
porcentajes de comparación del golpe contra los templates complementarios. Para ello, se realiza
el siguiente procedimiento:

1. Comparar el golpe contra los templates complementarios.

(4.1) R n = Comparar(G c , T n )

(4.2) R p = Comparar(G c , T p )

Donde:

• G c simboliza el golpe capturado

• T n simboliza el template con vector de dirección al X negativo

• T p simboliza el template con vector de dirección al X positivo

• Comparar es una función que retorna la similitud de un golpe con un template, cuyo
valor de retorno estará en el intervalo [0, 1]

2. Calcular la diferencia entre el template de mayor coincidencia con el template de menor


coincidencia.
¯ ¯
(4.3) D = ¯R n − R p ¯

Para poder analizar el resultado de la diferencia entre los templates y poder determinar si
es un valor significativo o no, se utiliza un valor de referencia. Ese valor de referencia será
una estimación de la diferencia teórica máxima que puede existir entre los resultados de
las comparaciones del golpe contra los templates complementarios.

Se partió de la premisa que, para templates complementarios, si un golpe coincide plena-


mente con un template (el resultado de la comparación es 1) entonces existirá una diferencia
significativa con el resultado de la comparación del mismo golpe contra el template opuesto.

Un golpe que coincide plenamente con un template, es el golpe promedio del template. Por
ende, la comparación dará como resultado que son exactamente iguales.

(4.4) Comparar(A n , T n ) = 1

84
4.3. VISUALIZADOR 3D

(4.5) Comparar(A p , T p ) = 1

Donde:

• A n simboliza el golpe promedio del template con vector de dirección al X negativo

• A p simboliza el golpe promedio del template con vector de dirección al X positivo

Si comparamos el golpe promedio de un template contra su template opuesto nunca pueden


ser iguales.

(4.6) Comparar(A p , T n ) < 1

(4.7) Comparar(A n , T p ) < 1

Los resultados de estas comparaciones son utilizados para obtener los valores de referencias.

• Valor de referencia X negativo

(4.8) V R n = Comparar(A n , T n ) − Comparar(A n , T p ) = 1 − Comparar(A n , T p )

V R n representa la diferencia teórica máxima entre el template de mayor coincidencia


T n contra el template de menor coincidencia T p .

• Valor de referencia X positivo

(4.9) V R p = Comparar(A p , T p ) − Comparar(A p , T n ) = 1 − Comparar(A p , T n )

V R p representa la diferencia teórica máxima entre el template de mayor coincidencia


T p contra el template de menor coincidencia T n .

Entonces, durante el preprocesamiento de los templates del perfil y para todos los templates
complementarios, se obtienen los valores de referencia V R n y V R p para ser utilizados
durante la búsqueda de la dirección de un golpe. Además, se estableció un valor de la
coordenada X del vector de impulso asociado a cada valor de referencia:

• Para el valor de referencia V R p , el valor de la coordenada X será 1

• Para el valor de referencia V R n , el valor de la coordenada X será -1

3. Obtener el valor de referencia y el valor de la coordenada X asociada, de acuerdo al template


de mayor coincidencia. Si el golpe capturado G c coincide mayormente con el template T n ,
entonces el valor de referencia a utilizar será V R n (Ecuación 4.8). De lo contrario, se
utilizará V R p (Ecuación 4.9).

85
CAPÍTULO 4. INSTANCIACIÓN

• Vr representa el valor de referencia a utilizar

• Vx representa el valor de la coordenada X asociada al valor de referencia Vr

4. Obtener el valor final de la coordenada X del vector de impulso.

(4.10) X = I nter polacionLineal(D, 0, Vr , 0, Vx )

La interpolación lineal de 4.10 convierte el valor D, en el intervalo 0 y Vr , al intervalo 0 y


Vx .

De este modo, la dirección del golpe tendrá el sentido del vector director del template de
mayor coincidencia. Si el valor D (Ecuacion 4.3) es igual al valor de referencia del template
de mayor coincidencia Vr , se aplicará el valor Vx a la coordenada X del vector de impulso. Si
D es 0, entonces el golpe coincide de igual manera con ambos templates complementarios.
En tal caso, el valor de la coordenada X será 0, por lo tanto la dirección de la pelota será
hacia el medio.

En conclusión, para recrear virtualmente la dirección del golpe capturado debemos obtener el
valor de la coordenada X del vector de impulso mediante:

• El uso de la estrategia de reconocimientos de golpes.

• La diferencia entre los resultados de las comparaciones del golpe contra los templates
complementarios.

• El análisis de la diferencia obtenida a partir del valor de referencia precalculado.

• El cálculo del valor de la coordenada X del vector de impulso según el vector director del
template de mayor coincidencia.

4.3.5.5 Ejecución del ejercicio

Cuando un ejercicio finaliza, indicando si lo realizó bien o no, se muestra en el visualizador


3D el resultado. Además, desde la aplicación del instructor se podrá observar lo realizado por
el jugador durante esa sesión. Por cada golpe que realizó puede ver el golpe reconocido por la
aplicación y si lo hizo correctamente o no.
En la Figura 4.29 se observa en la parte superior un resumen de la configuración del ejercicio
a realizar y la foto de perfil del jugador. Luego, en el centro de la Figura se observa una grilla
con los golpes realizados y los resultados correspondientes. Existen dos columnas para visualizar
los resultados, donde Resultado ejercicio corresponde a si cumplió con el objetivo del ejercicio, es
decir, si lo hizo correctamente; y Resultado final es una combinación del resultado del ejercicio y si
realizó el golpe que debía ejecutar. Por ejemplo, se establece en la configuración del ejercicio que
el jugador sólo debe realizar golpes de tipo Drive. Luego, durante la ejecución, un golpe cumplió

86
4.3. VISUALIZADOR 3D

con el objetivo del ejercicio, pero fue identificado como un golpe de tipo Revés. En ese caso, la
columna Resultado ejercicio mostrará un Bien, pero el resultado final será Mal ya que el jugador
realizó un golpe que no debía efectuar.

Figura 4.29: Pantalla del ejercicio en ejecución

En la parte inferior izquierda de la Figura, se observan tres botones: una pelota, dos pelotas
y un ojo. El primero de ellos sirve para visualizar en la cancha la trayectoria que realizará la
pelota en el próximo golpe a efectuar. El segundo para visualizar en la cancha las trayectorias y
los piques de todos los golpes realizados, mostrando en verde los resultados finales que fueron
correctos y, en rojo, los incorrectos. Por último, el tercero es para simular el Ojo de Halcón, el
mismo que en los partidos de tenis.
En la parte inferior derecha de la Figura se encuentran los botones para repetir el ejercicio y
el botón para pausar el visualizador.

87
CAPÍTULO 4. INSTANCIACIÓN

4.3.5.6 Mostrar trayectoria de la pelota

Como se mencionaba anteriormente, uno de los botones muestra en el visualizador la trayec-


toria que realiza la pelota al efectuar un golpe, como se aprecia en la Figura 4.30

Figura 4.30: Visualizador en ejercicio de precisión mostrando trayectoria de la pelota

Para lograr esto, se creó la clase VisualExercise. La clase implementa la lógica necesaria para
configurar y dibujar la trayectoria de la pelota en el escenario. El método startExercise, que se
muestra en el Algoritmo 4.12, se invoca cuando se inicia un ejercicio. La clase RibbonTrail [30]
de Ogre es utilizada.
Una instancia de la clase dibuja automáticamente el rastro que deja un nodo de escena al
moverse por el escenario, generando la geometría de los elementos que componen la cadena de la
trayectoria. Sólo se debe agregar el nodo de escena a rastrear, que será el nodo de escena que
contiene la pelota de tenis, además de otros parámetros de configuración tales como la distancia
máxima de la trayectoria, la cantidad máxima de elementos de la cadena, el ancho y color de los
elementos, etcétera.

88
4.3. VISUALIZADOR 3D

1 void Vi su al E xercise : : s t a r t E x e r c i s e ( ) {
2 / / Creo un nodo de escena para e l o b j e t o RibbonTrail
3 mSceneNodeTrail = mSceneManager−>getRootSceneNode ( ) −>createChildSceneNode ( ) ;
4 / / Creo y c o n f i g u r o e l RibbonTrail desde e l archivo t r a i l . scene
5 / / El archivo c o n t i e n e l o s parametros de c o n f i g u r a c i o n d e l RibbonTrail
6 DotScene * dotScene = new DotScene ( mSceneManager ) ;
7 dotScene −>parseDotScene ( " t r a i l . scene " , mSceneNodeTrail ) ;
8 d e l e t e dotScene ;
9

10 / / Obtengo e l o b j e t o RibbonTrail que fue adjuntado a l nodo durante l a carga y


11 / / c r e a c i o n d e l o b j e t o desde e l archivo
12 mRibbonTrail = mSceneNodeTrail −>getChild ( 0 ) −>getAttachedObject ( 0 ) ;
13 / / Obtengo l a r e f e r e n c i a a l nodo que c o n t i e n e l a p e l o t a de t e n i s y l o agrego a l
14 / / RibbonTrail para que d i b u j e l a e s t e l a automaticamente mientras se desplaza
15 / / por e l e s c e n a r i o
16 SceneNode * nodeTennisBall = mSceneManager−>getSceneNode (BALL_SCENE_NODE_NAME) ;
17 mRibbonTrail −>addNode ( nodeTennisBall ) ;
18 }

Algoritmo 4.12: VisualExercise::startExercise

Luego, cuando finaliza el ejercicio, la trayectoria que generó la pelota al realizar el golpe es
almacenada y se establece el color en rojo o verde, según el resultado del ejercicio. De esta manera,
estará disponible para visualizarla cuando el instructor presione el botón correspondiente.

Figura 4.31: Visualizador en ejercicio de precisión mostrando las trayectorias de las pelotas

La Figura 4.31 muestra las trayectorias de la pelota en los golpes realizados en la sesión del
ejercicio de precisión. Se puede apreciar que un solo golpe cumplió con el objetivo del ejercicio, el

89
CAPÍTULO 4. INSTANCIACIÓN

cual corresponde a la trayectoria de color verde.

4.3.5.7 Ojo de halcón

El ojo de halcón es un sistema informático usado en tenis y otros deportes para seguir la
trayectoria de la pelota. El sistema genera una imagen de la trayectoria y el pique de la pelota en
el suelo que puede ser utilizado por los jueces para decidir en jugadas dudosas [31].
La tecnología del ojo de halcón fue implementada en el visualizador 3D como una animación
de la cámara, desplazando la misma hacia la posición del pique de la pelota, simulando un pedido
de challenge [32] por parte del jugador. La cámara comienza situada en una posición y una
orientación inicial, del lado de la cancha donde el jugador realizó el golpe. Luego, se dirige hacia
el lugar donde se detectó el pique de la pelota, a una velocidad constante. Por último, la cámara
enfoca el pique de la pelota, como se muestra en la Figura 4.32. Además, el pique es dibujado
dependiendo del ángulo, velocidad y dirección de impacto de la pelota con el suelo de la cancha.

Figura 4.32: Visualizador en ejercicio de precisión mostrando el pique de la pelota, luego de


ejecutar la animación del ojo de halcón

90
4.3. VISUALIZADOR 3D

4.3.6 Visualizador en Oculus Rift

Para poder adaptar nuestra aplicación, más precisamente el visualizador 3D al Oculus Rift
DK2, la implementación debió ser modificada y diseñada específicamente para que funcione
correctamente con Oculus Rift. Para ello se utilizó el SDK 0.4.4-beta [33].
El SDK funciona en dos modos:

• Modo directo

• Modo extendido

En el modo directo, la imagen se envía directamente al Oculus. En contraparte, en el modo


extendido, el Oculus Rift se utiliza como un monitor secundario y, según la documentación, es el
modo recomendado a utilizar en la versión del SDK. Además, de acuerdo a lo que se encuentra en
los foros de Ogre, el modo directo no funciona correctamente con la versión 1.9 de Ogre y DirectX
9, el sistema de renderizado utilizado por nuestra aplicación. A su vez, el modo extendido debe
ejecutarse bajo OpenGL.
Teniendo en cuenta estas restricciones, se adoptó la implementación del visualizador 3D
para ser utilizado con Oculus, incluyendo las librerías adecuadas y la clase Rift [34]. La clase
encapsula todo el comportamiento y la interacción con el dispositivo.

4.3.6.1 Proceso de inicialización y configuración de la aplicación con Oculus Rift

1. Se crea una ventana de renderizado en el segundo monitor.

2. Se crean dos cámaras en la escena, una al lado de la otra, mirando en la misma dirección.
Cada cámara se corresponderá con los ojos de una persona. Se crea un nodo de escena
mBodyNode, que representa el cuerpo de la persona. Luego se crea un nodo de escena
mHeadNode, donde se adjuntan las cámaras que representan los ojos de la persona. El
nodo mHeadNode será un nodo hijo de mBodyNode. De esta manera, nuestra aplicación
controlará el cuerpo de la persona (caminar, girar), es decir el nodo mBodyNode, y la clase
Rift manejará el nodo mHeadNode, la cabeza de la persona.

3. Se inicializa el dispositivo y se crea un nuevo Rift.

4. Se ajusta la distancia entre las cámaras, utilizando el método Rift::getIPD(). La función


retorna la distancia, en metros, entre el ojo izquierdo y el ojo derecho del dispositivo. Por
defecto, este valor es 0,064 metros (6,4 centímetros).

5. Se invoca el método Rift::setCameras(leftCamera, rightCamera) para enviar las cámaras


a la clase Rift. La clase creará los ViewPorts a partir de esas cámaras y configurará las
matrices de proyección. El Oculus Rift estará configurado.

91
CAPÍTULO 4. INSTANCIACIÓN

6. En cada frame, se deberá invocar el metodo Rift::update() para actualizar las transforma-
ciones del dispositivo. Luego, a partir de la orientación y la posición, que se obtienen con los
métodos Rift::getOrientation() y Rift::getPosition() respectivamente, se actualizará el nodo
que contiene las cámaras mHeadNode.

Como se puede ver en la Figura 4.33, el visualizador funciona en Oculus Rift. Como se explicó
anteriormente, cada imagen correspondiente a cada ojo es tomada desde una cámara distinta en
el visualizador. Por ello es que en la imagen que se proyecta en el ojo izquierdo se puede ver más
hacia la izquierda que en la otra imagen. Asimismo se puede observar la perspectiva de la pelota
para un ojo y para otro.

Figura 4.33: Visualizador en Oculus Rift

92
CAPÍTULO
5
C ONCLUSIONES Y TRABAJOS FUTUROS

5.1 Conclusiones

Este trabajo incluye el desarrollo de una plataforma que es capaz de realizar captura, analizar
y almacenar los golpes realizados por el jugador. Cada característica de la plataforma fue
implementada siguiendo los atributos de calidad de modificabilidad y extensibilidad para que
tenga la capacidad de adecuarse a nuevos requerimientos.

Dentro del framework existen tres módulos más importantes, tal como el módulo de datos, el
módulo de dispositivos y el módulo de estrategias. Dentro del módulo de las estrategias, se han
implementado diferentes técnicas de comparación para poder analizar los golpes y Templates del
jugador.

Mediante el Editor de Perfiles el instructor puede administrar a sus alumnos. También se


pueden cargar los Templates y golpes de los jugadores.

El instructor puede configurar el ejercicio desde el Editor de Perfiles para que el alumno lo
realice en el Visualizador 3D. Además, en la aplicación del instructor se puede ver el resultado de
cada uno de los intentos que realizó el jugador en ese ejercicio. El Visualizador 3D contiene una
cancha representando de manera fiel las dimensiones reales de una cancha profesional. Además,
para llevar a cabo el movimiento de la pelota se implementó con un motor físico para interpretar
cada uno de los comportamientos. Asimismo, en el visualizador se pueden ver cada una de las
trayectorias resultantes de los golpes y la animación del ojo de halcón visualizando el último
pique de la pelota.

Por último se implementó el Visualizador 3D para el Oculus Rift añadiendo mayor realidad
ya que contempla el movimiento del jugador que realiza con la cabeza.

93
CAPÍTULO 5. CONCLUSIONES Y TRABAJOS FUTUROS

5.2 Limitaciones del sistema

A lo largo del trabajo nos hemos encontrado con diversos obstáculos. El primero radica en los
sensores que componen el dispositivo Wiimote. Estos sensores, como se explicó en el anexo, tienen
un rango muy limitado para utilizarse en un entorno donde las aceleraciones se dan de manera
brusca. Por lo tanto, se pierde mucha información al tener reducido el rango de los sensores.
Los sensores que más fácil se saturan realizando un golpe de tenis son los giróscopos. Esto es
porque durante un corto lapso del golpe se debe girar la raqueta rápidamente. Por otra parte, los
sensores acelerómetros se saturan en menor medida que los anteriores. Estos sensores han sido
saturados por personas que juegan habitualmente al tenis o deportes similares, ya que tienen la
capacidad de desarrollar una mayor aceleración en su golpe.
No sólo la saturación es un problema en los sensores, sino también la cantidad de valores que
pueden leer por unidad de tiempo. Hay que tener en cuenta el tiempo de duración de un golpe
es menor a 1 segundo. Sería ideal que cada sensor tenga la capacidad de leer por lo menos 1000
valores por segundo.
Además, mediante los giróscopos y acelerómetros no se puede calcular la posición relativa del
dispositivo. Tener la posición relativa nos ayudaría para poder distinguir en qué dirección realizó
el golpe.
Otra de las limitaciones con la que nos hemos encontrado es que en nuestro sistema realizamos
la captura de los datos que el jugador realiza con su brazo. Sin embargo, existen varios puntos
que se deberían evaluar para considerar si un golpe está realizado correctamente. Uno de ellos es
la posición del cuerpo al momento del impacto con la pelota. Además, para cada golpe el cuerpo
debe realizar un movimiento en particular.
Las partes del cuerpo que son analizadas por un instructor son todas. A continuación detalla-
mos las más importantes:

• Posición del codo.

• Posición y dirección de los pies.

• Dirección del torso.

Por ello, analizar un golpe de tenis considerando sólo el movimiento del brazo es insuficiente
si se pretende utilizar el sistema para un uso profesional.
Como no se pudo recrear virtualmente el golpe a partir de los sensores de los dispositivos
utilizados se tuvo que implementar la estrategia para calcular el ángulo de dirección del golpe. Es
muy probable que mediante la posición relativa del dispositivo pueda ser calculada la dirección
del golpe.

94
5.3. TRABAJOS FUTUROS

5.3 Trabajos futuros

Entre los trabajos futuros para extender nuestra propuesta, podemos encontrar:

• Agregar un nuevo dispositivo a la plataforma que detecte las extremidades del cuerpo, para
trabajar en conjunto con el Wiimote. Por ejemplo, Kinect.

• Utilizar un dispositivo con sensores de mayor precisión y mayor cantidad de muestras por
unidad de tiempo.

• Utilizar otro dispositivo similar al Wiimote, que sea uno de bajo costo pero que cuente con
la posición en el espacio. Por ejemplo, Ps Move.

• Obtener una mayor cantidad de métricas a partir de los sensores del dispositivo. Por
ejemplo, calcular la velocidad a partir de las aceleraciones.

• Integrar el dispositivo en una raqueta para que el jugador no sienta diferencias al momento
de realizar un golpe. Además, en la punta de la raqueta se podría incorporar otros sensores
acelerómetros y giróscopos para complementar con otro punto de observación.

• Incorporar la realización de golpes con la pelota en movimiento.

95
PÉNDICE
A
A
A PÉNDICE

A.1 Captura de datos

Es importante hacer la aclaración de que si bien fue planteado para utilizarse en aplicaciones
de diversos deportes para reconozcer gestos, fue considerado el tenis como principal deporte para
aplicarlo. Debido a esto, se podrá observar que en ciertas ocasiones llamamos a los gestos como
golpes, o su traducción al inglés Strokes.
Los datos generados por los sensores de los dispositivos están dados en valores pertenecientes
a un rango aceptable. Particularmente en el Wiimote el sensor acelerómetro que se utiliza es el
acelerómetro ADXL330 [35], que registra valores de tres dimensiones y cada una tiene un rango
aceptable de:

±3g

donde g es la constante de gravitación universal.


Adicionalmente el Wiimote tiene la posibilidad de conectar una extensión llamada Wii Remote
Plus. Esta expansión agrega mayor precisión a cada uno de los ejes identificados por los sensores
acelerómetros, contiene tres sensores giróscopos los cuales tienen un rango de aceptación de:


±2500ω =
dt
donde w representa la velocidad angular caracterizada por la división de una medida angular
sobre el tiempo.
Un golpe de tenis dura aproximadamente 1,3 seg desde que se prepara para realizar el golpe
hasta que logra el impacto con la pelota. Pero el lapso es muchísimo más corto si tomamos en

97
APÉNDICE A. APÉNDICE

cuenta desde que el jugador se encuentra preparado para realizar el golpe hasta el impacto, este
tiempo es aproximadamente de 0,5 seg.
Teniendo en cuenta estos tiempos y sabiendo que el dispositivo Wiimote tiene la capacidad
de tomar hasta 100 muestras por segundo nuestro muestreo de los golpes va a estar limitado a
unos 50 valores por cada uno de los sensores. Si bien esta cantidad parece ser suficiente creemos
que para poder lograr una mayor precisión en los resultados es necesario que esta cantidad de
muestras sea mayor.
Una mayor cantidad de muestras ayuda a ver los cambios de estos sensores a lo largo del
tiempo con mayor precisión, se puede ver cuando se incrementan o decrementan los valores de
manera abrupta, se puede ver cuando el cambio se produce de manera lineal o también cuando se
mantienen estables.
Por lo tanto, tener más información acerca del gesto capturado posibilita realizar un mejor
análisis y también compararlo contra otros gestos simulares o totalmente diferentes.

A.1.1 Saturación de sensores

Frente a diversas situaciones ocurridas en fase de desarrollo comenzamos a observar que


algunos de los sensores, principalmente los sensores giróscopos, se saturaban con facilidad.
El problema se basa en que cuando se gira de una manera abrupta el dispositivo los sensores
giróscopos proveen de valores nulos. Como no existe una forma de evitar que el sensor arroje
esos valores nulos se tomó la decisión de frente a esta situación, en vez de tomar el valor nulo
tomemos el último valor válido.

Figura A.1: Imagen mostrando saturación en uno de los sensores giróscopos

En la Figura A.1 se puede ver cómo en la parte inferior hay interrupciones en la captura de
los datos, esto es porque esos valores durante ese lapso de tiempo se encuentran fuera del rango

98
A.2. BIBLIOTECA WIIYOURSELF

aceptable por el sensor. Claramente en el resto de la imagen no observamos una discontinuidad a


lo largo del tiempo. Si bien le llamamos discontinuidad, es porque los valores no son reflejo de la
realidad.
Para evitar estos saltos de continuidad se tomó la decisión de elegir el máximo valor aceptable
por el rango, o el mínimo según la situación. Por ejemplo, si estamos reconociendo los datos que
arroja un giróscopo donde su rango aceptable es [-2000, 2000] y de pronto ocurrió una saturación,
considerando que el anterior valor fue de 1988, se le asignará el valor 2000 hasta que el sensor
obtenga un valor que se corresponda dentro del rango aceptable.
El mismo concepto se aplica cuando los valores sensados correspondan al rango negativo,
cuando ocurre la saturación se le asigna el valor -2000 hasta que obtenga uno dentro del rango
aceptable.

A.2 Biblioteca Wiiyourself

Cabe destacar que se utilizó una librería del dispositivo Wiimote que se encuentra disponible
en [19]. Si bien nos ayudó en un comienzo a poder interactuar con el dispositivo, fuimos detectando
ciertas falencias, como por ejemplo que los controles no estaban orientados a eventos.
Si bien el paradigma orientado a eventos añade cierta dificultad con respecto a otros para-
digmas de programación, consideramos que es necesario que el sistema actúe de esa manera.
Teniendo en cuenta lo anterior se decidió realizar dicha implementación.

A.3 Algoritmo DTW

El algoritmo Dynamic Time Warping (DTW) es un algoritmo famoso y reconocido en muchas


áreas. Primeramente, introducido en los ’60 y explorado extensivamente en los ’70 por aplicaciones
de reconocimiento de voz, es actualmente utilizado en diversas áreas como [36]:

• Reconocimiento en escrituras y firmas.

• Reconocimiento de lenguaje por señas y reconocimiento de gestos.

• Data mining y clustering de secuencias de tiempos (búsqueda en BD de secuencias de


tiempo).

• Visión artificial y animación por computadora.

• Vigilancia o monitoreo por sistema.

• Alineamiento de secuencias de proteínas e ingeniería química.

• Música y procesamiento de señales.

99
APÉNDICE A. APÉNDICE

El algoritmo DTW ha ganado su popularidad por ser extremadamente eficiente como medida
de similitud entre series de tiempo similares. Éste minimiza los efectos de cambio y distorsión
en el tiempo, permitiendo transformaciones elásticas de las series con el fin de detectar "forma"
similares con distintas fases.
Dada dos series de tiempo X = (X 1 , X 2 ...X n ), N ∈ N y Y = (Y1 , Y2 ...Ym ), M ∈ N representada por
las secuencias de valores, DTW produce una solución óptima de orden O(MN) la cual puede ser
aún mejorada a través de diferentes técnicas como por ejemplo multi-scaling. La única restricción
situada en las secuencias de datos es que deben estar muestreadas a puntos equidistantes en el
tiempo [36].
El algoritmo DTW se basa en un algoritmo de programación dinámica, donde es común
utilizar una función de distancia llamada función de costo:

c i, j = distance(X i , Y j )

La función calcula la distancia entre un punto de la serie X contra un punto de la serie Y .


La tarea de optimizar la alineación de las secuencias se convierte en la tarea de organizar todos
los puntos de la secuencia minimizando la función de costo (o distancia). En otras palabras, el
algoritmo de programación dinámica DTW realiza la búsqueda del camino óptimo a través de
una matriz de distancia de tamaño nxm. Se definen dos condiciones para obtener el camino:

• Los puntos finales de las dos series corresponden a una y a otra. Es decir, el camino
comienza siempre en (1, 1) y finaliza siempre en la coordenada que se encuentra en el
extremo inferior derecho (n, m) de la matriz.

• El tiempo avanza hacia adelante. Esta condición puede ser satisfecha permitiendo solamen-
te tres tipos de movimiento: abajo, derecha y abajo-y-derecha. Por tanto, siempre se debe
desplazar en una dirección que haga que i y j crezcan, o al menos uno de ellos. Dicho de
otro modo, dado un elemento cualquiera del camino (i, j), el elemento siguiente debe ser (i,
j+1), (i+1, j) o (i+1, j+1).

Para obtener el camino de menor coste, se calcula la matriz de costes totales D, en la que cada
elemento representa el coste del camino de menor coste que llega hasta él. La ventaja de esta
matriz es que cada elemento puede escribirse como el coste local de ese punto, más el menor de
los costes acumulados de los elementos anteriores. Teniendo en cuenta esto y la condición de que
el camino siempre debe avanzar hacia delante, el valor de cada elemento de D se obtiene de la
siguiente manera:

(A.1) d i, j = c i, j + min(d i−1, j , d i, j−1 , d i−1, j−1 )

La ecuación A.1 cuenta con algunas excepciones:

• El primer punto d 1,1 queda igual a c 1,1 , ya que no existe ningún punto anterior cuyo coste
sumarle.

100
A.3. ALGORITMO DTW

• En la primera columna de puntos, el camino sólo puede desplazarse en vertical, ya que no


hay puntos anteriores en horizontal y el camino sólo avanza hacia delante. La expresión de
cualquier punto de esta columna puede expresarse simplemente como la suma de todos los
elementos desde ese punto hasta el origen, ambos incluidos.

j
X
d 1, j = c 1,k
k=1

• De forma análoga al caso anterior, la primera fila presenta un caso similar: el camino sólo
puede desplazarse horizontalmente, por tanto la expresión de sus puntos queda:

i
X
d i,1 = c k,1
k=1

1 double ExecuteDTW ( vector <double > * vectorX , vector <double > * vectorY ) {
2 i n t m = vectorX −>s i z e ( ) ;
3 i n t n = vectorY −>s i z e ( ) ;
4

5 / / Creacion de matriz de c o s t o t o t a l e s
6 vector <vector <double >> c o s t (m, vector <double >(n , 0 . 0 ) ) ;
7 c o s t [ 0 ] [ 0 ] = s q r t ( pow ( ( vectorX −>at ( 0 ) − vectorY −>at ( 0 ) ) , 2 ) ) ;
8

9 / / Calcular c o s t o s de l a primera columna


10 f o r ( i n t i = 1 ; i < m; i ++) {
11 c o s t [ i ] [ 0 ] = c o s t [ i − 1 ] [ 0 ] + s q r t ( pow ( ( vectorX −>at ( i ) − vectorY −>at ( 0 ) ) , 2 ) ) ;
12 }
13

14 / / Calcular c o s t o s de l a primera f i l a
15 f o r ( i n t j = 1 ; j < n ; j ++)
16 {
17 c o s t [ 0 ] [ j ] = c o s t [ 0 ] [ j − 1] + s q r t ( pow ( ( vectorX −>at ( 0 ) − vectorY −>at ( j ) ) , 2 ) ) ;
18 }
19

20 / / Calcular c o s t o de todos l o s elementos de l a matriz


21 f o r ( i n t i = 1 ; i < m; i ++) {
22 f o r ( i n t j = 1 ; j < n ; j ++) {
23 c o s t [ i ] [ j ] = min ( c o s t [ i − 1][ j ] , min ( c o s t [ i ] [ j − 1] , c o s t [ i − 1][ j − 1]) ) + s q r t ( pow ( (
vectorX −>at ( i ) − vectorY −>at ( j ) ) , 2 ) ) ;
24 }
25 }
26

27 / / Retorna e l c o s t o t o t a l
28 return c o s t [m− 1][n − 1 ] ;
29 }

Algoritmo A.1: Algoritmo DTW

101
APÉNDICE A. APÉNDICE

Una vez completa la matriz D, en su último elemento D[n, m] se obtiene el coste total de
igualar ambas series (Algoritmo A.1). Evaluando este coste, se podrá determinar si las series son
lo suficientemente parecidas.

102
B IBLIOGRAFÍA

[1] C. Ghaoui, Encyclopedia of Human Computer Interaction.


ITPro collection, Idea Group Reference, 2005.

[2] “Nintendo Wii Remote.” https://en.wikipedia.org/wiki/Wii_Remote.

[3] Wikipedia, “Playstation move.” "https://en.wikipedia.org/wiki/PlayStation_Move".

[4] S. S. D. Zulkarnain, “Studying the wiimote ‚Äì exploration to enhance the feeling of interac-
tivity in applications,” 2009.
http://www.few.vu.nl/~eliens/archive/tutorial/wiimote.pdf.

[5] Wikipedia, “Sensor kinect.” "https://en.wikipedia.org/wiki/Kinect".

[6] E. Ruffaldi, A. Filippeschi, C. A. Avizzano, B. G. Bardy, D. Gopher, and M. Bergamasco,


“Feedback, affordances, and accelerators for training sports in virtual environments.,”
Presence, vol. 20, no. 1, pp. 33–46, 2011.

[7] C. G. Bauza, J. D’Amato, A. Gariglio, M. J. Abásolo, M. Vénere, C. Manresa-Yee, and R. Mas-


Sansó, “A tennis training application using 3d gesture recognition,” in Proceedings of the
7th International Conference on Articulated Motion and Deformable Objects, AMDO’12,
(Berlin, Heidelberg), pp. 239–249, Springer-Verlag, 2012.

[8] L. J. P. J. P. P. H. J. Leong, T., “Wii want to write: An accelerometer based gesture recognition
system,” Carnegie Mellon University, pp. pp. 4–7., 2009.
International Conference on Recent and Emerging Advanced Technologies in Engineering,.

[9] H. Y. L. Y. C. L. Liu X., Sun J., “Overview of virtual reality apply to sports,” JCIT: Journal of
Convergence Information Technology 6(12), pp. 1–7, 2011.

[10] B. Bideau, R. Kulpa, N. Vignais, S. Brault, F. Multon, and C. Craig, “Using virtual reality to
analyze sports performance,” IEEE Comput. Graph. Appl., vol. 30, pp. 14–21, Mar. 2010.

[11] P. Dierckx, Curve and Surface Fitting with Splines.


New York, NY, USA: Oxford University Press, Inc., 1993.

103
BIBLIOGRAFÍA

[12] V. D. Moya F., González C., Desarrollo de Videojuegos: Técnicas Avanzadas.


2012.

[13] L. E. Potter, J. Araullo, and L. Carter, “The leap motion controller: A view on sign language,”
in Proceedings of the 25th Australian Computer-Human Interaction Conference: Aug-
mentation, Application, Innovation, Collaboration, OzCHI ’13, (New York, NY, USA),
pp. 175–178, ACM, 2013.

[14] Z. Zhang, “Microsoft kinect sensor and its effect,” IEEE MultiMedia, vol. 19, pp. 4–10, Apr.
2012.

[15] C. Cruz-Neira, D. J. Sandin, T. A. DeFanti, R. V. Kenyon, and J. C. Hart, “The cave: Audio
visual experience automatic virtual environment,” Commun. ACM, vol. 35, pp. 64–72,
June 1992.

[16] J. Kim, C. Chung, S. Nakamura, S. Palmisano, and S. K. Khuu, “The oculus rift: A cost-
effective tool for studying visual-vestibular interactions in self-motion perception,” Fron-
tiers in Psychology, vol. 6, no. 248, 2015.

[17] J. C. Lee, “Hacking the nintendo wii remote,” IEEE Pervasive Computing, vol. 7, pp. 39–45,
July 2008.

[18] T. Schlömer, B. Poppinga, N. Henze, and S. Boll, “Gesture recognition with a wii controller,” in
Proceedings of the 2Nd International Conference on Tangible and Embedded Interaction,
TEI ’08, (New York, NY, USA), pp. 11–14, ACM, 2008.

[19] gl.tter, “Wiiyourself, native c++ wiimote library.” "http://wiiyourself.gl.tter.org/".

[20] “Open source 3d engine.” "http://www.ogre3d.org".

[21] “Bullet, real-time physics simulation.” "http://bulletphysics.org".

[22] E. Gamma, R. Helm, R. Johnson, and J. Vlissides, Design Patterns: Elements of Reusable
Object-oriented Software.
Boston, MA, USA: Addison-Wesley Longman Publishing Co., Inc., 1995.

[23] P. B. Galvin, G. Gagne, and A. Silberschatz, Operating System Concepts.


New York, NY, USA: John Wiley & Sons, Inc., 9th ed., 2013.

[24] A. Roche, Árboles de decisión y series de tiempo. Tesis de Maestría Ingenería Matemática.
Facultad de Ingeniería, UDELAR. Uruguay, 2009.

[25] “ITF Dimensions (ITF CS 04/02).” http://www.itftennis.com/technical/courts/


court-testing/dimensions.aspx.

104
BIBLIOGRAFÍA

[26] L. M. Lazo Marcos., Incorporación de comportamiento físico en motor gráficos. Tesis de grado.
Universidad Nacional del Centro de la Pcia de Buenos Aires, Tandil, Argentina, 2009.

[27] “Motion states.” "http://www.bulletphysics.org/mediawiki-1.5.8/index.php/


MotionStates".

[28] L. Bass, P. Clements, and R. Kazman, Software Architecture in Practice.


Addison-Wesley Professional, 3rd ed., 2012.

[29] “Vector director.” "https://es.wikipedia.org/wiki/Vector_director".

[30] “Ogre::ribbontrail-class.” "http://www.ogre3d.org/docs/api/1.9/class_ogre_1_1_


ribbon_trail.html".

[31] “Hawk-eye in tennis.” "http://www.hawkeyeinnovations.co.uk/sports/tennis".

[32] “Regla de challenge en tenis.” "https://en.wikipedia.org/wiki/Hawk-Eye#Tennis".

[33] “Kit de desarrollo de software para oculus rift.” "https://developer.oculus.com/


downloads/pc/0.4.4-beta/Oculus_SDK_for_Windows/".

[34] “Oculus rift rendering in ogre 3d.” "https://github.com/Germanunkol/


OgreOculusSample/blob/master/Readme.md".

[35] “Adxl330, small, low power, 3-axis 3g imems accelerometer.” http://www.analog.com/en/


products/mems/mems-accelerometers/adxl330.html.

[36] P. Senin, “Dynamic Time Warping Algorithm Review,” Tech. Rep. CSDL-08-04, Department
of Information and Computer Sciences, University of Hawaii, Honolulu, Hawaii 96822,
Dec. 2008.

105

También podría gustarte