wiimote hack - rovira i virgili universitydeeea.urv.cat/public/propostes/pub/pdf/1231pub.pdf ·...

159
Wiimote Hack TITULACIÓN: Ingeniería Técnica Industrial en Electrónica Industrial AUTOR: Ricardo Bonache Samaniego DIRECTOR: José Luís Ramírez Falo FECHA: Junio de 2009

Upload: others

Post on 09-May-2020

4 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

Wiimote Hack

TITULACIÓN: Ingeniería Técnica Industrial en Electrónica Industrial

AUTOR: Ricardo Bonache Samaniego DIRECTOR: José Luís Ramírez Falo

FECHA: Junio de 2009

Page 2: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

2

Índice

1 Introducción ....................................................................................................... 5

2 Objetivo .............................................................................................................. 8

3 Especificaciones previas .................................................................................... 8

4 Antecedentes ...................................................................................................... 9

4.1 Tipos de pizarra interactiva .......................................................................... 9

4.1.1 Pizarra digital interactiva de gran formato ............................................. 9

4.1.2 Pizarra digital interactiva portátil ........................................................... 9

4.2 Diferentes tecnologías utilizadas para el posicionamiento del puntero ....... 9

4.2.1 Electromagnética ..................................................................................... 9

4.2.2 Infrarroja ................................................................................................ 10

4.2.3 Ultrasónica - infrarrojo ......................................................................... 10

4.2.4 Resistiva ................................................................................................. 10

4.3 Elementos que forman una pantalla interactiva ......................................... 10

4.3.1 Ordenador .............................................................................................. 10

4.3.2 Proyector ................................................................................................ 10

4.3.3 Hardware de posicionamiento del puntero sobre la superficie de

proyección……………………………………………………………...11

4.3.4 Puntero ................................................................................................... 11

4.3.5 Software de interconexión entre el hardware externo y el ordenador ... 11

4.4 Características de una pizarra interactiva .................................................. 11

4.4.1 Resolución .............................................................................................. 11

4.4.2 Superficie o área activa ......................................................................... 11

4.4.3 Conexiones ............................................................................................. 12

4.4.4 Punteros ................................................................................................. 12

4.4.5 Software .................................................................................................. 12

4.4.6 Portabilidad ........................................................................................... 12

4.5 Beneficios para los docentes ...................................................................... 13

4.6 Beneficios para los alumnos ...................................................................... 14

5 Análisis previo ................................................................................................. 15

6 Funcionamiento del Wiimote ......................................................................... 16

6.1 Hardware .................................................................................................... 18

6.1.1 Acelerómetro .......................................................................................... 18

6.1.2 Emisor/receptor Bluetooth ..................................................................... 18

Page 3: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

3

6.1.3  Sensor de emisiones infrarrojas............................................................. 19 

6.2  Control de la cámara por software ............................................................. 21 

6.2.1  Puesta en marcha de la cámara ............................................................. 21 

6.2.2  Ajuste de sensibilidad............................................................................. 21 

6.2.3  Formato de los datos.............................................................................. 22 

6.3  Conexión del mando al ordenador ............................................................. 24 

7  Montaje del puntero IR .................................................................................. 25 

8  Desarrollo del software ................................................................................... 30 

8.1  Conexión con el mando. ............................................................................ 30 

8.2  Calibración................................................................................................. 31 

8.3  Selección del punto al que enviar el cursor ............................................... 34 

8.4  Selección de la función que realiza el cursor según el estado del puntero IR ……………………………………………………………………………38 

8.4.1  Actualización de las variables “vis1” y “vis2” ..................................... 44 

8.5  Funciones adicionales ................................................................................ 45 

8.6  Rutina de Servicio a la Interrupción .......................................................... 47 

9  Resultados finales ............................................................................................ 49 

10  Conclusiones .................................................................................................... 51 

11  Manual de instalación y uso ........................................................................... 53 

11.1  Instalación de WiimoteBoard (utilidad adjunta en el CD)......................... 53 

11.2  Instalación de Classroom Presenter 3 ........................................................ 57 

11.3  Instalación de Click-N-Type...................................................................... 62 

11.4  Manual de uso de Wiimote Board ............................................................. 68 

11.4.1  Conexión por primera vez de los Wiimotes al PC ................................. 68 

11.4.2  Conexión de los Wiimotes al PC ............................................................ 68 

11.4.3  Apertura del programa .......................................................................... 70 

11.4.4  Funcionamiento del programa............................................................... 70 

11.5  Información para colocar correctamente los mandos ................................ 81 

11.6  Consideraciones a tener en cuenta según el tipo de instalación................. 82 

11.6.1  Instalación fija ....................................................................................... 82 

11.6.2  Instalación móvil .................................................................................... 83 

12  Presupuesto ...................................................................................................... 84 

13  Bibliografía y referencias ............................................................................... 85 

13.1  Referencias................................................................................................. 85 

13.2  Bibliografía ................................................................................................ 85 

Page 4: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

4

14  Anexo ................................................................................................................ 86 

14.1  Estudios...................................................................................................... 86 

14.1.1  Estudio del porcentaje de visión de la cámara del Wiimote según la posición en la que se encuentre el mando. ............................................ 86 

14.1.2  Estudio del porcentaje de visión de la cámara del Wiimote según la posición en la que se encuentre el mando, con un obstáculo delante. .. 93 

14.1.3  Estudio de la mejora de visión con dos Wiimotes respecto a un solo Wiimote, con obstáculo estándar. ......................................................... 97 

14.1.4  Estudio de la mejora de visión con dos Wiimotes respecto a un solo Wiimote, con obstáculo en la posición más problemática. ................. 101 

14.2  Código desarrollado durante el proceso de creación del programa ......... 108 

14.3  Código fuente del programa final (información adjunta en el CD) ......... 122 

14.3.1  Archivo Program.cs ............................................................................. 122 

14.3.2  Archivo MultipleWiimoteForm.cs ........................................................ 123 

14.3.3  Archivo CalibrationForm.cs ................................................................ 148 

14.3.4  Archivo WiimoteInfo.cs ........................................................................ 150 

14.3.5  Archivo Warper1.cs y Warper2.cs ....................................................... 152 

14.3.6  Archivo MouseControl.cs..................................................................... 157 

14.3.7  Archivo AboutBox1.cs .......................................................................... 158 

14.4  Agradecimientos ...................................................................................... 159 

Page 5: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

5

1 Introducción

Mediante la realización de este proyecto se pretende obtener una aplicación que permita convertir una imagen proyectada de cualquier ordenador en una pizarra digital interactiva. Para poder hacerlo, se utilizan unos sensores que indicaran al ordenador la posición de un puntero infrarrojo.

El usuario podrá mover ese puntero por encima de la proyección y el cursor del ratón deberá trasladarse hasta la posición en la que este el puntero.

Actualmente se comercializan muchos dispositivos que permiten realizar esta tarea. El inconveniente que ofrecen es su elevado precio. El más barato que se pueda encontrar en el mercado supera ampliamente la barrera de los 800 €. Por ejemplo, en la solución portátil comercializada por la empresa Mimio, el sensor cuesta 600 € aproximadamente, y

el puntero 450 €. En total costaría 1050 € el conjunto. Si se comprueba una solución fija, la cual no se puede trasladar ni ampliar de tamaño, este coste es mayor. Hitachi comercializa una pizarra interactiva fija por 1800 €, con un tamaño de 77 pulgadas. El beneficio que

presenta es que no necesita uso de un puntero, sino que se puede utilizar directamente con el dedo ya que todo el perímetro de la pizarra funciona como sensor. En estos precios no se incluye el proyector, pieza necesaria para poder crear una pizarra digital interactiva. Hitachi también ha desarrollado un proyector específico para pizarras digitales interactivas, el cual evita la aparición de sombras ya que es de corta distancia. Su coste es de 1300 €. En

total, la compra de la pizarra digital fija con el proyector tiene un precio de 3100 €, una

cantidad imposible de conseguir para un colegio público con pocos recursos. En este proyecto se intenta realizar un sistema que presente un funcionamiento similar al de los dispositivos que se venden actualmente, pero a un precio mucho más reducido. Por tanto, el espíritu de este proyecto es la realización de los elementos necesarios para montar una pizarra digital interactiva de bajo coste, por debajo de 200 €, sin incluir el coste del

proyector. Este proyecto se diseña para aprovechar los proyectores existentes en las aulas o salas de proyecciones. El beneficio de este proyecto es que permite la conversión en pizarra digital de cualquier tipo de proyección, sea cual sea el tamaño de esta. Por eso, se piensa como un método de aprovechamiento de los proyectores ya existentes en los diversos centros de enseñanza o salas de proyección.

Este sistema ya se ha intentado desarrollar en diversas universidades estadounidenses. Estas universidades partían de la utilización de un mando de la videoconsola Nintento Wii, llamado comercialmente Wiimote, para posicionar un puntero infrarrojo. Este mando dispone de un chip que envía ya las coordenadas del punto infrarrojo, con lo que representa la manera más sencilla de obtener un sensor del puntero barato y resistente. Además, esta característica reduce significativamente las horas de desarrollo de la aplicación, ya que disponiendo de la posición del puntero como dato, solo hay que tratarlo correctamente para saber a dónde enviar el cursor del ratón. Otra de las ventajas que ofrece este mando es que se conecta por Bluetooth, ofreciendo una gran capacidad de conexión con cualquier ordenador. En caso de que el ordenador no disponga de un dispositivo de comunicación Bluetooth incorporado, se puede adquirir un stack Bluetooth USB que dota a cualquier ordenador con conexión USB del protocolo de comunicaciones Bluetooth, con lo que se asegura que el sistema sea compatible con un gran número de ordenadores.

El pionero en el uso del Wiimote como sensor para crear una pizarra digital interactiva fue Johnny Chung Lee. Él actualmente es desarrollador de nuevas aplicaciones en el departamento de Ciencias Aplicadas de Microsoft. Se graduó en Interacción entre

Page 6: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

6

Computadores y Humanos en la Universidad de Carnegie Mellon, USA. Durante su estancia en el departamento de Interacción entre Computadores y Humanos de la Universidad Carnegie Mellon desarrolló la aplicación “Wiimote Whiteboard” en Junio de 2008. Mediante el uso de esta aplicación y un solo mando de la videoconsola Nintendo Wii, conseguía convertir cualquier imagen de ordenador en una superficie táctil. Únicamente se necesitaba el uso de uno led infrarrojo para indicar el movimiento que se deseaba realizar. Esta aplicación presentaba una interfaz de usuario simple, pero conseguía mover el cursor del ratón allá donde el usuario indicara con su puntero infrarrojo. Solamente se tenía que calibrar la imagen donde se quería usar el puntero y que el mando viera este puntero.

A partir del desarrollo de “Wiimote Whiteboard”, Johnny Chung Lee desarrollo

nuevas aplicaciones que explotaban las posibilidades del Wiimote. Entre estas se encuentran “Wiimote Multipoint Grid”, la cual permite mover una imagen que aparezca en un ordenador con las manos. Para poder hacerlo se necesita introducir un emisor infrarrojos encima de la pantalla a utilizar y cinta reflectante en los dedos. El movimiento de la mano hacia la derecha o la izquierda desplaza la imagen hacia el mismo lado al que se mueva la mano. Otra aplicación desarrolladla para su uso con Wiimote es “WiiDesktopVR”. Esta aplicación permite reproducir el movimiento del cuerpo en el

ordenador y es muy útil cuando se juega a juegos de acción. Por ejemplo, si el usuario que está jugando delante de la pantalla se agacha, en el juego el personaje también se agacha. Para conseguirlo, el usuario debe llevar una banda con emisores infrarrojos situada en la cabeza, y el mando debe de estar colocando encima de la pantalla. De esta manera, si el usuario mira para la derecha la imagen del juego se mueve hacia la derecha. El juego realiza todos los movimientos que realice la cabeza del usuario.

Para que Johnny pudiera realizar toda esta tarea, necesitaba la ayuda de una librería que leyera la información enviada por el Wiimote y la almacenara. Esta librería también debe dividir la información en paquetes manejables para el programador. Toda esta tarea la realizó Brian Peek, que es desarrollador Senior en ASPSOFT, Inc y Microsoft C# MVP. Este estadounidense desarrollo la primera librería que permitía el uso de las funciones que ofrecía el Wiimote. Mayoritariamente están son 2: información del ángulo del mando o movimiento de este mediante el uso del acelerómetro que incorpora y información de la posición de un puntero infrarrojo mediante el chip de tratamiento de imagen que lleva incorporado el mando. Brian Peek consiguió leer la información del mando correctamente y almacenarla, para su posterior tratamiento. Además su librería también implementa la conexión y desconexión correcta del mando, para conseguir que comience a enviar datos y poderlos tratar correctamente. Actualmente esta librería va por la versión 1.7, y es actualizada aproximadamente cada 3 meses por una versión que mejora las deficiencias detectadas en la anterior.

Desde la aparición de la librería “Wiimotelib” y de la aplicación “WiimoteBoard”, se

ha creado un gran movimiento de desarrollo de estas aplicaciones en internet. Existe una gran cantidad de foros o wikis en las que se explica que funciones realiza el programa original o que mejoras se pueden incorporar. Se han creado una gran cantidad de aplicaciones relacionadas con estos proyectos, de las cuales querría destacar “WiimoteConnect”. Esta aplicación permite establecer automáticamente la conexión Bluetooth con los mandos, y ahorra la tarea al usuario, el cual tiene que realizar la conexión mediante el uso del panel de control de su dispositivo Bluetooth, cada vez que quiere utilizar los mandos. “WiimoteConnect” busca si hay mandos cercanos dispone y

Page 7: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

7

establece la conexión Bluetooth. El único inconveniente que presenta es que únicamente funciona con el driver de Microsoft.

Una gran cantidad de usuarios norteamericanos ha desarrollado su propia aplicación para convertir una proyección en pizarra digital interactiva. Las más importantes son “Wiimote Whiteboard 0.9.7 Uls”, creada por Uwe Schmidt, y “Wiimote Smoothboard”

llevada a cabo por Goh Boon Jin. Esta ultima aplicación destaca por ser la primera en poder utilizarse con dos mandos en vez de con solo uno, pero tiene el inconveniente de que los mandos se deben calibrar por separado. Esta técnica incrementa los errores, ya que el usuario nunca pulsara en el mismo lugar para ambas calibraciones. El mínimo desvío de su mando al pulsar los puntos de calibración creara una diferencia de posicionamiento entre ambos mandos. Actualmente esta aplicación se puede descargar de manera gratuita, pero aparece un cartel de registro que impide el uso inmediato de la misma. Todas las funciones se mantienen operativas, pero se insta al usuario a registrarla pagando 25 €. Por tanto, este

programa ya se distribuye con fines comerciales o lucrativos, lo que lleva a que su creador esté desarrollando un gran número de funciones complementarias. Por su parte, “Wiimote

Whiteboard 0.9.7 Uls” destaca por ofrecer una solución apta para cualquier distribución Linux y Mac OS X. Actualmente estas aplicaciones se encuentran aún en fase de desarrollo intensa, y las versiones publicadas en internet son las primeras realizadas por sus creadores. Como he indicado antes, este tipo de aplicaciones se empezaron a crear a partir del otoño de 2008, gracias a la aparición de la primera versión de “Wiimote Whiteboard”

de Johnny Chung Lee, el iniciador de este tipo de solución que permite la interactividad con el ordenador a un muy bajo coste.

Con el desarrollo de este proyecto se pretende crear una aplicación propia que realice lo que otros no han conseguido: conseguir utilizar dos mandos diferentes calibrándolos al mismo tiempo. Si se utilizan dos mandos, se evita que se deje de ver el puntero a causa de que el usuario que escribe sobre la proyección tape un mando. Siempre se dispone de otro mando suplementario que verá el puntero infrarrojo. De esta manera se asegura que la pizarra funcionara en todo momento, independientemente de la posición que adopte el usuario respecto a los mandos. Así el usuario no se tiene que preocupar, y se asegura el funcionamiento de la pizarra digital en cualquier situación de uso habitual. Al calibrar los dos mandos al mismo tiempo se evita los errores provocados a causa de que el usuario nunca clicará en el mismo punto exacto. Al calibrarse al mismo tiempo, las coordenadas de ese punto serán las mismas para los dos mandos. Esto posibilitará que la diferencia de coordenadas que puede enviar un mando u otro para la misma posición del puntero sea muy pequeña. Evita incrementar el error a causa de no calibrar clicando en el mismo punto exacto que el mando anterior, ya que por poco que se mueva el usuario, esa diferencia de posición se trasladará al envío de coordenadas del mando, lo que provocará que el cursor no vaya a la posición a la que esté el puntero, sino que se desvíe un poco.

Para poder realizar toda esta tarea, se parte de la última versión de “Wiimotelib”, que

es la 1.7. Esta versión posibilita la conexión, captación y almacenamiento de datos de dos mandos diferentes. Gracias a esta librería, el desarrollo del programa se basará en tratar adecuadamente los datos enviados por ambos mandos para obtener como resultado la posición de la pantalla a la que hay que enviar el cursor del ratón, en función del lugar donde se ponga el puntero infrarrojo en la proyección de la pantalla del ordenador.

Page 8: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

8

2 Objetivo

El objetivo principal de este proyecto es la realización de una Pizarra Digital Interactiva1 utilizando elementos de bajo coste. Actualmente, los diferentes tipos de PDI existentes en el mercado tienen un precio muy elevado y lo que se pretende con este proyecto es realizar una PDI utilizando elementos de bajo coste para que el producto final no supere los 150 €, posibilitando su instalación en multitud de instituciones que dispongan

de presupuestos reducidos.

Para posibilitar este bajo coste utilizaremos como hardware externo el mando de la videoconosola Nintendo Wii, conocido comercialmente con el nombre de Wiimote y un puntero infrarrojo para indicar la posición en pantalla. Este proyecto se centrará mayoritariamente en el desarrollo del software necesario para interpretar la posición del puntero infrarrojo sobre la proyección y trasladar el cursor del ratón hasta esa posición para poder realizar la tarea que el usuario desee.

3 Especificaciones previas

Para la realización de este proyecto se marcan las siguientes especificaciones previas:

El software debe desarrollarse en lenguaje de programación C#.

La interfaz de usuario debe de ser intuitiva y de fácil asimilación.

Se deben utilizar librerías públicas de código abierto.

En caso de que sea necesario aportar un software externo que cumplimente las funciones de la PDI, este debe ser de código abierto y libre distribución (“freeware”).

Las especificaciones anteriores se basan en la idea expresada anteriormente de aplicación de bajo coste. Ese motivo es el que nos lleva a utilizar siempre aplicaciones gratuitas disponibles en internet para su uso. La aplicación se desarrolla en C# debido a que es un lenguaje compatible con una gran cantidad de ordenadores, gracias al uso de la plataforma .Net ofrecida por Microsoft. Esto posibilitará que nuestra aplicación sea compatible con cualquier versión del sistema operativo Windows, siempre que este tenga instalado el paquete .Net Framework, que es de descarga gratuita a través de la pagina web de Microsoft.

1 La PDI consiste en un ordenador conectado a un video-proyector, que proyecta la imagen de la

pantalla sobre una superficie, desde la que se puede controlar el ordenador mediante un lápiz electrónico, para hacer anotaciones manuscritas sobre cualquier imagen proyectada, así como guardarlas, imprimirlas, enviarlas por correo electrónico y exportarlas a diversos formatos. Definición extraída de Wikipedia [1].

Page 9: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

9

4 Antecedentes

4.1 Tipos de pizarra interactiva

4.1.1 Pizarra digital interactiva de gran formato

Este tipo de pizarras se caracterizas porque la superficie de escritura es específica, y solo se puede utilizar la pizarra digital dentro de esa superficie, que viene impuesta por el fabricante que comercializa el producto. Esto se debe a que se utiliza como tecnología de posicionamiento del puntero de escritura la inducción electromagnética. Por este motivo toda la superficie de escritura debe de ser sensible a los cambios del campo electromagnético que aparecen sobre esta. Esta tecnología permite un posicionamiento óptimo, pero imposibilita su uso en otro lugar que no sea en el que se encuentra instalado, además de encarecer enormemente su precio ya que se tiene de adquirir toda la pizarra y el puntero especifico para esta.

4.1.2 Pizarra digital interactiva portátil

En este caso, podemos convertir cualquier superficie donde realicemos la proyección en pizarra interactiva, ya que no es necesario que la pizarra lleve sensores. Para permitir esta posibilidad, necesitamos incluir algún tipo de hardware que nos permita posicionar el puntero sobre la superficie de proyección. Este hardware puede utilizar diversas tecnologías para posicionar el puntero como puede ser lectura de infrarrojos o por emisión y recepción de ultrasonidos. Como ventajas ofrecen la posibilidad de poder instalarse en cualquier lugar. Como inconvenientes ofrecen un posicionamiento menos preciso que las comentadas anteriormente, ya que los diferentes sensores utilizados siempre tienen una desviación causada por múltiples factores externos que pueden impedir un correcto posicionamiento. También hay que tener en cuenta que, cada vez que instalamos el sistema en un lugar diferente, se ha de calibrar la zona proyectada para conocer el tamaño de esta, mientras que en las pizarras de gran formato no es necesario ya que la pizarra no cambia nunca de tamaño.

4.2 Diferentes tecnologías utilizadas para el posicionamiento del puntero

4.2.1 Electromagnética

Se utiliza un lápiz emisor de señales electromagnéticas como puntero, combinado con una malla sensora contenida en toda la superficie de proyección. Dicha malla detecta la señal del lápiz en toda la superficie de sensado con muy alta precisión (una pizarra electromagnética tiene en 2.5 cm2 la misma resolución que una táctil de 77 pulgadas de tamaño puede tener en toda la superficie) y envía la posición del puntero cuando este toca cualquier punto de la superficie de sensado. Esta tecnología es la utilizada por las empresas Numonics e Interwrite[1].

Page 10: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

10

4.2.2 Infrarroja

En este caso, el puntero está dotado de un diodo emisor de luz infrarroja en la parte superior. El sensor detecta la luz infrarroja emitida y posiciona el punto infrarrojo sobre un eje de coordenadas cartesianas. Esto es posible gracias a la calibración realizada antes de usar la pizarra. Para que esto sea posible el sensor tiene que estar ubicado a cierta distancia. Esta tecnología no requiere pegar sensores especiales, ni soportes o superficies sensibles. Tampoco limita el área de proyección pudiendo ser incluso de varios metros cuadrados. Tecnología usada por LiveTouch[1].

4.2.3 Ultrasónica - infrarrojo

Cuando el marcador entra en contacto con la superficie de la pizarra, este envía simultáneamente una señal ultrasónica y otra de tipo infrarrojo para el sincronismo. Dos receptores que se colocan en dos lados de la superficie de proyección reciben las señales y calculan la posición del puntero, para proyectar en ese punto lo que envía el puntero. Esta tecnología permite que las pizarras sean de cualquier material (siempre y cuando sea blanca y lisa para una correcta proyección). Tecnología utilizada por eBeam [1].

4.2.4 Resistiva

En este caso, el panel de la pizarra es el elemento que facilita la posición del puntero y está formado por dos capas separadas, la exterior de las cuales es deformable al tacto. La presión aplicada facilita el contacto entre las láminas exterior e interior, provocando una variación de la resistencia eléctrica que nos permite localizar el punto señalado. Se puede utilizar cualquier tipo de puntero con esta tecnología, ya que el sensor es la superficie donde escribimos. Por este motivo, esta tecnología se utiliza en pizarras fijas. Tecnología utilizada por Polyvision y Smart Board [1].

4.3 Elementos que forman una pantalla interactiva

4.3.1 Ordenador

Este puede ser portátil o de sobremesa. Debe disponer de conexión a pantalla externa para poder reproducir las imágenes en un proyector. Además, es necesario que el sistema operativo que utilice sea compatible con el software de la pizarra interactiva.

4.3.2 Proyector

Se utiliza con objetivo de poder ver la imagen de la pantalla del ordenador sobre la superficie que queremos utilizar como pizarra digital. Hay que prever una luminosidad y resolución suficiente. El proyector conviene colocarlo en el techo y a una distancia de la superficie a utilizar que permita obtener una imagen luminosa de gran tamaño y nítida.

Page 11: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

11

4.3.3 Hardware de posicionamiento del puntero sobre la superficie de proyección

Se utilizan diversos tipos de sensor, según la tecnología de posicionamiento que utilicemos. Este sensor puede ser la superficie de escritura, encontrarse acoplada a ella, o estar alrededor de esta para tener una visión a distancia de la posición del puntero. Este hardware debe estar conectado al ordenador, para poder indicar a qué posición debe mover el mouse. Existen diversos tipos de conexión al ordenador, como pueden ser por cable con conexión USB o RS232, por Bluetooth o por infrarrojos. La más utilizada es la de tipo Bluetooth, ya que permite colocar el sensor en cualquier punto que se encuentre dentro de un radio de 10 m respecto el ordenador. Permite una gran versatilidad.

4.3.4 Puntero

El puntero se utiliza para indicar a qué posición de la proyección quieres mover el cursor del ratón del ordenador. Sirve para posicionar el cursor sobre la superficie de proyección. Es el elemento que se utiliza para interactuar con el ordenador, ya que es con el que controlamos los movimientos y acciones del cursor. La tecnología utilizada en el puntero depende del tipo de sensor que utilicemos. Esta deberá ir en consonancia con la tecnología de sensado utilizada, ya que sino no se podría identificar la posición del puntero.

4.3.5 Software de interconexión entre el hardware externo y el ordenador

Este software es el encargado de recibir la información del hardware externo de sensado e interpretarla para transformar la posición del puntero sobre la superficie de proyección en el punto que se quiere marcar sobre la pantalla del ordenador. Es proporcionado por el fabricante o distribuidor de la pizarra digital y generalmente permite gestionar la pizarra, capturar imágenes y pantallas, disponer de plantillas, de diversos recursos educativos, de herramientas tipo zoom y reconocimiento de escritura, entre otras utilidades [1].

4.4 Características de una pizarra interactiva

4.4.1 Resolución

Se refiere al mínimo desplazamiento del puntero que puede ser detectado por el sistema de sensado. Desplazamientos inferiores a ese valor no producirán ningún efecto. Este valor determina a su vez el mínimo desplazamiento que hará el cursor sobre la pantalla, ya que como mínimo se moverá una distancia igual a la resolución del sistema sensor.

4.4.2 Superficie o área activa

Es al área de dibujo de la pizarra interactiva, donde se detectan las herramientas de trabajo. Esta superficie no debe producir reflejos y debe ser fácil de limpiar [1].

Page 12: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

12

4.4.3 Conexiones

Las pizarras interactivas presentan los siguientes tipos de conexiones: cable (USB, serie), conexión sin cables (Bluetooth) o conexiones basadas en tecnologías de identificación por radiofrecuencia [1].

4.4.4 Punteros

Dependiendo del tipo de pizarra utilizado, se puede escribir directamente con el dedo, con lápices electrónicos que proporcionan una funcionalidad similar a los ratones (disponen de botones que simulan las funciones de los botones izquierdo y derecho del ratón y de doble clic) o incluso con rotuladores de borrado en seco adaptados a la tecnología usada por el sensor de posición [1].

4.4.5 Software

Las pizarras deben disponen de un software compatible con Windows 98, 2000, NT, ME y XP, Linux (según modelo) y Mac (según modelo). Este software permite controlar el movimiento del cursor del ordenador desde la imagen proyectada. El movimiento se debe realizar con un puntero especial o con los dedos, según el tipo de software utilizado. Esto es posible a través de la interpretación de la información enviada por el hardware externo, el cual detecta la posición donde se encuentra el puntero o los dedos sobre la proyección. Generalmente, este software integra funciones adicionales como pueden ser las siguientes [1]:

Reconocimiento de escritura manual y teclado en la pantalla.

Biblioteca de imágenes y plantilla.

Herramientas pedagógicas como, regla y transportador de ángulos, librerías de imágenes de Matemáticas, Física, Química, Geografía, Música, etc.

Capacidad para importar y salvar al menos en algunos de los siguientes formatos: JPG, BMP, GIF, HTML, PDF, PowerPoint...

Recursos didácticos en diversas áreas con distintos formatos (HTML, Flash, …)

Capacidad para crear recursos.

Integración con aplicaciones externas.

4.4.6 Portabilidad

Una característica muy importante de este tipo de pizarras es la capacidad de trasladar esta tecnología de un lugar a otro y aplicarla de forma rápida y sencilla. Al ser compatibles con cualquier superficie donde se proyecte una imagen, se pueden utilizar en multitud de lugares. Solo se debe disponer de un ordenador, un proyector y el hardware comentado anteriormente para convertir esa superficie en táctil. Tanto el hardware de sensado como el puntero tienen un peso muy reducido, con lo que son fácilmente portables. Hay algunos tipos de pizarras digitales interactivas que no se pueden trasladar, ya que el sensor de posición es la propia superficie de escritura.

Page 13: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

13

4.5 Beneficios para los docentes

Es un recurso flexible y adaptable a diferentes estrategias docentes [1]:

o El recurso se acomoda a diferentes modos de enseñanza, reforzándolas estrategias de enseñanza con la clase completa, pero sirviendo como adecuada combinación con el trabajo individual y grupal de los estudiantes.

o La pizarra interactiva es un instrumento perfecto para el educador constructivista ya que es un dispositivo que favorece el pensamiento crítico de los alumnos. El uso creativo de la pizarra sólo está limitado por la imaginación del docente y de los alumnos.

o La pizarra fomenta la flexibilidad y la espontaneidad de los docentes, ya que estos pueden realizar anotaciones directamente en los recursos web utilizando marcadores de diferentes colores.

o La pizarra interactiva es un excelente recurso para su utilización en sistemas de videoconferencia, favoreciendo el aprendizaje colaborativo a través de herramientas de comunicación:

o Posibilidad de acceso a una tecnología TIC atractiva y de sencillo uso.

o La pizarra interactiva es un recurso que despierta el interés de los profesores a utilizar nuevas estrategias pedagógicas y a utilizar más intensamente las TIC, animando al desarrollo profesional individual.

o El docente se enfrenta a una tecnología sencilla, especialmente si se la compara con el hecho de utilizar ordenadores para toda la clase.

Interés por la innovación y el desarrollo profesional:

o La pizarra interactiva favorece el interés de los docentes por la innovación y el desarrollo profesional y facilita el cambio pedagógico que puede suponer la utilización de una tecnología que inicialmente encaja con los modelos tradicionales, y que resulta de fácil uso.

o El profesor se puede concentrar más en observar a sus alumnos y atender sus preguntas ya que no debe estar mirando la pantalla del ordenador continuamente.

o Aumenta la motivación del profesor: dispone de más recursos, obtiene una respuesta positiva de los estudiantes, etc.

o El profesor puede preparar clases mucho más atractivas y documentadas. Los materiales que vaya creando los puede ir adaptando y reutilizar cada año.

Ahorro de tiempo:

o La pizarra ofrece al docente la posibilidad de grabación, impresión y reutilización de la clase reduciendo así el esfuerzo invertido y facilitando la revisión de la clase impartida.

Page 14: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

14

o Generalmente, el software asociado a la pizarra posibilita el acceso a gráficos, diagramas y plantillas, lo que permiten preparar las clases de forma más sencilla y eficiente, guardarlas y reutilizarlas.

No requieren conocimientos previos para su utilización. Es una tecnología muy intuitiva.

4.6 Beneficios para los alumnos

Aumento de la motivación y del aprendizaje:

o Incremento de la motivación e interés de los alumnos gracias a la posibilidad de disfrutar de clases más llamativas en las que se favorece el trabajo colaborativo, los debates y la presentación de trabajos de forma vistosa a sus compañeros. Con esta tecnología se favorece la auto confianza y el desarrollo de habilidades sociales.

o La utilización de pizarras digitales facilita la comprensión, especialmente en el caso de conceptos complejos, dada la potencia para reforzar las explicaciones utilizando vídeos, simulaciones e imágenes con las que es posible interaccionar.

o Los alumnos pueden repasar los conceptos dado que la clase o parte de las explicaciones pueden ser enviadas por correo electrónico a los alumnos por parte del docente.

1. Acercamiento de las TIC a alumnos con discapacidad:

o Los estudiantes con dificultades visuales se beneficiarán del aumento de tamaño de los textos e imágenes, así como de las posibilidades de interactuar con objetos y símbolos de gran tamaño.

o Los alumnos con problemas de audición se verán favorecidos gracias a la posibilidad de utilizar presentaciones visuales o del uso del lenguaje de signos de forma simultánea.

o Los estudiantes con otros tipos de necesidades educativas especiales, tales como alumnos con problemas severos de comportamiento y de atención, se verán favorecidos por disponer de una superficie interactiva de gran tamaño sensible a un lápiz electrónico o incluso al dedo (en el caso de la pizarra táctil) con la cual pueden interactuar llegando a obtener un resultado creado por ellos. Mejora su nivel de atención debido al desarrollo de la capacidad de interacción.

Page 15: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

15

5 Análisis previo

Para llegar a conseguir el objetivo marcado, debemos observar que posibilidades existen en el mercado, que sean de bajo coste y nos permitan posicionar un puntero en una superficie de proyección.

De entre todas las tecnologías existentes, comentadas anteriormente, la que ofrece una solución más económica es la de posicionamiento por infrarrojos, ya que con una cámara específica para la detección de luz infrarroja, podríamos detectar este punto y posicionarlo. En el caso de utilizar tecnología resistiva o electromagnética necesitaríamos que toda la superficie de escritura fuera a su vez sensora de la posición del puntero, con la problemática de que este sistema no sería portable y encarecería el producto final si se tratara de una superficie muy grande. La tecnología ultrasónica basa parte de su posicionamiento en la detección de infrarrojos, con lo que es una solución más cara que la utilización de tecnología infrarroja únicamente.

La detección de posición por infrarrojos resulta una solución mucho más económica que cualquier otra, pero el grado de error en el posicionamiento del puntero sobre la superficie es mucho más elevado que en los otros tipos de tecnología. A pesar de ello, elegimos esta tecnología como medio de posicionamiento en nuestro proyecto ya que el objetivo principal es que la solución final presente un precio muy bajo.

Por tanto, para la realización de este proyecto necesitamos un elemento que indique la posición del puntero infrarrojo sobre una superficie. Observando los diversos componentes electrónicos con gran número de ventas que disponen de sistema de posicionamiento de infrarrojos, encontramos que la solución más factible sería la utilización de un mando de la videoconsola Nintendo Wii (llamado Wiimote), ya que dispone de una cámara de alta resolución (1024 x 768) con un filtro de infrarrojos. Además, su conexión con la videoconsola es mediante tecnología Bluetooth, con lo que se puede interconectar fácilmente con cualquier PC que disponga de interfaz de conexión Bluetooth. Este mando dispone de un chip de la empresa PixArt que interpreta la imagen recibida la cámara, y posiciona los puntos que ve enviando su posición X y Y sobre el plano que capta la cámara del mando. El propio mando ya nos posiciona el emisor infrarrojo, y nos envía la información por Bluetooth, con lo que resulta la opción más factible. El precio de este es de 36 €, con lo que es el hardware de sensado mas barato que encontramos en el mercado.

Para la realización del software hemos de tener en cuenta los datos que envía el hardware y cómo interpretarlos. Buscando en Internet encontramos una librería que realiza la conexión con los mandos de la Wii y trata las tramas de datos enviadas por el mando para poder ser interpretadas desde lenguaje de programación C#. Este es otro de los motivos por los que elijo este lenguaje de programación para la realización del software.

Page 16: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

16

6 Funcionamiento del Wiimote

La función de detección de infrarrojos se desarrollo en el Wiimote después de que Nintendo, durante el desarrollo de su videoconsola “Wii”, detectara que el posicionamiento

mediante acelerómetro era insuficiente. Deseaban utilizar el mando para mover un cursor por la pantalla, y el acelerómetro no era lo suficiente preciso. Por tanto, necesitaban un método para posicionar un punto fijo cercano a la pantalla. Con esa idea en mente, dotaron al mando de un sensor de puntos infrarrojos y diseñaron una barra con dos grupos de 5 leds infrarrojos separados 19 centímetros entre ellos. Esta barra de leds se sitúa debajo de la pantalla utilizada, con lo que le permite a la consola posicionar el lugar donde se encuentra la imagen en la que tiene que colocar el cursor.

En este proyecto, aprovechamos esta funcionalidad del mando para situar nuestro puntero infrarrojo sobre la superficie proyectada, y de esta manera indicar al ordenador la posición a la que queremos enviar el mouse del ordenador.

El funcionamiento del Wiimote es simple. Dispone de un filtro infrarrojo delante de la cámara de alta resolución, con lo que la cámara solo recibe la imagen de fuentes emisoras de infrarrojos. Si situamos un led infrarrojo delante, esta cámara percibe un punto y envía su posición X e Y, respecto la imagen que capta la cámara en ese momento, que tiene una resolución de 1024 pixeles de ancho por 768 de alto. Por tanto, el punto superior izquierdo que ve la cámara seria la posición (0,0), el punto superior derecho la posición (0,1024), el punto inferior izquierdo la posición (768,0) y el punto inferior derecho la posición (1024,768). El mando dispone de un chip que posiciona el punto que recibe la cámara sobre el plano que capta esta, y envía la posición del punto por Bluetooth al dispositivo al que esté conectado. Este chip ha sido desarrollado por la empresa PixArt Imaging, Inc. Este sistema de posicionamiento de puntos recibe el nombre de “Sistema de

posicionamiento multiobjeto”, o también llamado MOTS (Multi-Object Tracking System). Se trata de un sistema de procesamiento de imagen asistido por ordenador, que ya se encuentra integrado en el hardware, lo que permite localizar la posición de los puntos brillantes que reciba la cámara.

El chip de procesado de la posición de los puntos puede procesar hasta 4 puntos diferentes simultáneamente, y enviar la posición de todos ellos. Por tanto, podríamos posicionar 4 punteros infrarrojos diferentes si se deseara. Si hubiera más de 4 punteros en la superficie, escogería los 4 puntos más brillantes por defecto.

El mando dispone de un tiempo de muestreo de 100 ms. Este será el tiempo que se tarda en refrescar la información de los puntos.

También dispone de una pequeña memoria de 4 KB utilizada para guardar el emoticono del jugador que utiliza el mando en ese momento.

A continuación se expone una tabla con las direcciones en las que el mando recibe los datos enviados por el ordenador:

Dirección Función

0x11 Indicación del número de jugador y activación/desactivación del vibrador.

0x12 Indicación de la ID del mando

Page 17: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

17

0x13 Activación del sensor IR

0x14 Activación del altavoz

0x15 Estado del mando

0x16 Escribir datos en memoria

0x17 Leer datos de memoria

0x18 Datos enviados al altavoz

0x19 Silenciar altavoz

0x1a Activar sensor IR 2

Tabla 1. Direcciones de recepción de datos del Wiimote

También existen direcciones en las que el mando coloca los datos a enviar al PC. Estas son las siguientes:

Dirección Función

