Desarrollo de una interfaz multimodal para un robot domótico móvil
Transcripción
Desarrollo de una interfaz multimodal para un robot domótico móvil
UNIVERSIDAD POLITÉCNICA DE MADRID ESCUELA TÉCNICA SUPERIOR DE INGENIEROS DE TELECOMUNICACIÓN DEPARTAMENTO DE INGENIERÍA ELECTRÓNICA PROYECTO FIN DE CARRERA Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia JORGE CANCELA GONZÁLEZ Ingeniero de Telecomunicación Madrid, 2009 UNIVERSIDAD POLITÉCNICA DE MADRID DEPARTAMENTO DE INGENIERÍA ELECTRÓNICA ESCUELA TÉCNICA SUPERIOR DE INGENIEROS DE TELECOMUNICACIÓN PROYECTO FIN DE CARRERA Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia JORGE CANCELA GONZÁLEZ Ingeniero de Telecomunicación Tutor del Proyecto JUAN MANUEL MONTERO MARTÍNEZ Doctor Ingeniero de Telecomunicación 2009 Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Proyecto fin de carrera 4 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. PROYECTO FIN DE CARRERA Título: Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Autora: Jorge Cancela González Tutor: Dr. Ingeniero Juan Manuel Montero Martínez Departamento: Ingeniería Electrónica de la Escuela Técnica Superior de Ingenieros de Telecomunicación de Madrid de la Universidad Politécnica de Madrid Grupo: Tecnología del Habla MIEMBROS DEL TRIBUNAL Presidente: D. Javier Ferreiros López Vocal: Firma: D. Fernando Fernández Martínez Secretario: D. Juan Manuel Montero Martínez Suplente: D. Rubén San Segundo Hernández Firma: Firma: Firma: Fecha de Lectura: Calificación: Proyecto fin de carrera 5 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Proyecto fin de carrera 6 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. AGRADECIMIENTOS En primer lugar, me gustaría agradecer a mi tutor Juancho su dedicación durante este tiempo, su esfuerzo y sus buenos consejos, gracias a los cuales he podido sacar este proyecto adelante. También me gustaría agradecer a todos aquellos que han pasado por el GTH durante mi estancia y con los que he pasado tan buenos momentos, Nuria, Vicente, Loles, Juanma, Rober, Fran, Fernando, Jorge, Javi… A todos los residentes del CM. Moncloa con los que he convivido desde el primer día de carrera hasta hoy. A mis compañeros de la ETSIT, Juan Pablo, David, Merino, Cris, Ana, Agus, Rodri, Luis, David, Javi, Mamen, Bea, Miguel, Gerardo, Cañada y Bernal agradecerles nuestros entrañables equipos de fútbol y las excursiones al parque de Francos Rodríguez. También quiero dar las gracias a todos los que conocí entre el club deportivo y el césped de la escuela, Manina, Almu, Rafa, Javi, Carlos, Lara, Ari, Orlando, Hugh y Gión. Al piso calle de los estudiantes 4. Álvaro, Carlos, Pablo, Ignasi y Juan Luis por estar siempre dispuestos a aceptar a Roomba como una más. A Carmen, por su apoyo durante todo este tiempo y por tener la grandísima paciencia de aguantar conversaciones sobre aspiradoras que se mueven solas, paquetes bluetooth y mandos de la wii. Por último, quiero dar las gracias de forma muy especial, a mi familia porque gracias a ellos puedo estar escribiendo en este momento los agradecimientos de mi proyecto fin de carrera. Especialmente, agradezco a mis padres su apoyo y su cariño durante todo este tiempo. Proyecto fin de carrera 7 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Proyecto fin de carrera 8 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. TABLA DE CONTENIDO 1. 2. Introducción............................................................................................... 21 Estado del arte .......................................................................................... 23 2.1. Domótica ............................................................................................ 23 2.1.1. El sistema domótico .................................................................... 24 2.1.2. Aplicaciones domóticas .............................................................. 25 2.1.3. Evaluación del estado domótico de una vivienda ....................... 29 2.2. Tecnologías de accesibilidad ............................................................. 32 2.3. Bluetooth ............................................................................................ 33 2.3.1. Introducción ................................................................................ 33 2.3.2. Arquitectura Bluetooth ................................................................ 35 2.3.2.1. Esquema de transmisión ..................................................... 37 2.3.2.2. Definición de paquete .......................................................... 38 2.3.2.3. Definición de enlace físico ................................................... 38 2.3.2.4. Inmunidad al ruido ............................................................... 39 2.3.3. Perfiles Bluetooth ........................................................................ 41 2.3.3.1. HID (Dispositivos de Interfaz Humana) ................................ 45 2.3.3.2. SPP (Perfil de Puerto Serie) ................................................ 46 2.4. Symbian ............................................................................................. 47 2.4.1. Introducción a Symbian .............................................................. 47 2.4.2. Arquitectura................................................................................. 50 2.4.2.1. Arquitectura software ........................................................... 51 2.4.3. J2ME ........................................................................................... 53 2.4.3.1. Características básicas de J2ME......................................... 55 2.4.3.2. Máquinas Virtuales J2ME .................................................... 55 2.4.3.2.1. Configuraciones............................................................... 58 2.4.3.2.2. Perfiles............................................................................. 60 2.4.3.3. MIDLETS ............................................................................. 63 2.4.3.3.1. El gestor de aplicaciones ................................................. 63 2.4.3.3.2. Ciclo de vida de un MIDlet ............................................... 63 2.4.3.3.3. Estados de un MIDlet en fase de ejecución..................... 65 2.4.3.3.4. Estados de un MIDlet ...................................................... 65 2.5. Reconocedores de voz ...................................................................... 67 2.5.1. Introducción a los sistemas de reconocimiento de voz ............... 67 2.5.2. Los reconocedores ..................................................................... 67 2.5.3. Métodos de reconocimiento ........................................................ 69 2.5.3.1. Reconocimiento de patrones ............................................... 70 2.5.4. Variabilidad de la señal de voz ................................................... 72 2.5.4.1. Variaciones en el contexto ................................................... 73 2.5.4.2. Variaciones en el estilo ........................................................ 73 2.5.4.3. Variaciones en el locutor...................................................... 74 2.5.4.4. Variaciones en el entorno .................................................... 74 2.5.5. Prestaciones ................................................................................... 75 3. Descripción del sistema ............................................................................ 77 3.1. Visión general del sistema ................................................................. 77 3.1.1. Requisitos previos....................................................................... 77 3.2. Arquitectura ........................................................................................ 77 9 Proyecto fin de carrera Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. 3.3. Dispositivos ........................................................................................ 79 3.3.1. Roomba ...................................................................................... 79 3.3.2. Teléfono móvil Nokia N70 ........................................................... 80 3.3.3. Dispositivo Wiimote..................................................................... 82 3.3.4. Servivox ...................................................................................... 83 3.3.5. Bluesoleil .................................................................................... 84 3.4. Aplicación cliente ............................................................................... 85 3.4.1. Introducción ................................................................................ 85 3.4.2. La clase CSocketNode ............................................................... 87 3.4.2.1. Introducción ......................................................................... 87 3.4.2.2. Arquitectura ......................................................................... 87 3.4.2.3. Detalle de funciones de CSocketNode ................................ 88 3.4.2.4. Integración en el sistema ..................................................... 90 3.4.2.5. Ejemplos de uso .................................................................. 91 3.4.3. Funcionamiento de la aplicación cliente ..................................... 93 3.4.4. Implementación de la aplicación cliente...................................... 94 3.5. El reconocedor de voz servivox ......................................................... 99 3.5.1. Introducción ................................................................................ 99 3.5.2. Adaptación de la aplicación Servivox.......................................... 99 3.5.3. Evaluación de Servivox ............................................................. 101 3.5.3.1. Metodología de evaluación ................................................ 101 3.5.3.2. Resultados ......................................................................... 105 3.5.3.3. Conclusiones ..................................................................... 116 3.6. Aplicación de gestión de Wiimote .................................................... 120 3.6.1. Wiimote ..................................................................................... 120 3.6.1.1. Memoria interna ................................................................. 122 3.6.1.2. Alimentación ...................................................................... 122 3.6.1.3. Interfaz de comunicación ................................................... 123 3.6.1.4. Gestión de paquetes bluetooth .......................................... 125 3.6.2. Implementación de la aplicación de gestión wiimote ................ 125 3.6.2.1. La librería wiiuse ................................................................ 125 3.6.2.2. Librerías dinámicas, dll ...................................................... 126 3.6.2.3. API de la librería Wiiuse .................................................... 127 3.6.2.4. Implementación del software de control y comunicaciones del wiimote 133 3.7. Aplicación teléfono móvil .................................................................. 140 3.7.1. Introducción .............................................................................. 140 3.7.2. Aplicación en el ordenador ....................................................... 140 3.7.2.1. Implementación ................................................................. 141 3.7.3. Aplicación para el teléfono móvil............................................... 144 3.8. Aplicación Roomba .......................................................................... 152 3.8.1. Introducción .............................................................................. 152 3.8.2. Arquitectura............................................................................... 153 3.8.2.1. Conexión física de Roomba y configuración del puerto serie 154 3.8.2.2. Rootooth y configuración bluetooth ................................... 155 3.8.2.3. Modos de funcionamiento .................................................. 159 Proyecto fin de carrera 10 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. 3.8.2.4. Descripción de los comandos proporcionadas por la interfaz serie de Roomba SCI .......................................................................... 160 3.8.3. El sistema de control y gestión de Roomba .............................. 161 3.8.4. Detalles de implementación ...................................................... 165 3.8.4.1. Inicialización ...................................................................... 169 3.8.4.2. Inicialización de las comunicaciones ................................. 174 3.8.4.3. Hebra principal................................................................... 177 3.8.4.4. Hebra secundaria .............................................................. 181 4. Pliego de condiciones ............................................................................. 185 4.1. Condiciones generales..................................................................... 185 4.2. Condiciones generales a todos los programas ................................ 186 4.3. Condiciones generales de prueba.................................................... 186 4.4. Recursos materiales ........................................................................ 186 4.5. Recursos lógicos .............................................................................. 187 5. Presupuesto ............................................................................................ 189 5.1. Presupuesto de ejecución material .................................................. 189 5.2. Relación de salarios ......................................................................... 189 5.2.1. Relación de obligaciones sociales ............................................ 190 5.2.2. Relación de salarios efectivos totales ....................................... 190 5.2.3. Coste de la mano de obra ......................................................... 190 5.2.4. Coste total de materiales .......................................................... 191 5.2.5. Importe total del presupuesto de ejecución material ................. 191 5.3. Importe de ejecución por contrata .................................................... 192 5.4. Honorarios Facultativos ................................................................... 192 5.5. Importe Total del Proyecto ............................................................... 193 6. Bibliografía .............................................................................................. 195 ANEXO 1. Manual de usuario del sistema ..................................................... 197 A.1. Tareas de usuario ............................................................................... 197 A.1.1. Aplicación wiimote ....................................................................... 197 A.1.2. Aplicación cliente .......................................................................... 203 A.1.3. Servivox ........................................................................................ 203 A.1.4. Aplicación teléfono móvil .............................................................. 206 A.1.5. Aplicación Roomba ....................................................................... 209 A.2. Tareas de administrador...................................................................... 209 A.2.1. Aplicación wiimote ........................................................................ 209 A.2.2. Aplicación cliente .......................................................................... 210 A.2.3. Servivox ........................................................................................ 211 A.2.3.1. Configuración de Servivox ..................................................... 212 A.2.3.2. Arranque del sistema en modo automático ............................ 216 A.2.4. Aplicación teléfono móvil .............................................................. 217 A.2.5. Aplicación Roomba ....................................................................... 218 ANEXO 2. Información más destacable de la API Roomba ........................... 219 Proyecto fin de carrera 11 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Proyecto fin de carrera 12 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. TABLA DE ILUSTRACIONES Ilustración 1: Ejemplo de componentes de la casa domótica [1] ...................... 23 Ilustración 2: Ejemplo de una instalación domótica [1] ..................................... 24 Ilustración 3: Esquema conceptual sobre el sistema VoIP obtenido de [27] .... 29 Ilustración 5: Esquema de una scatternet Bluetooth ........................................ 36 Ilustración 6: Modelo sistema FH/TDD [6] ........................................................ 37 Ilustración 7: Ajuste del salto de frecuencia [6] ................................................ 38 Ilustración 8: Formato de paquete de datos Bluetooth [6] ................................ 38 Ilustración 9: Capas de software que residen tanto en el anfitrión como en el dispositivo HID ................................................................................................. 46 Ilustración 10: Modelo de capas del perfil SPP ................................................ 47 Ilustración 11: Logotipo de SymbianOS y empresas que conformaron el SIG inicial ................................................................................................................ 48 Ilustración 12: Diagrama esquemático de la arquitectura de la plataforma S60 [7] ..................................................................................................................... 51 Ilustración 13: Arquitectura software Symbian simplificada .............................. 51 Ilustración 14: Arquitectura software Symbian detallada .................................. 52 Ilustración 15: Arquitectura de la plataforma Java 2 de Sun ............................ 54 Ilustración 16: Entorno de ejecución de J2ME ................................................. 56 Ilustración 17: Preverificación de clases en CDLC/KVM. ................................. 58 Ilustración 18: Arquitectura del entorno de ejecución de J2ME. ....................... 61 Ilustración 19: Ciclo de vida de un MIDlet. ....................................................... 64 Ilustración 20: Estados de un MIDlet. ............................................................... 66 Ilustración 21: Diagrama de bloques de un reconocedor obtenido de [11]....... 68 Ilustración 22: Arquitectura básica de un sistema reconocedor obtenido de [13] ......................................................................................................................... 69 Ilustración 23: Esquema de un reconocedor de dos etapas, obtenido de [11] . 71 Ilustración 24: Visión general del sistema con las aplicaciones y dispositivos que intervienen ................................................................................................. 78 Ilustración 25: Detalle del archivo de configuración ‘config_mov.ini’ ................ 79 Ilustración 26: Vista del robot iRoomba de iRobot............................................ 80 Ilustración 27: Vista del dispositivo de comunicaciones inalámbrico Rootooh . 80 Ilustración 28: Vista anterior y posterior del teléfono móvil N70 de Nokia ........ 82 Ilustración 29: Vista del dispositivo Wiimote de Nintendo ................................ 82 Ilustración 30: Vista de la barra de infrarrojos de Nintendo .............................. 83 Ilustración 31: Vista de la pantalla principal del software Bluesoleil ................. 85 Ilustración 32: Esquema de funcionamiento de la aplicación cliente ................ 86 Ilustración 33: Vista del archivo de configuración 'config_sys.ini' ..................... 94 Ilustración 34: Diagrama de flujo de la aplicación cliente ................................. 95 Ilustración 35: Diagrama de flujo para la conexión y manejo de la conexión CSocketNode en la aplicación cliente .............................................................. 97 Ilustración 36: Vista de Servivox con el umbral de confianza ajustada a 0,71. ....................................................................................................................... 102 Ilustración 37: Imagen que muestra el contenido de un archivo de diccionario. ....................................................................................................................... 102 Ilustración 38: Conjunto 'frases conocidas'..................................................... 103 Ilustración 39: Conjunto 'frases desconocidas' ............................................... 103 13 Proyecto fin de carrera Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 40: Conjuntos para entrenamiento y test ...................................... 105 Ilustración 41: Número de frases correctamente reconocidas por nivel de umbral ............................................................................................................ 106 Ilustración 42: Porcentaje de frases correctamente clasificadas por nivel de umbral ............................................................................................................ 107 Ilustración 43: Definición de los umbrales empleados en la evaluación ......... 108 Ilustración 44: Resultados de clasificación del conjunto de test 1 .................. 109 Ilustración 45: Resultados de clasificación del conjunto de test 2 .................. 110 Ilustración 46: Resultados de clasificación del conjunto de test 3 .................. 111 Ilustración 47: Resultados de clasificación del conjunto de test 4 .................. 112 Ilustración 48: Resultados de clasificación del conjunto de test 5 .................. 113 Ilustración 49: Resultados de clasificación del conjunto de test 6 .................. 114 Ilustración 50: Resultados de clasificación del conjunto de test 7 .................. 115 Ilustración 51: Gráfica con los resultados de clasificación ............................. 116 Ilustración 52: Frases correctamente clasificadas empleando el umbral alto promedio ........................................................................................................ 118 Ilustración 53: Frases correctamente clasificadas empleando el umbral bajo promedio ........................................................................................................ 119 Ilustración 54: Vista frontal, lateral y posterior del wiimote ............................. 120 Ilustración 55: Chip ADXL330 ........................................................................ 121 Ilustración 56: Esquema interno de un acelerómetro ADXL330 ..................... 121 Ilustración 57: Sistema de coordenadas definido sobre el Wiimote con las definiciones de sus movimientos .................................................................... 122 Ilustración 58: Esquema de comunicaciones de la aplicación de gestión del Wiimote .......................................................................................................... 134 Ilustración 59: Diagrama de estados para el tratamiento de las teclas del wiimote ........................................................................................................... 136 Ilustración 60: Transiciones entre estados con el control basado en movimientos ................................................................................................... 138 Ilustración 61: Ilustraciones con las posiciones del wiimote asociadas a cada uno de los movimientos .................................................................................. 140 Ilustración 62: Esquema de funcionamiento de la aplicación cliente instalada en el ordenador ................................................................................................... 141 Ilustración 63: Arquitectura genérica para desarrollo con J2ME .................... 145 Ilustración 64: Detalle de la transición entre movimientos y secuencia de bits (en decimal en la imagen) que se van a enviar .............................................. 152 Ilustración 65: Relación de los diferentes actores con el sistema .................. 153 Ilustración 66: Figura del pin-out de la conexión Mini-DIN de roomba .......... 155 Ilustración 67: Dispositivo de comunicaciones Rootooth................................ 156 Ilustración 68: Diagrama de bloques del sistema Rootooth y de las comunicaciones con la aplicación de control.................................................. 159 Ilustración 69: Diagrama esquemático con las transiciones entre los diversos estados en los que se puede encontrar Roomba ........................................... 160 Ilustración 70: Vista esquemática del funcionamiento de la aplicación cliente 162 Ilustración 71: Vista esquemática de la interfaz Roomba ............................... 163 Ilustración 72: Captura del fichero ‘config_mov.ini’ ........................................ 164 Ilustración 73: Captura del fichero ‘config_sys.ini’ .......................................... 165 Proyecto fin de carrera 14 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 74: Vista superior e inferior de Roomba con los sensores de pared (derecha) y de borde (izquierda) destacados. ................................................ 167 Ilustración 75: Esquema del flujo principal del programa ............................... 169 Ilustración 76: Figura del protocolo de comandos AT .................................... 176 Ilustración 77: Detalle del flujo de la hebra principal de la aplicación Roomba ....................................................................................................................... 178 Ilustración 78: Detalle del flujo de la hebra secundaria de la aplicación Roomba ....................................................................................................................... 182 Ilustración 79: Vista de la aplicación Bluesoleil al arrancar ............................ 197 Ilustración 80: Aplicación Bluesoleil una vez reconocido el dispositivo wiimote ....................................................................................................................... 199 Ilustración 81: Proceso de conexión del dispositivo wiimote ......................... 200 Ilustración 82: Vista de Bluesoleil una vez establecida la conexión con el wiimote ........................................................................................................... 200 Ilustración 83: Vista de la aplicación 'wiimote.exe' ......................................... 201 Ilustración 84: Configuración por defecto del mando wiimote ........................ 202 Ilustración 85: Configuración por defecto del mando wiimote ........................ 202 Ilustración 86: Vista de la aplicación cliente en ejecución .............................. 203 Ilustración 87: Aplicación RoombaN70 en el menú principal del teléfono móvil N70 ................................................................................................................. 206 Ilustración 88: Búsqueda de dispositivos bluetooth ........................................ 206 Ilustración 89: Establecimiento de las conexiones bluetooth ......................... 207 Ilustración 90: Mensaje de protección del teléfono móvil N70 ........................ 207 Ilustración 91: Mensaje de confirmación del establecimiento del servicio SPP en el equipo seleccionado. .................................................................................. 207 Ilustración 92: Pantalla principal de la aplicación RoombaN70 ...................... 208 Ilustración 93: Lista de movimientos disponibles............................................ 208 Ilustración 94: Vista de la aplicación de gestión del teléfono móvil ................ 209 Ilustración 95: Detalle de la entrada socket_wiimote del fichero 'config_sys.ini' ....................................................................................................................... 210 Ilustración 96: Detalle de la entrada config_wiimote en el archivo 'config_sys.ini' ....................................................................................................................... 210 Ilustración 97: Entradas de configuración de los sockets del sistema en el fichero 'config_sys.ini' ..................................................................................... 211 Ilustración 98: Entrada puerto_serie_movil del fichero 'config_sys.ini' ........... 217 Ilustración 99: Sección puerto_serie_roomba del fichero 'config_sys.ini' ....... 218 Proyecto fin de carrera 15 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Proyecto fin de carrera 16 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. TABLA DE TABLAS Tabla 1: Bloque de dispositivos de sistema de alarma de intrusión y defensa . 30 Tabla 2: Bloque de dispositivos de alarmas técnicas ....................................... 30 Tabla 3: Bloque de dispositivos de simulación de presencia ........................... 30 Tabla 4: Bloque de dispositivos de videoportero .............................................. 31 Tabla 5: Bloque de dispositivos de control de persianas.................................. 31 Tabla 6: Bloque de dispositivos de control y regulación de la iluminación ....... 31 Tabla 7: Bloque de dispositivos de control del clima ........................................ 31 Tabla 8: Bloque de dispositivos de programación ............................................ 31 Tabla 9: Bloque de dispositivos de interfaz de usuario .................................... 32 Tabla 10: Bloque de dispositivos conectables a empresas suministradoras .... 32 Tabla 11: Bloque de dispositivos de la red multimedia..................................... 32 Tabla 12: Clasificación de los dispositivos Bluetooth según su potencia ......... 34 Tabla 13: Anchos de banda de los dispositivos Bluetooth según su versión ... 35 Tabla 14: Servicios soportados por el OS Symbian en la versión 6 ................. 50 Tabla 15: Librerías de configuración CLDC. .................................................... 59 Tabla 16: Librerías del perfil MIDP. .................................................................. 62 Tabla 17: Tabla con las características técnicas del teléfono móvil N70.......... 82 Tabla 18: Resultados del conjunto de test 1 .................................................. 109 Tabla 19: Resultados del conjunto de test 2 .................................................. 110 Tabla 20: Resultados del conjunto de test 3 .................................................. 111 Tabla 21: Resultados del conjunto de test 4 .................................................. 112 Tabla 22: Resultados del conjunto de test 5 .................................................. 113 Tabla 23: Resultados del conjunto de test 6 .................................................. 114 Tabla 24: Resultados del conjunto de test 7 .................................................. 115 Tabla 25: Frases conocidas correctamente clasificadas según el umbral ...... 117 Tabla 26: Frases desconocidas correctamente clasificadas según el umbral 117 Tabla 27: Reportes de wiimote ....................................................................... 124 Tabla 28: Rango de valores de las posiciones del wiimote asociadas a sus estados ........................................................................................................... 138 Tabla 29: Pin-out de la conexión Mini-DIN de roomba ................................... 154 Tabla 30: Tabla con los parámetros configurables del archivo 'config_mov.ini' ....................................................................................................................... 165 Tabla 31: Sueldos de las personas que han intervenido en el proyecto ........ 189 Tabla 32: Obligaciones sociales ..................................................................... 190 Tabla 33: Salarios efectivos totales ................................................................ 190 Tabla 34: Coste de la mano de obra .............................................................. 190 Tabla 35: Coste de materiales........................................................................ 191 Tabla 36: Presupuesto de ejecución material................................................. 192 Tabla 37: Importe de ejecución por contrata .................................................. 192 Tabla 38: Honorarios facultativos ................................................................... 193 Tabla 39: Honorarios totales .......................................................................... 193 Tabla 40: Importe total del proyecto ............................................................... 193 Tabla 41: API de Roomba (1/3) ...................................................................... 220 Tabla 42: API de Roomba (2/3) ...................................................................... 221 Tabla 43: API de Roomba (3/3) ...................................................................... 222 Proyecto fin de carrera 17 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Proyecto fin de carrera 18 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. TABLA DE CUADROS Cuadro 1: Líneas de código con los include necesarios para el buen funcionamiento de la clase CSocketNode ........................................................ 91 Cuadro 2: Sobreescritura de la función ServerLoop() ...................................... 92 Cuadro 3: Sobreescritura de la función OnMsg() ............................................. 92 Cuadro 4: Tratamiento de la información recibida con IsConnected() y ReceiveMsg() ................................................................................................... 93 Cuadro 5: Implementación del flujo principal de la aplicación cliente ............... 96 Cuadro 6: Implementación de la función check_sockets() ............................... 97 Cuadro 7: Implementación de la función conecta_sockets() ............................ 98 Cuadro 9: Busqueda de wiimotes en el ambiente .......................................... 134 Cuadro 10: Inicializa socket wiimote y comienza el bucle principal ................ 135 Cuadro 11: Gestión de pulsación de botones................................................. 137 Cuadro 12: Código con la gestión de movimientos en el wiimote .................. 139 Cuadro 14: Función de configuración del puerto serie ................................... 142 Cuadro 15: Función abre_socket() para inicializar un objeto de la clase CSocketNode ................................................................................................. 143 Cuadro 16: Implementación de la función conecta_socket() .......................... 143 Cuadro 17: Implementación de la función read_string() ................................. 144 Cuadro 18: Implementación de la función maneja_info() ............................... 144 Cuadro 22: Diagrama de clases de gestión gráfica de un MIDlet................... 149 Cuadro 23: Inicialización del Canvas del dispositivo N70 y la función paint() 150 Cuadro 24: Funciones para el tratamiento de eventos en el teléfono móvil ... 151 Cuadro 25: Cuadro con los posibles parámetros del comando ATSW y ejemplos de configuración .............................................................................. 158 Cuadro 26: Tipos definidos de movimientos en Roomba ............................... 166 Cuadro 27: Tipo definido Tsensores .............................................................. 166 Cuadro 28: Inicialización de la estructura Tsensores ..................................... 169 Cuadro 29: Llamadas a read_file_config() y detalle de la función. ................. 171 Cuadro 34: Implementación de la función de comprobación de las medidas de seguridad........................................................................................................ 179 Cuadro 35: Bucle de comprobación del buffer de transmisión de secuencias 180 Cuadro 36: Implementación de la función ejecuta_secuencias() ................... 181 Cuadro 37: Definición de la clase CServidor .................................................. 182 Cuadro 38: Implementación de la función movimiento_onmsg() .................... 182 Cuadro 39: Implementación de la función movimiento2secuencia() .............. 183 Cuadro 40: Implementactión de la función secuencia_a_buffer()................... 184 Cuadro 41: Configuración de las variables relativas al ruido en el entorno .... 213 Proyecto fin de carrera 19 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Proyecto fin de carrera 20 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. 1. Introducción Este proyecto final de carrera tiene como objetivo el desarrollo de una interfaz multimodal que permita el control de un robot domótico móvil, concretamente la aspiradora Roomba de la empresa iRobot, mediante el empleo de diversas modalidades. El primero de ellos y el más ligado al grupo en el que se desarrolla el proyecto es el uso de un reconocedor de voz para el control del robot domótico; el uso de este tipo de tecnologías implica un alto grado de accesibilidad de cara a personas que de otra forma se encuentran limitadas. Como alternativas al control mediante voz, se presenta el control mediante un dispositivo para videoconsola bluetooth, se trata del mando wiimote de la videoconsola Wii de Nintendo. Por último también será posible el control de Roomba mediante una aplicación para teléfonos móviles con el sistema operativo Symbian mediante el empleo de la tecnología J2ME de Sun. Proyecto fin de carrera 21 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Proyecto fin de carrera 22 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. 2. Estado del arte A continuación haremos una evaluación del estado del arte de las diversas tecnologías que intervienen en el proyecto, como son bluetooth, el sistema operativo Symbian y los reconocedores de voz, así como una introducción al estado actual de la domótica y las tecnologías de accesibilidad. 2.1. Domótica El término domótica proviene de la unión de las palabras domus (que significa casa en latín y tica (de automática, palabra en griego, “que funciona por sí sola”) [1]. Se entiende por domótica al conjunto de sistemas capaces de automatizar una vivienda, aportando servicios de gestión energética, seguridad, bienestar y comunicación, y que pueden estar integrados por medio de redes interiores y exteriores de comunicación, cableadas o inalámbricas, y cuyo control goza de cierta ubicuidad, desde dentro y fuera del hogar. Se podría definir como la integración de la tecnología en el diseño inteligente de un recinto. Lo que se pretende conseguir es la automatización de la vivienda, del hogar, ya sea en una casa aislada o esté en un piso de un inmueble. La automatización de edificios no destinados a vivienda, es decir oficinas, despachos, pequeño terciario y servicios en general, se denomina inmótica. Ilustración 1: Ejemplo de componentes de la casa domótica [1] Algunos ejemplos de objetivos que tratan de abordarse con la domótica son los siguientes: Proyecto fin de carrera 23 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Encender / apagar, abrir / cerrar, regular, detectar, posicionar cualquier tipo de dispositivo de un hogar: Persianas, toldos, puertas, ventanas, iluminación, climatización, riego, electrodomésticos (línea blanca). Simulación de presencia, creación de escenas de iluminación. Gestión remota, programación horaria, gestión de la energía… Sistemas de seguridad técnica (humo, agua, gas, fallo suministro eléctrico, fallo línea telefónica, detección de presencia,...) Sistema de seguridad no conectados a una central receptora de alarmas (intrusión, detección de presencia, aperturas de puertas y ventanas, etc.) o seguridad personal (servicios SOS, tercera edad, conexión con hospitales…). Seguridad de seguridad conectados a una central receptora de alarmas (intrusión, detección presencia, aperturas de puertas y ventanas…) Audio/Vídeo. El cine en casa. Televisión interactiva y videos bajo demanda. 2.1.1. El sistema domótico Para presentar un sistema domótico podemos hacer una exposición de los elementos comunes de una instalación de este tipo [1]. Ilustración 2: Ejemplo de una instalación domótica [1] Proyecto fin de carrera 24 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. a. Al elemento que permite y centraliza la comunicación de la red doméstica con el exterior y se le denomina “pasarela residencial”, aunque está muy generalizado el anglicismo Gateway. El número de dispositivos que actúan como gateway está en creciente aumento debido por un lado, al aumento en las capacidades de las redes, tanto de la World Wide Web como de las redes móviles, de forma que ya no es necesario una red privada sino que las redes actuales permiten a un precio asequible interconectar el hogar con un centro de control. Por otro lado, los dispositivos también aumentan en capacidad de procesamiento y sus capacidades de transmisión, al tiempo que los precios descienden. Es decir, ya no se tiende a un diseño ad-hoc adaptado sino que hablamos de dispositivos y redes comerciales que se adaptarán a las necesidades del usuario. b. Una red local doméstica que permite la comunicación entre todos los sistemas descritos. Esta red interconecta los dispositivos de adquisición y puede contener una parte de la inteligencia que se encarga de tomar las decisiones apropiadas para proporcionar al usuario los servicios que el usuario esté esperando. Al igual que en el caso de los gateway, en este caso tampoco necesitamos un diseño ad-hoc, sino que existe una amplia gama de estándares para establecer redes locales y de dispositivos para nuestra. 2.1.2. Aplicaciones domóticas Las posibles aplicaciones son innumerables dadas las posibilidades de la domótica, podemos decir tranquilamente que las posibilidades son tan extensas como puedan ser las pretensiones de los propios usuarios, por ello trataremos de agruparlas en las más comunes: 1) En el ámbito del ahorro energético: a. Programación y zonificación de la climatización. El usuario personaliza a qué hora y qué zonas de la vivienda desea que estén gestionadas por el control central b. Racionalización de cargas eléctricas: desconexión de equipos de uso no prioritario en función del consumo eléctrico en un momento dado. (Reduce la potencia contratada). c. Gestión de tarifas, derivando el funcionamiento de algunos aparatos a horas de tarifa reducida. 2) En el ámbito del nivel de confort: Proyecto fin de carrera 25 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. a. Control de todos los dispositivos instalados y operativos desde un dispositivo central, simplificando su gestión y optimizando su uso. b. Automatización del apagado/encendido en cada punto de luz. La forma de encender y apagar la iluminación de la vivienda puede ser automatizada y controlada de formas complementarias al control tradicional a través del interruptor clásico. Se puede en esta manera conseguir un incremento del confort y ahorro energético. La iluminación puede ser regulada en función del nivel de luminosidad ambiente, evitando su encendido innecesario o adaptándola a las necesidades del usuario. La activación de ésta se realiza siempre cuando el nivel de luminosidad pasa un determinado umbral, ajustable por parte del usuario. Esto garantiza un nivel de iluminación mínima, que puede ser especialmente útil para, por ejemplo, un pasillo o la iluminación exterior. La iluminación puede ser activada en función de la presencia de personas en la estancia. Se activa la iluminación cuando un sensor detecta presencia. Esto garantiza una buena iluminación para, por ejemplo, zonas de paso como pasillos. Asegura que luces no se quedan encendidas en habitaciones cuando no hace falta. c. Automatización de todos los distintos sistemas/ instalaciones / equipos dotándolos de control eficiente y de fácil manejo. El hecho de que los sistemas de la vivienda se pueden programar, ya sea para que realicen ciertas funciones con sólo tocar un botón, o que las lleven a cabo en función de otras condiciones del entorno (hora, temperatura interior o exterior, etc.) produce un aumento del confort y un ahorro de tiempo. d. Integración del portero al teléfono, o del video-portero al televisor. La señal de audio y control del portero automático se puede integrar en la red de telefonía interior de la vivienda, para permitir utilizar el teléfono en lugar de la habitual consola de control de esta instalación. Cualquier llamada desde el portero automático puede ser atendida desde un terminal telefónico, entablando conversación con la persona visitante y, si es preciso, abrirle la puerta. La señal de vídeo y control del video-portero automático se puede integrar en la red de televisión de la vivienda y edificio, para permitir utilizar el televisor en lugar de la habitual consola de control de esta instalación. Cualquier llamada desde el videoportero automático puede ser atendida desde el televisor, reconociendo la persona visitante y, si es preciso, abrirle la puerta mediante el propio mando a distancia del televisor (u otro de uso específico). Opcionalmente, y cuando no hay nadie en la vivienda, podría pensarse en desviar la llamada desde el portero automático a un número de Proyecto fin de carrera 26 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. abonado telefónico, simulando la presencia de un usuario en casa o por ejemplo abrirle la puerta de acceso de la calle a un mensajero. e. El riego automático es una aplicación muy utilizada por la gente que vive en viviendas unifamiliares. El riego puede ser gestionado por un controlador que normalmente se limita a regar según la programación horaria. Pero el riego puede ser más desarrollado y avanzado que eso. Puede ser activado de forma automática según programación horaria, pero también según la humedad en el césped, el día de la semana o cualquier otro valor. Además si el riego esta integrado en el sistema de domótica se puede controlar el riego de forma remota o según otros eventos como incendios o robos. Además existe la posibilidad de realizar actuaciones puntuales y personalizadas como por ejemplo regar por la tarde en vez de por la noche si el dueño planifica una barbacoa con los amigos por la noche. 3) En el ámbito de la protección personal y patrimonial: a. Detección de un posible intruso. En caso de intruso el control central se encarga de hacer saltar las alarmas, a la vez que avisa al propietario del inmueble y las autoridades. b. Simulación de presencia. Gestión del control de acceso y control de presencia, así como la simulación de presencia. c. Detección de conatos de incendio, fugas de gas, escapes de agua. Mediante el nodo telefónico, se puede tener acceso (mediante un pulsador radio-frecuencia que se lleve encima por ejemplo) a los servicios de Samur, Policía, etc. A través del nodo telefónico es posible desviar la alarma hacia los bomberos, por ejemplo. d. Servicios de alerta médica, telemedicina, teleasistencia, telecuidado, etc. e. Cerrado de persianas puntual y seguro. f. Se puede detectar averías en los accesos, en los ascensores, etc. 4) En el ámbito de las comunicaciones: a. Control Remoto Dentro de la vivienda: a través de un esquema de comunicación con los distintos equipos (mando a distancia, bus de comunicación, etc.). Reduce la necesidad de moverse dentro de la vivienda, este hecho puede ser particularmente importante en el caso de personas de la tercera edad o minusválidos. Proyecto fin de carrera 27 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Fuera de la vivienda: presupone un cambio en los horarios en los que se realizan las tareas domésticas (por ejemplo: la posibilidad de que el usuario pueda activar la cocina desde el exterior de su vivienda, implica que previamente ha de preparar los alimentos) y como consecuencia permite al usuario un mejor aprovechamiento de su tiempo. b. Transmisión de alarmas. c. Intercomunicaciones entre las habitaciones. d. Telefonía IP. Las comunicaciones de voz por Internet utiliza la conexión a Internet como red de transporte de los datos, para realizar una comunicación VoIP (Voice Over IP). Se puede realizar las llamadas desde el ordenador personal hasta otro PC remoto o bien hasta cualquier tipo de teléfono, basta con disponer de un PC, conexión a Internet, un equipo multimedia (altavoces y micrófono) y el software necesario para ello. Pero también existe la posibilidad de integrar, o hasta sustituir la telefonía tradicional con la telefonía IP. Como terminal para realizar las llamadas, se puede utilizar por parte del que tiene contratado el servicio: El PC, aprovechando los altavoces y micrófonos internos o externos. El PC, con un teléfono especial conectado al puerto USB. Un teléfono normal conectado a un hub que a su vez esta conectado a un router. Un Teléfono o SmartPhone dotado de tecnología WiFi que directamente integra el software de telefonía IP. Proyecto fin de carrera 28 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 3: Esquema conceptual sobre el sistema VoIP obtenido de [27] Tal vez la ventaja más tangible para los usuarios finales radique en el método de facturación de estas llamadas. Mientras que las operadoras telefónicas tradicionales suelen tarificar las comunicaciones según la distancia y el tiempo de conexión, el coste de una llamada por Internet puede no depender de la lejanía del interlocutor. Pero aún siendo dependiente de su destino, la comunicación tendrá siempre un valor considerablemente más reducido que el de una llamada telefónica habitual, pudiendo en algunos casos ser gratis. 2.1.3. Evaluación del estado domótico de una vivienda Para valorar el grado de inteligencia de un edificio se han de tener en cuenta diversas variables observables tanto en sus sistemas automatizados como en su estructura. La medida en que se contemplan estas variables nos permitirán decidir si un edificio es inteligente o sencillamente dispone de funciones automatizadas. La asociación española de domótica, CEDOM, proporciona una tabla de niveles para evaluar el grado de “domotización” de un hogar. Esta tabla se ha desarrollado a partir de la propuesta española confeccionada por el CTN202/SC205 “Sistemas electrónicos para viviendas y edificios”, la cual ha sido enviada y aceptada para incluirse en el Plan de Trabajo del WG2 de CLC/TC205 “HBES Installations”. La tabla se divide en varios subapartados según las diferentes agrupaciones de servicios que se pueden ofrecer en el ámbito domótico, dando como resultado diferentes bloques en los que se obtiene una suma parcial con el grado de estado domótico de la vivienda, Tabla 1-Tabla 12. Proyecto fin de carrera 29 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Dispositivos Detectores de presencia Teclado codificado, llave electrónica o equivalente Sirena interior Contactos de ventana y/o impactos Sistema de mantenimiento de alimentación en caso de fallo de suministro eléctrico Módulo de habla/escucha, destinado a la escucha en caso de alarma. También se admite cualquier tipo de control que permita conocer si realmente existe un intruso (cámaras web...) Sistema conectable con central de alarmas Nº de dispositivos o condición a cumplir 1. 2. 3. 4. 1. 2. 1. 2. 1. 2. 3. 1. 2. 1. 2. Ninguno Dos 2 Uno cada 20 m Uno por estancia Ninguno Uno No Si No En puntos de fácil acceso En todas las ventanas No Si No Si 1. No 2. Si Tabla 1: Bloque de dispositivos de sistema de alarma de intrusión y defensa Dispositivos Nº de dispositivos o condición a cumplir Detectores de inundación necesarios en zonas húmedas (baños, cocina, lavadero, garaje) 1. No 2. Los necesarios Electro válvula de corte de agua con instalación para “bypass” manual. Detectores de concentraciones de gas butano y/o natural en zonas donde se prevea que habrá elementos que funcionen con gas Electro válvula de corte de gas con instalación para “bypass” manual 1. 2. 1. 2. No Los necesarios No Los necesarios 1. No 2. Los necesarios Detector de incendios 1. No 2. Los necesarios Tabla 2: Bloque de dispositivos de alarmas técnicas Dispositivos Nº de dispositivos o condición a cumplir Simulador de presencia 1. No 2. Relacionada con las persianas motorizadas o con los puntos de luz. 3. Relacionada con las persianas y con los puntos de luz. Tabla 3: Bloque de dispositivos de simulación de presencia Proyecto fin de carrera 30 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Dispositivos Videoportero Nº de dispositivos o condición a cumplir 1. No 2. Si Tabla 4: Bloque de dispositivos de videoportero Dispositivos Nº de dispositivos o condición a cumplir Control de persianas 1. No 2. Todas las de superficie 2 superior a 2 m 3. Todas Tabla 5: Bloque de dispositivos de control de persianas Dispositivos Regulación lumínica con control de escenas En jardín o grandes terrazas mediante interruptor crepuscular o interruptor horario astronómico Conexión/desconexión general de iluminación Nº de dispositivos o condición a cumplir 1. No 2. En dependencias dedicadas al ocio 3. En salón y dormitorios 1. No 2. Si 2.1. No 2.1. Un acceso 2.1. Todos los accesos Control de puntos de luz y tomas de corriente 3. No más significativas 4. 50 % de los puntos de luz 5. 80% de los puntos de luz + 20% de las tomas de corriente Tabla 6: Bloque de dispositivos de control y regulación de la iluminación Dispositivos Nº de dispositivos condición a cumplir o Cronotermostato 1. No 2. Uno en el salón 3. Zonificando la vivienda en un mínimo de dos zonas 4. Varios cronotermostatos, zonificando la vivienda por estancias Tabla 7: Bloque de dispositivos de control del clima Dispositivos Posibilidad de realizar programaciones horarias sobre los equipos controlados Nº de dispositivos o condición a cumplir 1. No 2. Si Gestor energético 1. No 2. Si Tabla 8: Bloque de dispositivos de programación Proyecto fin de carrera 31 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Dispositivos Nº de dispositivos o condición a cumplir Consola o equivalente 1. No 2. Si Control telefónico bidireccional 3. No 4. Si 5. Interacción mediante SMS 1. No 2. Si Equipo para control a través de Internet, WAP o equivalente Tabla 9: Bloque de dispositivos de interfaz de usuario Dispositivos Nº de dispositivos o condición a cumplir Dispositivos conectables a empresas suministradoras a través de redes de comunicación 1. Cero 2. Uno 3. Dos 4. Tres o más Tabla 10: Bloque de dispositivos conectables a empresas suministradoras Dispositivos Nº de dispositivos o condición a cumplir Tomas SAT y Tomas Multimedia 1. No 2. Tres tomas satélite + tres tomas multimedia 3. Tres tomas satélite + Una toma multimedia en todas las estancias, incluido terraza Punto de acceso inalámbrico 1. No 2. Wifi Tabla 11: Bloque de dispositivos de la red multimedia 2.2. Tecnologías de accesibilidad Podemos definir las tecnologías de accesibilidad como aquellas que permiten poner productos, herramientas y servicios digitales al alcance de todos. Las tecnologías de la información y la comunicación (TIC) se caracterizan hoy día por su digitalización: los productos y servicios se encuentran a disposición de los usuarios mediante la web, software, telefonía móvil, etc. Las personas con discapacidad, entre otros colectivos, se enfrentan constantemente a grandes barreras de acceso, pero el adecuado uso de las TIC puede fácilmente romper estas barreras y ofrecer lo que se denomina diseño para todos. En nuestro caso el concepto de tecnología accesible conecta fuertemente con el de domótica, ya que trabajamos con un robot pensado especialmente para el hogar que, además de ofrecer un valor añadido de confort para un usuario normal, también se puede emplear para el 32 Proyecto fin de carrera Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. acercamiento de este tipo de tecnologías a personas ancianas o con algún tipo de discapacidad, facilitando de esta forma las tareas diarias en el hogar. 2.3. Bluetooth 2.3.1. Introducción En 1994, la empresa L.M. Ericcson se interesó en conectar sus teléfonos móviles y otros dispositivos (por ejemplo, PDAs) sin necesidad de cables [3][4]. En conjunto con otras cuatro empresas (IBM, Intel, Nokia y Toshiba), formó un SIG (grupo de interés especial) con el propósito de desarrollar un estándar inalámbrico para interconectar ordenadores, dispositivos de comunicaciones y accesorios a través de radios inalámbricos de bajo consumo de energía, corto alcance y económicos. El primer objetivo para los productos Bluetooth de primera generación eran los entornos de la gente de negocios que viaja frecuentemente. Por lo que se debería pensar en integrar el chip de radio Bluetooth en equipos como: PCS portátiles, teléfonos móviles, PDAs y auriculares. Esto originaba una serie de cuestiones previas que deberían solucionarse tales como: El sistema debería operar en todo el mundo. El emisor de radio deberá consumir poca energía, ya que debe integrarse en equipos alimentados por baterías. La conexión deberá soportar voz y datos, y por lo tanto aplicaciones multimedia. Ilustración 4: Logotipo de Bluetooth Al proyecto se le asignó el nombre de bluetooth. Aunque la idea original eran tan sólo prescindir de cables entre dispositivos, su alcance se expandió rápidamente al área de las LANs inalámbricas. Aunque esta idea le dio más utilidad al estándar, también provocó el surgimiento de competencia con el 802.11. Para empeorar las cosas, los dos sistemas interfieren entre sí en el ámbito eléctrico. Sin desanimarse por eso el SIG de bluetooth emitió en julio de 1999 una especificación de 1500 páginas acerca de V1.0. Un poco después, el grupo de estándares del IEEE que se encarga de las redes de área personal inalámbrica, 802.15, adoptó como base el documento sobre bluetooth y empezó a trabajar sobre él. A pesar de que podía parecer extraño estandarizar algo que ya cuenta con una especificación bien detallada, sin implementaciones incompatibles que tengan que armonizarse, la historia demuestra que al existir un estándar abierto manejado por un cuerpo neutral como el IEEE, con frecuencia se estimula el uso de una tecnología. Para ser un Proyecto fin de carrera 33 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. poco más precisos, debe apuntarse que la especificación de Bluetooth está dirigida a un sistema completo, de la capa física a la capa de aplicación. El comité 802.15 del IEEE estandariza solamente la capa física y la de enlace de datos; el resto de la pila de protocolos está fuera de sus estatutos. Aún cuando el IEEE aprobó en el 2002 el primer estándar para las redes de área personal, 802.15.1, el SIG de Bluetooth continúa sus mejoras. A pesar de que las versiones del SIG y del IEEE difieren, se espera que en breve coincidan en un solo estándar. Por lo tanto podemos decir que se denomina Bluetooth al protocolo de comunicaciones diseñado especialmente para dispositivos de bajo consumo, con una baja cobertura y basados en transceptores de bajo coste. Gracias a este protocolo, los dispositivos que lo implementan pueden comunicarse entre ellos cuando se encuentran dentro de su alcance. Las comunicaciones se realizan por radiofrecuencia de forma que los dispositivos no tienen que estar alineados y pueden incluso estar en habitaciones separadas si la potencia de transmisión lo permite. Estos dispositivos se clasifican como "Clase 1", "Clase 2" o "Clase 3" en referencia a su potencia de trasmisión, Tabla 12, siendo totalmente compatibles los dispositivos de una clase con los de las otras. Clase Potencia máxima permitida (dBm) 20 dBm Rango (aproximado) Clase 1 Potencia máxima permitida (mW) 100 mW Clase 2 2.5 mW 4 dBm ~10 metros Clase 3 1 mW 0 dBm ~ 1 metro ~ 100 metros Tabla 12: Clasificación de los dispositivos Bluetooth según su potencia En la mayoría de los casos, la cobertura efectiva de un dispositivo de clase 2 se extiende cuando se conecta a un transceptor de clase 1. Esto es así gracias a la mayor sensibilidad y potencia de transmisión del dispositivo de clase 1, es decir, la mayor potencia de transmisión del dispositivo de clase 1 permite que la señal llegue con energía suficiente hasta el de clase 2. Por otra parte la mayor sensibilidad del dispositivo de clase 1 permite recibir la señal del otro pese a ser más débil. Los dispositivos con Bluetooth también pueden clasificarse según su ancho de banda, Tabla 13. Proyecto fin de carrera 34 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Versión Ancho de banda Versión 1.2 1 Mbit/s Versión 2.0 + EDR 3 Mbit/s UWB Bluetooth (Propuesto) 53 – 480 Mbit/s Tabla 13: Anchos de banda de los dispositivos Bluetooth según su versión La versión 1.2, a diferencia de la 1.1, provee una solución inalámbrica complementaria para co-existir Bluetooth y Wifi en el espectro de los 2.4 GHz, sin interferencia entre ellos. Para lograrlo usa la técnica "Adaptive Frequency Hopping (AFH)", que ejecuta una transmisión más eficiente y un cifrado más seguro. Para mejorar las experiencias de los usuarios, la V1.2 ofrece una calidad de voz (Voice Quality - Enhanced Voice Processing) con menor ruido ambiental, y provee una más rápida configuración de la comunicación con los otros dispositivos bluetooth dentro del rango del alcance, como pueden ser PDAs, HIDs (Human Interface Devices), computadoras portátiles, computadoras de escritorio, Headsets, impresoras y teléfonos móviles. La versión 2.0, creada para ser una especificación separada, principalmente incorpora la técnica "Enhanced Data Rate" (EDR) que le permite mejorar las velocidades de transmisión en hasta 3Mbps a la vez que intenta solucionar algunos errores de la especificación 1.2. La versión 2.1, simplifica los pasos para crear la conexión entre dispositivos, además el consumo de potencia es 5 veces menor. La versión 2.2 aumenta considerablemente la velocidad de transferencia. La idea es que el nuevo Bluetooth trabaje con WiFi, de tal manera que sea posible lograr mayor velocidad en los smartphones. 2.3.2. Arquitectura Bluetooth Empecemos nuestro análisis del sistema Bluetooth con un rápido vistazo de sus elementos y de su propósito. [5] La unidad básica de un sistema Bluetooth es una piconet, que consta de un nodo maestro y hasta siete nodos esclavos activos a una distancia de 10-100 metros. En un mismo espacio pueden encontrarse varias piconets y se pueden conectar mediante un nodo puente, como se muestra en la Ilustración 5. Un conjunto de piconets interconectadas se denomina scatternet. Proyecto fin de carrera 35 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 5: Esquema de una scatternet Bluetooth Para poder operar en todo el mundo es necesaria una banda de frecuencia abierta a cualquier sistema de radio independientemente del lugar del planeta donde nos encontremos. Sólo la banda ISM (médico-científica internacional) de 2,45Ghz cumple con éste requisito, con rangos que van de los 2.400Mhz a los 2.500Mhz, y solo con algunas restricciones en países como Francia, España y Japón. Debido a que la banda ISM está abierta a cualquiera, el sistema de radio Bluetooth deberá estar preparado para evitar las múltiples interferencias que se pudieran producir. Éstas pueden ser evitadas utilizando un sistema que busque una parte no utilizada del espectro o un sistema de salto de frecuencia. En los sistemas de radio Bluetooth se suele utilizar el método de salto de frecuencia debido a que ésta tecnología puede ser integrada en equipos de baja potencia y bajo coste. Éste sistema divide la banda de frecuencia en varios canales de salto, donde, los transceptores, durante la conexión van cambiando de uno a otro canal de salto de manera pseudo-aleatoria. Con esto se consigue que el ancho de banda instantáneo sea muy pequeño y también una propagación efectiva sobre el total de ancho de banda. En conclusión, con el sistema FH (Salto de frecuencia), se pueden conseguir transceptores de banda estrecha con una gran inmunidad a las interferencias. Además de los siete nodos esclavos activos de una piconet, puede haber hasta 255 nodos estacionados en la red. Estos son dispositivos que el nodo maestro ha cambiado a un estado de bajo consumo de energía para reducir el desgaste innecesario de sus pilas. Lo único que un dispositivo en estado estacionario puede hacer es responder a una señal de activación por parte del maestro. También hay dos estados intermedios, “hola” y “sniff”, pero no nos ocuparemos de ellos aquí. La razón para el diseño maestro/esclavo es que los diseñadores pretendían facilitar la implementación de chips Bluetooth completos por debajo de 5 dólares. La consecuencia de esta decisión es que los esclavos son sumamente pasivos y realizan todo lo que los maestros les indican. En esencia, una piconet es un sistema TDM centralizado, en el cual el maestro controla el Proyecto fin de carrera 36 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. reloj y determina qué dispositivos se comunica en un momento determinado. Todas las comunicaciones se realizan entre el maestro y el esclavo; no existe comunicación directa de esclavo a esclavo. 2.3.2.1. Esquema de transmisión Bluetooth utiliza un sistema FH/TDD (salto de frecuencia/división de tiempo duplex) [6], en el que el canal queda dividido en intervalos de 625µs, llamados slots, donde cada salto de frecuencia es ocupado por un slot. Esto da lugar a una frecuencia de salto de 1600 veces por segundo, en la que un paquete puede ocupar un slot para la emisión y otro para la recepción y que pueden ser usados alternativamente, dando lugar a un esquema de tipo TDD, Ilustración 6. Ilustración 6: Modelo sistema FH/TDD [6] Dos o más unidades Bluetooth pueden compartir el mismo canal dentro de una piconet, en donde una unidad actúa como maestra, controlando el tráfico de datos en la piconet que se genera entre las demás unidades, mientras el resto de unidades actúan como esclavas, enviando y recibiendo señales hacia el maestro. El salto de frecuencia del canal está determinado por la secuencia de la señal, es decir, el orden en que llegan los saltos y por la fase de ésta secuencia. En Bluetooth, la secuencia queda fijada por la identidad de la unidad maestra de la piconet (un código único para cada equipo), y por su frecuencia de reloj. Por lo que, para que una unidad esclava pueda sincronizarse con una unidad maestra, ésta primera debe añadir un ajuste a su propio reloj nativo y así poder compartir la misma portadora de salto, Ilustración 7. Proyecto fin de carrera 37 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 7: Ajuste del salto de frecuencia [6] En países donde la banda está abierta a 80 canales o más, espaciados todos ellos a 1Mhz, se han definido 79 saltos de portadora, y en aquellos donde la banda es más estrecha se han definido 23 saltos. 2.3.2.2. Definición de paquete El intercambio de información entre dos unidades Bluetooth se realiza mediante un conjunto de slots que forman un paquete de datos. Cada paquete comienza con un código de acceso de 72 bits, que se deriva de la identidad maestra, seguido de un paquete de datos de cabecera de 54 bits. Éste contiene importante información de control, como tres bits de acceso de dirección, tipo de paquete, bits de control de flujo, bits para la retransmisión automática de la pregunta, y chequeo de errores de campos de cabeza. Finalmente, el paquete que contiene la información, que puede seguir al de cabeza, tiene una longitud de 0 a 2745 bits. En cualquier caso, cada paquete que se intercambia en el canal está precedido por el código de acceso, Ilustración 8. Ilustración 8: Formato de paquete de datos Bluetooth [6] Los receptores de la piconet comparan las señales que reciben con el código de acceso, si éstas no coinciden, el paquete recibido no es considerado como válido en el canal y el resto de su contenido es ignorado. 2.3.2.3. Definición de enlace físico En la especificación Bluetooth se han definido dos tipos de enlace que permitan soportar incluso aplicaciones multimedia: Enlace de sincronización de conexión orientada (SCO) Enlace asíncrono de baja conexión (ACL) Proyecto fin de carrera 38 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Los enlaces SCO soportan conexiones asimétricas, punto a punto, usadas normalmente en conexiones de voz, estos enlaces están definidos en el canal, reservándose dos slots consecutivos (envío y retorno) en intervalos fijos. Los enlaces ACL soportan conmutaciones punto a punto simétricas o asimétricas, típicamente usadas en la transmisión de datos. Un conjunto de paquetes se han definido para cada tipo de enlace físico: Para los enlaces SCO, existen tres tipos de slot simple, cada uno con una portadora a una velocidad de 64 kbit/s. La transmisión de voz se realiza sin ningún mecanismo de protección, pero si el intervalo de las señales en el enlace SCO disminuye, se puede seleccionar una velocidad de corrección de envío de 1/3 o 2/3. Para los enlaces ACL, se han definido el slot-1, slot-3, slot-5. Cualquiera de los datos pueden ser enviados protegidos o sin proteger con una velocidad de corrección de 2/3. La máxima velocidad de envío es de 721 kbit/s en una dirección y 57.6 kbit/s en la otra. Como ya hemos comentado, las unidades maestras controlan el tráfico del canal, por lo que estas tienen la capacidad para reservar slots en los enlaces SCO. Para los enlaces ACL, se utiliza un esquema de sondeo. A una esclava sólo se le permite enviar un slot a un maestro cuando ésta se ha dirigido por su dirección MAC (medio de control de acceso) en el procedimiento de slot maestro-esclavo. Éste tipo de slot implica un sondeo por parte del esclavo, por lo que, en un tráfico normal de paquetes, este es enviado a una urna del esclavo automáticamente. Si la información del esclavo no está disponible, el maestro puede utilizar un paquete de sondeo para sondear al esclavo explícitamente. Los paquetes de sondeo consisten únicamente en uno de acceso y otro de cabecera. Éste esquema de sondeo central elimina las colisiones entre las transmisiones de los esclavos. 2.3.2.4. Inmunidad al ruido Como se mencionó anteriormente Bluetooth opera en una banda de frecuencia que está sujeta a considerables interferencias, por lo que el sistema ha sido optimizado para evitar éstas interferencias. En este caso La técnica de salto de frecuencia es aplicada a una alta velocidad y una corta longitud de los paquetes (1600 saltos/segundo, para slots-simples). Los paquetes de datos están protegido por un esquema ARQ (repetición automática de consulta), en el cual los paquetes perdidos son automáticamente retransmitidos, aun así, con este sistema, si un paquete de datos no llegase a su destino, sólo una pequeña parte de la información se perdería. La voz no se retransmite nunca, sin embargo, se utiliza un esquema de codificación muy robusto. Éste esquema, que está basado en una modulación variable de declive delta (CSVD), que sigue la forma de la onda de audio y es muy resistente a los errores de bits. Estos errores son percibidos como ruido de fondo, que se intensifica si los errores aumentan Proyecto fin de carrera 39 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. 2.3.2.5. Establecimiento de la conexión De un conjunto total de 79 (23) portadoras del salto, un subconjunto de 32(16) portadoras activas han sido definidas. El subconjunto, que es seleccionado pseudo-aleatoriamente, se define por una única identidad. Acerca de la secuencia de activación de las portadoras, se establece que, cada una de ellas visitará cada salto de portadora una sola vez, con una longitud de la secuencia de 32 (16) saltos. En cada uno de los 2.048 (1.028) saltos, las unidades que se encuentran en modo standby (en espera) mueven sus saltos de portadora siguiendo la secuencia de las unidades activas. El reloj de la unidad activa siempre determina la secuencia de activación. Durante la recepción de los intervalos, en los últimos 18 slots o 11,25 ms, las unidades escuchan una simple portadora de salto de activación y correlacionan las señales entrantes con el código de acceso derivado de su propia identidad. Si los triggers son correlativos, esto es, si la mayoría de los bits recibidos coinciden con el código de acceso, la unidad se auto-activa e invoca un procedimiento de ajuste de conexión. Sin embargo si estas señales no coinciden, la unidad vuelve al estado de reposo hasta el siguiente evento activo. Para establecer la piconet, la unidad maestra debe conocer la identidad del resto de unidades que están en modo standby en su radio de cobertura. El maestro o aquella unidad que inicia la piconet transmite el código de acceso continuamente en periodos de 10 ms, que son recibidas por el resto de unidades que se encuentran en standby. El tren de 10 ms. de códigos de acceso de diferentes saltos de portadora, se transmite repetidamente hasta que el receptor responde o bien se excede el tiempo de respuesta. Cuando una unidad emisora y una receptora seleccionan la misma portadora de salto, la receptora recibe el código de acceso y devuelve una confirmación de recibo de la señal, es entonces cuando la unidad emisora envía un paquete de datos que contiene su identidad y frecuencia de reloj actual. Después de que el receptor acepta éste paquete, ajustará su reloj para seleccionar el canal de salto correcto determinado por emisor. De éste modo se establece una piconet en la que la unidad emisora actúa como maestra y la receptora como esclava. Después de haber recibido los paquetes de datos con los códigos de acceso, la unidad maestra debe esperar un procedimiento de requerimiento por parte de las esclavas, diferente al proceso de activación, para poder seleccionar una unidad específica con la que comunicarse. El número máximo de unidades que pueden participar activamente en una simple piconet es de 8, un maestro y siete esclavos, por lo que la dirección MCA del paquete de cabecera que se utiliza para distinguir a cada unidad dentro de la piconet, se limita a tres bits. Proyecto fin de carrera 40 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. 2.3.2.6. Seguridad Para asegurar la protección de la información se ha definido un nivel básico de encriptación, que se ha incluido en el diseño del clip de radio para proveer de seguridad en equipos que carezcan de capacidad de procesamiento, las principales medidas de seguridad son: Una rutina de pregunta-respuesta, para autentificación. Una corriente cifrada de datos, para encriptación Generación de una clave de sesión (que puede ser cambiada durante la conexión) Tres entidades son utilizadas en los algoritmos de seguridad: La dirección de la unidad Bluetooth, que es una entidad pública. Una clave de usuario privada, como una entidad secreta. Un número aleatorio, que es diferente por cada nueva transacción. Como se ha descrito anteriormente, la dirección Bluetooth se puede obtener a través de un procedimiento de consulta. La clave privada se deriva durante la inicialización y no es revelada posteriormente. El número aleatorio se genera en un proceso pseudo-aleatorio en cada unidad Bluetooth. 2.3.3. Perfiles Bluetooth Para que un dispositivo pueda utilizar la tecnología inalámbrica Bluetooth, debe saber interpretar los perfiles Bluetooth, que describen las distintas aplicaciones posibles [3][4][5]. Estos perfiles son guías que indican los procedimientos por los que los dispositivos equipados con tecnología Bluetooth se comunican entre sí. Existe un amplio abanico de perfiles que detallan los diferentes tipos de uso y aplicaciones de la tecnología inalámbrica Bluetooth. Al seguir las directrices proporcionadas en las especificaciones Bluetooth, los desarrolladores pueden crear aplicaciones compatibles con otros dispositivos que se ajusten a este estándar. Cada perfil incluye, como mínimo, información sobre las siguientes cuestiones: Dependencia de otros perfiles Propuestas de formato de interfaz de usuario Características concretas de la pila de protocolos Bluetooth utilizada por el perfil. Para realizar su función, cada perfil se sirve de ciertas opciones y parámetros en cada capa de la pila. También se puede incluir un breve resumen de los servicios requeridos si resulta necesario. Proyecto fin de carrera 41 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. La siguiente lista muestra algunos de los perfiles más importantes del estándar y en las siguientes secciones capítulos se hará énfasis en los dos perfiles que vamos a utilizar en las aplicaciones del proyecto, SPP y HID. Advanced Audio Distribution Profile (A2DP) Distribución de audio avanzada. Define cómo se puede propagar un stream de audio (mono o estéreo) entre dispositivos a través de una conexión Bluetooth. Audio/Video Remote Control Profile (AVRCP) Control remoto de audio/video. Diseñado para ofrecer un interfaz estándar para el control de televisores y aparatos de música entre otros, de forma que un mando único pueda agrupar todo el control. Puede usarse junto con A2DP o VDP. Basic Imaging Profile (BIP) Tratamiento básico de imágenes. Diseñado para enviar imágenes, incluye capacidades de ajuste de tamaño y conversión a formatos adecuados. También puede dividir una imagen en trozos más pequeños. Basic Printing Profile (BPP) Impresión básica. Permite el envío de texto, e-mails y otros documentos a impresoras en base a trabajos de impresión. Es distinto a HCRP en que no requiere drivers específicos de impresora, lo que lo hace más apto para dispositivos móviles como cámaras y teléfonos, que no pueden actualizar drivers con sencillez. Common ISDN Access Profile (CIP) Acceso común a ISDN. Provee acceso ilimitado a los servicios de ISDN. Cordless Telephony Profile (CTP) Telefonía sin cables. Permite que los teléfonos inalámbricos utilicen Bluetooth. Se espera que los teléfonos puedan utilizarlo para comunicarse con la línea de teléfono dentro de una casa, y con la red de telefonía móvil cuando no esté disponible (fuera de casa). Device ID Profile (DID) Identificación de dispositivo. Permite a un dispositivo ofrecer identificación más allá de la clasificación en tipo de dispositivo de acuerdo con la versión, fabricante, producto y revisión de la especificación. Podría utilizarse para permitir a un ordenador conectarse a un dispositivo y descargar los drivers necesarios. Sus capacidades son semejantes a las de la especificación de plug and play. Dial-up Networking Profile (DUN) Conexión a red por dial-up o línea conmutada. El caso de uso típico es el de un portátil accediendo a Internet por medio de la línea de un teléfono móvil. Se basa en SPP y permite un funcionamiento razonablemente sencillo con productos existentes, en base a su similitud con los Proyecto fin de carrera 42 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. protocolos de línea serie (serial line Internet protocol). Incluye entre otros el protocolo PPP. Fax Profile (FAX) Fax. Busca ofrecer una interfaz bien definida entre un teléfono móvil o fijo y un ordenador con software de fax. Debe darse soporte al comando AT definido en ITU T.31 o ITU T.32, definidos por ITU-T. No cubre llamadas de voz o datos. File Transfer Profile (FTP) Transferencia de ficheros. Da acceso remoto a los sistemas de ficheros, permitiendo listados de directorios y cambios a éstos, obtención, envío y borrado de ficheros. Se basa en GOEP y utiliza OBEX como transporte. General Audio/Video Distribution Profile (GAVDP) Distribución general de audio/video. Base de A2DP y VDP. Generic Access Profile (GAP) Acceso genérico. Es la base para todos los demás perfiles. Generic Object Exchange Profile (GOEP) Intercambio genérico de objetos. Sirve como base para otros perfiles de datos, y se basa a su vez en OBEX. Hard Copy Cable Replacement Profile (HCRP) Reemplazo de cables. Es una alternativa a una conexión cableada entre un dispositivo y una impresora, aunque no fija un estándar de comunicación con la impresora, por lo que necesita drivers concretos para la impresora que se utiliza, lo que reduce su utilidad en dispositivos sencillos que no suelan disponer de drivers. Hands-Free Profile (HFP) Manos libres. Usado comúnmente para permitir la comunicación con teléfonos móviles dentro de un coche. Utiliza SCO para transportar un canal de audio mono por medio de PCM. Su versión actual es la 1.5. Es un perfil integrado desde hace tiempo en muchos automóviles de fábrica. Human Interface Device Profile (HID) Dispositivo de interfaz humana. Da soporte a dispositivos tales como ratones, joysticks y teclados. También puede utilizarse para indicadores luminosos o botones en otros tipos de dispositivos. Se ha diseñado para ofrecer un enlace de baja latencia manteniendo bajo el consumo. HID es un wrapper ligero del protocolo original definido para USB. Su uso simplifica la implementación del anfitrión (en concreto, el soporte de USB es reutilizable para Bluetooth en sistemas operativos). Últimamente se ha utilizado en los mandos de las consolas Wii y PS3. Headset Profile (HSP) Proyecto fin de carrera 43 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Auriculares. Uno de los perfiles más comunes, que permiten el uso de los auriculares Bluetooth (BT headsets) con los teléfono móviles. Utiliza SCO para transportar audio a 64 kbps codificado con CVSD o PCM y un subconjunto de comandos AT de GSM 07.07 para dar facilidades sencillas como tono, respuesta, colgado y ajuste de volumen. Object Push Profile (OPP) Un perfil básico para el envío de “objetos” genéricos como fotos, tarjetas virtuales (Vcard) o citas. Sigue el modelo push ya que el emisor es el que inicia siempre la comunicación. Utiliza las API's de OBEX para las operaciones de conexión y desconexión, envío, recepción y cancelación. Situándose por encima de OBEX sigue indirectamente la especificación de la pila Bluetooth. Personal Area Networking Profile (PAN) Redes de área personal. Permite el uso del protocolo de encapsulación de Bluetooth en protocolos de nivel de red sobre un enlace Bluetooth. Phone Book Access Profile (PBAP) Acceso a agenda de teléfonos. Permite el envío de agendas telefónicas entre dispositivos. Puede utilizarse, por ejemplo, para enviar desde un móvil a una pantalla (por ejemplo, de coche en un manos libres) los datos de una llamada. Serial Port Profile (SPP) Puerto serie. Basado en la especificación 07.10 de ETSI por medio del protocolo RFCOMM. Emula una línea serie y provee un interfaz de reemplazo de comunicaciones basadas en RS-232, con las señales de control típicas. Base de DUN, FAX, HSP y AVRCP. Service Discovery Profile (SDAP) Descubrimiento de servicios. SIM Access Profile (SAP, SIM) Acceso a SIM. Permite que los dispositivos compatibles con GSM como teléfonos puedan conectarse a una tarjeta SIM de forma que un teléfono “esclavo” (como el de un coche) no necesite una tarjeta propia. Synchronisation Profile (SYNCH) Sincronización. Se origina como parte de las especificaciones de infrarrojo pero ha sido seleccionado para pasar a formar parte de la especificación principal. También conocido como IrMC Synchronization. Video Distribution Profile (VDP) Distribución de vídeo. Habilita el transporte de un stream de vídeo. Puede usarse para distribuir un vídeo grabado desde cualquier fuente a Proyecto fin de carrera 44 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. un reproductor o televisor. Debe soportar H.263, y opcionalmente MPEG-4 y los perfiles 3 y 8 de H.263. Wireless Application Protocol Bearer (WAPB) Portador de protocolos de aplicación inalámbrica. Permite el transporte de WAP sobre PPP, a su vez sobre Bluetooth. 2.3.3.1. HID (Dispositivos de Interfaz Humana) El perfil HID recoge los protocolos, procedimientos y características empleados por las interfaces de usuario Bluetooth tales como teclados, dispositivos punteros, consolas o aparatos de control remoto [3][4]. La situación de uso más habitual es un escritorio inalámbrico, dispositivos móviles y dispositivos de juegos: Teclado, ratón, presentador inalámbrico, dispositivos de juego, tableta gráfica, PC, portátil, teléfono móvil, PDA, etc. El HID define dos roles, el de dispositivo de interfaz humana (HID) y el de anfitrión. El dispositivo de interfaz humana es el dispositivo que proporciona el servicio de entrada y salida de datos de procedencia humana desde y hacia el anfitrión. Y por otro lado el anfitrión es el dispositivo que usa o solicita los servicios de un dispositivo de interfaz humana. Este perfil utiliza la definición de dispositivo HID del bus de serie universal (USB) para aprovechar los controladores de clase para dispositivos USB. Indica, igualmente, cómo utilizar el protocolo HID de USB para identificar las funciones del dispositivo de clase HID y cómo los dispositivos Bluetooth pueden utilizar los servicios HID a través de la capa L2CAP. Está diseñado para permitir la inicialización y el control de los dispositivos que se describen a sí mismos, además de para proporcionar un enlace con baja latencia y requisitos de potencia mínimos. El perfil HID de Bluetooth se basa en el perfil de acceso genérico (GAP), especificado en el documento de perfiles de Bluetooth. Para simplificar al máximo su introducción, el protocolo HID funciona de forma nativa en L2CAP y no recicla protocolos Bluetooth, aparte del perfil de descubrimiento de servicios. La Ilustración 9 es un ejemplo de implementación de las capas de software que residen tanto en el anfitrión como en el dispositivo de interfaz humana. En este ejemplo, el anfitrión es un ordenador personal con las capas superiores de software Bluetooth ejecutándose en su procesador nativo, y está conectado a un módulo de radio Bluetooth a través de un bus de transporte, como USB. El HID de este ejemplo tiene su firmware integrado en el firmware de radio, ejecutándose en la misma CPU, para reducir al máximo el coste de implementación. Proyecto fin de carrera 45 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 9: Capas de software que residen tanto en el anfitrión como en el dispositivo HID 2.3.3.2. SPP (Perfil de Puerto Serie) A la hora de crear un puerto serie virtual en un enlace bluetooth debemos hacer uso del perfil SPP (Serial Port Profile), este nos permite establecer un puerto serie virtual a partir de las capacidades de conectividad de las capas bajas de Bluetooth. Lo que nos permite esta capacidad de Bluetooth es indicarle al dispositivo al que se conecte que tiene una conexión que puede utilizar a partir de ahora y que presenta las mismas características que un puerto serie convencional, con las ventajas que esto representa a la hora de trabajar con hardware o software que utilizase uno de estos puertos [3][4]. El perfil SPP define dos roles: Dispositivo A – Este es el dispositivo que toma la iniciativa de establecer la conexión con el otro dispositivo (iniciador). Dispositivo B – Este es el dispositivo que espera a que otro tome la iniciativa de crear la conexión (aceptor). La estructura de capas de emulación de puertos mostrada en la Ilustración 10 es la entidad que emula el puerto de serie, o que proporciona un API a las aplicaciones. Proyecto fin de carrera 46 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. . Ilustración 10: Modelo de capas del perfil SPP Banda base, LMP y L2CAP son los protocolos Bluetooth de la capa 1 y 2 de OSI. RFCOMM es la adaptación de GSM TS 07.10 a Bluetooth y proporciona un protocolo de transporte para la emulación de puertos de serie. SDP es el protocolo de descubrimiento de servicios Bluetooth. Las aplicaciones de ambas partes son normalmente aplicaciones heredadas que se desea comunicar a través de un cable de serie (que en este caso se emula) y con capacidad para ello. Pero las aplicaciones heredadas no reconocen los procedimientos Bluetooth para la configuración de cables de serie emulados, por lo que necesitan la ayuda de algún tipo de aplicación compatible con Bluetooth en ambos lados (estos problemas no se tratan de forma explícita en este perfil, que se ocupa fundamentalmente de la interoperabilidad Bluetooth). 2.4. Symbian 2.4.1. Introducción a Symbian Symbian OS es un sistema operativo propietario diseñado para dispositivos móviles con librerías asociadas, producido por Symbian Ltd. Es un descendiente directo de EPOC de Psion y corre exclusivamente en procesadores ARM. Para competir contra Palm y contra el Smartphone de Microsoft, empresas líderes en telefonía móvil, como Nokia®, Siemens®, Fujitsu®, Arima®, Samsung®, LG®, Mitsubishi Electric®, Panasonic®, Motorola®, Lenovo®, Sharp®, Benq®, Sony Ericsson® formaron en 1998 una alianza fruto de la cual crearon la empresa Symbian; su principal objetivo era desarrollar un sistema operativo abierto para las diversas plataformas de teléfonos móviles. Así llego el Sistema Operativo Symbian, un sistema operativo multitarea diseñado específicamente para dispositivos móviles. Proyecto fin de carrera 47 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 11: Logotipo de SymbianOS y empresas que conformaron el SIG inicial A diferencia de un PC convencional la programación de los teléfonos móviles tiene grandes limitaciones es por esto que Symbian está diseñado de manera específica para este tipo de dispositivos y presenta unas características que lo hacen ciertamente particular [7]: Diseñado para residir en un espacio de memoria muy pequeño. Hacer un uso dinámico de escasos recursos de memoria. Administrar eficientemente la energía. Soportar en tiempo real los protocolos de comunicación y telefonía Además de lo anteriormente citado debe de tratarse de un sistema muy “gentil” con el usuario y tolerante a fallos, en comparación con un sistema operativo de PC. Por ejemplo: cuando se le quita la batería al teléfono mientras está encendido, el usuario esperaría que su información se encuentre íntegra al volver a activarlo, y no tener en ningún momento la preocupación de que sus datos guardados se hayan perdido o peor, que el teléfono deje de funcionar porque el sistema operativo se dañó debido el corte de energía. Además toda la programación del OS Symbian está basada en eventos y el CPU está en “OFF” cuando las aplicaciones no están directamente conectadas con un evento [8]. Esto se consigue a través de un programa llamado Objetos Activos (Active Objects). El uso correcto de estas técnicas ayuda a asegurar una larga vida de la batería y también de esta manera los programadores pueden depurar que cantidad de energía consumen sus aplicaciones. Symbian soporta respuesta en tiempo real suficientemente rápida, tanto que es posible construir un teléfono de núcleo sencillo alrededor de este, un Proyecto fin de carrera 48 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. teléfono con un solo procesador ejecuta tanto las aplicaciones de usuario como las compilaciones de señal. Esta no es una característica disponible en Linux o Windows CE. Sin embargo, sí que lo soporta el OS symbian EKA2 para hacerlos mas pequeños, baratos y con características más eficientes [7]. Técnicamente, el sistema operativo Symbian es una colección compacta de código ejecutable y varios archivos, la mayoría de ellos son bibliotecas vinculadas dinámicamente (DLL por sus siglas en inglés) y otros datos requeridos, incluyendo archivos de configuración, de imágenes y de tipografía, entre otros recursos residentes. Symbian se almacena, generalmente, en un dispositivo flash dentro del dispositivo móvil. Gracias a este tipo de tecnología, se puede conservar información aún si el sistema no posee carga eléctrica en la batería, además de que es factible reprogramar la memoria sin necesidad de separarla de los demás circuitos. Las aplicaciones compatibles con Symbian se desarrollan a partir de lenguajes de programación orientados a objetos como C++, Java (con sus variantes como PJava, J2ME, etc.), Visual Basic para dispositivos móviles, entre otros, incluyendo algunos lenguajes disponibles en versión libre. La extensa variedad de aplicaciones que se pueden desarrollar van desde administradores de archivos hasta visualizadores de películas, guías de ciudades, mapas, diccionarios, emuladores de juegos, por mencionar algunas. Cada aplicación se puede instalar en el teléfono con la ayuda de una computadora, una interfaz USB o firewire, dependiendo del modelo de teléfono y el cable correspondiente. Las aplicaciones se graban en la memoria flash del teléfono dentro del proceso de sincronización de archivos, contactos y correos electrónicos. Symbian es actualizable. Esta tarea puede realizarla el usuario, dependiendo del modelo de su equipo, a través de los sitios en Internet de los fabricantes de teléfonos o bien, al obtener el disco compacto o tarjeta de memoria flash de los distribuidores autorizados. Adicionalmente, Symbian proporciona una interfaz gráfica fácil de comprender, llena de íconos y opciones, con lo cual se evita que el usuario deba aprender manuales inmensos para explotar las capacidades de su equipo de comunicación móvil. Paradójicamente, Symbian también es vulnerable a los virus que afectan a computadoras personales y asistentes digitales (PDA). La manera más común de contagio es cuando el aparato está en comunicación con algún otro dispositivo contaminado en la red local (si el teléfono es compatible con la norma IEEE 802.11) o en la red personal (si es compatible con Bluetooth). Menos frecuente es la infección por mensajes cortos (MMS); sin embargo, estos virus pueden bloquear aplicaciones e incluso el sistema de archivos, no obstante, también hay métodos para prevenirlos y eliminarlos instalando programas antivirus. Symbian contiene una muy variada y extensa colección de bibliotecas para implementar muchos de los estándares de la industria de teléfonos de Proyecto fin de carrera 49 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. generación 2, 2.5 y 3. En la capa de software de sistema, en su versión 6, incluye soporte de distintos servicios, como los que se muestran en la siguiente tabla, Tabla 14. Entorno Servicios Redes TCP/IP, SSL, FTP, etcétera. Comunicaciones Bluetooth, WiFi Telefonía GSM, GPRS, CDMA2000, EDGE, WCDMA HTML, HTTPS, WAP Navegadores de Internet Multimedia WAV, JPEG, MP3, etc. Tabla 14: Servicios soportados por el OS Symbian en la versión 6 Lo anterior, coloca a Symbian en un sistema muy completo, diseñado prácticamente para cualquier dispositivo móvil. Además de la gran comunidad de desarrolladores que trabajan en este sistema, su plataforma abierta permite la instalación de una gran variedad de programas que poco a poco mejorarán su funcionamiento, a favor de la versatilidad de las comunicaciones personales. 2.4.2. Arquitectura Como venimos comentando en este texto el sistema operativo Symbian está pensado para trabajar sobre dispositivos con grandes restricciones, especialmente energéticas. En estos casos el sistema operativo proporciona una API que permite el desarrollo de aplicaciones en un lenguaje nativo para Symbian, que como se ve en la Ilustración 12, se apoyaría directamente sobre la plataforma de servicios desarrollada específicamente para la arquitectura del dispositivo que empleemos sobre el sistema operativo. Por último también existe la posibilidad de trabajar con Java sobre Symbian, pero para ello necesitaremos encontrar una máquina virtud apropiada para el hardware con el que estemos trabajando. Como veremos más adelante esta es la opción que emplearemos en este proyecto y por lo tanto más adelante detallaremos los requisitos técnicos de este tipo de arquitecturas. Proyecto fin de carrera 50 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 12: Diagrama esquemático de la arquitectura de la plataforma S60 [7] 2.4.2.1. Arquitectura software Vamos a comentar a continuación la arquitectura software que nos permite ejecutar aplicaciones en Symbian ya sean desarrolladas en lenguaje nativo para este sistema operativo o aplicaciones desarrolladas para una máquina virtual Java. Ilustración 13: Arquitectura software Symbian simplificada Comenzamos con el nivel más bajo o interno de los componentes base de Symbian OS. Esto incluye el núcleo, más concretamente micronúcleo, kernel-EKA1 o EKA2, y la librería de usuario que permite al usuario utilizar programas que hagan peticiones al núcleo. Esta librería contiene un programador y un administrador de memoria, pero no tiene soporte para el sistema de archivos. Esta función es proveída del lado del servidor del usuario (o sea las compañías que comercializan con Symbian o en general cualquiera que desarrolle programas para Symbian). La capa base, es decir inmediatamente superior al núcleo, incluye el servidor de archivos, que provee una vista muy semejante a DOS de los sistemas de archivo del dispositivo (una letra de directorio, y las diagonales invertidas son usadas para delimitar las carpetas). Symbian OS soporta varios tipos de sistemas de archivos incluyendo Proyecto fin de carrera 51 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. FAT32 y el sistema especifico de Symbian de almacenamiento (flash) llamado NOR. Los sistemas de archivos no son expuestos generalmente al usuario a través de la interfaz de usuario de teléfono (por eso usamos programas administradores de archivos que nos dejen ingresar y modificar los directorios ocultos). Inmediatamente encima de la base están una selección de librerías de sistema, una base de datos DMBS y el sistema de manejo de los archivos de recursos. Por causa de estas capas el software no es completamente legible si no está compilado para la versión específica de Symbian. En la Ilustración 14 se muestra arquitectura del sistema operativo Symbian según la descripción que se encuentra en la bibliografía [7] Ilustración 14: Arquitectura software Symbian detallada En la capa de servicios del sistema operativo existen tres servidores principales-ETEL (telefonía EPOC), ESOCK (tomas o enchufes-sockets-de EPOC) y C32 (responsable de la comunicación serial). Cada uno de estos permite una combinación de plugins, por ejemplo ESOCK permite diferentes módulos de protocolos PRT implementando diferentes tipos de combinaciones de protocolos de red. El subsistema también contiene códigos referentes a comunicaciones de corto rango tales como Bluetooth, Infrarrojo (IrDA) y USB. Existe también un largo volumen de “interfaz de usuario (User InterfaceUI-Code), aunque la mayor parte de la interfaz de usuario es actualmente mantenida por terceros (los conocidos como third parties), sin embargo las clases base y la subestructura están ya contenidas en Symbian OS, este componente es conocido como UIKON. El Symbian Os también contiene los gráficos, el trazado del texto y las librerías de render de la fuente. La arquitectura de una aplicación Symbian de manera Standard contiene embebidos una capa de la aplicación, un archivo (la aplicación en sí) y el sistema de reconocimiento de datos. Symbian Os también contiene una selección de “motores de aplicación” utilizables fácilmente para aplicaciones populares de los teléfonos inteligentes tales como calendarios, agendas y listas de tareas. Una aplicación Symbian típicamente está compuesta por un motor Proyecto fin de carrera 52 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. DLL y una aplicación gráfica, la aplicación en sí es un muy delgado envoltorio sobre el motor DLL, Symbian OS provee la mayoría de estos motores DLL en su arquitectura. Existen por supuesto muchas otras cosas que no están integradas en este modelo (Symbian OS)-por ejemplo Sync ML, JavaME, los cuales proveen otra serie de API’s a la mayoría de los sistemas operativos en el mercado y aparatos multimedia. Con algunos de estos se han logrado acuerdos que no son hechos directamente por Symbian Ltd. sino por los fabricantes de teléfonos, en algunos casos de estos marcos (frameworks) se han tratado de suplir con plugins de terceras partes (por ejemplo, Helix Player para los codecs multimedia). 2.4.3. J2ME En la sección anterior hablamos de la arquitectura del sistema operativo Symbian y de cómo es posible desarrollar aplicaciones en código nativo que se integren con las capas bajas de la arquitectura. También hemos hablado de la posibilidad de desarrollar aplicaciones sobre Java que se integren en el sistema operativo. Pero la versión estándar de Java no se puede emplear en este tipo de dispositivos por razones que ahora veremos, en lugar de esta debemos emplear la conocida como J2ME que vamos a comentar a partir de ahora. Sun, dispuesto a proporcionar las herramientas necesarias para cubrir las necesidades de todos los usuarios, creó distintas versiones de Java de acuerdo a las necesidades de cada uno. Según esto nos encontramos con que el paquete Java 2 lo podemos dividir en 3 ediciones distintas. J2SE (Java Standard Edition) orientada al desarrollo de aplicaciones independientes de la plataforma, J2EE (Java Enterprise Edition) orientada al entorno empresarial y J2ME (Java Micro Edition) orientada a dispositivos con capacidades restringidas [9]. Java 2 Platform, Micro Edition (J2ME): Esta versión de Java está enfocada a la aplicación de la tecnología Java en dispositivos electrónicos con capacidades computacionales y gráficas muy reducidas, tales como teléfonos móviles, PDAs o electrodomésticos inteligentes. Esta edición tiene unos componentes básicos que la diferencian de las otras versiones, como el uso de una máquina virtual denominada KVM (Kilo Virtual Machine, debido a que requiere sólo unos pocos Kilobytes de memoria para funcionar) en vez del uso de la JVM clásica, inclusión de un pequeño y rápido recolector de basura y otras diferencias que ya iremos viendo más adelante. Proyecto fin de carrera 53 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 15: Arquitectura de la plataforma Java 2 de Sun En la actualidad no es realista ver Java como un simple lenguaje de programación, más bien podemos hablar de una serie de tecnologías que abarca a todos los ámbitos de la computación con dos elementos en común: El código fuente en lenguaje Java es compilado a código intermedio interpretado por una Java Virtual Machine (JVM), por lo que el código ya compilado es independiente de la plataforma. Todas las tecnologías comparten un conjunto más o menos amplio de APIs básicas del lenguaje, agrupadas principalmente en los paquetes java.lang y java.io. Un claro ejemplo de éste último punto es que J2ME contiene una mínima parte de las APIs de Java. Esto es debido a que la edición estándar de APIs de Java ocupa 20 Mb, y los dispositivos pequeños disponen de una cantidad de memoria mucho más reducida. En concreto, J2ME usa 37 clases de la plataforma J2SE provenientes de los paquetes java.lang, java.io, java.util. Esta parte de la API que se mantiene fija forma parte de lo que se denomina “configuración” y ya hablaremos de ella más extensamente. Otras diferencias con la plataforma J2SE vienen dadas por el uso de una máquina virtual distinta de la clásica JVM denominada KVM. Esta KVM tiene unas restricciones que hacen que no posea todas las capacidades incluidas en la JVM. Estas Proyecto fin de carrera 54 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. diferencias las veremos más detenidamente capacidades de la KVM en el siguiente apartado. cuando analicemos las 2.4.3.1. Características básicas de J2ME Ya hemos visto qué es Java Micro Edition y la hemos enmarcado dentro de la plataforma Java2. En este apartado vamos a ver cuáles son los componentes que forman parte de esta tecnología. Por un lado tenemos una serie de máquinas virtuales Java con diferentes requisitos, cada una para diferentes tipos de pequeños dispositivos. Configuraciones, que son un conjunto de clases básicas orientadas a conformar el corazón de las implementaciones para dispositivos de características específicas. Existen 2 configuraciones definidas en J2ME: o Connected Limited Device Configuration (CLDC) enfocada a dispositivos con restricciones de procesamiento y memoria, y Connected Device Configuration (CDC) enfocada a dispositivos con más recursos. o Perfiles, que son unas bibliotecas Java de clases específicas orientadas a implementar funcionalidades de más alto nivel para familias específicas de dispositivos. Un entorno de ejecución determinado de J2ME se compone entonces de una selección de: a) Máquina virtual. b) Configuración. c) Perfil. d) Paquetes Opcionales. La arquitectura de un entorno de ejecución la podemos ver en la Ilustración 16. A continuación estudiaremos en profundidad cada uno de estos tres componentes. 2.4.3.2. Máquinas Virtuales J2ME Una máquina virtual de Java (JVM) es un programa encargado de interpretar código intermedio (bytecode) de los programas Java precompilados a código máquina ejecutable por la plataforma, efectuar las llamadas pertinentes al sistema operativo subyacente y observar las reglas de seguridad y corrección de código definidas para el lenguaje Java. De esta forma, la JVM proporciona al programa Java independencia de la plataforma con respecto al hardware y al sistema operativo subyacente [10]. Las implementaciones 55 Proyecto fin de carrera Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. tradicionales de JVM son, en general, muy pesadas en cuanto a memoria ocupada y requerimientos computacionales. J2ME define varias JVMs de referencia adecuadas al ámbito de los dispositivos electrónicos que, en algunos casos, suprimen algunas características con el fin de obtener una implementación menos exigente. Ilustración 16: Entorno de ejecución de J2ME Ya hemos visto que existen 2 configuraciones CLDC y CDC, cada una con unas características propias que veremos en profundidad más adelante. Como consecuencia, cada una requiere su propia máquina virtual. La VM (Virtual Machine) de la configuración CLDC se denomina KVM y la de la configuración CDC se denomina CVM. Veremos a continuación las características principales de cada una de ellas: KVM Se corresponde con la Máquina Virtual más pequeña desarrollada por Sun. Su nombre KVM proviene de Kilobyte (haciendo referencia a la baja ocupación de memoria, entre 40Kb y 80Kb). Se trata de una implementación de Máquina Virtual reducida y especialmente orientada a dispositivos con bajas capacidades computacionales y de memoria. La KVM está escrita en lenguaje C, aproximadamente unas 24000 líneas de código, y fue diseñada para ser: o Pequeña, con una carga de memoria entre los 40Kb y los 80 Kb, dependiendo de la plataforma y las opciones de compilación. o Alta portabilidad. o Modulable. o Lo más completa y rápida posible y sin sacrificar características para las que fue diseñada. Proyecto fin de carrera 56 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Sin embargo, esta baja ocupación de memoria hace que posea algunas limitaciones con respecto a la clásica Java Virtual Machine (JVM): 1. No hay soporte para tipos en coma flotante. No existen por tanto los tipos double ni float. Esta limitación está presente porque los dispositivos carecen del hardware necesario para acelerar estas operaciones. 2. No existe soporte para JNI (Java Native Interface) debido a los recursos limitados de memoria. 3. No existen cargadores de clases (class loaders) definidos por el usuario. Sólo existen los predefinidos. 4. No se permiten los grupos de hilos o hilos daemon. Cuándo queramos utilizar grupos de hilos utilizaremos los objetos Colección para almacenar cada hilo en el ámbito de la aplicación. 5. No existe la finalización de instancias de clases. No existe el método Object.finalize(). 6. No hay referencias débiles. 7. Limitada capacidad para el manejo de excepciones debido a que el manejo de éstas depende en gran parte de las APIs de cada dispositivo por lo que son éstos los que controlan la mayoría de las excepciones. Aparte de la no inclusión de estas características, la verificación de clases merece un comentario aparte. El verificador de clases estándar de Java es demasiado grande para la KVM. De hecho es más grande que la propia KVM y el consumo de memoria es excesivo, más de 100Kb para las aplicaciones típicas. Este verificador de clases es el encargado de rechazar las clases no válidas en tiempo de ejecución. Este mecanismo verifica los bytecodes de las clases Java realizando las siguientes comprobaciones: Ver que el código no sobrepase los límites de la pila de la VM. Comprobar que no se utilizan las variables locales antes de ser inicializadas. Comprobar que se respetan los campos, métodos y los modificadores de control de acceso a clases. Proyecto fin de carrera 57 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 17: Preverificación de clases en CDLC/KVM. Por esta razón los dispositivos que usen la configuración CLDC y KVM introducen un algoritmo de verificación de clases en dos pasos. Este proceso puede apreciarse gráficamente en la Ilustración 17. 2.4.3.2.1. Configuraciones Una configuración es el conjunto mínimo de APIs Java que permiten desarrollar aplicaciones para un grupo de dispositivos. Éstas APIs describen las características básicas, comunes a todos los dispositivos: Características soportadas del lenguaje de programación Java. Características soportadas por la Máquina Virtual Java. Bibliotecas básicas de Java y APIs soportadas. Como ya hemos visto con anterioridad, existen dos configuraciones en J2ME: CLDC, orientada a dispositivos con limitaciones computacionales y de memoria y CDC, orientada a dispositivos con no tantas limitaciones. Ahora veremos un poco más en profundidad la configuración CLDC que es la vamos a utilizar en este proyecto. Configuración de dispositivos limitados con conexión, CLDC (Connected Limited Device Configuration). La CLDC está orientada a dispositivos dotados de conexión y con limitaciones en cuanto a capacidad gráfica, cómputo y memoria. Un ejemplo de estos dispositivos son: teléfonos móviles, buscapersonas (pagers), PDAs, organizadores personales, etc. Proyecto fin de carrera 58 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ya hemos dicho que CLDC está orientado a dispositivos con ciertas restricciones. Algunas de estas restricciones vienen dadas por el uso de la KVM, necesaria al trabajar con la CLDC debido a su pequeño tamaño. Los dispositivos que usan CLDC deben cumplir los siguientes requisitos: o Disponer entre 160 Kb y 512 Kb de memoria total disponible. Como mínimo se debe disponer de 128 Kb de memoria no volátil para la Máquina Virtual Java y las bibliotecas CLDC, y 32 Kb de memoria volátil para la Máquina Virtual en tiempo de ejecución. o Procesador de 16 o 32 bits con al menos 25 Mhz de velocidad. o Ofrecer bajo consumo, debido a que estos dispositivos trabajan con suministro de energía limitado, normalmente baterías. o Tener conexión a algún tipo de red, normalmente sin cable, con conexión intermitente y ancho de banda limitado (unos 9600 bps). La CLDC aporta las siguientes funcionalidades a los dispositivos: o Un subconjunto del lenguaje Java y todas las restricciones de su Máquina Virtual (KVM). o Un subconjunto de las bibliotecas Java del núcleo. o Soporte para E/S básica. o Soporte para acceso a redes. o Seguridad. La Tabla 15: Librerías de configuración CLDC. Nos muestra las librerías incluidas en la CLDC. Nombre del paquete CLDC Descripción java.io Clases y paquetes estándar de E/S. Subconjunto de J2SE. java.lang Clases e interfaces de la Máquina Virtual. Subconj. de J2SE. Clases, interfaces y utilidades estándar. Subconj. de J2SE. Clases e interfaces de conexión genérica CLDC java.util javax.microedition.io Tabla 15: Librerías de configuración CLDC. Proyecto fin de carrera 59 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Un aspecto muy a tener en cuenta es la seguridad en CLDC. Esta configuración posee un modelo de seguridad sandbox al igual que ocurre con los applets. En cualquier caso, una determinada Configuración no se encarga del mantenimiento del ciclo de vida de la aplicación, interfaces de usuario o manejo de eventos, sino que estas responsabilidades caen en manos de los perfiles. 2.4.3.2.2. Perfiles Acabamos de decir que el perfil es el que define las APIs que controlan el ciclo de vida de la aplicación, interfaz de usuario, etc. Más concretamente, un perfil es un conjunto de APIs orientado a un ámbito de aplicación determinado. Los perfiles identifican un grupo de dispositivos por la funcionalidad que proporcionan (electrodomésticos, teléfonos móviles, etc.) y el tipo de aplicaciones que se ejecutarán en ellos. Las librerías de la interfaz gráfica son un componente muy importante en la definición de un perfil. Aquí nos podemos encontrar grandes diferencias entre interfaces, desde el menú textual de los teléfonos móviles hasta los táctiles de los PDAs. El perfil establece unas APIs que definen las características de un dispositivo, mientras que la configuración hace lo propio con una familia de ellos. Esto hace que a la hora de construir una aplicación se cuente tanto con las APIs del perfil como de la configuración. Tenemos que tener en cuenta que un perfil siempre se construye sobre una configuración determinada. De este modo, podemos pensar en un perfil como un conjunto de APIs que dotan a una configuración de funcionalidad específica. Ya hemos visto los conceptos necesarios para entender cómo es un entorno de ejecución en Java Micro Edition. Este entorno de ejecución se estructura en capas, una construida sobre la otra como veíamos en la figura 3. Anteriormente vimos que para una configuración determinada se usaba una Máquina Virtual Java específica. Teníamos que con la configuración CDC usábamos la CVM y que con la configuración CLDC usábamos la KVM. Con los perfiles ocurre lo mismo. Existen unos perfiles que construiremos sobre la configuración CDC y otros que construiremos sobre la CLDC. Para la configuración CDC tenemos los siguientes perfiles: Foundation Profile. Personal Profile. RMI Profile. Proyecto fin de carrera 60 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 18: Arquitectura del entorno de ejecución de J2ME. Por otro lado para la configuración CLDC tenemos los siguientes: PDA Profile. Mobile Information Device Profile (MIDP). En la Ilustración 18 se puede ver cómo quedaría el esquema del entorno de ejecución al completo. Un perfil puede ser construido sobre cualquier otro. Sin embargo, una plataforma J2ME sólo puede contener una configuración. PDA Profile: El PDA Profile está construido sobre CLDC. Pretende abarcar PDAs de gama baja, tipo Palm, con una pantalla y algún tipo de puntero (ratón o lápiz) y una resolución de al menos 20000 pixels (al menos 200x100 pixels) con un factor 2:1. Mobile Information Device Profile (MIDP): Este perfil está construido sobre la configuración CLDC. Al igual que CLDC fue la primera configuración definida para J2ME, MIDP fue el primer perfil definido para esta plataforma. Este perfil está orientado para dispositivos con las siguientes características: o Reducida capacidad computacional y de memoria. o Conectividad limitada (en torno a 9600 bps). o Capacidad gráfica muy reducida (mínimo un display de 96x54 pixels monocromo). o Entrada de datos alfanumérica reducida. Proyecto fin de carrera 61 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. o 128 Kb de memoria no volátil para componentes MIDP. o 8 Kb de memoria no volátil para datos persistentes de aplicaciones. o 32 Kb de memoria volátil en tiempo de ejecución para la pila Java. Los tipos de dispositivos que se adaptan a estas características son: teléfonos móviles, buscapersonas (pagers) o PDAs de gama baja con conectividad. El perfil MIDP establece las capacidades del dispositivo, por lo tanto, especifica las APIs relacionadas con: o La aplicación (semántica y control de la aplicación MIDP). o Interfaz de usuario. o Almacenamiento persistente. o Trabajo en red. o Temporizadores. En la Tabla 16 podemos ver cuáles son los paquetes que están incluidos en el perfil MIDP. Paquetes del MIDP Descripción javax.microedition.lcdui Clases e interfaces para GUIs javax.microedition.rms Record Management Storage. Soporte para el almacenamiento persistente del dispositivo javax.microedition.midlet Clases de definición de la aplicación Clases e interfaces de E/S básica java.io javax.microedition.io java.lang java.util Clases e interfaces de conexión genérica Clases e interfaces de la Máquina Virtual Clases e interfaces de utilidades estándar Tabla 16: Librerías del perfil MIDP. Proyecto fin de carrera 62 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Las aplicaciones que realizamos utilizando MIDP reciben el nombre de MIDlets (por simpatía con APPlets). Decimos así que un MIDlet es una aplicación Java realizada con el perfil MIDP sobre la configuración CLDC. 2.4.3.3. MIDLETS Los MIDlets son aplicaciones creadas usando la especificación MIDP. Están diseñados para ser ejecutados, como ya sabemos, en dispositivos con poca capacidad gráfica, de cómputo y de memoria. En estos dispositivos no disponemos de líneas de comandos donde poder ejecutar las aplicaciones que queramos, si no que reside en él un software que es el encargado de ejecutar los MIDlets y gestionar los recursos que éstos ocupan, es lo que se denomina el gestor de aplicaciones. 2.4.3.3.1. El gestor de aplicaciones AMS (Application Management System). Este software reside en el dispositivo y es el que nos permite ejecutar, pausar o destruir nuestras aplicaciones J2ME. A partir de ahora nos referiremos a él con las siglas de sus iniciales en inglés AMS. El AMS realiza dos grandes funciones: Por un lado gestiona el ciclo de vida de los MIDlets. Por otro, es el encargado de controlar los estados por los que pasa el MIDlet mientras está en la memoria del dispositivo, es decir, en ejecución. 2.4.3.3.2. Ciclo de vida de un MIDlet El ciclo de vida de un MIDlet pasa por 5 fases Ilustración 19: descubrimiento, instalación, ejecución, actualización y borrado. Proyecto fin de carrera 63 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 19: Ciclo de vida de un MIDlet. El AMS es el encargado de gestionar cada una de estas fases de la siguiente manera: 1. Descubrimiento: Esta fase es la etapa previa a la instalación del MIDlet y es donde seleccionamos a través del gestor de aplicaciones la aplicación a descargar. Por tanto, el gestor de aplicaciones nos tiene que proporcionar los mecanismos necesarios para realizar la elección del MIDlet a descargar. El AMS puede ser capaz de realizar la descarga de aplicaciones de diferentes maneras, dependiendo de las capacidades del dispositivo. Por ejemplo, esta descarga la podemos realizar mediante un cable conectado a un ordenador o mediante una conexión inalámbrica. 2. Instalación: Una vez descargado el MIDlet en el dispositivo, comienza el proceso de instalación. En esta fase el gestor de aplicaciones controla todo el proceso informando al usuario tanto de la evolución de la instalación como de si existiese algún problema durante ésta. Cuándo un MIDlet está instalado en el dispositivo, todas sus clases, archivos y almacenamiento persistente están preparados y listos para su uso. 3. Ejecución: Mediante el gestor de aplicaciones vamos a ser capaces de iniciar la ejecución de los MIDlets. En esta fase, el AMS tiene la función de gestionar los estados del MIDlet en función de los eventos que se produzcan durante esta ejecución. 4. Actualización: El AMS tiene que ser capaz de detectar después de una descarga si el MIDlet descargado es una actualización de un MIDlet ya presente en el dispositivo. Si es así, nos tiene que informar de ello, Proyecto fin de carrera 64 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. además de darnos la oportunidad de decidir si queremos realizar la actualización pertinente o no. 5. Borrado: En esta fase el AMS es el encargado de borrar el MIDlet seleccionado del dispositivo. El AMS nos pedirá confirmación antes de proceder a su borrado y nos informará de cualquier circunstancia que se produzca. Hay que indicar que el MIDlet puede permanecer en el dispositivo todo el tiempo que queramos. Después de la fase de instalación, el MIDlet queda almacenado en una zona de memoria persistente del dispositivo MID. El usuario de éste dispositivo es el encargado de decidir en qué momento quiere eliminar la aplicación y así se lo hará saber al AMS mediante alguna opción que éste nos suministre. 2.4.3.3.3. Estados de un MIDlet en fase de ejecución Además de gestionar el ciclo de vida de los MIDlets, como ya hemos visto, el AMS es el encargado de controlar los estados del MIDlet durante su ejecución. Durante ésta el MIDlet es cargado en la memoria del dispositivo y es aquí donde puede transitar entre 3 estados diferentes: Activo, en pausa y destruido. Cuándo un MIDlet comienza su ejecución, está en el estado “Activo” pero, ¿qué ocurre si durante su ejecución recibimos una llamada o un mensaje? El gestor de aplicaciones debe ser capaz de cambiar el estado de la aplicación en función de los eventos externos al ámbito de ejecución de la aplicación que se vayan produciendo. En este caso, el gestor de aplicaciones interrumpiría la ejecución del MIDlet sin que se viese afectada la ejecución de éste y lo pasaría al estado de “Pausa” para atender la llamada o leer el mensaje. Una vez que terminemos de trabajar con el MIDlet y salgamos de él, éste pasaría al estado de “Destruido” dónde sería eliminado de la memoria del dispositivo. Cuándo decimos que el MIDlet pasa al estado “Destruido” y es eliminado de memoria, nos referimos a la memoria volátil del dispositivo que es usada para la ejecución de aplicaciones. Una vez finalizada la ejecución del MIDlet podemos volver a invocarlo las veces que queramos ya que éste permanece en la zona de memoria persistente hasta el momento que deseemos desinstalarlo. 2.4.3.3.4. Estados de un MIDlet Un MIDlet durante su ejecución pasa por 3 estados diferentes, estos tres estados son: Activo: El MIDlet está actualmente en ejecución. Pausa: El MIDlet no está actualmente en ejecución. En este estado el MIDlet no debe usar ningún recurso compartido. Para volver a pasar a ejecución tiene que cambiar su estado a Activo. 65 Proyecto fin de carrera Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Destruido: El MIDlet no está en ejecución ni puede transitar a otro estado. Además se liberan todos los recursos ocupados por el MIDlet. La Ilustración 20 nos muestra el diagrama de estados de un MIDlet en ejecución: Ilustración 20: Estados de un MIDlet. Como vemos en el diagrama, un MIDlet puede cambiar de estado mediante una llamada a los métodos MIDlet.startApp(), MIDlet.pauseApp() o MIDlet.destroyApp(). El gestor de aplicaciones cambia el estado de los MIDlets haciendo una llamada a cualquiera de los métodos anteriores. Un MIDlet también puede cambiar de estado por sí mismo. Ahora vamos a ver los estados por los que pasa un MIDlet durante una ejecución típica y cuáles son las acciones que realizan tanto el AMS como el MIDlet. En primer lugar, se realiza la llamada al constructor del MIDlet pasando éste al estado de “Pausa” durante un corto período de tiempo. El AMS por su parte crea una nueva instancia del MIDlet. Cuando el dispositivo está preparado para ejecutar el MIDlet, el AMS invoca al método MIDlet.startApp() para entrar en el estado de “Activo”. El MIDlet entonces, ocupa todos los recursos que necesita para su ejecución. Durante este estado, el MIDlet puede pasar al estado de “Pausa” por una acción del usuario, o bien, por el AMS que reduciría en todo lo posible el uso de los recursos del dispositivo por parte del MIDlet. Proyecto fin de carrera 66 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Tanto en el estado “Activo” como en el de “Pausa”, el MIDlet puede pasar al estado “Destruido” realizando una llamada al método MIDlet.destroyApp(). Esto puede ocurrir porque el MIDlet haya finalizado su ejecución o porque una aplicación prioritaria necesite ser ejecutada en memoria en lugar del MIDlet. Una vez destruido el MIDlet, éste libera todos los recursos ocupados. 2.5. Reconocedores de voz 2.5.1. Introducción a los sistemas de reconocimiento de voz El módulo reconocedor de voz tiene como objetivo convertir una secuencia de palabras emitidas por un usuario en una secuencia textual que sea lo más fiel posible a aquella. Para lograr esto deberá analizar la secuencia acústica en busca de las unidades de información que se desean obtener. El conjunto de unidades de información sobre el cual el reconocedor compara las tramas acústicas se denomina vocabulario del mismo [11]. A lo largo de las cinco últimas décadas, el reconocimiento automático del habla mediante máquinas ha sido un objetivo que la investigación ha perseguido a través de enormes esfuerzos realizados en investigación tratando de crear dicha máquina. Sin embargo, a pesar de lo atractivo que resultaría diseñar una máquina capaz de reconocer la palabra hablada y comprender su significado sea cual sea el discurso hablado y en cualquier entorno posible, es muy difícil diseñar una máquina adaptada a todos ellos, por lo que hasta el momento podemos realizar una máquina de reconocimiento para entornos muy concretos [14]. 2.5.2. Los reconocedores Los reconocedores de voz se pueden clasificar según diferentes criterios. Los principales tipos de reconocedor se pueden resumir en los siguientes [12]: Según el objetivo último del reconocimiento existen: o Reconocedores de habla: Lo más importante es conseguir la secuencia de palabras que se ha dicho. o Reconocedores de locutor: Lo que interesa es averiguar la identidad del hablante. o Reconocedores de idioma: El objetivo es identificar el idioma en el que se está hablando. Proyecto fin de carrera 67 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. o Reconocedores de emoción: El objetivo es determinar el estado emocional del locutor. Según el tamaño del vocabulario, las prestaciones y complejidad del sistema varían: o Pequeños: Son capaces de reconocer los dígitos del 0 al 9, si, no… o Medianos: Vocabularios cuyo máximo es 1000 palabras. o Grandes: Vocabularios con más de 1000 palabras. o Muy grandes: Vocabularios con más de 10000 palabras. Según el tipo de reconocimiento: o Habla aislada: Basados en órdenes simples y sin pausas. o Habla continua: Permiten reconstruir un mensaje emitido por un locutor en condiciones normales incluyendo pausas, dudas. El modelo genérico de un sistema de reconocimiento de voz se presenta a continuación, explicando brevemente cada uno de sus componentes: Ilustración 21: Diagrama de bloques de un reconocedor obtenido de [11] Micrófono: Es el elemento transductor del sistema, encargado de recoger las vibraciones del aire producidas en el proceso de habla y convertirlas en una señal analógica. Proyecto fin de carrera 68 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Conversor analógico/digital: Este elemento tiene una doble misión. Por una parte realiza un muestreo de la señal. Por otra parte, debe digitalizar la señal, asociando a cada valor analógico de la señal en el instante de muestreo un valor perteneciente a un dominio finito de símbolos. Detector de principio y fin: Comprueba el nivel de señal y lo compara con los umbrales preestablecidos para detectar la presencia del principio o final de un frase o palabra. Extractor de características: Extrae de la señal digital un conjunto de características (features) que serán empleados por el subsistema reconocedor. Reconocedor: Mediante los vectores de características obtenidos mediante el detector y empleando tanto los modelos acústicos como los modelos de lenguaje para generar la secuencia de palabras que más se asemeje a dichos vectores de características. El reconocedor también puede proporcionar la información necesaria para llevar a cabo una adaptación de los modelos anteriormente mencionados para mejorar los resultados obtenidos. Un esquema más detallado del reconocedor puede verse en la Ilustración 22. Ilustración 22: Arquitectura básica de un sistema reconocedor obtenido de [13] 2.5.3. Métodos de reconocimiento Durante años, se utilizó una aproximación fonético-acústica como principal método de reconocimiento del habla. Sin embargo, dicha Proyecto fin de carrera 69 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. aproximación no obtuvo en la práctica tan buenos resultados como otras aproximaciones alternativas [14]. En líneas generales, podemos decir que actualmente existen dos aproximaciones al reconocimiento del habla: Aproximación fonético-acústica: Está basada en la teoría de la fonética acústica, según la cual existe un número finito y diferenciable de unidades fonéticas en el lenguaje hablado y que dichas unidades están caracterizadas, en términos generales, por una serie de propiedades que se manifiestan en la señal de voz o en su espectro. Aunque, las propiedades acústicas de estas unidades fonéticas son muy variables debido principalmente a los locutores y a las unidades fonéticas vecinas, se asume que las reglas que gobiernan esa variabilidad son sencillas y que pueden ser rápidamente aprendidas y aplicadas en situaciones prácticas. Aproximación de reconocimiento de patrones: Este método tiene dos pasos, el entrenamiento de los patrones y el reconocimiento mediante la comparación de patrones. El “conocimiento” sobre el habla se introduce en el sistema mediante un proceso de entrenamiento. La idea es que si se dispone de un número suficiente de versiones diferentes del patrón que se desea reconocer en el conjunto de datos de entrenamiento que se proporciona al algoritmo de reconocimiento, el proceso de entrenamiento debe ser capaz de caracterizar adecuadamente las propiedades acústicas del patrón, que quedan reflejadas en el modelo acústico que es un modelo oculto de Markov. La utilidad del método está en el paso de comparación de patrones, que realiza una comparación directa entre la voz que debe reconocerse (habla desconocida) con cada uno de los posibles patrones que ha aprendido en la fase de entrenamiento y clasifica el habla desconocida en función de lo bien que encaja con los patrones. 2.5.3.1. Reconocimiento de patrones En líneas generales, se puede decir que un reconocedor basa su funcionamiento en dos eventos bien diferenciados: la segmentación y el reconocimiento [12]. La mayoría de los reconocedores actuales optan por utilizar un esquema estocástico basado en representar la secuencia acústica mediante modelos ocultos de Markov (HMM, Hidden Markov Models), así como técnicas de reconocimiento de patrones y algoritmos avanzados basados en la teoría de programación dinámica para resolver ambos problemas de manera integrada. Los Modelos Ocultos de Markov son un modelo estadístico en el que se asume que el sistema a modelar es un proceso de Markov de parámetros desconocidos. El objetivo es determinar los parámetros desconocidos, “ocultos (hidden)”, de dicha cadena a partir de los parámetros observables. Los Proyecto fin de carrera 70 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. parámetros extraídos se pueden emplear para llevar a cabo sucesivos análisis, un HMM se puede considerar como la red bayesiana dinámica más simple. A lo largo de los años, el desarrollo de las tecnologías y algoritmos de reconocimiento ha dado lugar, como consecuencia, a un incremento de la complejidad de las tareas que debe llevar a cabo el reconocedor de habla. Para tratar de dividir esta complejidad, es habitual dividir el trabajo del mismo en dos fases, aplicando diferentes modelos en cada una de ellas para obtener un mejor resultado global. Ilustración 23: Esquema de un reconocedor de dos etapas, obtenido de [11] El reconocedor del Grupo de Tecnología del Habla que se ha empleado en la realización de este Proyecto presenta este tipo de funcionamiento. En un primer proceso, denominado one pass, se aplica como modelo acústico un HMM por cada alófono y como modelo lingüístico uno basado en bigramas. Una vez efectuado el reconocimiento y asignada una puntuación o score a cada una de las palabras reconocidas, se pasa a un segundo bloque conocido como etapa de rescoring, en la cual se utiliza el modelo acústico de la etapa previa y se varía el modelo lingüístico a uno basado en trigramas, aprovechando que este modelo contiene mayor información. La información entre ambas etapas no se limita a los parámetros acústicos sino que puede reutilizar una mayor información del one pass para simplificar el trabajo del rescoring. A continuación haremos una breve explicación de los elementos que intervienen en este reconocedor. Confianza: Se entiende como medida de confianza la puntuación que le asigna el reconocedor a cada una de las decisiones que toma, constituyendo de esta forma un sistema de medida de lo bien o lo mal que el propio reconocedor asume que está realizando su tarea. La confianza suele medirse en dos niveles diferentes: palabra y frase. o Nivel de palabra: Indica el grado de corrección que el sistema asigna a cada una de las palabras que reconoce. Esta medida sólo se aplica a las palabras que han sido reconocidas, de 71 Proyecto fin de carrera Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. manera que no se tendrán en cuenta posibles errores debidos, por ejemplo, al borrado de palabras. o Nivel de frase: Expresa la corrección de la frase en conjunto. Esta medida se realiza confrontando la frase reconocida con la trascripción de la frase original, de manera que ahora sí se tendrán en cuenta los posibles borrados de palabras. Modelos acústicos: Los modelos acústicos se construyen a partir de Modelos ocultos de Markov de los alófonos. Los alófonos aislados se tratan como HMM, con el objetivo de tener en cuenta la variabilidad que introducen los alófonos adyacentes en la pronunciación de cada alófono. Modelos lingüísticos: El conocimiento léxico, es decir, la definición del vocabulario y la pronunciación de las palabras son parte esencial de la sintaxis y semántica de la lengua y, como tales, definen reglas que determinan qué secuencias de palabras son gramaticalmente correctas y dan lugar a un discurso comprensible. En los reconocedores automáticos suelen emplearse modelos estocásticos del lenguaje, que modelan las características del idioma desde un punto de vista probabilístico. La clave de estos modelos consiste en proporcionar la información probabilística adecuada, de manera que las secuencias de palabras más comunes tengan mayor probabilidad. Esto no sólo mejora el resultado del reconocimiento, sino que contribuye a restringir el espacio de búsqueda del reconocedor, aumentando la rapidez del sistema. Grafos: El trabajo de reconocimiento se puede asimilar como un problema de búsqueda y los grafos son una de las herramientas más potentes para resolver este tipo de problemas. Permiten evaluar diferentes alternativas de actuación en base a una determinada función de coste, que asocia un valor a cada uno de los caminos que recorren el grafo. Todo grafo consta de un conjunto de nodos y una serie de uniones entre ellos. Si el grafo es dirigido, dichas uniones reciben el nombre de flechas y son unidireccionales. En función del problema considerado, los nodos y las flechas constituirán sistemas de almacenamiento de información. [11] 2.5.4. Variabilidad de la señal de voz Aunque en la actualidad pueden construirse reconocedores muy precisos para un determinado locutor, con un lenguaje determinado y un estilo de hablar particular, en un entorno conocido y para una tarea concreta, todavía no somos capaces de crear un reconocedor que entienda a cualquier locutor, independientemente del entorno, el lenguaje o la tarea. [13] 72 Proyecto fin de carrera Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Es por esto que la precisión y la robustez son las últimas medidas a tener en cuenta para un resultado exitoso de los algoritmos de reconocimiento. Hay varias razones por las que los algoritmos o sistemas actuales no dan los resultados esperados por los usuarios. A continuación se describen algunos de ellos. 2.5.4.1. Variaciones en el contexto La interacción hablada entre las personas requiere un conocimiento del significado de las palabras y el contexto en el que son dichas. Palabras con significados muy diferentes pueden tener la misma pronunciación como, por ejemplo, vaca y baca. En ocasiones se da el caso de que no sólo hay palabras que se pronuncian igual, sino que la combinación de dos de ellas, además de poder tener la misma pronunciación, tienen un significado semántico diferente como por ejemplo “toma té verde” o “tomate verde” que se pronuncian casi igual pero no tienen un significado parecido. Incluso disponiendo de la mejor información semántica y lingüística, es casi imposible descifrar la secuencia de palabras correcta a menos que el locutor haga pausas entre las palabras o utilice la entonación para distinguir entre estas frases confusas desde el punto de vista semántico. Además de las posibles variaciones de contexto en los niveles de palabra y frase, también pueden encontrarse variaciones de contexto a nivel de fonema. En función del contexto, la realización de un fonema puede ser diferente. Esta dependencia del contexto se hace más evidente en habla rápida o espontánea en la que muchos fonemas no llegan a pronunciarse con precisión. 2.5.4.2. Variaciones en el estilo Para intentar solucionar los problemas de pronunciación, pueden imponerse unas condiciones para el uso de los reconocedores. Podemos tener un sistema de reconocimiento de habla aislada, en el cual el locutor debe realizar una pausa después de cada palabra, de modo que se eliminan los problemas derivados de la combinación de palabras con similar pronunciación. Además, el habla aislada proporciona un correcto contexto de silencios lo que facilita el modelado y decodificación del habla, reduciendo significativamente la complejidad computacional y la tasa de error. El problema es que este reconocedor de habla aislada no es natural para la mayoría de las personas. En el reconocimiento de habla continua, la tasa de error la tasa de error para el habla espontánea que puede surgir en cualquier conversación diaria es mucho mayor que para un discurso cuidadosamente articulado y leído en voz alta. La tasa de habla también afecta a la tasa de reconocimiento de palabras. Generalmente, cuanto mayor es la tasa de habla (palabras/minuto) mayor es la Proyecto fin de carrera 73 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. tasa de error. Además, si una persona susurra o grita para reflejar sus estados emocionales, la variación se incrementa más significativamente. 2.5.4.3. Variaciones en el locutor Cada individuo habla de una forma diferente. La forma en la que una persona habla es el reflejo de una serie de características físicas, edad, sexo, dialecto, salud y educación. De esta manera, los patrones de habla de una persona pueden ser totalmente diferentes de los de otra. Incluso si eliminamos las diferencias debidas a locutores diferentes, un mismo locutor a menudo es incapaz de reproducir exactamente los mismos sonidos. Para un reconocimiento independiente del locutor, se suelen crear modelos que combinan las características de miles de locutores. Para mejorar el funcionamiento de un reconocedor independiente del locutor, es necesario definir una serie de condiciones. Una podría ser definir un registro del usuario por el cual dicho usuario tenga que hablar durante, por ejemplo, 30 minutos. Con los datos y entrenamiento dependientes del locutor, podremos ser capaces de capturar varias características acústicas dependientes del locutor que puedan mejorar significativamente el funcionamiento del reconocedor. En la práctica, el reconocimiento dependiente del locutor permite no sólo mejorar la precisión sino también la velocidad, puesto que la decodificación puede realizarse de manera más eficiente al emplear un modelo acústico y fonético más apropiado. Un sistema de reconocimiento dependiente del locutor típico puede reducir el error de reconocimiento de palabras de forma significativa comparado con un sistema de reconocimiento independiente del locutor similar. El problema de los sistemas dependientes del locutor es el tiempo que se necesita para obtener todos los datos del locutor, que resulta poco práctico desde el punto de vista de algunas aplicaciones como puede ser una operadora telefónica automática. Muchas aplicaciones deben funcionar con locutores desconocidos que trabajarán con el sistema durante un período determinado de tiempo, de manera que el reconocimiento independiente del locutor sigue siendo una característica importante. Cuando se dispone de una cantidad limitada de datos dependientes del locutor, es necesario emplear tanto los datos dependientes del locutor como los independientes empleando técnicas de adaptación al locutor. 2.5.4.4. Variaciones en el entorno El mundo en el que vivimos está lleno de sonidos de distinta intensidad y procedentes de muy diversas fuentes. Cuando empleamos un ordenador, podemos tener a otras personas hablando en segundo plano, alguien puede cerrar de un portazo una puerta o el aparato de aire acondicionado puede comenzar a funcionar. Si el reconocimiento de habla se encuentra integrado en dispositivos móviles como teléfonos móviles o PDA’s (Personal Digital Assistants), los ruidos debidos al espectro varían más, principalmente porque el usuario se puede estar moviendo. 74 Proyecto fin de carrera Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Todos estos parámetros externos como son el ruido ambiente o la colocación del micrófono pueden afectar en gran medida al funcionamiento del reconocedor. También hay que tener en cuenta que, además de los ruidos que pueda haber en segundo plano, el locutor también produce ruidos como pueden ser extraléxicos que emite cuando está dudando, por ejemplo. El ruido también puede provenir de los propios dispositivos de entrada como son los micrófonos o los convertidores A/D. Al igual que sucede en el entrenamiento de un sistema independiente del locutor, podemos construir un sistema a partir de datos recogidos en numerosos y variados ambientes. Podemos emplear técnicas de adaptación para minimizar las diferencias entre los posibles entornos de manera similar a lo que hacíamos en un entrenamiento para adaptar a un locutor. Sin embargo, y a pesar de los progresos que se han llevado a cabo en este campo, las variaciones en el entorno siguen siendo uno de los mayores retos que deben afrontar los actuales sistemas de reconocimiento de habla. 2.5.5. Prestaciones En la actualidad, tal como comentábamos en el inicio de esta sección, no existen reconocedores perfectos, todos cometerán un cierto error a la hora de transcribir los mensajes acústicos que reciben. Algunos de los motivos que llevan a este reconocimiento erróneo pueden ser el entorno en que se obtiene la señal de voz (puede ser más o menos ruidoso) o la ausencia de referencias en el vocabulario (out of vocabulary). [11] La calidad de un reconocedor se puede medir evaluando cada una de las palabras que constituyen la frase. Esto se hace así debido a la forma en la que se desarrolla el alineamiento y la confrontación de la frase reconocida con la trascripción escrita de la secuencia acústica de entrada, recogida en una base de datos de entrenamiento. De esta manera, al confrontar dos frases pueden darse los siguientes casos: Acierto: La palabra reconocida coincide con la original. Sustitución: La palabra reconocida no coincide con la original sino con otra. Borrado: El reconocedor no ha reconocido una palabra que sí se encontraba en la frase original. Inserción: El sistema introduce una palabra que no se encontraba en la frase original. A partir de estos valores se definen una serie de porcentajes que proporcionan información sobre la calidad del reconocedor: Proyecto fin de carrera 75 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. número de aciertos ⋅ 100 longitud de la hipótesis %aciertos = %sustituciones = %borrados = % inserciones = (1) número de sustituciones ⋅ 100 longitud de la hipótesis número de borrados ⋅ 100 longitud de la hipótesis (2) (3) número de inserciones ⋅ 100 longitud de la hipótesis (4) Realmente las tres primeras tasas constituyen el 100%, dado que el índice por el cual se normalizan es la longitud en palabras de la hipótesis y en esta no tiene sentido definir las inserciones, puesto que una inserción es un palabra ajena a la hipótesis que ha introducido el reconocedor. La suma de las tres últimas tasas es el porcentaje de error del reconocedor: %error = %sustituciones + % borrados + % inserciones (5) El parámetro de mayor utilidad para la medida de las prestaciones de un reconocedor no es la tasa de palabras correctas, sino la tasa de precisión de palabra o word accuracy (WA) , definida como: WA = 100% - %error = %aciertos - %inserciones Proyecto fin de carrera (6) 76 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. 3. Descripción del sistema 3.1. Visión general del sistema Como aproximación al sistema, veremos de forma global todos los dispositivos y aplicaciones que intervienen en el proyecto, el análisis de requisitos previos y de qué forma interactúan unos con otros. En las siguientes secciones de este capitulo detallaremos de qué forma se implementaron cada una de las aplicaciones que gestionan los dispositivos. 3.1.1. Requisitos previos Uno de los motivaciones por las que surgió la necesidad de desarrollar este proyecto fue la necesidad de integrar el reconocedor de voz Servivox con el robot Robonauta, este proyecto de la Escuela Técnica Superior de Ingenieros Industriales de la UPM, con el objetivo de poder trabajar en los laboratorios de la ETSIT y debido a la indisponibilidad de Robonauta surgió la idea de crear un robot demostrador que nos permitiese probar Servivox como interfaz controladora Lo anteriormente expuesto condicionó en gran manera la arquitectura que presenta el sistema, ya que Servivox no funcionará de forma independiente sino que estará sometida a alguna unidad de control. Concretamente se basa en una arquitectura cliente-servidor realizando la comunicación mediante sockets, la unidad de control en Robonauta será un cliente y todas las que unidades que controla son servidores. Es necesario comentar que con el paso del tiempo el proyecto de Roomba se fue cargando de cierta autonomía, y aunque seguía cumpliendo con los requisitos y verificando los objetivos de integración con Robonauta, el proyecto se convirtió en el desarrollo de varias interfaces amigables que permitiesen el control de un robot domótico móvil. En el desarrollo del programa de control para Roomba el objetivo fundamental era conseguir definir una interfaz basada en una lista de movimientos que el sistema fuese capaz de traducir a una secuencia de bytes que trasmitiría por el puerto serie virtual (estándar bluetooth SPP) a Roomba. Un ejemplo de estos movimientos puede ser “avanza”, “gira a la derecha”, “aspira”, etc… 3.2. Arquitectura La Ilustración 24 muestra la arquitectura global del sistema. Como sabemos el objetivo principal es lograr controlar el robot Roomba desde distintas interfaces, un teléfono móvil, el mando wiimote de la videoconsola Wii de Nintendo y por último empleando la voz a través del reconocedor de voz Servivox del Grupo de Tecnología del Habla de la ETSIT, UPM. Proyecto fin de carrera 77 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Para lograr la interconexión disponemos de un PC, es aquí en donde correrán las aplicaciones que gestionarán cada uno de los elementos que intervienen en el proyecto. Para interconectar las aplicaciones utilizaremos los sockets del sistema y para simplificar el modelo de conexiones utilizaremos una aplicación, la aplicación Cliente, que será la encargada de gestionar las conexiones entre las aplicaciones de gestión de las diversas interfaces de control y la aplicación de gestión Roomba. Ilustración 24: Visión general del sistema con las aplicaciones y dispositivos que intervienen Para realizar las conexiones entre las aplicaciones que están ejecutándose en el PC y los diferentes dispositivos hemos empleado la tecnología bluetooth con el software BlueSoleil que implementa la torre del estándar. Además, como se puede ver en la imagen esquemática, es también necesario implementar una aplicación para recoger información en el teléfono móvil y establecer la conexión con el PC. Con objeto de poder adaptar el sistema al equipo en el que está trabajando la arquitectura del sistema se complementa con dos archivos que permiten la configuración y ajuste del sistema. El primero de ellos config_sys.ini permite ajustar parámetros como los sockets internos que utilizan las aplicaciones para comunicarse, puede suceder que alguno de los que vienen Proyecto fin de carrera 78 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. por defecto ya está en uso por otro aplicación, o puertos a través de los cuales las aplicaciones se comunican las aplicaciones con los dispositivos. El otro archivo de configuración tiene por finalidad ajustar los parámetros de los movimientos definidos para Roomba, como veremos más adelante, definiremos una serie de órdenes o movimientos que el robot Roomba será capaz de interpretar, y como veremos algunos de estos movimientos tienen parámetros de ajuste, por ejemplo velocidad, distancia, etc… en el archivo config_mov.ini se permite que el administrador del sistema modifique alguno de esos parámetros para adaptar el sistema a sus necesidades. Ilustración 25: Detalle del archivo de configuración ‘config_mov.ini’ En el manual del usuario que se adjunta se puede encontrar más información sobre cómo modificar y utilizar estos archivos para configurar el sistema apropiadamente. 3.3. Dispositivos A modo de introducción se comentarán algunas de las características más interesantes y destacables de los dispositivos que intervienen en el sistema. 3.3.1. Roomba Roomba es aspirador robótico fabricado y vendido por iRobot que funciona de forma autónoma, Ilustración 26. Se comercializa como iRobot Roomba Robotic Floorvac. Roomba se lanzó al mercado en 2002. En 2004 comenzó a venderse la segunda generación de modelos, y en 2007 la tercera [22]. Proyecto fin de carrera 79 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 26: Vista del robot iRoomba de iRobot El aparato es un disco de 34 cm de diámetro y menos de 9 cm de altura y cuenta con sensores de contacto con paredes y muebles e infrarrojos. Los modelos de segunda y tercera generación cuentan con un sensor de suciedad que les permite centrarse en los puntos más sucios. Si los sensores detectan que la unidad queda atascada, ha sido levantada o no puede salir de una zona estrecha, una alarma comienza a sonar para que el dueño pueda encontrarlo. Dispone además de un puerto serie min-Din que permite la transferencia de información y se complementa con una API (Application Programming Interface) que ofrece al programador toda una serie de funciones para el control de Roomba. Para librar la transferencia de datos de las limitaciones del cable la empresa iRobot desarrolló Rootooth, Ilustración 27, un pequeño dispositivo que se puede conectar a la salida miniDIN de Roomba y establecer una conexión bluetooth implementando el perfil SPP (puerto serie virtual) [24]. Ilustración 27: Vista del dispositivo de comunicaciones inalámbrico Rootooh 3.3.2. Teléfono móvil Nokia N70 El teléfono móvil Nokia N70 es uno de los terminales de Nokia de la serie N de teléfonos del tipo Smartphone. De entre todas sus características técnicas [24] las que más nos interesan a la hora de implementar una aplicación de control para Roomba es la posibilidad de trabajar sobre Java para implementar el software. Para ello el Nokia N70, dispone del sistema operativo Symbian OS 8.1ª que permite montar una KVM (Kilo Virtual Machine) de Java 80 Proyecto fin de carrera Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. que se complementa con la configuración CLDC y en concreto para este dispositivo móvil con el perfil MIDP 2.0. El Nokia N70 permite también establecer conexiones inalámbricas tipo bluetooth, de forma que la información procesada, procedente de la aplicación de adquisición puede transmitirse fácilmente a otra máquina. A continuación se presentan las características del Nokia N70 en la Tabla 17. Forma Plataforma Sistema Operativo Memoria RAM Frecuencias GSM GPRS EDGE (EGPRS) WCDMA Pantalla principal Cámara Grabación de vídeo Mensajes multimedia Videollamada Pulse para hablar (PPH) Soporte de Java Memoria interna Memoria externa Ranura de tarjeta de memoria Bluetooth Infrarrojos Soporte para cable de datos Navegación Correo electrónico Reproductor de música Radio Reproductor de vídeo Tonos polifónicos Tonos de llamada Modo "fuera de línea" Batería Proyecto fin de carrera Candybar ("monobloque") Serie 60(S60) 2ª Edición Feature Pack 3 Symbian OS 8.1ª 32 MB 900/1800/1900 MHz Sí Sí Sí (2100 MHz) TFT, 262.144 colores, 176x208 pixels 2.0 Megapixels (flash, zoom digital 20x) Sí, CIF Sí Sí Sí Sí, MIDP 2.0 22 MB Tarjeta RS-DV-MMC (incluida tarjeta de 64 MB) Sí, RS-DV-MMC (intercambiable en caliente) 2.0 No Sí WAP 2.0/xHTML, HTML Sí Sí, estéreo con bajos en auriculares Sí, FM Sí Sí, 64 acordes Sí - Mp3,WAV,AAC,MIDI,AMR,(NB-AMR) Sí BL-5C (3.7V, 970 mAh) 81 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Autonomía en llamada Autonomía en espera Peso Dimensiones Hasta 3 horas y media Hasta 265 horas 126 gramos 108.8x53x21.8 milímetros Tabla 17: Tabla con las características técnicas del teléfono móvil N70 Ilustración 28: Vista anterior y posterior del teléfono móvil N70 de Nokia 3.3.3. Dispositivo Wiimote El dispositivo Wiimote es el mando principal de la videoconsola Wii de Nintendo, sus características más interesantes son la capacidad de reconocer movimientos gracias al acelerómetro en su interior, capaz de detectar las aceleraciones en los tres ejes del espacio. Ilustración 29: Vista del dispositivo Wiimote de Nintendo Esta información se complementa con la información adquirida desde el sensor de infrarrojos de la parte frontal y que sitúa la posición a la que apunta el wiimote en referencia a una barra de transmisión de infrarrojos, Ilustración 30: Vista de la barra de infrarrojos de Nintendo. Proyecto fin de carrera 82 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 30: Vista de la barra de infrarrojos de Nintendo Por último el dispositivo wiimote posee la capacidad de transmitir toda la información adquirida en los acelerómetros y de su posicionamiento sobre la barra de infrarrojos a través del protocolo Bluetooth y al mismo tiempo también es posible transmitir información hacia el Wiimote para almacenarla en su memoria interna. 3.3.4. Servivox Robonauta es un proyecto cuyo objetivo es la integración de comportamientos inteligentes en robots guía. El objetivo de este proyecto es el desarrollo de un sistema inteligente de asistencia para el acceso personalizado a lugares públicos, y una interacción fluida con la información y con ciudadanos allí presentes. Busca fomentar la integración en la sociedad de técnicas relacionadas con la automática e inteligencia artificial, mediante el uso de las nuevas tecnologías de la información. Dentro de las Tecnologías del habla aplicadas al diálogo, entre otros, se plantea un subobjetivo de asistencia en la adaptación de un nuevo usuario o a una nueva exposición o entorno. Cuando se plantea la construcción de un sistema de reconocimiento de habla, la opción más directa es el entrenamiento de un sistema específico para la tarea que se va realizar. Si queremos que el entrenamiento sea robusto, necesitaremos disponer de un elevado número de datos de entrenamiento. Puesto que el robot se moverá en lugares públicos, pese a que la tarea a desarrollar sea la misma, las condiciones acústicas del entorno o el hablante que se dirigirá al robot varían de un entorno a otro. Por este motivo, no dispondremos de un número de datos suficiente como para realizar un buen entrenamiento pero necesitamos construir un sistema de reconocimiento fiable, haciéndose necesaria la aplicación de técnicas de adaptación del robot al entorno. Proyecto fin de carrera 83 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. 3.3.5. Bluesoleil En este proyecto se utilizará la pila de Bluesoleil para gestionar las aplicaciones Bluetooth. Las pilas Bluetooth pueden clasificarse en dos grandes grupos: Implementaciones de propósito general, escritas con énfasis en la amplitud de características y la flexibilidad, típicamente para ordenadores personales. Se puede añadir soporte para perfiles Bluetooth específicos por medio de drivers. Implementaciones empotradas para su uso en dispositivos donde los recursos son limitados y la demanda es baja, tales como periféricos Bluetooth. En general, sólo puede usarse una pila en un momento dado. Los cambios suelen requerir la desinstalación de la pila previa, aunque una traza de las pilas usadas en el pasado permanezca en el registro. Existen casos en los que dos pilas pueden usarse en el mismo ordenador, cada una de ellas con su propia radio Bluetooth independiente. Widcomm es la primera pila que salió para el sistema operativo Windows. Inicialmente desarrollada por Widcomm Inc., ésta fue adquirida por Broadcom Coporation en abril de 2004, que continúa vendiendo licencias para su uso en multitud de dispositivos Bluetooth. Existe una API para interactuar con la pila a través de una aplicación genérica. Windows XP incluye una pila integrada a partir del Service Pack 2. Previamente, Microsoft lanzó un QFE de su pila en el Service Pack 1, con la referencia QFE323183. No obstante, sólo fue distribuida a compañías y no directamente al público. Estas compañías podían utilizar el QFE como parte de los instaladores de sus dispositivos Bluetooth, aunque ya no está soportado por Microsoft. Windows Vista incluye también una pila integrada que es una expansión de la pila presente en Windows XP. Además del soporta para más perfiles Bluetooth, también soporta el desarrollo de drivers que permite que los desarrolladores externos den soporte a perfiles adicionales, un aspecto que no estaba presente en la pila de Windows XP y sólo permitía el desarrollo por encima de la pila de Microsoft (lo que según algunos retrasó su adopción). Microsoft no ha lanzado una pila oficial para versiones anteriores de su sistema operativo como Windows 2000 o Windows ME. Sin embargo las pilas que se encuentran por defecto instaladas en el sistema operativo no dan buenos resultados, si como en nuestro caso, 84 Proyecto fin de carrera Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. utilizamos un dispositivo de comunicaciones Bluetooth externo que se conecta mediante USB al PC. En estos casos el fabricante distribuye el software Bluesoleil con el que existe compatibilidad total. Ilustración 31: Vista de la pantalla principal del software Bluesoleil BlueSoleil está desarrollada por IVT Corporation, que se dedica al desarrollo de pilas para dispositivos empotrados y sistemas de escritorio. [26] Está disponible en versiones estándar y VoIP para Microsoft Windows. La versión de escritorio soporta DUN, FAX, HFP, HSP, LAP, OBEX, OPP, PAN SPP, AV, BIP, FTP, GAP, HID, SDAP y SYNC. La API se puede obtener sin coste alguno, y se provee una interfaz de usuario que monitoriza la actividad de la API en tiempo real, lo que ofrece apoyo al desarrollo de software. 3.4. Aplicación cliente 3.4.1. Introducción Aunque en un primer momento el desarrollo de la aplicación cliente estuvo vinculado a la necesidad de emular una unidad de control central, el transcurso del proyecto hizo que está aplicación fuera ganando peso como unidad de interconexión entre la aplicación de control de Roomba y las aplicaciones de las interfaces de control (reconocedor, wiimote, teléfono móvil) hasta convertirse en uno de los puntos clave del sistema de cara a conseguir robustez, velocidad de respuesta y flexibilidad. Proyecto fin de carrera 85 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 32: Esquema de funcionamiento de la aplicación cliente Tenemos por lo tanto dos objetivos generales que enmarcarán el desarrollo y la arquitectura de la aplicación cliente: A. Desarrollo de una aplicación que permita emular la existencia de una unidad de control que permita la conexión de la aplicación del reconocedor de voz, Servivox. Este requisito viene impuesto por la necesidad de integrar Servivox como parte del sistema de control del robot ROBONAUTA desarrollado en la Escuela Técnica Superior de Ingenieros Industriales de la UPM. Para que la conexión sea correcta, Servivox debe comunicarse con la unidad de control a través de los sockets del sistema empleando la clase CSocketNode, de la que se hablará posteriormente en este capitulo, con una estructura de servidor. Además es necesario implementar un pequeño protocolo de comunicaciones entre la unidad de control y Servivox que consiste en que el reconocedor de voz espera a que la unidad de control le envíe la cadena “estimar ruido”, a partir de este momento el reconocedor de voz estima el ruido ambiente y contesta con la cadena “ruido”, a partir de ese momento Servivox se queda esperando que el locutor hable. B. El segundo objetivo consiste en servir de nexo de unión entre la aplicación de control de Roomba y las aplicaciones de control y gestión de las interfaces de control. Este objetivo surgió cuando una vez interconectado el reconocedor y Roomba se vio la posibilidad de utilizar otras interfaces de control con mayor fiabilidad y velocidad de respuesta Proyecto fin de carrera 86 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. que implementasen la capacidad de enviar mensajes con los movimientos de la interfaz de control de Roomba. Al plantear este segundo objetivo surgió la necesidad de que se verificasen ciertos requisitos para que la aplicación funcionase correctamente, este se puede resumir en una serie de subobjetivos o requisitos dentro de este objetivo general. B.1 Requisito de robustez: el cliente simplemente se debe de encargar de comprobar que conexiones están disponibles y manejarlas correctamente, en el caso de que alguna falle no debe afectar al buen funcionamiento del resto. B.2 Requisito de flexibilidad: en cierto momento o durante un gran período de tiempo un usuario puede no necesitar un interfaz de control, por ejemplo, puede querer usar el reconocedor de voz y el teléfono móvil y nunca llegar a usar el wiimote. En este caso el cliente debe de trabajar igual con tan solo dos dispositivos, pero sin dejar de comprobar que en algún momento el usuario encienda el wiimote. B.3 Requisito de velocidad de respuesta: el cliente debe introducir el mínimo retardo posible. Su única labor debe ser el mantenimiento de las conexiones y la conmutación entre entradas y salida sin ningún tipo de tratamiento sobre la información transmitida, esto a su vez permite que todos las interfaces de control pueden utilizar la interfaz de control de Roomba basada en movimientos con la certeza de que el cliente no influirá en la respuesta. 3.4.2. La clase CSocketNode 3.4.2.1. Introducción La clase CSocketNode implementada en C++ nos permite crear un objeto de esta clase que inicializaremos como cliente o servidor y que permitirá la comunicación a través de un socket del equipo. Dependiendo de cómo inicialicemos, el CSocketNode será el que lleve el peso de la comunicación (Servidor) o esperará a que otro la inicie (Cliente). Más adelante detallaremos la utilidad y posibilidades de las funciones que se ofrecen como public y protected. Recordemos que el estilo de visibilidad protected se comportará como pública en la clase base y en las que componen la jerarquía de herencia, y como privada en las clases que sean de la jerarquía de herencia; si es necesario detallaremos como se apoyan estas funciones en variables o funciones privadas y de las que hacen uso internamente. 3.4.2.2. Arquitectura Proyecto fin de carrera 87 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Debemos distinguir si estamos trabajando con un cliente o con un servidor; en ambos casos el uso de los métodos será muy semejante, ya que en general cuando llamamos a uno de ellos lo primero que se hace es comprobar si el socket con el que estamos trabajando es un cliente o un servidor, y en función de eso realizará acciones diferentes. En cualquiera de los dos casos, después de crear e inicializar llamaremos al método StartThread() que lanzará una hebra en la que continuamente se comprueba si la conexión es correcta y si todo va bien. Si no es así se llamará al método HandleConnection() para intentar solventarlo; a partir aquí es en donde existe una diferencia entre el caso del cliente y el servidor ya que este último comprueba si se ha recibido algún mensaje (que será tratado en el método OnMsg()). 3.4.2.3. Detalle de funciones de CSocketNode Funciones con carácter PUBLIC: CSocketNode(): Es el constructor de la clase, se trata de un método que se ejecuta automáticamente al crear un objeto de la clase. Necesita hacer uso de winsock.dll que previamente tendremos que indicar la configuración del proyecto. Además de esto aumenta el valor de la variable count que contiene información sobre el número de Socket inicializados. virtual ~CSocketNode(): Es el destructor de la clase, al igual que el constructor es una función especial llamada automáticamente en la ejecución del programa, y por tanto no tienen por qué ser explícitamente llamada por el programador. Su cometido es liberar los recursos computacionales que el objeto de dicha clase haya adquirido en tiempo de ejecución al expirar este. Actualiza el valor de count. int Init(char* address, int port, int type): Es el inicializador de los sockets, debemos pasarle como parámetros la dirección del equipo y un puerto dentro de este equipo, así como el tipo de socket que queremos inicializar SOCKET_SERVER o SOCKET_CLIENT. Si se trata de un servidor se llama al método bind (asocia un objeto Socket a un extremo local) y después a listen (coloca al socket en modo de escucha). En el caso de un cliente esto no es necesario. int Close(): Cierra el socket que estábamos utilizando, si hay alguna hebra lanzada espera hasta que termine. Proyecto fin de carrera 88 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. int IsConnected(): Devuelve 1 si el socket está conectado, este método nos permite comprobar si un socket que queremos utilizar está en condiciones de hacerlo de forma correcta. int SendMsg(const char* cad,int length): Permite el envío de un mensaje a través del socket, debemos pasar como segundo parámetro la longitud de la cadena que se puede obtener fácilmente haciendo sizeof(cad). Este método se encarga de añadir una cabecera que comprobará el otro extremo. Devuelve error en caso de que el socket no sea válido o si no consigue enviar correctamente el mensaje. int ReceiveMsg(char* cad,int* size, int timeout=200): Lee del socket el número de bytes que indiquemos en size y lo almacena directamente en la dirección apuntada por cad, también debemos establecer un timeout máximo. Este método se encarga de comprobar una cabecera que el método SendMsg añade al transmitir (ambas acciones son transparentes para el usuario), basándose en esta cabecera el método puede devolver dos errores, -1 indica error en la cabecera y -2 indica que no hay cabecera, en ambos casos los datos recibidos no son válidos. Por último puede devolver -3 indicando que el tamaño de cad es insuficiente. void StartThread(): Al ejecutar este método se crea una hebra que hará el trabajo de cliente o servidor dependiendo del tipo de socket que se trate. En ambas hebras lo que se hace un bucle infinito en el que se ejecuta ServerLoop() o ClientLoop(), métodos que detallaremos a continuación. void ServerLoop(): Si está correctamente conectado y llega algún mensaje al socket llama al método OnMsg(). Si no está conectado llama al método HandleConnection() que se encarga de conectar este servidor con el cliente. void ClientLoop(): Comprueba que está conectado; en caso de que no lo esté, llama a HandleConnection() que se encarga de conectar con un servidor. Existe una diferencia respeto al servidor, y es que como vimos antes la hebra del socket servidor está esperando la llegada de un mensaje para pasárselo al método OnMsg(), como en el cliente no tenemos directamente implementado esto, podemos hacer uso de la herencia y crear una clase que sobrescriba el método ClientLoop() de forma que haga lo mismo que el servidor. Otra posibilidad es implementar en nuestro programa un bucle comprobando la conexión con isConnected() y ver si hay algún mensaje con ReceiveMsg(). Proyecto fin de carrera 89 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. int HandleConnection(): Comprueba si el socket está conectado y en caso de que no lo esté, se encarga de solucionarlo. int PingServer(): Hace un ping al servidor. (Recordemos que por defecto el cliente no trata los mensajes que le llegan al socket) Funciones con carácter PROTECTED: void ServerThread(): Es el método que se ejecuta cuando se llama a startThread() y estamos en un socket servidor. Es un bucle que continuamente comprueba el correcto funcionamiento del socket y llama a ServerLoop(). void ClientThread(): Es el método que se ejecuta cuando se llama a startThread() y estamos en un socket cliente. Es un bucle que continuamente comprueba el correcto funcionamiento del socket y llama a ClientLoop(). int Ack(): Envía la cadena “Ack”. int Nack(): Envía cadena “Nack”. int GetAck(int timeout): Intenta recibir la cadena “Ack” dentro del timeout, puede dar error por alcanzar este tiempo o porque la cadena que recibe no es correcta. virtual void OnConnection(): Imprime “onConnection()”, se puede utilizar para realizar alguna tarea durante la conexión. virtual void OnMsg(char* cad,int length): La hebra del servidor llama a este método cuando detecta que ha llegado algún mensaje al socket. Podemos crear una nueva clase que herede de CSocketNode y reescribir este método de forma que cuando llegue un mensaje de forma que podamos darle el tratamiento que nosotros queramos, es aquí en donde reside el verdadero potencial de esta clase. void Error(char* cad=""): Imprime un mensaje de error, si el socket está abierto, lo cierra. 3.4.2.4. Integración en el sistema Para trabajar con la clase CSocketnode, es necesario vincular en el proyecto con el que vamos a trabajar los archivos de CSocketnode para que el funcionamiento sea correcto. Proyecto fin de carrera 90 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. En primer lugar debemos incluir al comienzo del fichero en el que vayamos a utilizar la clase CSocketNode las cabeceras, socketnode.h y portable.h para lo cual debemos incluir las líneas de código que se muestran en el Cuadro 1, comprobando que la ruta de los archivos es correcta. #include "Socket/socketnode.h" Cuadro 1: Líneas de código con los include necesarios para el buen funcionamiento de la clase CSocketNode Además es necesario añadir algunas directivas de preprocesador en el entorno de trabajo: _Windows, _Win32_ Por último añadimos al entorno de trabajo los siguientes archivos: imprimetrace.c Output.cpp. Y con todo esto ya podremos trabajar con la clase CSocketNode en nuestro proyecto. 3.4.2.5. Ejemplos de uso Como hemos comentado anteriormente solo los socket servidor están preparados para recibir mensajes y tratarlos en el método onMsg(); normalmente nos interesará que la comunicación sea bidireccional, por esto y como ya hemos comentado tenemos la posibilidad de crear una nueva clase que herede de la anterior reescribiendo los métodos clientLoop() para que compruebe si hay mensajes recibidos como en el caso de serverLoop() y podremos también reescribir el método onMsg() para especificar que hacemos con el mensaje una vez que lo recibamos. En el Cuadro 2 se muestra la nueva clase CServidor que hereda de CSocketNode, sobrescribimos el método ServerLoop() que es el encargado de realizar las gestiones oportunas cuando llega un mensaje nuevo a una instancia de la clase servidor. La modificación en este caso consiste en que actúe de la misma forma que lo hace el cliente llamando al método OnMsg(). Proyecto fin de carrera 91 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. class CServidor: public CSocketNode public: void CServidor:: ServerLoop(){ if(!IsConnected()) HandleConnection(); else { char msg[2000]; int l=2000; if(0==ReceiveMsg(msg,&l,0)) { OnMsg(msg,l); } } } }; Cuadro 2: Sobreescritura de la función ServerLoop() Por otro lado podemos sobrescribir la función OnMsg(), Cuadro 3, para personalizar el comportamiento que queremos cuando llegue una nueva cadena a través del socket. Como apunte, destacar la necesidad de establecer 0 en el último carácter de la cadena para indicar el fin de la misma. class CServidor: public CSocketNode public: void CServidor::OnMsg(char* cad,int length){ cad[length]=0; . . . } }; Cuadro 3: Sobreescritura de la función OnMsg() La otra posibilidad, que es la que vamos a detallar en este apartado, consiste en hacer uso directamente de los métodos IsConnected() y ReceiveMsg(). Estas dos funciones permiten por un lado analizar que la conexión está todavía correctamente establecida, si la conexión es correcta podemos comprobar si existe información en el buffer de lectura, leemos la información y la tratamos adecuadamente, Cuadro 4. Proyecto fin de carrera 92 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. if(instancia_socketnode.IsConnected()){ . . Conexion comprobada y correcta, comprobamos si hay información en el buffer . . if (instancia_socketnode.ReceiveMsg (bufin, &ret, 500) == 0){ bufin[ret] = 0; . . . Tratamiento de la información recibida . . . } } Cuadro 4: Tratamiento de la información recibida con IsConnected() y ReceiveMsg() 3.4.3. Funcionamiento de la aplicación cliente La aplicación cliente permite la interconexión de todos los dispositivos de control ya mencionados (teléfono móvil, wiimote y reconocedor de voz) con la aplicación de control de Roomba permitiendo el envío de mensajes de forma totalmente transparente, podemos decir que se trata del módulo de comunicaciones de la aplicación Roomba aunque realmente se traten de dos aplicaciones diferentes. La aplicación cliente ofrece la posibilidad de configurar todos los sockets de comunicaciones con otras aplicaciones, el método de configuración es a través de un archivo de configuración denominado config_sys.ini, cuya estructura se muestra en la Ilustración 33, podemos ver que existen secciones, que comienzan con el nombre de la sección entre corchetes, [nombre_de_sección], existe una sección para cada uno de las aplicaciones de control de las distintas interfaces, cada una de estas secciones presenta dos entradas, que son “ip_equipo” en donde está la dirección del socket que queremos utilizar e “id_socket” con el número de socket que vamos a utilizar. Proyecto fin de carrera 93 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 33: Vista del archivo de configuración 'config_sys.ini' 3.4.4. Implementación de la aplicación cliente A continuación comentaremos la implementación llevada a cabo en el desarrollo de la aplicación cliente de forma que cumpla los requisitos anteriormente descritos. Como se ve en la Ilustración 34 el flujo principal del programa es un bucle continuo. Debido a esto debemos tener especial cuidado en que el flujo del programa no se pueda quedar atascado en ningún punto, por ejemplo esperando a que algún dispositivo se conecte, o que transmita información, etc. ya que si esto ocurriese no se verificarían los requisitos ni de robustez ni flexibilidad, así mismo el programa no debe darse por vencido en caso de que alguna de los dispositivos no se encuentre conectado en algún momento, ya que en cualquier momento puede intentar conectarse. Con objetivo de comprobar continuamente si existe una aplicación que se acaba de conectar, el programa principal hace uso de las funciones conecta_sockets(), que se detallan más adelante y de check_sockets() que como se puede observar en su implementación en el Cuadro 6 comprueba el estado de las conexiones y actualiza la estructura de estado de las conexiones sockets. Proyecto fin de carrera 94 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Una vez se conoce el estado de las conexiones va viendo si alguna de las interfaces que están conectadas tiene información pendiente de transmitir a la aplicación Roomba en caso afirmativo transmite esa información y continúa la comprobación con el resto de interfaces. Ilustración 34: Diagrama de flujo de la aplicación cliente La implementación del flujo principal de la aplicación cliente, Cuadro 5, reproduce lo que se puede ver en el diagrama de flujo de la aplicación, Ilustración 34 y se puede observar también que en caso de conectarse con la aplicación Servivox debe recibir como primera cadena cuando se conecta “estimarRuido” para que la conexión sea válida. Y a su vez el cliente debe responder con la cadena “ruido”. Proyecto fin de carrera 95 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. void main(int argc,char *argv[]){ estado.reconocedor=0; estado.roomba=0; estado.wiimote=0; estado.movil=0; char bufin[1024]; IMPRIME_TRACE(1,"CLIENTE\n"); cl.Init("127.0.0.1",6003, SOCKET_CLIENT; cl_roomba.Init("127.0.0.1",6004, SOCKET_CLIENT); wiimote.Init("127.0.0.1",6005, SOCKET_CLIENT); movil.Init("127.0.0.1",6006, SOCKET_CLIENT); conecta_sockets(); while (1){ int ret=sizeof(bufin); if(estado.movil||estado.roomba){ if (movil.ReceiveMsg (bufin, &ret, 500) == 0){ bufin[ret] = 0; cl_roomba.SendMsg (bufin, strlen(bufin)); } } if(estado.wiimote||estado.roomba){ if (wiimote.ReceiveMsg (bufin, &ret, 500) == 0){ bufin[ret] = 0; cl_roomba.SendMsg (bufin, strlen(bufin)); } } if(estado.reconocedor||estado.roomba){ if (cl.ReceiveMsg (bufin, &ret, 500) == 0){ bufin[ret] = 0; if (strcmpi(bufin,"estimarRuido")==0){ Sleep(1000); cl.SendMsg ("ruido", strlen("ruido")); }else{ cl_roomba.SendMsg (bufin, strlen(bufin)); } } } conecta_sockets(); check_sockets(); } } Cuadro 5: Implementación del flujo principal de la aplicación cliente Proyecto fin de carrera 96 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. void check_sockets(){ if(movil.IsConnected()){ estado.movil=1; }else{ estado.movil=0; } if(cl.IsConnected()){ estado.reconocedor=1; }else{ estado.reconocedor=0; } if(cl_roomba.IsConnected()){ estado.roomba=1; }else{ estado.roomba=0; } if(wiimote.IsConnected()){ estado.wiimote=1; }else{ estado.wiimote=0; } } Cuadro 6: Implementación de la función check_sockets() Si vemos el diagrama de flujo de conecta_sockets() Ilustración 35 y con más detalle la implementación de la función Cuadro 7, vemos que su función es comprobar en la estructura que contiene el estado de las conexiones si hay alguna conexión que no esté establecida y en caso de que así sea realiza un único intento de conexión, si consigue establecer la conexión actualiza con el valor correspondiente la estructura con el estado de las conexiones, si no continúa con el resto de interfaces. Ilustración 35: Diagrama de flujo para la conexión y manejo de la conexión CSocketNode en la aplicación cliente Proyecto fin de carrera 97 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. void conecta_sockets(){ check_sockets(); // Actualiza el valor de los flags if(!estado.movil){ do{ IMPRIME_TRACE(1,"conectando con el telefono movil...\n"); movil.HandleConnection(); }while(0); if(movil.IsConnected()) estado.movil=1; } if(!estado.reconocedor){ do{ IMPRIME_TRACE(1,"conectando con servidor reconocedor...\n"); cl.HandleConnection(); }while(0); if(cl.IsConnected()) estado.reconocedor=1; } if (!estado.roomba){ do{ IMPRIME_TRACE(1,"conectando con servidor roomba...\n"); cl_roomba.HandleConnection(); }while(0); if(cl_roomba.IsConnected()) estado.roomba=1; } if (!estado.wiimote){ do{ IMPRIME_TRACE(1,"conectando con servidor wiimote...\n"); wiimote.HandleConnection(); }while(0); if(wiimote.IsConnected()) estado.wiimote=1; } } Cuadro 7: Implementación de la función conecta_sockets() Proyecto fin de carrera 98 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. 3.5. El reconocedor de voz servivox 3.5.1. Introducción En este apartado trataremos de explicar las modificaciones necesarias efectuadas con objeto de poder comunicar Servivox con otras aplicaciones. Además realizaremos un experimento que nos permita determinar un umbral de confianza para el reconocedor de voz Servivox de manera que se pueda utilizar de la forma más óptima posible. En cualquier caso nunca se tratará de un umbral óptimo ya que este dependerá en gran medida de la voz del locutor y de la gramática que éste use, por esto decimos que nuestro objetivo es lograr un umbral de confianza lo más óptimo posible. La definión del umbral de confianza hace referencia al valor mínimo de confianza que debe otorgar el reconocedor a un elemento reconocido para que sea aceptado como correctamente reconocido. La necesidad de emplear este umbral surge ya que el reconocedor siempre ofrece al usuario una salida, mejor o peor, pero siempre ofrece un elemento reconocido. Puede ser que la frase se encuentre fuera de la gramática o que exista mucho ruido en el ambiente y la frase reconocida no se parezca en absoluto a la que el usuario dice. El uso del umbral en el reconocedor ayuda a filtrar las frases con niveles de confianza demasiado bajo. 3.5.2. Adaptación de la aplicación Servivox La aplicación Servivox genera la gramática que empleará en el reconocimiento a partir del fichero ’frases.comandos’. A este fichero se puede añadir todas las frases que queremos que el reconocedor conozca y asociar a cada una de ellas una orden, esta orden será enviada a través del socket definido para la comunicación con la aplicación cliente. La definición por defecto del fichero ‘frases.comandos’ es a siguiente: hola rumba -> orden[atiende] qué tal -> orden[atiende] atiende ahora -> orden[atiende] buenos días -> orden[atiende] buenas tardes -> orden[atiende] escúchame -> orden[atiende] desconecta -> orden[deja_atender] adiós -> orden[deja_atender] apágate -> orden[deja_atender] cerrar -> orden[deja_atender] avanza despacio -> orden[avanza_despacio] avanza -> orden[avanza_despacio] adelante -> orden[avanza_despacio] arranca -> orden[avanza_despacio] Proyecto fin de carrera 99 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. muévete hacia delante -> orden[avanza_despacio] hacia atrás -> orden[retrocede] retrocede -> orden[retrocede] atrás -> orden[retrocede] retrocede -> orden[retrocede] marcha atrás -> orden[retrocede] avanza rápido -> orden[avanza_rapido] avanza más rápido -> orden[avanza_rapido] adelante rápido -> orden[avanza_rapido] arranca rápido -> orden[avanza_rapido] muévete rápido -> orden[avanza_rapido] gira a la derecha -> orden[gira_despacio_derecha] gira a la derecha despacio -> orden[gira_despacio_derecha] a la derecha -> orden[gira_despacio_derecha] a la derecha despacio -> orden[gira_despacio_derecha] derecha -> orden[gira_despacio_derecha] derecha despacio -> orden[gira_despacio_derecha] giro a la derecha -> orden[gira_despacio_derecha] giro a la derecha despacio -> orden[gira_despacio_derecha] gira a la derecha rápido -> orden[gira_rapido_derecha] gira a la derecha más rápido -> orden[gira_rapido_derecha] a la derecha rápido -> orden[gira_rapido_derecha] a la derecha más rápido -> orden[gira_rapido_derecha] derecha rápido -> orden[gira_rapido_derecha] derecha más rápido -> orden[gira_rapido_derecha] giro a la derecha rápido -> orden[gira_rapido_derecha] giro a la derecha más rápido -> orden[gira_rapido_derecha] gira a la izquierda -> orden[gira_despacio_izquierda] gira a la derecha izquierda -> orden[gira_despacio_izquierda] a la izquierda -> orden[gira_despacio_izquierda] a la izquierda despacio -> orden[gira_despacio_izquierda] izquierda -> orden[gira_despacio_izquierda] izquierda despacio -> orden[gira_despacio_izquierda] giro a la izquierda -> orden[gira_despacio_izquierda] giro a la izquierda despacio -> orden[gira_despacio_izquierda] gira a la izquierda rápido -> orden[gira_rapido_izquierda] gira a la izquierda más rápido -> orden[gira_rapido_izquierda] a la izquierda rápido -> orden[gira_rapido_izquierda] a la izquierda más rápido -> orden[gira_rapido_izquierda] izquierda rápido -> orden[gira_rapido_izquierda] izquierda más rápido -> orden[gira_rapido_izquierda] giro a la izquierda rápido -> orden[gira_rapido_izquierda] Proyecto fin de carrera 100 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. giro a la izquierda más rápido -> orden[gira_rapido_izquierda] párate ya -> orden[para] quieta -> orden[para] detente -> orden[para] para ya -> orden[para] párate ahí -> orden[para] no te muevas más -> orden[para] quédate ahí -> orden[para] frénate -> orden[para] para -> orden[para] limpia la habitación -> orden[aspira] limpia la casa -> orden[aspira] limpia -> orden[aspira] aspira la habitación -> orden[aspira] aspira la casa -> orden[aspira] aspira -> orden[aspira] limpia el suelo -> orden[aspira] quita el polvo -> orden[aspira] vuelve a casa -> orden[a_casa] a casa -> orden[a_casa] busca tu casa -> orden[a_casa] vuelve a cargarte -> orden[a_casa] encuentra tu casa -> orden[a_casa] encuentra tu cargador -> orden[a_casa] vuelve al inicio -> orden[a_casa] busca el punto de inicio -> orden[a_casa] de la vuelta -> orden[da_la_vuelta] sentido contrario -> orden[da_la_vuelta] cambia de orientación -> orden[da_la_vuelta] 3.5.3. Evaluación de Servivox 3.5.3.1. Metodología de evaluación La confianza en el reconocimiento es un valor que Servivox calcula en función de la gramática que tiene previamente almacenadas, esto es el vocabulario, y las probabilidades acústicas, y la frase que ha obtenido en el reconocimiento. En base a este cálculo fija un valor de confianza de forma que si supera el umbral que hemos establecido enviará el comando que hemos asociado a esa frase y simplemente indicará la frase que hemos establecido. Proyecto fin de carrera 101 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 36: Vista de Servivox con el umbral de confianza ajustada a 0,71. La gramática de la que hace uso Servivox y que previamente tenemos que enseñarle se compone de una serie de palabras que conforman el vocabulario con una tras codificación que indica la forma en que esas palabras se pronuncian, de forma que cuando Servivox reconozca esa cadena de fonemas podrá saber de qué palabra se trata de las que se encuentran en su vocabulario, esto es importante, ya que aunque el reconocedor tenga cada fonema por separado solo aceptará como válidas aquellas cadenas que le hayamos enseñado previamente, en la Ilustración 37 podemos ver un ejemplo de archivo con la información fonética, que se almacenan en archivos *.dic. Además de esta información Servivox genera otro tipo de datos obtenidos de la misma fuente que el vocabulario, se trata de las relaciones entre las diferentes palabras que conforman ese vocabulario, este dato ayuda a aportar un dato sobre la confianza que el reconocedor tiene sobre la frase que obtiene en el proceso de reconocimiento. Ilustración 37: Imagen que muestra el contenido de un archivo de diccionario. Proyecto fin de carrera 102 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Para realizar la evaluación del umbral de decisión partimos de un conjunto de frases cada una de las cuales tiene varias interpretaciones realizadas por diversos locutores. Partiendo de este conjunto de frases debemos crear dos conjuntos disjuntos, a uno lo denominaremos ‘frases conocidas’ y al otro ‘frases desconocidas’. Como su propio nombre indica, el conjunto de ‘frases conocidas’ serán aquellas que usemos para generar la gramática del reconocedor de forma que cuando alguna de las muestras de este conjunto llegue al reconocedor este no debería tener problemas para reconocer lo que se está diciendo puesto que conoce la frase exacta, evidentemente esto no será siempre cierto, ya que el reconocedor no está adaptado al locutor, y por lo tanto no siempre se realizará un correcto reconocimiento. Ilustración 38: Conjunto 'frases conocidas' Por otro lado ninguna de las frases que contiene el conjunto ‘frases desconocidas’ son conocidas como tal por el reconocedor, si que puede conocer muchas de las palabras que forman esas frases, pero no la estructura entera, de esta forma todas las frases que del conjunto ‘frases desconocidas’ que le pasemos al reconocedor deben ser mal reconocidas y por lo tanto el umbral óptimo será aquel que rechace todas estas. Ilustración 39: Conjunto 'frases desconocidas' Proyecto fin de carrera 103 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Para realizar el experimento que nos permita calcular un umbral lo más óptimo posible debemos, por un lado coger elementos de ‘frases conocidas’ y de ‘frases desconocidas’, enviarlos al reconocedor y observar la salida. Con esta información debemos buscar el umbral que permita hacer máxima la probabilidad de aceptar las conocidas y descartar las desconocidas, esto es: max{Paceptar(‘frases conocidas’)+Prechazar(‘frases desconocidas’)} Por otro lado, debemos usar un subconjunto de frases de ambos conjuntos para realizar la evaluación del umbral. Es decir, el experimento da como resultado un umbral óptimo para esa situación en concreto, ya que, nosotros seleccionamos ese umbral porque cumple las condiciones que nosotros exigimos. Ahora es necesarios ver cómo de bueno es este umbral, y para hacerlo, cogemos un conjunto de frases disjunto al que hemos utilizado en el entrenamiento y vemos cuanto ‘frases conocidas’ acepta y cuantas ‘frases desconocidas’ rechaza. Proyecto fin de carrera 104 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 40: Conjuntos para entrenamiento y test Evidentemente cuantos más experimentos se realicen los resultados obtenidos se aproximaran más a la realidad. En nuestro caso se han realizado siete experimentos diferentes variando los conjuntos de entrenamiento y test. 3.5.3.2. Resultados Una vez hemos realizado los conjuntos de train y test, podemos introducir los conjuntos en el reconocedor y registrar los resultados obtenidos. Para hacerlo creamos una estructura que vaya acumulando el número de veces que cada uno de los umbrales es correcto para cada una de las ejecuciones del reconocedor, por lo tanto tenemos que distinguir si estamos trabajando con el conjunto de frases conocidas o desconocidas para el reconocedor, y si la salida del reconocedor es correcta o no. Según lo anterior si, partimos de un elemento del conjunto de frases conocidas y esta frase es reconocida correctamente con un cierto grado de fiabilidad, debemos señalar que ese nivel es correcto para esa frase y todos los Proyecto fin de carrera 105 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. anteriores también, ya que si obtenemos una confianza de 0.8, cualquier valor inferior a este aceptará la frase como correctamente reconocida. Por el contrario, si la frase no está bien reconocida, lo que haremos es indicar que todos los umbrales por encima del nivel de confianza obtenido son los correctos para esa frase, ya que son los que la clasifican de forma correcta. Si ahora hablamos de elementos del conjunto de frases desconocidas tenemos justamente lo opuesto, cuando detectamos una frase incorrectamente reconocida establecemos que los umbrales por encima del nivel de confianza determinada clasifican la frase de forma correcta. Si la frase, aún no perteneciendo al conjunto conocido, es correctamente reconocida (recordemos que esto puede pasar ya que, aunque la frase no pertenece al conjunto las palabras individualmente si lo hacen) los umbrales de confianza por debajo de la confianza del reconocedor serán marcados como correctos para la clasificación. Una vez tenemos recabada toda la información podemos presentarla de forma gráfica de forma que podamos analizar más fácilmente la información de los experimentos. A continuación mostraremos y analizaremos los resultados del segundo experimento y explicaremos la metodología de análisis y extracción de información para presentar los resultados. En primer lugar, la imagen Ilustración 41 muestra, en número absoluto, el número de frases conocidas y desconocidas que son bien clasificadas por cada uno de los umbrales Número de frases correctamente clasificadas 400 350 300 Desconocid as 250 Frases conocidas 200 150 100 50 96 92 88 84 80 76 72 68 64 60 56 52 48 44 40 36 32 28 24 20 16 8 12 4 0 0 Ilustración 41: Número de frases correctamente reconocidas por nivel de umbral . Si estudiamos que porcentaje de cada uno de los conjuntos se clasifica correctamente obtenemos la Ilustración 42 de la que se pueden extraer varias 106 Proyecto fin de carrera Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. observaciones. Lo primero que se puede observar es como la tendencia de las dos curvas es totalmente diferente, por una parte las frases conocidas mantienen un nivel casi constante independientemente del umbral, esto hecho concuerda con la teoría, si estamos utilizando frases conocidas incluidas en la gramática del reconocedor lo normal es que este las reconozca bien y por lo tanto cualquier umbral permita una buena clasificación de la muestra. Evidentemente cuanto más estricto sea el umbral más, confianza necesitamos en el reconocimiento y debido a esto existe un pequeño descenso en la curva en la zona alta. El porcentaje de frases desconocidas bien reconocidas también sufre una evolución previsible. A priori lo que ocurre con los elementos de este conjunto es que serán mal clasificados si el umbral es demasiado bajo; si el umbral es cero se aceptarán frases con una confianza muy baja; a medida que aumentamos el umbral la capacidad de clasificación va mejorando hasta conseguir un punto máximo, seguido de un pequeño descenso. Porcentaje de frases correctamente clasificadas 90 Porcentaje Conocidas 80 Porcntaje desconoci das 70 60 50 40 96 92 88 84 80 76 72 68 64 60 56 52 48 44 40 36 32 28 24 20 16 12 8 4 0 30 Umbral Ilustración 42: Porcentaje de frases correctamente clasificadas por nivel de umbral Finalmente podemos fusionar toda la información de frases conocidas y desconocidas y elaborar una representación conjunta del porcentaje de frases conocidas y desconocidas bien clasificadas para cada umbral, dando como resultado la Ilustración 42. Esta es el gráfico que aporta mayor información sobre los resultados del entrenamiento del reconocedor de voz Además se muestra el intervalo de confianza al 95% que indica el rango de incertidumbre que tenemos sobre el resultado obtenido de manera que cualquier valor dentro de ese intervalo es igualmente válido. Proyecto fin de carrera 107 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. El porcentaje de frases correctamente clasificadas viene determinado por el número de frases reconocidas correctamente y cuya confianza se encuentra por encima del umbral y las frases reconocidas incorrectamente y con la confianza por debajo del umbral, es decir: frases_correctamente_clasificadas =Nºfrases_correctas(confianza>umbral)+Nºfrases_incorrectas(confianza<umbral) Una vez calculado el número de frases correctamente clasificadas del conjunto de test, evaluamos el tanto por ciento sobre el número total de frases del conjunto test. Ilustración 43: Definición de los umbrales empleados en la evaluación A continuación se muestran los resultados obtenidos en los siete conjuntos de evaluación utilizados durante los experimentos. Proyecto fin de carrera 108 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Experimento 1 La Ilustración 44 muestra los resultados obtenidos después de entrenar el reconocedor con el subconjunto 1. Resultados, Conjunto 1 Porcentaje de frases correctamente clasificadas 90 85 80 75 70 65 60 55 50 45 40 1 8 15 22 29 36 43 50 57 64 71 Umbral 78 85 92 99 Ilustración 44: Resultados de clasificación del conjunto de test 1 A partir de la gráfica determinamos los umbrales alto, medio y bajo así como el punto máximo. A partir de ahí evaluamos el porcentaje de frases que están correctamente clasificadas para cada uno de esos umbrales. Valor Umbral alto 0,85 Nº de frases correctamente clasificadas 56 Porcentaje Umbral medio Umbral bajo 0,65 0,50 58 56 77,33 % 74,66 % Punto máximo 0,98 55 73,33 % 74,66 % Tabla 18: Resultados del conjunto de test 1 Proyecto fin de carrera 109 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Experimento 2 La Ilustración 45 muestra los resultados obtenidos después de entrenar el reconocedor con el subconjunto número 2. Resultados, Conjunto 2 90 Porcentaje de frases correctamente clasificadas 85 80 75 70 65 60 55 50 45 40 1 8 15 22 29 36 43 50 57 64 71 78 85 92 99 Umbral Ilustración 45: Resultados de clasificación del conjunto de test 2 A partir de la gráfica determinamos los umbrales alto, medio y bajo así como el punto máximo. A partir de ahí evaluamos el porcentaje de frases que están correctamente clasificadas para cada uno de esos umbrales. Valor Umbral alto 0,96 Nº de frases correctamente clasificadas 27 Porcentaje Umbral medio Umbral bajo 0,77 0,55 40 27 53,33 % 36 % Punto máximo 0,86 27 36 % 36 % Tabla 19: Resultados del conjunto de test 2 Proyecto fin de carrera 110 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Experimento 3 La Ilustración 46 muestra los resultados obtenidos después de entrenar el reconocedor con el subconjunto número tres. Resultados, Conjunto 3 90 Porcentaje de frases correctamente clasificadas 85 80 75 70 65 60 55 50 45 40 1 8 15 22 29 36 43 50 57 64 71 78 85 92 99 Umbral Ilustración 46: Resultados de clasificación del conjunto de test 3 A partir de la gráfica determinamos los umbrales alto, medio y bajo así como el punto máximo. A partir de ahí evaluamos el porcentaje de frases que están correctamente clasificadas para cada uno de esos umbrales. Valor Umbral alto 0,97 Nº de frases correctamente clasificadas 56 Porcentaje Umbral medio Umbral bajo 0,71 0,50 59 57 78,66 % 76 % Punto máximo 0,87 57 76 % 74,66 % Tabla 20: Resultados del conjunto de test 3 Proyecto fin de carrera 111 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Experimento 4 La Ilustración 47 muestra los resultados obtenidos después de entrenar el reconocedor con el subconjunto número cuatro. Resultados, Conjunto 4 90 Porcentaje de frases correctamente clasificadas 85 80 75 70 65 60 55 50 45 40 1 8 15 22 29 36 43 50 Umbral 57 64 71 78 85 92 99 Ilustración 47: Resultados de clasificación del conjunto de test 4 A partir de la gráfica determinamos los umbrales alto, medio y bajo así como el punto máximo. A partir de ahí evaluamos el porcentaje de frases que están correctamente clasificadas para cada uno de esos umbrales. Valor Umbral alto 0,96 Nº de frases correctamente clasificadas 58 Porcentaje Umbral medio Umbral bajo 0,77 0,53 60 55 80 % 73,33 % Punto máximo 0,87 87 61 % 77,33 % Tabla 21: Resultados del conjunto de test 4 Proyecto fin de carrera 112 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Experimento 5 La Ilustración 48 muestra los resultados obtenidos después de entrenar el reconocedor con el subconjunto número cinco. Resultados, Conjunto 5 90 Porcentaje de frases correctamente clasificadas 85 80 75 70 65 60 55 50 45 40 1 8 15 22 29 36 43 50 57 64 Umbral 71 78 85 92 99 Ilustración 48: Resultados de clasificación del conjunto de test 5 A partir de la gráfica determinamos los umbrales alto, medio y bajo así como el punto máximo. A partir de ahí evaluamos el porcentaje de frases que están correctamente clasificadas para cada uno de esos umbrales. Valor Umbral alto 0,98 Nº de frases correctamente clasificadas 54 Porcentaje Umbral medio Umbral bajo 0,75 0,55 60 56 80 % 74,66 % Punto máximo 0,86 59 78,66 % 72 % Tabla 22: Resultados del conjunto de test 5 Proyecto fin de carrera 113 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Experimento 6 La Ilustración 49 muestra los resultados obtenidos después de entrenar el reconocedor con el subconjunto número seis. Resultados, Conjunto 6 Porcentaje de frases correctamente clasificadas 90 85 80 75 70 65 60 55 50 45 40 1 8 15 22 29 36 43 50 57 64 71 78 85 92 99 Umbral Ilustración 49: Resultados de clasificación del conjunto de test 6 A partir de la gráfica determinamos los umbrales alto, medio y bajo así como el punto máximo. A partir de ahí evaluamos el porcentaje de frases que están correctamente clasificadas para cada uno de esos umbrales. Valor Umbral alto 0,92 Nº de frases correctamente clasificadas 50 Porcentaje Umbral medio Umbral bajo 0,71 0,52 50 42 66,66 % 56 % Punto máximo 0,86 50 66,66 % 66,66 % Tabla 23: Resultados del conjunto de test 6 Proyecto fin de carrera 114 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Experimento 7 La Ilustración 50Ilustración 46 muestra los resultados obtenidos después de entrenar el reconocedor con el subconjunto número siete. Resultados, Conjunto 7 90 Porcentaje de frases correctamente clasificadas 85 80 75 70 65 60 55 50 45 40 1 8 15 22 29 36 43 50 Umbral 57 64 71 78 85 92 99 Ilustración 50: Resultados de clasificación del conjunto de test 7 A partir de la gráfica determinamos los umbrales alto, medio y bajo así como el punto máximo. A partir de ahí evaluamos el porcentaje de frases que están correctamente clasificadas para cada uno de esos umbrales. Valor Umbral alto 0,97 Nº de frases correctamente clasificadas 56 Porcentaje Umbral medio Umbral bajo 0,69 0,51 58 56 77,33 % 74,66 % Punto máximo 0,86 57 76 % 74,66 % Tabla 24: Resultados del conjunto de test 7 Proyecto fin de carrera 115 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. 3.5.3.3. Conclusiones Para presentar las conclusiones podemos ver el conjunto de los resultados obtenidos y determinar un valor promedio óptimo y aconsejado para establecer como valor del umbral de confianza. Experim ento U.alto U.medio U.bajo Pto. máximo % correctas u.alto % correctas u. medio % correctas u. bajo % correctas punto max 1 2 3 4 5 6 7 0,85 0,96 0,97 0,96 0,98 0,92 0,97 0,94 0,65 0,77 0,71 0,77 0,75 0,71 0,69 0,72 0,50 0,55 0,50 0,53 0,55 0,52 0,51 0,52 0,98 0,86 0,87 0,87 0,86 0,86 0,86 0,88 74,66 36 74,66 77,33 72 66,66 74,66 67,99 77,33 53,33 78,66 80 80 66,66 77,33 73,33 74,66 36 76 73,33 74,66 56 74,66 66,47 73,33 36 76 61 78,66 66,66 76 66,80 Promedio Los resultados de la tabla anterior se pueden observar en la Ilustración 51 de forma gráfica. Las barras verdes representan el porcentaje de frases correctamente clasificadas en cada uno de los experimento para los tres umbrales empleados. Así mismo se puede ver destacado en color azul el promedio de las frases correctamente clasificadas en los siete experimentos. Pocentaje de frases correctamente clasificadas 90 80 70 60 50 40 30 Umbral alto Umbral medio Umbral bajo Ilustración 51: Gráfica con los resultados de clasificación Como se puede apreciar estudiando los resultados finales de las pruebas, los niveles de umbral situados en la zona entorno a 0,72 proporcionan, en media, la mejor respuesta del sistema. La razón de los buenos resultados obtenidos por estos valores viene determinada en gran medida por el compromiso que supone entre lograr el rechazo de frases 116 Proyecto fin de carrera Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. erróneas pero con la suficiente flexibilidad para que el reconocedor no tenga que obtener una confianza absoluta en su resultado. Por otro lado se puede ver que los porcentajes de frases correctamente reconocidas a nivel bajo y alto son muy parecidos, un 66,99% para el umbral promedio alto y un 66,47 % para el bajo. Sin embargo, pese al parecido en los resultados, la procedencia de ambos es bien distinta, si analizamos estos resultados teniendo en cuenta la evolución del número de frases conocidas y desconocidas bien clasificadas en función del umbral. Conocidas correctas 1 Umbral alto promedio (Umbral=0,94) 80,18 Umbral bajo promedio (Umbral=0,52) 87,83 Conocidas correctas 2 78,73 84,23 Conocidas correctas 3 78,82 82,43 Conocidas correctas 4 78,37 82,43 Conocidas correctas 5 77,47 81,53 Conocidas correctas 6 77,47 81,53 Conocidas correctas 7 76,57 81,98 Promedio 78,23 83,13 Tabla 25: Frases conocidas correctamente clasificadas según el umbral Umbral alto promedio (Umbral=0,94) Desconocidas correctas 1 65,35 Umbral bajo promedio (Umbral=0,52) 30,26 Desconocidas correctas 2 78,07 60,08 Desconocidas correctas 3 78,50 64,03 Desconocidas correctas 4 77,19 60,08 Desconocidas correctas 5 78,50 59,21 Desconocidas correctas 6 79,38 60,96 Desconocidas correctas 7 77,19 61,40 Promedio 76,31 56,57 Tabla 26: Frases desconocidas correctamente clasificadas según el umbral Los resultados arrojados por las tablas, Tabla 25 y Tabla 26 y que se pueden observar de manera gráfica en las Ilustración 52 e Ilustración 53 que se muestran a continuación, ponen de manifiesto que si establecemos un umbral alto los resultados son muy semejantes tanto en frases conocidas como desconocidas con unas tasas de acierto en la clasificación entorno al 76%, lo que nos da una idea de que se rechazan demasiadas frases que aun siendo Proyecto fin de carrera 117 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. conocidas no alcanzan una confianza lo suficiente alta para catalogarlas de bien reconocidas. Por otro lado, si establecemos un umbral bajo la diferencia de porcentajes entre conocidas y desconocidas se agudiza, el porcentaje de frases conocidas correctamente conocidas se sitúa por encima del 80% en todos los casos de estudio mientras que las tasas para las frases desconocidas se sitúa en valor promedio por debajo del 60%. El análisis de estos resultados confirma las premisas de que establecer un valor demasiado bajo del umbral de confianza provoca que las frases conocidas sean prácticamente bien clasificadas en su totalidad, es decir casi todas las frases serán bien reconocidas y con un valor de confianza por encima del umbral. Por el contrario, muchas frases desconocidas serán aceptadas debido a la baja confianza que se le exige al reconocimiento de forma que muchas de ellas se encuentren mal clasificadas. Umbral alto promedio (Umbral=0,92) 85 80 75 70 65 60 55 50 Frases conocidas Frases desconocidas Ilustración 52: Frases correctamente clasificadas empleando el umbral alto promedio Proyecto fin de carrera 118 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Umbral bajo promedio (Umbral=0,52) 100 90 80 70 60 50 40 30 20 10 0 Frases conocidas Frases desconocidas Ilustración 53: Frases correctamente clasificadas empleando el umbral bajo promedio Recapitulando los resultados obtenidos y las conclusiones obtenidas podemos sintetizar que un valor demasiado bajo del umbral de confianza provoca excesivos errores de clasificación al dar por válidas frases con confianza demasiado bajas y un umbral de confianza demasiado alto provoca que la exigencia de confianza que requerimos sea cumplida por pocas de las frases de forma que las tasas de frases correctamente clasificadas decaen. Por lo tanto la mejor solución pasa por un compromiso fijando un umbral de confianza entorno a 0,72. Con lo dicho en el párrafo anterior no se descarta que en algunas ocasiones sea necesario el uso de umbral alto o bajo ya que debemos tener en cuenta la aplicación en la que queremos integrar nuestra aplicación. Pensemos por un momento que pretendemos usar el reconocedor de voz para una aplicación en la que el requisito fundamental en la fiabilidad del sistema, por ejemplo control de robots como es el caso de este proyecto, el empleo de un umbral demasiado bajo podría provocar resultados inesperados que afecten gravemente a la integridad del sistema. En estos casos el empleo de un umbral alto que nos garantice una buena fiabilidad aún a riesgo de perder eficiencia, quizás tengamos que repetir varias veces el mismo comando hasta que el reconocedor obtenga una confianza adecuada, es la mejor solución ya que así nos evitaremos muchos de los errores de los que antes hablábamos. En lado opuesto podemos encontrarnos con aplicaciones que requieran ejecutarse en tiempo real asumiendo la posibilidad de tasas de error elevadas. En cualquier caso es necesario tener muy presente los requerimientos de la aplicación con la que trabaje el reconocedor de voz a la hora de establecer un umbral de confianza óptimo. Proyecto fin de carrera 119 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. 3.6. Aplicación de gestión de Wiimote 3.6.1. Wiimote El dispositivo comercial wiimote es el mando principal de la popular videoconsola Wii de la empresa Nintendo. Sus características más destacables son la capacidad de movimiento en el espacio y la transmisión de esta información a través de Bluetooth utilizando el perfil HID [2]. Ilustración 54: Vista frontal, lateral y posterior del wiimote En su cara frontal, el Wiimote presenta los botones “A”, “1”, “2”, ”+”, ””,”HOME” y ”POWER”, junto a un pad. En la parte posterior solo presenta el botón “B”, en un formato similar a un gatillo, la información sobre el estado de estos botones también se transmite vía bluetooth. Adicionalmente, en su parte frontal incluye un altavoz y cuatro LEDs numerados [16]. El Wiimote consta de un acelerómetro, que es un instrumento para medir la aceleración, detectar o medir vibraciones, o medir aceleración debida a la gravedad (inclinación). El acelerómetro que lleva instalado el Wiimote es el ADXL330, un chip MEMS (sistema micro electro-mecánico) de Analog Devices, y este dispositivo es capaz de medir tanto la aceleración como la dirección del movimiento o la rotación de sus tres ejes. Proyecto fin de carrera 120 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 55: Chip ADXL330 Básicamente, el funcionamiento de este acelerómetro se basa en un trozo de silicio, sujeto a un extremo, y colocado en el seno de un campo eléctrico generado en una estructura capacitiva [17]. De esta forma cuando se realizan movimientos con el Wiimote estos movimientos se transmiten al trozo de silicio, provocando que se desplace dentro del campo eléctrico Ilustración 56, esta variación hace que la capacidad de la estructura varíe, esta variación es fácilmente detectable y medible, y es lo que posteriormente será interpretado para indicar el movimiento realizado. Ilustración 56: Esquema interno de un acelerómetro ADXL330 En el frontal del Wiimote se encuentra un plástico oscuro translucido, tras el cual se encuentra el emisor infrarrojo MOT (Multi-Object Tracking). Este sensor rastrea visualmente objetos múltiples, con una resolución de un megapixel, pudiendo rastrear desde 0 a 10023 grados en horizontal, y desde 0 hasta 767 grados en vertical. Pero claro, este sensor por si solo no funciona, necesita hacer uso de una barra sensora que se coloca junto al televisor la cual posee cuatro leds infrarrojos en ambos extremos. El sensor del Wiimote localiza estos leds conformando los extremos de una “pantalla virtual”, que será un campo de acción relativo cerca del televisor. Para que funcione correctamente habrá que configurar la consola, indicando la posición de la barra y la relación de aspecto de nuestro televisor (16:9 o 4:3). Destacar que cuando el sensor MOT del Wiimote pierde la barra o el campo de acción, el sensor de aceleración y giro, mide la aceleración lineal y los rangos de rotación, ofreciendo valores aproximados de la posición y rotación del wiimote. Cuando el mando entra de nuevo en contacto con la barra, se recalibrarán automáticamente la posición y rotación [16]. Proyecto fin de carrera 121 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 57: Sistema de coordenadas definido sobre el Wiimote con las definiciones de sus movimientos Las definiciones de pitch y roll serán con las que trabajemos para de alguna forma gestionar y transformar los movimientos realizados con el wiimote a mensajes en el formato Roomba que permita su control. Debido a que la definición de pitch y roll se realiza como movimientos sobre alguno de los ejes coordenados, para su definición matemática basta tener en cuenta las aceleraciones medidas en cada uno de los ejes de forma que: roll = arctan 2 (ax , (a y + a z ) ) (1) pitch = arctan 2 (a y , (a x + az ) ) (2) 2 2 2 2 3.6.1.1. Memoria interna El Wiimote dispone de 16KB de memoria en un chip de EEPROM donde una sección de 6 kilobytes puede ser libremente leída y escrita lo que permite al usuario guardar los datos de configuración del controlador para el Wiimote. 3.6.1.2. Alimentación El Wiimote utiliza dos pilas AA como fuente de energía, que pueden alimentar el Wiimote durante 60 horas usando solamente las funciones de acelerometría y 25 horas utilizando acelerómetros y la cámara de infrarrojos. Aunque el fabricante desaconseja otros tipos de baterías recargables como las de iones de litio (Li-ion) y níquel-cadmio (NiCd), la asistencia del sitio web de la Proyecto fin de carrera 122 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. empresa indica que baterías recargables de níquel-hidruro metálico (NiMH) pueden ser utilizadas. 3.6.1.3. Interfaz de comunicación Una vez obtenemos los datos de detección de movimiento por parte de los acelerómetros y de situación a través de los infrarrojos se envían al chip Bluetooh de Broadcom Technologies que se encuentra integrado en la placa del mando. A su vez, todos estos datos son enviados desde el chip Bluetooth a otro chip Bluetooth Broadcom que se sitúa dentro de la consola (o en nuestro caso se enviará a un módulo Bluetooth instalado en nuestro PC). La comunicación se realiza utilizando la banda de los 2.4GHZ, proporcionando una corriente de datos de 2.1Mb/s, siendo más que suficiente para manejar a la vez hasta cuatro mandos que se pueden conectar vía bluetooth. El wiimote incorpora, en la parte posterior del mando, un puerto para la conexión de los diferentes periféricos que se pueden acoplar al Wiimote, como por ejemplo un Nunchuk, que incorpora un joystick analógico y un acelerómetro, aumentando considerablemente las posibilidades [16]. La conexión bluetooth se realiza implementado el perfil HID (Human Interface Device) de la pila de comunicaciones bluetooth. El estándar HID permite que los dispositivos se puedan describir a si mismos, utilizando un bloque descriptor de HID. Este bloque incluye una enumeración de informes que el dispositivo entiende. Un informe, puede ser visto como un puerto de una red, que está asignado con algún servicio en particular. La única diferencia, es que los reportes son unidireccionales, y el descriptor HID lista para cada puerto la dirección, ya sea de salida o bien de entrada, también dice cual será el tamaño de de la información útil para cada uno de los puertos. El PC puede pedir información al wiimote mediante el protocolo de descubrimiento de servicios, SDP, por sus siglas en inglés. En este caso, el Wiimote informará y devolverá una gran cantidad de información. En particular ofrece información sobre el vendedor y un identificador del producto, como podemos ver en el Cuadro 8. Requesting Information… BD Address: 00:19:1D:62:36:84 Device Name: Nintendo RVL-CNT-01 ID Vendedor:0x057e ID del Producto: 0x0306 LMP Version: 1.2 (0x2) LMP Subversion: 0x229 Manufacturer: Broadcom Corporation (15) Features: 0xbc 0x02 0x04 0x38 0x00 0x00 0x00 <encryption> <slot offset> <timing accuracy> <role switch> <sniff mode> <RSSI> <power control> <enhance iscam> <interlaced iscam> <interlaced pscan> <AFH cap. slave> Cuadro 8: Sección del bloque de autodescripción HID del Wiimote Proyecto fin de carrera 123 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. A partir de esta información podemos localizar el tipo de dispositivo que está enviando informes, en caso de que estemos buscando alguno en concreto debemos conocer su ID de vendedor y producto. El Wiimote envía reportes al host, con una frecuencia máxima de 100 informes por segundo. Ahora bien, el PC que tenga conexión con él, debe poner el wiimote en modo descubrimiento de servicios, esto se logra al apretar los botones 1 y 2 al mismo tiempo, o al apretar el botón rojo de sincronización, que se encuentra en la parte de atrás, cerca de la batería. Una vez que se encuentra en este modo, el HID driver del host, puede empezar a pedirle información al Wiimote. Pero, si el driver HID del host no logra conectarse con el Wiimote, en menos de 20 segundos, el Wimote se apagará. Apretando los botones 1 y 2 continuamente, hará que el Wiimote se tenga que mantener en modo descubrimiento, por lo que no se apagará. Esto, no funciona cuando se utiliza el botón sincronizar. Cuando se encuentra en modo de descubrimiento, los LEDs del Wiimote parpadearán. El número de parpadeos es directamente proporcional con lo que le queda de vida a las pilas. Salidas ID del reporte 0x11 Bytes de información 1 0x12 Entradas Función LEDs, motor ID del reporte 0x20 Bytes de información 6 Función 2 Tipo de informe/ID 0x21 21 Puerto de expansión Lee datos 0x13 1 0x22 4 Escribe datos 0x14 1 Habilita el sensor de IR Habilita altavoz 0x30 2 0x15 1 Devuelve el status 0x31 5 0x16 21 Escribe datos 0x32 16 0x17 6 Lee datos 0x33 17 0x18 21 0x34 21 0x19 1 Escribe datos de altavoz Silencia altavoz Es sólo para los botones Da un informe del estado de los botones Puerto de expansión para los botones Informe de estado sobre los movimientos y los botones. Puerto de expansión IR 0x1a 1 Habilita el sensor IR Tabla 27: Reportes de wiimote Proyecto fin de carrera 124 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Teniendo en cuenta que la salida se refiere a paquetes que son enviados del host al wiimote y entrada se refiere a los paquetes que van del Wiimote al host, podemos observar en la Tabla 27 un pequeño recopilatorio de los informes que es posible enviar entre el wiimote y el host que esté gestionando el wiimote. Entonces para comunicarnos con el Wiimote tendremos que escribir: o la cabecera bluetooth o el ID del informe o la información útil Por ejemplo, tenemos: (a1) 30 00 00, con la cabecera bluetooth entre paréntesis. Es un paquete de datos de entrada (0xa1), en el canal 0x30, con 2 bytes de informe 0x00, 0x00. 3.6.1.4. Gestión de paquetes bluetooth Una vez conocido el protocolo de comunicación tendremos que examinar los paquetes que el dispositivo nos va enviando y analizarlo convenientemente para conocer el estado de cada uno de los botones, acelerómetros, etc… así mismo deberemos poder elaborar las estructuras de datos adecuadas para controlar el Wiimote, por ejemplo, iluminar o apagar los LEDs. Por suerte existen multitud de bibliotecas que se encargan de analizar los paquetes de bluetooth de wiimote, extraer la información necesaria y presentarla en un nivel de abstracción superior. Nosotros hemos elegido hacer uso de la biblioteca wiiuse.dll [21] por estar desarrollada en C y ofrecer un gran conjunto de herramientas que nos permiten tanto el envío como recepción de paquetes HID. 3.6.2. Implementación de la aplicación de gestión wiimote El objetivo del desarrollo de esta aplicación plantea con objetivo final, en primer lugar la conexión vía bluetooth con el dispositivo wiimote que permite abstraer al desarrollador del 3.6.2.1. La librería wiiuse Wiiuse.dll es un librería escrita en C que permite gestionar varias conexiones con mandos Wiimote ofreciendo una API que permite abstraer al desarrollador del nivel de capa bluetooth para centrarse en el desarrollo de la aplicación. Wiiuse está disponible en www.wiiuse.net [21] bajo licencia GNU GPLv3 y GNU LGPLv3 (non-commercial) y actualmente ofrece soporte tanto para los acelerómetros internos, IR tracking, nunchuk y guitar hero 3. 125 Proyecto fin de carrera Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. En cuanto a compatibilidad con la pila bluetooth, wiiuse se puede utilizar en sistemas Linux o Windows (2000, XP, Vista) utilizando la propia pila bluetooth de Microsoft como otras alternativas como son Bluesoleil (como es en el caso de este proyecto), Widcomn Stack o Toshiba Stack. 3.6.2.2. Librerías dinámicas, dll A modo de introducción pasaremos ahora a comentar las características que presenta el trabajo con bibliotecas dll [2][21]. Las dll o Dynamic Linking Library (Bibliotecas de Enlace Dinámico), es el término con el que nos referimos a los archivos con código ejecutable que cargan bajo demanda del programa por parte del sistema operativo. Esta denominación se refiere a los sistemas operativos Windows siendo la extensión con la que se identifican los ficheros, aunque el concepto existe en prácticamente todos los sistemas operativos modernos. Las dll pueden verse como la evolución de las bibliotecas estáticas y de forma análoga contienen funcionalidad o recursos que utilizan otras aplicaciones. Sin embargo, su uso propicia algunas ventajas: a. Reducen el tamaño de los archivos ejecutables, gran parte del código puede estar almacenado en bibliotecas y no en el propio ejecutable lo que favorece una mayor modularización del sistema global. b. Pueden existir dll compartidas entre varias aplicaciones, si el código suficientemente genérico, puede resultar de utilidad para múltiples aplicaciones. c. Facilitan la gestión y aprovechamiento de la memoria del sistema, la carga dinámica permite al sistema operativo aplicar algoritmos que mejoren el rendimiento del sistema cuando se carguen estas bibliotecas. Además, al estar compartidas, basta con mantener una copia en memoria para todos los programas que la utilicen. d. Brindan mayor flexibilidad frente a cambios, es posible mejorar el rendimiento o solucionar pequeños errores distribuyendo únicamente una nueva versión de la biblioteca dinámica. Sin embargo, no todo son ventajas. En los sistemas Windows, las DLLs son muy comunes y muchos programas usan las mismas DLLs, pero debido a la evolución, cada una de las DLLs evoluciona incorporando mejoras pero modificándolas de tal forma que dejan de ser compatibles. Esto puede producir dos efectos no deseados: 126 Proyecto fin de carrera Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. a. Que la instalación de un programa reemplace una DLL con una nueva versión incompatible. b. Que la instalación del programa borre una DLL compartida. 3.6.2.3. API de la librería Wiiuse La librería wiiuse se encuentra abundantemente documentada en el link ya mencionado en el apartado anterior, www.wiiuse.net, en donde se puede obtener toda la información necesaria sobre su compatibilidad con el stack bluetooth así como todo el potencial que puede ofrecer su API de la que vamos a mencionar las características más importantes para el desarrollo de este proyecto. La librería Wiiuse permite gestionar la conexión con varios dispositivos wiimote simultáneamente. Pero para poder utilizarlos en la aplicación los dispositivos deben estar previamente inicializados en el sistema. Es posible inicializar varios aunque después no se lleguen a usar. Mostraremos ahora las funciones de búsqueda y conexión con Gimotees más útiles ofrecidas por la libería. wiiuse_init() : permite inicializar un número máximo de dispositivos wiimote. Esta función devuelve un array de punteros hacia objetos wiimote que han sido inicializados pero todavía no se encuentran conectados. En el siguiente ejemplo se muestra la inicialización del array para un número máximo de dos dispositivos wiimote. wiimote** wiimotees = wiiuse_init(2); wiiuse_find() :una vez tengamos inicializadas las estructuras para gestionar el wiimote es el momento de buscarlos en el entorno las señales de dichos dispositivos. Siguiendo con el ejemplo buscaremos señales de un máximo de dos wiimotes diferentes durante un tiempo máximo de cinco segundos con la siguiente llamada a la función wiiuse_find(): int found=wiiuse_find(wiimotes,2,5); wiiuse_connect(): es el ultimo paso para establecer correctamente la comunicación, en algunos casos no es necesario ya que la propia wiiuse_find() consigue establecer correctamente la comunicación. Es buena práctica, sin embargo, utilizar wiiuse_connect() para asegurar que está conexión se establece correctamente. Proyecto fin de carrera 127 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. int connected=wiiuse_connect(wiimotes, 2); if (connected) printf(“Connected to %i wiimotes (of %i found).\n”,connected,found); else{ printf(“Failed to connect to any wiimote.\n”); return 0; } wiiuse_disconnect(), wiiuse_shutdown(): estas funciones permiten desconectar y limpiar las conexiones establecidas y las estructuras creadas. wiiuse_set_bluetooh_stack(): Utilizando wiiuse_find(), tratará de detectar de forma automática el bluetooth stack que el sistema está utilizando. Si es incapaz de encontrar la configuración bluetooth adecuada, o si conocemos de antemano el bluetooth stack que el sistema va a utilizar, por ejemplo, porque estamos utilizando un dispositivo USB que dispone de su propio software de gestión bluetooth, podemos establecer la configuración que queramos antes de llamar a wiiuse_find() void wiiimotees_set_bluetooth_stack(struct wiimote_t** wm, int wiimotees, enum win_bt_stack_t type); En el momento de escribir este proyecto wiiuse ofrece soporte para dos tipos de bluetooth stack: WIIUSE_STACK_BLUESOLEIL, permite el uso de la bluetooth stack de bluesoleil WIIUSE_STACK_MS, otra bluetooth stack diferente, probadas XP SP2 y widcomm wiiuse_poll(): Wiiuse está pensado para utilizarse como un sistema de polling no bloqueante, esto significa que necesitamos constantemente comprobar la existencia de un nuevo evento. La función wiiuse_poll() permite comprobar la existencia de eventos pasándole como parámetro el array de parámetros inicializados que obtuvimos con wiiuse_init() y el número máximo de wiimotes que estamos gestionando. Como resultado wiiuse_poll() devolverá el número de wiimotes en los que se ha producido un evento. int wiiuse_poll(struct wiimote_t** wm, int wiimotes); Ya que es necesario estar continuamente en un loop es aconsejable lanzar una hebra para el tratamiento de eventos y otro para el flujo principal del programa. Un ejemplo de bucle para realizar el polling es el siguiente: Proyecto fin de carrera 128 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. while(1){ if(wiiuse_poll(wiimotes,2)){ int i=0; for(; i < 2; ++i){ switch(wiimotes[i]->event){ /* Gestión de eventos */ } } } } La variable wiimote_t: event la fija la función wiiuse_poll() para indicar qué tipo de evento ha ocurrido. El valor que puede tener es alguno de los que se nombran en esta lista: o o WIIUSE_NONE: Ningún evento. WIIUSE_EVENT: Un evento genérico ha ocurrido en el wiimote. a. Se pulsa un botón b. Se deja de pulsar un botón c. Movimiento en el joystick d. Cambia la orientación del dispositivo un valor por encima del umbral e. La camara de IR detecta cambios o WIIUSE_STATUS: Informe sobre el estado del wiimote. a. Una extensión ha sido conectada al puerto de expansión del wiimote. b. Una extensión ha sido desconectada c. Respuesta enviada por una petición de estado wiiuse_status(). La información obtenida de un reporte de estado es la siguiente: o Si existe alguna extensión vinculada al wiimote. Si el altavoz esta funcionando. Que LEDs están encendidos. Estado de la batería (como un float entre 0 y 1). WIIUSE_DISCONNECT: El wiimote se ha desconectado. a. La batería se agota. b. Si presiona el botón power durante un par de segundos. c. El wiimote se desconecta. o o WIIUSE_READ_DATA: El wiimote envía la información pedida de la ROM. WIIUSE_NUNCHUK_INSERTED: Un nunchuk ha sido conectado. Proyecto fin de carrera 129 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. o o o o o WIIUSE_NUNCHUK_REMOVED: Un nunchuk se ha quitado. WIIUSE_CLASSIC_CTRL_INSERTED: Control clásico conectado. WIIUSE_CLASSIC_CTRL_REMOVED: Control clásico desconectado. WIIUSE_GUITAR_HERO_3_CTRL_INSERTED: Guitar hero conectado. WIIUSE_GUITAR_HERO_3_CTRL_REMOVED: Guitar hero desconectado. wiiuse_set_timeout() : esta función solo funciona en Windows, en otros sistemas simplemente no hace nada. En Windows un timeout se utiliza cuando realizamos el polling de los wiimotes. Si por ejemplo notamos que están respondiendo demasiado despacio puede bajarse el valor de timeout, que por defecto está establecido a 20 ms, sin embargo bajar demasiado el timeout pued causar problemas. El valor de timeout se especifica en milisegundos. Los parámetros de timeout que toma la función son, en primer lugar, el timeout normal, que es el que se empleará en el polling normal del wiimote, y como segundo parámetro el timeout de expansión que se empleará para cualquier dispositivo de expansión del wiimote. void wiiuse_set_timeout(struct wiimote_t** wm, int wiimotes, byte normal_tiemout,byte exp_timeout ); wiiuse_set_orient_threshold(): Los sensores de acelerómetría son muy sensibles a la hora de adquirir la información, esto provoca que produzcan mucho ruido, debido a esto los ángulos del wiimote respecto a los ejes están continuamente cambiando y en consecuencia produciendo eventos, si estamos usando la función wiiuse_poll() esto se convierte en un problema. Para ofrecer una solución a este problema se pueden fijar umbrales de orientación de forma que se generará un evento siempre y cuando el movimiento de wiimote supere dichos umbrales, evitando de esta forma la generación de eventos provocado por pequeñas vibraciones o el propio ruido generado en los acelerómetros. Por defecto este umbral estará fijado en 0.5 grados. void wiiuse_set_orient_threshold(struct wiimote_t* wm, float threshold); Destacar que este ajuste solamente se aplica a un dispositivo wiimote y que el umbral se aplicará a los ángulos con los tres ejes. También se pueden fijar los umbrales de ángulos en el nunchuk: void wiiuse_set_nunchuk_orient_threshold(struct wiimote_t* wm, float threshold); wiiuse_set_accel_orient_threshold(): al igual que en el caso anterior las pequeñas vibraciones y el ruido de los acelerómetros provoca que se 130 Proyecto fin de carrera Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. generen eventos aunque en este caso en lugar de ser debido al cambio de ángulo se debe a la variación en la aceleración sobre los tres ejes del sistema de coordenadas. void wiiuse_set_accel_threshold(struct wiimote_t* wm,int threshold); wiiuse_motion_sensing(): por defecto la adquisición de información por parte de los acelerómetros no se encuentra activada, por lo que para trabajar con el control con movimientos el primer paso será activar la información proveniente de aquí. Como parámetro status pasaremos 0 para desactivar y 1 para activar. void wiiuse_motion_sensing(struct wiimote_t* wm,int status); wiimote Struct: es la estructura con la que se manejan cada uno de los wiimotes y que se pasa como parámetro en prácticamente todas las funciones que estamos utilizando contiene información acerca del estado actual de los dispositivos y su configuración. Algunas de las características más interesantes se presentarán a continuación: o int unid: Se trata de un identificador único que se asigna a cada wiimote wiiuse_init(). o struct gforce_t gforce: Aquí se almacena la información sobre aceleración en los ejes del sistema de coordenadas generada por los acelerómetros. El rango que pueden detectar los acelerómetros es de +/- 3g. La estructura gforce contiene por lo tanto los valores de aceleración por eje almacenados como float. o struct ir_t ir: Información relativa a la posición a la que apunta el wiimote sobre el dispositivo IR. o struct orient_t orient: orientación del wiimote sobre los ejes. Esta estructura contiene en formato float el valor de roll y pitch que varía desde los -180 a 180 grados. El valor de yaw es tambien float pero su rango de variación es de -26 a 26 grados y solamente será calculado si el dispositivo de IR está en uso en cualquier otro caso el valor de será siempre cero. Esta estructura contiene también otras variables en formato float como son a_roll y a_pitch que son las variables de pitch y roll sin aplicar un algoritmo previo de suavizado. Este algoritmo se utiliza para intentar paliar los efectos de ruido provocado por los propios acelerómetros y tambien se puede modificar usando la función wiiuse_set_smooth_alpha() que permite ajustar el factor de suavizado del algoritmo. Proyecto fin de carrera 131 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Macros de botones: el uso de macros definidas en la librería wiiuse es la forma más sencilla para comprobar el estado de los botones de los dispositivos (que a continuación aparecerán como argumentos de entrada denominados Dev y que pueden ser tanto un wiimote, nunchuk, control clásico o Guitar Hero 3). o IS_PRESSED(): Devuelve un 1 si el botón que pasamos con parámetro está pulsado en este preciso momento. if(IS_PRESSED(dev,button)){ /*button is pressed */ } else { /*button is not pressed */ } o IS_JUST_PRESSED(): Devuelve un 1 si el botón que pasamos con parámetro se ha pulsado en algún momento. Esta macro puede resultar más interesante cuando queremos tratar el caso de que el usuario presione una única vez el botón. if(IS_JUST_PRESSED(dev,button)){ /*button is pressed */ } else { /*button is not pressed */ } o IS_RELEASED(): El usuario deja de pulsar el botón. if(IS_RELEASED(dev,button)){ /*button is pressed */ } else { /*button is not pressed */ } o IS_HELD(): devolverá 1 si el botón señalado está siendo pulsado por el usuario, ha sido presioando pero todavía no ha sido liberado. if(IS_HELD(dev,button)){ /*button is pressed */ } else { /*button is not pressed */ } Hasta ahora hemos hablado de pasar botones como parámetro. Para hacerlo debemos usar algunos de los códigos que aparecen a continuación: Proyecto fin de carrera WIIMOTE_BUTTON_ONE WIIMOTE_BUTTON_TWO WIIMOTE_BUTTON_B WIIMOTE_BUTTON_A WIIMOTE_BUTTON_MINUS 132 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. WIIMOTE_BUTTON_HOME WIIMOTE_BUTTON_LEFT WIIMOTE_BUTTON_RIGHT WIIMOTE_BUTTON_DOWN WIIMOTE_BUTTON_UP WIIMOTE_BUTTON_PLUS Macros de estado: al igual que para el control de botones existen macros definidas que permiten averiguar el estado en el que se encuentra el wiimote o alguno de sus dispositivos extra (control clásico, nunchuk, guitar hero). o WIIUSE_USING_ACC(wm): Devuelve 1 si el control por movimientos está activo. Es decir, si hemos utilizado la función void wiiuse_motion_sensing() y hemos activado esta característica. o WIIUSE_USING_EXP(wm): Devuelve 1 si hay alguna extensión conectada al wiimote. o WIIUSE_USING_IR(wm): Devuelve 1 si estamos haciendo uso de los dispositivos IR. o WIIUSE_USING_SPEAKER(wm): haciendo del altavoz. Devuelve 1 si estamos o WIIUSE_USING_SPEAKER(wm,number): Devuelve 1 estamos haciendo del LED que indicamos en number (1-4). si 3.6.2.4. Implementación del software comunicaciones del wiimote y de control Para comenzar con la descripción del software de gestión del wiimote instalado en el PC comenzamos por mostrar de manera esquemática los diferentes módulos o funcionalidades que debe disponer para el correcto funcionamiento. Proyecto fin de carrera 133 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 58: Esquema de comunicaciones de la aplicación de gestión del Wiimote La misión principal de este módulo de gestión es lograr identificar qué teclas está pulsando el usuario en cada momento o intentar reconocer los movimientos que está realizando y a partir de la estimación de lo que el usuario quiere transmitir esa información a la aplicación cliente que a su vez será la encargada de retransmitir el mensaje a la aplicación de gestión y control de Roomba. Por lo tanto, además de la inteligencia para determinar qué movimiento está realizando el usuario, el modulo de gestión de wiimote necesita implementar dos interfaces de comunicaciones, la primera para comunicarse mediante bluetooth con el wiimote, para lo cual ya hemos dicho que emplearíamos la librería wiiuse.dll [21]. En cuanto a la segunda, como en el resto del proyecto, emplearemos el CSocketNode para comunicar ambas aplicaciones. El primer paso es buscar si existe algún dispositivo wiimote conectado y en caso de que así sea se establece la conexión. wiimotes = wiiuse_init(MAX_WIIMOTES); found = wiiuse_find(wiimotes, MAX_WIIMOTES, 5); if (!found) { printf ("No wiimotes found."); return 0; } connected = wiiuse_connect(wiimotes, MAX_WIIMOTES); if (connected) printf("Connected to %i wiimotes (of %i found).\n", connected,found); else { printf("Failed to connect to any wiimote.\n"); return 0; } Cuadro 9: Busqueda de wiimotes en el ambiente El siguiente paso es crear un servidor CSocketnode y comprobar si existe un cliente con el que establecer conexión en el socket preestablecido para esta comunicación. En caso de que no se puede establecer la conexión se reintenta hasta que sea posible. Una vez hecho esto, entramos en el bucle principal del programa, que está continuamente comprobando el estado de la Proyecto fin de carrera 134 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. conexión con el cliente, por si es necesario reestablecerla y esperando que suceda algún evento en el wiimote. if (servidor_roomba.Init ("127.0.0.1",6005, SOCKET_SERVER)!=0) { errorPrintf("Error al crear el servidor"); } printf( "MODULO SERVIDOR\n"); do{ printf("Conectando con el cliente\n"); servidor_roomba.HandleConnection(); Sleep(500); }while (!servidor_roomba.IsConnected()); while(1){ if(!servidor_roomba.IsConnected()){ do{ printf("Conectando con el cliente\n"); servidor_roomba.HandleConnection(); Sleep(500); }while (!servidor_roomba.IsConnected()); } . . . bucle principal . . . Cuadro 10: Inicializa socket wiimote y comienza el bucle principal Como ya se ha dicho en el párrafo anterior el bucle principal está continuamente “escuchando” al wiimote a la espera de que suceda algún evento para realizar el tratamiento apropiado para cada uno de ellos. Concretamente esteremos interesados en ver cuándo se pulsa cada uno de los botones que tendrá su función ya detallada o cuándo el botón B se encuentra pulsado, momento en el cual el control comienza a ser basado en los movimientos del usuario. Comenzando por el uso de los botones, trataremos individualmente cada uno de los sucesos asociados a la pulsación de cada uno de los botones. En este caso el empleo de la función IS_JUST_PRESSED() facilita el tratamiento de eventos, ya que aunque el usuario mantenga pulsado el botón más tiempo del que es necesario para procesar el evento unicamente se contabilizará una pulsación evitando de esta manera la activación de multiples eventos consecuencia de ese tiempo prolongado. Para la gestión de las acciones relacionadas con la pulsación de botones se propone la implementación del siguiente diagrama de estados, en donde se tiene que cuenta que, por ejemplo, cuando el usuario presiona el botón derecha puede querer que, si está parado, comience a girar hacia la derecha, si ya está Proyecto fin de carrera 135 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. girando hacia la derecha, que lo haga más rápido, o que se pare si está girando hacia la izquierda. La Ilustración 59 muestra mediante un diagrama de estados las respuestas que deber tener el módulo de gestión únicamente ante las entradas provenientes de los movimientos derecha, izquierda, arriba y abajo. Faltaría por añadir por ejemplo, las reacciones ante el botón A que provoca que el sistema pase al estado ‘inicio’ sea cual sea el estado en el que se encuentre. Este tratamiento para los movimientos solamente será efectivo durante un corto período de tiempo. De esta forma si pulsamos una vez ‘UP’, pasamos al estado ‘avanza’, si en menos de un corto período de tiempo pulsamos de nuevo ‘UP’ pasaremos al estado ‘avanza rapido’, si el tiempo es mayor volveremos a ‘inicio’. Con esto conseguimos partir siempre de un estado conocido, y evitamos que si estamos en el estado ‘avanza’ y otra interfaz envía el movimiento ‘para’ deberíamos pasar al estado ‘inicio’, sin embargo seguiríamos en ‘avanza’, con lo que el resultado no sería el esperado por el usuario. Ilustración 59: Diagrama de estados para el tratamiento de las teclas del wiimote La implementación de este diagrama de estados se muestra a continuación, detallando el tratamiento para el caso de que se presione el botón derecha siendo similar para el resto de casos. Proyecto fin de carrera 136 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. if (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_RIGHT)){ switch(estado_actual){ case derecha_rapido: bufin="( gira_rapido_derecha )"; estado_siguiente=derecha_rapido; break; case derecha: bufin="( gira_rapido_derecha )"; estado_siguiente=derecha_rapido; break; case inicio: bufin="( gira_despacio_derecha )"; estado_siguiente=derecha; break; case izquierda_rapido: bufin="( gira_despacio_izquierda )"; estado_siguiente=izquierda; break; case izquierda: bufin="( para )"; estado_siguiente=inicio; break; default: bufin="( gira_despacio_derecha )"; estado_siguiente=derecha; break; } if(!(estado_siguiente==estado_actual)){ printf("Bufin: %s\n", bufin); if(servidor_roomba.SendMsg (bufin, strlen(bufin))!=0){ printf("Error enviando\n"); }else{ printf("enviado correctamente\n"); } estado_actual=estado_siguiente; } return; } if if if if if if if if (IS_JUST_PRESSED(wm, (IS_JUST_PRESSED(wm, (IS_JUST_PRESSED(wm, (IS_JUST_PRESSED(wm, (IS_JUST_PRESSED(wm, (IS_JUST_PRESSED(wm, (IS_JUST_PRESSED(wm, (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_LEFT)){…} WIIMOTE_BUTTON_UP)){…} WIIMOTE_BUTTON_DOWN)){…} WIIMOTE_BUTTON_A)){…} WIIMOTE_BUTTON_MINUS)){…} WIIMOTE_BUTTON_HOME)){…} WIIMOTE_BUTTON_ONE)){…} WIIMOTE_BUTTON_TWO)){…} Cuadro 11: Gestión de pulsación de botones En el caso de que queramos trabajar con los movimientos del wiimote el tratamiento es bastante diferente, ya que independientemente del estado en el que nos encontremos únicamente tendremos en cuenta el valor de pitch o roll del wiimote. Por lo tanto la estrategia a seguir es fijar umbrales de determinen qué rango de valores se asocia a cada uno de los movimientos, y a partir de eso detectar en qué rango de valores se encuentra el wiimote, y permitir que cualquier tipo de transición entre todos ellos. Proyecto fin de carrera 137 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. avanza avanza_rapido retrocede gira a la derecha despacio gira a la izquierda despacio gira a la derecha rápido gira a la izquierda rápido valores de pitch < -45 < -80 > 40 - valores de roll < -60 - < -80 - > 60 > 80 Tabla 28: Rango de valores de las posiciones del wiimote asociadas a sus estados Ilustración 60: Transiciones entre estados con el control basado en movimientos Proyecto fin de carrera 138 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. if (IS_PRESSED(wm, WIIMOTE_BUTTON_B)){ pitch=wm->orient.pitch; roll=wm->orient.roll; printf("Pitch %i; Yaw %i; Roll %i \n",pitch,yaw_a,roll); /* Tratamiento de la variación de pitch */ if (pitch<=(-80)){ switch(estado_actual){ case avanza: bufin="( avanza_rapido )"; estado_siguiente=avanza_rapido; break; case retrocede: bufin="( para )"; estado_siguiente=inicio; break; } if(!(estado_siguiente==estado_actual)){ printf("Bufin: %s\n", bufin); if(servidor_roomba.SendMsg (bufin, strlen(bufin))!=0){ printf("Error enviando\n"); }else{ printf("enviado correctamente\n"); } estado_actual=estado_siguiente; } return; } if (pitch<=(-45)){…} if (pitch>45){…} /* Tratamiento de la variación de roll */ if if if if (roll>=70){…} (roll>=40){…} (roll<=(-70)){…} (roll<=(-40)){…} Cuadro 12: Código con la gestión de movimientos en el wiimote Proyecto fin de carrera 139 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 61: Ilustraciones con las posiciones del wiimote asociadas a cada uno de los movimientos 3.7. Aplicación teléfono móvil 3.7.1. Introducción Para trabajar con el teléfono móvil ha sido necesario desarrollar dos aplicaciones. una trabajará en el ordenador en donde se encuentran el resto de aplicaciones y su labor será la de establecer la comunicación bluetooth con el teléfono móvil y gestionar los mensajes que le lleguen de este, tratarlos adecuadamente y reenviarlos a través del socket de comunicaciones a la aplicación cliente que es la que se comunica con la aplicación de control de Roomba. Por otro lado ha sido necesario desarrollar sobre J2ME una aplicación que se instale en el teléfono móvil y que sea capaz de establecer una conexión bluetooth y que permita la selección de un mensaje para enviar a la aplicación cliente. 3.7.2. Aplicación en el ordenador Como ya se ha dicho esta aplicación que se ejecuta en el ordenador tiene la finalidad de hacer de nexo de unión entre la información que recibe vía bluetooth desde el teléfono móvil y la aplicación cliente con la que se comunica mediante sockets del sistema. Proyecto fin de carrera 140 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 62: Esquema de funcionamiento de la aplicación cliente instalada en el ordenador La comunicación bluetooth con el teléfono móvil se realiza implementado el perfil SPP, es decir cuando desde el teléfono móvil arranca la aplicación establece un puerto serie virtual con el ordenador, de forma que a efectos prácticos cuando queramos establecer una conexión con el teléfono móvil tendremos a nuestra disposición ese perfil de puerto serie virtual que se maneja exactamente igual que un puerto serie convencional. 3.7.2.1. Implementación La implementación de la aplicación que reside en el ordenador consta de dos partes bien diferenciadas, por una lado, la primera para de establecimiento de la comunicaciones, en la que deben efectuar las conexiones inalámbricas y la conexión a través del socket con la aplicación y cliente, y por otro lado la implementación de las rutinas de gestión y retransmisión de los mensajes recibidos. Por lo tanto la conexión bluetooth con el teléfono móvil se realiza inicializando y configurando un puerto serie tradicional. Implementamos la función que permita inicializar el puerto serie, Cuadro 13 y a su vez esta función emplea la función set_up_serial_port() para configurar adecuadamente el puerto serie, Cuadro 14. Proyecto fin de carrera 141 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. HANDLE inicializarPuertoSerie(char* port_name,long baud_rate){ HANDLE serial_port; serial_port = CreateFile(port_name, // Nombre del puerto COMM GENERIC_READ | GENERIC_WRITE, // Modo de apertura 0, //COM devices must be opened w/exclusive-access NULL, // no security attrs OPEN_EXISTING, //COM devices must use OPEN_EXISTING 0, // not overlapped I/O NULL); // hTemplate must be NULL for COM devices if (serial_port == INVALID_HANDLE_VALUE) { fprintf(stderr, "Error abriendo el puerto para telefono movil: %s \n", port_name); CloseHandle(serial_port); exit(0); } set_up_serial_port(serial_port, baud_rate); return serial_port; //Configurar el puerto serie // esta función devuelve un manejador para el puerto } Cuadro 13: Función de inicialización del puerto serie void set_up_serial_port(HANDLE h, long baud){ DCB properties; COMMTIMEOUTS time_outs; //Estructura con la configuración del puerto serie GetCommState(h, &properties); //Obtiene la configuración del manejador properties.BaudRate = CBR_115200; //Velocidad 115200,No paridad,8 bits, //1bit de parada properties.Parity = NOPARITY; properties.ByteSize = 8; properties.StopBits = ONESTOPBIT; properties.fRtsControl = 0; properties.fDtrControl=0; SetCommState(h, &properties); //Establece la nueva configuración GetCommTimeouts(h,&time_outs); //Obtiene los timeouts del manejador time_outs.ReadIntervalTimeout = 50; time_outs.ReadTotalTimeoutConstant = 50; time_outs.ReadTotalTimeoutMultiplier = 10; time_outs.WriteTotalTimeoutConstant = 50; time_outs.WriteTotalTimeoutMultiplier = 10; SetCommTimeouts(h, &time_outs); //Guarda la configuración de timeouts } Cuadro 14: Función de configuración del puerto serie Por otro lado es necesario establecer una conexión a través del socket con la aplicación cliente, para esto, se hace de la clase CSocketNode como en el resto de aplicaciones del proyecto, dos sencillas funciones bastan para hacer esto, por un lado, abre_socket() inicializa el socket de comunicaciones, Cuadro 15 y por otro lado se emplea la función conecta_socket(), Cuadro 16, para establecer la conexión a través del socket. Proyecto fin de carrera 142 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. int abre_socket(char* socket_d,long puerto){ if (socket_N73.Init (socket_d,puerto, SOCKET_SERVER)!=0) { fprintf(stderr, "Error abriendo el socket"); } return 0; } Cuadro 15: Función abre_socket() para inicializar un objeto de la clase CSocketNode int conecta_socket(){ do{ IMPRIME_TRACE(1,"Conectando con el cliente\n"); socket_N73.HandleConnection(); Sleep(500); }while (!socket_N73.IsConnected()); return 0; } Cuadro 16: Implementación de la función conecta_socket() Una vez establecidas las comunicaciones debemos implementar el software que gestione los mensajes que llegan desde el teléfono móvil a través del puerto serie virtual para poder retransmitirlos a través del socket. Para hacerlo se llama periódicamente a la función read_string(), que comprueba si existe algún byte pendiente de lectura con la ayuda de la función maneja_info(), en caso de que sea así vamos leyendo byte a byte hasta encontrarnos con el carácter ‘)’ que indica el final del mensaje. Una vez hecho esto, trasmitimos el mensaje a través del socket de comunicaciones oportuno. Proyecto fin de carrera 143 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. int read_string(){ int i=0; int flag=0; char string_envio[40]; strcpy(string_envio,"esperando..."); while(maneja_info()){ if(flag==0){ flag=1; }else{ string_recibido[i]=*buff; i++; flag=0; } if(string_recibido[i-1]==')'){ string_recibido[i]='\0'; strcpy(string_envio,string_recibido); if(socket_N73.SendMsg (string_envio,i)!=0){ printf("Error enviando\n"); }else{ printf("Valor Leido: %s , enviado correctamente\n",string_envio); } break; } } printf("Esperando...\r"); return 0; } Cuadro 17: Implementación de la función read_string() int maneja_info(){ unsigned long bytes_received; ReadFile(serial_port,buff,1, &bytes_received, NULL); if(bytes_received==1){ return 1; } return 0; } Cuadro 18: Implementación de la función maneja_info() 3.7.3. Aplicación para el teléfono móvil Como ya se ha dicho en capitulo destinado al estado del arte de J2ME, cuando trabajamos con esta distribución de desarrollo Java tendremos que diseñar nuestro software para una arquitectura muy concreta según el hardware con el que vayamos a trabajar. En nuestro caso se trata del teléfono móvil Nokia N70, recordamos que la configuración de este dispositivo es de una KVM, sobre la que se asienta la configuración CLDC y el perfil MIDP 2.0 todo ello sobre el sistema operativo Symbian OS 8.1ª. Proyecto fin de carrera 144 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 63: Arquitectura genérica para desarrollo con J2ME Para desarrollar aplicaciones sobre J2ME es necesario descargar e instalar los paquetes de desarrollo para Java (SDK) y el Sun Java Wireless Toolkit de J2ME que proporciona multitud de herramientas para desarrollar aplicaciones (conocidas como MIDlets) para este tipo dispositivos, por ejemplo ofrece la posibilidad de emplear emuladores de teléfonos móviles para testear las aplicaciones sin necesidad de realizar el proceso de instalación sobre el dispositivo. En este caso es interesante mostrar el código casi en su totalidad con la intención de remarcar las diferencias entre la programación de una aplicación software para un PC convencional y el desarrollo de una aplicación para un dispositivo móvil. En primer lugar tenemos que crear la aplicación que actuará como main y que por lo tanto debe adaptarse el perfil MIDP. Para eso utilizamos la herencia desde la clase MIDlet e implementamos, u opcionalmente dejamos vacío, los métodos que todo MIDlet debe tener para que su ciclo de vida funcione de forma correcta. En el Cuadro 19 se muestra la fase de inicialización, creamos una clase que hereda de MIDlet y en la que se definen algunos atributos básicos para manejar conexiones bluetooth y crear una GUI además de redefinir los métodos básicos para el correcto funcionamiento del MIDlet como son destroyApp(), pauseApp() y startApp() siendo esta último el primer método que será invocado. Proyecto fin de carrera 145 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. import import import import java.io.*; java.util.*; javax.microedition.*; javax.bluetooth.*; public class RoombaN70 extends MIDlet implements DiscoveryListener,CommandListener { private Roomote panCanvas; private Display pantalla; InputStream in; OutputStream out; DataOutputStream dos; DataInputStream dis; StreamConnection stream = null; List menu; //---- atributos Bluetooth ---protected UUID uuid = new UUID(0x1101); // serial port profile protected int inquiryMode = DiscoveryAgent.GIAC; // no pairing is needed protected int connectionOptions = ServiceRecord.NOAUTHENTICATE_NOENCRYPT; protected int stopToken = 255; //---- atributos de la GUI ---protected Form infoArea = new Form("Symbian Roomba Control"); protected Vector deviceList = new Vector(); private private private private static static static static final final final final Command Command Command Command CMD_ROOMOTE = new Command("Roomote",Command.ITEM, 1); CMD_EXIT = new Command("Salir", Command.EXIT, 1); enviar = new Command("Enviar", Command.ITEM, 1); volver = new Command("Volver", Command.ITEM, 1); protected void destroyApp(boolean arg0) throws MIDletStateChangeException{ } protected void pauseApp() { } protected void startApp() throws MIDletStateChangeException { pantalla = Display.getDisplay(this); panCanvas = new Roomote(this); pantalla.setCurrent(infoArea); makeInformationAreaGUI(); try { startDeviceInquiry(); } catch (Throwable t) { log(t); } } Cuadro 19: Definición de atributos y métodos básicos Una vez superada la inicialización es necesario establecer la conexión bluetooth con el PC para comenzar a transmitir información. El Cuadro 20 muestra los métodos básicos empleados para establecer y manejar conexiones bluetooth. En primer lugar se analiza las señales en el ambiente en busca de dispositivos bluetooth, ofreciendo la posibilidad de detener la búsqueda en cualquier momento si hemos encontrado el dispositivo que buscamos. Una vez detenida la búsqueda de equipos bluetooth se ofrece una lista de todos los dispositivos disponibles al usuario para que seleccione sobre cual de ellos quiere implementar la comunicación. Proyecto fin de carrera 146 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. //------- Device inquiry section ------private void startDeviceInquiry() { try { log("Buscando dispositivos en el entorno..."); DiscoveryAgent agent = getAgent(); agent.startInquiry(inquiryMode, this); } catch (Exception e) { log(e); } } private void crear_stream(){ try{ in=stream.openInputStream(); out=stream.openOutputStream(); dos = new DataOutputStream(out); dis = new DataInputStream(in); dos.writeChars("Conexión establecida"); }catch(Exception e){ . . . } } public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) { log("Equipo encontrado:(" + getNombreDisp(btDevice) + ")"); deviceList.addElement(btDevice); } public void inquiryCompleted(int discType) { log("Busqueda finalizada. selecciona equipo:"); makeDeviceSelectionGUI(); } // ------- Service search section ------- // private void startServiceSearch(RemoteDevice device) { try { log("Estableciendo servicios de SPP en: "+ getNombreDisp(device)); UUID uuids[] = new UUID[] { uuid }; getAgent().searchServices(null, uuids, device, this); } catch (Exception e) { log(e); } } public void servicesDiscovered(int transId, ServiceRecord[] records) { log("Servicio establecido."); for (int i = 0; i < records.length; i++) { ServiceRecord rec = records[i]; String url = rec.getConnectionURL(connectionOptions, false); handleConnection(url); } } public void serviceSearchCompleted(int transID, int respCode) { String msg = null; switch (respCode) { case SERVICE_SEARCH_COMPLETED: msg = "correctamente.\n Seleccione que desea hacer:"; infoArea.addCommand(CMD_ROOMOTE); break; . . . } log("Servicio de busqueda finalizado- " + msg); } Cuadro 20: Métodos para el manejo de conexiones bluetooth Proyecto fin de carrera 147 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. // ------- The actual connection handling. ------- // private void handleConnection(final String url) { try { log("Conectando..."); stream = (StreamConnection) Connector.open(url); log("Bluetooth stream abierto."); limpia_log(); crear_stream(); dos.flush(); out.flush(); } catch (IOException e) { log(e); } } // ------- Sección de Graphic User Interface ------- // private void makeInformationAreaGUI() { infoArea.deleteAll(); infoArea.addCommand(CMD_EXIT); infoArea.setCommandListener(this); Display.getDisplay(this).setCurrent(infoArea); } private void makeDeviceSelectionGUI() { final List devices = new List("Selecciona un dispositivo",List.IMPLICIT); for (int i = 0; i < deviceList.size(); i++) devices.append( getNombreDisp((RemoteDevice) deviceList.elementAt(i)), null); devices.setCommandListener(new CommandListener() { public void commandAction(Command arg0, Displayable arg1) { makeInformationAreaGUI(); startServiceSearch((RemoteDevice) deviceList.elementAt(devices.getSelectedIndex())); } }); pantalla.setCurrent(devices); } Cuadro 21: Métodos para el manejo de conexiones bluetooth y presentación al usuario Una vez que el usuario seleccione uno de los dispositivos se establecerá la comunicación creando un servicio de SPP en la máquina destino, habilitando de esta forma un puerto COM que cualquier aplicación podrá utilizar a partir de este momento. Establecida la comunicación debemos diseñar la interfaz de comunicación con el usuario. En J2ME, un objeto Displayable contiene la información que va a ser visualizada, y un objeto Display gestiona qué objeto Displayable se mostrará al usuario. La clase Displayable tiene dos descendientes: Canvas: Permite el control total de la pantalla a bajo nivel. Se usa en aplicaciones que capturan eventos y realizan llamadas gráficas. Llama al método paint(Graphics) para dibujar en la pantalla. Screen: Ofrece estructuras predefinidas (Form, Alert, TextBox, List). No accede a las características nativas del dispositivo. Permite un mayor grado de portabilidad. Proyecto fin de carrera 148 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Cuadro 22: Diagrama de clases de gestión gráfica de un MIDlet En nuestro caso emplearemos las clase Screen para crear listas con todos los movimientos disponibles, de forma que el usuario en un determinado momento pueda seleccionar que un mensaje concreto. Por otro lado tendremos una interfaz gráfica basada en la clase Canvas, que será la que arranque por defecto, y que permitirá utilizar el joystick del teléfono móvil como elemento para enviar movimientos. Como se puede ver en el Cuadro 24 cuando se detecta que se ha pulsado una de estas teclas se hace un tratamiento espacial para cada una de ellas, después modificamos el método paint(), Cuadro 23, de forma que el mensaje de pantalla se refresque de forma coherente con el estado del teléfono móvil. Proyecto fin de carrera 149 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. import javax.microedition.lcdui.*; public class Roomote extends Canvas implements CommandListener { private RoombaN73 midlet; private Command salir; private Command movi_menu; int estado=0; private int x, y; public Roomote(RoombaN70 mid){ salir = new Command("Salir", Command.EXIT,1); movi_menu = new Command("Movimientos", Command.ITEM,1); this.midlet = mid; this.addCommand(salir); this.addCommand(movi_menu); this.setCommandListener(this); x=0; y=0; } public void paint(Graphics g) { g.setColor(255,255,255); g.fillRect(0,0,getWidth(),getHeight()); g.setColor(0,0,0); if(estado==0){ g.drawString("Roomote activado", (getWidth()/2), (getHeight()/2), Graphics.BASELINE|Graphics.HCENTER);} if(estado==1){ g.drawString("retrocede", (getWidth()/2), (getHeight()/2), Graphics.BASELINE|Graphics.HCENTER);} if(estado==2){ g.drawString("izquierda", (getWidth()/2), (getHeight()/2), Graphics.BASELINE|Graphics.HCENTER);} if(estado==22){ g.drawString("izquierda rápido", (getWidth()/2), (getHeight()/2), Graphics.BASELINE|Graphics.HCENTER);} if(estado==3){ g.drawString("avanza", (getWidth()/2), (getHeight()/2), Graphics.BASELINE|Graphics.HCENTER);} if(estado==32){ g.drawString("avanza rápido", (getWidth()/2), (getHeight()/2), Graphics.BASELINE|Graphics.HCENTER);} if(estado==4){ g.drawString("derecha", (getWidth()/2), (getHeight()/2), Graphics.BASELINE|Graphics.HCENTER);} if(estado==42){ g.drawString("derecha rápido", (getWidth()/2), (getHeight()/2), Graphics.BASELINE|Graphics.HCENTER);} } Cuadro 23: Inicialización del Canvas del dispositivo N70 y la función paint() Proyecto fin de carrera 150 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. public void commandAction(Command c, Displayable d){ if (c == salir){ midlet.salir(); } if (c == movi_menu){ midlet.lista(); } } protected void keyPressed(int keyCode) { switch(getGameAction(keyCode)){ case Canvas.DOWN: { midlet.envia_mensaje("( retrocede )"); estado=1; break; } case Canvas.LEFT: { if((estado==2)||(estado==22)){ midlet.envia_mensaje("( gira_rapido_izqda )"); estado=22; }else{ midlet.envia_mensaje("( gira_despacio_izqda )"); estado=2; } break; } case Canvas.UP: { if((estado==3)||(estado==32)){ midlet.envia_mensaje("( avanza_rapido )"); estado=32; }else{ midlet.envia_mensaje("( avanza_despacio )"); estado=3; } break; } case Canvas.RIGHT:{ if((estado==4)||(estado==42)){ midlet.envia_mensaje("( gira_rapido_dcha )"); estado=42; }else{ midlet.envia_mensaje("( gira_despacio_dcha )"); estado=4; } break; } } this.repaint(); } } Cuadro 24: Funciones para el tratamiento de eventos en el teléfono móvil Proyecto fin de carrera 151 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. 3.8. Aplicación Roomba 3.8.1. Introducción El desarrollo de la aplicación para el control y gestión de Roomba tiene dos objetivos principales que condicionarán en gran medida la arquitectura de esta aplicación. En la primera fase del proyecto solamente se contemplaba el desarrollo de una aplicación para el control mediante voz de un robot domótico móvil. Partiendo de esto se desarrolló el software de control de Roomba pensando en conseguir una interfaz de comunicaciones que consiguiera aprovechar al máximo todas las capacidades de las que dispone Roomba y que al mismo tiempo resultase intuitiva para el usuario, realizando de forma transparente la conversión desde los conceptos que le transmite al reconocedor y que son cercanos al lenguaje natural del usuario a los bits que finalmente se transmiten a Roomba. Además de esto, el peso de esta conversión debería recaer totalmente sobre el nuevo software liberando al reconocedor de tal tarea. El resultado de estas premisas iniciales se materializó desarrollando una aplicación que admite como elementos de entrada cadenas de texto que definen movimientos, la definición de estos movimientos son conceptos próximos al habla espontánea, por ejemplo tenemos “avanza” o “avanza rápido”. Para dotar de máxima flexibilidad a estos movimientos el administrador puede definir qué es rápido o cúal es la velocidad normal modificando los archivos de configuración con los que cuenta el sistema. En la Ilustración 64 podemos ver la transición desde los mensajes naturales hasta llegar a la transmisión en binario con el tipo de struct al que está asociado. Ilustración 64: Detalle de la transición entre movimientos y secuencia de bits (en decimal en la imagen) que se van a enviar Este tipo de estratificación ayuda en gran medida a que diversos actores interactúen con el sistema en diferente medida y según las necesidades que necesiten cubrir. Así, un usuario del sistema se limitará a emplear los diversos movimientos que ofrece el sistema a través de las diversas interfaces según se describe en el manual de usuario. El administrador del sistema tiene la Proyecto fin de carrera 152 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. capacidad de configurar las interfaces asignando los movimientos a diversas frases, en el reconocedor, o ciertos botones, teléfono móvil y wiimote, además el administrador del sistema puede adaptar los movimientos modificando la velocidad, distancia de recorrido o añadir diferentes melodías a los movimientos. Por último un desarrollador del sistema podría de forma sencilla crear nuevos movimientos modificando estructuras de tipo Tsecuencia y añadirlos al conjunto de movimientos disponibles. Ilustración 65: Relación de los diferentes actores con el sistema La otra pauta que hemos seguido en el desarrollo de esta aplicación, viene dada por otra de las motivaciones por las que se comenzó a desarrollar la aplicación, crear un robot demostrador con la finalidad de realizar pruebas con el reconocedor de voz Servivox como interfaz de control de un robot, y finalmente la instalación del reconocedor en el robot Robonauta. El robot Robonauta dispone de una unidad de control central que admite que otros módulos se comuniquen con esta unidad a través de los sockets del sistema empleando arquitectura de servidor, así pues nuestro reconocedor tiene que implementar la arquitectura servidor sobre los sockets y partir de esto utilizaremos un cliente que emulará esta unidad de control y que se conectará con el programa Roomba que también debe emplear la arquitectura servidor en la comunicación socket. 3.8.2. Arquitectura Roomba proporciona una interfaz de comunicación serie a través de un conector Mini-DIN que permite que el robot domótico se pueda comunicar, por ejemplo, con un PC [22]. En una primera fase del proyecto la comunicación con Roomba se realizaba con un adaptador de Mini-DIN a RS-232 que permitía conectarla directamente con el puerto serie de un PC permitiendo escribir en ese puerto serie (COM1 en la mayoría de los casos) y enviar de esta forma los comandos apropiados para controlarla. Una vez conseguimos establecer conexión a través de un cable serie sustituimos ese enlace por una conexión Bluetooth. Para permitir que Roomba puede trabajar con el protocolo bluetooth Proyecto fin de carrera 153 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. debemos instalar en la salida Mini-DIN un dispositivo denominado Rootooth, también de la empresa iRobot, gracias al Rootooth Roomba puede implementar el perfil de puerto serie virtual de Bluetooth, SPP. En este apartado trataremos de comentar los aspectos más significativos de la interfaz hardware y software de Roomba de cara a mostrar las posibilidades que podemos explotar para el desarrollo de aplicaciones. Recordemos que la API de la que dispone Roomba se denomina Serial Command Interface (SCI) e implementa toda una serie de comandos que son interpretados por Roomba cuando se reciben a través del puerto serie. 3.8.2.1. Conexión física de Roomba y configuración del puerto serie La SCI responde a los comandos que llegan al conector Mini-DIN en Roomba. Este conector ofrece comunicación serie en ambos sentidos a los niveles de TTL (0 – 5V). El conector ofrece también una conexión sin regular de la batería que podemos usar como fuente de alimentación, Tabla 29. El MiniDIN se encuentra en la parte de arriba de Roomba debajo de la tapa decorativa [23]. Pin 1 2 Name Vpwr Vpwr Description Roomba battery + (unregulated) Roomba battery + (unregulated) 3 4 5 6 7 RXD TXD BRC GND GND 0 – 5V Serial input to Roomba 0 – 5V Serial output from Roomba Baud Rate Change Roomba battery ground Roomba battery ground Tabla 29: Pin-out de la conexión Mini-DIN de roomba Ilustración 66 muestra el pinout visto desde arriba del conector hembra del Mini-DIN situado en Roomba. Como se puede ver para los voltajes de transmisión y recepción se usan 0-5V que difieren de los que se emplean normalmente en un puerto serie de PC (voltajes lógicos de RS232) por esto es necesario un adaptador de Mini-DIN a RS232, si queremos emplear el puerto serie de un PC para transmitir la información a través de él. Proyecto fin de carrera 154 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 66: Figura del pin-out de la conexión Mini-DIN de roomba En nuestro caso como ya hemos comentado en varias ocasiones, aunque en una primera fase del proyecto utilizamos para comunicarnos el puerto serie RS232 del PC finalmente se utilizó comunicación a través de tecnología Bluetooth. Con lo cual al Mini-DIN conectaremos un dispositivo denominado Rootooth y que detallaremos más adelante. En cuanto a la configuración del puerto serie tenemos: Baud: 115200 (por defecto) o 19200 Bits de datos: 8 Paridad: None Bits de parada: 1 Control de flujo: None Como vemos, por defecto, Roomba se comunica a 115200 baudios. Si utilizamos un microcontrolador que no soporta esta velocidad existen dos posibilidades para modificar esta velocidad a 19200 baudios. i. Primer método: Al encender Roomba, mantener presionado el botón Clean/Power. Después de unos 10 segundos Roomba reproducirá una melodía de tonos descendentes. A partir de aquí Roomba se comunicará a 19200 baudios hasta que la apaguemos, quitemos la batería, el voltaje de la batería caiga por debajo del mínimo requerido o el baud rate sea explícitamente cambiado a través de la SCI. ii. Segundo método: Podemos utilizar el pin de cambio de baud rate (pin 5 en el Mini-DIN) para cambiar la velocidad. El procedimiento es el siguiente, una vez que Roomba se enciende esperar 2 segundos y enviar tres pulsos al pin de cambio de baud rate, cada pulso debe tener una duración de entre 50 y 500 milisegundos. A partir de esto Roomba se comunicará a 19200 baudios hasta que la batería se vacíe o el baud rate sea explícitamente cambiado a través de la SCI. Una vez configurado el puerto serie ya estamos en disposición de utilizarlo desde otro dispositivo ajustando la configuración según el caso. 3.8.2.2. Rootooth y configuración bluetooth Proyecto fin de carrera 155 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. El uso de bluetooth para el envío de datos a Roomba se hace a través de un dispositivo, el Rootooth Ilustración 67, de la propia empresa iRobot, que se conecta al puerto Mini-DIN e implementa el perfil SPP del stack de protocolo de bluetooth. Lo que se consigue en definitiva es establecer una conexión entre el Rootooh y el equipo en donde tengamos un dispositivo bluetooth que emula la existencia de un puerto serie. A partir de aquí cualquier aplicación en el PC puede trabajar con un puerto serie para enviar datos a Roomba. Ilustración 67: Dispositivo de comunicaciones Rootooth Pasemos ahora a describir el método utilizado para el control y la configuración del módulo Rootooth, se trata de un protocolo semejante al estándar industrial Hayes AT que se emplea en módems telefónicos; consiste en enviar cadenas ASCII, que conforman el conjunto de los comandos AT, a través del puerto serie, la comunicación por defecto se realiza con la siguiente configuración: Baud rate: 9600 bps Data bits: 8 Paridad: No Bits de parada: 1 A partir de aquí, podemos escribir en el puerto serie y enviar comandos AT que configuren el Rootooth según nuestras necesidades. Disponemos de un amplio abanico de comandos AT que permiten una alta adaptación del dispositivo de comunicaciones a nuestras necesidades [24], a continuación enumeraremos las características configurables más destacables y acto seguido nos centraremos en los comandos AT que nos permitan ajustar la velocidad del puerto a nuestro equipo y otros comandos AT muy importantes que nos permiten conmutar entre el modo de transmisión de datos y el modo de configuración (en el modo de configuración Rootooth no tratará la información que le llegue como datos sino como información de configuración). Conseguir y establecer información sobre el enlace radio (comandos ATSI) Escribir en las localizaciones de memoria, permite la configuración de multitud de registros (comandos ATSW) Seguridad (comandos ATSP) Proyecto fin de carrera 156 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Establecer el nombre del servicio (comandos ATSSN) Leer localizaciones de memoria (comandos ATSR) Búsqueda de dispositivos bluetooth (comandos ATDI) Comandos de conexión y desconexión (comandos ATDI, ATSMA, ATMACLR…) Conmutar entre modos de configuración y transmisión (comandos ATMD, +++, ATMF,…) Emparejar dispositivos bluetooth (ATPAIR, ATUPAIR) Ajustar niveles de recepción de potencia (ATSPF) Centrémonos en el comando ATSW y sus posibilidades, ya que el envío de este comando con los parámetros adecuados permite escribir en los registros del dispositivo y es lo que nos permite ajustarlo y configurarlo. Como hemos comentado previamente, nuestro interés pasa por configurar Rootooth para adaptar su configuración de puerto serie, para lograrlo debemos hacer uso de algunos de los comandos AT que ya hemos comentado; el primer paso será conmutar desde el modo de transmisión de datos a modo de configuración, una vez en este modo configurar la conexión serie y por último volver al modo de transmisión de datos. i. Cambiar a modo de configuración: enviamos el comando “+++[retorno de carro]” si todo va bien rootooth devolverá “OK” ii. Configurar el puerto serie: siempre que queramos enviar un comando AT debemos enviar el comando “AT” como prefijo de atención, a lo que rootooth, igual que en el caso anterior, debe responder “OK”, aquí ya podemos enviar el comando de configuración que queramos en nuestro caso usaremos ATSW con los parámetros adecuados. Como podemos ver en el cuadro superior ATSW20,472,0,0,1 “enter” y no obtenemos respuesta por parte de Rootooth. iii. Volver al modo de transmisión de datos: Enviamos el comando “ATMD” y recibimos “OK” si todo va bien. Proyecto fin de carrera 157 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Comando ATSW, parámetros y configuración ATSW, <n> posibles registros que permiten configuración <n> 20 Descripción Configuración UART Argumentos ,<baudrate>,<paridad>,<stopbits> ,<almacenamiento> 22 Establecer estado PIO ,<PIO#>,<estado>,<almacenamiento> 23 Establecer lógica PIO ,<PIO#>,<estado>,<almacenamiento> 24 Activar configuración por defecto ,<valor>,<valor>,<valor>,<valor> 26 Ver configuración usuario ,<valor>,<valor> 29 Establecer código PIN ,<PIN>,<valor> 30 Establecer modo hibernar ,<valor> Nosotros queremos configurar la comunicación a través del puerto serie, así que trabajaremos con “Configuración UART” así que ahora tenemos: ATSW20,<baudrate>,<paridad>,<bits_de_parada>,<parámetro de almacenamiento> Baud Rate Igual 1200 2400 4800 9600 192k 38,4k 57,6k 115,2k 230,4k 460,8k 921,6k Valor ASCII 0 5 10 20 39 79 157 236 472 944 1887 3775 Error 1,73% 1,73% 1,73% -0.82% 0.45% -0.18% 0.03% 0.03% 0.03% -0.02% 0.00% Paridad: 0= Sin paridad; 1=paridad impar; 2=paridad par Bits de parada: 0=Un bit de parada;1=Dos bits de parada Almacenamiento de parámetros en flash: 0=No almacenar; 1=Almacenar Por ejemplo: 115200 bps, sin paridad, un bit de parada y almacenar ATSW20,472,0,0,1 Cuadro 25: Cuadro con los posibles parámetros del comando ATSW y ejemplos de configuración Proyecto fin de carrera 158 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 68: Diagrama de bloques del sistema Rootooth y de las comunicaciones con la aplicación de control. 3.8.2.3. Modos de funcionamiento La SCI de Roomba permite cuatro modos de funcionamiento: Off, Passive, Safe y Full. Si quitamos la batería o encendemos por primera vez Roomba, estará en modo Off y estará a la escucha, a la velocidad de comunicación por defecto, esperando la llegada de un comando Start. Una vez que lo recibe podemos cambiar a uno de los cuatro modos de operación enviando el comando correspondiente. Modo Passive Una vez que llega el comando Start o uno de los comandos de limpieza (Spot, Clean, Dock) la SCI pasa a modo Passive. En este modo se puede hacer peticiones y recibir datos de los sensores usando los comandos de apropiados, no se puede, sin embargo, cambiar los parámetros actuales de los actuadores (motores, altavoces, luces). Para poder trabajar con los actuadores necesitamos cambiar de modo Passive a modo Full o modo Safe. Modo Safe Cuando cambiamos a modo Safe pasamos a tener control total sobre Roomba, siempre y cuando se verifiquen las siguientes de seguridad que se resumen en que no se den ninguna de las siguientes situaciones: o Detección de un borde mientras se mueve hacia delante o Detección de un rueda en el aire o Conexión al cargador y cargando En caso de que alguna de estas condiciones se cumpla el sistema pasa automáticamente a modo Passive y se paran todos los motores. En caso de que no enviemos ningún comando mientras estemos en modo Safe, Roomba esperará con los motores y LEDs apagados y no responderá a la Proyecto fin de carrera 159 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. pulsación de ningún botón o a los datos de entrada de los sensores. Si Roomba está cargando deja de hacerlo cuando entramos en el modo Safe. Modo Full Cuando enviamos el comando de modo Full a la SCI, Roomba cambia a este modo que nos permite absoluto control sobre Roomba, todos sus actuadores, inhibiendo al mismo tiempo las condiciones de seguridad. Si no enviamos comandos a la SCI cuando está en modo Full, Roomba esperará con los motores y LEDs apagados y no responderá a ningún botón ni activación de sensores. Al igual que en casos anteriores si Roomba está en proceso de carga y pasamos a modo Full, Roomba abandonará inmediatamente el proceso de carga. Ilustración 69: Diagrama esquemático con las transiciones entre los diversos estados en los que se puede encontrar Roomba 3.8.2.4. Descripción de los comandos proporcionadas por la interfaz serie de Roomba SCI Comentaremos en esta sección algunos de los comandos que proporciona la interfaz SCI y que podremos enviar por el puerto serie con la Proyecto fin de carrera 160 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. finalidad de controlar Roomba. Cada comando se especifica como un código de un byte que, opcionalmente, puede ir acompañado de más bytes de datos que servirán para añadir parámetros a los comandos. Las siguientes tablas muestran un resumen con los comandos más destacables así como su código asociado, si existe la posibilidad de que se le añadan bytes de datos y una pequeña descripción de su finalidad, para más información consultar la bibliografía. 3.8.3. El sistema de control y gestión de Roomba La interfaz desarrollada para Roomba cumple con los objetivos de partida de los que ya hemos hablado previamente; partiendo de un fichero de configuración en el que se indican las direcciones del puerto serie en el que se conectará Roomba con el programa cliente, que será el encargado de atender a los dispositivos de control de forma transparente para el programa de control de Roomba, atenderá los mensajes que le lleguen del cliente, independientemente de donde provengan, y con la ayuda del fichero de configuración de movimientos los traducirá en una secuencia de bytes, o lo que es lo mismo, a una serie de comandos que Roomba es capaz de interpretar. En pocas palabras el software de control de Roomba ofrece una interfaz de movimientos para cualquier otro programa que se conecte con él a través de un socket o indirectamente lo haga a través de la aplicación cliente. Ilustración 70, muestra de forma esquemática el funcionamiento y los objetivos de la aplicación de gestión y control de Roomba. Proyecto fin de carrera 161 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 70: Vista esquemática del funcionamiento de la aplicación cliente Como ya hemos dicho, el objetivo de la aplicación es ofrecer un paso intermedio entre las diversas interfaces que tienen como objetivo controlar Roomba y esta misma. De forma que permita el paso intermedio entre un conjunto de posibles movimientos y su traducción y envío al robot Roomba a través el puerto serie virtual, SPP. Proyecto fin de carrera 162 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 71: Vista esquemática de la interfaz Roomba A continuación podemos ver una lista con los movimientos actualmente definidos en el sistema para Roomba. ( atiende ) ( avanza_despacio ) ( avanza_rapido ) ( da_la_vuelta ) ( gira_despacio_derecha ) ( gira_rapido_derecha ) ( gira_despacio_izquierda ) ( gira_rapido_izquierda ) ( deja_atender ) ( retrocede ) ( a_casa ) ( para ) ( aspira ) ( graba_recorrido_1 ) ( deja_grabar_1 ) ( recorrido_1 ) El sistema también tiene disponibles dos archivos de configuración que permiten adaptar el sistema a las necesidades específicas de una determinada situación. Concretamente tendrá la posibilidad de ajuste de las características de los movimientos a través del archivo ‘config_mov.ini’ y de las características de comunicación con otros procesos con el fichero ‘config_sys.ini’. Proyecto fin de carrera 163 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Comencemos con el ajuste de movimientos, para ello deberemos modificar el fichero, que por defecto se llama ‘config_mov.ini’, una vez dentro las posibilidades que tenemos son modificar velocidades y distancias o añadir una melodía para cada uno de ellos. Esta última característica puede resultar interesante de cara a mostrar un sistema domótico accesible para todos, de forma que un usuario con problemas visuales puede comprobar que Roomba está respondiendo de forma correcta a las órdenes en función de la melodía que escuche. Ilustración 72: Captura del fichero ‘config_mov.ini’ Como se puede ver en la Ilustración 72 el fichero de configuración de movimientos tiene una entrada por cada uno de los movimientos. Cada uno de estos movimientos presenta cuatro variables: velocidad, ang_giro, distancia y melodía. Como su propio nombre indica, velocidad hace referencia a la velocidad a la que se ejecuta el movimiento. Al igual que ang_giro y distancia son variables útiles en algunos movimientos para indicar que se ejecute durante una determinada longitud o ángulo. Por último, melodía permite asignar un tono a cada uno de los movimientos. Proyecto fin de carrera 164 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. A la hora de realizar las modificaciones debemos tener muy en cuenta el rango de valores que admiten los parámetros de velocidad y distancia. En ambos casos los valores numéricos deben estar entre 0 y 255; en el caso de velocidades este número indicará la velocidad en milímetros por segundo, en el caso de la distancia estaremos hablando de milímetros y en si modificamos el ángulo de giro lo especificaremos en grados sexagesimales. Parámetro Velocidad Distancia Ángulo de giro Rango 0-255 0-255 0-360 Unidades mm/s Mm grados sexagesimales Tabla 30: Tabla con los parámetros configurables del archivo 'config_mov.ini' Por otro lado, el administrador también tiene la opción de configurar los sockets, por donde recibirá los movimientos de otra aplicación que quiera hacer uso de Roomba, y del puerto serie, por el que enviará los comandos a Roomba una vez hecha la conversión entre movimientos y comandos. Los valores de configuración para el socket serán la dirección y el propio número de socket en esa dirección, estos valores vendrán impuestos por la aplicación que se conecte a Roomba, en nuestro caso será el cliente y por defecto utilizará un socket de la máquina local “127.0.0.1” y el número de socket será el 6004. Cualquier aplicación que quiera hacer uso del software de control tendrá que conectarse a este socket como cliente para establecer la conexión correctamente. En la configuración del puerto serie tendremos que especificar el nombre el puerto que emplearemos y la velocidad de conexión que queremos emplear. La velocidad por defecto debe ser 115200 baudios y el nombre del puerto debemos verlo al configurar Roomba en nuestro equipo en que puerto establece la conexión. Ilustración 73: Captura del fichero ‘config_sys.ini’ 3.8.4. Detalles de implementación Comenzaremos ahora a detallar la implementación software del desarrollo de la aplicación, para esto será necesario introducir algunas de las Proyecto fin de carrera 165 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. estructuras de uso interno que se emplean en la aplicación y facilitan en gran medida el trabajo. El uso de estas estructuras junto con la posibilidad de crear tipos definidos permite encapsular y definir entidades de uso común en la aplicación. Para empezar, el Cuadro 26 muestra los tres tipos definidos que se emplean para trabajar con movimientos en esta aplicación. Es importante tener en mente este cuadro cuando posteriormente se explique el funcionamiento de la aplicación ya que se harán referencias a estas estructuras. typedef struct{ Movimiento tipo; char* nombre; int velocidad; int angulo_giro; int distancia; char melodia[MAX_MELODIA]; } TMovimiento; typedef struct{ char nombre[MAX_NOMBRE_COMANDO]; int numPar; TiposSecuencias tipoSecuencia; unsigned char *secuencia; int longSecuencia; } TNombreComando; typedef struct { char *nombre; int par1; int par2; int par3; } Tsecuencia; Cuadro 26: Tipos definidos de movimientos en Roomba Además de las estructuras encargadas de mantener información referente a las estructuras existe otro tipo definido de gran valor, Tsensores. typedef struct{ BYTE pared; BYTE borde1; BYTE borde2; BYTE borde3; BYTE borde4; BYTE ruedas; } Tsensores; Cuadro 27: Tipo definido Tsensores Proyecto fin de carrera 166 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Tsensores es una estructura de datos que se utiliza para verificar las condiciones de seguridad. En el caso de que en Roomba se intente ejecutar algún movimiento y alguno de los flags de la estructura sea diferente de cero se reflejará en el comportamiento de Roomba que ejecutará una rutina de emergencia. En esta rutina lo primero que se hace es detener el movimiento y retroceder emitiendo un sonido característico que indica la situación de peligro. Existen diversas causas que pueden provocar que Roomba se encuentre en una situación peligrosa y todas ellas se reflejan en un flag de la estructura Tsensores. Detallemos ahora cuales son estas posibles causas: Detección de pared con el detector frontal. Detección de borde, existen tres detectores en la parte de abajo que detectan un posible borde mediante el empleo de infrarrojos. Detección de rueda colgando. Conectado a la red eléctrica. Ilustración 74: Vista superior e inferior de Roomba con los sensores de pared (derecha) y de borde (izquierda) destacados. Una vez presentadas las estructuras da datos más relevantes del sistema, podemos entrar ya a comentar la estructura del software de control de Roomba. La Ilustración 75 muestra a grandes rasgos el flujo de la aplicación de control de Roomba. En primer lugar, y como es normal, es una fase inicialización. En esta etapa, la aplicación inicializa variables y lee ficheros de configuración en busca de la información necesaria. El siguiente paso consiste en establecer todos los servicios de comunicaciones. Esto implica establecer la conexión bluetooth con Roomba, e implementar sobre esta conexión bluetooth una conexión de puerto serie. Por Proyecto fin de carrera 167 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. otro lado conectarnos a través de un socket del sistema la aplicación de control de Roomba con la aplicación cliente. Una vez superada las etapas de inicialización establecimiento de las conexiones comienza realmente la aplicación de gestión de Roomba. Para lograr esto en primer lugar dividiremos el flujo del programa en dos hebras que nos permitan gestionar todo esto de forma mucho más eficaz, como veremos más adelante será necesario el empleo de una tercera hebra cuando queramos implementar la posibilidad de grabar y reproducir recorridos. Como se muestra en la Ilustración 75, el flujo principal de la aplicación será el que se encargue de comprobar las condiciones de seguridad y en caso de que todo sea correcto leerá el buffer que almacena las secuencias, traducirá estas secuencias a una ristra de bits y los enviará a través del puerto serie virtual. El concepto de secuencia está relacionado con una de las estructuras de las que hablamos en primer lugar y no son más que un procesado de los movimientos con la información contenida en el fichero ‘config_mov.ini’, por ejemplo si recibe el movimiento “( avanza )” crea una secuencia que indique avance a la velocidad definida en el fichero de movimientos. Por otro lado la otra hebra que lanzamos estará a la espera de la llegada de un mensaje a través del socket de comunicaciones con la aplicación cliente y en cuanto llegue comprobará que realmente se trata de un mensaje correcto para transformarlo en una secuencia y almacenarlo en el buffer. Como vemos existen dos hebras que acceden concurrentemente a una misma sección de memoria. Dicho esto parece clara la necesidad de usar el concepto de sección crítica a la hora de implementar el buffer de almacenamiento de estructuras de cara a evitar errores de acceso múltiple. Proyecto fin de carrera 168 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 75: Esquema del flujo principal del programa 3.8.4.1. Inicialización La fase de inicialización tiene como finalidad asignar valores predeterminados a las estructuras de datos que situarán al sistema en un estado inicial conocido. Por ejemplo, el valor de los sensores se inicia a cero, ya que partimos de la premisa de que al encender el sistema este se encuentra en un estado en el que se verifican las condiciones de seguridad, en el Cuadro 28 podemos ver la inicialización de la estructura que almacena el valor de los sensores que comprueban las condiciones de seguridad. sensores.borde1=0; sensores.borde2=0; sensores.borde3=0; sensores.borde4=0; sensores.ruedas=0; sensores.pared=0; //Estructura con el valor //de los sensores de seguridad, //por defecto a 0 //(condición de seguridad) Cuadro 28: Inicialización de la estructura Tsensores Otra de las tareas que se realiza durante la inicialización del sistema es la lectura de los archivos de configuración, tanto del fichero con la configuración definida para los puertos serie y sockets de comunicación, como el fichero en donde tenemos almacenada toda la información sobre la configuración de los movimientos que puede realizar Roomba. Para realizar la lectura de estos ficheros, ambos archivos *.ini, hemos desarrollado varias Proyecto fin de carrera 169 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. funciones que permiten leer con facilidad este tipo de archivos debido a su estructura común. Internamente los ficheros *.ini se encuentran divididos en bloques y dentro de estos bloques líneas con la información. [bloque1] Línea 1=contenido de la línea 1; . . . Línea n=contenido de la línea n; [bloque2] Línea 1=contenido de la línea 1; . . . Línea n=contenido de la línea n; [bloque n] Línea 1=contenido de la línea 1; . . . Línea n=contenido de la línea n; En primer lugar, buscaremos la información necesaria para configurar el puerto serie que utilizaremos para comunicarnos con Roomba y el socket de comunicación con el cliente. Para leer la configuración del puerto serie emplearemos la función read_file_config() que toma tres argumentos, el primero de ellos es el lugar en donde está guardado el nombre del puerto que vamos a utilizar (COM1, COM2, …). El segundo parámetro es un puntero al lugar en el que se almacenará la velocidad que tendrá el puerto serie. Por último el tercer parámetro hacer referencia al bloque dentro del fichero “config_sys.ini” en donde está almacenada la información que buscamos. Proyecto fin de carrera 170 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. char puerto_telefono[40]="puerto_serie_movil"; char port_name[MAX_LONG_NOMBRE_PUERTO]; long baud_rate = 9600; . . read_file_config(port_name,&baud_rate,puerto_telefono); . . void read_file_config(char* port_name_r,long* velocidad_r,char* puerto0){ char puerto[MAX_LONG_NOMBRE_PUERTO]=""; char* velo="115200"; long vel=0; if(DameProfileString(fichero_config_sys,puerto0,"velocidad","0",puerto,12*sizeof(cha r), FALSE)!=SIN_ERROR){ fprintf(stderr, "Error al leer velocidad en archivo config_sys.ini\n"); }else{ vel=atoi(puerto); *velocidad_r=vel; } if(DameProfileString (fichero_config_sys,puerto0,"nombre","0",puerto, 12*sizeof(char), FALSE)!=SIN_ERROR){ fprintf(stderr, "Error al leer nombre en archivo config_sys.ini\n"); }else{ puerto[strlen(puerto)]='\0'; strcpy(port_name_r,puerto); } } Cuadro 29: Llamadas a read_file_config() y detalle de la función. De forma análoga para leer para leer la configuración de los sockets emplearemos la función read_file_socket_config(). El primero de ellos es el lugar en donde está guardada la dirección de la máquina del socket que vamos a usar (en nuestro caso será en la máquina local 127.0.0.1). El segundo parámetro es un puntero al lugar en el que se almacenará el número que tendrá el puerto serie. Por último el tercer parámetro hacer referencia al bloque dentro del fichero “config_sys.ini” en donde está almacenada la información que buscamos. Proyecto fin de carrera 171 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. char name_socket_roomba[MAX_LONG_NOMBRE_PUERTO]="socket_roomba"; char socket_direccion_roomba[16]; long socket_roomba = 6000; . . strcpy(socket_direccion_roomba, "127.127.127.127"); read_file_socket_config(socket_direccion_roomba,&socket_roomba,name_socket_roomba); . . void read_file_socket_config(char* dir_socket,long* n_socket,char* equipo_id){ char dir_local[MAX_LONG_NOMBRE_PUERTO]=""; if (DameProfileString (fichero_config_sys,equipo_id,"dir_socket","0", dir_local, LONG_DIR_SOCKET FALSE)!=SIN_ERROR){ fprintf(stderr, "Error al leer nombre en archivo config_sys.ini\n"); }else{ strcpy(dir_socket,dir_local); } char numero_socket[10]; long socket=0; if (DameProfileString (fichero_config_sys,equipo_id,"n_socket","0", numero_socket, LONG_N_SOCKET, FALSE)!=SIN_ERROR){ fprintf(stderr, "Error al leer velocidad en archivo config_sys.ini\n"); }else{ socket=atoi(numero_socket); *n_socket=socket; } } El último paso de la inicialización es la lectura del fichero “config_mov.ini” para obtener los parámetros de los movimientos definidos en el sistema y a partir de esta información generar un array de estructuras TMovimiento que contenga todos los movimientos con sus respectivos parámetros. Como podemos ver en el cuadro Cuadro 30, en donde se muestran las primeras líneas de la implementación de la función “read_file_config_mov.ini”, en primer lugar se reserva memoria para todas las estructuras que vamos a almacenar, esto resulta bastante sencillo ya que disponemos de una variable global NUM_MOVIMIENTOS, que contiene el número de movimientos reconocidos. A continuación se van leyendo cada una de las secciones que contiene información sobre los movimientos y se van extrayendo los parámetros de configuración, al mismo tiempo se van creando la lista de movimientos con los parámetros de configuración adecuados. Proyecto fin de carrera 172 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. read_file_config_mov(); . . int read_file_config_mov(void){ int n_movimientos=NUM_MOVIMIENTOS; if((lista_movimientos=(TMovimiento*)calloc(sizeof(TMovimiento),n_movimientos))==NULL ){ fprintf(stderr, "calloc devuelve NULL al crear array de movimientos"); exit(0); } char* velocidad_mov="0"; char* radio_mov="0"; // Movimiento avanza_rapido... if (DameProfileString (fichero_config_mov,"avanza_rapido","velocidad","0", velocidad_mov,3*sizeof(char),FALSE)!=SIN_ERROR){ fprintf(stderr, "Error al leer Movimiento\n"); } if (DameProfileString (fichero_config_mov,"avanza_rapido","ang_giro","0", radio_mov,3*sizeof(char),FALSE)!=SIN_ERROR){ fprintf(stderr, "Error al leer Movimiento\n"); } lista_movimientos[0].melodia; if (DameProfileString (fichero_config_mov,"avanza_rapido","melodia","0", lista_movimientos[0].melodia,MAX_MELODIA*sizeof(char),FALSE)!=SIN_ERROR){ fprintf(stderr, "Error al leer Movimiento\n"); } lista_movimientos[0].tipo=AVANZA_RAPIDO; lista_movimientos[0].nombre="( avanza_rapido )"; lista_movimientos[0].velocidad=atoi(velocidad_mov); lista_movimientos[0].angulo_giro=atoi(radio_mov); // Movimiento avanza_despacio... if (DameProfileString (fichero_config_mov,"avanza_despacio","velocidad","0", velocidad_mov,3*sizeof(char),FALSE)!=SIN_ERROR){ fprintf(stderr, "Error al leer Movimiento\n"); } if (DameProfileString (fichero_config_mov,"avanza_despacio","ang_giro","0", radio_mov,3*sizeof(char),FALSE)!=SIN_ERROR){ fprintf(stderr, "Error al leer Movimiento\n"); } lista_movimientos[1].melodia; if (DameProfileString (fichero_config_mov,"avanza_despacio","melodia","0", lista_movimientos[1].melodia,MAX_MELODIA*sizeof(char),FALSE)!=SIN_ERROR){ fprintf(stderr, "Error al leer Movimiento\n"); } lista_movimientos[1].tipo=AVANZA_DESPACIO; lista_movimientos[1].nombre="( avanza_despacio )"; lista_movimientos[1].velocidad=atoi(velocidad_mov); lista_movimientos[1].angulo_giro=atoi(radio_mov); . . . . Cuadro 30: Llamada a read_file_config_mov() y primeras líneas de la implementación de dicha función. Proyecto fin de carrera 173 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. 3.8.4.2. Inicialización de las comunicaciones Después de leer los ficheros de configuración y establecer los parámetros de funcionamiento básicos del sistema, pasaremos a configurar las comunicaciones, esto es, establecer el puerto serie que nos comunique con Roomba y el socket de comunicaciones con la aplicación cliente que a su vez será el encargado de gestionar las comunicaciones con los dispositivos periféricos (wiimote, móvil y reconocedor de voz). Como ya se vio en la sección anterior, en el fichero “config_sys.ini” se encontraba la información necesaria sobre qué puerto serie y socket debemos utilizar, así como la velocidad del puerto serie. Toda esta información fue recolectada en la parte de inicialización así que en este momento ya disponemos de ella en el sistema y podremos hacer uso de ella para configurar las comunicaciones como veremos a continuación. Comenzaremos con el puerto serie, la configuración y establecimiento de la comunicación se puede dividir en dos partes, en la primera estableceremos un manejador de puerto serie con las características de transmisión necesarias y partir de este manejador y ya en una segunda etapa estableceremos la comunicación configurando un SPP (puerto serie virtual) a través de bluetooth. Es decir cuando encendemos Roomba, nuestro gestor de bluetooth en el PC, Bluesoleil en nuestro caso, detecta en el ambiente la señal de Roomba, cuando esto ocurre, el Rootooth registra en la aplicación Bluesoleil la posibilidad de emplear el perfil SPP indicando a través de qué puerto puede hacerlo. Una vez que esto ocurre podemos emplear ese número de puerto como si de uno convencional se tratase, pero una vez establecido el manejador debemos iniciar la conexión e indicar al Rootooth que vamos a transmitir información. Como hemos dicho, lo primero que haremos es crear un manejador de puerto serie, este tipo de manejador se crea igual que cuando creamos un manejador para escribir en un fichero de disco, solo que presenta ciertas características particulares, como se puede ver en el Cuadro 31, para inicializar el HANDLE llamamos a la función CreateFile como si de un fichero se tratara. A continuación invocamos los métodos GetCommState() y GetCommTimeouts() que nos darán acceso a estructuras de datos que deberemos modificar para ajustar parámetros como baudrate, paridad, bits de parada y información de control de flujo y también nos permitirá la configuración de los Timeouts del puerto. Estas estructuras son DCB y COMMTIMEOUTS. Proyecto fin de carrera 174 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. serial_port = inicializarPuertoSerie(port_name,baud_rate); . . HANDLE inicializarPuertoSerie(char* port_name,long baud_rate){ HANDLE serial_port; serial_port = CreateFile(port_name, // Nombre del puerto COMM GENERIC_READ | GENERIC_WRITE, // Modo de apertura 0, //comm devices must be opened w/exclusiveaccess NULL, // no security attrs OPEN_EXISTING, // comm devices must use OPEN_EXISTING 0, // not overlapped I/O NULL); // hTemplate must be NULL for comm devices if (serial_port == INVALID_HANDLE_VALUE){ fprintf(stderr, "Error abriendo el puerto para roomba: %s \n", port_name); CloseHandle(serial_port); exit(0); } set_up_serial_port(serial_port, baud_rate); return serial_port; } Cuadro 31: Creación del manejador para el puerto serie void set_up_serial_port(HANDLE h, long baud){ DCB properties; //Estructura que contiene la configuración del puerto serie COMMTIMEOUTS time_outs; GetCommState(h, &properties); properties.BaudRate = CBR_115200; properties.Parity = NOPARITY; properties.ByteSize = 8; properties.StopBits = ONESTOPBIT; properties.fRtsControl = 0; properties.fDtrControl=0; // Pide estrucutra de configuración //Velocidad 115200 // No paridad // 8 bits // un bit de parada // ningún tipo de control de flujo SetCommState(h, &properties); //Establece la nueva configuración GetCommTimeouts(h,&time_outs); //Coge los Timeouts del manejador h time_outs.ReadIntervalTimeout = 50; time_outs.ReadTotalTimeoutConstant = 50; time_outs.ReadTotalTimeoutMultiplier = 10; time_outs.WriteTotalTimeoutConstant = 50; time_outs.WriteTotalTimeoutMultiplier = 10; SetCommTimeouts(h, &time_outs); // Los modifica //Y los guarda } Cuadro 32: Modificación de las estructuras de datos DCB y COMMTIMEOUTS asociadas al HANDLE del puerto serie. Una vez hecho esto ya tendremos configurado un puerto serie, en realidad nosotros sabemos que este puerto serie a través del que nos hemos conectado no es un típico cable de RS-232 sino que es el puerto serie virtual que dispositivo bluetooth de Roomba ofrece a nuestro equipo. El siguiente paso por lo tanto es configurar este canal de comunicación. Para configurar el Rootooth de forma que funcione de forma correcta es necesario hacer uso de un conjunto de comandos denominados comandos AT, como se especifica en Proyecto fin de carrera 175 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. el manual de Rootooth [24]. Al enviar la cadena ‘+++’, entraremos en el modo de configuración del Rootooh, una vez estemos aquí mediante el empleo de los comandos, ya descritos en la sección de estado del arte, concretamente en el Cuadro 25, podremos adaptar el canal de comunicaciones a nuestras necesidades y finalmente salir y volver al modo transmisión de datos con la cadena ‘ATMD’ y esperando el ACK correspondiente. Ilustración 76: Figura del protocolo de comandos AT En la Ilustración 76 se puede observar de forma esquemática el proceso de configuración del Rootooth y en el Cuadro 33 podemos observar la implementación de las funciones de configuración del Rootooth que implementan dicho protolo. En concreto podemos observar como la función set_bluetooth(), recibe como parámetro de entrada el puerto serie por el que enviar la información, esta información no es nada más que las distintas cadenas de char que tenemos que enviar para realizar la configuración. Además nos apoyamos en otra función, rx_ack(), para comprobar que el ACK recibido del Rootooth es el esperado si todo funciona correctamente. Proyecto fin de carrera 176 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. int set_bluetooth(HANDLE serial_port){ unsigned char send1[]={'+','+','+',0x0D}; unsigned char send2[]={'A','T',0x0D}; unsigned char send3[]={'A','S','T','W',',',4,7,2,',',0,',',0,',',1,0x0D}; unsigned char send4[]={'A','T','M','D',0x0D}; printf("Configuracion Bluetooth...\n"); tx_secuencia (send1,serial_port,sizeof(send1)); if(rx_ack(serial_port,2)!=0){ printf(stderr,"Error en la configuracion Bluetooth\n"); } tx_secuencia (send2,serial_port,sizeof(send2)); if(rx_ack(serial_port,2)!=0){ fprintf(stderr,"Error en la configuracion Bluetooth\n"); } tx_secuencia (send3,serial_port,sizeof(send3)); tx_secuencia (send4,serial_port,sizeof(send4)); if(rx_ack(serial_port,2)!=0){ fprintf(stderr,"Error en la configuracion Bluetooth\n"); } return 0; } int rx_ack (HANDLE serial_port,int tam){ char buff[]={0,0,0,0,0,0}; char OK_ACK[]={0x0D,0x0A,'O','K',0x0D,0x0A}; unsigned long bytes_received; ReadFile(serial_port, buff,sizeof(buff), &bytes_received, NULL); buff[bytes_received]=0; printf("Respuesta Roomba: %s\n", buff); if(strncmp(buff,OK_ACK,6)==0){ return 0; } return 1; } Cuadro 33: Implementación de las funciones de configuración del Rootooh 3.8.4.3. Hebra principal La hebra principal tiene dos finalidades principales, en primer lugar comprobar periódicamente las medidas de seguridad para ejecutar una rutina de seguridad en el caso de que no se cumplan en un determinado momento. El segundo objetivo es comprobar si existe alguna secuencia almacenada en el buffer y en el caso de que la haya transformar la en una secuencia binaria y transmitirla hacia el puerto serie. La Ilustración 77 muestra un detalle del flujo de la aplicación de control de Roomba en el que se detalla el papel de la hebra principal. Proyecto fin de carrera 177 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 77: Detalle del flujo de la hebra principal de la aplicación Roomba Esquemáticamente podemos hablar de tres secciones bien diferenciadas, la primera de ellas la sección que comprueba las medidas de seguridad. Aunque cuando explicamos la arquitectura de Roomba vimos que existen modos de funcionamiento en los que se comprueban las medidas de seguridad, en este proyecto hemos decidido trabajar siempre en modo Full permitiendo el control total sobre Roomba y la posibilidad de definir una rutina de emergencia personalizada. En el Cuadro 33 se muestra la implementación de la función que implementa el control de las medidas de seguridad. Para ello se definen cadenas de arrays con la secuencia para requerir la lectura de los diversos sensores de los que dispone Roomba. Una vez que se envían estas secuencias pasamos a leer el puerto serie por donde se recibirá una respuesta por parte de los sensores en forma binaria. Esta información se almacena en la estructura de tipo Tsensores denominada ‘sensores_seguridad’. Una vez comprobados todos los sensores, llegamos a la parte final en la que se ejecuta la rutina de seguridad en el caso de que alguno de los sensores indique situación de peligro. La rutina de seguridad reacciona parando Roomba, emitiendo una melodía característica y retrocediendo durante un breve período de tiempo con la finalidad de alejarse del peligro. Para finalizar con esta sección comentar dos detalles que se pueden observar sobre la implementación. El primero de ellos en relación con la necesidad de obtener acceso exclusivo a la región crítica a través de la llamada a ‘EnterCriticalSection(&seccion_critica_buffer)’, la finalidad de hacerlo es que no se modifique el buffer de almacén de secuencias, ya que si podrían darse errores en el caso de que se ejecute la rutina de seguridad, o incluso podría ser peligroso para la integridad del sistema si se ejecuta alguna cuando no se verifican las condiciones de seguridad. El otro detalle que debemos reseñar es la existencia de un flag, denominado ‘flag_seguridad_on’ que deshabilita, en el caso de que sea necesario, la ejecución de la rutina de comprobación de medidas de seguridad. Esto resulta especialmente útil cuando ejecutamos movimientos como ‘( aspira Proyecto fin de carrera 178 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. )’ o ‘( a_casa )’ en los que las propias rutinas de Roomba se hacen cargo de la comprobación de las medidas de seguridad. void comprueba_seguridad(HANDLE serial_port, Tsensores sensores_seguridad){ if(flag_seguridad_on) { unsigned char LEDS_S[]={164,115,0,0,0}; unsigned char add_song1[]={140,1,2,70,50,80,50}; //genera u7na melodía unsigned char tono1[]={141,1}; unsigned long bytes_rec=0; BYTE lectura[]={0}; EnterCriticalSection(&seccion_critica_buffer); tx_secuencia (lee_pared,serial_port,sizeof(lee_pared)); ReadFile(serial_port,lectura,1,&bytes_rec, NULL); sensores_seguridad.pared=*lectura; tx_secuencia (lee_borde1,serial_port,sizeof(lee_borde1)); . . tx_secuencia (lee_borde2,serial_port,sizeof(lee_borde2)); . . tx_secuencia (lee_borde3,serial_port,sizeof(lee_borde3)); . . tx_secuencia (lee_borde4,serial_port,sizeof(lee_borde4)); . . tx_secuencia (lee_ruedas,serial_port,sizeof(lee_ruedas)); . . if(sensores_seguridad.borde1 || sensores_seguridad.borde2 || sensores_seguridad.borde3 || sensores_seguridad.borde4 || sensores_seguridad.pared || sensores_seguridad.ruedas){ tx_secuencia (add_song1,serial_port,sizeof(add_song1)); tx_secuencia (tono1,serial_port,sizeof(tono1)); printf("No se cumplen las medidas de seguridad\n"); tx_secuencia (retrocede,serial_port,sizeof(retrocede)); Sleep(100); tx_secuencia (para,serial_port,sizeof(para)); } LeaveCriticalSection(&seccion_critica_buffer); } return; } Cuadro 34: Implementación de la función de comprobación de las medidas de seguridad Superada la etapa de verificación de las condiciones de seguridad el flujo del programa tiene como objetivo leer el buffer de secuencias, definida como una sección crítica, en el caso de que exista alguna secuencia pendiente de ser enviada, se pasa como parámetro mediante un puntero al buffer a la función ejecuta_secuencias(), como se puede ver en el bucle que se encarga de realizar estas actividades, Cuadro 35, dentro de la función roomba_server(), que es en donde se puede definir como el esqueleto de la hebra principal. Proyecto fin de carrera 179 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. while (1){ comprueba_seguridad(serial_port, sensores); EnterCriticalSection(&seccion_critica_buffer); int puntero_lectura=punt_lectura; int puntero_escritura=punt_escritura; if(puntero_lectura==puntero_escritura){ //Si no hay nada que leer sale de la region critica espera 50ms // y vuelve a comprobar... }else{ puntero_lectura=(puntero_lectura++)%(TAM_BUFFER_SECUENCIAS); ejecuta_secuencias(serial_port,&buffer_secuencias[puntero_lectura-1],1); printf("Lectura de secuencia::: %s\n", buffer_secuencias[puntero_lectura-1].nombre); punt_lectura=puntero_lectura; } LeaveCriticalSection(&seccion_critica_buffer); } Cuadro 35: Bucle de comprobación del buffer de transmisión de secuencias El Cuadro 36 muestra la implementación de la función ejecuta_secuencias(). La función de esta llamada es leer del buffer de secuencias el siguiente elemento a enviar. Un vez leído se procesa dependiendo del tipo de secuencia del que se trata, los que se muestran en este cuadro son el TIPO_SIMPLE, TIPO_AVANZA y TIPO_FUNCION. El tipo TIPO_FUNCION es quizás el más versatíl ya que permite ejecutar cualquier función compleja. El TIPO_SIMPLE incluye secuencias que simplemente consisten en enviar una serie de comandos conocidos a través del puerto serie, por ejemplo para aspirar, volver a casa o iniciar el sistema. Es aquí en donde se desactiva si es necesario el flag de medidas de seguridad. Por último el TIPO_AVANZA indica que una parte de la secuancia de bits es conocida pero otra depende del archivo de ‘config_mov.ini’. Normalmente se trata de movimientos en los que hay que ajustar la velocidad. Proyecto fin de carrera 180 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. int ejecuta_secuencias(HANDLE serial_port,Tsecuencia int p1,p2; int k; *sec, int modo){ flag_seguridad_on=1; for(k=0;k<NELEMS(nombresComandos);k++){ // Comparamos la secuencia leída y almacenada con todas conocidas para // identificar de cual se trata. if(strncmp(sec->nombre,nombresComandos[k].nombre, strlen(nombresComandos[k].nombre))==0){ switch (nombresComandos[k].tipoSecuencia){ case TIPO_SIMPLE: if(strcmp(sec->nombre,"dock")==0) {flag_seguridad_on=0;} if(strcmp(sec->nombre,"aspira")==0) {flag_seguridad_on=0;} if(strcmp(sec->nombre,"start")==0) {flag_atiende=1;} if(strcmp(sec->nombre,"fin_roomba")==0) {flag_atiende=0;} tx_secuencia(nombresComandos[k].secuencia, serial_port,nombresComandos[k].longSecuencia); break; case TIPO_FUNCION: if(strcmp(sec->nombre,"graba1")==0) inicia_graba_ruta(1); if(strcmp(sec->nombre,"deja_graba1")==0) fin_graba_ruta(); if(strcmp(sec->nombre,"recorrido1")==0) ejecuta_ruta(1); break; case TIPO_AVANZA: p1=sec->par1; p2=sec->par2; if((p1==0)&(p2==0)){ // Si los parametros son 0 ambos se asume avanzar // a la velocidad por defecto tx_secuencia (nombresComandos[k].secuencia,serial_port nombresComandos[k].longSecuencia); }else{ nombresComandos[k].secuencia[2]=0; nombresComandos[k].secuencia[3]=p1; tx_secuencia (nombresComandos[k].secuencia,serial_port, nombresComandos[k].longSecuencia); } break; } return 0; } Cuadro 36: Implementación de la función ejecuta_secuencias() 3.8.4.4. Hebra secundaria La hebra secundaria se lanza dentro de la función roomba_server(). Esta hebra implementa una clase denominada CServidor que hereda de CSocketNode. Esta nueva clase CServidor sobrescribe la función OnMsg(), de forma que cuando llegue un nuevo mensaje a través del socket de comunicaciones se captura el mensaje y se le pasa como parámetro a la función movimiento_onmsg() en donde se procesa de forma adecuada. Es también aquí en donde se procesa el mensaje si queremos grabar un recorrido, Cuadro 37. Proyecto fin de carrera 181 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. // Creamos una nueva clase, CServidor, que hereda a CSocketNode y que sobreescribe el // método OnMsg() para que cada vez que llegue un mensaje al socket sea tratado class CServidor: public CSocketNode{ convenientemente public: void CServidor::OnMsg(char* cad,int length){ cad[length]=0; flag_recorriendo=0; movimiento_onmsg(cad); if(flag_graba_ruta){ graba_ruta(cad); } } }; Cuadro 37: Definición de la clase CServidor Continuando con el proceso del mensaje recibido según se puede ver en la vista esquemática del flujo de la hebra secundaria (Ilustración 78) una vez recibido el mensaje correctamente la función movimiento_onmsg() Ilustración 78: Detalle del flujo de la hebra secundaria de la aplicación Roomba El Cuadro 38 muestra la implementación de la función movimiento_onmsg(), lo que hace es realizar una traducción de movimiento a secuencia y almacena esta en el buffer de secuencias. void movimiento_onmsg(char* cadena){ Tsecuencia sec_c; sec_c=movimiento2secuencia(cadena); secuencia_a_buffer(&punt_lectura,&punt_escritura,buffer_secuencias,sec_c); return; } Cuadro 38: Implementación de la función movimiento_onmsg() Proyecto fin de carrera 182 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Tsecuencia movimiento2secuencia(char* movimiento){ Tsecuencia secu; Movimiento movimiento_recibido; int velocidad=0; int angulo=0; int sentido=1; char song[MAX_MELODIA]=""; int i=0; for(i;i<NUM_MOVIMIENTOS;i++){ if(strncmp(lista_movimientos[i].nombre, movimiento,strlen(lista_movimientos[i].nombre))==0){ movimiento_recibido=lista_movimientos[i].tipo; velocidad=lista_movimientos[i].velocidad; angulo=lista_movimientos[i].angulo_giro; strcpy(song,lista_movimientos[i].melodia); break;} } switch (movimiento_recibido) { case AVANZA_RAPIDO: secu.nombre="avanza"; secu.par1=velocidad; secu.par2=angulo; secu.par3=sentido; break; case AVANZA_DESPACIO: . . . break; case GIRA_RAPIDO_DCHA: . . . break; case GIRA_DESPACIO_DCHA: . . . break; case GIRA_RAPIDO_IZQ: . . . break; case GIRA_DESPACIO_IZQ: . . . break; case DA_LA_VUELTA: . . . break; case PARA: . . . break; case DEJA_ATENDER: . . . break; case ATIENDE: . . . break; . . . } return secu; } Cuadro 39: Implementación de la función movimiento2secuencia() Proyecto fin de carrera 183 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. La función movimiento2secuencia() es la encargada de transformar los movimientos en secuencias de comandos de la API Roomba, aunque como ya vimos será en la hebra principal y en momento de la transmisión cuando se conforme la conforme la secuencia definitiva, en esta función se asigna a cada movimiento el tipo de secuencia (TIPO_SIMPLE, TIPO_AVANZA, TIPO_FUNCION, etc…), un secuencia básica (TIPO_AVANZA) o la secuencia definitiva (TIPO_SIMPLE) y en algunos casos se asignan un par de parámetros, por ejemplo velocidades leídas del fichero de configuración. Por último dentro de movimiento_onmsg() se llama a la función secuencia_a_buffer() pasando como parámetro la secuencia que devuelve movimiento2secuencia(). La función secuencia_a_buffer() accede al buffer, la sección crítica, y comprueba si existe espacio disponible en el buffer, en el caso de que así sea almacena la secuencia y actuliza los punteros, en el caso de que el buffer esté lleno se va sin hacer nada. int secuencia_a_buffer(int* p_lec,int* p_esc,Tsecuencia secuencia){ *sec,Tsecuencia if(secuencia.nombre==NULL){ //Si la secuencia es NULL no hace nada }else{ EnterCriticalSection(&seccion_critica_buffer); int puntero_lectura=*p_lec; int puntero_escritura=*p_esc; if((puntero_escritura+1)%(TAM_BUFFER_SECUENCIAS)==puntero_lectura){ //Si está lleno se va sin hacer nada... }else{ puntero_escritura=((puntero_escritura++)%(TAM_BUFFER_SECUENCIAS)); check_secuencia2(secuencia,&buffer_secuencias[puntero_escritura-1]); *p_esc=puntero_escritura; } volcado_estruc(sec,TAM_BUFFER_SECUENCIAS); LeaveCriticalSection(&seccion_critica_buffer); return 0; } return 0; } Cuadro 40: Implementactión de la función secuencia_a_buffer() Proyecto fin de carrera 184 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. 4. Pliego de condiciones 4.1. Condiciones generales La obra será realizada bajo la dirección técnica de un Ingeniero de Telecomunicación y el número de programadores necesarios. La ejecución material de la obra se llevará a cabo por el procedimiento de contratación directa. El contratista tiene derecho a obtener, a su costa, copias del pliego de condiciones y del presupuesto. El ingeniero, si el contratista lo solicita, autorizará estas copias con su firma, después de confrontarlas. Se abonará al contratista la obra que realmente se ejecute, de acuerdo con el proyecto que sirve de base para la contrata. Todas las modificaciones ordenadas por el ingeniero-director de las obras, con arreglo a sus facultades, o autorizadas por la superioridad, serán realizadas siempre que se ajusten a los conceptos de los pliegos de condiciones y su importe no exceda la cifra total de los presupuestos aprobados. El contratista, o el organismo correspondiente, quedan obligados a abonar al ingeniero autor del proyecto y director de obra, así como a sus ayudantes, el importe de sus respectivos honorarios facultativos por dirección técnica y administración, con arreglo a las tarifas y honorarios vigentes. Tanto en las certificaciones de obra como en la liquidación final, se abonarán las obras realizadas por el contratista a los precios de ejecución material que figuran en el presupuesto, por cada unidad de obra. En el caso excepcional en el que se ejecute algún trabajo no consignado en la contrata, siendo admisible a juicio del ingeniero-director de las obras, se pondrá en conocimiento del organismo correspondiente, proponiendo a la vez la variación de precios estimada por el ingeniero. Cuando se juzgue necesario ejecutar obras que no figuren en el presupuesto de la contrata, se evaluará su importe a los precios asignados a ésta u otras obras análogas. Si el contratista introduce en el proyecto, con autorización del ingenierodirector de la obra, alguna mejora en su elaboración, no tendrá derecho sino a lo que le correspondería si hubiese efectuado la obra estrictamente contratada. El ingeniero redactor del proyecto se reserva el derecho de percibir todo ingreso que en concepto de derechos de autor pudiera derivarse de una posterior comercialización, reservándose además el derecho de introducir cuantas modificaciones crea convenientes. Proyecto fin de carrera 185 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. 4.2. Condiciones generales a todos los programas Estarán realizados en lenguajes estándar. Se entregarán tres copias de los listados para cada programa o subrutina. Los programas y subrutinas deberán ir documentados, indicando brevemente su función, entradas y salidas, y cualquier otra información de interés. Se entregará, junto con los programas, un manual de uso e instalación. 4.3. Condiciones generales de prueba Los programas y subrutinas que se entreguen deberán funcionar sobre un ordenador PC o compatible con microprocesador Pentium Core 2 Duo o superior y con, al menos, 512 MBytes de RAM. Se ejecutarán bajo sistema operativo Windows 2000 XP Professional o superior, en entorno local. Solamente se aceptarán los programas si funcionan correctamente en todas sus partes, rechazándose en caso contrario. Si, por causas debidas al contratista, los programas no funcionaran bajo las condiciones expuestas anteriormente, la empresa contratante se reservará el derecho de rescindir el contrato. 4.4. Recursos materiales A continuación se listan los recursos materiales que se han empleado en la realización de este proyecto Ordenador PC compatible, Pentium Core 2 Duo, 512 MB de memoria RAM y 2 GB de disco duro. Altavoces. Micrófono. Tarjeta de red Ethernet. Aspiradora Roomba. Adaptador Bluetooth Conceptronic. Mando de control Wiimote de Nintendo. Proyecto fin de carrera 186 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Teléfono móvil Nokia N70 4.5. Recursos lógicos Sistema operativo Windows XP Professional. Compilador Microsoft Visual C++ 6.0 Bluesoleil Office 2003. Proyecto fin de carrera 187 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Proyecto fin de carrera 188 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. 5. Presupuesto El presupuesto consta de cuatro apartados: de ejecución material, el presupuesto de ejecución cálculo de los gastos generales y del beneficio dirección de obra y, por último, el presupuesto conceptos anteriores. el cálculo del presupuesto por contrata que incluirá el industrial, el coste de la total, suma de todos los Todas las cantidades que aparecen están contempladas en Euros. 5.1. Presupuesto de ejecución material Se incluye en este presupuesto los gastos en herramientas empleadas, tanto hardware como software, así como la mano de obra. En la ejecución de este proyecto han participado las siguientes personas: Un Ingeniero Superior de Telecomunicación, encargado del desarrollo y redacción del proyecto, así como de la obtención e interpretación de los resultados. Un mecanógrafo, encargado de la escritura del proyecto en un procesador de textos, elaboración de gráficos, etc. 5.2. Relación de salarios Partimos del sueldo base mensual de cada una de las personas que han intervenido en el proyecto para calcular el sueldo base diario respectivo. A éste habrá que añadir las obligaciones sociales. Ingeniero Superior de Telecomunicación Sueldo base mensual Sueldo base diario Gratificación Sueldo total diario 1.334,59 44,49 6,07 50,56 632,49 21,08 5,67 26,76 Mecanógrafo Tabla 31: Sueldos de las personas que han intervenido en el proyecto Proyecto fin de carrera 189 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. 5.2.1. Relación de obligaciones sociales CONCEPTO Vacaciones anuales retribuidas Indemnización por despido Seguro de accidentes Subsidio familiar Subsidio de vejez Abono días festivos Días de enfermedad Plus de cargas sociales Otros conceptos TOTAL 8,33% 1,60% 7,00% 2,90% 1,80% 12,00% 0,75% 4,25% 15,00% 53,63% Tabla 32: Obligaciones sociales 5.2.2. Relación de salarios efectivos totales Ingeniero Superior de Telecomunicación Mecanógrafo Sueldo diario Obligaciones sociales Total/día 50,56 27,11 77,67 26,76 14,35 41,1 Tabla 33: Salarios efectivos totales 5.2.3. Coste de la mano de obra Para calcular el coste de la mano de obra basta con aplicar el número de días trabajado por cada persona por el salario respectivo. Ingeniero Superior de Telecomunicación Mecanógrafo Días Salario(€)/día Total (€) 330 77,67 25.630,7 40 41,1 1.644,13 TOTAL COSTE DE MANO DE OBRA 27.274,83 Tabla 34: Coste de la mano de obra Proyecto fin de carrera 190 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. 5.2.4. Coste total de materiales Para la ejecución de este proyecto se han empleado un ordenador personal tipo PC basado en el microprocesador Pentium Core 2 Duo, dispositivo de conexión Bluetooth de tipo USB, el teléfono móvil empleado Nokia N70, el dispositivo de juego Wiimote de la empresa Nintendo, la aspiradora Roomba de la empresa iRobot y una impresora Láser HP LaserJet 1320N, para la elaboración de toda la documentación necesaria. También se incluyen los gastos de material fungible y de oficina. Los costes referentes a los materiales utilizados se reflejan en la siguiente tabla: Precio (€) 1 ordenador personal para 1.502,53 diseño Uso (meses) Amortización (años) Total (€) 12 5 300,51 Compilador Microsoft Visual C++ 420,71 12 5 84.14 Impresora Láser HP LaserJet 1320N 780,71 1 5 13,01 Dispositivo Bluetooth 12,80 12 5 2,56 Teléfono móvil Nokia N70 179,7 12 5 35,94 Aspiradora Roomba 579 12 5 115,4 Dispositivo Wiimote 39,90 12 5 7,98 Placa de red Ethernet 120,2 - - 120,2 Material fungible y de oficina 120,2 - - 120,2 TOTAL GASTO DE MATERIAL 799,94 Tabla 35: Coste de materiales 5.2.5. Importe total del presupuesto de ejecución material Proyecto fin de carrera 191 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. El presupuesto de ejecución material se calcula basándose en los costes de mano de obra y los costes materiales. IMPORTE (€) CONCEPTO COSTE TOTAL DE MATERIALES 799,94 COSTE TOTAL DE MANO DE OBRA 27.274,83 TOTAL PRESUPUESTO DE EJECUCIÓN MATERIAL 28.074,77 Tabla 36: Presupuesto de ejecución material 5.3. Importe de ejecución por contrata Al importe de ejecución material hay que añadirle los siguientes conceptos: CONCEPTO IMPORTE (€) GASTOS GENERALES Y FINANCIEROS (22%) 6.140,83 BENEFICIO INDUSTRIAL (6%) 1.674,77 TOTAL G.G. Y B.I. 7.815,6 Resultando: IMPORTE DE EJECUCIÓN POR CONTRATA 35.890,37 Tabla 37: Importe de ejecución por contrata 5.4. Honorarios Facultativos Este proyecto se encuadra dentro del grupo XII: Aplicaciones de la Electrónica y Aparatos de Telecomunicación. Si se aplican las tarifas correspondientes sobre el importe del presupuesto de ejecución material se tiene: Hasta 30.050,61 (Coef. 1,0 sobre 7%) Hasta 60.101,21 (Coef. 0,9 sobre 7%) Proyecto fin de carrera 2.103,54 367,90 192 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. TOTAL HONORARIOS FACULTATIVOS (€) 2.471,48 Tabla 38: Honorarios facultativos Los honorarios que hay que aplicar son los correspondientes tanto por redacción del proyecto como por dirección, por lo que el total de honorarios es: Honorarios de Ingeniero por redacción 2.462,7 Honorarios de Ingeniero por dirección 2.471,48 TOTAL HONORARIOS 4.934,14 Tabla 39: Honorarios totales 5.5. Importe Total del Proyecto El Importe Total del Proyecto es la suma del Importe de Ejecución por Contrata, los Honorarios de Redacción y los Honorarios de Dirección, al cuál habrá que aplicar el 16% de IVA. EJECUCIÓN POR CONTRATA HONORARIOS IMPORTE IVA (16%) IMPORTE TOTAL 35.890,37 4.934,14 40.824,51 6.531,92 47.356,43 Tabla 40: Importe total del proyecto El importe total del presente proyecto asciende a la cantidad de CUARENTA Y SIETE MIL CIENTO CINCUENTA Y OCHO euros CON CINCUENTA Y UN céntimos. EL INGENIERO AUTOR DEL PROYECTO Fdo.: Jorge Cancela González MADRID, JULIO DE 2009. Proyecto fin de carrera 193 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Proyecto fin de carrera 194 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. 6. Bibliografía [1] CEDOM Asociación española de domótica www.cedom.es [2] Wikipedia. www.wikipedia.es, www.wikipedia.com [3] Web Oficial del SIG de Bluetooth. www.bluetooth.com [4] Web oficial del SIG de Bluetooth castellano: http://spanish.bluetooth.com/bluetooth/ [5] Andrew Tanemnaum “Computer Networks” 4th Edition Prentice Hall [6] BlueZona http://www.bluezona.com [7] Ben Morris “The Symbian OS Architecture Sourcebook” [8] Symbian OS Basics – Workbook” Nokia Corporation [9] Sergio Gálvez Rojas, Lucas Ortega Díaz “Java a tope: J2ME” [10] J2ME Building Blocks for Mobile Devices. White Paper on KVM and the Connected, Limited Device Configuration (CLDC). Sun Microsystems [11] Juan Manuel Lucas Cuesta: “Análisis e implementación de mejoras para un reconocedor de habla continua”. Proyecto fin de carrera. ETSI Telecomunicación. Madrid. UPM. 2006 [12] Nuria Pérez Magariños: “Mejora de la interfaz vocal de control de un robot autónomo móvil. Adaptación acústica y generación supervisada de mapas”. Proyecto fin de carrera. ETSI Telecomunicación. Madrid. UPM 2008 [13] Xuedong Huang, Alex Acero y Hsiao-Wuen Hon: “Spoken language processing. A guide to theory, algorithm and system development”. Prentice-Hall PTR. Upper Saddle River, New Jersey. 2001 Proyecto fin de carrera 195 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. [14] Lawrence Rabiner y Biing.Hwang Juang: “Fundamentals of speech recognition”. Prentice-Hall PTR. Englewoods Cliffs, New Jersey. 1993 [15] Datasheet de ADXL330 http://www.analog.com/static/importedfiles/data_sheets/ADXL330.pdf [16] www.wiili.org [17] Introduction to using accelerometers (A presentation from Analog Devices): http://www.analog.com/Analog_Root/static/library/techArticles/mems /sensor971.pdf [18] Some of the data sheets for Analog Devices accelerometers have hints for how to analyze the output: http://www.analog.com/en/subCat/0,2879,764%255F800%255F0%2 55F%255F0%255F,00.html [19] A paper on calculating orientation with linear accelerometers: http://www.freescale.com/files/sensors/doc/app_note/AN3461.pdf [20] Nintendo Inc. www.nintendo.es [21] Wiiuse API Overview www.wiiuse.net [22] iRobot Inc. www.iRobot.com [23] iRobot® Roomba® Serial Command Interface (SCI) Specification. Copyright 2006 – RoboDynamics Corp. [24] RooTooth User Guide Revision 1.2. Copyright 2006 – RoboDynamics Corp. [25] Nokia Inc. www.nokia.es [26] Bluesoleil Website http://www.bluesoleil.com/ [27] Advento Networks http://www.e-advento.com/ Proyecto fin de carrera 196 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. ANEXO 1. Manual de usuario del sistema Este apartado trata de ser una guía práctica sobre cómo configurar, ajustar y hacer uso de todo el sistema descrito anteriormente. Dividiremos la estructura del anexo en dos partes, separando las tareas pensadas para que las realice el usuario de las tareas que forman parte de las responsabilidades del administrador del sistema. A.1. Tareas de usuario Por tareas de usuario nos referimos solamente a las que debe hacer una persona que quiera poner en marcha el sistema y emplear las diversas interfaces de que dispone para controlar la aspiradora Roomba. A.1.1. Aplicación wiimote Como ya se ha dicho el wiimote hace uso del perfil HID de bluetooth, por eso antes de ser usado tiene que estar reconocido en el sistema. En nuestro caso el dispositivo bluetooth vamos a emplear el software Bluesoleil para trabajar con los dispositivos bluetooth, aunque con cualquier otro gestor el funcionamiento debe ser semejante. Ilustración 79: Vista de la aplicación Bluesoleil al arrancar Proyecto fin de carrera 197 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Por lo tanto para comenzar lanzamos el programa Bluesoleil (Ilustración 79) a modo de introducción podemos comentar la información que ofrece la pantalla principal de la aplicación. En la parte superior y destacado con un trazo rojo se pueden ver todos los perfiles que Bluesoleil es capaz de manejar, estos iconos aparecerán destacados cuando pinchemos sobre un dispositivo vinculado a la aplicación para remarcar qué servicios ofrece dicho dispositivo. En la zona del centro aparecen también en formato marca de agua los iconos de los dispositivos que en algún momento fueron y utilizados por la aplicación. En este caso un teléfono móvil, el dispositivo BlueRadios que hace referencia a Roomba y el dispositivo Nintendo RVL-CNT-01 que hace referencia al wiimote. Por último en la parte baja se ofrece información referente a la propia máquina en la que se está ejecutando la aplicación. Volviendo al arranque y puesta en marcha del dispositivo wiimote, el primer paso que debemos ejecutar es vincular el dispositivo wiimote con el gestor de bluetooth ya que se trata de un dispositivo HID. Para ello basta con poner el wiimote en modo ‘auto-descubrimiento’ (lo que sucede es que envía paquetes bluetooth que definen qué clase de dispositivo es, qué perfiles implementa, etc…) presionando los botones ‘1’,’2’,’+’ o ‘-’ y durante unos segundos los LED parpadearán (el número de LEDs dependerá del nivel de batería) indicando que el wiimote están enviando paquetes bluetooth para darse a conocer. Al mismo tiempo que presionamos estos botones debemos pinchar en el centro de la aplicación bluesoleil para que lea los paquetes que hay en el entorno. Si todo va correctamente el icono del Nintendo RVL-CNT-01 debe aparecer destacado y el icono del ratón de la parte superior también, indicando que el dispositivo ofrece el servicio HID, Ilustración 80. Proyecto fin de carrera 198 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 80: Aplicación Bluesoleil una vez reconocido el dispositivo wiimote Una vez reconocido el dispositivo debemos establecer una conexión. Este establecimiento de la conexión solo se tiene que hacer con el wiimote al tratarse de un dispositivo HID, con el teléfono móvil y Roomba no es necesario. El procedimiento es sencillo basta pinchar en el icono del dispositivo nintendo con el botón derecho del ratón, seleccionar ‘Connect’ en el menú despegable y seleccionar el único perfil que ofrece ‘Bluetooth Human Interface Device Service’, Ilustración 81. Proyecto fin de carrera 199 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 81: Proceso de conexión del dispositivo wiimote Ilustración 82: Vista de Bluesoleil una vez establecida la conexión con el wiimote Finalmente podemos lanzar la aplicación ‘wiimote.exe’ para comenzar a manejar el wiimote. La información que ofrece esta aplicación si arranca y funciona correctamente es la que se puede ver en la Ilustración 83. Las primeras líneas ofrecen información general sobre el número de wiimote detectados y cuantas conexiones existen, inmediatamente después de Proyecto fin de carrera 200 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. establecer el servicio de servidor comienza con los intentos de conexión con cliente, por cada uno de los intentos imprime un línea ‘Conectando con el cliente’. Una vez conectado con el cliente ofrece información sobre el estado del wiimote y comienza a escuchar eventos y reenviarlos hacia el cliente. Ilustración 83: Vista de la aplicación 'wiimote.exe' La configuración del mando wiimote se muestra continuación de forma gráfica y de forma textual según aparece en el fichero ‘config_sys.ini’. Proyecto fin de carrera 201 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 84: Configuración por defecto del mando wiimote button_UP=( avanza_despacio ) button_UP_2=( avanza_rapido ) button_DOWN=( retrocede ) button_DOWN_2=( retrocede ) button_RIGHT=( gira_despacio_derecha ) button_RIGHT_2=( gira_rapido_derecha ) button_LEFT=( gira_despacio_izquierda ) button_LEFT_2=( gira_rapido_izquierda ) button_A=( para ) button_B= activa el control con aceleradores button_MINUS=( deja_de_atender ) button_PLUS=( atiende ) button_HOME=( a_casa ) button_ONE=( aspira ) button_TWO=( aspira ) Ilustración 85: Configuración por defecto del mando wiimote Proyecto fin de carrera 202 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. A.1.2. Aplicación cliente La única tarea que debe realizar el usuario con el cliente es lanzar la aplicación. Es recomendable arrancarla en primer lugar ya que el resto de aplicaciones se intercomunican a través de esta, por lo tanto cuando arranquemos cualquier aplicación buscará la conexión con el cliente en el socket adecuado y aunque la aplicación cliente está continuamente buscando al resto de aplicaciones en los socket, haciendo que sea indiferente si se conectan antes o después, es buena práctica comenzar lanzado esta aplicación aunque no es estrictamente necesario. La aplicación cliente refresca continuamente el estado de las conexiones con las distintas aplicaciones, indicando con un ‘1’ que la conexión está correctamente establecida. Ilustración 86: Vista de la aplicación cliente en ejecución A.1.3. Servivox Una vez configurado el reconocedor de voz como se indica en la sección de administrador el usuario, se limita a arrancar la aplicación y emplear cualquiera de las frases registradas en la configuración de Servivox para enviar el movimiento deseado. Movimiento ( atiende ) o hola rumba o qué tal o atiende ahora o buenos días o buenas tardes o escúchame Proyecto fin de carrera 203 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Movimiento ( deja_de_atender ) o desconecta o adiós o apágate o cerrar Movimiento ( avanza_despacio o avanza despacio o avanza o adelante o arranca o muévete hacia delante Movimiento ( retrocede ) o hacia atrás o retrocede o atrás o retrocede o marcha atrás Movimiento ( avanza_rapido ) o avanza rápido o avanza más rápido o adelante rápido o arranca rápido o muévete Movimiento ( gira_despacio_derecha ) o gira a la derecha o gira a la derecha despacio o a la derecha o a la derecha despacio o derecha o derecha despacio o giro a la derecha o giro a la derecha despacio Movimiento ( gira_rapido_derecha ) o gira a la derecha rápido o gira a la derecha más rápido o a la derecha rápido o a la derecha más rápido o derecha rápido o derecha más rápido o giro a la derecha rápido o giro a la derecha más rápido Proyecto fin de carrera 204 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Movimiento ( gira_despacio_izquierda ) o gira a la izquierda o gira a la derecha izquierda o a la izquierda o a la izquierda despacio o izquierda o izquierda despacio o giro a la izquierda o giro a la izquierda despacio Movimiento ( gira_rapido_izquierda ) o gira a la izquierda rápido o gira a la izquierda más rápido o a la izquierda rápido o a la izquierda más rápido o izquierda rápido o izquierda más rápido o giro a la izquierda rápido o giro a la izquierda más rápido Movimiento ( para ) o parate ya o quieta o detente o para ya o párate ahí o no te muevas más o quédate ahí o frénate o para Movimiento ( aspira ) o limpia la habitación o limpia la casa o limpia o aspira la habitación o aspira la casa o aspira o limpia el suelo o quita el polvo Movimiento ( a_casa ) o vuelve a casa o a casa o busca tu casa o vuelve a cargarte o encuentra tu casa o encuentra tu cargador Proyecto fin de carrera 205 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. o vuelve al inicio o busca el punto de inicio Movimiento ( da_la_vuelta ) o de la vuelta o sentido contrario o cambia de orientación A.1.4. Aplicación teléfono móvil En el caso del teléfono móvil debemos lanzar dos aplicaciones, la de gestión de mensajes en el PC y la aplicación en el teléfono móvil. En primer lugar lanzamos la aplicación desde el menú principal del teléfono móvil N70. Ilustración 87: Aplicación RoombaN70 en el menú principal del teléfono móvil N70 En cuanto arrancamos la aplicación automáticamente comenzará la búsqueda de dispositivos bluetooth en el ambiente. Si aparece el equipo que buscamos podemos detener la búsqueda con el botón Stop. Ilustración 88: Búsqueda de dispositivos bluetooth Proyecto fin de carrera 206 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Al finalizar la búsqueda seleccionamos el equipo en el que queremos establecer el servicio SPP y la aplicación MIDlet comenzará a establecer las comunicaciones necesarias. Ilustración 89: Establecimiento de las conexiones bluetooth Debemos aceptar el uso de las herramientas de comunicación por parte de la aplicación RoombaN70. Ilustración 90: Mensaje de protección del teléfono móvil N70 Ilustración 91: Mensaje de confirmación del establecimiento del servicio SPP en el equipo seleccionado. Proyecto fin de carrera 207 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Hasta ahora lo que hemos hecho es seleccionar un equipo determinado y establecer un servicio de SPP en ese equipo, de forma que a partir de ahora podemos arrancar la aplicación del PC ya que a partir de ahora ya puede encontrar el puerto COM. Por otro lado la aplicación del teléfono móvil nos informa que el servicio se ha establecido correctamente, seleccionamos en el menú de la izquierda y elegimos la opción Roomote. Una vez aquí podemos emplear el joystick del teléfono móvil para control Roomba. Ilustración 92: Pantalla principal de la aplicación RoombaN70 Si queremos seleccionar otro de los posibles movimientos disponibles, seleccionamos la opción Movimientos en el lado izquierdo de la pantalla y nos aparecerá una lista con todos los movimientos disponibles. Seleccionando el movimiento y a continuación ‘Opciones->Enviar’ enviaremos el mensaje con el movimiento a la aplicación del PC. Ilustración 93: Lista de movimientos disponibles Por otro lado la aplicación del PC está esperando la llegada de mensajes por parte del teléfono móvil y los reenvía a la aplicación cliente imprimiendo en pantalla el mensaje recibido y si se ha enviado correctamente. Proyecto fin de carrera 208 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 94: Vista de la aplicación de gestión del teléfono móvil A.1.5. Aplicación Roomba La aplicación de gestión Roomba basta con que la aplicación Bluesoeil esté activa y Roomba con el Rootooth en el radio de acción del dispositivo de comunicaciones Bluetooth. Una vez que arranque la aplicación el usuario debe confirmar que quiere empezar a emplear Roomna enviando el movimiento ‘( atiende )’ a partir del cual ya podrá hacer lo que quiera. A.2. Tareas de administrador Las tareas del administrador del sistema son aquellas que impliquen la configuración de cada uno de los módulos que componen el sistema de cara a establecer la correcta interconexión entre cada uno de ellos y con los dispositivos externos (Roomba y teléfono móvil). A.2.1. Aplicación wiimote Los requisitos de configuración de wiimote son, la configuración del socket de comunicaciones entre la aplicación cliente y la aplicación de gestión del wiimote y en segundo lugar la configuración de los botones del dispositivo. Ambas configuraciones se realizan en el archivo ‘config_sys.ini’, para configurar el socket buscamos la entrada socket_roomba e introducimos la dirección de la máquina en la que se encuentra el socket que queremos emplear y la propia dirección del socket dentro de la máquina. En principio el único requisito para seleccionar un socket es que ninguna aplicación lo emplee de manera habitual. Proyecto fin de carrera 209 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 95: Detalle de la entrada socket_wiimote del fichero 'config_sys.ini' Por otro lado, para la configuración de los botones debemos modificar las variables de la entrada config_wiimote, asociando cada uno de los botones con la cadena de texto que queremos asociar con los eventos provocados por ese botón o acción. El texto que se transmitirá por el socket será tal y como se introduzca en este campo. Ilustración 96: Detalle de la entrada config_wiimote en el archivo 'config_sys.ini' A.2.2. Aplicación cliente La configuración de la aplicación cliente simplemente debe ajustar todos los sockets de comunicación con todas y cada una de las aplicaciones que vamos a emplear. En cada una de las entradas de socket_roomba, socket_wiimote, socket_movil y socket_reconocedor podemos adaptar la dirección IP de la máquina del socket en el que se encuentra el socket y el número de socket adecuado. Proyecto fin de carrera 210 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Ilustración 97: Entradas de configuración de los sockets del sistema en el fichero 'config_sys.ini' A.2.3. Servivox En la aplicación Servivox podemos realizar varias tareas de administrador, la más obvia de ellas es asignar más frases a cada uno de los movimientos de disponibles; para hacerlo debemos modificar el archivo ‘frases.comandos’. Este archivo contiene una línea por cada una de las frases en las que se asigna cada una de ellas con un comando que se enviará si la confianza del reconocimiento supera cierto umbral. La estructura de cada una de las líneas tiene la siguiente estructura: frase que queremos reconocer -> orden[comando_que_queremos_enviar] Al incluir esta línea en el fichero frases.comandos, el reconocedor Servivox transmitirá por el socket de comunicaciones el mensaje ‘( comando_que_queremos_enviar )’ cuando reconozca la ‘frase que queremos reconocer’ con una confianza suficientemente alta. Es decir, en realidad no es estrictamente necesario que se reconozca la frase completa y exacta sino que se reconozca una frase que se asemeje a la definida con una confianza alta, por ejemplo, podemos reconocer ‘frase_que_queremos’ y que Servivox la asocie a la ‘frase_que_queremos_reconocer’ por ser la más próxima en su gramática y que esto lo haga otorgandole una alta confianza. Además de añadir frases al reconocedor también debemos hacer otras tareas de administración como por ejemplo las tareas referentes a la configuración del micrófono o parámetros propios del reconocedor de voz. En [12] podemos encontrar un completo manual de usuario para obtener el máximo rendimiento de Servivox. Aquí vamos a reproducir algunas de sus Proyecto fin de carrera 211 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. secciones, concretamente las referentes a la configuración de los parámetros de Servivox y la puesta en marcha del reconocedor en modo automático. A.2.3.1. Configuración de Servivox El fichero ‘Urbano.ini’ es el fichero de configuración en donde se encuentran todas las variables que será necesario modificar para adaptar el sistema a las condiciones del entorno y tarea que se vaya a desempeñar en cada momento. Está dividido en cuatro grandes secciones: línea 0, Gramática, Modelos y Wav. En nuestro caso las secciones que más nos van a interesar con línea 0 y gramática. Sección línea 0 Al comienzo del fichero se encuentran las variables relacionadas con la configuración del sistema para ejecutar los diferentes casos de uso que se detallan en el siguiente apartado. o “modoAutomatico” es la variable que indica si el usuario desea que el proceso de configuración del sistema sea o no transparente para él. Los posibles valores que puede tomar son: Valor 0: El modo automático está desactivado y, por tanto, el usuario puede modificar manualmente la configuración del sistema. Valor 1: El modo automático está activado y, por tanto, la configuración/ funcionamiento del sistema es transparente al usuario. o “adaptacionNecesaria” es la variable que indica al sistema si es necesario que el usuario lleve a cabo un proceso de adaptación de los modelos de lenguaje a su voz. Si el modo automático está activo, se ignorará el valor de esta variable. Los valores que puede tomar son: Valor 0: No es necesario adaptar los modelos acústicos al locutor. Valor 1: Es necesario que el locutor lleve a cabo un proceso de adaptación. El siguiente grupo de variables son las variables relacionadas con el detector. Está preparado para cambiar de una configuración para un entorno ruidoso o para un entorno con bajo nivel de ruido, según se comenten unas u otras variables. El sistema ignorará todas las líneas y textos que vayan precedidos de punto y coma en los fichero de inicialización, considerándolos comentarios. Proyecto fin de carrera 212 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. ;Nivel low del detector HC Nivel low del detector HC ;Nivel speech del detector HC Nivel speech del detector HC ;Nivel high del detector HC Nivel high del detector HC = 3 = 6 = 20 = 9 = 25 ; ; = ; ; ; en en 6 en en en dbs dbs * ; en dBs dBs * dBs dBs * Cuadro 41: Configuración de las variables relativas al ruido en el entorno Actualmente se encuentra activa la configuración para un entorno de grabación con alto nivel de ruido. o “Nivel low del detector HC” es el nivel en decibelios relativos al ruido de fondo estimado a partir del cual el detector considera que puede haber habla. Además, una vez se ha terminado de hablar el sistema deberá detectar que los niveles de sonido se encuentran por debajo de este umbral durante un cierto tiempo para considerar que ha comenzado o terminado de hablarse. Actualmente su valor es 6 dB debido a la configuración de entorno ruidoso. Si el entorno no fuese ruidoso el valor sería 3dB. o “Nivel speech del detector HC” es el nivel en decibelios que debe superarse durante un cierto tiempo para que el sistema considere que se está hablando. Su valor actual es 20 dB para la configuración de entorno ruidoso. El valor para el entorno no ruidoso es de 6dB. o “Nivel high del detector HC” es el nivel máximo que debe superarse al menos una vez mientras el usuario habla para que se considere como habla. Su valor actual es 25 dB ya que la configuración activa es la correspondiente a un entorno ruidoso. Si el entorno no es ruidoso el valor de esta variable es 9dB. Dentro de este grupo de variables del detector también se encuentran las variables que controlan los tiempos de silencio para determinar el comienzo y el final de la voz. De todas ellas, la más importante es: o “Tiempo máximo debajo de Speech HC” que determina los milisegundos que deben transcurrir para que el detector considere que el locutor ha terminado de hablar. Su valor actual es 700 ms, pero puede subirse en caso de que haya más ruido o bajarlo si hay menos ruido. El siguiente bloque de variables determina cuáles son los dispositivos asociados con las tarjetas de sonido del ordenador: Proyecto fin de carrera 213 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. o “SoundBlasterIn”: Dispositivo de entrada de la tarjeta de sonido. Su valor varía entre 0 o 1 dependiendo del ordenador. Actualmente vale 0. o “SoundBlasterOut”: Dispositivo de salida de la tarjeta de sonido. Su valor varía entre 0 o 1 dependiendo del ordenador. Actualmente vale 0. Después están las variables para el reconocimiento, la parametrización y la comprensión: o “Tiempo máximo reconocimiento continua” especifica la duración en segundos de la frase más larga que puede decirse. Una mayor duración de frase implica un mayor consumo de memoria. Su valor actual es 10 segundos. o “Aprendizaje Reglas” es un flag que indica si el método de aprendizaje que se empleará a la hora de reconocer y traducir lo reconocido al comando que se enviará al robot se realizará mediante el empleo de reglas. Puede tomar dos posibles valores: Valor 0: Desactiva el aprendizaje mediante reglas. Valor 1: Activa el aprendizaje mediante reglas. Es un método más lento pero permite asociar varios comandos a una frase. Actualmente el valor de esta variable es 0. o “Aprendizaje Trigramas” es un flag que indica si el método de aprendizaje que se empleará a la hora de reconocer y traducir lo reconocido al comando que se enviará al robot se realizará mediante el empleo de trigramas. Puede tomar dos posibles valores: Valor 0: Desactiva el aprendizaje mediante trigramas. Valor 1: Activa el aprendizaje mediante trigramas. Es un método más lento pero sólo puede asociarse un comando a cada frase. Actualmente el valor de esta variable es 1. Las tres siguientes variables se relacionan con la comunicación entre cliente y servidor: o “PalabraRuido” contiene la palabra que el cliente enviará como respuesta para permitir al sistema la estimación inicial de los niveles de ruido del entorno. Su valor actual es “ruido” pero puede cambiarse. Proyecto fin de carrera 214 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. o “PalabraEstimarRuido” almacena la palabra que se enviará al cliente para pedir permiso al comienzo de la ejecución para estimar el ruido. Su valor actual es “EstimarRuido”. o “PuertoReconocimiento” tiene el número de puerto donde se encuentra el servidor de habla. El valor actual es 6003. Las últimas variables de esta sección se refieren al filtrado de las palabras reconocidas en función de la confianza con que han sido reconocidas y a la posibilidad de eliminar ficheros antiguos que puedan llevar a error en caso de que no se sobre-escriban correctamente. o “enviaConfianzaCompleta” es una variable que indica si al texto que se ha reconocido hay que añadirle la confianza con que ha sido reconocido o no. Los posibles valores que tiene son: Valor 0: No se añade la confianza al texto reconocido y enviado. Valor 1: Se añade la confianza al texto reconocido. Actualmente su valor es 0. o “limpiaDirectorios” es una variable que indica si el usuario quiere eliminar todos los ficheros y archivos de las carpetas de uso para evitar posibles errores derivados de utilizar archivos antiguos o equivocados. Puede tener los siguientes valores: Valor 0: No se eliminan ficheros. Valor 1: Se eliminan los ficheros conflictivos. Actualmente su valor es 1. Sección gramática La sección de gramática tiene las siguientes variables: o “dir_dic” es el directorio en el que se encuentran los diccionarios. Puesto que cada tarea tiene asociados unos diccionarios, este directorio deberá corresponderse con el de la tarea. El formato es: ..\data\nombreDirectorioTarea\. Es muy importante poner la última barra ya que, en caso de no ponerla, el sistema no funcionará. o “dir_gram” es el directorio en el que están las gramáticas de la tarea y, por lo tanto, tiene el mismo valor que el directorio de los diccionarios. Proyecto fin de carrera 215 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. o “NomFicheroTextoEtrenamiento” contiene el nombre fichero de frases de cada tarea con la extensión .txt del o “regeneraComprensión” es un flag que indica al sistema la necesidad de generar la compresión, es decir, asociar las frases con los comandos por las que deben traducirse una vez sean reconocidas. Si tiene un valor igual a 0, no se regenerará la comprensión y, por lo tanto, el tiempo que tardará el sistema en estar preparado para reconocer será menor. Hay que tener cuidado con este flag porque si se realiza un cambio en el fichero de comandos y el flag está a 0, el sistema no asimilará los nuevos cambios realizados. Su valor actual es 1. o “max_n_palabras_continua” contiene el número de palabras diferentes que es capaz de reconocer el sistema. Su valor actual es 1000 palabras. o “FactorSuavizado” permite al sistema ser capaz de contemplar casos no aparecidos en el texto de entrenamiento. Esta variable puede tomar valores entre 0 y 1. Si está próxima a cero, permite una mayor flexibilidad a la hora de reconocer frases que no es encuentren en la lista predefinida. Si se aproxima a uno, el sistema estará casi limitado a la lista de frases predefinidas, aunque podría llegar a ser capaz de comprender si el usuario no dice las frases predefinidas exactamente de la manera en que están escritas. Sólo para valores bajos del factor de suavizado se empleará la confianza como medida de aceptación de una frase. Actualmente el valor de esta variable es 0.01. A.2.3.2. Arranque del sistema en modo automático Según esta configuración, el sistema cargará automáticamente la configuración del sistema que haya sido definida en el fichero de configuración “urbano.ini” que se ha descrito en la sección anterior. Los pasos a seguir para lograr esta configuración son: Paso 1: Abrir el archivo “urbano.ini” que se encuentra en la carpeta “DATA” y realizar los siguientes cambios y/o comprobaciones: o Comprobar que está activado el modo automático (variable modoAutomático=1), activándola en caso de que no lo estuviese. o Comprobar que la variable usuario de la sección WAV tiene asociado el nombre del usuario que en ese momento va a utilizar el sistema, cambiándolo en caso de que fuese necesario. Se deben escribir todas las letras minúsculas y teniendo cuidado de no dejar espacios detrás del nombre. Un ejemplo sería: usuario = carlos Proyecto fin de carrera 216 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. o Verificar que la variable micrófono de la sección WAV tiene el valor que se ajusta a las características del micrófono que va a emplearse. Si el micrófono está físicamente conectado al ordenador mediante un cable: microfono = cable Si el micrófono es inalámbrico, la variable debe tener el siguiente valor: microfono = inalambrico En caso de que la variable no tenga el valor deseado, deberá cambiarse al valor correcto, escribiendo todas las letras en minúscula y sin tildes. Paso 2: Lanzar la aplicación “mfc_ROBINT_release.exe” que se encuentra en la carpeta “BIN”. Al hacerlo, aparecerá la ventana del reconocedor cuya funcionalidad se detalla en la sección de interfaz gráfica del sistema. Paso 4: Decir las frases que se deseen dentro de las que se hayan definido en el archivo de comandos guardado en el directorio de tarea o frases similares. NOTA: La inicialización de Servivox no finalizará hasta que se comunique con la aplicación cliente. A.2.4. Aplicación teléfono móvil La aplicación teléfono móvil requiere dos ajustes en el fichero ‘config_sys.ini’. El puerto de comunicaciones de la aplicación de gestión del teléfono móvil con la aplicación cliente se configura como ya hemos visto en apartados anteriores, localizando en el fichero ‘config_sys.ini’ la entrada socket_movil, ajustamos las dos variables de configuración del socket. El segundo ajuste consiste en configurar los parámetros del puerto serie que va a emplear para conectar la aplicación con el teléfono móvil. Si observamos la sección puerto_serie_movil del fichero ‘config_sys.ini’ vemos que los dos parámetros necesarios para definir una conexión serie son: el nombre del puerto serie y la velocidad de transmisión. Ilustración 98: Entrada puerto_serie_movil del fichero 'config_sys.ini' Proyecto fin de carrera 217 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. En el caso del teléfono móvil la velocidad es fija a 9600 baudios y el nombre del puerto se obtiene de manera muy sencilla cuando establecemos el servicio SPP en el PC nos saldrá un mensaje para que permitamos al teléfono móvil conectarse con nuestro equipo. Cuando aceptemos ese mensaje nos dirá que el teléfono móvil ha establecido un servicio de SPP en un determinado puerto COM. En principio esta configuración solo es necesaria la primera vez que arranquemos el sistema, las siguientes veces el puerto será siempre el mismo. A.2.5. Aplicación Roomba La configuración que requiere la aplicación Roomba es la misma que la aplicación del teléfono móvil. El socket de comunicaciones con la aplicación cliente y el puerto serie de comunicación entre la aplicación y Roomba. Los parámetros de la configuración son 115200 baudios de velocidad y la obtención del nombre del puerto se realiza de forma semejante al caso del teléfono móvil. La primera vez que encendamos Roomba se conectará con nuestro dispositivo bluetooth e implementará un servicio SPP en nuestro PC, una vez hecho esto nos indicará en qué puerto está instalado el servicio. Ilustración 99: Sección puerto_serie_roomba del fichero 'config_sys.ini' Proyecto fin de carrera 218 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. ANEXO 2. Información más destacable de la API Roomba En las siguientes tablas se ofrece de forma breve algunos de los comandos más útiles del API de Roomba, si desea más información puede consultar varias referencias que se ofrecen en la bibliografía Proyecto fin de carrera 219 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. Comandos de la interfaz SCI para Roomba: NOMBRE CÓDIGO Start 128 Nº DE BYTES DE DATOS 0 Baud 129 1 DESCRIPCIÓN Activa la SCI, debe ser el primero en ser enviado, pasa a modo Passive. Cambia la velocidad de transmisión, este cambio solo será persistente hasta que Roomba se reinicie. Cambia a modo Passive. La secuencia a enviar es [129][Códi.BaudRate] BaudRate Code Control 130 0 Safe 131 0 Full 132 0 Power 133 0 BaudRate in bps 0 300 1 600 2 1200 3 2400 4 4800 5 9600 6 14400 7 19200 8 28800 9 38400 10 57600 11 115200 Permite el control de Roomba. Este comando debe ser enviado después del comando Stara y antes de enviar cualquier comando de control. Roomba debe estar en modo Passive y se cambia a modo Safe. Este comando pone el SCI en modo Safe. El SCI debe estar en modo Full para aceptar este comando. Activa control sin restricción sobre Roomba a través de la SCI y desactivas las condiciones de seguridad. La SCI debe estar en modo Safe para aceptar este comando y la cambia a modo Full. Pone Roomba en posición Sleep, exactamente igual que presionar el botón Power. La SCI debe estar en modo Safe o Full para aceptar este comando. Cambia la SCI a modo Passive. Tabla 41: API de Roomba (1/3) Proyecto fin de carrera 220 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. NOMBRE CÓDIGO Nº DE BYTES DE DATOS DESCRIPCIÓN Spot 134 0 Comienza un ciclo de limpieza tipo spot. Exactamente igual que presionar el botón “spot”. La SCI debe estar en modo Safe o Full para aceptar este comando. Cambia a modo Passive. Clean 135 0 Max 136 0 Drive 137 4 Comienza un ciclo de limpieza normal. Exactamente igual que presionar el botón “clean”. La SCI debe estar en modo Safe o Full para aceptar este comando. Cambia a modo Passive. Comienza un ciclo de limpieza de tiempo máximo. Exactamente igual que presionar el botón “max”. La SCI debe estar en modo Safe o Full para aceptar este comando. Cambia a modo Passive. Permite el control de las ruedas. Este comando acepta cuatro bytes de datos, que se interpretan de la siguiente como dos valores de 16 bits con signo (en complemento a dos). Los dos primeros bytes indican la velocidad media de las ruedas en milímetros por segundo (mm/s), con el byte más alto enviado primero. Los otros dos bytes indican el radio, en milímetros, que queremos que Roomba gire. El radio más grande que podemos usar hace que Roomba vaya en línea recta. La SCI debe estar en modo Safe o Full para aceptar este comando. Secuencia: [137][Velocidad byte mayor][Velocidad byte menor][Radio byte mayor][Radio byte menor] Casos especiales(radio): Línea recta=32768=hex 8000 Giro sentido horario=-1 Giro sentido anti-horario=1 Motor s 138 1 Este comando controla los motores de limpieza. El estado de cada motor se especifica con un bit en el byte de datos que acompaña al comando. Este comando no cambia el modo y la SCI debe estar en modo Safe o Full. Secuencia: [138][Bits motores] On=1;Off=0 Bit Moto r 7 n/a 6 n/a 5 n/a 4 n/a 3 n/a 2 Cepi llo Prin cipa l 1 Aspi rado ra 0 Cepi llo late ral Tabla 42: API de Roomba (2/3) Proyecto fin de carrera 221 Jorge Cancela González Desarrollo de una interfaz multimodal para un robot domótico móvil. Control por voz y mando a distancia. NOMBRE CÓDIGO Nº DE BYTES DE DATOS DESCRIPCIÓN Leds 139 3 Controla el estado de los LEDs. El estado de los LEDs de spot, clean, max y detector de suciedad se especifican con un bit en el primer byte de datos. En el led status se usan dos bits del primer byte. El LED del botón power necesita los otros dos bytes de datos, en el primero se indica el color y en el segundo la intensidad. Secuencia: [139][LEDs][Color Power][Intensidad Power] On=1;Off=0 status (bicolor rojo/verde): 00=Off; 01=rojo; 10=verde, 11=ambar POWER: color 0-255,intensidad 0-255 (y valores intermedios en ambos) Song 140 3+ 2*Número de notas Bit 7 6 LED n/a n/a 5 4 Status(2bits) 3 2 1 0 Spot Clean Max Detector Suciedad Permite almacenar hasta cinco melodías diferentes indicando el tono de la nota y la duración de la misma. El formato es el siguiente: [140][# de melodía][# de notas][tono de la nota 1][duración de la nota 1][tono de la nota 2][duración de la nota 2]...[tono de la nota N][duración de la nota N] Ejemplo de notas: Tabla 43: API de Roomba (3/3) Proyecto fin de carrera 222 Jorge Cancela González