Preview only show first 10 pages with watermark. For full document please download

Universidad De Costa Rica Facultad De Ingeniería Escuela De Ingeniería Eléctrica

   EMBED


Share

Transcript

Universidad de Costa Rica Facultad de Ingeniería Escuela de Ingeniería Eléctrica IE – 0502 Proyecto Eléctrico Desarrollo de plataforma basada en Software Libre para adquisición y procesamiento de señales bioeléctricas como componente para una Interfaz Cerebro - Computador Por: Jeffrey Esquivel S. Ciudad Universitaria Rodrigo Facio Marzo del 2010 Desarrollo de plataforma basada en Software Libre para adquisición y procesamiento de señales bioeléctricas como componente para una Interfaz Cerebro - Computador Por: Jeffrey Esquivel S. Sometido a la Escuela de Ingeniería Eléctrica de la Facultad de Ingeniería de la Universidad de Costa Rica como requisito parcial para optar por el grado de: BACHILLER EN INGENIERÍA ELÉCTRICA Aprobado por el Tribunal: _________________________________ Dr. Lochi Yu, Ph.D Profesor Guía _________________________________ Dr. Jaime Fornaguera, Ph.D Profesor lector _________________________________ Michael Padilla, MSc. Profesor lector ii DEDICATORIA A mi hermano, a mi padre, a mi madre y a mi abuelo. iii RECONOCIMIENTOS El autor desea agradecerle al Dr. Lochi Yu, Director del Laboratorio de Ingeniería Biomédica de la Escuela de Ingeniería Eléctrica de la Universidad de Costa Rica, sin su apoyo este trabajo simplemente no existiría. También a todos los integrantes del Programa de Investigación en Neurociencias de la Universidad de Costa Rica por haberlo acogido durante la duración de este trabajo y en especial al Msc. Michael Padilla Mora quién amablemente atendió todas las dudas no relacionadas con ingeniería (cuya cantidad no fue para nada despreciable) y al Dr. Jaime Fornaguera por su tiempo y atención a la hora de revisar este trabajo. Finalmente, aún cuando este trabajo es el resultado final del esfuerzo colectivo de muchas personas, el autor desea recalcar que todos los errores (de hecho u omisión) son su completa responsabilidad. Este trabajo fue financiado parcialmente por el Programa de Investigación en Neurociencias de la Universidad de Costa Rica. iv ÍNDICE GENERAL ÍNDICE DE FIGURAS..................................................................................vii ÍNDICE DE TABLAS..................................................................................viii NOMENCLATURA........................................................................................ix RESUMEN........................................................................................................x CAPÍTULO 1: Introducción...........................................................................1 1.1 Justificación.......................................................................................................................2 1.2 Objetivos...........................................................................................................................3 1.2.1 Objetivo general.....................................................................................................3 1.2.2 Objetivos específicos.............................................................................................3 1.3 Metodología......................................................................................................................3 CAPÍTULO 2: Desarrollo teórico...................................................................5 2.1 La generación de señales bioeléctricas en el cerebro........................................................6 2.2 Sistemas de electroencefalografía.....................................................................................9 2.2.1 Ondas o ritmos cerebrales y su clasificación.......................................................10 2.3 Plataformas de procesamiento e interpretación de señales.............................................13 2.4 BCIs y sus aplicaciones...................................................................................................13 2.5 Otros conceptos importantes...........................................................................................14 2.5.1 Software Libre......................................................................................................14 2.5.2 Blender y su motor de juegos (BGE)...................................................................15 2.5.3 Red Periférica de Realidad Virtual (VRPN)........................................................16 CAPÍTULO 3: Elección de la plataforma....................................................17 3.1 Sistemas basados en MATLAB.....................................................................................18 3.2 Sistemas independientes.................................................................................................18 3.1.1 BioSig..................................................................................................................19 3.1.2 OpenViBE...........................................................................................................19 3.1.3 BCI2000..............................................................................................................20 CAPÍTULO 4: Interfaz de la plataforma con el sistema de electroencefalografía......................................................................................22 4.1 Diseño de la interfaz OpenViBE - EEG..........................................................................22 4.2 Análisis de un controlador existente: el Oscilador Genérico..........................................25 v 4.1.1 Constructor CDriverGenericOscillator()..............................................................26 4.1.2 Método getName(), método getHeader() y método isConfigurable()..................26 4.1.3 Método initialize()................................................................................................26 4.1.4 Método uninitialize()............................................................................................27 4.1.5 Método start() ......................................................................................................28 4.1.6 Método stop().......................................................................................................28 4.1.7 Método loop().......................................................................................................28 4.1.8 Método configure()..............................................................................................29 CAPÍTULO 5: Interfaz de la plataforma con la aplicación final..............30 5.1 Diseño de la Interfaz OpenVIBE – BGE.......................................................................32 5.2 Implementación de la Interfaz OpenVIBE - BGE.........................................................33 CAPÍTULO 6: Conclusiones y recomendaciones........................................35 6.1 Conclusiones..................................................................................................................35 6.2 Recomendaciones...........................................................................................................35 BIBLIOGRAFÍA............................................................................................37 ANEXOS.........................................................................................................40 Anexo 1: archivo ovasCDriverGenericOscilator.h completo...............................................40 Anexo 2: archivo ovasCDriverGenericOscilator.cpp completo............................................41 Anexo 3: archivo python_vrpn/CMakeLists.txt corregido...................................................44 Anexo 4: archivo python_vrpn/vrpn_Analog.i corregido.....................................................45 Anexo 5: Procedimento para la compilación de libvrpn con bindings en Python sobre plataforma Linux...................................................................................................................46 Anexo 6: Módulo de Python para la interacción entre el BGE y OpenViBE.......................47 vi ÍNDICE DE FIGURAS Figura 2.1: Diagrama de bloques básico de un sistema BCI incorporando la detección de la señal, su procesamiento y su utilización [modificado de Thorpe et al. 2005]........................5 Figura 2.2: Ilustración de las partes básicas de la neurona [Wikimedia Commons. n.d.]......7 Figura 2.3: Radios y resistividad de las distintas capas de la cabeza [Hurtado. 2010]...........9 Figura 2.4: Las cinco ondas cerebrales típicas [Wikimedia Commons. n.d.].......................11 Figura 3.1: Interface Gráfica de Usuario del diseñador de OpenViBE con dos bloques interconectados y desplegando el menú contextual [Renard et al. n.d.]...............................20 Figura 4.1: Flujo de trabajo de un controlador del servidor de adquisición de OpenViBE [Renard et al. 2010]...............................................................................................................24 Figura 5.1: A la izquierda, niños utilizando el AVC. A la derecha, una toma de pantalla del AVC [Padilla. 2010]..............................................................................................................30 Figura 5.2: Diagrama de los componentes de la comunicación entre OpenViBE y BGE [Arias. 2010].........................................................................................................................32 vii ÍNDICE DE TABLAS Tabla 4.1: Miembros de la clase CDriverGenericOscillator y su tipo..................................25 viii NOMENCLATURA 2D Dos Dimensiones 3D Tres Dimensiones AVC Ambiente Virtual Cooperativo API Interfaz de Programación de Aplicaciones (Application Programming Interface) BCI Interfaz Cerebro-Computador (Brain-Computer Interface) BGE Motor de Juegos de Blender (Blender Game Engine) EEG Electroencefalograma HID Dispositivo de Interfaz Humana (Human Interface Device) SL Software Libre VM Máquina Virtual (Virtual Machine) VR Realidad Virtual (Virtual Reality) VRPN Red Periférica de Realidad Virtual (Virtual Reality Peripheral Network) ix RESUMEN Este informe expone el trabajo realizado para la elección y adaptación de una plataforma en Software Libre (SL) para la Interfaz Cerebro – Computador (BCI), que formará parte del proyecto de Ambientes Virtuales Cooperativos (AVCs) del Programa de Investigación en Neurociencias y la Escuela de Ingeniería Eléctrica de la Universidad de Costa Rica. El documento describe el proceso de valoración y comparación entre distintas plataformas de SL, detalla y justifica la elección de una plataforma específica e investiga su adaptación como intermediaria entre el equipo de adquisición de datos y las aplicaciones finales desarrolladas con Blender Game Engine (BGE). Así, se establece una plataforma con tres etapas básicas: una de adquisición de señales, una de procesamiento e interpretación y una de comunicación con la aplicación final. Finalmente se presentan algunas conclusiones y recomendaciones que deberán ser consideradas durante la continuación del proyecto. x CAPÍTULO 1: Introducción “In order to make an apple pie from scratch, you must first create the universe.” – Carl Sagan Este proyecto involucra la investigación realizada para la elección y adaptación de una plataforma en Software Libre para una Interfaz Cerebro – Computador (BCI), que pueda adquirir, procesar, interpretar y utilizar señales bioeléctricas provenientes del cerebro humano como parte de una aplicación con jugabilidad multiusuario. La misma formará parte del proyecto “Ambientes Virtuales Cooperativos: Herramientas innovadoras para la educación preescolar” del Programa de Investigación en Neurociencias y la Escuela de Ingeniería Eléctrica de la Universidad de Costa Rica. Esta plataforma constará de tres componentes de software esenciales que serán descritos a continuación: • El componente capaz de adquirir señales: el proceso físico de adquisición de las señales se llevará a cabo desde un equipo de electroencefalografía no invasiva, por lo que será necesario que la plataforma cuente con un componente capaz de adquirir estas señales y las transforme en una entrada adecuada para su procesamiento por un componente posterior. • El componente de procesamiento e interpretación de las señales: las funciones que realiza este componente pueden variar dependiendo de muchos factores (particularidades del equipo de adquisición, la región del cerebro que se está 1 2 analizando, el algoritmo de interpretación, etc.), por lo que el componente que se utilice para este propósito, debe ser suficientemente flexible como para poder ser adaptado a un gran número de distintos posibles escenarios. • El componente de comunicación con la aplicación: finalmente, las señales, ya interpretadas, serán utilizadas como entradas o comandos en un juego tipo Ambiente Virtual Cooperativo (AVC) desarrollado utilizando el Motor de Juegos de Blender (BGE); esto implica que la plataforma deberá contar con un componente capaz de comunicarse con un juego ejecutándose a través del BGE. 1.1 Justificación Ferdig (2006) afirma que los elementos de innovación y motivación en un sistema tecnológico suelen propiciar un mayor involucramiento por parte de los usuarios. Es por esto que uno de los objetivos específicos del proyecto de AVCs es el “desarrollar una interfase de interacción basada en la detección de cambios electrofisiológicos en las ondas cerebrales de los usuarios y apta para ser utilizada con aplicaciones educativas.” (Padilla, 2010). Este trabajo de graduación representa el primer esfuerzo hacia la conformación de la plataforma de Software Libre que se utilizará como base para cumplir con el objetivo descrito en el párrafo anterior. 3 1.2 Objetivos 1.2.1 Objetivo general • Desarrollar una plataforma de Software Libre capaz de adquirir señales bioeléctricas para ser utilizada como un componente dentro de un sistema de Interfaz Cerebro – Computador. 1.2.2 • Objetivos específicos Estudiar y caracterizar las herramientas de Software Libre disponibles para la adquisición de señales bioeléctricas. • Definir una interfaz de bajo nivel para establecer la conexión con el hardware de adquisición y/o modelos de las señales. • Definir una interfaz de alto nivel para el control de aplicaciones en hardware y/o software. • 1.3 Incorporar un generador de ondas cerebrales a la plataforma desarrollada. Metodología El proyecto se divide en dos etapas: primero se realizará una investigación bibliográfica de los distintos sistemas de SL disponibles para el procesamiento y análisis de señales bioeléctricas del cerebro, con el fin de poder elegir uno sobre el cual basar la implementación de la plataforma. Luego se procederá con el estudio, diseño y documentación de los procedimientos necesarios para integrar esta plataforma con los 4 demás componentes del BCI (específicamente, el equipo de electroencefalografía y el AVC ejecutándose a través del BGE). CAPÍTULO 2: Desarrollo teórico “We must always think about things, and we must think about things as they are, not as they are said to be.” – George Bernard Shaw Para comprender mejor el funcionamiento de un sistema, suele ser muy útil diagramar un modelo que lo esquematice desde sus etapas iniciales hasta sus salidas finales. A través de este tipo de representaciones, llamadas diagramas de bloques, se pueden describir los procesos y/o transformaciones que sufren las entradas en su tránsito por el sistema. Figura 2.1: Diagrama de bloques básico de un sistema BCI incorporando la detección de la señal, su procesamiento y su utilización [modificado de Thorpe et al. 2005] 5 6 En la figura 2.1 podemos observar el diagrama de bloques de un sistema Interfaz Cerebro – Computador, donde se esquematiza el proceso desde la generación de las señales bioeléctricas en el cerebro hasta el resultado final del sistema, es decir, la aplicación particular para ese BCI. Este capítulo se ha dividido conforme al diagrama de bloques de la figura 2.1, de manera que cada sección incorpora la teoría más importante con respecto a su etapa correspondiente. Al final del capítulo se incluye teoría sobre algunos conceptos y aplicaciones utilizados para este trabajo; los cuales facilitarán el entendimiento del desarrollo práctico del mismo. 2.1 La generación de señales bioeléctricas en el cerebro “La actividad neuronal del cerebro humano inicia entre la décimo sétima y la vigésima tercera semana de desarrollo prenatal. Se cree que desde esta etapa temprana y a través de toda la vida, las señales eléctricas generadas en el cerebro representan también el estado del cuerpo completo y no solo el funcionamiento cerebral.” (Sanei & Chambers, 2007, p. 1) Estas señales eléctricas tienen su origen en la unidad más básica de la vida: la célula, y más específicamente, en un tipo particular de célula del Sistema Nervioso que se denomina neurona. En el cerebro humano, cientos de miles de millones de neuronas se interconectan entre sí, y con otras células, para llevar a cabo todas las tareas que este órgano tiene a su cargo. 7 Figura 2.2: Ilustración de las partes básicas de la neurona [Wikimedia Commons. n.d.] Tal y cómo se puede observar en la figura 2.2, una neurona se compone principalmente de cuatro partes: el soma o cuerpo celular, el axón, las dendritas y las ramificaciones terminales del axón. El soma contiene al núcleo y las demás partes básicas de la célula que posibilitan los procesos vitales de la misma; el axón (con sus terminales) y las dendritas tienen como función la transmisión y recepción, respectivamente, de las señales bioeléctricas, llamadas potenciales de acción o impulsos (Carlson, 2006). La diferencia de potencial eléctrico entre el interior y el exterior de una neurona cuando se encuentra en estado estacionario (o de reposo) depende de su tipo, pero típicamente se encuentra entre los -40 y -90 milivoltios. Un potencial de acción se da cuando esta diferencia de potencial eléctrico varía, volviéndose menos negativa que un valor específico llamado umbral de disparo. Una vez que se dispara un potencial de acción en una neurona, una carga eléctrica viaja a través del axón, hacia las dendritas de otras neuronas, las cuales pueden o no 8 disparar sus propios potenciales de acción dependiendo de si se logra o no alcanzar su umbral de disparo. La unión entre una terminal del axón de una neurona y la membrana somática o la dendrita de otra es llamada sinapsis. En el caso de las neuronas en el cerebro, las sinapsis son mayoritariamente del tipo químico. En una sinapsis química no existe una conducción eléctrica directa entre ambas células, sino que existe un espacio muy pequeño (de entre 20 y 30 nanómetros), llamado hendidura sináptica, a través del cuál viajan agentes químicos, llamados neurotransmisores, que son los encargados de transportar la señal de una neurona a otra. Cabe destacar que el efecto de los neurotransmisores puede ser inhibitorio o excitatorio, dependiendo de si causan que la diferencia de potencial eléctrico entre la neurona receptora y su entorno se vuelva más o menos negativa, respectivamente. Ahora bien, en el cerebro humano, cada una de las neuronas presentes se encuentra conectada con aproximadamente 10,000 otras neuronas a través de sus dendritas. La sumatoria de los potenciales de acción (tanto excitatorios como inhibitorios) de todas estas conexiones entrantes determina si la propia célula presentará un acción de potencial de acción o no. En conjunto, estos procesos de excitación sináptica en las dendritas de las neuronas presentes en la corteza cerebral generan corrientes cuyo campo eléctrico puede registrarse a través de electrodos colocados sobre el cuero cabelludo. Esta medición es precisamente la función que desempeña un sistema de electroencefalografía (Buzsaki, 2006). 9 2.2 Sistemas de electroencefalografía Como se mencionó anteriormente, un electroencefalograma es una medición de los campos eléctricos producidos por la suma de las corrientes que viajan a través de las neuronas en el cerebro. Esta medición se lleva a cabo directamente sobre el cuero cabelludo utilizando para ello electrodos. Los mayores inconvenientes que estas mediciones presentan son la atenuación debido a las varias capas existentes entre el sensor y lo que se desea medir y las señales presentes que no son de interés (también llamadas, ruido). La figura 2.3 ilustra las estructuras involucradas presentes entre el cerebro y los electrodos de registro, así como sus respectivos valores de resistencia eléctrica y de radio. Figura 2.3: Radios y resistividad de las distintas capas de la cabeza [Hurtado. 2010] 10 En la misma figura se puede apreciar que el cráneo tiene un efecto de atenuación 100 veces superior al de los tejidos blandos. En contraste, se debe acotar que la mayoría del ruido proviene directamente del cerebro (ruido interno) o del cuero cabelludo (ruido externo o del sistema). Otra característica limitante de la técnica de electroencefalografía es que solo es posible hacer mediciones del campo eléctrico producido por grupos de muchas neuronas activas y no del producido por una sola neurona, o el de un grupo pequeño de ellas (Nunez & Srinivasan, 1981). Es más, como se puede observar en la ecuación 2.2-1 (donde q representa la carga, r la distancia, r es la dirección del vector distancia y lo demás es un valor constante), el campo eléctrico decae proporcionalmente al cuadrado de la distancia, por lo que es más difícil medir la actividad de las neuronas localizadas en partes más profundas del cerebro que medir la actividad de las neuronas más cercanas al cráneo (Klein & Thorne, 2007).  E= 1 q r 4  0 r 2 (2.2-1) Para mitigar los efectos negativos mencionados en el párrafo anterior, los sistemas de electroencefalografía deben utilizar técnicas de amplificación y filtrado de señales con el objetivo de lograr obtener información útil a partir de las mediciones que se realizan. 2.2.1 Ondas o ritmos cerebrales y su clasificación Según Niedermeyer & da Silva (2005), los ritmos cerebrales se definen como formas de onda de similar duración y apariencia que ocurren de manera regular en un electroencefalograma. Estas ondas se reconocieron desde el inicio de la 11 electroencefalografía, tanto en humanos como en animales, y muchas fueron caracterizadas durante las décadas de 1930 y 1940. En adultos saludables las amplitudes y frecuencias de estas formas de onda varían según el estado cognitivo de cansancio o de vigilia, entre otros, de la persona. Así las características de estas formas de onda también cambian con la edad. Existen cinco ondas cerebrales principales que se distinguen por su rango de frecuencia y se les llama (ordenadas de menor a mayor rango frecuencia): delta (δ), zeta (θ), alfa (α), beta (β), y gama (γ ) (Sanei & Chambers, 2007). En la figura 2.4 se pueden observar los distintos tipos de ondas. Figura 2.4: Las cinco ondas cerebrales típicas [Wikimedia Commons. n.d.] 12 Las ondas delta se encuentran entre los 0.5 y los 4 Hz y están asociadas principalmente con el estado de sueño profundo, aunque también se pueden encontrar en el estado despierto (Sanei & Chambers, 2007). Las ondas zeta se encuentran en el rango de los 4–7.5 Hz y aparecen conforme el estado de alerta se va desvaneciendo hacia un estado de somnolencia. Estas ondas han sido asociadas con la inspiración creativa y los estados de meditación profunda (Sanei & Chambers, 2007). Las ondas alfa aparecen en la mitad posterior de la cabeza, usualmente sobre la región occipital del cerebro. Su frecuencia se encuentra entre los 8 y los 13 Hz, con una amplitud usual de menos de 50 μV y usualmente su apariencia es sinusoidal. Se cree que las ondas alfa indican un estado relajado de alerta pero sin atención o concentración, sin embargo, el origen y el significado fisiológico de estas es todavía desconocido (Sanei & Chambers, 2007). Una onda beta se encuentra en el rango de 14-26 Hz (aunque alguna literatura no le define límite superior). Este tipo de onda es el normal cuando se está despierto y se ha relacionado con los procesos de razonamiento activo, prestar atención, enfocarse en el mundo exterior o resolver problemas concretos. Usualmente estas ondas se encuentran principalmente sobre las regiones frontal y central y su amplitud, normalmente, es menor a 30 μV (Sanei & Chambers, 2007). Las frecuencias superiores a los 30 Hz (principalmente hasta los 45 Hz) corresponden al rango de las ondas gama (también llamado estado beta rápido) y aún 13 cuando su ocurrencia es inusual, la detección de estos ritmos permite confirmar ciertas enfermedades del cerebro (Sanei & Chambers, 2007). 2.3 Plataformas de procesamiento e interpretación de señales La siguiente etapa en un BCI, luego de la adquisición de las señales bioeléctricas del cerebro, es la del procesamiento e interpretación de dichas señales. En general, es posible dividir las herramientas disponibles para esta etapa en dos grandes categorías: las que se basan en el ambiente computacional MATLAB y las aplicaciones que funcionan de manera independiente, ejecutándose directamente sobre el sistema operativo (Delorme et al, en prensa). Las distintas herramientas varían en su funcionalidad, rendimiento, tipo de licencia, características y, por supuesto, costo económico. En muchos casos, se utilizan varias herramientas trabajando en conjunto para lograr un objetivo específico de un BCI. En el capítulo 3 se hará mayor hincapié en este tema. 2.4 BCIs y sus aplicaciones Los BCIs son dispositivos que procesan las señales cerebrales para permitir la comunicación e interacción directa con el ambiente (Rao & Scherer, 2010). La investigación en BCIs inició en los años 70 en la Universidad de California en Los Ángeles (UCLA) bajo el financiamiento de la Fundación Nacional de Ciencias (NSF) de los Estados Unidos, y luego de un contrato de la Agencia de Investigación en Proyectos Avanzados de Defensa (DARPA) de ese mismo país (Vidal, 1977). 14 Una tecnología de este tipo tiene muchas y muy variadas áreas de aplicación. Por ejemplo, en el área de la medicina se utilizan BCIs para permitirle a pacientes que hayan perdido la comunicación entre su cerebro y su sistema motriz (a causa de enfermedades como la esclerosis lateral amiotrófica o de accidentes como un daño agudo a la espina dorsal, por ejemplo) el poder interactuar de nuevo con su ambiente sin necesidad de depender de otro ser humano para muchos aspectos (Hinterberger, 2007). Otros ejemplos de áreas de aplicación fuera del ámbito médico son el uso como Dispositivo de Interfaz Humana (HID) en personas saludables y con aplicaciones en la industria de los videojuegos o el monitoreo de la atención de un usuario que está llevando a cabo una tarea crítica. Los BCI son de gran interés en el estudio del funcionamiento del cerebro, pues permiten obtener información directa de la forma en que el cerebro procesa eventos en su entorno. Podemos esperar que conforme avance nuestro entendimiento del cerebro y su funcionamiento, se desarrollen nuevas aplicaciones y áreas de acción para estas tecnologías que en la actualidad todavía no son fácilmente imaginables. 2.5 Otros conceptos importantes 2.5.1 Software Libre El SL es aquél que le garantiza a sus usuarios las siguientes cuatro libertades básicas: a) Libertad de uso del software para cualquier propósito (Libertad 0) 15 b) Libertad de estudiar cómo funciona el software y modificarlo para cualquier propósito (Libertad 1) c) Libertad para distribuir copias del software a terceros (Libertad 2) d) Libertad para distribuir copias de las modificaciones que uno haga al software (Libertad 3) Las libertades 1 y 3 requieren que el código fuente del programa esté disponible al usuario, por lo que parte de las condiciones necesarias para que una aplicación sea SL es la disponibilidad de su código fuente (Free Software Foundation, n.d.). 2.5.2 Blender y su motor de juegos (BGE) Blender es una aplicación de SL que permite la creación de una gran variedad de contenidos en 2D y 3D. Inició como un proyecto privado de la empresa Not a Number Technologies (NaN), la que se encargó de su desarrollo hasta el 2002, año en que se declaró en bancarrota. Actualmente Blender es Software Libre y su desarrollo es supervisado a través de la organización The Blender Foundation (The Blender Foundation, n.d.). “Actualmente los usuarios de Blender han dirigido sus aplicaciones hacia una amplia variedad de actividades, por ejemplo: cortometrajes, ilustraciones, juegos interactivos y aplicaciones educativas […]. Otra característica relevante es que Blender permite trabajar con una amplia variedad de sistemas operativos, como Windows, Macintosh, Linux, Solaris, ente otros. Asimismo, tolera una amplia variedad de formatos gráficos y de audio.” (Esquivel & Paniagua, en prensa) 16 Dos de las características más importantes de esta aplicación, en el marco de este trabajo, son: su integración con el lenguaje de scripting Python y su facilidad para la creación de juegos utilizando el BGE. El BGE es el componente de Blender que permite la creación de contenidos que interactúan con el usuario en tiempo real. El BGE utiliza un sistema de “bloques lógicos” (constituidos por sensores, controladores y actuadores) para controlar los objetos presentes en el juego y entre sus muchas características presenta la integración con una biblioteca de física de los cuerpos blandos que le permite representar movimientos como sucederían en el mundo real. 2.5.3 Red Periférica de Realidad Virtual (VRPN) VRPN es un software compuesto por varias clases en una biblioteca de programación y por varios programas que implementan una interfaz entre aplicaciones y dispositivos físicos en un sistema de Realidad Virtual (VR). Esta interfaz fue diseñada para funcionar de manera independiente de los dispositivos y es transparente desde el punto de vista de la red (Taylor, 2001). VRPN permite la comunicación efectiva entre dispositivos de entrada, aplicaciones y ambientes de simulación de VR. Esta biblioteca fue puesta en el dominio público por su autor y la parte de cliente de la biblioteca ha sido probada en distintos sistemas operativos, tales como SGI/Irix, PC/Win32, HP700/Hpux, Sparc/Solaris, PC/Linux, Mac/OSX, Ipaq/Linux, and Zaurus/Linux (Taylor, 1998). CAPÍTULO 3: Elección de la plataforma “Too much knowledge never makes for simple decisions.” – From Discourses on Leadership by Crown Prince Raphael Corrino El incremento a nivel mundial en el interés por la investigación en el área de las BCIs se ha visto acompañado por un desarrollo en la cantidad de herramientas especializadas de software disponibles. Las necesidades específicas del campo de la investigación en BCIs han generado varios requerimientos que debe cumplir una plataforma de software especializada en este tipo de aplicaciones, a saber: flexibilidad, facilidad de uso, eficiencia, rendimiento y robustez (Delorme et al, en prensa). Aunado a ello, el proyecto de AVCs dentro del cual se enmarca este trabajo impone un requerimiento adicional con respecto a la plataforma: debe estar basada en SL. Este requerimiento, más allá de las razones filosóficas, proviene de aspectos completamente técnicos, por ejemplo: • Dado que el diseño específico del BCI no está definido en su totalidad, la plataforma elegida debe permitir su modificación a cualquier nivel para poder ajustarla a los requerimientos futuros que pudieran identificarse conforme el proyecto avanza. 17 18 • Como el proyecto se enmarca en un ámbito académico, la plataforma debe permitir su estudio a profundidad, no solo para permitir que otros estudiantes aprendan del desarrollo creado, sino también para que sea posible su revisión por parte de los pares académicos nacionales e internacionales. • Finalmente, uno de los posibles resultados del proyecto de AVCs es la implementación de varios BCIs en distintos centros preescolares del sistema de educación pública. La dependencia de software propietario (por ejemplo, MATLAB) implicaría un costo prohibitivo en licencias, por lo que la plataforma escogida debe permitir su redistribución con un costo económico mínimo o nulo. 3.1 Sistemas basados en MATLAB Los requerimientos de modificación y estudio a profundidad podrían ser cumplidos utilizando plataformas de SL que se ejecutan sobre una aplicación genérica de procesamiento (p.e. MATLAB), sin embargo, el tercer requerimiento implica que la plataforma entera debe poder ser redistribuida a un bajo costo, lo cual no es posible hacer con MATLAB, pues el sistema como un todo seguiría siendo propietario. Por otro lado, las aplicaciones como MATLAB son una herramienta muy útil para desarrollar y probar prototipos de algoritmos muy fácilmente, sin embargo su uso fuera del campo de la investigación es muy poco, pues posee ciertas limitaciones técnicas. Un ejemplo de esto es el hecho de que es una aplicación de un solo hilo por lo que no es capaz de adquirir datos y procesarlos al mismo tiempo (Delorme et al, en prensa). 3.2 Sistemas independientes 19 A partir de la investigación bibliográfica fue posible identificar tres plataformas independientes disponibles al público: BioSig, OpenVIBE y BCI2000. 3.1.1 BioSig BioSig emergió del BCI original de la Universidad Tecnológica de Graz (UT Graz) y originalmente fue diseñado como un toolbox para MATLAB u Octave. Actualmente también contiene una biblioteca escrita en C/C++ que permite su utilización de manera independiente, provee un gran rango de funcionalidades, y su desarrollo sigue estando ligado a la UT Graz. El uso de esta plataforma usualmente requiere habilidades avanzadas de programación y conocimientos profundos del código propio de la plataforma (Delorme et al, en prensa). 3.1.2 OpenViBE Este es un proyecto desarrollado desde cero en C++ por el Instituto Nacional de Investigación en Ciencias de la Computación y Control de Francia (INRIA). Su enfoque se basa en la programación visual, utilizando para ello bloques que se interconectan gráficamente entre sí para crear la cadena de procesamiento de las señales, lo que lo convierte en una de las plataformas con mayor facilidad de uso para usuarios cuya principal formación no es en las ciencias de la computación o programación. La figura 3.1 muestra la interfaz gráfica de usuario de OpenViBE e ilustra el principio de programación visual a través de bloques funcionales. 20 Figura 3.1: Interface Gráfica de Usuario del diseñador de OpenViBE con dos bloques interconectados y desplegando el menú contextual [Renard et al. n.d.] 3.1.3 BCI2000 Esta también es una plataforma escrita en C++, cuyo desarrollo es liderado por Gerwin Schalk en el Centro Wadsworth (Albany NY) y su enfoque principal es la recolección y procesamiento de datos en línea. Esta es una de las plataformas más completas en cuando a funcionalidad y tiene una gran base de usuarios a nivel mundial gracias al tiempo que lleva de existir. Su uso requiere conocimientos de programación, y aún cuando su código fuente está disponible para propósitos de investigación, el proyecto no se considera SL porque el uso de manera comercial implica la obtención de una licencia propietaria. 21 Para la decisión final de la plataforma, además de la información descrita anteriormente, también se tomó en cuenta la cantidad y calidad de la documentación disponible en cada caso, así como la accesibilidad de sus desarrolladores y su comunidad. Al final, considerando todos los factores mencionados, se eligió la plataforma OpenViBE. Esta selección obedeció a su facilidad de uso (aspecto importante para facilitar el trabajo multidisciplinario donde no todos tienen un entrenamiento formal en programación), su documentación clara y completa, por la gran disposición de su comunidad para prestar ayuda. Además cuenta con todas las características necesarias para construir BCIs que puedan ser usadas con usuarios finales y no solo en un ambiente de investigación controlado, como lo son: • Capacidad de ser controlado desde la línea de comandos: es posible controlar OpenViBE de manera tal que se pueda usar sin intervención de un operador (más allá de dar “doble click” a un ícono) aunque no es posible ejecutarlo sin interfaz gráfica. • Capacidad de correr en arquitecturas empotradas: es posible correr el componente de análisis e interpretación (Designer) sobre un procesador tipo Atom pero sin el proceso de adquisición de datos (Acquisition Server). • Controladores para OpenEEG/ModularEEG: la plataforma se distribuye con controladores que le permiten funcionar con estos equipos de adquisición que son de fácil construcción y bajo costo. CAPÍTULO 4: Interfaz de la plataforma con el sistema de electroencefalografía “May be ugly, but such is life.” – hggdh en el canal #ubuntu-server de IRC Para el momento de finalización de este trabajo, todavía no había sido posible la adquisición del equipo de electroencefalografía que se pretende utilizar como parte del proyecto de AVCs. Tampoco fue posible obtener información técnica detallada por parte del fabricante, tal que se pudiera utilizar en el diseño de una interfaz que garantizara su funcionamiento con el equipo elegido. Tomando esto en cuenta, se decidió hacer el estudio de cómo funciona una interfaz genérica dentro de la plataforma escogida, OpenViBE, con el fin de utilizar este análisis como base para la implementación de la interfaz real una vez que se tenga el hardware real y se le pueda hacer ingeniería inversa. 4.1 Diseño de la interfaz OpenViBE - EEG OpenViBE como sistema se divide en dos procesos distintos: uno encargado de la adquisición de datos (OpenViBE acquisition server) y el componente principal encargado del procesamiento de los datos (OpenViBE designer). Estos procesos se comunican a través de un protocolo cliente/servidor, de manera tal que es teóricamente posible tener varias aplicaciones de procesamiento utilizando los mismos datos provenientes del servidor. 22 23 Dada esta división de procesos, el componente encargado de interactuar directamente con los equipos de adquisición de señal es, como su nombre lo indica, el servidor de adquisición. Por lo tanto, para conectarse con la plataforma, es necesario escribir un controlador para el servidor de adquisición. OpenViBE incluye un repertorio de controladores ya listos para conectar una gran variedad de equipos de adquisición. En su gran mayoría, estos controladores han sido desarrollados utilizando las herramientas que facilita el fabricante de cada equipo. Un controlador debe ser capaz de proveer dos tipos de datos al servidor de adquisición: datos de encabezado y datos de buffer. Los datos en el encabezado se encargan de proveer información que no varía durante todo el experimento (como el sexo y edad del sujeto, información sobre los canales y el muestreo, etc.); mientras que los datos en el buffer representan la información adquirida propiamente por el equipo de electroencefalografía. El flujo de trabajo de un controlador se puede observar en la figura 4.1. Básicamente, este flujo de trabajo consta de 5 etapas: a) Etapa inicial de espera b) Etapa de configuración c) Etapa inicialización d) Etapa de adquisición iniciada e) Etapa de ciclo de adquisición 24 Figura 4.1: Flujo de trabajo de un controlador del servidor de adquisición de OpenViBE [Renard et al. 2010] Durante la etapa inicial de espera, el controlador simplemente se encuentra en espera de que se inicie la configuración del dispositivo. En la etapa de configuración, el controlador debe adquirir toda la información del encabezado que no pueda conseguir directamente del hardware (por ejemplo, la edad o el sexo del sujeto del experimento). Para esto se puede utilizar cualquier método que el programador crea conveniente, sin embargo, se recomienda utilizar un cuadro de diálogo que se le presentará al usuario para que provea dicha información. En la etapa de inicialización, el controlador verifica que el hardware está listo para empezar la adquisición de las señales. También en esta etapa debería estar toda la información del encabezado lista para ser enviada al servidor de adquisición. 25 Finalmente, la etapa de adquisición iniciada indica que OpenViBE está listo para recibir datos del equipo de adquisición, y durante esta etapa se estará llamando regularmente a la etapa de ciclo de adquisición para obtener nuevos datos. 4.2 Análisis de un controlador existente: el Oscilador Genérico Como parte del paquete completo que se distribuye con OpenViBE, se encuentra el controlador “Generic Oscillator” del servidor de adquisición, que se utiliza para realizar pruebas cuando no se tiene un equipo de adquisición disponible. A nivel de código fuente, el controlador se divide en dos archivos (como es la costumbre cuando se programa en C y C++), el y ovasCDriverGenericOscilator.h ovasCDriverGenericOscilator.cpp. el archivo archivo de encabezado: de implementación: Ambos se encuentran listados completos en los Anexos 1 y 2, respectivamente. El archivo de encabezado muestra que la clase CDriverGenericOscillator, que define a este controlador, OpenViBEAcquisitionServer::IDriver. es una clase derivada de Esto es importante pues la clase principal de cualquier controlador que se desee programar debe derivar de esta clase. Luego, también se observa que la clase CDriverGenericOscillator define 6 miembros protegidos, éstos se encuentran listados en la Tabla 4.1, junto con el tipo de dato que contiene cada miembro (en sintaxis de C++). Tabla 4.1: Miembros de la clase CDriverGenericOscillator y su tipo Miembro m_pCallback Tipo de dato OpenViBEAcquisitionServer::IDriverCallback* 26 m_oHeader OpenViBEAcquisitionServer::CHeader m_ui32SampleCountPerSentBlock OpenViBE::uint32 m_pSample OpenViBE::float32* m_ui32TotalSampleCount OpenViBE::uint32 m_ui32StartTime OpenViBE::uint32 Esta clase también define 10 métodos públicos que se explicarán en las siguientes subsecciones. Nótese que por claridad se omitieron los detalles relacionados con la tarea de registrar eventos en la bitácora interna del programa, pues esto se utiliza exclusivamente para labores de corrección de errores de programación (debugging). 4.1.1 Constructor CDriverGenericOscillator() Este es el método constructor que se utiliza cuando se desea instanciar un objeto del tipo CDriverGenericOscillator. Su función es inicializar todos los miembros del objeto a valores conocidos, también se encarga de definir valores por defecto para la frecuencia de muestro y para la cantidad de canales que se van a crear. 4.1.2 Método getName(), método getHeader() y método isConfigurable() Estos métodos, como sus nombres lo indican, se utilizan para obtener información sobre este controlador. En este caso específico, getName() siempre devolverá la cadena de caracteres “Generic Oscillator”, isConfigurable() siempre devolverá el valor booleano “verdadero” y getHeader() devolverá un puntero con la dirección del miembro m_oHeader 4.1.3 del objeto. Método initialize() El método initialize() toma dos argumentos: un entero constante sin signo de 32 bits, llamado ui32SampleCountPerSentBlock y la dirección de un objeto de tipo IdriverCallback, llamado rCallback y devuelve un valor booleano. 27 Lo primero que hace este método es probar si el controlador ya se encuentra conectado, en cuyo caso termina ahí su ejecución y devuelve un valor de “falso” (pues el que ya esté conectado implicaría que el controlador ya fue inicializado). Luego determina si ya fueron establecidos los valores para la cantidad de canales y la frecuencia de muestreo, de no ser así, termina su ejecución y devuelve un valor de “falso” (pues se supone que el controlador fue configurado antes de ser inicializado). Luego reserva memoria para un vector de números de punto flotante de 32 bits del tamaño ui32SampleCountPerSentBlock por la cantidad de canales; si esta operación falla (no fue posible reservar el espacio en memoria), se hace un poco de limpieza y devuelve un valor de “falso”. Si la operación es exitosa, se asigna la direccion del espacio reservado en memoria al miembro m_pSample, se asigna el valor de ui32SampleCountPerSentBlock al miembro m_ui32SampleCountPerSentBlock y finalmente, se le asigna al puntero m_pCallback, la dirección de rCallback. Finalmente, se devuelve un valor de verdad de “verdadero”. 4.1.4 Método uninitialize() Este método no recibe ningún parámetro y devuelve un valor booleano. El método inicia revisando si el controlador no está conectado o si en este momento está en la etapa de adquisición iniciada, en cuyo caso regresa el valor “falso” (pues si el controlador no está conectado no fue inicializado correctamente y si está en la etapa de adquisición iniciada tampoco puede ser terminado sin antes parar la adquisición). 28 Luego se marca para borrado el espacio de memoria reservado por el puntero m_pSample y a este y a m_pCallback se les asigna el valor NULL. Finalmente se regresa el valor “verdadero”. 4.1.5 Método start() Este método no recibe ningún parámetro y devuelve un valor booleano. El método inicia revisando si el controlador no está conectado o si en este momento está en la etapa de adquisición iniciada, en cuyo caso regresa el valor “falso” (pues si el controlador no está conectado no fue inicializado correctamente y si ya está en la etapa de adquisición iniciada no tiene sentido iniciarlo de nuevo). Luego, inicializa la variable miembro m_ui32TotalSampleCount a cero y la variable m_ui32StartTime al tiempo del sistema operativo en ese momento. Finalmente regresa el valor “verdadero”. 4.1.6 Método stop() Este método no recibe ningún parámetro y devuelve un valor booleano. El método revisa si el controlador no está conectado o si no está en etapa de adquisición iniciada, en cuyo caso devuelve un valor de “falso”, en caso contrario, devuelve un valor de “verdadero”. 4.1.7 Método loop() Este es el método principal del controlador, en un controlador real de un equipo de adquisición sería el encargado de obtener los datos y ponerlos en el miembro m_pSample según la posición que le toca en el vector. 29 En el caso de este controlador específico, lo que se hace es generar tres valores distintos de la función seno (utilizando como parámetro el índice del vector) para sumarlos y colocarlos en el miembro m_pSample, en la posición correspondiente al índice y enviar de vuelta este valor al servidor de adquisición. 4.1.8 Método configure() Este método no recibe ningún parámetro y devuelve un valor booleano. Este método lleva a cabo la función de crear y desplegar un cuadro de diálogo (creando para esto un objeto del tipo CConfigurationGlade con el parámetro del archivo .glade que define el cuadro de diálogo) CConfigurationGlade, y luego llama al método configure() del objeto pasándole como argumento el miembro m_oHeader donde el método debe almacenar la información recolectada. Finalmente devuelve el valor de verdad que devuelva el método configure(). CAPÍTULO 5: Interfaz de la plataforma con la aplicación final “Cyberspace was a consensual hallucination that felt and looked like a physical space but actually was a computer-generated construct representing abstract data.” – William Gibson Para poder diseñar la interfaz entre la aplicación final y la plataforma escogida para el procesamiento e interpretación de las mismas, fue necesario estudiar como se comunican éstas con “el mundo exterior” para así poder trazar una ruta de comunicación entre ambas. Figura 5.1: A la izquierda, niños utilizando el AVC. A la derecha, una toma de pantalla del AVC [Padilla. 2010] Como se mencionó anteriormente, la aplicación final para el BCI al que se refiere este trabajo es un juego de tipo AVC hecho con el BGE (ver Figura 5.1). El BGE es un componente más de la suite de producción 3D, Blender, lo cual implica que integra mucha de su funcionalidad. De especial interés es la funcionalidad de la Interfaz de Programación de Aplicaciones (API) basada en el lenguaje de scripting Python, que provee la capacidad 30 31 para accesar y modificar elementos de una aplicación interactiva en tiempo de ejecución. A través de esta API es que se hace posible crear un módulo de este lenguaje capaz de establecer la conexión con “el mundo exterior” y de modificar elementos dentro del juego en respuesta a los estímulos externos recibidos. Asimismo, gracias a que OpenViBE (la plataforma seleccionada) fue diseñada para comunicarse con simulaciones en ambientes de VR, fue posible utilizar su servidor del protocolo Red Periférica de Realidad Virtual (VRPN) con el fin de enviar los resultados de su procesamiento a aplicaciones externas que sean clientes de este protocolo. Específicamente, OpenViBE soporta la comunicación a través de dos de los muchos módulos que soporta el protocolo VRPN: módulo de botones y módulo de valores analógicos. Finalmente, está disponible una biblioteca de VRPN que provee un API, programada en C++, que permite incorporar, de manera sencilla, la funcionalidad de servidor o cliente VRPN a una aplicación. Asimismo, esta biblioteca incluye una versión de un wrapper para Python, lo que permite utilizar las funciones de la biblioteca desde un módulo o script programado en este lenguaje. 32 5.1 Diseño de la Interfaz OpenVIBE – BGE Figura 5.2: Diagrama de los componentes de la comunicación entre OpenViBE y BGE [Arias. 2010] La figura 5.1 muestra el diseño implementado para la interfaz comunicación entre el juego ejecutándose a través del BGE y los resultados procesados a través de OpenViBE. Como se observa, la interfaz diseñada consta de las siguientes cuatro partes: A) El servidor de VRPN: este servidor se ejecuta como parte de la plataforma de OpenViBE; es el encargado de obtener los datos ya procesados y listos para ser utilizados desde la etapa de salida para transmitirlos por red hacia la aplicación cliente. B) Biblioteca de VRPN en Python: esta biblioteca funciona como wrapper permitiendo a módulos y scripts de Python el acceso a las funciones disponibles a través de la biblioteca en C++. 33 C) Biblioteca de VRPN en C++: esta biblioteca provee una serie de clases y métodos que permiten a una aplicación funcionar como cliente de VRPN, creando conexiones con servidores de este protocolo y pudiendo reaccionar ante eventos enviados por uno de estos servidores. D) Módulo de Python: este módulo se ejecuta como parte del BGE y utiliza las funciones de la biblioteca para actuar como cliente de VRPN y poder así escuchar eventos enviados desde el servidor de VRPN y reaccionar ante ellos modificando el juego en ejecución. 5.2 Implementación de la Interfaz OpenVIBE - BGE Como se mencionó anteriormente, la biblioteca de VRPN disponible del sitio oficial de dicho protocolo (http://www.cs.unc.edu/Research/vrpn/), provee un wrapper para Python, éste último fue creado utilizando la herramienta SWIG cuyo propósito es precisamente facilitar la creación de módulos que permitan el acceso desde un lenguaje de scripting hacia una biblioteca definida en C/C++. Sin embargo, se encontró que dicho wrapper estaba bastante desactualizado y no funcionaba bien luego de compilar, por lo que se procedió a consultar en las listas de correo del proyecto y de allí se obtuvo la idea de utilizar el repositorio git creado por Ryan Pavlik, que se encuentra más actualizado. Ahora bien, el código de este repositorio también contenía dos errores que debieron ser investigados y corregidos para lograr la compilación y el correcto funcionamiento de la biblioteca en Python. Estos errores se encontraron en los archivos de definición de 34 compilación para CMake: python_vrpn/CMakeLists.txt y en el archivo de definición de interfaz para SWIG del módulo vrpn_Analog: python_vrpn/vrpn_Analog.i. En el Anexo 3 python_vrpn/CMakeLists.txt se encuentra el código completo del archivo en su versión final corregida. Asimismo, el Anexo 4 contiene el código completo y corregido del archivo python_vrpn/vrpn_Analog.i. Luego de la corrección de los archivos, se procedió a compilar con CMake y a probar el wrapper de manera exitosa a nivel local en la distribución Ubuntu 10.04 de 32bits, utilizando Python en su versión 2.6. El procedimiento de esta compilación se puede encontrar en el Anexo 5. A continuación, se probaron los módulos del wrapper en un script que se conectaba a una Máquina Virtual (VM) ejecutando OpenViBE sobre Windows XP. Finalmente, se programó un módulo de Python que se utilizó dentro de un juego muy simple de Blender para poder comunicarse con OpenViBE ejecutándose en la VM con Windows XP. El código fuente de este módulo se muestra en el Anexo 6. A través de este módulo fue posible modificar elementos del juego en respuesta a señales provenientes de OpenViBE, demostrando así la comunicación entre ambos sistemas y probando así la interfaz implementada. CAPÍTULO 6: Conclusiones y recomendaciones “El final: todo comienza por ahí.” – Balerom 6.1 • Conclusiones Luego de una investigación bibliográfica de las plataformas de SL disponibles para la construcción del BCI, se identificó OpenViBE como la mejor herramienta disponible. • Es posible realizar la conexión entre la plataforma OpenViBE y un juego desarrollado con el BGE a través de un wrapper en Python de libvrpn. • La arquitectura de OpenViBE permite el desarrollar fácilmente un controlador para comunicarse con cualquier dispositivo de adquisición de datos; sin embargo, se necesita información específica del equipo para poder llevar a cabo esta labor. • La comunidad y documentación de OpenViBE fueron un producto adicional e importante para el desarrollo de este trabajo. 6.2 • Recomendaciones Se debe tener el equipo de adquisición de datos, y preferiblemente, la información técnica del mismo para poder desarrollar un controlador de OpenViBE. 35 36 • De ser posible, sería recomendable tener uno de los equipos oficialmente soportados por OpenViBE, tanto para propósitos de comparación con el controlador desarrollado como para tener un equipo adicional con el cual experimentar. • Sería recomendable tener una versión binaria estable y de fácil distribución de todos los componentes contemplados en este trabajo, tanto para plataforma Linux como para plataforma Windows. • Para facilitar el trabajo multi-disciplinario, es deseable contar con documentación ordenada y estructurada que permita adquirir los conocimientos básicos necesarios para poder trabajar en el proyecto. • Es importante tomar en cuenta el uso y el usuario final que va a tener esta plataforma de BCI, para poder adaptarla lo máximo posible a dicho escenario. Esto incluye el tomar en cuenta las limitaciones en cuanto a presupuesto de mantenimiento de los centros educativos y en cuanto al nivel de capacitación de sus profesores en el área de las Tecnologías de la Información y Comunicaciones. • La flexibilidad de la plataforma desarrollada permite tener escenarios donde distintos equipos pueden ejecutar distintas partes del proceso del BCI. Se deben analizar varias combinaciones de casos y equipos, tanto para escoger el escenario óptimo para este proyecto como para tener flexibilidad en proyectos futuros. BIBLIOGRAFÍA 1. Berger, T.W., Chapin, J.K., Gerhardt, G.A., McFarland, D.J., Principe, J.C., Soussou, W.V., Taylor, D.M., Tresco, P.A. “Brain-Computer Interfaces: An International Assessment of Research and Development Trends”, 1ra edición, Springer Science + Business Media B.V., Estados Unidos, 2008. 2. Chambers, J.A., & Sanei S.. “Eeg Signal Proccesing”, 1ra edición, John Wiley & Sons Ltd., Inglaterra, 2007. 3. Ferdig, R. “Assessing technologies for teaching and learning: understanding the importance of technological pedagogical content knowledge”, British Journal of Educational Technology 37 (5), 2006. 4. Nunez, P.L., & Srinivasan R. “Electric fields of the brain: The neurophysics of EEG”, Oxford University Press, Inglaterra, 1981. 5. Klein, S. & Thorne, B. M. “Biological psychology”, Worth Publishers, Estados Unidos, 2007. 6. Free Software Foundation. “The Free Software Definition”, Tomado de http://www.gnu.org/philosophy/free-sw.html el 2010-06-24. 7. The Blender Foundation. “Blender.org history”, Tomado de http://www.blender.org/blenderorg/blender-foundation/history/ en 2010-06-24. 8. Taylor, R.T., Hudson, T.C., Seeger, A., Weber, H., Juliano, J. & Helser, A.T., “VRPN: A Device-Independent, 37 Network-Transparent VR Peripheral 38 System”, Proceedings of the ACM Symposium on Virtual Reality Software & Technology 2001, VRST 2001. Banff Centre, Canada, November 15-17, 2001. 9. Taylor II, R.M., “The Virtual Reality Peripheral Network (VRPN)”, Tomado de http://www.cs.unc.edu/Research/vrpn en 2010-06-24. 10. Hinterberger, T., Nijboer, F., Kübler, A., Matuz, T., Furdea, A., Mochty, U., Jordan, M., Lal, T.N., Hill, J., Mellinger, J., Bensch, M., Tangermann, M., Widman, G., Elger, C.E., Rosenstiel, W., Schölkopf, B. & Birbaumer, N. “Brain-Computer Interfaces for Communication in Paralysis: A Clinical Experimental Approach. Toward Brain-Computer Interfacing”, 43-64. (Eds.) Dornhege, G., J. del R. Millán, T. Hinterberger, D. J. McFarland, K.-R. Müller, MIT Press, Cambridge, MA, USA (09 2007). 11. Renard, Y., Lotte, F., Gibert, G., Congedo, M., Maby, E., Delannoy, V., Bertrand, O., & Lécuyer, A. “OpenViBE: An Open-Source Software Platform to Design, Test and Use Brain-Computer Interfaces in Real and Virtual Environments”, Presence : teleoperators and virtual environments, vol. 19, no 1, 2010 en prensa 12. Delorme, A., Kothe, C., Vankov, A., Bigdely-Shamlo, N., Oostenveld, R., Zander, T. & Makeig, S . “MATLAB-Based Tools for BCI Research”, (B+H)CI: The Human in Brain-Computer Interfaces and the Brain in Human-Computer Interaction, en prensa. 13. Padilla, M. “Ambientes Virtuales Cooperativos: Herramientas innovadoras para la educación preescolar”, Costa Rica. Programa de Investigación en Neurociencias, Universidad de Costa Rica (inédito), 1984. 39 14. Esquivel, A. & Paniagua, C. “Software Libre para el diseño de herramientas virtuales: aplicaciones psicológicas y educativas”, Costa Rica, 2010, en prensa. 15. Niedermeyer E., Lopes da Silva F. “Electroencephalography: Basic Principles, Clinical Applications, and Related Fields”, 5ta edición, Estados Unidos, Lippincot Williams & Wilkins, 2004. 16. Buzsaki G. “Rhythms of the brain”, Estados Unidos, Oxford University Press, 2006. 17. Vidal J. “Real-Time Detection of Brain Events in EEG”, Estados Unidos, IEEE Proceedings 65: 633–641, 1977. 18. Carlson N. “Fisiología de la conducta” (M. J. Ramos, C. Muñoz & F. Rodríguez, Traducción), 8va edición, Madrid, Pearson Educación, 2006. ANEXOS Anexo 1: archivo ovasCDriverGenericOscilator.h completo #ifndef __OpenViBE_AcquisitionServer_CDriverGenericOscillator_H__ #define __OpenViBE_AcquisitionServer_CDriverGenericOscillator_H__ #include "../ovasIDriver.h" #include "../ovasCHeader.h" namespace OpenViBEAcquisitionServer { class CDriverGenericOscillator : public OpenViBEAcquisitionServer::IDriver { public: CDriverGenericOscillator(OpenViBEAcquisitionServer::IDriverContext& rDriverContext); virtual void release(void); virtual const char* getName(void); virtual OpenViBE::boolean initialize( const OpenViBE::uint32 ui32SampleCountPerSentBlock, OpenViBEAcquisitionServer::IDriverCallback& rCallback); virtual OpenViBE::boolean uninitialize(void); virtual OpenViBE::boolean start(void); virtual OpenViBE::boolean stop(void); virtual OpenViBE::boolean loop(void); virtual OpenViBE::boolean isConfigurable(void); virtual OpenViBE::boolean configure(void); virtual const OpenViBEAcquisitionServer::IHeader* getHeader(void) { return &m_oHeader; } protected: OpenViBEAcquisitionServer::IDriverCallback* m_pCallback; OpenViBEAcquisitionServer::CHeader m_oHeader; OpenViBE::uint32 m_ui32SampleCountPerSentBlock; OpenViBE::float32* m_pSample; OpenViBE::uint32 m_ui32TotalSampleCount; OpenViBE::uint32 m_ui32StartTime; }; }; #endif // __OpenViBE_AcquisitionServer_CDriverGenericOscillator_H__ 40 41 Anexo 2: archivo ovasCDriverGenericOscilator.cpp completo #include "ovasCDriverGenericOscilator.h" #include "../ovasCConfigurationGlade.h" #include #include #include using namespace OpenViBEAcquisitionServer; using namespace OpenViBE; using namespace OpenViBE::Kernel; //___________________________________________________________________// // // CDriverGenericOscillator::CDriverGenericOscillator(IDriverContext& rDriverContext) :IDriver(rDriverContext) ,m_pCallback(NULL) ,m_ui32SampleCountPerSentBlock(0) ,m_pSample(NULL) ,m_ui32TotalSampleCount(0) ,m_ui32StartTime(0) { m_rDriverContext.getLogManager() << LogLevel_Trace << "CDriverGenericOscillator::CDriverGenericOscillator\n"; m_oHeader.setSamplingFrequency(512); m_oHeader.setChannelCount(4); } void CDriverGenericOscillator::release(void) { m_rDriverContext.getLogManager() << LogLevel_Trace << "CDriverGenericOscillator::release\n"; delete this; } const char* CDriverGenericOscillator::getName(void) { m_rDriverContext.getLogManager() << LogLevel_Trace << "CDriverGenericOscillator::getName\n"; return "Generic Oscillator"; } //___________________________________________________________________// // // boolean CDriverGenericOscillator::initialize( const uint32 ui32SampleCountPerSentBlock, IDriverCallback& rCallback) { m_rDriverContext.getLogManager() << LogLevel_Trace << "CDriverGenericOscillator::initialize\n"; if(m_rDriverContext.isConnected()) { return false; } if(!m_oHeader.isChannelCountSet() ||!m_oHeader.isSamplingFrequencySet()) { return false; } 42 m_pSample=new float32[m_oHeader.getChannelCount()*ui32SampleCountPerSentBlock]; if(!m_pSample) { delete [] m_pSample; m_pSample=NULL; return false; } m_pCallback=&rCallback; m_ui32SampleCountPerSentBlock=ui32SampleCountPerSentBlock; return true; } boolean CDriverGenericOscillator::start(void) { m_rDriverContext.getLogManager() << LogLevel_Trace << "CDriverGenericOscillator::start\n"; if(!m_rDriverContext.isConnected()) { return false; } if(m_rDriverContext.isStarted()) { return false; } m_ui32TotalSampleCount=0; m_ui32StartTime=System::Time::getTime(); return true; } boolean CDriverGenericOscillator::loop(void) { m_rDriverContext.getLogManager() << LogLevel_Debug << "CDriverGenericOscillator::loop\n"; if(!m_rDriverContext.isConnected()) { return false; } if(!m_rDriverContext.isStarted()) { return true; } uint32 l_ui32CurrentTime=System::Time::getTime(); if(l_ui32CurrentTime-m_ui32StartTime > (1000*(m_ui32TotalSampleCount+m_ui32SampleCountPerSentBlock))/m_oHeader.getSamplingFrequency ()) { CStimulationSet l_oStimulationSet; l_oStimulationSet.setStimulationCount(1); l_oStimulationSet.setStimulationIdentifier(0, 0); l_oStimulationSet.setStimulationDate(0, 0); l_oStimulationSet.setStimulationDuration(0, 0); for(uint32 j=0; jsetSamples(m_pSample); m_pCallback->setStimulationSet(l_oStimulationSet); } return true; } boolean CDriverGenericOscillator::stop(void) { m_rDriverContext.getLogManager() << LogLevel_Trace << "CDriverGenericOscillator::stop\n"; if(!m_rDriverContext.isConnected()) { return false; } if(!m_rDriverContext.isStarted()) { return false; } return true; } boolean CDriverGenericOscillator::uninitialize(void) { m_rDriverContext.getLogManager() << LogLevel_Trace << "CDriverGenericOscillator::uninitialize\n"; if(!m_rDriverContext.isConnected()) { return false; } if(m_rDriverContext.isStarted()) { return false; } delete [] m_pSample; m_pSample=NULL; m_pCallback=NULL; return true; } //___________________________________________________________________// // // boolean CDriverGenericOscillator::isConfigurable(void) { m_rDriverContext.getLogManager() << LogLevel_Trace << "CDriverGenericOscillator::isConfigurable\n"; return true; } boolean CDriverGenericOscillator::configure(void) { m_rDriverContext.getLogManager() << LogLevel_Trace << "CDriverGenericOscillator::configure\n"; CConfigurationGlade m_oConfiguration("../share/openvibe-applications/acquisitionserver/interface-Generic-Oscillator.glade"); return m_oConfiguration.configure(m_oHeader); } 44 Anexo 3: archivo python_vrpn/CMakeLists.txt corregido # # # # Changes made by: 2009-2010 Ryan Pavlik http://academic.cleardefinition.com Iowa State University HCI Graduate Program/VRAC # XXX TODO Install these bindings, don't just build them! if(SWIG_FOUND AND PYTHONLIBS_FOUND AND VRPN_BUILD_PYTHON) include(${SWIG_USE_FILE}) include_directories(${PYTHON_INCLUDE_PATH}) if(VRPN_BUILD_CLIENT_LIBRARY) set(VRPN_CLIENT_LIBRARY vrpn) elseif(VRPN_BUILD_SERVER_LIBRARY) set(VRPN_CLIENT_LIBRARY vrpnserver) else() message(FATAL_ERROR "Cannot compile Python wrapper without either the client or full library. Enable one and try again.") endif() # # # # # # XXX TODO: add dependency on these files - perhaps change extension to .h? set(COMMON client-only.i python-callback-wrapper.i) set_source_files_properties(${COMMON} PROPERTIES CPLUSPLUS ON) set(MODULES vrpn_Analog vrpn_Analog_Output vrpn_Auxiliary_Logger vrpn_Button vrpn_Dial vrpn_ForceDevice vrpn_Poser vrpn_Text vrpn_Tracker) foreach(module ${MODULES}) set_source_files_properties(${module}.i PROPERTIES CPLUSPLUS ON) swig_add_module(${module} Python ${module}.i) swig_link_libraries(${module} ${PYTHON_LIBRARIES} ${VRPN_CLIENT_LIBRARY}) endforeach() endif() 45 Anexo 4: archivo python_vrpn/vrpn_Analog.i corregido // // // // // // // // // file: author: copyright: license: depends: tested on: references: vrpn_Analog.i Thiebaut Mochel [email protected] 2008-06-05 (C)2008 CECPV Released to the Public Domain. python 2.4, swig 1.3.35, VRPN 07_15 Linux w/ gcc 4.1.2 http://python.org/ http://vrpn.org/ http://www.swig.org %module vrpn_Analog %{ #include #include #include #include #include %} "../vrpn_Types.h" "../vrpn_BaseClass.h" "../vrpn_Analog.h" "../vrpn_Analog_Output.h" "../vrpn_Analog_USDigital_A2.h" %include %include %include %include "../vrpn_Configure.h" "../vrpn_Connection.h" "../vrpn_BaseClass.h" "../vrpn_Analog.h" %{ static PyObject* convert_analog_cb(vrpn_ANALOGCB* t) { return Py_BuildValue("(iddddd)",t->num_channel,t->channel[0],t->channel[1],t>channel[2],t->channel[3],t->channel[4]); } %} %include python-callback-wrapper.i PYTHON_CALLBACK_WRAPPER(analog,vrpn_ANALOGCB,vrpn_ANALOGCHANGEHANDLER) 46 Anexo 5: Procedimento para la compilación de libvrpn con bindings en Python sobre plataforma Linux ~/vrpn$ mkdir build ~/vrpn/build$ ccmake ../ # En la GUI, presionar para iniciar la configuración # En la misma GUI, cambiar la opción de VRPN_BUILD_PYTHON a On # Presionar de nuevo para que se configure con la nueva opción prendida # Presionar para generar los archivos Makefile ~/vrpn/build$ make ~/vrpn/build$ sudo make install 47 Anexo 6: Módulo de Python para la interacción entre el BGE y OpenViBE !/usr/bin/python import Blender import GameLogic import vrpn_Button start_trial=0 c = GameLogic.getCurrentController() o = c.owner def handle_button(userdata,t): global start_trial if t[0] == 1: if t[1] == 1: start_trial = 1 else: start_trial = 0 else: if start_trial == 1: o.localPosition = [0.0, 0.0, t[1]] t=vrpn_Button.vrpn_Button_Remote("[email protected]") vrpn_Button.register_button_change_handler(handle_button) vrpn_Button.vrpn_Button_Remote.register_change_handler(t,None,vrpn_Button.get_button_change_ handler()) def main(): vrpn_Button.vrpn_Button_Remote.mainloop(t)