0x20 Puerto de expansión

0x21 Lectura de datos de memoria

0x22 Escritura de datos de memoria

0x30 Botones

0x31 Estado botones/Información acelerómetro

0x32 Estado botones/Información sensor IR

0x33 Estado botones/Información acelerómetro

0x34 Estado botones/Información sensor IR

0x35 Estado botones/Información acelerómetro

0x36 Estado botones/Información sensor IR

0x37 Estado botones/Información acelerómetro

0x3d Estado botones/Información sensor IR

0x3e Estado botones/Información acelerómetro

0x3f Estado botones/Información sensor IR

Taula 2. Direcciones de envío de datos del Wiimote

La información sobre el puerto de expansión indica si hay algún elemento auxiliar conectado al puerto que hay debajo del mando. Las direcciones de lectura de datos en la memoria del mando y escritura de datos en la memoria del mando se utilizan para conocer qué datos han sido los últimos que se han introducido, tanto en lectura como en escritura.

Page 18: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

18

6.1 Hardware

A nivel de hardware, el mando dispone de diversos componentes. A continuación comentaremos los más importantes:

6.1.1 Acelerómetro

El mando dispone de un acelerómetro integrado que proporciona los datos de movimiento y giro/inclinación del mando en todo momento. Este tipo de dispositivos se conocen como MEMS (sistema micro electro-mecánico) [2].

El chip MEMS utilizado en el Wiimote proviene de Analog Devices y es exactamente el modelo ADLXL330, con un tamaño de 4x4x1,45 mm. Este chip está diseñado específicamente para tener un consumo muy bajo, alargando la vida de las pilas. Su rango de detección es de ±3,6 gravedades y tiene una resolución de 300 mV/g [2].

Estudiando el funcionamiento de estos chips, se descubre que miden tanto la aceleración. Para comprender su funcionamiento, imagine una pila con dos minúsculas placas dentro del sensor. Una se mantiene fija, pero la otra se mueve. Los electrones que rodean la placa que se ha movido varían, y midiendo la capacitancia, el sensor es capaz de detectar el movimiento realizado. El dispositivo puede así enviar datos de movimientos relativos en todos los ejes de coordenadas, aparte de los datos de aceleración, detectando (dentro de sus limitaciones) giros, movimientos en el aire, inclinaciones... Estos datos se envían al chip Broadcom, encargado de la emisión de datos a través de Bluetooth [2].

Figura 1. Imagen del acelerómetro sobre la placa PCB del Wiimote

6.1.2 Emisor/receptor Bluetooth

Para comunicarse con la consola, el Wiimote dispone de un chip emisor y receptor de datos por Bluetooth, proporcionado por la empresa especializada en comunicaciones Broadcom Technologies. Se trata del modelo BCM2042.

Este chip se encarga de enviar el conjunto de datos para su recepción en otro dispositivo Bluetooth que aplique el tratamiento necesario a los datos recibidos. La velocidad de transferencia que ofrece este chip es de 2.1 Mbits/s. Broadcom ha incluido mejoras especiales que permiten una latencia muy baja entre consola y mando, intentando que la respuesta sea prácticamente la de un mando cableado clásico. Además, el componente Bluetooth de la compañía tiene un consumo realmente bajo [2].

Page 19: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

19

Este chip utiliza el protocolo estándar Bluetooth HID para comunicarse con la consola, con lo que podemos leer sus datos desde cualquier stack Bluetooth estándar. Este protocolo de comunicación está basado en el USB HID, con lo que podemos interpretar el mando como un dispositivo USB, una vez se haya emparejado este con el dispositivo Bluetooth del PC.

Figura 2. Imagen del chip de comunicación Bluetooth integrado en el Wiimote

6.1.3 Sensor de emisiones infrarrojas

El Wiimote incluye en su parte superior una cámara monocroma con una resolución de 128x96, con procesado de imagen mediante hardware ya incorporado. En la parte delantera del mando encontramos un plástico de color negro. Se trata de un filtro que solo deja pasar rayos infrarrojos, con lo que esta cámara únicamente captará puntos en los que haya un emisor infrarrojo. Como ya hemos dicho anteriormente, el procesador de imagen incorporado es capaz de posicionar hasta 4 puntos infrarrojos en movimiento. Los datos de la posición de estos puntos se enviar por Bluetooth al dispositivo al que esté conectado el mando. Al incluir este procesado por hardware, solo está disponible el resultado de la posición de los puntos, y por tanto, no podemos recibir toda la imagen que capta la cámara, con lo que no se podría utilizar para leer imágenes del exterior y tratarlas posteriormente. Si elimináramos el filtro de infrarrojos del mando, podríamos posicionar cualquier punto brillante, pero siempre siguiendo las especificaciones del procesador de imagen. Es decir, podríamos posicionar 4 puntos únicamente y nunca podríamos obtener la imagen de lo que está viendo el mando [3].

El procesador MOTS de la marca PixArt incorporado utiliza un análisis de subpixeles, los cuales multiplica automáticamente por 8, llegando a obtener una resolución de 1024x768 para los puntos posicionados [3].

Page 20: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

20

Figura 3. Imagen de la cámara sobre la placa PCB del Wiimote

Esta cámara dispone de un rango de visión efectiva de 33 grados horizontales y 23 grados verticales. Con el filtro de infrarrojos intacto, los emisores infrarrojos con una longitud de onda de 940 nm son detectados con el doble de intensidad que los emisores que disponen de una longitud de onda de 850 nm, aproximadamente. El inconveniente de los emisores de 940 nm es que cuando la distancia entre el mando y el emisor es muy corta, el mando no lo posiciona correctamente debido a la gran intensidad que ofrece [3].

No podemos indicar el modelo del procesador de imagen ni las características de este porque es información confidencial de Nintendo, sobre la cual no hay ningún tipo de documento publicado. Este procesador fue desarrollado íntegramente para su aplicación en el mando de la consola Wii, y Nintendo dispone de la licencia en exclusiva, con lo que no hay información pública sobre sus características.

Finalmente, el circuito completo que forma el mando es el siguiente:

Figura 4. Imagen de la parte superior de la placa de circuito impreso del Wiimote

Figura 5. Imagen de la parte inferior de la placa de circuito impreso del Wiimote

Page 21: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

21

6.2 Control de la cámara por software

Centraremos este apartado en que datos enviar a la cámara para inicializarla o cambiar funciones de control del procesador.

6.2.1 Puesta en marcha de la cámara

1. Escribir byte bajo del registro de activación de cámara, enviando 0x04 al registro de salida 0x13.

2. Escribir byte alto del registro de activación de cámara, enviando 0x04 al registro de salida 0x1a.

3. Escribir 0x08 en el registro 0xb00030.

4. Escribir bloque 1 de información de sensibilidad de la cámara (se explicará la información a enviar en el siguiente apartado) en la dirección 0xb00000.

5. Escribir bloque 2 de la información de sensibilidad de la cámara en la dirección 0xb0001a.

6. Escribir el número de modo (se explicará la información a enviar en posteriores apartados) en el registro 0xb00033.

7. Escribir 0x08 en el registro 0xb00030 otra vez.

Después de realizar estos pasos, el Wiimote tendrá la cámara IR activada y estará cogiendo datos con la sensibilidad deseada [3]. Para el desarrollo de este proyecto la sensibilidad se ajusta siempre al máximo para detectar el puntero aunque la intensidad del infrarrojo sea baja.

6.2.2 Ajuste de sensibilidad

La sensibilidad de la cámara IR se controla mediante dos bloques de configuración, de 9 bytes y 2 bytes de longitud respectivamente. La siguiente tabla expresa los datos a enviar para configurar la sensibilidad deseada. Hay 6 niveles de sensibilidad. El nivel 6 es el más alto:

Bloque 1 Bloque 2 Nivel 00 00 00 00 00 00 90 00 41 40 00 Máxima sensibilidad 02 00 00 71 01 00 64 00 fe fd 05 Wii nivel 1 02 00 00 71 01 00 96 00 b4 b3 04 Wii nivel 2 02 00 00 71 01 00 aa 00 64 63 03 Wii nivel 3 02 00 00 71 01 00 c8 00 36 35 03 Wii nivel 4 07 00 00 71 01 00 72 00 20 1f 03 Wii nivel 5

Tabla 3. Datos a enviar para obtener los diferentes niveles de sensibilidad de la cámara.

Page 22: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

22

El último byte de ambos bloques determina la intensidad de la sensibilidad. Incrementando el valor de este último byte reduces la sensibilidad. Cuando el ultimo byte del bloque 1 es 0x41 y el segundo byte del bloque 2 es 0x00, el Wiimote envía datos para los puntos menos brillantes que pueda ver su cámara. Por tanto, con esa configuración obtendremos la mayor sensibilidad posible. Poniendo la sensibilidad lo más alto posible conseguimos la mayor resolución posible después del tratamiento del procesador de imagen. Al reducir la sensibilidad, reducimos también la resolución con la que el procesador tratará los datos de la imagen recibida. Si escogiéramos el nivel 1, la resolución de los puntos enviados por el mando sería muy próxima a la resolución real de la cámara, que es de 128x96 [3].

6.2.3 Formato de los datos

La cámara IR puede devolver diferentes configuraciones de datos describiendo los objetos que esta posicionando. Cuando la cámara IR identifica un objeto, lo asigna a la primera posición del vector disponible. Hay que recordar que el mando devuelve 1 vector con 8 posiciones (posición x de 4 puntos y posición y de 4 puntos). Si el objeto se mueve a una zona fuera de visión de la cámara, la posición de memoria donde se encontraba la información de ese punto se marca como vacía, pero los otros puntos que está viendo la cámara en ese momento mantienen su posición en memoria. Por ejemplo, si la cámara estuviera posicionando dos puntos diferentes y el primero que hubiera visto saliera de la zona de visión de la cámara, los datos que devolvería el mando serian [vacio, posición X e Y del segundo objeto, vacio, vacio] [3].

Hay 3 tipos diferentes de datos que nos puede enviar el mando de cada punto posicionado. Según el Número de Modo que configuremos al inicializar la cámara, enviara unos datos más básicos y reducidos o más extensos, lo que mejorará la precisión.

Modo Número de Modo Básico 1

Extendido 3 Completo 5

Tabla 4. Diferentes modos de recibir la información del Wiimote

6.2.3.1 Modo Básico

En el Modo Básico, la cámara IR devuelve datos con una longitud de 10 bytes, que se corresponden a la posición X e Y de los 4 puntos que se pueden posicionar. Cada posición se codifica en 10 bits, con un rango de 0 a 1023 para las dimensiones X, y un rango de 0 a 767 para las dimensiones Y. Cada par de puntos se empaqueta en 5 bytes. Por tanto, se envían 2 paquetes de 5 bytes para posicionar la totalidad de puntos [3].

Page 23: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

23

El formato seguido para enviar las coordenadas de un par de puntos es el siguiente:

Bit Byte 7 6 5 4 3 2 1 0

0 X1<7:0> 1 Y1<7:0> 2 Y1<9:8> X1<9:8> Y2<9:8> X2<9:8> 3 X2<7:0> 4 Y2<7:0>

Tabla 5. Formato de datos enviados por el Wiimote en Modo Básico para conocer la posición de 4 puntos

6.2.3.2 Modo Extendido

En Modo Extendido la cámara IR devuelve los mismos datos que en Modo Básico, y además añade 4 bits que aportan un valor aproximado del tamaño del punto recibido sobre la imagen que capta la cámara. En este modo, los datos característicos de un punto ocupan 3 bytes, con lo que los 4 puntos forman un total de 12 bytes. La información sobre el tamaño del punto tendrá un rango de 0 a 15 [3]. El formato seguido para el envío de datos en este modo es el siguiente:

Bit Byte 7 6 5 4 3 2 1 0

0 X<7:0> 1 Y<7:0> 2 Y<9:8> X<9:8> S<3:0>

Tabla 6. Formato de datos enviados por el Wiimote en Modo Extendido

6.2.3.3 Modo Completo

En Modo Completo, la cámara IR devuelve muchos más datos que en los modos comentados anteriormente. En este modo se envían 9 bytes por punto recibido, lo que hace un total de 36 bytes para enviar los datos de los 4 puntos. Para poder enviar estos datos, se dividen en paquetes de 18 bytes que se enviar a 2 registros de entrada diferentes, concretamente los que ocupan las posiciones de memoria 0x3e y 0x3f [3].

Los primeros 3 bytes de los datos característicos de cada punto son iguales a los enviados en Modo Extendido. Los cuatro bytes posteriores indican el valor mínimo y máximo del punto X e Y registrados desde que se ve ese punto en la cámara. El siguiente byte queda a 0 y se utiliza para separar los datos. El último byte enviado indica aproximadamente la intensidad del punto luminoso que recibe la cámara. La indicación de

Page 24: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

24

los valores mínimo y máximo tiene un rango de 0 a 63 y la indicación de la intensidad del punto luminoso tiene un rango de 0 a 127 [3].

El formato seguido para el envío de datos en este modo es el siguiente:

Bit Byte 7 6 5 4 3 2 1 0

0 X<7:0> 1 Y<7:0> 2 Y<9:8> X<9:8> S<3:0> 3 0 X min<6:0> 4 0 Y min<6:0> 5 0 X max<6:0> 6 0 Y max<6:0> 7 0 8 Intensidad<7:0>

Tabla 7. Formato de datos enviados por el Wiimote en Modo Completo.

En el desarrollo de este proyecto se utiliza siempre el Modo Básico, ya que con los datos de la posición concreta de los puntos tenemos suficiente, no necesitamos saber ni el tamaño ni la intensidad de este. Solo será necesario conocer la posición del punto para enviar el cursor allí.

6.3 Conexión del mando al ordenador

Para conectar el mando al ordenador, se han de pulsar los botones “1” y “2”

simultáneamente, o pulsar el botón rojo que hay al lado de las pilas, en la parte trasera del mando. Esta acción hace que el mando sea visible para las búsquedas de cualquier dispositivo Bluetooth durante 20 segundos. Al conectar el mando por primera vez no es necesario introducir ningún código de emparejamiento, con lo que el proceso es muy sencillo. Simplemente hay que realizar una búsqueda de dispositivos cercanos y seleccionar el dispositivo “Nintendo RVL-CNT-01”. Se configura con los valores por defecto y el mando queda ya emparejado. Como el proceso de emparejamiento dura más de 20 segundos, es importante mantener pulsados los botones 1 y 2 siempre, ya que así nos aseguramos de que el mando es visible, porque si no lo fuera no podríamos emparejarlos.

Una vez se han emparejado, para las próximas conexiones solo hará falta pulsar el botón 1 y 2 simultáneamente en el mando, para convertirlo en visible y darle doble clic al icono que indique “Nintendo RVL-CNT-01”, que saldrá en la lista de dispositivos

Bluetooth asociados a su ordenador. Una vez hecho esto tendremos los mandos conectados a nuestro ordenador, y podremos ejecutar la aplicación que los utiliza como sensores para conocer la posición de un puntero IR visto por la cámara del mando.

Page 25: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

25

7 Montaje del puntero IR

Para poder utilizar el sistema, es necesario que cada usuario se cree o compre un puntero infrarrojo, ya que el led infrarrojo será lo que indique en qué posición de la pantalla queremos escribir. Hay que recordar que el Wiimote solo detecta la posición de un emisor de rayos infrarrojos.

El circuito a montar, por tanto, consta de un led infrarrojo de 1.5 V y un pulsador que conecta el led con la pila y una pila de 1.5 V que alimenta al led. El pulsador permite decidir al usuario cuando quiere iluminar el led, es decir, cuando quiere que los movimientos del puntero se trasladen a la pantalla. Para su funcionamiento no es necesaria la inclusión de ninguna resistencia, ya que al ser el led de 1.5 V, con una pila lo podemos alimentar directamente sin que haya que introducir ningún elemento resistivo, tal como muestra la siguiente imagen:

Figura 6. Esquema de montaje del puntero infrarrojo [8]

Un elemento añadido a posteriori a este esquema es un condensador de Tántalo de 4.7 µF que se utiliza para evitar los rebotes del pulsador. Los rebotes del pulsador podrían plasmarse en pantalla cuando estemos utilizando la aplicación. Para evitarlos introduzco este condensador en paralelo al led.

He decidido partir de un rotulador de pizarra blanca, ya que al ser más gruesos que cualquier otro tipo de rotulador o bolígrafo me permiten alojar en su interior una pila de 1.5 V y todos los elementos del circuito sin problemas de espacio, con lo que obtengo un puntero infrarrojo portátil y compacto. Otro beneficio es que el impacto visual se reduce, ya que el led se integra en el lugar donde antes estaba el fieltro del rotulador. De esta manera puede pasar desapercibido.

El rotulador en cuestión elegido es el BIC Whiteboard Marker, ya que por su tamaño es ideal para contener una pila en su interior y además ergonómico ya que se estrecha en la parte de escritura. Otra de las ventajas que nos ofrece es que un led de 5 mm encaja perfectamente en la parte superior de la carcasa del rotulador, con lo que no es necesario realizar ninguna adaptación y ofrece un buen resultado visual.

En un principio escogí un led de la marca Telefunken, el modelo CQY 99, ya que ofrecía un ángulo de emisión de 60º [9]. El inconveniente que presenta este led es el valor de su longitud de onda: 920 nm. El Wiimote ve de forma óptima los leds con una longitud de onda de 940 nm. Leds con longitud de onda inferior, son recibidos por el mando, pero los interpreta como si tuvieran menor intensidad. Este efecto incrementa la aparición de errores por pérdida de visión. Pude comprobar este efecto después este modelo de led durante varios días, en conjunto con la aplicación que he desarrollado.

Page 26: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

26

Por ese motivo, decido cambiar el led por el modelo Vishay TSAL 6400 [10]. Se recomienda encarecidamente el uso de este led, ya que ofrece los mejores resultados en conjunto con el Wiimote. Las características de este modelo son una longitud de onda de 940 nm y un ángulo de visión de ± 25 º. Este led aguanta de tensión máxima 1.7 V. Por este motivo no necesita una resistencia entre el led y la pila, ya que aunque la pila ofrezca un valor de tensión superior a 1.5 V, el led es capaz de soportarlos sin dañarse.

Para el pulsador, elijo uno de tipo membrana de 12 x 12 mm, capaz de soportar 12 V DC, y con una fuerza de maniobra necesaria de 160 grs. Elijo este tipo de pulsador ya que su forma cuadrada presenta una mayor comodidad para el usuario. Este podrá apoyar su dedo encima del soporte del botón. La fuerza de presión de este tipo de pulsador es baja respecto a otros, con lo que es mucho más cómodo trabajar con él. Realiza una presión muy baja encima del pulsador ya se enciende el led. Por este motivo es más cómodo para el usuario, ya que este tiene que mantener el pulsador apretado en todo momento para poder escribir. Otro tipo de pulsadores quedaría mejor integrado en el conjunto pero sería necesario realizar una fuerza mayor, con lo que el usuario se cansaría mucho antes y dejaría de utilizarlo.

Por último, la elección del tipo de pila a utilizar. En un principio se puso una pila de 1.5 V de tipo A, pero ofrecía el inconveniente de que los portapilas que hay actualmente en el mercado no caben a causa de su abultado tamaño. Por tanto, para poner esta pila necesitamos soldar directamente los cables de alimentación a la pila, con el inconveniente de que cada vez que haya que sustituirla hay que desoldar la pila. Por ese motivo, después de comprobar los diversos tipos de pila que hay en el mercado, escogí una pila de 1.5 V de tipo N. Esta pila ofrece un tamaño muy reducido, y su portapilas también es muy compacto con lo que se puede integrar perfectamente dentro del bolígrafo. El único inconveniente que ofrecen es su coste, más elevado respecto a las de tipo A, ya que el tipo N no es un formato de uso habitual en los componentes electrónicos domésticos. Se utiliza para los buscapersonas actualmente pero estos dispositivos están en desuso, con lo que estas pilas no son muy comunes y ofrecen un precio elevado.

El primer paso para llevar a cabo el montaje fue soldar el condensador de Tántalo al led, siguiendo la polaridad de este. De esta manera ya tengo un módulo compacto con el led y condensador unidos:

Figura 7. Led infrarrojo soldado a condensador de tántalo de 47 µF.

Page 27: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

27

Una vez tenemos el led y el condensador soldados, hago unos agujeros al marcador de pizarra, que previamente habremos vaciado, dejando solo la carcasa de plástico. Estos agujeros serán los que utilizaré para pasar el cable del pulsador por dentro de la carcasa del marcador, ya que soldar los cables dentro de la carcasa es muy difícil, los soldamos fuera y pasamos el cable por dentro, dejando el pulsador a la vista en la parte externa de la carcasa. Por tanto, una vez hechos los agujeros, sueldo los cables a las patas del pulsador. Después paso los cables por los agujeros y los dejo dentro de la carcasa de plástico del marcador. Para fijar el pulsador al marcador hago unos pequeños agujeros para encajar las patas en el plástico y lo fijo con un poco de pegamento en cada pata. El resultado es el siguiente:

Figura 8. Pulsador con los cables soldados a las respectivas patas.

Figura 9. Pulsador con los cables ya pasados por el interior del marcador.

Figura 10. Marcador con los cables procedentes del pulsador.

Page 28: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

28

Uno de los cables va hacia el led y el otro hacia la pila, la cual irá colocada en la parte trasera.

Una vez tenemos el marcador con los cables pasados por su interior, soldamos un cable al polo negativo del portapilas, el cual va directamente al led, y el cable que viene del pulsador lo soldamos al polo positivo de este:

Figura 11. Detalle del portapilas soldado.

Podemos ver como el cable negro va a la parte superior, y proviene del polo negativo, mientras que en el polo positivo soldamos el cable del pulsador. Ya lo tenemos todo listo para soldar el led en la parte superior siguiendo su polaridad y encajarlo todo dentro del marcador:

Figura 12. Detalle del led soldado ya a los cables provenientes del pulsador y de la pila.

Se aíslan el polo positivo y negativo del led con goma termoretráctil, para evitar cortocircuitos.

Page 29: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

29

Figura 13. Marcador con el led soldado y la pila ya introducida en su interior.

Ya solo queda introducir el led en la parte superior y fijarlo con un poco de pegamento. Si no se fijara con pegamento, al utilizarlo se iría hacia el interior del marcador y el led quedaría tapado por la carcasa del marcador. Poniendo un poco de pegamento en la base del infrarrojo, ya queda fijado a la pared de plástico del marcador y se evita que se desplace hacia dentro de marcador. El resultado final es el siguiente:

Figura 14. Puntero infrarrojo acabado

El usuario deberá pulsar el botón que hay en la parte superior del puntero cada vez que quiera mover el cursor hasta la posición en la que se encuentre el puntero. Para escribir encima de la proyección deberá mantener pulsado el botón mientras desliza el puntero sobre la superficie. Observará como el trazo va apareciendo en ella. Cuando suelte el botón, dejará de escribir ya que el cursor dejará de moverse.

Page 30: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

30

8 Desarrollo del software

Una vez tenemos a punto todo el hardware necesario para llevar a cabo este proyecto, necesitamos diseñar un software que nos convierta el punto captado por la cámara del Wiimote en una coordenada de la pantalla de nuestro ordenador, para indicar al puntero del mouse que se dirija a esa coordenada. Por tanto, tenemos que crear un programa, que mediante una calibración previa, conozca que coordenadas del punto en el mando son las esquinas de nuestra proyección, para obtener así la relación entre coordenadas del mando y coordenadas del mouse. Como punto de referencia tenemos el programa desarrollado por Johnny Chung Lee, llamado “Wiimote Whiteboard v0.3”, el cual se puede descargar de la web http://johnnylee.net/projects/wii/ [4]. Este programa implementa la calibración de un solo mando. Partiendo de estos conocimientos, en este proyecto se desarrolla una aplicación que permita la utilización de dos mandos diferentes para posicionar el cursor, ya que de esta manera evitaremos tener tantas zonas oscuras como se tendrían con un mando. Cuando algún objeto, o el propio usuario, se interponen entre el sensor y el Wiimote, este último no puede ver el puntero y el programa no funciona. Con dos mandos colocados uno en cada punta de la pizarra, aunque uno no vea el puntero el otro seguramente sí que tenga visión de este. Por tanto, en este proyecto desarrollaremos la aplicación para la utilización de dos mandos en vez de uno, lo que resultará en un mejor rango de funcionamiento de la aplicación.

8.1 Conexión con el mando.

Para comenzar a desarrollar el software, partimos de una librería diseñada específicamente para lenguaje de programación C#, la cual implementa todas las posibles funciones que podemos utilizar del mando. Es decir, realiza la conexión con este, activa el sensado de fuentes infrarrojas al conectarse y lee toda la información que envía el mando y la coloca en diferentes variables o vectores, según el tipo de información que sea. En definitiva, la almacena en el formato más manejable para su posterior tratamiento. Al disponer de esta librería pública en internet, nos ahorramos el tiempo de crear todo el sistema de conexión a base de envíos de los bytes comentados en el apartado de “Funcionamiento del mando” por el puerto de datos Bluetooth hacia el mando. Toda esta

tarea la realiza esta librería, además de leer la información de los puntos IR que capta y guardarla en vectores para tratarla en diferentes puntos del programa. La librería en cuestión se llama “WiimoteLib v1.7”. Ha sido creada por Brian Peek, programador Senior en ASPSOFT, Inc. y Microsoft C# MVP, y está disponible en la web “http://www.codeplex.com/WiimoteLib” [5].

A partir de esa librería comenzamos a desarrollar nuestro software. Al descargarte la librería, esta viene acompañada de un programa de testeo de los datos enviados por el Wiimote. La librería ya implementa la posibilidad de conectarse a dos mandos diferentes. Antes de comenzar a programar, compruebo que los dos mandos se conectan correctamente y envían los datos correctos. Esta prueba resulta positiva, con lo que la conexión Bluetooth funciona correctamente y se ha podido comprobar que la conexión entre los mandos y el PC es estable.

El código que posibilita la conexión se encuentra referenciado como Código 1 en el apartado 13.2 Código desarrollado durante el proceso de creación del programa incluido en el Anexo.

Page 31: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

31

En la carga del formulario principal de control de este programa, se realiza la conexión al mando. Al principio del código se crea una variable llamada mWC. Esta variable será crítica para todo el desarrollo del software, ya que contiene los datos que envían los dos mandos por separado. Es decir, mWC[0] tendrá almacenados los datos del mando 1 y mWC[1] tendrá almacenados los datos del mando 2. En el momento de conectar los mandos se crea un vector donde se identifican estos, para posteriormente poder elegir la información del mando que nos interese. Las funciones “try” y “catch” se aplican en zonas

de código donde es posible que se pueda producir un fallo, ya que estas funciones lo que permiten es tratar el posible fallo generado. Primero se prueba el código que hay dentro de try. Si este devuelve un error, se salta a la función catch, que indica que tratamiento dar a una excepción concreta. En este punto se tratan las excepciones más comunes, como que no haya mando conectado al ordenador, o que no se encuentre el mando. En caso de que la excepción sea de otro tipo, se muestra un mensaje que indica que el error ocurrido es desconocido. Si se encuentran todos los Wiimotes conectados al PC y se listan correctamente en el vector mWC, se pasa a la siguiente parte de código, donde se crean dos pestañas diferentes para mostrar los datos de cada Wiimote. Esto se realiza en “Create a

new tab” y “Create a new user control”. Posteriormente se indica al programa que los datos

de la pestaña Wiimote 1 sean los del mando 1, y los de la pestaña Wiimote 2 sean los del mando 2. La conexión entre el programa y los mandos se realiza con el comando “wm.Connect( );”. Al ejecutar este comando, el programa llama a la librería WiimoteLib y

le indica que tiene que realizar la conexión con el mando. Esta librería ya se encarga de pasar los paquetes de datos a las direcciones necesarias para que así sea. Una vez ejecutado ese comando, ya tenemos los diferentes mandos conectados y recibimos sus datos divididos según que mando nos los envía.

8.2 Calibración

Una vez tenemos el mando conectado a nuestro ordenador y recibimos los datos que este envía, lo primero que debería hacer el programa sería establecer la relación de correspondencia entre la posición de un punto captado por la cámara y la posición de ese punto sobre la pantalla de nuestro ordenador. Puede parecer una solución trivial, pero no lo es tanto si tenemos en cuenta que el mando no está perpendicular a la pizarra, sino que tiene cierto ángulo con esta, con lo que los puntos que posiciona el mando están en una superficie trapezoidal para la visión de este. Por lo tanto, para establecer una relación real entre la posición captada en el mando y la posición de ese punto en la pantalla, hay que convertir la posición del punto captado por el mando sobre una superficie trapezoidal en una posición sobre una superficie rectangular. Para hacer esto, se aplican diversas multiplicaciones matriciales a los datos enviados por el mando, las cuales dan como resultado la transformación de las coordenadas enviadas por el mando en coordenadas sobre la pantalla del ordenador.

Vamos a explicar en qué consiste esta técnica de transformación. Cuando miras el mundo a través de las lentes de una cámara, este se percibe como una imagen plana y todas las cosas se ven distorsionadas, tal como dictan las leyes de la perspectiva. Los objetos que puedes ver se encuentran lejos y se ven más pequeños, y los cuadrados se convierten en trapezoides. Si lo que tu estas mirando a través de la lente es una superficie plana, esta distorsión puede ser tratada mediante la multiplicación de unas matrices llamadas matrices de deformaciones (en inglés Warper Matrix) que convierten la posición X e Y de un punto sobre un trapezoide en posición X e Y de un punto sobre una superficie rectangular.

Page 32: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

32

Para realizar ese cálculo lo único que se necesitan son 8 valores X e Y. Cuatro de ellos serán las posiciones de las esquinas de nuestra pantalla. Estos valores se guardarán en una matriz llamada “destination quad”. Los otros 4 serán esas mismas posiciones

correspondientes a la cámara del mando, y se guardaran en la matriz llamada “source

quad”. Con esta información y mediante cálculos matemáticos, el ordenador puede

convertir cualquier punto visto por la cámara en un punto sobre la pantalla del ordenador. De esta manera conseguiremos que el cursor del mouse vaya a la posición que nosotros estamos marcando con el puntero sobre la proyección.

Por lo tanto, para poder posicionar cualquier punto necesitamos haber almacenado previamente las coordenadas de las esquinas. Las coordenadas de nuestra pantalla dependerán de la resolución de esta. La resolución de la pantalla se puede conocer rápidamente utilizando el comando “Screen.GetBounds(this).Width;” y

“Screen.GetBounds(this).Height;” . Para conocer las posiciones del mando, debemos de leer en cada esquina de la proyección que posición nos envía el mando, y almacenarla en la matriz “source quad”. Para conocer la posición de las esquinas según el mando, hemos de

realizar la etapa de calibración.

El funcionamiento de la calibración es muy sencillo. Se crea una pantalla con fondo de color blanco y 4 puntos de color rojo, que serán puntos conocidos por el ordenador y corresponderán a las esquinas de la proyección. Entonces el usuario debe de marcar esos puntos con su puntero IR. Al marcar esos puntos, el ordenador lee la posición que envía el mando y la almacena. De esta manera podemos establecer qué punto nos envía el mando en el origen de coordenadas de la pantalla. Relacionamos la posición 0,0 de la pantalla con la que nos envíe el mando para la esquina superior izquierda. Con la calibración también delimitamos nuestra superficie de trabajo, de manera que si utilizamos el cursor fuera de esa zona, no habrá ningún efecto sobre la posición del mouse.

Para realizar todas estas tareas se crea otro formulario nuevo que consistirá en una pantalla de fondo blanco donde se dibujaran 4 cruces rojas indicando los puntos donde el usuario debe clicar con el puntero IR. Este formulario no almacenará las posiciones enviadas, sino que únicamente se encargará de controlar las imágenes que se muestran por pantalla. Es decir, irá cambiando la cruz de posición cada vez que el formulario principal le indica que ya tiene almacenada la posición de ese punto. Todas las demás tareas las realiza el código escrito en el formulario principal “MultipleWiimoteForm.cs”. En el código de

este formulario se realiza todo el almacenamiento de los datos de la calibración, y se controla la posición en pantalla del nuevo punto a calibrar. Para almacenar la posición de los puntos en pantalla dentro de la matriz “destination quad” e indicar en que posición de

pantalla hay que dibujar la cruz, se dispone de la función “doCalibration( )”. Los datos

relativos a la posición de ese punto para el mando se almacenan en otra parte del código. Posteriormente explicaremos porque. Para conocer el punto de calibración que se tiene que realizar se utiliza la variable global “calibrationState”. Como el almacenamiento de los

datos que envía el mando se realiza en otra parte del código, utilizamos esta variable para controlar que se almacene la información relativa al mismo punto en las dos partes de código. La función “doCalibration” también se encarga de enviar las matrices “source

quad” y “destination quad” a la subrutina Warper, la cual utilizará esta información para calcular la posición a la que debe ir el mouse durante la utilización de la aplicación.

El código de la función “doCalibration” que posibilita la conexión se encuentra referenciado como Código 2 en el apartado 13.2 Código desarrollado durante el proceso

de creación del programa incluido en el Anexo.

Page 33: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

33

Se puede apreciar en el código, que para cada punto almacenamos la misma información en cuatro matrices diferentes: X1, Y1, X2, Y2. El motivo de este almacenamiento es que hemos elegido que se calibren los dos mandos al mismo tiempo.

Para cada punto de la calibración, el programa coje la información de la posición de ese punto para los dos mandos, y no pasa al siguiente punto hasta que no tiene la posición de los dos mandos. Al tener dos mandos diferentes, disponemos de dos funciones Warper distintas, ya que los mandos se encontraran en lugares diferentes. Por tanto, se dispone de la subrutina Warper1, que devuelve la posición en pantalla del PC de lo que ve el mando 1, y Warper2, que devuelve la posición en pantalla de lo que ve el mando 2. Como tenemos dos subrutinas Warper, hemos de crear 2 matrices “destination quad” diferentes, una para

Warper 1 y una para Warper 2. La matriz “destination quad” a su vez se compone de dos

matrices diferentes, la que almacena los datos de posición X y la que almacena los datos de posición Y. En conclusión, hay que crear 4 matrices diferentes: X1, Y1, X2 e Y2. Como los dos mandos se calibran al mismo tiempo, las dos matrices “destination quad” seran

iguales. Por tanto, X1=X2 en todas las coordenadas de la pantalla del PC, y de la misma manera Y1=Y2.

Las coordenadas de esos puntos enviadas por el mando no se almacenan aquí porque el mando envia una interrupción cada vez que tiene datos nuevos. Cuando la cámara capta una emisión IR, actualiza sus datos y provoca una interrupción, la cual debe ser atendida por el programa. Dentro de la rutina de atención a la interrupción encontramos la parte de código referente al almacenamiento de esa información. Al tratarse de una interrupción, queda justificado el uso de una variable para sincronizar la función doCalibration con el almacenamiento de la información enviada por el mando. Como no se sabe cuando llegará esta información, “calibrationState” informa de ello a “doCalibration”. Mientras “calibrationState” tiene un valor de 0, la calibración permanece inactiva. Al pulsar el boton

Calibrar del programa, esta variable pasa a tener un valor de 1, y se dibuja el primer punto de calibración. Una vez se ha recibido la información del mando de ese punto, se pone un valor de 2 a “calibrationState”, y asi sucesivamente hasta llegar al valor de 5, que es

cuando se informa de que todos los datos han sido recibidos y se envian a la subrutina Warper1 y Warper2.

El código que se encuentra dentro de la rutina de atención a la interrupción se encuentra referenciado como Código 3 en el apartado 13.2 Código desarrollado durante el

proceso de creación del programa incluido en el Anexo.

En la entrada de la rutina de atención a la interrupción (RSI) se comprueba siempre cual de los dos mandos la ha provocado. Las variables booleanas “mando1” y “mando2”

nos indican en el resto del código que mando ha generado la interrupción. Dentro de la calibración, se comprueba que mando nos ha enviado la información y la almacenamos en las diferentes matrices creadas con ese objetivo, tal como se hizo con los puntos de la función “doCalibration”. Las variables “x1” e “y1” contienen la información enviada por

el mando 1 de la posición del punto leido. Las variables “x2” e “y2” hacen lo mismo con la

información del mando 2. Estas variables se actualizan al principio de la RSI, gracias a la linea de código siguiente:

x1=MultipleWiimoteForm.mWC[0].WiimoteState.IRState.IRSensors[0].Raw

Position.X;

Código 4. Lectura de la posición X del punto infrarrojo 1 en el mando 1

Page 34: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

34

Desglosemos esta línea de código: “MultipleWiimoteForm” indica que la

información que vamos a consultar se encuentra en el ese formulario. “mWC[0]” significa

que consultamos la información del primer mando. Si fuera mWC[1], estaríamos mirando la información del segundo mando. “WiimoteState.IRState.IRSensor[0]” indica que

comprobamos la información del primer punto visto por el mando. Si hubiera dos puntos en la superficie, cogeríamos las coordenadas del primer punto que viera el mando, el que se almacenara en la posición 0 de 3. Durante el desarrollo de este programa solo tenemos en cuenta este punto, ya que no debería haber más punteros en la superficie de proyección. Si los hubiera, imperaría la posición del que se hubiera encendido primero. Por último, “RawPosition.X”, indica al programa que coja la posición X del punto recibido, teniendo

en cuenta que el máximo es 1024. Todas las funciones aplicadas en esta línea de código vienen implementadas en la librería “WiimoteLib”.

Una vez hemos almacenado la información enviada por el mando, utilizamos dos variables globales de tipo boleano para conocer cuando se ha recibido la información de los dos mandos para ese punto. Estas variables son “calibra1” y “calibra2”. Cuando las dos

se ponen a “true”, significa que hemos almacenado la posición de ese punto para los dos

mandos, y que podemos pasar al punto siguiente. Se actualiza el valor de “calibrationState”

y se actualizan los dos boleanos a valor “false” para utilizarlos en el siguiente punto de calibración. Con el nuevo valor de “calibrationState” se llama a la función “doCalibration”

para que pinte sobre la pantalla el nuevo punto.

Siguiendo este proceso, obtenemos las diferentes matrices que componen la información de las coordenadas X e Y de las cuatro esquinas, tanto para el mando como para la pantalla. Esta información se almacena en la subrutina Warper1 y Warper2, las cuales serán llamadas cada vez que recibamos unas coordenadas nuevas de alguno de los dos mandos. A estas funciones les introduciremos las coordenadas que ha enviado el mando, y devolverán la posición a la que hay que enviar el cursor del mouse del ordenador.

Se dispone de dos funciones adicionales relacionadas con la calibración: “saveCalibrationData( )” y “loadCalibrationData( )”. Estas funciones se encargan

respectivamente de almacenar los datos de calibración en un fichero y recuperarlos al abrir el programa de nuevo. Si la instalación del Wiimote es fija, no será necesario calibrarlo cada vez que se abra el programa. La última calibración realizada se cargará por defecto y no será necesario calibrar de nuevo antes de utilizar la pizarra digital. Ya se podrá comenzar a utilizar directamente.

8.3 Selección del punto al que enviar el cursor

Una vez se ha calibrado, ya se dispone de las coordenadas a las que enviar el puntero del mouse, pero nos encontramos un problema al hacerlo: disponemos de dos coordenadas diferentes. Tanto el mando 1 como el mando 2 nos ofrecen coordenadas distintas a las que enviar el cursor, siempre que los dos mandos vean el puntero IR. Estas coordenadas son muy próximas si se ha calibrado correctamente, pero siempre tienen una pequeña desviación entre ellas. Esta desviación provoca que el puntero vaya de una posición y otra, y por tanto hace que el trazo presente una leve vibración. Se tendrá que implementar una correcta selección de las coordenadas para evitar lo máximo posible la aparición de este efecto.

Como primera solución pensé en coger las coordenadas del mando que utilizara una zona de visión mayor para posicionar el puntero, y dejar el otro mando únicamente para las ocasiones en que el mando principal no viera el puntero. Para hacer esto, al final de la

Page 35: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

35

calibración se llama a la función “UpdateTrackingUtilization”, tanto para el mando 1 como para el mando 2. Esta función realiza una división entre el área de proyección que ve la cámara y el área ideal, que es constante. El resultado es el porcentaje de utilización de la visión total de la cámara. De esta manera se puede discriminar que mando tendrá una resolución mayor.

Esta primera solución no ofreció resultados correctos. El puntero tardaba mucho en moverse, ya que desechaba la mitad de los puntos que llegaban. Cuando los dos mandos ven el puntero IR, emiten interrupciones cada 100 ms con la última posición detecta. Este es el tiempo de muestreo de cada mando. Cuando un mando ejecuta la RSI, todas las peticiones de interrupción que llegan se desestiman. Al aplicar esta solución, cuando el mando con peor tracking entraba en la RSI, su información se desestimaba, y durante el tiempo que la RSI estaba en ejecución se desestimaban las peticiones de interrupción del mando principal, con lo que el puntero se movía lentamente

Había que coger la información enviada por los dos mandos para evitar ese efecto de lentitud. La siguiente implementación aplicada fue realizar la media de las coordenadas enviadas por los mandos, siempre después del tratamiento de la función Warper. El resultado fue que si los mandos no utilizaban un área de visión de la cámara mayor al 50%, el posicionamiento no funcionaba. El ratón se volvía errático y se aproximaban sus posiciones mediante líneas, con lo que resultaba muy difícil realizar una escritura natural. El problema estaba en la diferencia que había entre las coordenadas enviadas por un mando y por otro. La posición del cursor se encontraba a una distancia considerable de la posición del puntero IR. Y era peor cuando un mando dejaba de ver y luego volvían a ver los dos. En ese caso se producía un salto de posición muy grande que impedía una correcta escritura a mano. Este efecto se acusaba mas cuanto más diferencia había entre la utilización de la cámara de un mando y de otro, porque la diferencia de coordenadas entre los dos mandos era cada vez mayor. Por tanto, comprobé que este método solo se podía aplicar teniendo la certeza previamente de que la diferencia entre las coordenadas enviadas por el mando 1 y por el mando 2 era muy pequeña.

No se pueden descartar completamente los puntos de uno de los dos mandos si se quiere obtener una velocidad de movimiento del puntero rápida. Tampoco se puede realizar la media de las coordenadas enviadas por los mandos sin comprobar antes que la diferencia de coordenadas entre mandos es muy pequeña. Como solución posible, habrá que implementar un algoritmo que detecte en qué momento la posición del puntero para un mando es muy próxima a la posición del puntero para el otro mando para realizar la media en ese punto. En caso de que estas coordenadas no sean cercanas, se cogerán los puntos de del mando con mayor utilización del área de visión, y se descartaran los del otro mando. Se trataría de juntar las dos opciones probadas anteriormente. Después de diferentes pruebas se comprobó sobre la pantalla del ordenador, que cuando la diferencia entre WarpedX1 y WarpedX2 (que son las posiciones enviadas por el mando 1 y mando después de ejecutar la subrutina Warper) es menor a 50, y de igual manera con WarpedY1 y Warped Y2, se podía realizar la media entre los puntos obteniendo una posición correcta. Aplicando esta media cogemos los puntos de los dos mandos y por tanto el movimiento del cursor es más rápido, debido a las causas explicadas anteriormente. En caso de que la diferencia fuera mayor a 50, no se puede aplicar la media porque los puntos son muy distantes entre ellos, y se eligen los del mando que mas visión utiliza. Esta implementación ofrece unos resultados mucho más buenos que todas las anteriores, permitiendo realizar una escritura a mano bastante fluida. Aun así, detectamos pequeños saltos en la escritura.

Page 36: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

36

Después de analizar la causa de esos saltos, llegamos a la conclusión de que se crean en el momento en que se tapa un mando y luego se destapa. Este efecto se debe a que se pasa de coger la posición media a coger la posición enviada por el único mando que ve, lo que crea un cambio de coordenadas brusco. Este salto se detecta sobre todo cuando no estamos realizando la media de las coordenadas. Si por ejemplo el mando que mejor visión tiene es el 1, y cogemos todos los puntos de este, al taparlo pasamos a coger las posiciones del mando 2, habiendo una diferencia de coordenadas entre ellos que crean el salto. Al volver a ver los dos mandos, volvemos a coger la información enviada por el mando 1, lo que crea otro salto de coordenadas. Para evitar ese efecto creamos una nueva implementación que suavice el salto. El salto producido cuando el mando 1 deja de ver es inevitable, ya que tendremos que coger las coordenadas del único mando que ve. El que si que es evitable es el salto que se produce cuando vuelven a ver los dos mandos. Podemos seguir recibiendo las coordenadas del mando que nos enviaba la información antes, con lo que no se producirá ningún salto. Cuando la diferencia entre los puntos enviados por los dos mandos sea inferior a 50, que pasaremos a coger la media de los dos. Obtenemos como resultado que los saltos que se producían antes ya no se producen. Durante la realización de estas últimas pruebas se detecta otro error. Como he indicado anteriormente, la media se hace cuando la diferencia entre los puntos de los dos mandos es inferior a 50. Una vez se entra a realizar la media, no se vuelve a comprobar la diferencia entre puntos, sino que se hace siempre la media. Si uno de los dos mandos tuviera una utilización de cámara muy baja, la diferencia entre las coordenadas de los dos mandos en las esquinas de la proyección sería muy grande. Para evitar este efecto se realiza una comprobación del nivel de utilización de la cámara de los dos mandos antes de hacer la media. Si esta utilización es muy baja para alguno de los mandos, no se hace la media y se coge el punto enviado por el otro mando. Si los dos mandos tienen unos valores de utilización muy bajos, se comprobaría que mando nos había enviado la posición antes y seria el que la enviara ahora, siguiendo la última implementación aplicada para evitar saltos.

Finalmente, obtenemos una implementación que ofrece unos resultados muy buenos en cuanto a precisión de la posición y continuidad del trazo en caso de escritura a mano. El código aplicado se encuentra referenciado como Código 5 en el apartado 13.2 Código

desarrollado durante el proceso de creación del programa incluido en el Anexo.

Primero se comprueba si solo ve el puntero uno de los mandos, mediante las variables vis1 y vis2, las cuales indican si el mando 1 o el mando 2 ven el puntero IR. Si uno de los dos no ve, no es necesario seguir ejecutando código, se elije la posición enviada por el mando que está viendo y se actualiza el valor de la variable “vis_antes”. Esta

variable indica que mando nos estaba enviando las coordenadas anteriormente. Se sigue cogiendo la información de ese mando y evitar el salto de posición cuando los dos mandos vuelvan a ver el puntero IR.

En caso de que los dos mandos vean, se entra a seleccionar las coordenadas a las que enviar el puntero del mouse. El primer if comprueba la diferencia entre los puntos del mando 1 y del mando 2. Si es menor a 50 entra. Los dos siguientes if que se encuentran dentro comprueban si uno de los mandos tiene una utilización de cámara inferior al 30 %. Si es asi, se descartan los puntos de ese mando. En caso de que los dos mandos tengan una utilización superior al 30 %, tanto el punto X como el punto Y serán la media de las coordenadas enviadas por los dos mandos. Finalmente, siempre que se entra a este trozo de código se pone la variable “vis_antes” a 0. Como ya hemos aplicado la media, la

información del mando que había enviado las coordenadas anteriormente no nos es necesaria. Al poner esta variable a 0, aseguramos que en las próximas entradas se seguirá

Page 37: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

37

haciendo la media, para evitar saltos de posición, siempre que los dos mandos tengan una utilización de cámara mayor al 30 %.

Este trozo de código se encuentra dentro de la rutina de atención a las interrupciones que generan los mandos. Por este motivo, en cada if se comprueba el mando que ha generado la interrupción. Si se quisiera coger la información del mando 1 y el que hubiera generado la interrupción fuera el mando 2, no habría que enviar una coordenada nueva al mouse, la información enviada por el mando 2 no se utilizaría.

Las pruebas realizadas con este código sobre la pantalla del ordenador dieron resultados positivos. Pero al probar en un aula real, sobre una imagen proyectada en una pantalla de gran tamaño, los resultados no fueron tan convincentes. Después de realizar diversas comprobaciones, llegue a la conclusión de que este sistema de posicionamiento se mostraba eficaz cuando los mandos se encontraban alejados de la superficie a proyectar. Si los mandos se encontraban muy próximos se producían muchos saltos seguidos entre que los dos mandos vieran el puntero IR y que solo lo viera uno de ellos. La persona que escribe se pone delante de ellos y los tapa con el movimiento de su mano. En cambio, cuando los mandos se encuentran alejados, la persona que escribe sobre la proyección no los tapa tan frecuentemente y este método de posicionamiento funciona correctamente. El problema reside en que al cambiar de ver los dos mandos a que solo vea uno, no se puede asegurar que el mando que queda tapado es el que antes no teníamos en cuenta, por lo que se producen saltos continuamente. Podría darse el caso de que en un aula, por problemas de espacio hubiera que colocar los mandos muy cerca de la proyección. Por este motivo decidí crear una implementación nueva que solucionara este problema, y dejar al usuario la posibilidad de elegir el tipo de posicionamiento, según la distancia a la que colocara el mando.

El problema es que no sabemos qué mando va a ser tapado. Para solucionarlo, tomo como aproximación que se tapara el mando más alejado, ya que será siempre el que tenga una peor visibilidad. Divido la superficie de proyección en dos partes. Las coordenadas de los puntos que se encuentren en la parte izquierda de la proyección serán enviadas por el mando 1 siempre, y de igual manera con las coordenadas de la parte derecha, que serán enviadas por el mando 2. Suponemos que cuando escribo en la parte izquierda de la pizarra, al tener el mando 1 más próximo, generalmente tape al mando 2. Siguiendo este concepto, como cuando los dos mandos veían, el que enviaba las coordenadas de esos puntos era el mando 1, si tapo el mando 2 no habrá salto alguno y el trazo será más fluido. El punto crítico será la mitad de la pizarra, en la que paso de coger las coordenadas enviadas por el mando 1 a coger las que envía el mando 2. En esta transición se pueden provocar saltos del cursor. Para solucionar este defecto, no se pasa directamente a coger los puntos de un mando o de otro a mitad de proyección, sino que creo una zona de transición donde se cogen los puntos medios de los dos mandos, para suavizar la transición entre mandos. En esa zona el código será igual que el comentado anteriormente. Si la diferencia entre los puntos del mando 1 y del mando 2 es menor a 15, se coge la media de los puntos. Sino, se coge la información del mando que antes veía el puntero IR.

El código resultante se encuentra referenciado como Código 6 en el apartado 13.2

Código desarrollado durante el proceso de creación del programa incluido en el Anexo.

Si la posición máxima en el eje X es 1024, la mitad de la proyección será la coordenada X=512. Establecemos un margen de 50 puntos tanto a derecha como a izquierda, dejando como zona de transición de la posición 500 a la 600. Para todas las posiciones que queden a la izquierda de la proyección se tendrán en cuenta únicamente las

Page 38: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

38

coordenadas que envía el mando 1. Para las posiciones que queden a la derecha se tendrán en cuenta las coordenadas enviadas por el mando 2. En caso de que hubiera algún punto que no entrara dentro de la secuencia de if especificada, se tendrían en cuenta las coordenadas del mando que utilizara una zona de visión mayor. Se implementa el último else para evitar errores a causa de que la posición en la que estemos no reciba tratamiento por el código implementado antes del else. Lo pongo para tener una seguridad adicional de que no perderemos información de coordenadas que nos podría ser útil.

Con esta implementación, el cursor pierde velocidad de movimiento, pero los saltos son menos acusados, con lo que se puede escribir de una manera mucho más fluida. Mediante dos botones de selección de tipo “radioButton” el usuario podrá elegir qué tipo

de posicionamiento prefiere, según la distancia a la que coloque los mandos respecto la proyección.

Con la aplicación de estos dos códigos en nuestra aplicación, disponemos de una solución de posicionamiento del cursor muy buena para todas las situaciones en las que se pueda encontrar el usuario habitual de este sistema. Finalmente, obtenemos una escritura en la que el trazo se presenta bastante fluido, y las letras escritas se pueden comprender fácilmente.

8.4 Selección de la función que realiza el cursor según el estado del puntero IR

Este fue el apartado del proyecto que más tiempo de desarrollo necesitó. Sin una buena selección de que código ejecutar en función del estado del puntero IR, ninguna de las partes del programa funcionaria correctamente. No se podría ni calibrar, ya que el código referente a calibración se encuentra dentro de esta selección. Sin una buena identificación de que hay que hacer según el estado del puntero, no se podría desplazar el puntero sobre la proyección. Este apartado es crítico para el correcto funcionamiento de todo el proyecto. También fue el que más errores presentó hasta llegar a funcionar correctamente.

Para entender porque hay que hacer diferentes funciones, tenemos que pensar en un programa de dibujo genérico, como por ejemplo “Paint”, el cual viene integrado en todas

las distribuciones del SO Windows®. Para poder pintar sobre una superficie en blanco, el usuario debe pulsar el botón izquierdo de su mouse y desplazarse por la superficie. Al desplazarse va dibujando un trazo por las zonas por las que mueve el cursor del mouse. Cuando quiere dejar de dibujar suelta el botón izquierdo del mouse. Este es el comportamiento que se quiere imitar en el programa, ya que su mayor funcionalidad será la de permitir la escritura manual sobre la pantalla del ordenador. Como no se dispone de múltiples botones en el puntero IR que informen al ordenador de la acción que quiere realizar el usuario, hemos de utilizar las diferentes transiciones del led para clonar la acción que un usuario haría con su mouse tradicional.

El puntero IR puede presentar 3 estados diferentes: encendido del led infrarrojo, led infrarrojo mantenido en ON y apagado del led. Tendremos que tratar cada estado de forma diferente en nuestro software, ya que el comportamiento del cursor del mouse dependerá del estado del led IR. El encendido del led se produce cuando en el muestreo anterior el led estaba apagado, y en el muestreo actual esta encendido. El estado en el que el led se mantiene en ON ocurre cuando en el muestreo anterior el led estaba emitiendo infrarrojos y en el actual permanece emitiendo luz IR. Por último, el apagado del led ocurre cuando en el muestreo anterior el led estaba emitiendo y en el actual no se recibe ninguna emisión.

Page 39: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

39

No se trata el estado en el que el led permanece apagado, porque en este programa ese estado no tiene que realizar ninguna modificación, y por tanto no le afecta.

En el cambio de apagado a encendido del led IR, tenemos que detectar la nueva posición y enviar el cursor ahí. 10 ms después de enviar el cursor a la nueva posición se realiza la misma función que si el usuario apretara el botón izquierdo del ratón y lo mantuviera apretado. Se hace un clic sobre el punto en el que hayamos puesto el puntero IR. En caso de que estemos calibrando la pizarra, solo se tiene que leer la transición de apagado a encendido, ya que en caso de que permanezca encendido no se debe detectar como la posición de un punto nuevo. Solo se deben detectar coordenadas nuevas cuando el led pasa de apagado a encendido. Sino, como el programa es mucho más rápido que la persona encendiendo y apagando el led, se almacenarían las mismas coordenadas para los cuatro puntos antes de que le diera tiempo al usuario de desconectar el puntero IR.

En el segundo estado, el led antes estaba encendido y ahora también. En el primer estado ya se ha realizado la acción de clic, y se mantiene el botón izquierdo del mouse apretado. En este estado lo único que se hace es arrastrar el mouse por la zona que deseemos. Con este comportamiento conseguiremos escribir a mano sobre cualquier programa de dibujo, ya que lo que hacemos es arrastrar el cursor mientras lo mantenemos clicado. Esta acción, en cualquier programa de dibujo, pintara un trazo por los lugares por los que movamos el puntero IR.

Finalmente, en el tercer estado el led pasa de encendido a apagado. Debemos interpretar esta acción como que el usuario ha concluido de escribir y quiere cambiar de posición. Para posibilitarlo, hay que dejar de simular que se aprieta el botón izquierdo del mouse.

Para conseguir realizar las funciones del mouse hay que engañar al sistema operativo para qué crea que todas esas acciones las está realizando el usuario con su ratón físico. Se utiliza una librería de Windows®, que es la misma que utiliza el mouse para que el sistema operativo pueda interpretar la información que envía. Por tanto, desde el sistema operativo, se recibe una información que para él es provocada por un hardware externo. Para poder imitar este hardware externo se programan unos buffers con la diferente información que envía el mouse real en caso de que él hiciera todas las acciones descritas anteriormente. Estos buffers se envían con el comando “SendInput”, con lo que el sistema operativo los

interpretan como si un hardware externo fuera, y hace las acciones programas por nosotros anteriormente. Así conseguimos controlar las funciones que realiza el cursor del ordenador en cada estado y modificarlas según las diferentes necesidades.

La diferenciación de estados y el código asociado a cada estado se encuentra dentro de la rutina de atención a la interrupción, ya que es el lugar donde nos llega la información actualizada sobre el estado del puntero IR. Las acciones de control del mouse se deben realizar inmediatamente después de recibir la información del estado del puntero, ya que si hubiera retraso podría darse el caso de pintar en un lugar no deseado. Por tanto, esta diferenciación de estado es la primera acción a realizar después de identificar que mando ha generado la interrupción.

Realizar esta tarea con un solo mando resulta sencillo, ya que ese mando es el que te provoca la interrupción, y por tanto solo tienes que controlar el estado actual y anterior del puntero IR que envía el mando. Para controlar el estado anterior se utiliza la variable “lastWiiState”, la cual almacena toda la información enviada por el mando en la última interrupción recibida. Esta variable actualiza su contenido al final de la rutina de atención a

Page 40: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

40

la interrupción en curso, con lo que al recibir una nueva interrupción siempre se mantiene la información de la anterior interrupción recibida.

Al introducir dos mandos la tarea se complica enormemente, ya que cualquiera de los dos puede ver el puntero IR, o puede que solo lo vea uno. Los dos mandos pueden generar la interrupción, pero solo se controla un puntero IR. Habrá que establecer un sistema de detección de estado correcto para que se ejecute la función deseada independientemente del mando que genere la interrupción.

Esta tarea es muy compleja, porqué se puede dar el caso de que un mando vea el encendido del led IR y el otro no, y mientras se utiliza el puntero, el mando que veía el led deje de verlo, y el que no lo veía pase a verlo. En ese caso, se debe de interpretar que antes se veía el led en el otro mando y seguir arrastrándolo. No se deberían realizar las acciones descritas para cuando el led está apagado y se enciende. Pero para el último mando, antes no había led y ahora sí, con lo que para él el led se ha encendido. Por tanto, hay que programar un correcto sistema para que la transición entre los mandos no afecte a las funciones del mouse.

El primer problema que tuvimos relacionado con este aspecto apareció muy pronto. Nada más empezar el desarrollo del programa, después de realizar la programación del sistema de calibración para los dos mandos y comprobar que el código fuera correcto, esta no funcionaba. Aislé las partes más problemáticas, dejando únicamente el código necesario para que la calibración funcionara y comprobando que este estuviera escrito correctamente. Seguía ocurriendo lo mismo. Por tanto, el problema residía en que nunca se llegaba a ese trozo de código. Hay dos condiciones para llegar a captar los datos de calibración del primer punto. La primera condición es que “calibrationState” debe estar a 0. Puse un

cuadro de texto para comprobar el estado de esta variable y resultó ser 0. El problema no provenía de esa condición. La condición anterior a esa era que nos encontráramos en la transición de no ver emisión IR a verla. Por tanto, el problema residía en esa línea de código:

if (!(lastWiiState.IRState.IRSensors[0].Found))

Código 7. Condición a cumplir para realizar un clic (no funcional con 2 mandos).

Con esta línea de código indicamos que se ejecute el código que hay dentro del “if”

siempre que en la última entrada a la rutina de atención a la interrupción, la cámara del mando no encontrara ningún punto IR.

En esa línea, solo se comprobaba que el mando 1 antes no viera nada y ahora sí que viera un punto. Lo que viera el mando 2 antes no se tenía en cuenta porque la variable “lastWiiState” estaba asociada al mando 1. Esto provocaba que cuando el mando 1 creara la interrupción sí que funcionara y se almacenara la información de calibración. Pero cuando entraba el mando 2, no se tenía en cuenta el estado anterior de este mando, sino que solo se miraba el estado anterior del mando 1. Como el último estado del mando 1 es que había visto el punto IR, no se almacenaba la información enviada por este mando. Como en el código de calibración implementé que no pasara de punto hasta tener la información de los dos mandos, nunca se pasaba de punto.

Para solucionarlo, decidí duplicar la variable “lastWiiState”, obteniendo como resultado dos variables diferentes, “lastWiiState1” y “lastWiiState2”. El funcionamiento es

el mismo que el que hacían hasta ahora, pero cada una asociada a su respectivo mando. De esta manera almacenamos toda la información enviada por los dos mandos la última vez

Page 41: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

41

que cada uno de ellos provocara la interrupción. Cambio la anterior línea de código por la que figura a continuación:

if(!(lastWiiState1.IRState.IRSensors[0].Found))||!(lastWiiState2.IRState.IRSensors[0].Found))

Código 8. Nueva condición a cumplir para realizar un clic

Con esta nueva línea de código, sí que se tiene en cuenta la información del mando 2. Siempre que uno de los dos antes no viera ninguna emisión IR, se ejecuta el código de dentro del “if”. Ejecuto el programa y compruebo que funciona, aunque tarda un poco en realizar el cambio de un punto a otro. Después de analizar la línea de código detenidamente detecto que me provoca ese retardo. Las variables “lastWiiState” 1 y 2 almacenan la información de la última vez que sus respectivos mandos han entrado. Hasta que no entran los dos mandos no se actualizan las dos variables. Como ya hemos explicado anteriormente, el funcionamiento del programa no es secuencial. Es decir, no entra primero el mando 1 a la RSI y luego el mando 2. Entra el que primero haga una petición cuando estas no están inhibidas, es decir, cuando acaba la ejecución de la RSI. El problema residía en que si primero entraba el mando 1, se actualizaba la información de “lastWiiState1” a

“true” y “lastWiiState2” permanecía en “false”. Si al acabar de ejecutar la RSI, la primera

petición de interrupción era del mando 1, este volvía a entrar. Al llegar al “if”, una de las

condiciones se cumplía ya que “lastWiiState2” permanece en “false” hasta que entre el mando 2 y se volvía a entrar al if aunque fuera el mando 1 el que había creado la interrupción. La información del mando 1 se iba actualizando constantemente si el mando 1 era el que había generado la interrupción. Este error seria más grave aun si no se comprobara que mando ha generado la interrupción en el momento que guardamos los datos de calibración. En ese caso, podría almacenarse la información del mando 1 como si fuera la del mando 2, ya que el mando 1 habría entrado dos veces a guardar su información en el almacenamiento de datos de calibración.

Para solucionar ese defecto, comprobamos que mando ha generado la interrupción y si antes no había detectado luz infrarroja y ahora sí. La línea de código es la siguiente: if ((mando1 && !(lastWiiState1.IRState.IRSensors[0].Found)) || (mando2 &&

!(lastWiiState2.IRState.IRSensors[0].Found)))

Código 9. Condición a cumplir para realizar un clic, mas restrictiva que la anterior.

Con esta línea indico que si es el mando 1 el que ha generado la interrupción, se compruebe el estado anterior de este mando; y si es el mando 2 se compruebe el estado anterior únicamente de ese mando. Así evitamos entrar al “if” en situaciones no deseadas.

Con esa última línea aplicada, la calibración del programa ya funciona correctamente. Adquiere todos los puntos y posiciona el mouse correctamente allá donde el usuario quiere que vaya.

He mostrado todo el rato la línea que indica al programa cuando tiene que hacer clic, pero es igual de importante la parte de código en la que se indica cuando se debe de dejar de hacer clic. Es en ese trozo de código donde indicamos a “lastWiiState” que actualice su

valor a “false”, ya que si se entra en esa parte de código el mando ha pasado de ver emisión IR a no verla. Si no se modificara el estado de “lastWiiState” correctamente, la calibración no funcionaría porque las condiciones del “if” no se cumplirían cuando se esperaría que lo hicieran.

Page 42: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

42

El código que muestra como queda la secuencia de “if” se encuentra referenciado como Código 10 en el apartado 13.2 Código desarrollado durante el proceso de creación

del programa incluido en el Anexo.

La primera condición comprueba que mando ha generado la interrupción, y si ese mando actualmente ve algun punto IR. Si lo ve, comprueba si antes lo veía o no. Si actualmente no viera ningun punto IR, pasa directamente a comprobar si antes si que lo veia. En el caso de que antes no viera punto IR y ahora tampoco, no implementamos niguna acción porque para este proyecto ese estado no tiene que afectar al ordenador.

Por tanto si, en el instante en que se comprueba, el mando que genera la interrupción ve una emisión IR se pasa a comprobar si antes la veía o no. Si antes no la veía, es un punto nuevo, y entonces se actualiza la información de lastWiiState para asegurarse de que el campo que indica si se ve un punto IR cambia de valor a “true”.

Si antes ya se había detectado un punto IR, la función de mantener el botón izquierdo del ratón pulsado ya se ha ejecutado (esta función es simulada por el programa), con lo que el programa unicamente tiene que mover el cursor por las zonas por las que se mueva el puntero IR. Esta función es la que se hace dentro del “else if” en el que pone comentado arrastre del cursor.

En el caso de que actualmente no se vea emision IR, puede ser que antes sí que la hubiera y tengamos que soltar el boton derecho del raton. Para saberlo, se comprueba el estado de “lastWiiState”. Si tiene un valor de “true” es que antes se había recibido emisión IR. Lo que hay que hacer en este caso es actualizar el valor de “lastWiiState” a false, ya

que ahora no se recibe el punto IR. Addicionalmente, también hay que indicar al sistema operativo que deje de mantener el cursor del ratón en estado de clic.

Al principio, aparentemente el código implementado de esa manera funcionaba correctamente, con lo que me dediqué a realizar funciones nuevas o mejorar algunas de las que había. Durante la realización de esas mejoras incluí una barra en la parte superior del programa con multiples pestañas que realizan diversas funciones. Al clicar encima de esas pestañas, detecté que en el caso de que se tuviera que abrir una ventana, en vez de abrirse una se abrian siempre dos como mínimo. En un principio pensé que se debia a una mala programación de la barra. Después de pasar unos días probando diversas opciones, llegué a la conclusión de que no se debía a la barra, sinó a la función que hacía el ratón. Si tapaba uno de los dos mandos, solo se abría una ventana al clicar; pero si los dos mandos veian el puntero, se abrían dos ventanas. El problema tenía que residir en la programación de las condiciones anteriores.

El problema residia en que se miraban las dos condiciones por separado. Si el primer mando que entraba a la RSI era el mando 1, y antes no veía el punto IR y ahora sí, entraba en la función de hacer un clic. Acto seguido, si el mando 2 era el que generaba la información, y este antes no veía y ahora sí, también entraba a la función de hacer un clic nuevamente. El resultado final es que cada vez que los dos mandos pasaban del estado de no ver a ver, generaban cada uno un clic, obteniendo un doble clic no deseado. Este problema era provocado por mirar las condiciones de los mandos por separado. El programa no podía reconocer si uno de los dos mandos ya había hecho el clic antes, para no repetirlo. Para solucionarlo, incluí una variable más en las condiciones del if que compruebe si se ha hecho clic anteriormente. Esta variable recibe el nombre de “click_antes”. El código resultante se encuentra referenciado como Código 11 en el apartado 13.2 Código desarrollado durante el proceso de creación del programa incluido en el Anexo.

Page 43: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

43

Con este código, cuando un mando realizaba la acción de clicar, la variable booleana “click_antes” actualizaba su valor a “true”, impidiendo que el otro mando que no había

entrado en la RSI hiciera un clic de nuevo cuando entrase. Al probar esta implementación el fallo se mantiene. El problema reside en el lugar de código donde se actualiza el valor de “click_antes” a “false”. En el trozo de código anterior, este valor se actualiza en el

momento que un mando veía punto IR antes y ahora ve. Como he explicado en ocasiones anteriores, la ejecución de la interrupción se realiza de manera aleatoria, sin seguir un orden entre mando 1 y mando 2. El mismo mando que ha realizado la acción de clic puede entrar dos veces seguidas en la RSI. Cuando ocurre, como ese mando ha actualizado su valor de “lastWiiState” al hacer el clic, entra en el estado en el que antes se veía puntero IR y ahora también. En ese estado es donde se actualiza “click_antes” a “false”, con lo que

cuando entra el otro mando se vuelve a realizar la acción de clic, y el resultado es el mismo. Se debería actualizar el valor de “click_antes” en el ultimo estado, cuando el

mando antes veía punto IR y ahora no. Pero de ser así, uno de los mandos nunca entraría en la primera condición y no se actualizaría nunca su variable “lastWiiState”, ya que la

actualización de esta variable reside en el código que se ejecuta en la primera condición.

Cambio el código de nuevo, y en vez de utilizar una variable que indique si ya se ha realizado anteriormente el clic, introduzco un “if” que compruebe si las variables

“lastWiiState1” y “lastWiiState2” tienen ambas un valor de “false”. Si es así, realizo la

acción de clic. Si una de ellas no tiene valor “false”, es que ya he realizado el clic antes y

ahora no lo tengo que hacer. El resto de código anterior permanece inalterado. Solo se modifica la condición de hacer el clic. El código que aplico dentro de la primera condición se encuentra referenciado como Código 12 en el apartado 13.2 Código desarrollado

durante el proceso de creación del programa incluido en el Anexo.

Con este nuevo código me aseguro que se realiza la acción de clic únicamente una vez. Después de probarlo compruebo que no da el mismo fallo pero el cursor realiza clics indeseados cuando un solo mando se tapa y destapa.

Después de cercionarme de que el fallo no residía en la realización del clic, llego a la conclusión de que tiene que encontrarse en el punto en el que se deja de hacer clic. El problema consistía en que cuando uno de los dos mandos dejaba de ver el puntero infrarrojo, ambas variables “lastWiiState” actualizaban su valor a “false”. Por tanto, si en

la siguiente iteración entraba el mando que veía el puntero IR, se volvía a realizar la acción de clic porque se cumplía la condición de que ambas variables “lastWiiState” tenían un

valor “false”.

La solución que apliqué fue cambiar las condiciones de acceso a este estado. En vez de comprobar si el mando que ha entrado en al RSI actualmente no ve punto IR, se comprueba si los dos mandos no ven puntero IR. Si alguno de los dos sí que lo ve, no hay que realizar la acción de soltar el clic. Para poder hacer esto, declaro dos variables boleanas globales que indican si cada uno de los mandos ve algún punto IR. Estas variables reciben el nombre de “vis1” y “vis2”. Con la ayuda de estas variables se almacena la última información recibida sobre si cada uno de los mandos ve punto IR y se mantiene durante las diferentes llamadas a la RSI. Según el mando que haya entrado, se actualizará una variable o la otra. Por tanto, para dejar de clicar solo se ha de comprobar si actualmente ambas, “vis1” y “vis2”, contienen el valor “false”. Si es así, se actualiza la información de “lastWiiState” de ambos mandos a “false” y se deja de clicar. En caso

contrario no se realiza ninguna acción. La actualización de la información que contienen estas variables genera diversos problemas que serán comentados en el apartado 8.4.1

Actualización de las variables “vis1” y “vis2”.

Page 44: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

44

Finalmente, el código completo relacionado con la selección de función según el estado del puntero IR se puede encontrar dentro del código fuente del archivo MultipleWiimoteForm.cs, el cual se encuentra descrito en el apartado 13.3 Código fuente

del programa final incluido en el Anexo.

Todos los datos con el formato “buffer[X].xx = x;” se utilizan para simular el

comportamiento del mouse. El programa envía un buffer programado con los mismos datos que envía el hardware del mouse físico. En el apartado 8.5 Funciones Adicionales, incluido en esta memoria, se tratarán las diversas funciones que puede realizar el cursor del ratón, según la información que se programe en el buffer.

8.4.1 Actualización de las variables “vis1” y “vis2”

Es muy importante mantener correctamente actualizado el valor de estas variables para que se pueda discernir en qué momento los dos mandos no ven punto IR. El problema que encuentro, es que solo se actualiza una variable cada vez que se entra en la RSI, ya que solo puede entrar un mando en la RSI. Por tanto, en una de las dos variables habrá siempre información que no será actual, sino que será la información de la última vez que entro el mando asociado a esa variable. La RSI se ejecuta a una velocidad elevada, con lo que el usuario no debería detectar el retardo ocasionado por la actualización de estas variables. En la práctica es así, como la RSI se ejecuta mucho más rápido que las acciones que hace el usuario, esta presenta un funcionamiento correcto y el usuario no percibe retardo alguno.

Pero hay un problema que se puede generar aleatoriamente y que el programa debe controlar. Si los dos mandos están viendo el punto IR, estos van generando peticiones de interrupción y actualizando la información. Si por ejemplo, el último mando que ha actualizado la información era el mando 1 y mientras se ejecutaba la RSI, el mando 2 deja de ver el punto IR, este nunca entrará a actualizar el valor de “vis2” a “false” porque dejara

de generar interrupciones. Esto puede provocar un fallo si el usuario dejara de utilizar el puntero en ese momento. “vis2” tendría un valor “true” y no se soltaría el clic. Para

solucionarlo, creé un sistema de detección que comprueba si un mismo mando ha entrado más de 10 veces seguidas en la interrupción. Después de realizar diversos tests, comprobé que si los dos mandos veían el puntero IR, uno de ellos nunca entraba a la RSI más de 10 veces consecutivas. Por lo tanto, cuando un mando entra más de 10 veces seguidas, significa que el otro mando no está viendo el puntero IR, y hay que actualizar el valor de la variable “vis” asociada a ese mando. También actualizamos el valor de la variable “lastWiiState” correspondiente a ese mando, ya que en este caso el mando lleva un rato sin

ver. El código implementado para poder realizar estas acciones se encuentra referenciado como Código 13 en el apartado 13.2 Código desarrollado durante el proceso de creación

del programa incluido en el Anexo.

Estas líneas de código se realizan al principio de la RSI, justo después de detectar el mando que ha entrado en la RSI. En ellas se leen los datos de posición enviadas por el mando, y si el mando está viendo puntero IR o no. Al final de los dos “if” encontramos las

variables “enter1” y “enter2”. Estas variables son de tipo global, y van sumando 1 al valor

que contenían cada vez que el mando entra a ejecutar la RSI. Cuando acumulan un valor mayor a 10, se entra dentro del “if”, en el cual se pone “vis1” o “vis2” a “false”. Dentro del

“if” también encontramos la variable “act_1” o “act_2”. Cuando esta variable se pone a

true indica, que en la parte de código donde actualizamos “lastWiiState” del mando que no

ve, se actualice el valor de esta a “false”. No se pone aquí directamente porque

“lastWiiState” puede ser utilizado o modificado durante la ejecución de la RSI. Como esta

Page 45: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

45

variable se actualiza al final de la interrupción, prefiero cambiar su valor ahí y no al principio del programa para evitar errores de interpretación del código.

Para que el sistema funcione, la clave está en el punto donde pongo las variables “enter1” y “enter2” a 0. Si cada vez que entro a la RSI se va sumando 1, y nunca pusiera su

valor a 0, el sistema no funcionaria. Estas variables se ponen a 0 cada vez que entra el mando contrario al que lo ha hecho la anterior vez. En la última línea del código que se realiza cuando entra el mando 2, podemos ver un “if” que indica que si el mando 2 ve

punto IR, ponga la variable “enter1” a 0. De esta manera, cada vez que entra el mando

contrario, se pone la variable a 0, y nunca llega a 10 a no ser que un mismo mando entre 10 veces seguidas.

De esta manera se puede asegurar que el valor de “vis1” y “vis2” se mantendrá actualizado correctamente, con una desviación de poco menos de 1 segundo, la cual no percibirá el usuario.

8.5 Funciones adicionales

Durante la realización de todas las pruebas que hago con el programa, echo en falta funciones de ratón adicionales, como pueden ser el doble clic o el clic derecho. Al intentar hacer doble clic sobre un icono con el puntero IR, el programa lo interpreta como clic y arrastre. A poco que el usuario mueva la mano al hacer el segundo clic con el puntero, ya se interpreta como un nuevo clic y arrastre. Para solucionarlo, decido programar estas funciones en el programa.

Para poder hacerlo, primero hay que examinar la información enviada por el programa cada vez que hacemos clic. Este análisis se lleva a cabo en el código que se encuentra referenciado como Código 14 en el apartado 13.2 Código desarrollado durante

el proceso de creación del programa incluido en el Anexo.

Este código se encuentra dentro de un if, porque el usuario puede decidir cuando quiere realizar las funciones de ratón y cuando no. Esta funcionalidad es útil en el momento de calibrar, ya que antes de entrar en la ventana de calibración el usuario puede ver la imagen que capta cada mando, y ajustarlos para que vean el máximo posible. Para hacer eso, se desactiva el control del ratón, para que este no se mueva durante el tiempo que el usuario comprueba la calibración.

El primer dato del buffer es el tipo de acción que ocurre. En este caso indicamos que es un envío de información desde el mouse. El segundo y tercer campo son la posición X e Y a las que queremos enviar el cursor. El campo “mouseData” indica si la información que se envía es estándar o hay información adicional. El campo más importante es “dwFlags”.

En este se indica la función que queremos que realice el programa. Las diferentes funciones que ponemos como texto, son macros que contienen un valor hexadecimal. Estas macros se definen al principio del programa. En el campo “time” indicamos el retraso con

el que queremos que se ejecute la acción desde que esta se envía. El valor que introducimos en este campo se multiplica por 10 milisegundos, obteniendo la espera total en milisegundos. El ultimo campo, “dwExtraInfo” contiene información adicional a la ya

explicada, en caso de que la haya. Va relacionado con “mouseData”. La función

“SendInput” envía los dos buffers al Sistema Operativo, para que este los gestione como

información enviada por el mouse.

Page 46: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

46

Para añadir funciones adicionales, podemos mantener la estructura del buffer intacta, modificando únicamente el campo “dwFlags”. En este campo introduciremos la función

que queremos realizar. Para detectar esa función, incluyo diversos botones en una ventana aparte. Al pulsar estos botones haremos la función indicada en el mismo. Hay 3 funciones: doble clic, clic derecho y arrastre del cursor sin mantenerlo clicado.

El doble clic, o el clic derecho se tienen que realizar en el mismo lugar donde actualmente está la función de hacer un solo clic. Para poder hacerlo, introduzco diversas variables boleanas que indicaran la función que queremos hacer. Estas reciben el nombre de “doble_click” y “click_der”. Para implementar el arrastre sin hacer clic también

necesitamos una variable boleana. Cuando esta tenga un valor “true”, no realizaremos la

acción de clicar. Llamo a esta variable “arrastre”.

No se puede enviar directamente un valor hexadecimal que indique doble clic al sistema operativo, ya que no existe. Para hacer un doble clic, el programa tiene que enviar dos clics seguidos. Cuando la variable “doble_click” presenta el valor “true”, se envía dos

veces seguidas el buffer que indica la acción de un clic. Así, el programa realiza un doble clic. Una vez hecho el doble clic, se actualiza el valor de la variable “doble_click” a

“false”, para que la siguiente vez que se entre en la RSI el funcionamiento del cursor sea clic izquierdo.

Para la realización de un clic derecho sí que existe un valor hexadecimal, que indica al sistema operativo que queremos realizar esa acción. Por lo tanto, para implementarla podemos reutilizar las funciones existentes para hacer un clic. Simplemente, antes de enviar el “dwFlag” pongo un “if” que comprueba si “click_der” tiene un valor “true” o

“false”. Si tiene valor “true”, indico en el campo “dwFlag” que quiero hacer un clic

derecho. También actualizo el valor de la variable “click_der” a “false”, para que la

siguiente vez que se ejecute la RSI no se sigan haciendo clics derechos. Si por el contrario su valor es “false”, el campo “dwFlag” se carga con la acción de clic normal.

El código que hay dentro de la primera condición se modifica, obteniendo el código que se encuentra referenciado como Código 15 en el apartado 13.2 Código desarrollado

durante el proceso de creación del programa incluido en el Anexo.

Se entra a realizar clic izquierdo o derecho siempre que arraste no este marcado y no se tenga que hacer un doble clic. Si arrastre esta marcado, en la primera condición no se realiza ninguna acción y se pasa directamente a la segunda, que ya esta programa para arrastrar el cursor. Si se realiza doble clic, se tiene que ir a la segunda parte de código donde se envia el buffer que realiza un clic dos veces seguidas.

Al enviar el buffer de clic con la información de que haga un clic derecho, el sistema operativo lo interpreta igual que si el usuario apretara el boton derecho de su mouse y lo mantuviera apretado. Igual que se hace con el clic izquierdo, cuando se pasa de ver punto IR a no verlo hay que indicar al sistema operativo que se ha soltado el boton. El código de esa condición pasa a ser el que se encuentra referenciado como Código 16 en el apartado 13.2 Código desarrollado durante el proceso de creación del programa incluido en el Anexo.

El funcionamiento es identico a la condición anterior, pero esta vez indicamos que lo que queremos hacer es soltar el boton derecho en vez de apretarlo.

También hay que decir que, cuando se hace clic derecho, el aparatdo de arraste del cursor no se tiene en cuenta, debido a que presenta problemas de uso con esta función. Al darle encima de un icono, si mueves un poco la mano, lo detecta como si fuera un

Page 47: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

47

movimiento del icono a otra posición. Por ese motivo prefiero inhibirlo cuando utilizamos la función clic derecho.

8.6 Rutina de Servicio a la Interrupción

A lo largo de este punto de la memoria he ido explicando el funcionamiento de las diversas partes que componen la Rutina de Servicio a la Interrupción. En este apartado quiero comentar todo aquello que no he explicado en los anteriores.

El código de la RSI completo se puede consultar en el apartado 13.3.2 Archivo

MultipleWiimoteForm.cs, dentro del apartado 13.3 Código fuente del programa final que se encuentra incluido en el Anexo. A continuación se comentarán los detalles de programación más importantes de este código, que no se han comentado anteriormente.

El primer y segundo “if” que se ven al principio comprueba si la ID enviada por el mando corresponde con la ID del mando 1 o 2. Según la que sea, ponemos la variable “mando” asociada a ese mando a “true”, y la contraria a “false”, ya que son variables

globales.

Según el mando que haya entrado, almacenamos la información enviada por ese en diversas variables ya comentadas.

Posteriormente viene la selección de las coordenadas X e Y a las que enviaremos el cursor del ratón. La función “warpedX<x>.warp” devuelve en las variables “warpedX<x>”

y “warpedY<x>” las coordenadas a las que hay que enviar el mouse, donde <x> es el número del mando que ha generado la interrupción. Al llamarla se le pasa la coordenada X e Y que ha enviado el mando, y las variables en las que se quiere escribir el resultado. Ella convierte las coordenadas enviadas por el mando en coordenadas sobre la pantalla del PC. Para poder hacerlo, previamente se debe haber calibrado la pantalla.

A continuación, se observa una matriz con el nombre “SmoothingBuffer”. La función “Smoothing” se utiliza para suavizar el trazo cuando se escribe con el puntero IR.

Sin esta función, pequeños movimientos de la mano de la persona que escribe se plasman directamente en la pantalla, apareciendo la línea como si estuviera pixelada. Con la aplicación de esta función se evita. Se puede programar el grado de acción de la función “Smoothing”. En la interfaz de usuario del programa se dispone de una barra que indica el

nivel de acción de esta función. Su rango es de 0 a 20. Cuando menor es la utilización de la cámara, más se tiene que subir el nivel. No la ponemos siempre al máximo porque consume muchos recursos, y puede causar que el cursor se mueva más lentamente. Para poder realizar este suavizado, se memorizan las últimas coordenadas recibidas. Una vez memorizadas, se hace la media de estas. Con este funcionamiento conseguimos hacer líneas mucho más suaves, pero se necesitan 5 puntos para pintar en la pantalla un punto. Como coge 5 puntos, se crea un buffer al que le pasamos los últimos puntos y un índice va aumentando para indicar cuantos puntos se tienen almacenados. Cuando llega a 5, comienza a aplicarse el suavizado. Cada vez que se deja de ver el puntero IR, la información del buffer se borra, para que esté listo para la siguiente línea a dibujar. Para asegurarse, al realizar la acción de clic se pone a 0 el índice. De esta manera se cogen 5 nuevos datos cada vez que clicamos de nuevo, borrando los anteriores si los hubiera. Los resultados de esta función se envían al arrastrar el cursor. Por este motivo, cuando el mando antes veía punto IR y ahora también, la selección del punto a enviar depende de un “if”. En este “if” se comprueba si la función “Smoothing” esta activa. Si lo está, se cogen

como puntos los enviados por esta función. Estos puntos serán la media de los últimos datos enviados. Se memorizará una cantidad de puntos igual al nivel al que el usuario pone

Page 48: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

48

la función. Por tanto, aumentando el nivel se consigue que el cursor vaya más lento, pero que la línea dibujada no presente un trazo pixelado.

Después de la selección de función según el estado del puntero IR, encontramos dos “if” con una gran cantidad de líneas de código en su interior. Estos “if” tienen como

condición de entrada la detección del mando que ha generado la interrupción. Su función es la de actualizar la información de la variable “lastWiiState” asociada a cada uno de los

mandos. Se actualiza toda la información referente a la recepción de punteros IR. Como el mando envía la información de 4 puntos, y la estructura de “lastWiiState” es una copia de

la estructura de datos que envía el mando, se actualiza la información para los cuatro puntos IR que puede posicionar el mando. Al final de cada uno de los dos “if”, se

comprueba el estado de la variable “act_<x>”, donde <x> es el número del mando que ha

generado la interrupción. Si es “true”, se actualiza la información de “lastWiiState” del

mando contrario. Recordar que se pone a “true” cuando el mismo mando ha entrado 10

veces seguidas en la RSI. Esto significará, que el otro mando no ve el punto IR desde hace 10 interrupciones, y por tanto hay que asegurarse que el valor de visibilidad almacenado en “lastWiiState” es “false”.

Por último, al final del código vemos la aparición de la función “BeginInvoke”

repetidas veces. Todas estas cadenas solo se utilizan para actualizar el valor de porcentaje de carga de las baterías del mando que ha generado la interrupción, y pintar adecuadamente la barra de progreso asociada. En resumen, actualiza la información del estado de las pilas del mando que ha generado la interrupción.

La última línea de código está asociada a la primera. Son unas líneas clave para que la interrupción funcione adecuadamente. En la primera línea, la función “mut.WaitOne()”

indica que no se deben atender nuevas peticiones de interrupción. Inhibe la llegada de nuevas peticiones de interrupción. La última línea, “mut.ReleaseMutex()”, se encarga de

permitir que lleguen nuevamente interrupciones, las desinhibe. Con esas dos funciones conseguimos que no lleguen nuevas interrupciones mientras ejecutamos la RSI. Todas las interrupciones que lleguen durante ese periodo se desestiman.

Hay mas código creado para que esta aplicación funcione correctamente, como por ejemplo el de obertura y cierre de nuevas ventanas o aplicaciones, pero el corazón del programa se basa en la RSI. Es en ella donde se controlan las funciones principales y donde se extrae la información de las coordenadas a las que enviar el puntero del mouse. También es donde realizamos la programación de las funciones que hará el ratón. Si esta no fuera la correcta, sería imposible escribir en la pantalla. Por tanto, la RSI forma el núcleo del proyecto. Gran parte del código que he realizado fuera de la RSI se encarga de cuestiones estéticas, y se utiliza para realizar un diseño más amigable de la interfaz de usuario. Se trata de funciones como la apertura de diferentes ventanas o de programas externos a este proyecto, pero que complementan las funciones del mismo. Su programación es muy sencilla, y es común para todos los programas desarrollados en C# con una interfaz gráfica similar a la de este programa. Tanto por internet, como en cualquier libro que trate las funciones que ofrece el lenguaje C#, se puede encontrar la descripción del funcionamiento del código implementado fuera de la RSI.

Page 49: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

49

9 Resultados finales

Mediante la aplicación de todas las soluciones explicadas anteriormente y de diferente código de mejora de la interfaz gráfica, se obtiene el programa final. Este presenta el siguiente aspecto:

Figura 15. Interfaz de usuario final del programa

Después de colocar correctamente los mandos y calibrarlos, el programa permite convertir una proyección de la imagen enviada por un ordenador en una pizarra digital interactiva.

Para colocar el mando correctamente se han de tener en cuenta los resultados obtenidos en los estudios.

Mediante el testeo de la aplicación, se obtiene como resultado que el porcentaje mínimo de utilización de cámara que debe tener cada mando es del 30%, ya que valores inferiores ofrecen un resultado con una calidad muy baja. Esto se debe a que la resolución para porcentajes inferiores al 30% es muy baja, y por tanto el mando no detecta cambios de posición hasta que el usuario mueve unos cuantos centímetros el puntero. El efecto final obtenido es que al intentar escribir aparecen líneas entre una posición y otra muy alejada, impidiendo una escritura clara. Del 30% al 50% se puede utilizar el programa para dibujar o escribir, pero la calidad es baja, aunque se puede comprender lo que se escribe. A partir del 50% se puede apreciar texto escrito a mano con gran claridad y el cursor se puede mover con mucha precisión. Por tanto, no se puede utilizar esta aplicación con porcentajes de visión inferiores al 30%. Para asegurarse que el resultado sea superior a este porcentaje, se habrán de observar los resultados de los estudios realizados.

El resultado ofrecido por los estudios ratifica que la fórmula “d=2h” es la manera

más rápida y eficaz de calcular la distancia a la que hay que colocar los mandos respecto a la proyección. Recordar que se debe multiplicar por 2 la altura de la proyección para conocer esta distancia. Esta fórmula es válida para un rango de ángulos entre la proyección y el mando que van desde los 80º a los 20º. Para un ángulo inferior a 20º se tendrían que acercar más los mandos para que el porcentaje de visión fuera superior al 30%. Para conocer a qué distancia se tendrían que poner, hay que aplicar la fórmula “d=73% * 2h”, es

decir, coger el 73% del resultado de la fórmula anterior. Con la aplicación de esta fórmula se podría colocar el mando en un rango de ángulos que va desde 15º hasta 45º. Para ángulos inferiores a 15º habría que colocar el mando muy cerca de la proyección, lo que interferiría con los movimientos del usuario alrededor de la proyección, y aun así el

Page 50: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

50

porcentaje de visión obtenido difícilmente superaría el 30%. Por tanto, se descarta el uso de esta aplicación con ángulos inferiores a 15º, y se recomiendan ángulos superiores a 20º para poder mejorar el porcentaje de visión hasta valores superiores al 50%.

Con la realización de los estudios de visión con la presencia de un obstáculo delante del mando se demuestra la mejora que ofrece la inclusión de un segundo mando para ver las zonas oscuras que un solo mando no puede ver. Con el uso de un único mando colocado a 60º, la zona oscura que aparece es de 58 cm y si el mando se encuentra a 30º esta es de 21.56 cm. En cambio, incluyendo un segundo mando y con el obstáculo en la misma posición que con la que se han obtenido los resultados anteriores, no hay zona oscura para ninguno de los ángulos. Por tanto, con la inclusión de un segundo mando el programa puede funcionar en un rango de ángulos muy amplio con una garantía elevada de que no existirán zonas oscuras, aunque si el obstáculo se coloca en la peor posición sí que surgirán pequeñas zonas oscuras.

Por ejemplo, para un ángulo de 45º y teniendo el obstáculo situado en la posición que más afecta la visión de los dos mandos, aparece una zona oscura de 3 cm de ancho. Esta zona representa tan solo un 1.57 % del total de superficie útil, y es muy pequeña en comparación con los resultados que se obtenían con un solo mando. Al tratarse de la peor posición, si el usuario se alejara un poco de la proyección uno de los mandos ya podría ver el puntero infrarrojo y por tanto, toda la proyección sería útil. Para este ángulo el obstáculo en la peor posición se encuentra a 27 cm de la proyección, es decir, muy cerca de ella. Con alejarse un poco, esta zona oscura dejaría de serlo.

También se obtiene como resultado que colocando los mandos a 15º se asegura que no existirá ninguna zona oscura para cualquier lugar en el que se encuentre el obstáculo. Pero a cambio se obtiene un porcentaje de visión muy bajo, de tan solo 40% si se aplica la fórmula “d=73% * 2h”. Por tanto, los movimientos del ratón no serian muy fluidos y el

texto escrito se vería pixelado.

Queda demostrado que la utilización de los mandos a 10º no tiene sentido, ya que a 15º utilizando dos mandos ya se asegura que no existen puntos oscuros. Por tanto, colocar los mandos a 10º no ofrece ningún beneficio de uso y por el contrario reduce la resolución. Este efecto produce que el ratón se mueva a golpes e impidiendo que se pueda utilizar esta aplicación para escribir encima de la proyección, ya que el texto escrito no se podría comprender. Se concluye que el rango de utilización de este proyecto con dos mandos llega como máximo a 15º respecto la proyección.

Comprobando los resultados de todos los estudios se llega a la conclusión que colocar los mandos a 45º resulta la opción más equilibrada. Para este ángulo y con dos mandos, las zonas oscuras que aparecen son casi inexistentes para una utilización normal, y en el peor de los casos llegan a ser de 3 cm. Por otra parte, el porcentaje de visión en esta posición según el primer estudio realizado es del 68 % si la distancia se obtiene aplicando “d = 2h”, con lo que se asegura que el movimiento del cursor será muy fluido y la escritura

se podrá comprender fácilmente. Al ofrecen un rango de zonas oscuras tan bajo y un porcentaje de visión elevado, se considera que es la mejor opción para colocar los mandos, y se recomienda esta colocación para obtener unos resultados óptimos.

Page 51: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

51

10 Conclusiones

Se comprueba en la realización de los estudios que la mejora con dos mandos es significativa. Dejando de lado los porcentajes de mejora que ofrece, con el uso de dos mandos se evita la aparición de zonas oscuras en un uso normal de la pizarra interactiva. Evitar esas zonas es indispensable, ya que son zonas en las que la cámara no tiene visión y por tanto el cursor no se moverá y la pizarra interactiva no funcionará. Por este motivo, queda más que justificada la utilización de dos Wiimotes. El precio final del producto, pero ofrece unas mejoras suficientemente importantes como para asumir un aumento del precio del producto de 40 € (el precio de un mando).

La posición más equilibrada sería colocar los mandos a un radio igual a multiplicar por dos la altura de la proyección, y a partir de ese radio mover los mandos circularmente alrededor de la proyección hasta colocarlos con un ángulo de 45º respecto la proyección. La elección de esta colocación se justifica debido a que con ese ángulo se obtienen muy pocas zonas oscuras y los mandos tienen un porcentaje de visión suficiente como para que el movimiento del cursor sea fluido.

Se comprueba matemáticamente que los ángulos menores a 15º ofrecen un valor de visión muy reducido, lo que disminuye la resolución de los mandos de tal manera que el resultado final no es aceptable. Por tanto, se concluye que la aplicación no podrá utilizarse con ángulos inferiores a 15º.

Se realizan diversas mejoras que reducen los errores de posicionamiento del cursor. La posibilidad de calibrar los dos mandos al mismo tiempo es una de ellas. De esta manera se reducen los errores a causa de que el usuario no coloca el puntero infrarrojo en el mismo lugar en cada calibración. Si la calibración entre un mando y otro difiriera mucho, se provocarían saltos del cursor de una posición a otra cuando el mando que envía la información en ese momento se tapara. En caso de estar escribiendo, el cursor saltaría de un punto a otro y el texto no se comprendería. Esta mejora evita los saltos, y por tanto se cree necesaria su inclusión para permitir que el usuario pueda escribir sin problemas.

Otra mejora incluida es la posibilidad de escoger entre dos métodos de posicionamiento diferentes. Mediante el testeo de la aplicación se comprueba el rango de utilización de cada modo. Habitualmente y por defecto se utiliza el método para los mandos en el centro. Solo tiene sentido utilizar el otro método en lugares donde el ángulo entre los mandos y la proyección sea muy reducido.

También se incluyen diversas funciones que facilitan el uso del programa. Una de ellas es la ventana de Ayuda a calibración. Esta ventana muestra la visión de la cámara de ambos mandos. Con ella, el usuario puede colocar los mandos en una posición óptima más rápidamente. Únicamente debe intentar que las esquinas de la proyección correspondan con las esquinas de esta nueva ventana. La inclusión de esta opción se justifica debido a la reducción de tiempo que supone para el usuario colocar ambos mandos en una posición correcta.

Otra función de ese tipo es la posibilidad de realizar doble clic. Si el usuario pulsa dos veces seguidas el botón del puntero para hacer doble clic, y se mueve mínimamente, se interpreta como que desea mover el icono. Por ese motivo se asegura la correcta realización del doble clic mediante software. También se incluye la posibilidad de realizar clic derecho.

Page 52: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

52

El Wiimote posiciona cualquier punto infrarrojo que se encuentre dentro del rango de visión del mando, con lo que podría posicionar muchas más cosas que un puntero infrarrojo. Por ejemplo, se podría utilizar para conocer la posición de un robot sobre una superficie en la que se conozca la anchura y profundidad de esta. Si se dotara al robot de un led infrarrojo en la parte superior, el mando podría posicionarlo. Substituyendo la etapa de calibración del programa diseñando por la introducción de las coordenadas de las esquinas de la superficie mediante el uso del teclado, se podría indicar la posición a la que se desea enviar el robot y asegurarse que este va a la posición indicada. Permitiría tener controlada la posición del robot en todo momento. Esta solución se podría aplicar en lugares cerrados, donde la utilización de un sistema GPS es muy complicada debido a la mala recepción de satélites en lugares cerrados. Utilizando las propiedades del Wiimote, se podría obtener una solución de posicionamiento con un coste muy bajo.

El proyecto realizado presenta unos resultados muy similares a los productos comercializados en la actualidad, como Mimio. La resolución de estos productos comerciales es muy elevada, pero su rango de utilización es menor al de la solución obtenida en la realización de este proyecto. Siguiendo con el ejemplo de la empresa Mimio, el producto que comercializan tiene un rango de utilización de superficies de 1,2 m x 2.4 m hasta 2 m x 2.4 m. Como se puede ver, su rango de utilización es limitado, mientras que con la utilización del Wiimote, se pueden abarcar superficies de gran tamaño. Solamente se deberá disponer de espacio en la sala para alejar el Wiimote lo suficiente de la proyección como para que pueda verla en su totalidad. También se aprecia que la solución de Mimio tiene un valor de utilización mínimo muy grande, mientras que el uso del Wiimote posibilita convertir en pizarra digital interactiva cualquier tipo de pantalla. Por tanto, la utilización de los Wiimotes para crear una pizarra interactiva ofrece un rango de utilización mucho más amplio que las soluciones del mismo tipo que se comercializan actualmente.

En resumen, se ha podido realizar un programa donde se leyeran los datos de dos mandos diferentes y se combinaran entre si para mover el cursor a una posición concreta. También queda justificada la utilización de dos mandos para realizar este proyecto, debido a la mejora que presentan estos, medida en los estudios. Se ha realizado un sistema de calibración que permite calibrar los dos mandos realizando una única calibración. Esto hace que el proceso de instalación sea más rápido y sencillo para el usuario, y reduce los errores en el posicionamiento del puntero. Y todo con un coste final menor a 150 €.

Por tanto, se han cumplido los objetivos iníciales y se han visto ampliados con funciones adiciones insertadas en el programa.

Page 53: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

53

11 Manual de instalación y uso

Esta aplicación convierte una superficie en la cual estemos proyectando una imagen en una pizarra digital interactiva. Su finalidad es la interpretación correcta de los datos enviados por los mandos de la videoconsola Wii para poder escribir encima de la proyección. Para complementar las funciones de esta aplicación, se sugiere la instalación de otras dos aplicaciones de distintas fuentes a las que crearon este programa.

Una de estas aplicaciones recibe el nombre comercial “UW Classroom Presenter 3”.

Esta aplicación ha sido creada por el Departamento de Ciencia Computacional e Ingeniería de la Universidad de Washington [6]. Es de código abierto y libre distribución. Tanto el instalador, como el código fuente se pueden descargar de su página web: http://classroompresenter.cs.washington.edu/. Esta aplicación permite al usuario dibujar encima de cualquier presentación con formato Powerpoint. Admite tanto extensiones .ppt como .pptx. Las presentaciones son convertidas al formato propio de este programa antes de poder ser utilizadas. Una vez el usuario ha escrito o dibujado sobre las diferentes diapositivas, puede guardar las acciones realizadas en formato .cp3, que es el que utiliza este programa. Cualquier persona que tenga instalado Classroom Presenter 3, podrá abrir estas presentaciones a posteriori y analizar la información que se ha dibujado o escrito en ellas.

La otra aplicación que se recomienda instalar recibe el nombre comercial “Click-N-Type” [7]. Ha sido desarrollada por la empresa Lake Software. Es un programa de tipo Freeware y se puede descargar de la página web http://cnt.lakefolks.org/es-intro.htm. Este programa permite la escritura de texto en pantalla. El programa en si es un teclado virtual, el cual permite escribir clicando encima de las teclas virtuales que salen en la interfaz de usuario del programa.

La aplicación WiimoteBoard dispone de accesos directos a este programa en la pestaña Abrir. Para que estos accesos directos funcionen, se han de instalar previamente ambas aplicaciones.

En caso de no disponer de conexión a Internet, los instaladores de estas aplicaciones se pueden encontrar también en la carpeta donde se ha instalado WiimoteBoard.

Se recomienda encarecidamente a todos los usuarios que instalen estas aplicaciones para complementar las funciones de WiimoteBoard.

11.1 Instalación de WiimoteBoard

Para iniciar la instalación se debe de hacer doble clic sobre el archivo “WiimoteBoard”:

Page 54: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

54

Figura 16. Instalador de la aplicación

Aparece una ventana en la que se informa del programa que va a ser instalado. Si pulsa siguiente continuará con el proceso de instalación:

Figura 17. Información del programa que va a ser instalado

Page 55: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

55

Al pulsar “Siguiente” aparece una nueva ventana, en la que se pregunta al usuario en

que carpeta desea instalar el programa. En caso de que desee instalarlo en una carpeta diferente a la que viene por defecto, hay que pulsar en “Examinar” e indicar en qué lugar queremos instalarlo. En la parte inferior de la pantalla se puede elegir entre instalar la aplicación solo a este usuario, o a todos los usuarios del ordenador. Esta opción es útil en caso de que su ordenador sea utilizado por diversas personas, cada uno con una cuenta de usuario diferente. Podrá elegir entre instalar el programa solo en su cuenta de usuario, o instalarlo para todos los usuarios. Por defecto, el programa se instala en la ruta “C:\Archivos de programa\ETSE URV\” y únicamente para el usuario que está utilizando el ordenador en ese momento. Una vez configuradas todas las opciones pulse “Siguiente:

Figura 18. Selección de la ruta en la que se quiere instalar el programa

Finalmente aparece una ventana que indica que la configuración de la instalación ha terminado. Pulsando “Siguiente” se confirma que la configuración es correcta y se realiza la instalación del programa

Page 56: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

56

Figura 19. Confirmación de los parámetros de instalación

Posteriormente aparece la pantalla en la que se indica el estado de instalación. En este paso se copian los archivos necesarios para que la aplicación funcione correctamente, y se crea un icono de acceso directo en el escritorio y en menú desplegable de “Inicio”.

Debe esperar a que concluya la copia de archivos y aparezca una nueva ventana:

Figura 20. Proceso de instalación

Page 57: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

57

Una vez se han copiado todos los archivos, aparece la última ventana en la que se indica que la instalación se ha efectuado correctamente. En caso contrario indicaría que ha aparecido un error, y habría que iniciar el proceso desde el principio. Pulsando “Cerrar”

habrá concluido la instalación:

Figura 21. Indicación de que se ha instalado correctamente la aplicación

11.2 Instalación de Classroom Presenter 3

El instalador de este programa se puede descargar de la página web http://classroompresenter.cs.washington.edu/ . Pulsando encima del cartel “Classroom

Presenter 3 is now Available” se abre automáticamente la ventana de descarga del

instalador. La página web esta en ingles, pero el programa está traducido al castellano.

También se puede encontrar el instalador en la carpeta donde se ha instalado el programa WiimoteBoard. Por defecto, la ruta de esta carpeta es “C:\Archivos de programa\ETSE URV\Wiimote Board”. Dentro de esa carpeta se encuentra otra con el

nombre “instaladores de aplicaciones asociadas”:

Page 58: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

58

Figura 22. Imagen de la localización de la carpeta “instaladores de aplicaciones

asociadas”

Si abre esa carpeta encontrará otras dos carpetas diferentes. Una de ellas recibe el nombre “Classroom Presenter 3”. Si la abre encontrará el instalador de esta aplicación.

Para abrir la instalación, tiene que realizar doble clic encima del icono con el nombre “cp3-1719_r”. Una vez hecho, se abrirá una ventana que le guiará durante todo el proceso de instalación. Esta ventana estará en Ingles, pero el proceso es idéntico al descrito en la instalación de la aplicación Wiimote Board. En esta primera ventana se informa de la aplicación que va a proceder a instalar. Pulse “Next” para continuar con la instalación.

Page 59: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

59

Figura 23. Ventana de información sobre la aplicación que va a proceder a instalar

La nueva ventana que aparece informa al usuario sobre el tipo de licencia de este producto. En caso de que no esté de acuerdo con la información que se especifica, pulse “I

Do Not Agree” y la instalación será cancelada. Si está de acuerdo, debe pulsar “I Agree” y

“Next” para poder continuar la instalación:

Figura 24. Ventana de información sobre el tipo de licencia de este producto

Page 60: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

60

En la siguiente ventana se le solicita al usuario el lugar donde quiere instalar la aplicación. Pulsando “Browse” puede escoger un lugar diferente al que viene por defecto.

¡Para que pueda abrir directamente esta aplicación desde la pantalla del

programa Wiimote Board, debe instalar Classroom Presenter 3 en la carpeta que

viene por defecto!

Por tanto, si desea poder abrir esta aplicación en el futuro directamente desde la pantalla de Wiimote Board, no debe de cambiar el lugar de instalación, deje el que viene por defecto.

Otra opción que se encuentra en esta pantalla es la elección del número de usuarios a los que se debe instalar. Si su ordenador dispone de diversas cuentas de usuario, se puede elegir entre instalar la aplicación únicamente en la cuenta de usuario que ha abierto la instalación, o en todas las cuentas de usuario a la vez. Por defecto se instala únicamente para el usuario que ha abierto la instalación. Para instalarlo en todas las cuentas de usuario a la vez, debe pulsar “Everyone”.

Una vez haya concluido la configuración de todas las opciones, pulse “Next”.

Figura 25. Configuración de las opciones de instalación por defecto

Finalmente sale una ventana en la que se indica al usuario que se va proceder a llevar a cabo la instalación. Si no desea cambiar ninguna de las opciones anteriormente descritas, pulse “Next”. Si desea cambiar alguna opción, puede pulsar “Back” y volverá a la ventana

anterior.

Page 61: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

61

Figura 26. Confirmación de la configuración de la instalación

En la siguiente ventana se muestra el progreso de copia a tu PC de los archivos necesarios para que la aplicación funcione. Debe esperar a que la copia finalice. Cuando lo haga, aparecerá una nueva ventana que indicará que se ha concluido la instalación.

Figura 27. Finalización de la instalación

Page 62: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

62

Debe pulsar “Close” para cerrar la ventana, y ya podrá comenzar a utilizar Classroom Presenter 3.

Para más información sobre el funcionamiento de esta aplicación, puede dirigirse a la página web http://www.cs.washington.edu/research/edtech/presenter/doc/startguide3.html . En esta página web encontrará las instrucciones de uso de las diferentes funciones que ofrece este programa. El idioma de esta página es Inglés.

11.3 Instalación de Click-N-Type

El instalador de este programa se puede descargar de la página web http://cnt.lakefolks.org/es-intro.htm. En la parte inferior de la página pone: “Descargue la

última versión de Click-N-Type”. Al lado de este texto aparece el nombre “CNTzip.exe”, subrayado y pintado de color azul. Debe clicar encima de ese nombre y se abrirá la ventana para descargar la aplicación. Guárdela en la carpeta que desee. También deberá descargar otro archivo para traducir el programa a Español, ya que por defecto viene en Ingles. Debajo del texto “CNTzip.exe” se encuentra otro que pone “Español(España)” también

subrayado y pintado de azul. Clicando encima de este. Haciendo clic encima de ese texto, se abre una ventana de descarga que le pregunta donde desea guardar el archivo. Puede guardarlo donde desee, pero se recomienda guardarlo en el mismo lugar en el que ha guardado “CNTzip.exe”, ya que se tienen que instalar ambos.

También se puede encontrar el instalador en la carpeta donde se ha instalado el programa WiimoteBoard. Por defecto, la ruta de esta carpeta es “C:\Archivos de programa\ETSE URV\Wiimote Board”. Dentro de esa carpeta se encuentra otra con el

nombre “instaladores de aplicaciones asociadas”. En la Figura 22 se muestra esta carpeta.

Si la abre haciendo doble clic encima, encontrará otras dos carpetas diferentes. Una de ellas recibe el nombre “Click-N-Type”. Si la abre encontrará el instalador de esta

aplicación.

Para abrir la instalación, debe realizar doble clic en el archivo “CNTzip.exe”.

Figura 28. Archivo instalador de la aplicación Click-N-Type

Page 63: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

63

Una vez haya realizado doble clic, aparecerá la siguiente pantalla:

Figura 29. Descompresor del instalador de Click-N-Type

Debe pulsar “Unzip” para que el instalador se descomprima y se inicie la instalación. Cuando el proceso de descompresión concluya, aparece una ventana con el texto “1 file(s)

unzipped succesfully”. En caso de que no salga este mensaje, hay que cerrar el archivo y

volver a abrirlo, repitiendo el proceso de nuevo. Para proseguir, debe pulsar “Aceptar”. Automáticamente se abre otra ventana que indica que programa se va a instalar.

Figura 30. Instalador de Click-N-Type

Debe pulsar “Next” para continuar. Cuando lo haga, le aparecerá otra pantalla en la que se indica la carpeta donde se instalará el programa por defecto.

¡Para que pueda abrir directamente esta aplicación desde la pantalla del

programa Wiimote Board, debe instalar Click-N-Type en la carpeta que viene por

defecto!

Page 64: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

64

Por tanto, si desea poder abrir esta aplicación en el futuro directamente desde la pantalla de Wiimote Board, no cambie el lugar de instalación, deje el que viene por defecto.

Si desea cambiar la carpeta donde se instalará, pulse “Browse” y seleccione la

carpeta donde quiere instalarla.

Figura 31. Pantalla de selección de la carpeta donde instalar el programa

Pulse “Next” para pasar a la pantalla siguiente. La instalación se inicia

automáticamente y se copian los archivos necesarios para su funcionamiento en la carpeta que ha indicado.

Finalmente aparece una última pantalla en la que se informa que la instalación se ha realizado correctamente. Si apareciera algún error durante la instalación, debe iniciar el proceso de nuevo. Para cerrar la ventana pulse “Finish”.

Figura 32. Finalización de la instalación

Page 65: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

65

El programa ya se puede utilizar, pero aparecerá en Ingles. Para traducirlo, debe llevar a cabo los siguientes pasos:

Haga doble clic encima del archivo con el nombre “Spanish-Files”. Se abrirá la

siguiente ventana:

Figura 33. Inicio de instalación del paquete de traducción a Español de Click-N-Type

Para iniciar la instalación pulse “Setup”. El instalador se descomprimirá y se abrirá

automáticamente. Aparece la siguiente pantalla:

Figura 34. Selección de la carpeta donde se encuentra instalado Click-N-Type

El instalador busca automáticamente la carpeta donde tiene instalado Click-N-Type. Usted solo tendrá que confirmar si es esa la carpeta en la que se encuentra el programa que quiere traducir. Si es así, pulse “Instalar”. En caso contrario deberá buscar la carpeta en la ventana superior, en la cual aparecen todas las carpetas y archivos del ordenador.

Cuando pulse “Instalar” aparece una nueva pantalla con diversas opciones. Por

defecto vienen todas marcas:

Page 66: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

66

Figura 35. Selección de elementos a traducir

Si desea eliminar alguna opción, puede pulsar la casilla que hay al principio de cada frase y esta se desmarcará. Se recomienda dejar todas las opciones marcadas. Para completar la instalación pulse “Finalizar”.

Cuando lo haga empezará la instalación y se copiaran los archivos necesarios. Debe esperar a que concluya. Al acabar, aparece el siguiente mensaje:

Figura 36. Instalación finalizada

Si en el mensaje que aparece se le indica que la instalación se ha realizado con éxito, pulse “Aceptar” y ya podrá utilizar Click-N-Type traducido al Español. Si se indicara que ha surgido algún error durante la instalación, repítala desde el primer paso.

Usted ya dispone de la aplicación Click-N-Type instalada en su ordenador. Pero para utilizarla en conjunto con Wiimote Board se recomienda realizar la siguiente modificación:

Abra Click-N-Type. La apariencia que presenta este programa por defecto es la siguiente:

Page 67: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

67

Figura 37. Apariencia de Click-N-Type por defecto

Para ampliar las funciones del teclado pulse la pestaña “Archivo”, situada en la parte

superior izquierda de la ventana. Se abrirá un desplegable con diversas opciones. Pulse “Seleccione un teclado”

Figura 38. Pestaña Archivo desplegada

Se le abrirá una ventana con diferentes archivos. Seleccione “QWERTY101-long”.

Automáticamente la apariencia del teclado cambiará por la siguiente:

Figura 39. Click-N-Type con funciones extendidas

Comprobará que aparece un teclado numérico en el lateral derecho. Con esta extensión del teclado dispondrá de todas las funciones necesarias en la pantalla de la proyección, y podrá escribir pulsado las teclas con el puntero infrarrojo.

Page 68: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

68

Puede volver a cambiar la apariencia del teclado por la que viene por defecto en todo momento, realizando el mismo proceso, pero eligiendo en el último paso el archivo “QWERTY102-short”.

Click-N-Type se mantiene siempre encima de las ventanas que abra, con lo que solo necesita clicar con el puntero encima del campo en el que quiera escribir y pulsar uno a uno los botones de las letras que quiera escribir. Para pulsarlos, solo tendrá que poner el puntero infrarrojo encima y apretar y soltar el botón que se encuentra en la parte superior del puntero. Siguiendo este procedimiento, podrá escribir el texto que desee en cualquier programa.

Para obtener una información más detallada sobre las diferentes funciones que ofrece Click-N-Type, puede dirigirse a su página web: http://www.lakefolks.org/cnt/features.htm . El idioma de esta página es Inglés.

11.4 Manual de uso de Wiimote Board

11.4.1 Conexión por primera vez de los Wiimotes al PC

Para poder utilizar esta aplicación, primero se tienen que emparejar los Wiimote al PC. Este proceso solo se debe realizar la primera vez que se desea conectar los mandos al PC. No será necesario llevarlo a cabo cada vez que quiera utilizar la aplicación. Para hacerlo, debe disponer de un dispositivo Bluetooth instalado en su ordenador. Debe ir a la pantalla en la que empareje nuevos dispositivos. Para mas referencias, consulte el manual de instrucciones adjunto a su dispositivo de conexión Bluetooth. Debe de realizar el proceso de emparejamiento para poder conectar su PC con el Wiimote. Para poder detectar el Wiimote desde el PC, debe mantener pulsados al mismo tiempo los botones 1 y 2 del mando durante todo el proceso.

En la ventana de selección del dispositivo que quiere emparejar, debe buscar el dispositivo que tenga el nombre “Nintendo RVL-CNT-01”. Una vez localizado, haga doble

clic encima del icono que representa este dispositivo y prosiga el proceso de conexión. No se necesita ninguna clave de emparejamiento para poder conectar este dispositivo. Cuando haya finalizado el emparejamiento de un mando, debe realizar el mismo proceso para el otro mando. Cuando finalice, deberá ver en la ventana de Dispositivos Vinculados dos iconos con el nombre “Nintentdo RVL-CNT-01”. Estos iconos identifican a los dos

mandos que ha conectado. Deberá recordar como acceder a la carpeta donde se encuentran esos iconos, ya que cada vez que tenga que conectar los mandos deberá acceder a ella.

11.4.2 Conexión de los Wiimotes al PC

Una vez emparejados, el proceso de conexión es sencillo. Abra la carpeta donde se encuentran los iconos que simbolizan cada uno de los mandos. Para acceder a esta carpeta generalmente se dispone de un acceso directo pulsado clic derecho en el icono , que se encuentra en la barra de herramientas, en la parte inferior de la derecha de la pantalla.

Una vez se encuentre en esa carpeta, debe hacer doble clic en los dos iconos que tengan el nombre “Nintendo RVL-CNT-01”. Antes de hacer clic en estos iconos, deberá

pulsar una sola vez al mismo tiempo los botones 1 y 2 de ambos mandos. Al pulsarlos, los leds azules que hay en la parte inferior de la pantalla se ponen a parpadear. Con este

Page 69: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

69

proceso permite al PC conectarse al mando. Una vez se encuentren parpadeando los leds de ambos mandos, puede proceder a pulsar los dos iconos que reciban el nombre “Nintendo RVL-CNT-01”. Al hacer doble clic en los iconos, el proceso de conexión se

iniciará. Si no da ningún error, el icono cambiará de color e indicará que el mando ya se encuentra conectado. En caso de que hubiera algún error, saldría un mensaje notificándolo. Es posible que ocurra un error en la conexión si tarda mucho entre pulsar los botones de los mandos y hacer clic en los iconos, ya que solo se dispone de 20 segundos desde que se pulsan los botones de los mandos para realizar la conexión. Si fuera así, compruebe que mando tiene todos los leds azules apagados y pulse los botones 1 y 2 nuevamente. Vuelva a hacer doble clic sobre el icono asociado a ese mando y este se conectará al PC.

Cada icono se corresponde con un único mando. Como a priori los mandos no están identificados, no sabemos a qué mando corresponde cada icono. Por este motivo se recomienda que se pulsen los botones 1 y 2 de ambos mandos al mismo tiempo, y luego se proceda a hacer doble clic sobre los iconos del PC. De esta manera, se asegura que el mando que intenta conectar esta visible, ya que los dos lo están.

Figura 40. Ventana de conexión con los mandos.

En esta imagen aparecen los dos iconos en verde, lo que significa que ambos están conectados al PC. La interpretación del estado de conexión puede variar según el software del fabricante del dispositivo Bluetooth. Tendrá que cercionarse como simboliza su dispositivo que hay una conexión estable con un elemento Bluetooth externo, consultando el manual de instrucciones del dispositivo Bluetooth que utilice usted. Una vez esté seguro de que ambos mandos están conectados puede abrir el programa. Aunque se encuentren conectados al ordenador, los 4 leds de cada mando no dejan de parpadear. Dejarán de parpadear cuando el programa Wiimote Board se haya conectado a ellos. Por tanto, hasta que no abra Wiimote Board los leds azules seguirán parpadeando. No se alarme, no significa que haya realizado incorrectamente el proceso de conexión al dispositivo Bluetooth del ordenador.

Page 70: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

70

11.4.3 Apertura del programa

Se recuerda a los usuarios que antes de abrir el programa deben de haber conectado los mandos al dispositivo Bluetooth de su PC. En caso contrario, al abrir la aplicación saldrá un mensaje de error notificando que no se encuentra ningún mando conectado al ordenador.

Para abrir la aplicación, dispone de un icono en el escritorio con este aspecto:

Figura 41. Acceso directo a la aplicación

Dándole doble clic encima, la aplicación se abriría. También se encuentra un acceso directo en el menú desplegable de “Inicio”, dentro de las carpetas “Programas” y “ETSE URV”, tal como se muestra en la siguiente imagen:

Figura 42. Acceso directo a Wiimote Board ubicado en el menú desplegable “Inicio”

Haciendo un clic sobre este icono, la aplicación también se abrirá. Cualquiera de los dos métodos de apertura es válido.

11.4.4 Funcionamiento del programa

Una vez se ha abierto el programa, aparece la siguiente ventana:

Figura 43. Pantalla principal del programa Wiimote Board

Page 71: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

71

Al abrir el programa, los leds de los mandos conectados dejaran de parpadear. El mando en el que se encienda el primer led, será el mando 1. El primer led es el que se encuentra marcado con un punto encima. El mando en el que se encienda el segundo led, será el mando 2. El segundo led es el que dispone de dos puntos marcados encima de este.

Si utiliza este sistema en un lugar nuevo, se recomienda que realice los siguientes pasos:

1. Pulse el botón “Ayuda calibración”, que se encuentra situado en la parte

superior del programa. Esto hará que se habrá una ventana debajo de la existente, en la que aparece un cuadrado negro. Este cuadrado negro indica la visión que tiene el mando. Cuando encienda el puntero infrarrojo sobre la superficie que desea utilizar como pizarra digital, verá que en el cuadrado se dibuja una redonda roja. La posición de esa redonda es donde ve el mando que se encuentra el puntero IR. Esto le permitirá posicionar de manera correcta el mando.

Figura 44. Ventana principal de la aplicación Wiimote Board con Ayuda a la calibración abierta.

Page 72: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

72

2. Una vez abierta la Ayuda a la calibración, debe comprobar que como mínimo, toda la superficie de proyección es vista por el mando. Para hacerlo, tiene que colocar el puntero infrarrojo en las cuatro esquinas de la superficie proyectada, y comprobar que en el cuadro negro aparece un punto rojo para cada una de las esquinas. En caso contrario, deberá mover el mando hasta que vea los cuatro puntos. Esta acción hay que realizarla también para el mando 2. Para cambiar entre lo que ve el mando 1 y lo que ve el mando 2 se dispone de las pestañas que hay encima del cuadrado negro. Cambiando entre una pestaña y otra podrá comprobar lo que ven los dos mandos.

Como mínimo se deberían ver las cuatro puntas de la proyección, pero el programa se podría mostrar poco efectivo si el mando está muy alejado. Por eso, se recomienda intentar centran las cuatro esquinas de la proyección con las cuatro esquinas de la ventana del programa. Cuanto más área vea el mando, mejor funcionará el posicionamiento del cursor.

Si mueve el mando hacia arriba, el punto rojo que aparece en la ventana se desplazará hacia abajo. Si mueve el mando hacia abajo, el punto rojo se desplazara hacia arriba. Si lo mueve hacia la derecha, el punto rojo se moverá hacia la izquierda. Y si lo mueve hacia la izquierda, el punto rojo se moverá hacia la derecha. Recuerde que el objetivo es poner el punto rojo que aparece en la ventana negra en la misma esquina en la que este apuntando con el puntero sobre la proyección. Nunca podrá conseguir centrar las esquinas perfectamente, pero debe procurar aproximarse lo máximo posible. Después de realizar la calibración, un valor numérico le indicará el porcentaje de utilización de la zona de visión del mando. Si este porcentaje es mayor a 50%, el mando se encuentra bien situado. Sino deberá intentar acercarse mas utilizando la técnica comentada, si desea que el posicionamiento del cursor sea más preciso.

3. Una vez haya posicionado los mandos correctamente siguiendo la Ayuda de calibración, vuelva a pulsar el botón “Ayuda de calibración” y la ventana

negra desaparecerá, quedando el programa como el mostrado en la Figura 43.

4. Calibre la superficie de proyección pulsando el botón “Calibrar”. Cuando lo

pulse, aparecerá una pantalla blanca con una cruz roja como esta:

Figura 45. Cruz que se debe pulsar para calibrar el sistema

Debe de colocar el puntero infrarrojo en el lugar donde se juntan la línea vertical y la horizontal, en el centro. Una vez esté colocado correctamente, pulse el botón del puntero infrarrojo. Automáticamente la cruz desaparecerá y

Page 73: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

73

aparecerá otra en la esquina superior izquierda. Este proceso se realiza muy rápidamente, con lo que puede apretar y soltar rápidamente el puntero infrarrojo y el punto ya quedara registrado. Debe de realizar la misma acción para los puntos restantes, que aparecerán en las esquinas restantes. Puede pulsar la tecla “Esc” de su teclado para salir en cualquier momento de la

calibración. En caso de que hubiera algún fallo durante el proceso, debe de volver a pulsar el botón “Calibrar” y repetir el proceso.

5. Después de realizar la calibración, debe comprobar los valores de utilización de la zona de visión del mando. Puede encontrar esta información en los campos del programa que ponen “Utilización de cámara 1” y “Utilización de

cámara 2”. En la siguiente imagen podrá ver donde se encuentran:

Figura 46. Zona indicadora de la utilización de la visión de cada mando

Deberá comprobar que los valores no sean muy bajos. Si estos fueran muy bajos, el cursor del ratón podría ir a golpes o no moverse tal como el usuario desea. Se recomienda que tengan un valor superior al 50% para que el cursor se mueva correctamente. Con un valor del 40% en los dos mandos el funcionamiento es más que aceptable, pero puede presentar algún pequeño error.

Una vez que haya realizado toda la secuencia explicada en estos pasos, ya podrá utilizar el puntero infrarrojo para mover el cursor sobre la proyección.

Si detectara que el cursor del mouse se ha desviado de la posición en la que se encuentra el puntero infrarrojo durante la utilización de la pizarra, puede volver a realizar la calibración para solucionar el problema. En caso de se mueva mínimamente el mando de la posición en la que se encontraba, deberá de volver a realizar la calibración para que el cursor del mouse apunte donde desea usted. La calibración se puede llevar a cabo en el momento que usted desee.

Page 74: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

74

Si ya había realizado la calibración anteriormente y no ha movido ni los mandos ni el proyector, no será necesario volver a hacerla en caso de cerrar y volver a abrir el programa, ya que se recarga la última calibración realizada cada vez que se abre. Esta opción es útil en caso de que la instalación sea fija o tenga que reiniciar el ordenador, ya que no será necesario que vuelva a calibrar la pizarra.

11.4.4.1 Elección del modo de posicionamiento:

En el programa se dispone de una zona que recibe el nombre “Modo de

posicionamiento”. En ella, el usuario puede elegir la manera en la que el programa controla

la posición a la que enviar el cursor. Según el lugar en que haya instalado los mandos, el posicionamiento es mejor siguiendo una técnica u otra. El usuario puede elegir el modo que mejor posicione el cursor, después de comprobar el funcionamiento con uno u otro.

Figura 47. Zona de selección del modo de posicionamiento del cursor, según donde se hayan colocado los mandos.

Hay dos modos diferentes:

Mandos en el centro: Se utiliza este modo preferentemente cuando los mandos se encuentran cercanos al centro de la proyección. El ángulo entre la superficie que proyectamos y los mandos debe de estar entre 20º y 90º. Por tanto, este modo de posicionamiento se deberá utilizar cuando los mandos se encuentren delante de la proyección.

En este modo de posicionamiento se intenta hacer la media de la información enviada entre los dos mandos siempre que la desviación entre las coordenadas enviadas por un mando y por el otro sea pequeña. Este método ofrece mejores resultados cuanto más cercanos estén los mandos al centro de la proyección, y entre ellos.

Mandos en los laterales: Se utiliza este método cuando los mandos se encuentran en los laterales de la superficie a proyectar. Posiciona el cursor correctamente cuando el ángulo entre la superficie donde proyectamos las imágenes y el mando es inferior a 20º.

Page 75: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

75

¡Para la utilización de este modo es necesario colocar el mando 1 en la

parte izquierda de la proyección y el mando 2 en la parte derecha!

Con este modo se indica al programa que cuando se escribe a la izquierda de la proyección coja únicamente los datos que envía el mando 1, ya que al estar en esa zona tendrá una mejor visibilidad del puntero infrarrojo. De la misma manera, cuando escriba en la parte izquierda de la proyección únicamente se cogerá la información del mando 2.

Este método ofrece mejores resultados cuanto más próximos estén los mandos al paralelismo entre ellos y la superficie de proyección, es decir, cuando tengan un ángulo respecto la superficie de proyección muy reducido.

El usuario podrá elegir que posicionamiento prefiere, según el lugar donde haya instalado los mandos o sus preferencias personales.

Generalmente los mandos se encontrarán a un ángulo mayor a 20º, con lo que el modo “Mandos en el centro” es la opción por defecto. El posicionamiento mediante este modo permite una escritura a mayor velocidad que el posicionamiento “Mandos en los

laterales”. Esta mayor velocidad se debe a que en el posicionamiento “Mandos en el

centro” se leen los datos enviados por los dos mandos, mientras que en el otro modo solo

se leen los datos de un único mando.

11.4.4.2 Suavizado del cursor

El suavizado del cursor consiste en un método de mejora por software de los movimientos realizados con el puntero infrarrojo. Evita la vibración de la imagen a causa del movimiento de la mano del usuario. Su funcionamiento se basa en coger los últimos datos que ha enviado el mando y hacer la media de ellos, creando así un trazo mucho mas lineal. Sin esta opción, el trazo se vería muy pixelado ya que el mínimo movimiento de la mano se plasmaría en la pantalla. Con el suavizado de cursor se consigue realizar líneas mucho mas rectas.

Figura 48. Zona de control de la función Suavizado del cursor

Page 76: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

76

El usuario puede elegir el nivel de suavizado que desea. Cuando más alto sea el nivel, más lentamente deberá escribir para dar tiempo al programa a procesar todos los datos correctamente. A cambio obtendrá un trazo muy marcado y lineal.

Si los valores de utilización de las cámaras presentan un porcentaje elevado, se puede reducir considerablemente el valor del suavizado de línea, ya que el cursor presentará unos movimientos más estables. Cuanto pero es este valor, mas suavizado del cursor hay que aplicar, ya que el cursor presentará una vibración mayor a causa de la pérdida de precisión de los datos que envía el mando.

Para regular el nivel de suavizado del cursor, se dispone en el programa de una barra que se puede desplazar hacia arriba y hacia abajo. Puede regular el nivel entre 0 y 20. El nivel 0 desactiva el suavizado de línea. Los demás niveles indican la cantidad de datos que se han de recibir, para indicar al mando el punto al que tiene que ir. Si coloca el suavizado del cursor a 20, estará indicándole al programa que desea coger los últimos 20 datos enviados por cada mando para marcar una sola posición del cursor. Por tanto, tendrá que tener en cuenta que deberá reducir en gran cuantía la velocidad de escritura para que el programa interprete correctamente su escritura o sus movimientos.

El usuario podrá variar en todo momento el nivel del suavizado de cursor, adaptándolo a sus necesidades.

11.4.4.3 Control del cursor

Esta opción permite al usuario activar y desactivar el control del ratón mediante el

puntero infrarrojo. Cuando Control del cursor está marcado con , significa que puede controlar el mouse con el puntero infrarrojo. Cuando la casilla esta desmarcada, aunque usted mueva el puntero infrarrojo por la superficie de proyección, el mouse no hará ningún movimiento.

Figura 49. Zona de habilitación o deshabilitación del Control del cursor

Page 77: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

77

Esta opción es útil cuando se desea comprobar si la posición de los mandos es correcta en la ventana de ayuda a calibración. Por ese motivo, al abrir la ventana de ayuda a calibración, control del cursor se desactiva automáticamente. Al volver a cerrar esta ventana, se vuelve a activar.

En caso de que mueva el puntero infrarrojo por la superficie y el cursor del mouse no haga ningún movimiento, debe comprobar el estado de control del cursor, ya que puede ser el origen del problema.

Se deja a opción del usuario elegir en qué momento desea que el control del mouse por parte del puntero infrarrojo este habilitado, y en qué momento no.

11.4.4.4 Botón Calibrar

Este botón abre la ventana de calibración del sistema. Es necesario realizar una nueva calibración cada vez que se mueven los mandos de su posición. Debe realizar la calibración para delimitar el área de la proyección. Si el programa no conociera el área, no podría posicionar el puntero infrarrojo. Cualquier movimiento de los mandos o de la proyección variaría el área, con lo que tendría que volver a calibrar

El proceso de calibración es muy sencillo: Al pulsar el botón Calibrar, aparece una ventana blanca con una cruz roja pintada en la esquina superior izquierda. Debe colocar el puntero infrarrojo en el centro de la cruz y hacer una pulsación con el botón que hay en el puntero. El programa leerá las coordenadas de esa posición y pasará a la siguiente esquina, que será la superior derecha. Posteriormente irá a la esquina inferior izquierda y a la inferior derecha. En cada esquina debe colocar el puntero infrarrojo en el centro de la cruz y pulsar, para que la cruz vaya a la siguiente posición.

Una vez se han punteado todas las esquinas, ya se ha concluido la calibración. Si comprueba que el cursor está desviado respecto la posición del puntero infrarrojo, pruebe a calibrar de nuevo intentando apuntar el cursor justo en el centro de la cruz.

Intente ser lo más preciso posible apuntando al centro de la cruz roja, ya que sino la posición que se lee es errónea y el cursor ofrece un pequeño desvió respecto la posición del puntero infrarrojo.

11.4.4.5 Menú Abrir

El programa dispone de una barra en la parte superior con diversas opciones. El menú desplegable Abrir, ofrece la posibilidad de abrir los programas “Classroom Presenter

3” y “Click-N-Type” directamente desde Wiimote Board. De esta manera usted se ahorra

el tiempo necesario en localizar los accesos directos en el escritorio o en el menú de “Inicio”, y puede abrir de manera rápida y directa cualquiera de estas dos aplicaciones.

Page 78: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

78

Figura 50. Menú abrir desplegado

Si no se ha instalado ninguna de las dos, estas opciones estarán inoperativas, y se mostrará un error indicando que los programas no están instalados. Podrá seguir usando Wiimote Board sin ningún problema.

Si ha instalado uno de los programas y el otro no, se abrirá el que tenga instalado. Si intenta abrir el programa que no tiene instalado, aparecerá una ventana de error indicando que ese programa no está instalado. Clicando “Aceptar” esta ventana desaparecerá y podrá

seguir usando Wiimote Board.

Figura 51. Ventana de error que aparece en caso de fallo de apertura del programa

Es importante recordar que para que estas aplicaciones se puedan abrir desde Wiimote Board, es necesario que se instalen en el directorio que viene por defecto en la instalación de ambas aplicaciones.

11.4.4.6 Menú Ayuda Calibración

Pulsando encima de este menú aparece la ventana de ayuda a calibración en la parte inferior de la ventana principal del programa. Esta nueva ventana indica en qué lugar ve el puntero infrarrojo la cámara del Wiimote, cuando este está emitiendo luz infrarroja. Conociendo la posición del puntero para la cámara, podrá mover el mando hasta conseguir que vea la mayor área posible.

Recuerde que los puntos críticos para conocer esta área son las esquinas de la proyección. Si recorre las esquinas de la proyección con el puntero mientras observa la

Page 79: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

79

ventana de Ayuda de Calibración, podrá comprobar el área que el mando está utilizando para posicionar su cursor. Cuando mayor sea, mejor resultado ofrecerá el programa.

Esta opción se suele utilizar cuando se colocan los mandos en un lugar por primera vez, ya que permite encontrar una colocación muy buena en muy poco tiempo.

Al abrir la Ayuda de Calibración se desactiva automáticamente el Control del Cursor, para facilitar la tarea al usuario.

Para cerrar la Ayuda de Calibración, debe pulsar otra vez encima del menú Ayuda Calibración. Esta acción ara que la ventana se cierre y Control del Cursor se vuelva a activar de nuevo.

11.4.4.7 Menú Control del Ratón

Pulsando encima del menú Control del Ratón, aparece una nueva ventana con diversas opciones.

Figura 52. Ventana de selección de la función a hacer con el cursor

Esta ventana será siempre visible y aparecerá encima de las aplicaciones que tenga abiertas.

Pulsando encima de cualquiera de las opciones que aparecen en esta ventana, usted podrá utilizar su puntero infrarrojo para realizar cualquiera de estas acciones.

Las diferentes acciones que puede realizar son:

Doble clic: Si pulsa encima de ese botón con el puntero infrarrojo, las siguientes dos pulsaciones realizarán un doble clic en el lugar que usted desee. Esta opción es muy útil para abrir programas que tenga usted en el escritorio. Para hacerlo, solo debe de tener el icono que desea clicar y la ventana con las diferentes opciones visibles al mismo tiempo. Pulse y suelte el botón del puntero infrarrojo encima de Doble clic. A continuación, mueva el puntero infrarrojo hasta situarlo encima del icono sobre el que desea hacer doble clic. Pulse y suelte dos veces el botón del puntero infrarrojo y el programa se abrirá.

Clic derecho: Con esta opción, podrá realizar un clic derecho en cualquier lugar que usted desee. Solamente tiene que tener a la vista el lugar sobre el que desea realizar un clic derecho y la ventana con las diferentes opciones

Page 80: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

80

visible. Pulse y suelte el botón del puntero infrarrojo encima de clic derecho. Mueva el puntero infrarrojo hasta el lugar en el que quiera realizar la acción de dar con el clic derecho. Una vez se encuentre en el lugar pulse y suelte el botón del puntero infrarrojo. La acción de clic derecho se realizará y aparecerá un menú desplegable con diversas opciones.

Arrastre sin clicar: Si usted mueve el cursor por la proyección, observará que este se mantiene como si estuviera siempre el botón izquierdo del mouse

pulsado. Para evitar este efecto, puede pulsar la opción de Arrastre sin clicar. De esta manera usted podrá mover el mouse sin clicar encima de ningún icono. Si esta opción esta activa, el cuadrado que pone Arrastre activo

aparecerá . Para desactivar esta opción debe de mover el puntero infrarrojo por encima del botón “Reactivar”.

Reactivar: Se utiliza para desactivar la opción de Arrastre sin clicar. Si mueve el cursor del ratón por encima de este botón, comprobará que el

cuadrado blanco que aparece al lado del texto “Arrastre activo” pasa de a . Cuando el cuadrado no se encuentre marcado indicará que el arrastre sin

clicar está inactivo. Por tanto, cada vez que mueva el cursor este permanecerá clicado otra vez.

Para cerrar esta ventana únicamente hay que hacer clic encima de la cruz roja que está situada en la parte superior derecha de la ventana. Se puede volver a abrir cada vez que se desee pulsado nuevamente el menú “Control del ratón” situado

en la pantalla principal del programa.

11.4.4.8 Menú Acerca de

En este menú podrá encontrar información sobre la versión de programa que está utilizando y del fabricante de la misma. También dispondrá de una ventana que contiene una pequeña descripción de la función que realiza este programa, y el año en que se ha creado la última versión.

Figura 53. Ventana Acerca de

Page 81: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

81

Para cerrarla se puede pulsar el botón “OK” situado en la parte inferior derecha de la

ventana, o la cruz roja situada en la parte superior derecha.

Estas son todas las funciones que ofrece Wiimote Board. Si ha instalado las aplicaciones complementarias Classroom Presenter 3 y Click-N-Type no olvide consultar los manuales de uso de ambos programas. Estos manuales se encuentran en la página web de cada programa. Ambos están escritos en Ingles. Las páginas web que contienen los manuales son las siguientes:

Classroom Presenter 3: http://www.cs.washington.edu/research/edtech/presenter/doc/startguide3.html

Click-N-Type: http://www.lakefolks.org/cnt/features.htm

11.5 Información para colocar correctamente los mandos

Para una colocación correcta de los mandos, inicialmente los dos mandos deben colocarse aproximadamente a una distancia equivalente al doble de la altura de la proyección. Por tanto, si la proyección tiene una altura de 2 m, los mandos tienen que estar colocados a 4 metros de distancia de la superficie de proyección y mirando recto hacia ella [11].

Una vez los tenemos colocados a la distancia adecuada, se pueden mover en sentido circular alrededor de la superficie de proyección. Es decir, si la proyección tiene una altura de 2 metros, 4 metros será el radio del semicírculo sobre el cual podemos ir rotando los mandos alrededor de la superficie de proyección:

4m

Figura 54. Posicionamiento del mando cuando la proyección tiene una altura de 2 m

Los cuadrados azules simbolizan uno de los mandos. Este se puede girar alrededor de la superficie de proyección manteniendo el radio. Se deben de ir girando hasta encontrar el punto adecuado para cada usuario, ya que este punto dependerá mucho de la forma que tenga de escribir. También se puede acercar o alejar el mando, pero se recomienda como punto de partida el método explicado, ya que ofrece un ajuste más rápido del punto más adecuado.

En la imagen anterior aparece solo un mando que se mueve hacia la izquierda. El mando restante deberá de moverse hacia la derecha de la misma forma.

Page 82: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

82

Una vez se encuentre un lugar donde no se tapa a los mandos mientras se escribe, deberá alejar o acercar el mando para mejorar el porcentaje de utilización de la zona de visión del mando, siempre que este sea bajo. Si es superior al 50% no es necesario que mueva el mando. Deberá de utilizar el método de prueba y error hasta localizar la posición optima. Con la ventana de Ayuda a Calibración y aplicando este método, se tarda una media inferior a 6 intentos en localizar la posición más buena [11].

Si usted es diestro, deberá colocar con especial atención el mando que tenga situado a la izquierda de la proyección. Si por el contrario es zurdo, deberá procurar colocar con esmero el mando situado a la derecha de la proyección. El programa posicionará mejor el cursor cuanto más alto sea el porcentaje de utilización del mando indicado para cada caso.

La primera vez que se coloca el mando en un lugar donde no se ha utilizado antes este sistema, tardará aproximadamente 5 minutos en ponerlo en el lugar adecuado. Una vez que encuentre el punto adecuado, le será mucho más fácil colocar correctamente el mando la próxima vez que utilice este sistema en ese lugar.

11.6 Consideraciones a tener en cuenta según el tipo de instalación

11.6.1 Instalación fija

Si pretende colocar los mandos en un lugar fijo y no moverlos de ese lugar, debe de tener en cuenta las siguientes consideraciones:

Debe disponer de accesibilidad para cambiar las baterías, o conectar los mandos a la red eléctrica. Hay diversas tiendas online que venden adaptadores para poder conectar estos mandos a la red eléctrica y así no tener que preocuparse de cambiar las baterías.

Debe disponer de accesibilidad para pulsar los botones 1 y 2 de cada mando cuando desee conectarlos a su ordenador. En caso de que no pudiera acceder a ellos, es posible dejarlos pulsados continuamente con cualquier tipo de fijación. Esta acción no generaría ningún problema de uso, pero se recomienda que solo se realice cuando el mando esté conectado a una alimentación externa. Si fija los botones 1 y 2 y utiliza las pilas para alimentar los mandos, estas verán reducida su vida en gran cuantía, llegando a gastarse completamente en menos de un día. Si dispone de alimentación externa, puede instalar un interruptor en el cable del alimentador para encender los mandos cuando vaya a utilizarlos. Como los botones 1 y 2 se encontraran fijados, podrá conectarse sin tener que acceder a los mandos.

Otra opción es realizar una pequeña modificación en el mando para poder instalar un pulsador que nos permita activar la sincronización de los mandos a distancia. En la página web http://www.boonjin.com/smoothboard/index.php?title=Wiimote_modifications se explica cómo realizar estas modificaciones y que materiales se necesitan.

En esa página web también se explica cómo montar un sistema de alimentación externa para los Wiimotes, ya sea alimentándolos a través del USB del ordenador o conectándolos a la red eléctrica.

En caso de que no desee construir su propio sistema de alimentación externa, existen baterías recargables que reemplazan las pilas del mando, y que se pueden conectar a la red eléctrica por USB:

Page 83: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

83

Figura 55. Batería recargable para Wiimote

Con este producto, podría alimentar los mandos directamente desde la toma USB de su PC, o comprar un transformador de 220 V a 5V con conexión USB. Conectando el cable USB a la toma de este transformador, y conectando el transformador a cualquier enchufe ya tendría alimentado el Wiimote

Sugerencias de lugares donde colocar el mando en una instalación fija:

Encima del proyector,

A los lados del proyector, ya sea con la ayuda de un brazo metálico de extensión fijado al soporte del proyector, o con un brazo metálico fijado al techo.

En los laterales de la superficie de proyección, con la ayuda de un brazo metálico colocado en horizontal a esta superficie para conseguir que los mandos puedan ver la totalidad de la imagen proyectada.

11.6.2 Instalación móvil

Cuando usted realiza presentaciones en diferentes lugares y quiere dotarlas de interactividad, puede llevarse consigo los Wiimotes y instalarlos en cualquier lugar en el que se vea la imagen de la pantalla de su ordenador.

Deberá tener en cuenta que necesita llevar consigo un soporte para colocar los mandos, ya que estos deben de mantenerse fijos mientras utilice esta aplicación. Para fijarlos, es recomendable el uso de trípodes de cámara de fotos, o de soportes de micrófonos. Las pinzas de micrófono ofrecen una solución barata para poder colocar los mandos, ya que estos disponen de unas ranuras en los laterales en las que encajan las pinzas de micrófono. Deben de ser pinzas con muelle, para que se puedan abrir y cerrar.

Deberá comprobar que el lugar donde coloca los mandos es fijo y no presenta vibraciones, ya que estas afectarían al funcionamiento del programa.

También es importante que tenga en cuenta que deberá buscar la posición más adecuada de ambos mandos y calibrar el sistema. Este proceso ocupa aproximadamente entre 5 y 10 minutos.

Page 84: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

84

12 Presupuesto

El presupuesto necesario para el desarrollo de este proyecto es el siguiente:

Presupuesto desarrollo proyecto Descripción Unidades Precio unitario Precio total

Mando Nintendo RVL-CNT-01 "Wiimote" 2 Ud. 39,95 €/Ud 79,90 €

Soportes de micrófono Jirafa Plateado 2 Ud. 14,00 €/Ud 28,00 €

Marcador de pizarra blanca Bic Velleda 1 Ud. 1,24 €/Ud 1,24 €

Pulsador de membrana 12x12 mm 1 Ud. 0,36 €/Ud 0,36 €

Led infrarrojo Vishay TSAL 6400 1 Ud. 0,50 €/Ud 0,50 €

Condensador de tántalo de 47 µF 1 Ud. 4,40 €/Ud 4,40 €

Portapilas de pilas de tipo N 1 Ud. 0,49 €/Ud 0,49 €

Pila de tipo N 1 Ud. 2,14 €/Ud 2,14 €

Cable eléctrico unifilar de sección 0.5 mm 0,6 m 0,54 €/m 0,32 €

Horas de montaje del puntero infrarrojo 0,5 h 35 €/h 17,50 €

Horas de desarrollo del software 310 h 35 €/h 10.850,00 €

TOTAL 12.537,35 €

Si se prevén unas ventas de 1000 unidades para amortizar el coste de desarrollo del proyecto, el precio de venta de cada unidad de producto es el siguiente:

AMORTIZACIÓN

Previsión de ventas: 1000 unidades

Coste de materiales por unidad de producto 89,35 €

Coste de horas de montaje por unidad de producto 10,00 €

Coste de amortización del desarrollo del proyecto por unidad 10,90 €

Precio de venta de una unidad para amortizar coste de desarrollo del proyecto 110,25 €

Precio de venta de una unidad incluyendo un 10% de beneficio para la empresa distribuidora

121,27 €

El coste de horas montaje por unidad de producto asciende a 10,00 €, debido a que

para el montaje del puntero infrarrojo se ha tenido en cuenta que este puede ser montado por una persona con cualificación de Ciclo Formativo de Grado Medio en Electrónica. Tomando como sueldo para esta cualificación 20 €/h, y teniendo en cuenta que el puntero se puede montar en media hora, el precio final de montaje del puntero es de 10,00 €. El

coste de las horas de montaje del puntero realizado durante el desarrollo del proyecto se ha incluido como coste a amortizar.

Si se desea amortizar el desarrollo del producto con la venta de 1000 unidades sin obtener beneficio alguno, el precio de venta por unidad de producto asciende a 110,25 €. En este precio se incluyen los dos Wiimotes necesarios para el funcionamiento de la aplicación y el puntero infrarrojo, montado y funcionando.

Si por el contrario, se desea obtener un beneficio con la venta de estas unidades, se ha calculado el precio por unidad de producto que ofrecería un 10% de beneficio sobre el precio final. El beneficio obtenido en la venta de cada unidad seria de 11,02 € por unidad.

El precio final de venta de una unidad de producto con estos requisitos asciende a 121,27 €.

Page 85: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

85

13 Bibliografía y referencias

13.1 Referencias

[1] Página Web http://es.wikipedia.org/wiki/Pizarra_digital [Pizarra interactiva] 27/04/09

[2] Página Web http://www.taringa.net/posts/info/1843549/C%C3%B3mo-funciona-el-Wiimote.html [Funcionamiento del Wiimote] 11/05/09

[3] Página Web http://www.wiibrew.org/wiki/Wiimote#Bluetooth_Communication [Trama de datos del Wiimote] 11/05/09

[4] Página Web http://johnnylee.net/projects/wii/ [programa Wiimote Whiteboard v0.3] 13/05/09

[5] Página Web http://www.codeplex.com/WiimoteLib [librería WiimoteLib_v1.7] 13/05/09

[6] Página Web http://classroompresenter.cs.washington.edu/ [Classroom Presenter 3] 21/05/09

[7] Página Web http://cnt.lakefolks.org/es-intro.htm [Click-N-Type] 21/05/09

[8] Página Web http://johnnylee.net/projects/wii/pen.jpg [Esquema de montaje y componentes del puntero infrarrojo] 22/05/09

[9] Página Web http://www.datasheetarchive.com/pdf-datasheets/Databooks-3/Book518-398.pdf [Datasheet Telefunken CQY 99] 22/05/09

[10] Página Web http://www.vishay.com/docs/81011/tsal6400.pdf [Datasheet Vishay TSAL 6400] 22/05/09

[11] Página Web http://www.boonjin.com/smoothboard/index.php?title=Mount_and_position_the_Wiimote#Positioning_the_Wiimote [Positioning the Wiimote] 23/05/09

13.2 Bibliografía

Albahari, Joseph; Albahari, Ben. C# 3.0 pocket reference. 2ª ed. Sebastopol : O'Reilly, 2008.

Ceballos Sierra, Francisco Javier. El Lenguaje de programación C#. Madrid : RA-MA, 2002.

Davis, Stephen Randy; Sphar, Chuck. C# 2005 for dummies. Hoboken: Wiley, 2006.

Mayo, Joseph. C# al descubierto. Madrid : Prentice Hall, 2002.

Peek, Brian; Fernandez, Dan. Coding4Fun. Sebastopol : O'Reilly Media, Inc., 2009.

Page 86: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

86

a

1

0.38

a

1

0.28

14 Anexo

14.1 Estudios

14.1.1 Estudio del porcentaje de visión de la cámara del Wiimote según la posición en la

que se encuentre el mando.

Para poder realizar cualquier estudio, primero hay que conocer los ángulos de visión de la cámara integrada en los Wiimotes.

Coloqué el mando a una distancia de 1 metro de la superficie de proyección, y enfocado al punto medio de la misma, de manera que el mando quedara perpendicular a esta superficie. Mediante el uso de un nivel me aseguré que tuviera un ángulo de 0º respecto al suelo.

Una vez asegurada la correcta colocación del mando, ejecuté el programa Wiimote Board. Mediante el uso de la ventana “Ayuda calibración”, comprobé en qué posición se encontraban las esquinas que veía el mando esa distancia, y las marqué. Una vez marcadas las 4 esquinas, medí la distancia entre cada una obteniendo los siguientes resultados:

Medición X abajo X arriba Y izquierda Y derecha X media(cm) Y media (cm) 1 75,75 77,15 56 57,2 76,45 56,6 2 76,8 77,45 57,1 57,1 77,125 57,1 3 75 76,2 56,25 55,1 75,6 55,675

Media total 76,45 56,6

Tabla 8. Distancias de visión del mando colocándolo a 1 metro alejado de la proyección

Con estas distancias medidas y aplicando conceptos básicos de trigonometría, se puede conseguir obtener el ángulo de visión del mando, tanto en horizontal como en vertical.

Para conseguirlo, aplicamos el siguiente procedimiento:

Page 87: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

87

a

3

2.5

h

20.820.8

Se obtiene como resultado que el ángulo de visión horizontal es de 41.61º y el vertical de 31.55º.

Conociendo estos datos se puede sacar el valor de uso de la visión de la cámara en tanto por ciento, para cualquier punto dado, mediante la aplicación de cálculos trigonométricos.

En este estudio tomaremos que la proyección tiene una anchura de 1.9 m. Para desarrollar la explicación de los cálculos llevados a cabo, se toma que desde la mitad de la proyección hasta donde está el mando hay una distancia de 3 metros en horizontal y 2.5 en vertical. El punto medio de visión del mando se enfocará al punto medio de la pizarra durante todo el desarrollo del estudio. Esto significará, que desde el punto medio de la proyección, el mando ve 20.80 º hacia el lado izquierdo y 20.80 grados hacia el lado derecho. También durante el estudio se toma como referencia que el mando no está inclinado respecto a la vertical, es decir que presenta un ángulo de 0 º respecto al suelo.

Mediante la aplicación de leyes trigonométricas se obtiene la distancia de dos rectas. Una de ellas indica los metros de visión hábil del mando. La otra, los metros de visión utilizada para ver la proyección. La división entre estas dos distancias dará como resultado el porcentaje de uso de la visión total que ofrece el mando.

El desarrollo matemático es el siguiente:

Como primer pasó, se ha de obtener la longitud de la línea que conecta el punto medio de la cámara del mando con el punto medio de la proyección, para poder sacar todos los demás ángulos posteriormente.

Una vez tenemos el ángulo total desde la pared hasta el centro de la proyección, y la distancia de la hipotenusa, hay que obtener los metros de visión del mando. Utilizando el valor de h que hemos encontrado anteriormente se puede calcular la longitud de la línea marcada en negro. Esta línea delimita la longitud que es capaz de ver la cámara del mando.

20.8

3.95

x

Page 88: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

88

Una vez obtenida la distancia que es capaz de ver el mando en total, se ha de conseguir calcular la distancia que el mando utiliza para ver la proyección desde la posición que hemos supuesto. Para hacerlo, primero se calcula el ángulo desde la pared hasta la esquina derecha de la proyección. Este ángulo se restará después al que hemos obtenido anteriormente, que iba desde la pared hasta el punto medio del ángulo. Posteriormente se lleva a cabo el mismo cálculo para el lateral izquierdo de la proyección. La pizarra mide 1.90 m. Como cogemos la mitad de esta para calcular los ángulos por separado, en una medición se suma 1.90 / 2 = 0.95, y en la otra se resta ese valor. Recordar que el punto medio de la proyección se encuentra a 3 metros en horizontal y 2.5 en vertical respecto al mando.

α

βγ

3 m 0.95 m

2.5 m

Page 89: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

89

α

δθ

3 m 0.95 m

2.5 m

Teniendo los ángulos γ y θ, podemos definir dos triángulos, de los cuales conocemos el ángulo y uno de los lados, que será el valor de h que hemos calculado anteriormente, 3.9. Por tanto, se puede obtener el lado restante de ambos triángulos, que en este caso será la distancia que se desea encontrar, simbolizada por una línea más oscura en el siguiente dibujo:

θ γ

Como los ángulos son diferentes, las distancias también, ya que dependen de la posición y orientación del mando. El cálculo de las distancias es el siguiente:

Page 90: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

90

Los resultados obtenidos son: la distancia de visión del mando es de 2.96 m, mientras que la distancia de visión utilizada para ver toda la proyección es de 1.256 m. Por tanto, se están desperdiciando 1.7 m de visión del mando desde esa posición. En porcentaje sería el siguiente dato:

Se utiliza un 42 % del total de la visión de la cámara si se coloca el mando a 3 metros en horizontal desde el punto medio de la proyección, y separado 2.5 metros en vertical.

Aplicando este procedimiento a un programa de cálculo se obtienen los siguientes resultados, según el ángulo al que coloquemos el mando respecto la proyección y el radio que haya entre el punto medio de la proyección y el mando. Se toman movimientos circulares de radio X alrededor del punto medio de la proyección:

Con Radio = 2.76 m

Ángulo del mando (°) Porcentaje de visión (%)

80 89,53184958

75 88,20151782

70 86,32142884

65 83,87567522

60 80,84629437

55 77,21517878

50 72,96641563

45 68,08900118

40 62,57981857

35 56,44669772

30 49,71130259

25 42,41152799

20 34,60305694

15 26,35974869

10 17,77261164

5 8,947266051

Tabla 9. Porcentaje de visión del mando a diferentes ángulos con un radio de 2.76 m

Page 91: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

91

Con Radio = 2 m

Ángulo del mando (°) Porcentaje de visión (%)

80 123,9558834

75 122,605151

70 120,6571539

65 118,0565861

60 114,7351465

55 110,6143679

50 105,6098147

45 99,63696416

40 92,61896974

35 84,49625421

30 75,23747579

25 64,85087239

20 53,3944126

15 40,98274471

10 27,78887004

5 14,03897655

Tabla 10. Porcentaje de visión del mando a diferentes ángulos con un radio de 2 m

Con Radio = 2.5 m

Ángulo del mando (°) Porcentaje de visión (%)

80 98,92076705

75 97,54522818

70 95,5928239

65 93,03885164

60 89,85443899

55 86,00886622

50 81,47251881

45 76,22045194

40 70,23646821

35 63,51749897

30 56,07794925

25 47,95353903

20 39,20408482

15 29,91465379

10 20,1946252

5 10,17442111

Tabla 11. Porcentaje de visión del mando a diferentes ángulos con un radio de 2.5 m

Page 92: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

92

Con Radio = 3 m

Ángulo del mando (°) Porcentaje de visión (%)

80 82,32396581

75 81,04580915

70 79,24465213

65 76,91023969

60 74,03150686

55 70,59815703

50 66,60254787

45 62,04182071

40 56,92016813

35 51,25108886

30 45,05943442

25 38,38301924

20 31,27355748

15 23,79671553

10 16,03113652

5 8,06639851

Tabla 12. Porcentaje de visión del mando a diferentes ángulos con un radio de 3 m

Se comprueba primero el radio de 2.76 m, porque tal como se indica en el manual, la distancia óptima es aproximadamente el doble de la altura de la proyección. La proyección del proyector que usé para realizar las diferentes pruebas es de 1.38 m. Con estos resultados, se comprueba el porcentaje con ese radio y con un radio más próximo y más lejano.

14.1.1.1 Resultados

El primer resultado que se puede apreciar, es la incapacidad de visión si colocamos el mando a un radio de 2 metros y con un ángulo mayor a 45º. Se comprueba que por encima de ese ángulo, el porcentaje es mayor a 100, lo que significa que habría una zona de la proyección que no vería. También se obtiene de este estudio, que si se desea colocar el mando con un ángulo de 45º, 2 metros de longitud es la posición óptima. Hay que tener en cuenta que estas distancias están medidas sobre una proyección de 1.38 m de alto por 1.90 m de ancho.

De este resultado se podría extrapolar que si se coloca el mando a 45 º de ángulo respecto la proyección, la distancia a la que debe estar este es un 27 % menor a multiplicar 2 veces la altura de la proyección, aproximadamente.

Page 93: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

93

Comparando los valores de la tabla obtenida con un radio de 2.76 m con las de radio de 2.50 m, se detecta que los valores de uso de cámara de la última son más altos. Por tanto, con un radio de 2.5 m se ve mejor la superficie para todo el rango de diferentes ángulos de este estudio, que va de los 5 º a los 80 º. El problema que se presenta es que colocando el mando a 2.5 m, se utiliza un rango de visión tan elevado que cualquier movimiento de la proyección o del mando puede ocasionar una pérdida de visión de la proyección, en especial cuando el mando se encuentra a un ángulo de 80 º. Es preferible dejar un margen de error para tener cierta tolerancia en el punto de colocación del mando, ya que es muy complicado colocarlo en el punto exacto de distancia y ángulo.

La pérdida de visión de colocarlo a 2.76 m respecto colocarlo a 2.5 m es de 9.38 % en el caso más desfavorable.

Por tanto, el cálculo d = 2h, resulta ser una aproximación muy buena al valor óptimo, y te permite cierto margen de error en la colocación del mando. Se demuestra que el resultado es muy bueno, con lo que se recomienda el uso de este.

Se comprueba también que ampliar el radio a una distancia mayor a d = 2h, da como resultado una disminución de la utilización del área de visión de la cámara. No habría que alejar el mando más de 2.76 m, porque a esa distancia el porcentaje de visión es bueno para un gran espectro de diferentes ángulos.

Mediante el testeo de la aplicación, se puede comprobar que porcentajes inferiores al 30 % ofrecen resultados no admisibles para dibujar con una calidad mínima. Del 30% al 50 % se puede dibujar con muy baja calidad y a partir del 50 % la calidad es bastante buena. Esto ocurre porque la resolución va creciendo según aumenta el uso del área de visión de la cámara. Con un valor de uso inferior al 30%, el programa funciona pero la resolución es tan baja que crea líneas al escribir, ya que no detecta cambios de posición hasta que el usuario mueve unos cuantos centímetros el puntero. Por este motivo, valores inferiores al 30 % se deberían descartar.

Si se comprueban los datos de las tablas, a un radio de 2.76 m el ángulo máximo al que se podría poner el mando, siguiendo el criterio explicado anteriormente, sería de 20 º. Para poder ponerlo con un ángulo inferior, se debería colocar el mando a 2 metros de la proyección, y solo se admitirá como ángulo máximo 15º.

Por tanto, para ángulos de 10º o 5º queda descartado el uso de este sistema, ya que se deberían de colocar tan cerca de la proyección para ofrecer una visión mayor al 30% que interferirían al usuario de la misma.

Para ángulos inferiores a 45º, se recomienda colocar el mando más cerca de la proyección. El uso del cálculo “d = 73% * 2h”ofrece unos resultados muy buenos para

conocer la posición donde colocar el mando con ángulos que van desde los 45º hasta los 15º.

14.1.2 Estudio del porcentaje de visión de la cámara del Wiimote según la posición en la

que se encuentre el mando, con un obstáculo delante.

Se introduce un obstáculo en el cálculo del porcentaje de visión, para ver cómo afecta a este una persona escribiendo delante de la proyección.

Page 94: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

94

Este obstáculo se coloca separado a 50 cm de distancia de la proyección, y a 57 cm en horizontal del lateral izquierdo de la proyección, en sentido hacia dentro de la proyección. Los datos del tamaño de la superficie de proyección y de la colocación del mando son los mismos que los utilizados en el estudio anterior. En este caso el radio se mantiene siempre constante a 2.76 m durante todo el estudio.

Recordar que el obstáculo tiene un radio de 20 cm, y que al indicar la posición del mismo a lo largo de todo el estudio, lo que se indica es el centro de la circunferencia que representa el obstáculo.

En este caso se comprobará la afectación del obstáculo de manera visual, ya que se demuestra de forma mucho más clara como afecta a la visión total del mando. Con líneas verdes se representa la capacidad de visión máxima de los mandos. Con líneas azules se representa la zona de visión del mando utilizada. Las líneas moradas indican la zona que deja de verse por efecto del obstáculo.

Se obtienen los siguientes resultados:

Mando a 60º

Figura 56. Visión del mando a 60º con zona oscura producida por presencia de obstáculo

Colocando los mandos a 60º, se calcula que la distancia que tapa el obstáculo de la visión de la cámara es de 42.92 cm. Por tanto, para conocer la visión resultante restamos la distancia que tapa el obstáculo de la distancia que el mando utiliza para ver la proyección, y se divide de la distancia total que ve el mando para extraer el resultado en porcentaje:

La pérdida de visión respecto a la situación en la que no había obstáculo es del 24.72%.

Existe una zona oscura de un tamaño de 58 cm, la cual empieza a 56 cm del lateral izquierdo de la proyección. Se llama zona oscura aquella en la que el mando pierde visión directa del puntero IR a causa de un obstáculo en la zona de escritura.

Page 95: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

95

Mando a 45º

Figura 57. Visión del mando a 45º con zona oscura producida por presencia de obstáculo

En esta posición, el obstáculo tapa 38.07 cm de visión del mando.

La pérdida de visión es del 24.03 %.

Existe una zona oscura con una extensión de 84 cm que empieza a una distancia de 84 cm del lateral izquierdo de la proyección. Esta zona oscura afecta mayoritariamente la mitad derecha de la proyección en toda su extensión.

Mando a 30º

Figura 58. Visión del mando a 30º con zona oscura producida por presencia de obstáculo

En esta posición, el obstáculo tapa 21.56 cm de visión del mando

Page 96: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

96

La pérdida de visión es del 15.01%.

Existe una zona oscura con una extensión de 84 cm que empieza a una distancia de 1.06 cm del lateral izquierdo de la proyección y afecta a toda la proyección desde esa distancia.

Mando a 15º

Figura 59. Visión del mando a 15º con zona oscura producida por presencia de obstáculo

Si se coloca el mando a 15º, dispone del menor porcentaje de uso de la visión de la cámara de todo el estudio, pero no le afecta el obstáculo.

No existen zonas oscuras con este ángulo.

Visión = Visión sin obstáculo = 26.35 %

Pérdida de visión = 0%

14.1.2.1 Resultados

Se comprueba que incrementos del ángulo mayores a 45 º no producen un aumento significativo de pérdida de visión. Se puede ver como a 45º la pérdida de visión es del 24.03 % y a 60 º del 24.72 %. Esto significa que para un incremento de 15 º, la pérdida de visión ha aumentando en 0.69%. Este incremento es insignificante respecto al ángulo en que se ha movido el mando. Por tanto, la afectación del obstáculo no variará mucho respecto si tenemos el mando a 45 º o a un ángulo mayor a este.

Para ángulos inferiores a 45º, sí que representa un cambio notable. A 30º se comprueba que la pérdida de visión es de tan solo un 15 %, mientras que a 15º el ángulo es tan grande que el obstáculo solo afectaría si estuviera muy cerca de la proyección. En estos

Page 97: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

97

casos se debe comprobar la visión del mando, para saber que mando ofrece un resultado aceptable. A 30º, el mando ofrece una visión del 35.74 % y a 15 º de 26.35 %. La diferencia entre ambos es de 9.39 %.

Colocar el mando a 15º evitaría que el obstáculo afectara a la visión, pero a cambio el porcentaje de uso de la cámara sería muy bajo, con lo que el movimiento del ratón sería muy impreciso y errático, trazando puntos muy alejados entre sí. En caso de que el usuario no tenga mucho interés en dibujar texto o líneas precisas, se le recomendaría colocar el mando con este ángulo, ya que evitaría ser tapado.

La solución más equilibrada seria colocar el mando a 30º, ya que la pérdida de visión es baja y el porcentaje de utilización de la cámara asegura que el movimiento del cursor será más suave. Colocando el mando a este ángulo se obtendría un movimiento poco fluido y de baja calidad, pero se podría escribir texto.

Para ofrecer unos resultados de visión que garanticen que el movimiento del ratón sea lo más fluido posible, se recomienda colocar el mando a 60º. La posición de 45º no ofrece ningún beneficio respecto a la de 60º, ya que la diferencia de pérdida de visión en ambas posiciones es muy baja, y por el contrario, el porcentaje de visión del mando a 45º sí que es mucho más bajo que a 60º. En el caso de colocar el mando a este ángulo, el usuario debería tener en cuenta que debe escribir mirando con el puntero hacia el mando lo máximo posible, ya que sino existe una zona oscura de 58 cm donde no se vería el puntero. Esta posición asegura que si se escribe texto se haga con claridad, pero presenta una zona en la que no se puede utilizar el puntero si el usuario está de espaldas al mando.

14.1.3 Estudio de la mejora de visión con dos Wiimotes respecto a un solo Wiimote, con

obstáculo estándar.

Para la realización de este estudio, se parte del obstáculo comentado anteriormente, al cual recibe el nombre de obstáculo estándar, ya que representa una persona en posición de escritura delante del proyector. Recordar que este obstáculo se encontraba separado a 50 cm de distancia de la proyección, y a 57 cm en horizontal del lateral izquierdo de la proyección, en sentido hacia dentro de la proyección.

En la realización de este estudio se intenta demostrar como la inclusión de un segundo mando evita las pérdidas de visión del puntero infrarrojo.

Igual que en los anteriores estudios, se toman las mismas medidas de la proyección y un radio de 2.76 m alrededor de la proyección.

Las líneas verdes representan la capacidad de visión máxima de los mandos. Las líneas azules representan la zona de visión del mando utilizada. Las líneas moradas indican la zona que deja de verse por efecto del obstáculo.

Recordar que el obstáculo tiene un radio de 20 cm, y que al indicar la posición del mismo a lo largo de todo el estudio, lo que se indica es el centro de la circunferencia que representa el obstáculo.

Los diferentes ángulos a los que se ponen los mandos durante la realización del estudio indican el ángulo existente entre la proyección y uno u otro mando. Ambos mandos se colocan siempre al mismo ángulo respecto la proyección.

Page 98: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

98

Los resultados obtenidos son los siguientes:

Mandos a 60º

Figura 60. Visión de dos mandos colocados a 60º con obstáculo estándar

En este caso ambos mandos se colocan con un ángulo de 60º respecto la proyección, lo que significa que están separados entre ellos también 60º.

En este caso se comprueba visualmente que al incluir el segundo mando, no se crea ningún punto oscuro, ya que la zona oscura que presenta un mando es vista desde el otro mando. Por tanto, uno u otro mando verán el puntero infrarrojo en cualquier posición que se encuentre, evitando la existencia de puntos oscuros.

No existe zona oscura cuando las líneas moradas se cruzan en un punto, ya que esto significa que la zona oscura para un mando es vista desde el otro, y de la misma manera para el mando contrario.

Comprobando los datos de pérdida de visión del anterior estudio realizado, se extrae que la mejora conseguida introduciendo un segundo mando es del 24.72%, ya que se evita la pérdida de visión.

Page 99: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

99

Mandos a 45º

Figura 61. Visión de dos mandos colocados a 45º con obstáculo estándar.

Se aprecia en la imagen como las líneas moradas se cruzan en un punto, lo que significa que no hay zona oscura con la inclusión de un segundo mando.

Se puede comprobar visualmente como la afectación que ofrece el obstáculo para este ángulo en el mando que se encuentra a la derecha es muy baja, y que esa zona es vista por el otro mando. De la misma manera, la zona de visión del mando izquierdo que es inutilizada por el obstáculo, es vista desde el mando derecho, evitando en su conjunto la aparición de puntos oscuros.

Para obtener la mejora de visión, comprobamos el valor de pérdida de visión del anterior estudio, ya que esta pérdida será la que se habrá evitado con la inclusión de un segundo mando.

Mejora de visión respecto a tener un solo mando = 24.03 %

Mandos a 30º

Figura 62. Visión de los mandos a 30º con obstáculo estándar

Colocando los mandos con este ángulo y aplicando el obstáculo estándar se aprecia como el mando situado a la derecha tiene una plena visión de la proyección, y no hay

Page 100: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

100

ningún tipo de afectación por parte del obstáculo. De esta manera se garantiza que el mando de la derecha siempre verá la proyección, evitando la aparición de puntos oscuros.

Mejora de visión respecto a tener un solo mando = 15.01 %

Mandos a 15º

Figura 63. Visión de los mandos a 15º con obstáculo estándar.

Es evidente que si a 30º el obstáculo ya no afectaba uno de los mandos, a 15º tampoco lo hará. En este caso se comprueba que el obstáculo no afecta a ninguno de los mandos, teniendo ambos amplia visión de la proyección.

En este caso la mejora de incorporar un mando adicional es nula, ya que un solo mando podría ver la totalidad de la proyección sin problemas. Pero hay que tener en cuenta que estos valores se ofrecen con el obstáculo en la posición en la que se encuentra en la imagen. Si este se moviera, habría una ligera mejora.

Mejora de visión respecto a tener un solo mando = 0%

14.1.3.1 Resultados

A lo largo del estudio se puede comprobar cómo la incorporación de un segundo mando mejora notablemente la funcionalidad de esta aplicación. Únicamente observando el estudio para los mandos colocados a 60º, se puede apreciar que la combinación de la visión de ambos mandos evita la aparición de puntos oscuros. Por tanto, se pasa de tener una zona de 58 cm inutilizables (para este ángulo en concreto) a disponer de toda la superficie de proyección. Al margen del valor numérico de mejora de incorporar un mando, este cambio incrementa el valor de uso de la aplicación en sí, ya que disponer de una pizarra digital interactiva en la que no se puede escribir en 58 cm de proyección reduce el rango de utilidad del producto considerablemente.

Page 101: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

101

Por tanto, la inclusión de un segundo mando mejora en una gran cuantía la capacidad de uso de este proyecto, ya que permite ver el puntero infrarrojo colocando los mandos en un amplio rango de diferentes ángulos, y con un obstáculo delante que dificulta la visión.

Únicamente no se presenta mejora cuando los mandos se colocan a 15º, pero este tipo de colocación es bastante inusual por el bajo valor de uso de la visión de la cámara, el cual produce que el movimiento del cursor vaya a golpes y ofrece un trazo de muy baja calidad y muy irregular. Para los demás ángulos, la mejora radica en la eliminación total de los puntos oscuros, y el valor numérico de mejora equivale al porcentaje de visión que se perdía con el uso de un solo mando.

Se comprueba que la inclusión de un segundo mando eleva el rango de utilización del proyecto de manera considerable, ya que sin él, la aplicación ofrecería una gran cantidad de zonas oscuras donde no se podría realizar ninguna acción con el puntero. Por tanto, queda justificada la inclusión de un segundo mando.

14.1.4 Estudio de la mejora de visión con dos Wiimotes respecto a un solo Wiimote, con

obstáculo en la posición más problemática.

Con la realización de este estudio se pretende conseguir el porcentaje de mejora mínimo de incluir un mando adicional, para cada diferente ángulo al que se coloquen ambos mandos.

Para obtener el valor mínimo de mejora, se coloca el obstáculo en el peor sitio posible para cada ángulo. Posteriormente, se miden los metros de zona oscura que habría con un solo mando y se le resta los metros de zona oscura existentes con los dos mandos. El resultado se divide de los metros totales de la proyección, lo que da como resultado el porcentaje de mejora.

Recordar que la zona oscura es aquella zona de proyección que un mando deja de ver a causa de que hay un obstáculo delante que impide la visión de esa zona. También hay que indicar que el obstáculo tiene un radio de 20 cm, y que al indicar la posición del mismo a lo largo de todo el estudio, lo que se indica es el centro de la circunferencia que representa el obstáculo.

Para la realización de este estudio se parten de la misma proyección que en los estudios anteriores, y se mantiene siempre un radio de 2.76 m.

Las líneas verdes representan la capacidad de visión máxima de los mandos. Las líneas azules representan la zona de visión del mando utilizada. Las líneas moradas indican la zona que deja de verse por efecto del obstáculo.

Los diferentes ángulos a los que se ponen los mandos durante la realización del estudio indican el ángulo existente entre la proyección y uno u otro mando. Ambos mandos se colocan siempre al mismo ángulo respecto la proyección.

Page 102: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

102

Los resultados obtenidos son los siguientes:

Mandos a 60º

Figura 64. Visión de los mandos a 60º con obstáculo en la peor posición

Mediante el uso de un programa de representación gráfica, se intenta establecer el punto aproximado en el que el obstáculo tapa a los dos mandos. Este punto se encuentra alejado 28 cm de la proyección, y a 24 cm hacia dentro del lateral izquierdo de la proyección.

Colocando el obstáculo en esa posición, aparece una zona oscura de 16 cm de ancho que empieza a una distancia de 9 cm del lateral izquierdo de la proyección. El porcentaje de mejora que se consigue con la incorporación de un mando adicional es el siguiente:

Este cálculo se obtiene siguiendo la metodología explicada en el inicio del estudio.

Con el obstáculo en la posición donde afecta más a ambos mandos, se encontraría tapada un 8.42 % de la superficie, mientras que si solo hubiera el mando de la izquierda (el que peor visión tiene con el obstáculo), el porcentaje de zona afectada seria del 25.26 %. Para extraer estos valores, se divide la zona oscura que habría con un mando y con dos mandos. Los valores de estas zonas oscuras se encuentran en el numerador de la fórmula utilizada para obtener el porcentaje de mejora. En este caso, la zona oscura que habría con un mando seria de 48 cm y la zona oscura resultante con dos mandos de 16 cm.

Page 103: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

103

Mandos a 45º

Figura 65. Visión de los mandos a 45º con obstáculo en la peor posición

En este caso, el centro del obstáculo se encuentra alejado 27 cm de la proyección y a 39 cm del lateral derecho de la proyección.

Con el obstáculo en esta posición y los mandos a 45º respecto la proyección, existe un punto oscuro muy pequeño, de tan solo 3 cm de ancho. Esta zona tiene su inicio a 33 cm del lateral derecho de la proyección.

Se comprueba que con dos mandos posicionados a 45º y con este obstáculo, no se podría utilizar un 1.57 % del total de la proyección, mientras que si solo se tuviera un mando esta superficie no hábil llegaría al 32.63%.

Page 104: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

104

Mandos a 30º

Figura 66. Visión de los mandos a 30º con obstáculo en la peor posición

Para este ángulo, se coloca el centro del obstáculo alejado 22 cm de distancia de la proyección, y a 18 cm del lateral izquierdo de la proyección.

Con el obstáculo en este punto, se crea un punto oscuro de 5 cm de ancho que se inicia a 13 cm del lateral izquierdo de la proyección. Este punto oscuro es muy pequeño y su afectación será muy baja.

Mandos a 15º

Page 105: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

105

Figura 67. Visión de los mandos a 15º con obstáculo en la peor posición

El obstáculo en este caso se encuentra alejado 22 cm de la proyección y a 66 cm del lateral derecho.

Con este obstáculo y los mandos a 15º, no aparece zona oscura por un margen muy pequeño. Hay apenas 1 cm en los que ambos mandos pueden ver conjuntamente, aunque tengan el obstáculo delante.

Por tanto, con este ángulo se puede tener la certeza de que no habrá zonas oscuras aunque el obstáculo se encuentre situado en el peor lugar, siempre que se tengan dos mandos actuando conjuntamente.

Se puede apreciar como situando el obstáculo en esta posición, con un solo mando se perdería la visión de la mayor parte de la zona derecha o izquierda de la proyección, según si el mando se colocara a la izquierda o la derecha respectivamente. En cambio, con dos mandos se evita la aparición de zonas oscuras en toda la superficie de proyección. Por tanto, la mejora que se consigue al añadir un segundo mando es notable. En porcentajes, se obtendrían los siguientes resultados:

Mandos a 10º

En este estudio se incluye la valoración de la mejora cuando los mandos se encuentran a 10º, para demostrar que en esta posición la mejora es muy baja y el porcentaje de uso de la cámara también; con lo que no ofrece ningún beneficio ni resulta útil para el correcto funcionamiento de este proyecto.

Page 106: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

106

Figura 68. Visión de los mandos a 10º con obstáculo en la peor posición

El obstáculo se encuentra alejado 24 cm de la proyección y separado 85 cm del lateral derecho.

Con los mandos a un ángulo de 10º respecto a la proyección, se obtienen los siguientes resultados:

El porcentaje de mejora respecto a colocar los mandos a 15º es del 0.52 %, mientras que el porcentaje de uso de la visión de la cámara se decrementa en un 8.58 % en cada mando, debido al cambio de ángulo. Por tanto, la utilización de este ángulo no ofrece ningún beneficio para el usuario, ya que la resolución es muy baja con este ángulo respecto a 15º, y el beneficio es casi inexistente. No se ganaría nada pero se perdería una parte importante de resolución.

Por ese motivo, no se debe utilizar un ángulo inferior o igual a 10º para el correcto funcionamiento de este proyecto.

14.1.4.1 Resultados

Se puede comprobar cómo la mejora de visión mínima es del 16.84 %, la cual se da cuando los mandos se encuentran a un ángulo de 60º.

Este valor es suficientemente grande como para ser tenido en cuenta, ya que por 40 € mas (el coste de un Wiimote), se mejora el resultado del proyecto un 16.84 % mínimo. Esto significa que por cada euro invertido se mejora un 2.31 % mínimo la visión de los mandos.

También se obtiene como resultado, que la mejora de visión no aumenta cuanto más se reduce el ángulo, sino que presenta su mayor valor a 30º. Tanto a 15º como a 45º, la mejora es inferior a la conseguida a 30º. Para este ángulo, se pierde una zona de proyección mayor que con el ángulo de 45º, pero aun así el porcentaje de mejora es mayor. Este fenómeno se debe a que la zona que se pierde con un solo mando para el caso en el que el obstáculo se encuentra colocado en la peor posición, es mayor para un ángulo de 30º que para el de 45º. Como el obstáculo se mueve respecto los diferentes ángulos, para un ángulo de 30º afecta mucho más la posición de este en caso de que solo se tuviera un mando que en el caso en el que se tiene a 45º.

Se puede apreciar como colocando el mando a 30º, el obstáculo afecta muy poco a la visión del mando situado a la derecha. Por este motivo, este mando será capaz de cubrir una zona de proyección muy amplia, y supondrá un incremento de la mejora respecto a tener un solo mando situado a este ángulo.

Page 107: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

107

A pesar de todo, la zona oscura de la proyección a 30º ocupa un 2.63%, mientras que a 45º ocupa un 1.57% del total de la proyección. Por tanto, colocando los mandos a 45º se consigue tener una visión más amplia de la proyección, aunque el porcentaje de mejora conseguido introduciendo un mando adicional es menor.

Como resultados de este estudio, se obtiene que colocar el mando a 45º sería la opción más equilibrada, ya que para este ángulo el porcentaje de visión es muy elevado y la zona oscura es de 3 cm de ancho en el peor caso, lo que representa un 1.57% del total de la superficie. Si en este punto el usuario intentara escribir mirando hacía uno de los mandos, la cámara podría captar el puntero infrarrojo y por tanto podría escribir en esa zona.

Con un ángulo de 15º se obtiene que nunca se tapará la proyección, ni en el peor caso, pero la resolución de los mandos será muy baja. Esto causará que en caso de escribir texto cueste mucho escribirlo con claridad. En cambio, a 45º, la resolución es mucho mayor y la zona oscura es muy pequeña. Por ese motivo se recomienda colocar los mandos a 45º.

En este estudio también se comprueba que colocando un solo mando a 15º no se podría ver siempre la totalidad de la proyección, ya que en caso de tener el obstáculo situado en el peor punto, la visión del mando quedaría tapada por este. En cambio, incluyendo un mando adicional se vería la zona oscura resultante con el uso de un único mando, con lo que la mejora seria notable. En este caso es del 36.84%. En los anteriores estudios se había comprobado que para una utilización normal, la inclusión de un mando adicional a 15º no ofrecía ningún tipo de mejora. Con este estudio se certifica que la inclusión de un mando adicional ofrece mejora para todo el rango de diferentes ángulos posibles, incrementando la capacidad de utilización de la aplicación.

Por tanto, queda más que demostrado el beneficio que se puede obtener con la inclusión de un mando adicional. Este mando adicional permite incrementar en gran cuantía el rango de uso de la superficie de proyección para poder escribir o dibujar. Con la lectura de información enviada por dos mandos se consigue que la pizarra se pueda utilizar con una gran cantidad de combinaciones posibles, y se reducen las zonas oscuras como mínimo un 16 %. Las zonas oscuras suponen un gran inconveniente para esta aplicación, ya que el usuario no podrá realizar acción alguna en estas, con lo que una reducción del 16% supone un valor muy importante.

También se demuestra que colocar dos mandos a 10º no ofrece un beneficio suficiente como para tener en cuenta esta opción. La mejora respecto a colocarlos a 15º es del 0.52%, mientras que la pérdida de visión se incrementa en un 8.58%. La resolución sería tan baja que no se podría escribir texto, y las líneas quedarían muy pixeladas. A 15º ya se obtiene que no existen zonas oscuras, con lo que a 10º el beneficio con dos mandos es muy pequeño. Solo tendría sentido colocar los mandos con este ángulo si se pusiera un único mando y se quisieran evitar zonas oscuras, ya que el obstáculo le afectaría muy poco. Pero en este caso, la resolución seguiría siendo muy baja y solo se podrían dibujar líneas muy pixeladas, con lo que la comprensión de la tarea realizada por la persona que viera el resultado sería muy baja. Por tanto, se concluye que el rango de utilización de este proyecto con dos mandos llega como máximo a 15º respecto la proyección.

Page 108: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

108

14.2 Código desarrollado durante el proceso de creación del programa

En este apartado se incluirá todo el código que se ha ido desarrollando hasta llegar al resultado final. La explicación de la utilidad y funcionamiento del código se encuentra en el cuerpo de la memoria, en el apartado Funcionamiento del programa. En este apartado se referencia el código descrito a continuación y se explica su utilidad.

Código 1

public void MultipleWiimoteForm_Load(object sender, EventArgs e)

{

// find all wiimotes connected to the system

mWC = new WiimoteCollection();

int index = 1;

try

{

mWC.FindAllWiimotes();

}

catch(WiimoteNotFoundException ex)

{

MessageBox.Show("No se ha encontrado ningun Wiimote

disponible para conectar", "Error: no se ha encontrado ningun Wiimote",

MessageBoxButtons.OK, MessageBoxIcon.Error);

}

catch(WiimoteException ex)

{

MessageBox.Show("No se ha podido realizar una correcta

conexión con algún Wiimote", "Error en conexión a Wiimote",

MessageBoxButtons.OK, MessageBoxIcon.Error);

}

catch(Exception ex)

{

MessageBox.Show("Error en conexión indefinido", "Error

indefinido", MessageBoxButtons.OK, MessageBoxIcon.Error);

}

foreach(Wiimote wm in mWC)

{

// create a new tab

TabPage tp = new TabPage("Wiimote " + index);

tabWiimotes.TabPages.Add(tp);

// create a new user control

WiimoteInfo wi = new WiimoteInfo(wm);

tp.Controls.Add(wi);

// setup the map from this wiimote's ID to that control

mWiimoteMap[wm.ID] = wi;

// connect it and set it up as always

wm.WiimoteChanged += wm_WiimoteChanged;

wm.WiimoteExtensionChanged += wm_WiimoteExtensionChanged;

wm.Connect();

if(wm.WiimoteState.ExtensionType !=

ExtensionType.BalanceBoard)

Page 109: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

109

wm.SetReportType(InputReport.IRExtensionAccel,

IRSensitivity.Maximum, true);

wm.SetLEDs(index++);

}

}

Código 1. Conexión del mando al software de control

Código 2

public void doCalibration() {

if (cf == null)

return;

int x = 0;

int y = 0;

int size = 25;

Pen p = new Pen(Color.Red);

switch (calibrationState)

{

case 1:

x = (int)(screenWidth * calibrationMargin);

y = (int)(screenHeight * calibrationMargin);

cf.showCalibration(x, y, size, p);

dstX1[calibrationState - 1] = x;

dstY1[calibrationState - 1] = y;

dstX2[calibrationState - 1] = x;

dstY2[calibrationState - 1] = y;

break;

case 2:

x = screenWidth - (int)(screenWidth *

calibrationMargin);

y = (int)(screenHeight * calibrationMargin);

cf.showCalibration(x, y, size, p);

dstX1[calibrationState - 1] = x;

dstY1[calibrationState - 1] = y;

dstX2[calibrationState - 1] = x;

dstY2[calibrationState - 1] = y;

break;

case 3:

x = (int)(screenWidth * calibrationMargin);

y = screenHeight - (int)(screenHeight *

calibrationMargin);

cf.showCalibration(x, y, size, p);

dstX1[calibrationState - 1] = x;

dstY1[calibrationState - 1] = y;

dstX2[calibrationState - 1] = x;

Page 110: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

110

dstY2[calibrationState - 1] = y;

break;

case 4:

x = screenWidth - (int)(screenWidth *

calibrationMargin);

y = screenHeight - (int)(screenHeight *

calibrationMargin);

cf.showCalibration(x, y, size, p);

dstX1[calibrationState - 1] = x;

dstY1[calibrationState - 1] = y;

dstX2[calibrationState - 1] = x;

dstY2[calibrationState - 1] = y;

break;

case 5:

//compute warp

warper1.setDestination(dstX1[0], dstY1[0], dstX1[1],

dstY1[1], dstX1[2], dstY1[2], dstX1[3], dstY1[3]);

warper1.setSource(srcX1[0], srcY1[0], srcX1[1],

srcY1[1], srcX1[2], srcY1[2], srcX1[3], srcY1[3]);

warper1.computeWarp();

warper2.setDestination(dstX2[0], dstY2[0], dstX2[1],

dstY2[1], dstX2[2], dstY2[2], dstX2[3], dstY2[3]);

warper2.setSource(srcX2[0], srcY2[0], srcX2[1],

srcY2[1], srcX2[2], srcY2[2], srcX2[3], srcY2[3]);

warper2.computeWarp();

cf.Close();

cf = null;

calibrationState = 0;

cursorControl = true;

BeginInvoke((MethodInvoker)delegate() {

cbCursorControl.Checked = cursorControl; });

// saveCalibrationData();

track1=UpdateTrackingUtilization1();

track2=UpdateTrackingUtilization2();

break;

default:

break;

}

}

Código 2. Función “doCalibration”

Page 111: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

111

Código 3

switch (calibrationState)

case 1:

if (mando1)

{

srcX1[calibrationState - 1] = x1;

srcY1[calibrationState - 1] = y1;

calibra1 = true;

}

else if (mando2)

{

srcX2[calibrationState - 1] = x2;

srcY2[calibrationState - 1] = y2;

calibra2 = true;

}

if (calibra1 && calibra2)

{

calibra1 = false;

calibra2 = false;

calibrationState = 2;

doCalibration();

}

break;

case 2:

if (mando1)

{

srcX1[calibrationState - 1] = x1;

srcY1[calibrationState - 1] = y1;

calibra1 = true;

}

else if(mando2)

{

srcX2[calibrationState - 1] = x2;

srcY2[calibrationState - 1] = y2;

calibra2 = true;

}

if (calibra1 && calibra2)

{

calibra1 = false;

calibra2 = false;

calibrationState = 3;

doCalibration();

}

Page 112: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

112

break;

case 3:

if (mando1)

{

srcX1[calibrationState - 1] = x1;

srcY1[calibrationState - 1] = y1;

calibra1 = true;

}

else if(mando2)

{

srcX2[calibrationState - 1] = x2;

srcY2[calibrationState - 1] = y2;

calibra2 = true;

}

if (calibra1 && calibra2)

{

calibra1 = false;

calibra2 = false;

calibrationState = 4;

doCalibration();

}

break;

case 4:

if (mando1)

{

srcX1[calibrationState - 1] = x1;

srcY1[calibrationState - 1] = y1;

calibra1 = true;

}

else if(mando2)

{

srcX2[calibrationState - 1] = x2;

srcY2[calibrationState - 1] = y2;

calibra2 = true;

}

if (calibra1 && calibra2)

{

calibra1 = false;

calibra2 = false;

calibrationState = 5;

doCalibration();

}

break;

default:

break;

}//calibtation state

Código 3. Almacenamiento de las coordenadas enviadas por el Wiimote en estado de calibración

Page 113: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

113

Código 5

if((!vis1) && vis2 && mando2)

{

warpedX=warpedX2;

warpedY=warpedY2;

vis_antes = 2;

}

else if ((!vis2) && vis1 && mando1)

{

warpedX=warpedX1;

warpedY=warpedY1;

vis_antes = 1;

}

else if(vis1 && vis2)

{

if (((System.Math.Abs(warpedX1 - warpedX2)) < 50 &&

((System.Math.Abs(warpedY1 - warpedY2)) < 50)) || (vis_antes==0))

{

if (track1 < 30 && track2 > 30 && mando2)

{

warpedX = warpedX2;

warpedY = warpedY2;

}

else if (track1 > 30 && track2 < 30 && mando1)

{

warpedX = warpedX1;

warpedY = warpedY1;

}

else if (track1 > 30 && track2 > 30)

{

warpedX = (warpedX1 + warpedX2) / 2;

warpedY = (warpedY1 + warpedY2) / 2;

}

vis_antes = 0;

}

else if (vis_antes == 1 && mando1)

{

warpedX = warpedX1;

warpedY = warpedY1;

}

else if(vis_antes == 2 && mando2)

{

warpedX = warpedX2;

warpedY = warpedY2;

}

}

Código 5. Selección de coordenadas a las que enviar el puntero del mouse

Page 114: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

114

Código 6

if (warpedX1 < 501)

{

warpedX = warpedX1;

warpedY = warpedY1;

vis_antes = 1;

}

else if (warpedX2 > 599)

{

warpedX = warpedX2;

warpedY = warpedY2;

vis_antes = 2;

}

else if (warpedX1 > 500 && warpedX2 < 600)

{

if (((System.Math.Abs(warpedX1 - warpedX2)) < 50 &&

((System.Math.Abs(warpedY1 - warpedY2)) < 50)) || (vis_antes == 0))

{

warpedX = (warpedX1 + warpedX2) / 2;

warpedY = (warpedY1 + warpedY2) / 2;

vis_antes = 0;

}

else if (vis_antes == 1)

{

warpedX = warpedX1;

warpedY = warpedY1;

}

else if (vis_antes == 2)

{

warpedX = warpedX2;

warpedY = warpedY2;

}

}

else

{

if (track1 > track2)

{

warpedX = warpedX1;

warpedY = warpedY1;

}

else

{

warpedX = warpedX2;

warpedY = warpedY2;

}

}

Código 6. Selección de coordenadas útil cuando el mando esta cerca de la proyección.

Page 115: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

115

Código 10

if ((mando1 && ws.IRState.IRSensors[0].Found)|| (mando2 &&

MultipleWiimoteForm.mWC[1].WiimoteState.IRState.IRSensors[0].Found))

{

.

.

.

if ((mando1 && !(lastWiiState1.IRState.IRSensors[0].Found)) ||

(mando2 && !(lastWiiState2.IRState.IRSensors[0].Found)))//boton derecho

mouse apretado

{

if (mando1)

lastWiiState1.IRState.IRSensors[0].Found =

ws.IRState.IRSensors[0].Found;

else if (mando2)

lastWiiState2.IRState.IRSensors[0].Found =

MultipleWiimoteForm.mWC[1].WiimoteState.IRState.IRSensors[0].Found;

.

.

.

}

else if ((mando1 && lastWiiState1.IRState.IRSensors[0].Found) ||

(mando2 && lastWiiState2.IRState.IRSensors[0].Found))//arrastre cursor

{ .

.

.

}

}

else if ((mando1 && !(ws.IRState.IRSensors[0].Found)) || (mando2 &&

!(MultipleWiimoteForm.mWC[1].WiimoteState.IRState.IRSensors[0].Found)))

{

if ((mando1 && lastWiiState1.IRState.IRSensors[0].Found) ||

(mando2 && lastWiiState2.IRState.IRSensors[0].Found))//mouse up

{

if(mando1)

lastWiiState1.IRState.IRSensors[0].Found = false;

else if (mando2)

lastWiiState2.IRState.IRSensors[0].Found = false;

.

.

.

}

}

Código 10. Secuencia de condiciones necesarias para control el estado del puntero

Page 116: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

116

Código 11

if ((mando1 && ws.IRState.IRSensors[0].Found) || (mando2 &&

MultipleWiimoteForm.mWC[1].WiimoteState.IRState.IRSensors[0].Found))

{

if (((mando1 && lastWiiState1.IRState.IRSensors[0].Found == false) ||

(mando2 && lastWiiState2.IRState.IRSensors[0].Found == false)) &&

click_antes == false)//mouse down

{

click_antes = true;

.

.

.

}

else if ((mando1 && lastWiiState1.IRState.IRSensors[0].Found) ||

(mando2 && lastWiiState2.IRState.IRSensors[0].Found))

{

click_antes = false;

.

.

.

}

}

else if ((mando1 && !(ws.IRState.IRSensors[0].Found)) || (mando2 &&

!(MultipleWiimoteForm.mWC[1].WiimoteState.IRState.IRSensors[0].Found)))

{

if ((mando1 && lastWiiState1.IRState.IRSensors[0].Found) || (mando2

&& lastWiiState2.IRState.IRSensors[0].Found))//mouse up

{

lastWiiState1.IRState.IRSensors[0].Found = false;

lastWiiState2.IRState.IRSensors[0].Found = false;

.

.

.

}

}

Código 11. Código implementado para solucionar el problema de doble clic indeseado.

Page 117: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

117

Código 12

if ((mando1 && lastWiiState1.IRState.IRSensors[0].Found == false) ||

(mando2 && lastWiiState2.IRState.IRSensors[0].Found == false))//mouse

down

{

if (!lastWiiState1.IRState.IRSensors[0].Found &&

!lastWiiState2.IRState.IRSensors[0].Found)

{

if (cursorControl)

{

INPUT[] buffer = new INPUT[2];

buffer[0].type = INPUT_MOUSE;

buffer[0].mi.dx = (int)(warpedX * 65535.0f / screenWidth);

buffer[0].mi.dy = (int)(warpedY * 65535.0f / screenHeight);

buffer[0].mi.mouseData = 0;

buffer[0].mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;

buffer[0].mi.time = 0;

buffer[0].mi.dwExtraInfo = (IntPtr)0;

buffer[1].type = INPUT_MOUSE;

buffer[1].mi.dx = 0;

buffer[1].mi.dy = 0;

buffer[1].mi.mouseData = 0;

buffer[1].mi.dwFlags = MOUSEEVENTF_RIGHTDOWN;

buffer[1].mi.time = 1;

buffer[1].mi.dwExtraInfo = (IntPtr)0;

SendInput(2, buffer, Marshal.SizeOf(buffer[0]));

}

.

.

.

if (mando1)

lastWiiState1.IRState.IRSensors[0].Found = true;

else if (mando2)

lastWiiState2.IRState.IRSensors[0].Found = true;

}

}

Código 12. Nuevo “if” introducido en el punto en el que se realiza la acción de clic

Page 118: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

118

Código 13

if (mando1 == true)

{

vis1 =

MultipleWiimoteForm.mWC[0].WiimoteState.IRState.IRSensors[0].Found;

posx1 =

MultipleWiimoteForm.mWC[0].WiimoteState.IRState.IRSensors[0].RawPosition.

X;

posy1 =

MultipleWiimoteForm.mWC[0].WiimoteState.IRState.IRSensors[0].RawPosition.

Y;

enter1++;

if (enter1 > 10)

{

vis2 = false;

act_1 = true;

enter1 = 0;

}

if (vis1)

enter2 = 0;

}

else if (mando2 == true)

{

posx2 =

MultipleWiimoteForm.mWC[1].WiimoteState.IRState.IRSensors[0].RawPosition.

X;

posy2 =

MultipleWiimoteForm.mWC[1].WiimoteState.IRState.IRSensors[0].RawPosition.

Y;

vis2 =

MultipleWiimoteForm.mWC[1].WiimoteState.IRState.IRSensors[0].Found;

enter2++;

if (enter2 > 10)

{

vis1 = false;

act_2 = true;

enter2 = 0;

}

if (vis2)

enter1 = 0;

}

Código 13. Código implementado para captar los datos enviados por cada mando y comprobar cuantas veces seguidas el mismo mando ha entrado en la RSI.

Page 119: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

119

Código 14

if (cursorControl)

{

INPUT[] buffer = new INPUT[2];

buffer[0].type = INPUT_MOUSE;

buffer[0].mi.dx = (int)(warpedX * 65535.0f / screenWidth);

buffer[0].mi.dy = (int)(warpedY * 65535.0f / screenHeight);

buffer[0].mi.mouseData = 0;

buffer[0].mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;

buffer[0].mi.time = 0;

buffer[0].mi.dwExtraInfo = (IntPtr)0;

buffer[1].type = INPUT_MOUSE;

buffer[1].mi.dx = 0;

buffer[1].mi.dy = 0;

buffer[1].mi.mouseData = 0;

buffer[1].mi.dwFlags = MOUSEEVENTF_RIGHTDOWN;

buffer[1].mi.time = 1;

buffer[1].mi.dwExtraInfo = (IntPtr)0;

SendInput(2, buffer, Marshal.SizeOf(buffer[0]));

}//cusor control

Código 14. Código utilizado para simular el funcionamiento del ratón físico

Código 15

if (!lastWiiState1.IRState.IRSensors[0].Found &&

!lastWiiState2.IRState.IRSensors[0].Found)

{

if (cursorControl && !arrastre && !doble_click)

{

INPUT[] buffer = new INPUT[2];

buffer[0].type = INPUT_MOUSE;

buffer[0].mi.dx = (int)(warpedX * 65535.0f / screenWidth);

buffer[0].mi.dy = (int)(warpedY * 65535.0f / screenHeight);

buffer[0].mi.mouseData = 0;

buffer[0].mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;

buffer[0].mi.time = 0;

buffer[0].mi.dwExtraInfo = (IntPtr)0;

buffer[1].type = INPUT_MOUSE;

buffer[1].mi.dx = 0;

buffer[1].mi.dy = 0;

buffer[1].mi.mouseData = 0;

if (!click_der)

buffer[1].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;

else

buffer[1].mi.dwFlags = MOUSEEVENTF_RIGHTDOWN;

Page 120: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

120

buffer[1].mi.time = 1;

buffer[1].mi.dwExtraInfo = (IntPtr)0;

SendInput(2, buffer, Marshal.SizeOf(buffer[0]));

}//cusor control

else if (cursorControl && doble_click)

{

INPUT[] buffer = new INPUT[1];

buffer[0].type = INPUT_MOUSE;

buffer[0].mi.dx = (int)(warpedX * 65535.0f / screenWidth);

buffer[0].mi.dy = (int)(warpedY * 65535.0f / screenHeight);

buffer[0].mi.mouseData = 0;

buffer[0].mi.dwFlags = MOUSEEVENTF_LEFTUP;

buffer[0].mi.time = 0;

buffer[0].mi.dwExtraInfo = (IntPtr)0;

SendInput(1, buffer, Marshal.SizeOf(buffer[0]));

buffer[0].type = INPUT_MOUSE;

buffer[0].mi.dx = (int)(warpedX * 65535.0f / screenWidth);

buffer[0].mi.dy = (int)(warpedY * 65535.0f / screenHeight);

buffer[0].mi.mouseData = 0;

buffer[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;

buffer[0].mi.time = 0;

buffer[0].mi.dwExtraInfo = (IntPtr)0;

SendInput(1, buffer, Marshal.SizeOf(buffer[0]));

buffer[0].type = INPUT_MOUSE;

buffer[0].mi.dx = (int)(warpedX * 65535.0f / screenWidth);

buffer[0].mi.dy = (int)(warpedY * 65535.0f / screenHeight);

buffer[0].mi.mouseData = 0;

buffer[0].mi.dwFlags = MOUSEEVENTF_LEFTUP;

buffer[0].mi.time = 0;

buffer[0].mi.dwExtraInfo = (IntPtr)0;

SendInput(1, buffer, Marshal.SizeOf(buffer[0]));

buffer[0].type = INPUT_MOUSE;

buffer[0].mi.dx = (int)(warpedX * 65535.0f / screenWidth);

buffer[0].mi.dy = (int)(warpedY * 65535.0f / screenHeight);

buffer[0].mi.mouseData = 0;

buffer[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;

buffer[0].mi.time = 0;

buffer[0].mi.dwExtraInfo = (IntPtr)0;

SendInput(1, buffer, Marshal.SizeOf(buffer[0]));

doble_click = false;

}

}

Código 15. Código implementado para agregar las funciones doble clic, clic derecho y arraste del cursor sin clicar.

Page 121: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

121

Código 16 else if ((vis1 == false) && ( vis2 == false ))

{

if ((mando1 && lastWiiState1.IRState.IRSensors[0].Found) || (mando2 &&

lastWiiState2.IRState.IRSensors[0].Found))//mouse up

{

lastWiiState1.IRState.IRSensors[0].Found = false;

lastWiiState2.IRState.IRSensors[0].Found = false;

if (cursorControl)

{

INPUT[] buffer = new INPUT[2];

buffer[0].type = INPUT_MOUSE;

buffer[0].mi.dx = 0;

buffer[0].mi.dy = 0;

buffer[0].mi.mouseData = 0;

if (!click_der)

buffer[0].mi.dwFlags = MOUSEEVENTF_LEFTUP;

else

{

buffer[0].mi.dwFlags = MOUSEEVENTF_RIGHTUP;

click_der = false;

}

buffer[0].mi.time = 0;

buffer[0].mi.dwExtraInfo = (IntPtr)0;

buffer[1].type = INPUT_MOUSE;

buffer[1].mi.dx = 0;

buffer[1].mi.dy = 0;

buffer[1].mi.mouseData = 0;

buffer[1].mi.dwFlags = MOUSEEVENTF_MOVE;

buffer[1].mi.time = 0;

buffer[1].mi.dwExtraInfo = (IntPtr)0;

SendInput(2, buffer, Marshal.SizeOf(buffer[0]));

}

}//ir lost

}

Código 16. Modificación realizada en la ultima condición para que la función clic derecho funcione correctamente.

Page 122: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

122

14.3 Código fuente del programa final

14.3.1 Archivo Program.cs

Este archivo contiene el “Main” del programa. Es el código que se ejecuta al abrir el

programa. En este se desvia todo el funcionamiento del programa al archivo MultipleWiimoteForm.cs

using System;

using System.Windows.Forms;

namespace WiimoteTest

{

static class Program

{

/// <summary>

/// El Main del programa. En el solo se indica que se activen

los elementos visuales y se ejecuta el formulario MultipleWiimoteForm.

Desde MultipleWiimoteForm se controla todo el funcionamiento del

programa.

/// </summary>

[STAThread]

static void Main()

{

Application.EnableVisualStyles();

Application.SetCompatibleTextRenderingDefault(false);

Application.Run(new MultipleWiimoteForm());

}

}

}

Código 17 . Código fuente del archivo Program.cs

Page 123: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

123

14.3.2 Archivo MultipleWiimoteForm.cs

Este archivo contiene el núcleo del programa. Dentro de él se encuentra la rutina de atención a las interrupciones provocadas por los mandos. Esta subrutina recibe el nombre “wm_WiimoteChanged”. Durante la ejecución de la RSI se lleva a cabo la decisión de a que coordenadas se debe enviar el cursor del ratón para que este haga el mismo movimiento que el que hace el usuario con el puntero IR. También se decide qué función hace el cursor, si clic, doble clic, clic derecho o se desliza el cursor sin clicar. Se implementa a su vez las líneas de código necesarias para que todos los botones de la interfaz gráfica principal del programa funcionen correctamente.

using System;

using System.Collections.Generic;

using System.Windows.Forms;

using WiimoteLib;

using System.Threading;

using System.ComponentModel;

using System.Drawing;

using System.Drawing.Imaging;

using System.Text;

using System.Runtime.InteropServices;//para detectar eventos generados

por el ratón o el teclado

using System.IO;//para guardar la información de calibración en un

archivo

namespace WiimoteTest

{

public partial class MultipleWiimoteForm : Form

{

#region "raton"

const int smoothingBufferSize = 50; //se define el tamaño del

buffer de suavizado de linea

System.Drawing.PointF[] smoothingBuffer = new

System.Drawing.PointF[smoothingBufferSize];

int smoothingBufferIndex = 0;

int smoothingAmount = 4;

bool enableSmoothing = true;

public bool cursorControl = false; // estas variables se declaran

public porque serán utilizadas en otro archivo

public static bool arrastre = false;

public static bool click_der;

int screenWidth = 1024;//valores por defecto, posteriormente se

substituyen por la resolucion de la pantalla utilizada

int screenHeight = 768;

static int calibrationState = 0;

float calibrationMargin = .1f;

CalibrationForm cf = null; //definición de existencia de

diferentes ventanas

MouseControl mouse_ctr = null;

Page 124: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

124

AboutBox1 about = null;

static public int calib=0; //variables globales utilizadas para

diversas funciones

static bool calibra1;

static bool calibra2;

static float track1;

static float track2;

bool vis1;

bool vis2;

int enter1;

int enter2;

float warpedX = 0;

float warpedY = 0;

int posx1;

int posy1;

int posx2;

int posy2;

float warpedX1;

float warpedY1;

float warpedX2;

float warpedY2;

int x1 = 0;

int y1 = 0;

int x2 = 0;

int y2 = 0;

byte vis_antes;

bool act_1;

bool act_2;

public static bool doble_click;

bool ventana_abierta;

//se define una nueva matriz de valores en las que pasaremos las

coordenadas recibidas durante la calibración

Warper1 warper1 = new Warper1();

float[] srcX1 = new float[4];

float[] srcY1 = new float[4];

float[] dstX1 = new float[4];

float[] dstY1 = new float[4];

//misma matriz que la anterior pero se utilizará para coordenadas

del mando 2

Warper2 warper2 = new Warper2();

float[] srcX2 = new float[4];

float[] srcY2 = new float[4];

float[] dstX2 = new float[4];

float[] dstY2 = new float[4];

//declaración de constantes para identificar los eventos del

ratón

public const int INPUT_MOUSE = 0;

public const int INPUT_KEYBOARD = 1;

public const int INPUT_HARDWARE = 2;

public const int MOUSEEVENTF_MOVE = 0x01;

public const int MOUSEEVENTF_LEFTDOWN = 0x02;

public const int MOUSEEVENTF_LEFTUP = 0x04;

public const int MOUSEEVENTF_RIGHTDOWN = 0x08;

Page 125: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

125

public const int MOUSEEVENTF_RIGHTUP = 0x10;

public const int MOUSEEVENTF_MIDDLEDOWN = 0x20;

public const int MOUSEEVENTF_MIDDLEUP = 0x40;

public const int MOUSEEVENTF_ABSOLUTE = 0x8000;

//declaración de constantes para identificar los eventos del

teclado

public const byte VK_TAB = 0x09;

public const byte VK_MENU = 0x12; // VK_MENU es como Microsoft

llama a la tecla Alt

public const byte VK_SPACE = 0x20;

public const byte VK_RETURN = 0x0D;

public const byte VK_LEFT = 0x25;

public const byte VK_UP = 0x26;

public const byte VK_RIGHT = 0x27;

public const byte VK_DOWN = 0x28;

public const int KEYEVENTF_EXTENDEDKEY = 0x01;

public const int KEYEVENTF_KEYUP = 0x02;

//Se usa user32.dll para enviar las coordenadas a las que debe ir

el ratón

[DllImport("user32.dll", SetLastError = true)]

static extern uint SendInput(uint nInputs, INPUT[] pInputs, int

cbSize);

//declaración de estructura de datos a enviar para simular datos

enviados por el ratón físico

[StructLayout(LayoutKind.Sequential)]

public struct MOUSEINPUT

{

public int dx;//4

public int dy;//4

public uint mouseData;//4

public uint dwFlags;//4

public uint time;//4

public IntPtr dwExtraInfo;//4

}

//declaración de estructura de datos a enviar para simular datos

enviados por el teclado físico

[StructLayout(LayoutKind.Sequential)]

public struct KEYBDINPUT

{

public ushort wVk;//2

public ushort wScan;//2

public uint dwFlags;//4

public uint time;//4

public IntPtr dwExtraInfo;//4

}

[StructLayout(LayoutKind.Sequential)]

public struct HARDWAREINPUT

{

public uint uMsg;

public ushort wParamL;

public ushort wParamH;

}

[StructLayout(LayoutKind.Explicit, Size = 28)]

public struct INPUT

Page 126: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

126

{

[FieldOffset(0)]

public int type;

[FieldOffset(4)] //*

public MOUSEINPUT mi;

[FieldOffset(4)] //*

public KEYBDINPUT ki;

[FieldOffset(4)] //*

public HARDWAREINPUT hi;

}

//importa la función mouse_event de user32.dll

[DllImport("user32.dll")]

private static extern void mouse_event(

long dwFlags, //movimiento y opciones de clic

long dx, //posición horizontal

long dy, //posición vertical

long dwData, //movimiento de la rueda del ratón

long dwExtraInfo //información definida por aplicación de control

del ratón

);

[DllImport("user32.dll", SetLastError = true)]

[return: MarshalAs(UnmanagedType.Bool)]

public static extern bool SetCursorPos(int X, int Y);

//importa la función keyboard_event de user32.dll

[DllImport("user32.dll", CharSet = CharSet.Auto,

CallingConvention = CallingConvention.StdCall)]

public static extern void keybd_event(byte bVk, byte bScan, long

dwFlags, long dwExtraInfo);

WiimoteState lastWiiState1 = new WiimoteState();//se copia la

estructura de datos de WiimoteState

WiimoteState lastWiiState2 = new WiimoteState();//LastWiiState

permitirá almacenar la información de la ultima vez que el mando genera

interrupción

#endregion

Mutex mut = new Mutex(); //se declara la función Mutex

// se linka un wiimote a un control de usuario especifico

Dictionary<Guid,WiimoteInfo> mWiimoteMap = new

Dictionary<Guid,WiimoteInfo>();

public static WiimoteCollection mWC; // se crea la variable

mWC que se utiliza para identificar el mando del que se desea leer los

datos

public MultipleWiimoteForm()

{

screenWidth = Screen.GetBounds(this).Width; //lectura de la

resolución de la pantalla actual

screenHeight = Screen.GetBounds(this).Height;

InitializeComponent(); //inicialización a 0 de todas

las posiciones del buffer

Page 127: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

127

for (int i = 0; i < smoothingBufferSize; i++)

smoothingBuffer[i] = new System.Drawing.PointF();

setSmoothing(smoothingAmount);

}

public void MultipleWiimoteForm_Load(object sender, EventArgs

e)

{

// busqueda de todos los wiimotes conectados al PC

mWC = new WiimoteCollection();

int index = 1;

//busqueda de todos los wiimotes conectados

try

{

mWC.FindAllWiimotes();

}

catch(WiimoteNotFoundException ex) //tratamiento de los

diferentes errores posibles

{

MessageBox.Show("No se ha encontrado ningun

Wiimote disponible para conectar", "Error: no se ha encontrado ningun

Wiimote", MessageBoxButtons.OK, MessageBoxIcon.Error);

}

catch(WiimoteException ex)

{

MessageBox.Show("No se ha podido realizar una

correcta conexión con algún Wiimote", "Error en conexión a Wiimote",

MessageBoxButtons.OK, MessageBoxIcon.Error);

}

catch(Exception ex)

{

MessageBox.Show("Error en conexión indefinido",

"Error indefinido", MessageBoxButtons.OK, MessageBoxIcon.Error);

}

foreach(Wiimote wm in mWC) //una vez se conocen todos

los wiimotes conectados, se intenta conectar cada uno de ellos

{

// crea una nueva pestaña

TabPage tp = new TabPage("Wiimote " + index);

tabWiimotes.TabPages.Add(tp);

// crea un nuevo control de usuario

WiimoteInfo wi = new WiimoteInfo(wm);

tp.Controls.Add(wi);

// linka este wiimote con el control de usuario

creado

mWiimoteMap[wm.ID] = wi;

// conexión con el mando para recibir los datos

enviados por este

wm.WiimoteChanged += wm_WiimoteChanged;

wm.Connect();

// se pone la sensibilidad de la cámara IR al máximo

Page 128: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

128

wm.SetReportType(InputReport.IRAccel,

IRSensitivity.Maximum, true);

// enciende el led que identifica a este mando

como el 1 o el 2

wm.SetLEDs(index++);

}

loadCalibrationData();

}

public void wm_WiimoteChanged(object sender,

WiimoteChangedEventArgs e)

{

mut.WaitOne(); // se inhibe la atención a nuevas

interrupciones

//se extrae toda la información enviada por el wiimote

WiimoteState ws = e.WiimoteState;

WiimoteInfo wi = mWiimoteMap[((Wiimote)sender).ID];

wi.UpdateState(e);

bool mando1;

bool mando2;

mando2 = false;

mando1 = false;

//identificación del mando que ha entrado en la RSI

if (((((Wiimote)sender).ID).ToString()) ==

((MultipleWiimoteForm.mWC[0].ID).ToString()))

{

mando1 = true;

mando2 = false;

}

if (((((Wiimote)sender).ID).ToString()) ==

((MultipleWiimoteForm.mWC[1].ID).ToString()))

{

mando2 = true;

mando1 = false;

}

ws = MultipleWiimoteForm.mWC[0].WiimoteState;

//lectura de coordenadas de posición del puntero

if (mando1 == true)

{

Page 129: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

129

vis1 =

MultipleWiimoteForm.mWC[0].WiimoteState.IRState.IRSensors[0].Found;

vis2 =

MultipleWiimoteForm.mWC[1].WiimoteState.IRState.IRSensors[0].Found;

posx1 =

MultipleWiimoteForm.mWC[0].WiimoteState.IRState.IRSensors[0].RawPosition.

X;

posy1 =

MultipleWiimoteForm.mWC[0].WiimoteState.IRState.IRSensors[0].RawPosition.

Y;

x1 = posx1;

y1 = posy1;

enter1++; // cada vez que entra este mando se

suma 1

if (enter1 > 10) // se comprueba si el mando 1 ha entrado

10 veces seguidas a la RSi

{

vis2 = false; // si es así, significa que el mando 2

no ve el puntero IR

act_1 = true; // variable que actualiza la

información de lastwiistate

enter1 = 0;

}

if (vis1)

enter2 = 0;

}

else if (mando2 == true)

{

posx2 =

MultipleWiimoteForm.mWC[1].WiimoteState.IRState.IRSensors[0].RawPosition.

X;

posy2 =

MultipleWiimoteForm.mWC[1].WiimoteState.IRState.IRSensors[0].RawPosition.

Y;

vis2 =

MultipleWiimoteForm.mWC[1].WiimoteState.IRState.IRSensors[0].Found;

vis1 =

MultipleWiimoteForm.mWC[0].WiimoteState.IRState.IRSensors[0].Found;

x2 = posx2;

y2 = posy2;

enter2++;

if (enter2 > 10)

{

vis1 = false;

act_2 = true;

enter2 = 0;

}

if (vis2)

enter1 = 0;

}

//se entra en el if si el mando que ha entrado en la RSI veia

un puntero IR

Page 130: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

130

if ((mando1 && ws.IRState.IRSensors[0].Found) || (mando2 &&

MultipleWiimoteForm.mWC[1].WiimoteState.IRState.IRSensors[0].Found))

{

//si el mando 1 es el que ha entrado, se envian a la

función Warper las coordenadas recibidas del mando.

if (mando1)

{

warpedX1 = x1;

warpedY1 = y1;

warper1.warp(x1, y1, ref warpedX1, ref warpedY1);

//esta función devuelve el punto al que se tiene que enviar el cursor

}

else if (mando2)

{

warpedX2 = x2;

warpedY2 = y2;

warper2.warp(x2, y2, ref warpedX2, ref warpedY2);

}

// si solo ve el mando2 y es el que ha generado la RSI,

el cursor se envia a la posición recibida

if((!vis1) && vis2 && mando2)

{

warpedX=warpedX2;

warpedY=warpedY2;

vis_antes = 2;

}

else if ((!vis2) && vis1 && mando1) //si solo ve el

mando1, se envia a la posición recibida de ese mando

{

warpedX=warpedX1;

warpedY=warpedY1;

vis_antes = 1;

}

else if(vis1 && vis2) // si ven los dos mandos, se

realizan mas comprovaciones

{

if (rb_pos1.Checked) // se comprueba que sistema de

posicionamiento ha elegido el usuario

{

//se comprueba si las coordenadas enviadas por

ambos mandos son cercanas entre ellas. Si es así se hace la media. Sino

se cojen las del mando que mejor visión tiene

if (((System.Math.Abs(warpedX1 - warpedX2)) < 50

&& ((System.Math.Abs(warpedY1 - warpedY2)) < 50)) || (vis_antes == 0))

{

if (track1 < 15 && track2 > 15 && mando2)

{

warpedX = warpedX2;

warpedY = warpedY2;

}

else if (track1 > 15 && track2 < 15 && mando1)

{

Page 131: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

131

warpedX = warpedX1;

warpedY = warpedY1;

}

else if (track1 > 15 && track2 > 15)

{

warpedX = (warpedX1 + warpedX2) / 2;

warpedY = (warpedY1 + warpedY2) / 2;

}

vis_antes = 0;

}

else if (vis_antes == 1 && mando1) //si habia

mucha diferencia en las coordenadas, se comprueba que mando ha sido el

ultimo en ver el puntero y se cojen los datos de ese

{

warpedX = warpedX1;

warpedY = warpedY1;

}

else if (vis_antes == 2 && mando2)

{

warpedX = warpedX2;

warpedY = warpedY2;

}

}

else if (rb_pos2.Checked)

{

//si el punto que se posiciona esta en la mitad

izquierda de la proyección se cojen los datos del mando 1 unicamente

if (warpedX1 <= (screenWidth / 2) - 150)

{

warpedX = warpedX1;

warpedY = warpedY1;

}

else if (warpedX2 >= (screenWidth / 2) + 50) //

si esta en la mitad derecha, se cojen los datos del mando2

{

warpedX = warpedX2;

warpedY = warpedY2;

}

else if (warpedX1 > ((screenWidth / 2) - 150) &&

warpedX2 < ((screenWidth / 2) + 50)) //si esta en la zona media se

comprueba la diferencia entre ambos mandos

{

//si la diferencia de coordenadas entre

mandos es baja, se hace la media de ambas coordenadas

if (((System.Math.Abs(warpedX1 - warpedX2)) <

101 && ((System.Math.Abs(warpedY1 - warpedY2)) < 101)) || (vis_antes ==

0))

{

warpedX = (warpedX1 + warpedX2) / 2;

warpedY = (warpedY1 + warpedY2) / 2;

vis_antes = 0;

}

Page 132: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

132

else if (vis_antes == 1) // si la diferencia

es grande, se cojen los datos del ultimo mando que ha visto para evitar

saltos del cursor

{

warpedX = warpedX1;

warpedY = warpedY1;

}

else if (vis_antes == 2)

{

warpedX = warpedX2;

warpedY = warpedY2;

}

}

else // en caso de que alguna condicion falle,

se comprueba que mando tiene un porcentaje de visión mayor y se pasan los

datos de ese.

{

if (track1 > track2)

{

warpedX = warpedX1;

warpedY = warpedY1;

}

else

{

warpedX = warpedX2;

warpedY = warpedY2;

}

}

}

}

//la posición seleccionada finalmente se introduce en el

buffer se suavizado de linea.

smoothingBuffer[smoothingBufferIndex %

smoothingBufferSize].X = warpedX;

smoothingBuffer[smoothingBufferIndex %

smoothingBufferSize].Y = warpedY;

smoothingBufferIndex++; //se incrementa el indice del

buffer. Cuando sea suficiente, se hará la media de los datos enviados y

el resultado será la posición del cursor

//se comprueba si anteriormente el mando que ha generado

la RSI no veia puntero IR.

if ((mando1 && lastWiiState1.IRState.IRSensors[0].Found ==

false) || (mando2 && lastWiiState2.IRState.IRSensors[0].Found == false))

{

smoothingBufferIndex = 0;//resets the count

//en caso de que no se haya echo anteriormente, hay

que realizar la función que simula presión sobre el boton izquierdo del

ratón

Page 133: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

133

if (!lastWiiState1.IRState.IRSensors[0].Found &&

!lastWiiState2.IRState.IRSensors[0].Found)

{

if (cursorControl && !arrastre && !doble_click)

// se hace clic si no se esta arrastrando unicamente el cursor o se desea

hacer doble clic

{

INPUT[] buffer = new INPUT[2];

buffer[0].type = INPUT_MOUSE;

buffer[0].mi.dx = (int)(warpedX * 65535.0f /

screenWidth);

buffer[0].mi.dy = (int)(warpedY * 65535.0f /

screenHeight);

buffer[0].mi.mouseData = 0;

buffer[0].mi.dwFlags = MOUSEEVENTF_ABSOLUTE |

MOUSEEVENTF_MOVE;

buffer[0].mi.time = 0;

buffer[0].mi.dwExtraInfo = (IntPtr)0;

buffer[1].type = INPUT_MOUSE;

buffer[1].mi.dx = 0;

buffer[1].mi.dy = 0;

buffer[1].mi.mouseData = 0;

if (!click_der)

buffer[1].mi.dwFlags =

MOUSEEVENTF_LEFTDOWN;

else

buffer[1].mi.dwFlags =

MOUSEEVENTF_RIGHTDOWN;

buffer[1].mi.time = 1;

buffer[1].mi.dwExtraInfo = (IntPtr)0;

// se envia un buffer con los datos

necesarios para simular el comportamiento del ratón

SendInput(2, buffer, Marshal.SizeOf(buffer[0]));

}

else if (cursorControl && doble_click) //para

hacer doble clic se envian dos acciones de clic seguidas

{

INPUT[] buffer = new INPUT[1];

buffer[0].type = INPUT_MOUSE;

buffer[0].mi.dx = (int)(warpedX * 65535.0f /

screenWidth);

buffer[0].mi.dy = (int)(warpedY * 65535.0f /

screenHeight);

buffer[0].mi.mouseData = 0;

buffer[0].mi.dwFlags = MOUSEEVENTF_LEFTUP;

buffer[0].mi.time = 0;

buffer[0].mi.dwExtraInfo = (IntPtr)0;

SendInput(1, buffer,Marshal.SizeOf(buffer[0]));

buffer[0].type = INPUT_MOUSE;

buffer[0].mi.dx = (int)(warpedX * 65535.0f /

screenWidth);

buffer[0].mi.dy = (int)(warpedY * 65535.0f /

screenHeight);

buffer[0].mi.mouseData = 0;

Page 134: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

134

buffer[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;

buffer[0].mi.time = 0;

buffer[0].mi.dwExtraInfo = (IntPtr)0;

SendInput(1, buffer, Marshal.SizeOf(buffer[0]));

buffer[0].type = INPUT_MOUSE;

buffer[0].mi.dx = (int)(warpedX * 65535.0f /

screenWidth);

buffer[0].mi.dy = (int)(warpedY * 65535.0f /

screenHeight);

buffer[0].mi.mouseData = 0;

buffer[0].mi.dwFlags = MOUSEEVENTF_LEFTUP;

buffer[0].mi.time = 0;

buffer[0].mi.dwExtraInfo = (IntPtr)0;

SendInput(1, buffer, Marshal.SizeOf(buffer[0]));

buffer[0].type = INPUT_MOUSE;

buffer[0].mi.dx = (int)(warpedX * 65535.0f /

screenWidth);

buffer[0].mi.dy = (int)(warpedY * 65535.0f /

screenHeight);

buffer[0].mi.mouseData = 0;

buffer[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;

buffer[0].mi.time = 0;

buffer[0].mi.dwExtraInfo = (IntPtr)0;

SendInput(1, buffer, Marshal.SizeOf(buffer[0]));

doble_click = false;

}

}

// en caso de que se esté realizando la calibración,

se debe comprobar la etapa en la que está y almacenar los datos en el

lugar adecuado

switch (calibrationState)

{

case 1:

if (mando1)

{

srcX1[calibrationState - 1] = x1;

srcY1[calibrationState - 1] = y1;

calibra1 = true; // esta variable indica

cuando se han almacenado los datos del primer punto para el mando1

}

else if (mando2)

{

srcX2[calibrationState - 1] = x2;

srcY2[calibrationState - 1] = y2;

calibra2 = true;// variable que indica

que los datos referentes al mando 2 se han almacenado

}

if (calibra1 && calibra2) //cuando se recibe

el punto de los dos mandos, cambia calibrationstate y se pasa al

siguiente punto

{

calibra1 = false;

calibra2 = false;

calibrationState = 2;

Page 135: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

135

doCalibration(); // se indica que se pase

a dibujar el siguiente punto en la pantalla

}

break;

case 2:

if (mando1)

{

srcX1[calibrationState - 1] = x1;

srcY1[calibrationState - 1] = y1;

calibra1 = true;

}

else if(mando2)

{

srcX2[calibrationState - 1] = x2;

srcY2[calibrationState - 1] = y2;

calibra2 = true;

}

if (calibra1 && calibra2)

{

calibra1 = false;

calibra2 = false;

calibrationState = 3;

doCalibration();

}

break;

case 3:

if (mando1)

{

srcX1[calibrationState - 1] = x1;

srcY1[calibrationState - 1] = y1;

calibra1 = true;

}

else if(mando2)

{

srcX2[calibrationState - 1] = x2;

srcY2[calibrationState - 1] = y2;

calibra2 = true;

}

if (calibra1 && calibra2)

{

calibra1 = false;

calibra2 = false;

calibrationState = 4;

doCalibration();

}

break;

case 4:

if (mando1)

{

srcX1[calibrationState - 1] = x1;

srcY1[calibrationState - 1] = y1;

calibra1 = true;

}

else if(mando2)

{

Page 136: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

136

srcX2[calibrationState - 1] = x2;

srcY2[calibrationState - 1] = y2;

calibra2 = true;

}

if (calibra1 && calibra2)

{

calibra1 = false;

calibra2 = false;

calibrationState = 5;

doCalibration();

}

break;

default:

break;

}

//se actualiza el valor de lastWiiState para indicar

el valor correcto la siguiente vez que se lea

if (mando1)

lastWiiState1.IRState.IRSensors[0].Found = true;

else if (mando2)

lastWiiState2.IRState.IRSensors[0].Found = true;

}

else if ((mando1 &&

lastWiiState1.IRState.IRSensors[0].Found) || (mando2 &&

lastWiiState2.IRState.IRSensors[0].Found))

{

//si antes el mando ya veia el puntero ir, unicamente

hay que arrastrarlo si no se esta haciendo un clic derecho

if (cursorControl && !click_der)

{

INPUT[] buffer = new INPUT[1];

buffer[0].type = INPUT_MOUSE;

//si el suavizado esta activo, el punto donde

enviar el cursor será el valor que devuelva getSmoothedCursor

if (enableSmoothing)

{

System.Drawing.PointF s =

getSmoothedCursor(smoothingAmount);

buffer[0].mi.dx = (int)(s.X * 65535.0f /

screenWidth);

buffer[0].mi.dy = (int)(s.Y * 65535.0f /

screenHeight);

}

else

{

buffer[0].mi.dx = (int)(warpedX * 65535.0f /

screenWidth);

buffer[0].mi.dy = (int)(warpedY * 65535.0f /

screenHeight);

}

buffer[0].mi.mouseData = 0;

buffer[0].mi.dwFlags = MOUSEEVENTF_ABSOLUTE |

MOUSEEVENTF_MOVE;

Page 137: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

137

buffer[0].mi.time = 0;

buffer[0].mi.dwExtraInfo = (IntPtr)0;

SendInput(1, buffer, Marshal.SizeOf(buffer[0]));

}

}

}

else if ((vis1 == false) && ( vis2 == false )) // se

comprueba si ninguno de los mandos ve punto IR

{

// se comprueba si antes se veia punto IR. De ser así, se

tiene que indicar al SO que deje de mantener el boton izquierdo del raton

apretado

if ((mando1 && lastWiiState1.IRState.IRSensors[0].Found)

|| (mando2 && lastWiiState2.IRState.IRSensors[0].Found))

{

lastWiiState1.IRState.IRSensors[0].Found = false;

lastWiiState2.IRState.IRSensors[0].Found = false;

if (cursorControl)

{

INPUT[] buffer = new INPUT[2];

buffer[0].type = INPUT_MOUSE;

buffer[0].mi.dx = 0;

buffer[0].mi.dy = 0;

buffer[0].mi.mouseData = 0;

if (!click_der)

buffer[0].mi.dwFlags = MOUSEEVENTF_LEFTUP;

else //si se hacia clic derecho, hay que enviar

el evento de soltar boton derecho

{

buffer[0].mi.dwFlags = MOUSEEVENTF_RIGHTUP;

click_der = false;

}

buffer[0].mi.time = 0;

buffer[0].mi.dwExtraInfo = (IntPtr)0;

buffer[1].type = INPUT_MOUSE;

buffer[1].mi.dx = 0;

buffer[1].mi.dy = 0;

buffer[1].mi.mouseData = 0;

buffer[1].mi.dwFlags = MOUSEEVENTF_MOVE;

buffer[1].mi.time = 0;

buffer[1].mi.dwExtraInfo = (IntPtr)0;

SendInput(2, buffer, Marshal.SizeOf(buffer[0]));

}

}

}

//se actualiza la información que contiene lastWiiState para

que esté disponible para tratarla la siguiente vez que se entre en RSI

if (mando1)

{

lastWiiState1.IRState.IRSensors[0].Found =

MultipleWiimoteForm.mWC[0].WiimoteState.IRState.IRSensors[0].Found;

Page 138: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

138

lastWiiState1.IRState.IRSensors[0].RawPosition.X =

MultipleWiimoteForm.mWC[0].WiimoteState.IRState.IRSensors[0].RawPosition.

X;

lastWiiState1.IRState.IRSensors[0].RawPosition.Y =

MultipleWiimoteForm.mWC[0].WiimoteState.IRState.IRSensors[0].RawPosition.

Y;

lastWiiState1.IRState.IRSensors[1].Found =

MultipleWiimoteForm.mWC[0].WiimoteState.IRState.IRSensors[1].Found;

lastWiiState1.IRState.IRSensors[1].RawPosition.X =

MultipleWiimoteForm.mWC[0].WiimoteState.IRState.IRSensors[1].RawPosition.

X;

lastWiiState1.IRState.IRSensors[1].RawPosition.Y =

MultipleWiimoteForm.mWC[0].WiimoteState.IRState.IRSensors[1].RawPosition.

Y;

lastWiiState1.IRState.IRSensors[2].Found =

MultipleWiimoteForm.mWC[0].WiimoteState.IRState.IRSensors[2].Found;

lastWiiState1.IRState.IRSensors[2].RawPosition.X =

MultipleWiimoteForm.mWC[0].WiimoteState.IRState.IRSensors[2].RawPosition.

X;

lastWiiState1.IRState.IRSensors[2].RawPosition.Y =

MultipleWiimoteForm.mWC[0].WiimoteState.IRState.IRSensors[2].RawPosition.

Y;

lastWiiState1.IRState.IRSensors[3].Found =

MultipleWiimoteForm.mWC[0].WiimoteState.IRState.IRSensors[3].Found;

lastWiiState1.IRState.IRSensors[3].RawPosition.X =

MultipleWiimoteForm.mWC[0].WiimoteState.IRState.IRSensors[3].RawPosition.

X;

lastWiiState1.IRState.IRSensors[3].RawPosition.Y =

MultipleWiimoteForm.mWC[0].WiimoteState.IRState.IRSensors[3].RawPosition.

Y;

if (act_1 == true) // en caso de detectar que mando1 no

ve punto IR, se actualiza estado de lastWiiState

{

lastWiiState2.IRState.IRSensors[0].Found = false;

act_1 = false;

}

}

// misma función que el anterior para el mando2

if (mando2)

{

lastWiiState2.IRState.IRSensors[0].Found =

MultipleWiimoteForm.mWC[1].WiimoteState.IRState.IRSensors[0].Found;

lastWiiState2.IRState.IRSensors[0].RawPosition.X =

MultipleWiimoteForm.mWC[1].WiimoteState.IRState.IRSensors[0].RawPosition.

X;

lastWiiState2.IRState.IRSensors[0].RawPosition.Y =

MultipleWiimoteForm.mWC[1].WiimoteState.IRState.IRSensors[0].RawPosition.

Y;

lastWiiState2.IRState.IRSensors[1].Found =

MultipleWiimoteForm.mWC[1].WiimoteState.IRState.IRSensors[1].Found;

lastWiiState2.IRState.IRSensors[1].RawPosition.X =

MultipleWiimoteForm.mWC[1].WiimoteState.IRState.IRSensors[1].RawPosition.

X;

lastWiiState2.IRState.IRSensors[1].RawPosition.Y =

MultipleWiimoteForm.mWC[1].WiimoteState.IRState.IRSensors[1].RawPosition.

Y;

Page 139: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

139

lastWiiState2.IRState.IRSensors[2].Found =

MultipleWiimoteForm.mWC[1].WiimoteState.IRState.IRSensors[2].Found;

lastWiiState2.IRState.IRSensors[2].RawPosition.X =

MultipleWiimoteForm.mWC[1].WiimoteState.IRState.IRSensors[2].RawPosition.

X;

lastWiiState2.IRState.IRSensors[2].RawPosition.Y =

MultipleWiimoteForm.mWC[1].WiimoteState.IRState.IRSensors[2].RawPosition.

Y;

lastWiiState2.IRState.IRSensors[3].Found =

MultipleWiimoteForm.mWC[1].WiimoteState.IRState.IRSensors[3].Found;

lastWiiState2.IRState.IRSensors[3].RawPosition.X =

MultipleWiimoteForm.mWC[1].WiimoteState.IRState.IRSensors[3].RawPosition.

X;

lastWiiState2.IRState.IRSensors[3].RawPosition.Y =

MultipleWiimoteForm.mWC[1].WiimoteState.IRState.IRSensors[3].RawPosition.

Y;

if (act_2 == true)

{

lastWiiState1.IRState.IRSensors[0].Found = false;

act_2 = false;

}

}

//actualización del estado de la bateria tanto en barra como

en valor numérico

BeginInvoke((MethodInvoker)delegate() { pbBattery.Value =

((MultipleWiimoteForm.mWC[0].WiimoteState.Battery) > 0xc8 ? 0xc8 :

((int)(MultipleWiimoteForm.mWC[0].WiimoteState.Battery)));});

float f1 = (((100.0f * 48.0f *

(float)(MultipleWiimoteForm.mWC[0].WiimoteState.Battery / 48.0f))) /

192.0f);

BeginInvoke((MethodInvoker)delegate() { lblBattery.Text =

f1.ToString("f0") + "%"; });

BeginInvoke((MethodInvoker)delegate() { pbBattery2.Value =

((MultipleWiimoteForm.mWC[1].WiimoteState.Battery) > 0xc8 ? 0xc8 :

((int)(MultipleWiimoteForm.mWC[1].WiimoteState.Battery)));});

float f2 = (((100.0f * 48.0f *

(float)(MultipleWiimoteForm.mWC[1].WiimoteState.Battery / 48.0f))) /

192.0f);

BeginInvoke((MethodInvoker)delegate() { lblBattery2.Text =

f2.ToString("f0") + "%"; });

mut.ReleaseMutex(); // se vuelve a permitir la llegada de

interrupciones

}

private void MultipleWiimoteForm_FormClosing(object sender,

FormClosingEventArgs e)

{

//al cerrar el programa, se desconectan los mandos y se

guarda la información de la calibración en un archivo

foreach(Wiimote wm in mWC)

Page 140: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

140

wm.Disconnect();

saveCalibrationData();

}

#region "FUNCIONES"

public void loadCalibrationData()

{

// se abre el archivo que contiene los datos de la anterior

calibración

try

{

TextReader tr = new StreamReader("calibration.dat");

//busqueda del archivo

for (int i = 0; i < 4; i++) // carga de los valores

{

srcX1[i] = float.Parse(tr.ReadLine());

srcY1[i] = float.Parse(tr.ReadLine());

srcX2[i] = float.Parse(tr.ReadLine());

srcY2[i] = float.Parse(tr.ReadLine());

}

smoothingAmount = int.Parse(tr.ReadLine());

// se cierra el archivo

tr.Close();

}

catch (Exception x)

{

//en caso de excepción, no existe calibración anterior y

no hay que hacer nada

return;

}

//se envia a la función warper la información de calibración

leida

warper1.setDestination(screenWidth * calibrationMargin,

screenHeight * calibrationMargin,

screenWidth * (1.0f -

calibrationMargin),

screenHeight * calibrationMargin,

screenWidth * calibrationMargin,

screenHeight * (1.0f -

calibrationMargin),

screenWidth * (1.0f -

calibrationMargin),

screenHeight * (1.0f -

calibrationMargin));

warper1.setSource(srcX1[0], srcY1[0], srcX1[1], srcY1[1],

srcX1[2], srcY1[2], srcX1[3], srcY1[3]);

warper1.computeWarp();

warper2.setDestination(screenWidth * calibrationMargin,

screenHeight * calibrationMargin,

screenWidth * (1.0f - calibrationMargin),

screenHeight * calibrationMargin,

screenWidth * calibrationMargin,

screenHeight * (1.0f - calibrationMargin),

screenWidth * (1.0f - calibrationMargin),

screenHeight * (1.0f - calibrationMargin));

Page 141: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

141

warper2.setSource(srcX2[0], srcY2[0], srcX2[1], srcY2[1],

srcX2[2], srcY2[2], srcX2[3], srcY2[3]);

warper2.computeWarp();

setSmoothing(smoothingAmount);

cursorControl = true;

BeginInvoke((MethodInvoker)delegate() {

cbCursorControl.Checked = cursorControl; });

//se actualiza la información de uso de la cámara, segun la

calibración leida

track1=UpdateTrackingUtilization1();

track2=UpdateTrackingUtilization2();

}

public void saveCalibrationData()

{

//se guarda la ultima información de calibración obtenida

TextWriter tw = new StreamWriter("calibration.dat"); //

se crea un nuevo archivo

// se escriben las coordenadas de los puntos calibrados

for (int i = 0; i < 4; i++)

{

tw.WriteLine(srcX1[i]);

tw.WriteLine(srcY1[i]);

tw.WriteLine(srcX2[i]);

tw.WriteLine(srcY2[i]);

}

tw.WriteLine(smoothingAmount);

// se cierra el archivo

tw.Close();

}

public void doCalibration()

{

// se actualiza el punto a mostrar por pantalla dond el

usuario tiene que colocar el puntero en calibración

if (cf == null)

return;

int x = 0;

int y = 0;

int size = 25;

Pen p = new Pen(Color.Red);

//segun el valor de calibrationstate, se dibuja la cruz

en un lugar o otro y se guardan las coordenadas de la pantalla del PC

switch (calibrationState)

{

case 1:

x = (int)(screenWidth * calibrationMargin);

y = (int)(screenHeight * calibrationMargin);

cf.showCalibration(x, y, size, p);

dstX1[calibrationState - 1] = x;

dstY1[calibrationState - 1] = y;

dstX2[calibrationState - 1] = x;

dstY2[calibrationState - 1] = y;

break;

case 2:

Page 142: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

142

x = screenWidth - (int)(screenWidth *

calibrationMargin);

y = (int)(screenHeight * calibrationMargin);

cf.showCalibration(x, y, size, p);

dstX1[calibrationState - 1] = x;

dstY1[calibrationState - 1] = y;

dstX2[calibrationState - 1] = x;

dstY2[calibrationState - 1] = y;

break;

case 3:

x = (int)(screenWidth * calibrationMargin);

y = screenHeight - (int)(screenHeight *

calibrationMargin);

cf.showCalibration(x, y, size, p);

dstX1[calibrationState - 1] = x;

dstY1[calibrationState - 1] = y;

dstX2[calibrationState - 1] = x;

dstY2[calibrationState - 1] = y;

break;

case 4:

x = screenWidth - (int)(screenWidth *

calibrationMargin);

y = screenHeight - (int)(screenHeight *

calibrationMargin);

cf.showCalibration(x, y, size, p);

dstX1[calibrationState - 1] = x;

dstY1[calibrationState - 1] = y;

dstX2[calibrationState - 1] = x;

dstY2[calibrationState - 1] = y;

break;

case 5:

//al almacenar todos los datos se construyen las

matrices y se envian a sendas funciones Warper para que puedan funcionar

warper1.setDestination(dstX1[0], dstY1[0],

dstX1[1], dstY1[1], dstX1[2], dstY1[2], dstX1[3], dstY1[3]);

warper1.setSource(srcX1[0], srcY1[0], srcX1[1],

srcY1[1], srcX1[2], srcY1[2], srcX1[3], srcY1[3]);

warper1.computeWarp();

warper2.setDestination(dstX2[0], dstY2[0],

dstX2[1], dstY2[1], dstX2[2], dstY2[2], dstX2[3], dstY2[3]);

warper2.setSource(srcX2[0], srcY2[0], srcX2[1],

srcY2[1], srcX2[2], srcY2[2], srcX2[3], srcY2[3]);

warper2.computeWarp();

cf.Close();

cf = null;

calibrationState = 0; //una vez enviadas, se pone

calibrationstate a 0 para estar listo para una nueva calibración

cursorControl = true;

BeginInvoke((MethodInvoker)delegate() {

cbCursorControl.Checked = cursorControl; });

// se actualiza la información de uso de la

cámara

track1=UpdateTrackingUtilization1();

track2=UpdateTrackingUtilization2();

//en caso de que ayuda de calibración estuviera

abierta, se cierra.

Page 143: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

143

if (ventana_abierta == true)

{

this.Size = new System.Drawing.Size(317, 314);

cbCursorControl.Checked = true;

tabWiimotes.Visible = false;

ventana_abierta = false;

}

break;

default:

break;

}

}

float UpdateTrackingUtilization1()

{

//se actualiza la información de uso de la cámara del

mando1

//area partiendo de las coordenadas ideales de

calibración,para coincidir con las esquinas de pantalla

float idealArea = (1 - 2 * calibrationMargin) * 1024 * (1

- 2 * calibrationMargin) * 768;

//area del cuadrado realizado en la calibración

float actualArea = 0.5f * Math.Abs((srcX1[1] - srcX1[2])

* (srcY1[0] - srcY1[3]) - (srcX1[0] - srcX1[3]) * (srcY1[1] - srcY1[2]));

float util = (actualArea / idealArea) * 100;

BeginInvoke((MethodInvoker)delegate() {

lblTrackingUtil.Text = util.ToString("f0") + "%"; });

BeginInvoke((MethodInvoker)delegate() {

pbTrackingUtil.Value = (int)util; });

return util;

}

float UpdateTrackingUtilization2()

{

//se actualiza la información de uso de la cámara del

mando2¡

//area partiendo de las coordenadas ideales de

calibración,para coincidir con las esquinas de pantalla

float idealArea = (1 - 2 * calibrationMargin) * 1024 * (1

- 2 * calibrationMargin) * 768;

//area del cuadrado realizado en la calibración

float actualArea = 0.5f * Math.Abs((srcX2[1] - srcX2[2])

* (srcY2[0] - srcY2[3]) - (srcX2[0] - srcX2[3]) * (srcY2[1] - srcY2[2]));

float util = (actualArea / idealArea) * 100;

BeginInvoke((MethodInvoker)delegate() {

lblTrackingUtil2.Text = util.ToString("f0") + "%"; });

BeginInvoke((MethodInvoker)delegate() {

pbTrackingUtil2.Value = (int)util; });

return util;

}

Page 144: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

144

System.Drawing.PointF getSmoothedCursor(int amount)

{

//en esta función se realiza la media de las coordenadas

enviadas para suavizar el movimiento del cursor

int start = smoothingBufferIndex - amount;

if (start < 0)

start = 0;

System.Drawing.PointF smoothed = new

System.Drawing.PointF(0, 0);

int count = smoothingBufferIndex - start;

for (int i = start; i < smoothingBufferIndex; i++)

{

smoothed.X += smoothingBuffer[i %

smoothingBufferSize].X;

smoothed.Y += smoothingBuffer[i %

smoothingBufferSize].Y;

}

smoothed.X /= count;

smoothed.Y /= count;

return smoothed;

}

private void setSmoothing(int smoothing)

{

//en este codigo se detecta el nivel de suavizado que

elije el usuario

smoothingAmount = smoothing;

trackBar1.Value = smoothing;

enableSmoothing = (smoothingAmount != 0);

lblSmoothing.Text = "Nivel de suavizado: " +

smoothingAmount;

}

#endregion

private void btnCalibrar_Click(object sender, EventArgs e)

{

//se indica a calibrationform.cs que se haga visible y

dibuje la ventana de calibración

if (cf == null)

{

cf = new CalibrationForm();

cf.Show();

}

if (cf.IsDisposed)

{

cf = new CalibrationForm();

cf.Show();

}

cursorControl = false;

calibrationState = 1;

doCalibration();

}

private void cbCursorControl_CheckedChanged(object sender,

EventArgs e)

{

//al acabar la calibración se activa cursor control

automaticamente

Page 145: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

145

cursorControl = cbCursorControl.Checked;

}

private void trackBar1_Scroll(object sender, EventArgs e)

{

//se indica que trackbar1 contiene el valor de suavizado

deseado por el usuario

smoothingAmount = trackBar1.Value;

enableSmoothing = (smoothingAmount != 0);

lblSmoothing.Text = "Nivel de suavizado: " +

smoothingAmount;

}

private void controlDelRatonToolStripMenuItem_Click(object

sender, EventArgs e)

{

//al pulsar la pestaña de control del raton se abre la

ventana nueva

mouse_ctr = new MouseControl();

mouse_ctr.Show();

}

private void acercaDeToolStripMenuItem_Click(object sender,

EventArgs e)

{

//al pulsar la pestaña acerca de se abre la ventana con

la información

about = new AboutBox1();

about.Show();

}

private void

abrirVentanaCalibraciónToolStripMenuItem_Click(object sender, EventArgs

e)

{

//se mira si la ventana esta cerrada y si lo esta se

amplia el tamaño del formulario y se muestra el control de los mandos

if (ventana_abierta == false)

{

this.Size = new System.Drawing.Size(315, 561);

cbCursorControl.Checked = false; //al abrir ayuda de

calibración se desactiva cursor control

tabWiimotes.Visible = true;

ventana_abierta = true;

}

//si la ventana estaba abierta, se cierra

else if (ventana_abierta == true)

{

this.Size = new System.Drawing.Size(317, 314);

cbCursorControl.Checked = true;

tabWiimotes.Visible = false;

ventana_abierta = false;

}

}

Page 146: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

146

private void

abrirProgramaPresentacionesToolStripMenuItem_Click(object sender,

EventArgs e)

{

//se intenta abrir el archivo seleccionado

try

{

System.Diagnostics.Process p = new

System.Diagnostics.Process();

p.StartInfo.FileName = @"C:\Archivos de programa\UW

CSE\Classroom Presenter 3\Presenter.exe";

p.Start();

}

catch (Exception ex)

{

//en caso de que no se encuentre en Archivos de

programa, se busca en Program Files, para posibles versiones inglesas de

SO

try

{

System.Diagnostics.Process p = new

System.Diagnostics.Process();

p.StartInfo.FileName = @"C:\Program Files\UW

CSE\Classroom Presenter 3\Presenter.exe";

p.Start();

}

catch (Exception exc)

{

// si no se encuentra en ninguna de las dos

carpetas anteriores, se muestra ventana de error

MessageBox.Show("Se ha detectado un error al

intentar abrir la aplicación\n Puede deberse a dos causas:\n - Esta

aplicación no esta instalada en su PC\n - La aplicación se ha instalado

en una ubicación incorrecta", "Error", MessageBoxButtons.OK,

MessageBoxIcon.Error);

}

}

}

private void

abrirTecladoVirtualToolStripMenuItem_Click(object sender, EventArgs e)

{

//se intenta abrir el archivo seleccionado

try

{

System.Diagnostics.Process p = new

System.Diagnostics.Process();

p.StartInfo.FileName = @"C:\Archivos de

programa\Click-N-Type\Click-N-Type.exe";

p.Start();

}

catch (Exception ex)

{

//en caso de que no se encuentre en Archivos de

programa, se busca en Program Files, para posibles versiones inglesas de

SO

try

{

System.Diagnostics.Process p = new

System.Diagnostics.Process();

Page 147: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

147

p.StartInfo.FileName = @"C:\Program Files\Click-

N-Type\Click-N-Type.exe";

p.Start();

}

catch (Exception exc)

{

// si no se encuentra en ninguna de las dos

carpetas anteriores, se muestra ventana de error

MessageBox.Show("Se ha detectado un error al

intentar abrir la aplicación\n Puede deberse a dos causas:\n - Esta

aplicación no esta instalada en su PC\n - La aplicación se ha instalado

en una ubicación incorrecta", "Error", MessageBoxButtons.OK,

MessageBoxIcon.Error);

}

}

}

}

}

Código 18. Código fuente del archivo MultipleWiimoteForm.cs

Page 148: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

148

14.3.3 Archivo CalibrationForm.cs

Este archivo contiene el código fuente necesario para dibujar la pantalla de calibración. Es decir, hace que en la pantalla se muestre una imagen blanca de fondo y la cruz roja en el lugar donde el usuario tiene que colocar el puntero IR

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Drawing.Imaging;

using System.Text;

using System.Windows.Forms;

namespace WiimoteTest

{

public partial class CalibrationForm : Form

{

Bitmap bCalibration;

Graphics gCalibration;

int screenWidth = 1024;//valores por defecto de resolucion de

pantalla

int screenHeight = 768;

public CalibrationForm()

{

Rectangle rect = new Rectangle();

rect = Screen.GetWorkingArea(this); // se comprueba la

resolución real de la pantalla

InitializeComponent();

this.FormBorderStyle = FormBorderStyle.None;

this.Left = 0;

this.Top = 0;

this.Size = new Size(rect.Width, rect.Height);

this.Text = "Calibration - Working area:" +

Screen.GetWorkingArea(this).ToString() + " || Real area: " +

Screen.GetBounds(this).ToString();

//se comprueba si se apreta alguna tecla del teclado, porque

si se apreta "esc" se tiene que cerrar la calibración

this.KeyDown += new

System.Windows.Forms.KeyEventHandler(this.OnKeyPress);

//se actualiza el valor de las variables con la resolución de

la pantalla detectada antes

screenHeight = rect.Height;

screenWidth = rect.Width;

//se inicializan las funciones necesarias para mostrar la

imagen de calibración en pantalla

bCalibration = new Bitmap(screenWidth, screenHeight,

PixelFormat.Format24bppRgb);

gCalibration = Graphics.FromImage(bCalibration);

pbCalibrate.Left = 0;

pbCalibrate.Top = 0;

Page 149: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

149

pbCalibrate.Size = new Size(rect.Width, rect.Height);

gCalibration.Clear(Color.White);

BeginInvoke((MethodInvoker)delegate() { pbCalibrate.Image =

bCalibration; });

}

private void OnKeyPress(object sender,

System.Windows.Forms.KeyEventArgs e)

{

//en caso de que se pulse una tecla, se lee si es "esc". Si

lo es, se cierra la calibración

if ((int)(byte)e.KeyCode == (int)Keys.Escape)

{

this.Dispose();

return;

}

}

public void drawCrosshair(int x, int y, int size, Pen p, Graphics

g){

//esta función dibuja la cruz sobre la que el usuario tiene

que colocar el puntero IR

g.DrawEllipse(p, x - size / 2, y - size / 2, size, size);

g.DrawLine(p, x-size, y, x+size, y);

g.DrawLine(p, x, y-size, x, y+size);

}

public void showCalibration(int x, int y, int size, Pen p){

//esta función convierte toda la pantalla en color blanco.

Sobre ella se dibujan las cruces

gCalibration.Clear(Color.White);

drawCrosshair(x,y,size, p, gCalibration);

BeginInvoke((MethodInvoker)delegate() { pbCalibrate.Image =

bCalibration; });

}

}

}

Código 19. Código fuente del archivo CalibrationForm.cs

Page 150: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

150

14.3.4 Archivo WiimoteInfo.cs

Este archivo implementa el funcionamiento de la ventana de Ayuda a calibración. Actualiza la información de esa ventana según las últimas coordenadas que ha enviado el mando y muestra en una ventana de fondo negro las coordenadas enviadas en forma de punto rojo. Por tanto, representa donde se encuentre en punto IR captado según la visión total de la cámara. Esta información ayuda al usuario a colocar el mando de manera correcta.

using System;

using System.Drawing;

using System.Drawing.Imaging;

using System.Windows.Forms;

using WiimoteLib;

namespace WiimoteTest

{

public partial class WiimoteInfo : UserControl

{

private delegate void

UpdateWiimoteStateDelegate(WiimoteChangedEventArgs args);

//se definen las funciones necesarias para realizar imagenes

de diversas formas

private Bitmap b = new Bitmap(256, 192,

PixelFormat.Format24bppRgb);

private Graphics g;

private Wiimote mWiimote;

public WiimoteInfo()

{

InitializeComponent();

g = Graphics.FromImage(b);

}

public WiimoteInfo(Wiimote wm) : this()

{

//se identifica cada mando

mWiimote = wm;

}

public void UpdateState(WiimoteChangedEventArgs args)

{

//en caso de que la información del mando cambie, se

actualizan los datos

BeginInvoke(new

UpdateWiimoteStateDelegate(UpdateWiimoteChanged), args);

}

public void UpdateWiimoteChanged(WiimoteChangedEventArgs args)

{

//cuando hay un cambio en la información se analiza y se

muestran las coordenadas enviadas en la ventana de ayuda a calibración

WiimoteState ws = args.WiimoteState;

CheckForIllegalCrossThreadCalls=false; //se introduce para

evitar mensaje de error en compilación

Page 151: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

151

g.Clear(Color.Black); //en caso de que no se detecten

coordenadas de punto IR se pinta toda la ventana de negro

//en caso de que haya coordenadas de punto IR, se llama

a la función UpdateIR, la cual dibuja la posición correspondiente a esas

coordenadas en la ventana

UpdateIR(ws.IRState.IRSensors[0],Color.Red);

UpdateIR(ws.IRState.IRSensors[1],Color.Red);

UpdateIR(ws.IRState.IRSensors[2],Color.Red);

UpdateIR(ws.IRState.IRSensors[3],Color.Red);

pbIR.Image = b;

}

private void UpdateIR(IRSensor irSensor,Color color)

{

//esta función muestra en la ventana de ayuda de

calibración la posición del puntero respecto la visión total de la cámara

del mando

if(irSensor.Found)

{

//si hay punto IR, se pinta una redonda roja en

la posición enviada por el mando

g.DrawEllipse(new Pen(color),

(int)(irSensor.RawPosition.X / 4), (int)(irSensor.RawPosition.Y / 4),

irSensor.Size + 6, irSensor.Size + 6);

g.DrawEllipse(new Pen(color),

(int)(irSensor.RawPosition.X / 4), (int)(irSensor.RawPosition.Y / 4),

irSensor.Size + 5, irSensor.Size + 5);

g.DrawEllipse(new Pen(color),

(int)(irSensor.RawPosition.X / 4), (int)(irSensor.RawPosition.Y / 4),

irSensor.Size + 4, irSensor.Size + 4);

g.DrawEllipse(new Pen(color),

(int)(irSensor.RawPosition.X / 4), (int)(irSensor.RawPosition.Y / 4),

irSensor.Size + 3, irSensor.Size + 3);

g.DrawEllipse(new Pen(color),

(int)(irSensor.RawPosition.X / 4), (int)(irSensor.RawPosition.Y / 4),

irSensor.Size + 2, irSensor.Size + 2);

g.DrawEllipse(new Pen(color),

(int)(irSensor.RawPosition.X / 4), (int)(irSensor.RawPosition.Y / 4),

irSensor.Size + 1, irSensor.Size + 1);

}

}

}

}

Código 20. Código fuente del archivo WiimoteInfo.cs

Page 152: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

152

14.3.5 Archivo Warper1.cs y Warper2.cs

Tanto este archivo como Warper2.cs se encargan de transformar las coordenadas enviadas por el mando en coordenadas sobre la pantalla del ordenador, para así conocer la posición a la que enviar el cursor del ratón. En este caso Warper1 solo transforma las coordenadas enviadas por el mando 1. No se puede utilizar la misma función para los mandos porque para funcionar, previamente necesita tratar las coordenadas que se han enviado en el proceso de calibración, y estas son diferentes entre el mando 1 y el mando 2. Por este motivo se divide la función en dos archivos con el mismo código, ya que la información que necesitan calcular previamente para poder funcionar varía de uno a otro. La estructura será la misma pero luego almacenan informaciones diferentes. El código que se muestra a continuación corresponde al archivo Warper1.cs. El código de Warper2.cs es idéntico al mostrado, únicamente cambia la sexta línea. En vez de poner “class Warper1”

pone “class Warper2” para que se identifique como una función diferente, pero el código

restante es idéntico.

using System;

using System.Collections.Generic;

using System.Text;

namespace WiimoteTest

{

class Warper1

{

//este código se encarga de transformar las coordenadas envias

por el mando en coordenadas sobre la pantalla del PC

//se definen las diversas matrices utilizadas para los cálculos

necesarios

float[] srcX = new float[4];

float[] srcY = new float[4];

float[] dstX = new float[4];

float[] dstY = new float[4];

float[] srcMat = new float[16];

float[] dstMat = new float[16];

float[] warpMat = new float[16];

bool dirty;

public Warper1()

{

setIdentity();

}

public void setIdentity()

{

// se inicializan las matrices definidas anteriormente

setSource(0.0f, 0.0f,

1.0f, 0.0f,

0.0f, 1.0f,

1.0f, 1.0f);

setDestination(0.0f, 0.0f,

1.0f, 0.0f,

0.0f, 1.0f,

1.0f, 1.0f);

computeWarp();

}

Page 153: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

153

public void setSource( float x0,

float y0,

float x1,

float y1,

float x2,

float y2,

float x3,

float y3){

//se indica como tratar los valores enviados al acabar la

calibración desde MultipleWiimoteForm

srcX[0] = x0;

srcY[0] = y0;

srcX[1] = x1;

srcY[1] = y1;

srcX[2] = x2;

srcY[2] = y2;

srcX[3] = x3;

srcY[3] = y3;

dirty = true;

}

public void setDestination(float x0,

float y0,

float x1,

float y1,

float x2,

float y2,

float x3,

float y3){

//se indica como tratar los valores enviados al acabar la

calibración desde MultipleWiimoteForm

dstX[0] = x0;

dstY[0] = y0;

dstX[1] = x1;

dstY[1] = y1;

dstX[2] = x2;

dstY[2] = y2;

dstX[3] = x3;

dstY[3] = y3;

dirty = true;

}

public void computeWarp() {

//se rellenan las matrices con los valores necesarios

computeQuadToSquare( srcX[0],srcY[0],

srcX[1],srcY[1],

srcX[2],srcY[2],

srcX[3],srcY[3],

srcMat);

computeSquareToQuad( dstX[0], dstY[0],

dstX[1], dstY[1],

dstX[2], dstY[2],

dstX[3], dstY[3],

dstMat);

//la multiplicación de ambas matrices da como resultado la

matriz de homografia.

//La matriz resultante se multiplica por los puntos que envia

el mando y transforma las coordenadas enviadas por el mando en

coordenadas sobre la pantalla

Page 154: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

154

multMats(srcMat, dstMat, warpMat);

dirty = false;

}

public void multMats(float[] srcMat, float[] dstMat, float[]

resMat) {

//Función que multiplica correctamente la matriz

computeQuadToSquare con la matriz computeSquareToQuad

for (int r = 0; r < 4; r++) {

int ri = r * 4;

for (int c = 0; c < 4; c++) {

resMat[ri + c] = (srcMat[ri ] * dstMat[c ] +

srcMat[ri + 1] * dstMat[c + 4] +

srcMat[ri + 2] * dstMat[c + 8] +

srcMat[ri + 3] * dstMat[c + 12]);

}

}

}

public void computeSquareToQuad( float x0,

float y0,

float x1,

float y1,

float x2,

float y2,

float x3,

float y3,

float[] mat)

{

//se calcula la matriz necesaria para transformar el cuadrado

que forma la pantalla en un cuadrilátero

float dx1 = x1 - x2, dy1 = y1 - y2;

float dx2 = x3 - x2, dy2 = y3 - y2;

float sx = x0 - x1 + x2 - x3;

float sy = y0 - y1 + y2 - y3;

float g = (sx * dy2 - dx2 * sy) / (dx1 * dy2 - dx2 * dy1);

float h = (dx1 * sy - sx * dy1) / (dx1 * dy2 - dx2 * dy1);

float a = x1 - x0 + g * x1;

float b = x3 - x0 + h * x3;

float c = x0;

float d = y1 - y0 + g * y1;

float e = y3 - y0 + h * y3;

float f = y0;

//se define correctamente cada elemento de la matriz

mat[ 0] = a; mat[ 1] = d; mat[ 2] = 0; mat[ 3] = g;

mat[ 4] = b; mat[ 5] = e; mat[ 6] = 0; mat[ 7] = h;

mat[ 8] = 0; mat[ 9] = 0; mat[10] = 1; mat[11] = 0;

mat[12] = c; mat[13] = f; mat[14] = 0; mat[15] = 1;

}

Page 155: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

155

public void computeQuadToSquare( float x0,

float y0,

float x1,

float y1,

float x2,

float y2,

float x3,

float y3,

float[] mat)

{

//se calcula la matriz necesaria para transformar el

cuadrilátero que forma la imagen captada del mando en un cuadrado

computeSquareToQuad(x0,y0,x1,y1,x2,y2,x3,y3, mat);

// se invierte la matriz de los adjuntos

float a = mat[ 0], d = mat[ 1], /* se ignora */

g = mat[ 3];

float b = mat[ 4], e = mat[ 5], /* 3a columna*/

h = mat[ 7];

/* se ignora la 3a fila */

float c = mat[12], f = mat[13];

float A = e - f * h;

float B = c * h - b;

float C = b * f - c * e;

float D = f * g - d;

float E = a - c * g;

float F = c * d - a * f;

float G = d * h - e * g;

float H = b * g - a * h;

float I = a * e - b * d;

// Cálculo del determinante "I" = a * (e - f * h) + b *

(f * g - d) + c * (d * h - e * g);

float idet = 1.0f / (a * A + b * D + c

* G);

mat[ 0] = A * idet; mat[ 1] = D * idet; mat[ 2] = 0;

mat[ 3] = G * idet;

mat[ 4] = B * idet; mat[ 5] = E * idet; mat[ 6] = 0;

mat[ 7] = H * idet;

mat[ 8] = 0 ; mat[ 9] = 0 ; mat[10] = 1;

mat[11] = 0 ;

mat[12] = C * idet; mat[13] = F * idet; mat[14] = 0;

mat[15] = I * idet;

}

public float[] getWarpMatrix()

{

//se devuelve el resultado de la transformación de

coordenadas

return warpMat;

}

public void warp(float srcX, float srcY, ref float dstX, ref

float dstY)

{

Page 156: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

156

//se utiliza dirty como un flag que indica que los datos han

cambiado y hay que transformar las nuevas coordenadas recibidas

if (dirty)

computeWarp();

Warper1.warp(warpMat, srcX, srcY, ref dstX, ref dstY);

}

public static void warp(float[] mat, float srcX, float srcY, ref

float dstX, ref float dstY){

//se almacena el resultado y se devuelven las coordenadas X e

Y a las que habria que enviar el cursor del ratón

float[] result = new float[4];

float z = 0;

result[0] = (float)(srcX * mat[0] + srcY*mat[4] + z*mat[8] +

1*mat[12]);

result[1] = (float)(srcX * mat[1] + srcY*mat[5] + z*mat[9] +

1*mat[13]);

result[2] = (float)(srcX * mat[2] + srcY*mat[6] + z*mat[10] +

1*mat[14]);

result[3] = (float)(srcX * mat[3] + srcY*mat[7] + z*mat[11] +

1*mat[15]);

dstX = result[0]/result[3];

dstY = result[1]/result[3];

}

}

}

Código 21. Código fuente de los archivos Warper1.cs y Warper2.cs

Page 157: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

157

14.3.6 Archivo MouseControl.cs

En este archivo no se implementan las funciones addicionales de control del ratón, como pueden ser doble clic o clic derecho. El cuerpo del código que realiza esas funciones se encuentra en MultipleWiimoteForm.cs. En MouseControl.cs solo se programa la modificación de los valores de las variables que controlan la activación de esas funciones, según el botón que pulse el usuario. Por tanto, se programa una ventana con diferentes botones, en la que cada botón tendrá implementado el código necesario para modificar una variable booleana global que active la función deseada.

using System;

using System.Collections.Generic;

using System.Windows.Forms;

using WiimoteLib;

using System.Threading;

using System.ComponentModel;

using System.Drawing;

using System.Drawing.Imaging;

using System.Text;

using System.Runtime.InteropServices;//para detectar eventos generados

por el ratón o el teclado

using System.IO;//para guardar la información de calibración en un

archivo

namespace WiimoteTest

{

public partial class MouseControl : Form

{

public MouseControl()

{

InitializeComponent();

}

public void btn_dobleclick_Click(object sender, EventArgs e)

{

//en caso de hacer doble clic, se espera 150 ms y se pone la

variable doble_click a true

//se espera 150 ms porque sino se haria doble clic encima del

boton pulsado

Thread.Sleep(150);

MultipleWiimoteForm.doble_click = true;

}

private void btn_Clickder_Click(object sender, EventArgs e)

{

//en caso de hacer clic derecho, se espera 150 ms y se pone

la variable clic_der a true

//se espera 150 ms porque sino se haria clic derecho encima

del boton pulsado

Thread.Sleep(150);

MultipleWiimoteForm.click_der = true;

}

private void btn_activar_MouseEnter(object sender, EventArgs e)

{

Page 158: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

158

//en caso de estar arrastrando y poner el cursor encima de

Reactivar, se cambia el valor de la variable arrastre para dejar de

hacerlo

MultipleWiimoteForm.arrastre = false;

chk_arrastre.CheckState = CheckState.Unchecked;

}

private void btn_arrastre_Click(object sender, EventArgs e)

{

//si el usuario desea arrastrar sin hacer clic, se cambia el

valor de arrastre y se activa la casilla que indica que arrastre activo

MultipleWiimoteForm.arrastre = true;

chk_arrastre.CheckState = CheckState.Checked;

}

}

}

Código 22. Código fuente del archivo MouseControl.cs

14.3.7 Archivo AboutBox1.cs

Este archivo únicamente almacena los datos de la versión y la descripción del programa. Es la típica ventana “Acerca de” que se puede encontrar en cualquier programa,

en la cual se informa sobre datos característicos del programa. En el código fuente únicamente se implementa una línea de código para indicar que se cierre la ventana al pulsar el botón OK.

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Drawing;

using System.Reflection;

using System.Windows.Forms;

namespace WiimoteTest

{

partial class AboutBox1 : Form

{

public AboutBox1()

{

InitializeComponent();

}

private void okButton_Click(object sender, EventArgs e)

{

//al pulsar el boton OK, se tiene que cerrar la ventana

this.Close();

}

}

}

Código23 . Código fuente del archivo AboutBox1.cs

Page 159: Wiimote Hack - Rovira i Virgili Universitydeeea.urv.cat/public/PROPOSTES/pub/pdf/1231pub.pdf · 2009-09-22 · pizarra digital interactiva de bajo coste, por debajo de 200 €, sin

159

14.4 Agradecimientos

En este apartado me gustaría agradecer la ayuda que he recibido de diversas personas durante la realización del proyecto, sin la cual nunca habría llegado a ser lo que ha sido.

A Toni Amenós Murtra, por darme tantísimas ideas y estar ahí siempre que he tenido una duda. Hay pocos amigos como él, pero muchos menos programadores que sepan tantas cosas. Muchas gracias por toda la ayuda técnica que me has dado durante el desarrollo del proyecto, por aguantarme hasta resolver todas mis dudas y por ayudarme a entenderlo todo. Sin su inestimable ayuda este programa no habría llegado a ser lo que es.

A Verónica Rodríguez Salazar por las mejoras estéticas que ha realizado en el puntero infrarrojo y por todo el apoyo moral que me ha dado. Siempre ha estado ahí cuando era necesario.

A Sergi Plana, por explicarme todas mis dudas con gran detalle y ayudarme con la realización del código y de los estudios. Si su ayuda habría tardado mucho en poder hacer funcionar esto. Me ha dado las ideas necesarias en el momento adecuado para que pudiera obtener el resultado que esperaba.

A José Manuel Díaz, por cederme un trozo de su espacio de trabajo y aguantar las largas horas que me he pasado en el despacho de Mbot Solutions. También por ayudarme con la elección de los soportes necesarios para aguantar los mandos, sin los cuales no se podría haber probado el programa sobre una imagen proyectada.

Y por último, a José Luís Ramírez Falo, por prestarme su atención durante todo este tiempo y por toda la ayuda que me ha dado en la realización de esta memoria.