Story Transcript
Desarrollo de actividades interactivas para pacientes con discapacidad intelectual mediante la plataforma de desarrollo Watson y el robot Nao
Grado en ingeniería informática
AUTOR: Xavier Moreno Martinez. DIRECTOR: Dr. Domènec Savi Puig Valls. DATA: 05 / 2016.
1 OBJETIVOS ............................................................................................................................ 7 1.1 TALLER DEL BINGO MUSICAL ..................................................................................................... 8 2 ESPECIFICACIONES ................................................................................................................. 9 2.1 INTELIGENCIA ARTIFICIAL Y DESARROLLO COGNITIVO WATSON DE IBM ............................................... 9 2.1.1 DIALOGO ................................................................................................................................ 10 2.1.2 CLASIFICADOR DE LENGUAJE NATURAL .......................................................................................... 10 2.1.3 TRADUCCIÓN DE IDIOMAS .......................................................................................................... 10 2.1.4 IDEAS DE PERSONALIDAD ............................................................................................................ 11 2.1.5 ANALIZADOR DEL TONO ............................................................................................................. 11 2.1.6 CONVERSOR DE VOZ A TEXTO ...................................................................................................... 11 2.1.7 ALCHEMY API .......................................................................................................................... 12 2.1.7.1 AlchemyLanguage ............................................................................................................. 12 2.1.7.2 AlchemyVision .................................................................................................................. 12 2.1.7.2.1 Detección/reconocimiento facial ................................................................................... 13 2.2 ROBOT NAO, DE ALDEBARAN ROBOTICS .................................................................................... 14 2.2.1 ACTIVIDAD ACTUAL. BINGO MUSICAL ........................................................................................... 15 2.3 PYTHON ............................................................................................................................. 16 3 DISEÑO ................................................................................................................................ 17 3.1 3.2 3.3 3.4 3.5
PROMESAS .......................................................................................................................... 17 CACHEO DE PREGUNTAS ......................................................................................................... 19 COMUNICACIÓN CON WATSON ................................................................................................ 19 COMUNICACIÓN CON NAO ...................................................................................................... 20 DEMO. BINGO MUSICAL ......................................................................................................... 20
4 DESARROLLO ....................................................................................................................... 21 4.1 WATSON ............................................................................................................................ 21 4.1.1 MECANISMO DE PETICIONES ....................................................................................................... 21 4.2 NAO .................................................................................................................................. 22 4.2.1 TAREAS DE COMPORTAMIENTO ................................................................................................... 22 4.2.2 MECANISMO DE SUSCRIPCIÓN A LOS SENSORES .............................................................................. 23 4.2.2.1 Controlador de sensores ................................................................................................... 23 4.2.2.2 Sensor ............................................................................................................................... 23 4.3 DEMO. BINGO MUSICAL ........................................................................................................ 24 5 EVALUACIÓN ....................................................................................................................... 25 5.1 ABSTRACCIÓN DE NAO ........................................................................................................... 25 6 CONCLUSIONES ................................................................................................................... 26 7 ANEXOS ............................................................................................................................... 27 7.1 CONFIGURACIÓN DEL SDK DE NAO ........................................................................................... 27 7.1.1 WINDOWS .............................................................................................................................. 27 7.1.2 MAC ...................................................................................................................................... 27 7.1.3 LINUX ..................................................................................................................................... 27 7.1.4 COMPROBANDO LA INSTALACIÓN ................................................................................................ 28
2
7.2 CONFIGURACIÓN DE ALCHEMYAPI ........................................................................................... 28 7.3 ACTIVIDAD ANTERIOR DEL BINGO MUSICAL ................................................................................ 29 7.4 EXTENDED ABSTRACT PRESENTADO PARA LA CONFERENCIA NEW FRIENDS ......................................... 30 7.5 CONFIGURACIÓN DE UN NUEVO SERVICIO EN BLUEMIX .................................................................. 31 7.5.1 RECURSOS UTILIZADOS .............................................................................................................. 36 7.5.1.1 Enlaces destacados ........................................................................................................... 36 7.5.1.2 Tecnologías utilizadas ....................................................................................................... 36 7.5.2 GLOSARIO ............................................................................................................................... 37
3
4
Figura 1 Nao durante la actividad ........................................................................................ 8 Figura 2 Servicio de analizador del tono ........................................................................... 11 Figura 3 Robot Nao............................................................................................................ 14 Figura 4 Configuración actual sin Watson de la actividad ................................................ 15 Figura 5 Configuración actual de una canción sin Watson ............................................... 15 Figura 6 Esquema del funcionamiento de una promesa en JavaScript .............................. 18 Figura 7 Funcionamiento del sistema de cacheo ................................................................ 19 Figura 8 Configuración final de AlchemyAPI ................................................................... 28
5
Código fuente 1 Ejemplo de código usando el SDK de AlchemyAPI para detección de rostros............................................................................................................................ 13 Código fuente 2 Muestreo de información resultado de la detección de rostros ............... 13 Código fuente 3 Ejemplo de uso de comportamiento y promesas ..................................... 18 Código fuente 4 Ejemplo de concatenación de promesas.................................................. 18 Código fuente 5 Ejemplo de código usando AlchemyAPI (servicio original) .................. 21 Código fuente 6 Ejemplo de código usando nuestra abstracción ...................................... 21 Código fuente 7 Método para parar todos los comportamientos ejecutándose en Nao ..... 22 Código fuente 8 Método para ejecutar un comportamiento en Nao .................................. 22 Código fuente 9 Método de extracción del valor a un sensor ............................................ 23 Código fuente 10 Método de suscripción a un sensor ....................................................... 23 Código fuente 11 Método de desuscripción a un sensor ................................................... 23 Código fuente 12 Ejemplo de código usando AlchemyAPI después de la configuración 28
6
1
Objetivos
El principal problema de la robótica de hoy en día es que el robot actúa acorde a un programa preestablecido y sometido a un comportamiento definido. Si, de algún modo, pudiésemos dotar de unas capacidades de inteligencia artificial para que parezca que el robot es capaz analizar, procesar y reaccionar basado en el entorno sin necesidad de realizar alteraciones en el código que lo ejecuta, se podría mejorar en gran medida la percepción que tenemos actualmente de los robots “inteligentes”. Este proyecto de fin de carrera sale de la unión del grupo de investigación IRCV y la Fundació Ave Maria de Sitges para dotar del robot Nao de la institución de los servicios de inteligencia artificial de Watson. La Fundació Ave Maria es una institución privada sin ánimo de lucro que ofrece atención especializada a personas adultas con discapacidad intelectual. La misión de la fundación es actuar en los ámbitos prioritarios para el crecimiento cognitivo y físico de las personas con discapacidad intelectual, para mejorar su calidad de vida, al igual que la de sus familias, con el objetivo de ser la institución de referencia para este tipo de servicios. Uno de los servicios concretos son los talleres para mejorar los procesos cognitivos de los participantes. En concreto en el taller que nos centramos es el del Bingo Musical, explicado más adelante, que ahora utiliza un comportamiento cerrado de Nao. El cual se quiere ampliar con el desarrollo de un programa externo e integrarlo con el procesamiento cognitivo de Watson para que esté más abierto y productivo. Para terminar, los objetivos de este proyecto son: 1. Plantear e implementar un middleware, o framework, formado por dos partes: a. Utilización de servicios de Watson de manera óptima y cómoda para el desarrollador. b. Utilización del SDK de Nao para operar con el robot y permitir la lectura y monitorización de sus estados, entre ellos toda la información relacionada con los sensores y comportamientos. 2. Creación de una demostración con base de actividad interactiva que mejore la ya existente actividad del Bingo Musical para hacerlo más propenso a variaciones externas en el input de datos. En adición a todo lo anteriormente mencionado, se deberá implantar un sistema de promesas, detallado más adelante, permitiendo la concatenación de acciones en Nao sean del tipo que sean. Y, además, un sistema de cacheo de peticiones a los servicios de Watson para no procesar datos idénticos, o muy parecidos entre ellos.
7
1.1
Taller del Bingo Musical
Intentando estimular los procesos cognitivos de los participantes mediante esta actividad de una forma mas entretenida. La actividad se basa en mientras el robot reproduce una canción al final los participantes van a tener que adivinar que famoso cantante de los existentes en un plafón es el que esta siendo reproducido y, si lo aciertan, tendrán que arriesgarse a descubrir que canción es concretamente. Durante la actividad para reconocer al cantante tienen que hacer uso de las imágenes puestas a disposición de los participantes, siendo cada una de ellas una fotografía bastante grande del rostro, y solo reconocerá ésta fotografía ya que la actividad ha sido entrenada para reconocer solo esa fotografía para ése cantante. También comentar que ahora para realizar una ampliación o agregar un cantante, hay que duplicar una porción de la actividad desarrollada en Choregraphe, la encargada de gestionar toda la actividad que envuelve a una canción, y, si el cantante es nuevo, habría que volver a entrenar todos los reconocimientos visuales de la aplicación agregando la cara del nuevo cantante que entrará en juego.
Figura 1 Nao durante la actividad
8
2
Especificaciones
Las especificaciones a la hora de formular el proyecto son las de utilizar los servicios de forma conjunta, en una reunión se habló de las limitaciones a nivel de recursos, ya que la idea original era ejecutar todo el código como módulos de Choregraphe, restringiendo a la utilización de los recursos del robot que, por ejemplo, carece de algún componente que sea capaz de permitir ejecutar código de manera paralela. Entonces una de las especificaciones era la ejecución de código en un punto intermedio, entre el robot y Watson, un terminal que realizará el rol de coordinador. Otro de los requisitos era la limitación de los módulos a ejecutar en la demo, siendo necesario la utilización de los comportamientos existentes y editando tan solo lo que previamente se aceptó en una reunión, el reconocimiento facial de los famosos y la parametrización de los cantantes y las canciones.
2.1
Inteligencia artificial y desarrollo cognitivo Watson de IBM
Este servicio de la empresa IBM ofrece un sistema de inteligencia artificial capaz de dar servicios como lenguaje natural, extracción de información, representación del conocimiento, razonamiento automatizado y aprendizaje automático al campo de solución a preguntas de dominio público. La configuración de cada servicio que se vaya a utilizar de Watson tiene un cierto límite de consultas mensuales asignados siendo diferente para cada uno de los servicios, al menos en el tema de las consultas, en el caso de querer entrenar algún modulo en concreto, que solo son algunos, el precio crece bastante, pudiendo entrenar el sistema en bloques de datos, no ítem a ítem. Una vez superada la cuota gratuita mensual comienza una facturación en base a cantidad de peticiones diarias/semanales/mensuales dependiendo del servicio, siendo distinto el número de peticiones máximas por fracción de tiempo disponible en cada servicio seleccionado. Una vez entendido el procedimiento de pago de cada servicio, para habilitarlo se tiene que configurar, si no está configurado ya, un contenedor de aplicaciones que no dejará de ser una máquina virtual con recursos, donde van a ser ejecutadas las aplicaciones de Bluemix (nuestros servicios configurados de Watson). Éste es otro punto a tener en cuenta, el tipo de contenedor a contratar, el contenedor básico y gratuito, por ejemplo, está limitado a 3 aplicaciones, si necesitásemos más aplicaciones que necesiten ser utilizadas en la misma cuenta se deberá pasar a un contenedor de mayor tamaño y precio. 9
2.1.1
Dialogo
Este sistema nos proporciona las características de definición de un circuito de conversación entre el usuario y nuestro programa, su definición es íntegra en un documento XML en el que se pueden definir cualquier tipo de elementos que deberían existir en una conversación. Uno de los elementos más importantes es el que define el circuito de la conversación, donde se define un estado base que es al que se va cuando el sistema no reconoce la entrada del usuario, el cual puede ser una respuesta diciendo que no lo ha entendido bien, seguido a una lista de opciones disponibles dentro del estado actual de la conversación. Otro elemento son los enlaces de palabras para que el sistema de conversaciones sea capaz de enlazar más de una palabra al mismo concepto, de modo que si un inicializador del a conversación es “hola” y “buenos días” también está definido como sinónimo de “hola”, el sistema va a reconocer que eso es un inicializador de conversación.
2.1.2 Clasificador de lenguaje natural Aquí se toma como entrada del módulo un texto que va a ser procesado, para posteriormente devolver las clases que mas coinciden con este. Por ejemplo si se formula una pregunta, serán devueltas una serie de entidades que más coincidan con la pregunta formulada. Por ejemplo que se está formulado una pregunta acerca del tiempo, y que se centra en la temperatura, o si está lloviendo, etc. El módulo está dotado de aprendizaje automático, por lo que con cada pregunta que se le formula a Watson y es procesado por el clasificador de lenguaje natural, éste aprenderá de forma automática de cada entrada en el sistema que se le haga y va a mejorar poco a poco de una manera no supervisada.
2.1.3
Traducción de idiomas
Servicio de traducción de idiomas que nos permite identificar el idioma de un texto de entrada y éste traducirlo a otro idioma, siendo especialmente para envolver todo el sistema desarrollado y dotarlo de un sistema de diversos idiomas y no cerrarse a construir un sistema solo en ingles, solo en castellano, etc.
10
2.1.4
Ideas de personalidad
Basada en una entrada en forma de texto, analiza cada una de las palabras y deduce la personalidad que hay detrás del escritor de la entrada. Para realizar tales deducciones utiliza ciertos parámetros como: ● Personalidad: apertura, introversión/extroversión, asertividad, rango emocional, empatía. ● Necesidades a satisfacer: curiosidad, harmonía, estructura, estabilidad, practicidad, etc. ● Valores inherentes: humildad, conseguir objetivos, estimulación, tradiciones, etc. 2.1.5 Analizador del tono Con este módulo se saca partido al análisis lingüístico cognitivo y permite analizar tonos a nivel de frase y a nivel de entrada de texto. Esta información al ser procesada se devuelven tres tipos de tonos: ● Emoción: ira, asco, miedo, alegría y tristeza ● Actitudes sociales: franqueza, diligencia, extroversión, simpatía y rango emocional ● Estilos de lenguaje: analítico, seguro y vacilante
Figura 2 Servicio de analizador del tono
2.1.6 Conversor de voz a texto Módulo de conversión de una grabación o voz a tiempo real a una salida en formato de texto. Permitiendo tres tipos de argumento de entrada: • • •
Idioma. Fichero de audio en FLAC, PCM, WAV u Ogg. Stream de datos de hasta 100Mb de datos.
Y dando como datos importantes de salida: 11
• • •
Texto traducido. Palabras clave identificadas. Alternativas de palabras con nivel de confianza y posicionamiento temporal dentro del audio.
2.1.7 Alchemy API La mayor rama en desarrollo dentro del servicio Watson de IBM, ofrece un conjunto de servicios que se basan en entender el contenido y contexto de entradas de datos procedentes de texto e imágenes.
2.1.7.1 AlchemyLanguage Recoge una colección de análisis textual derivado de la información semántica del contenido que se le pasa, el cual puede ser texto llano, en HTML o una URL y dejar que el servicio procese los datos. Los datos mas relevantes que es capaz de extraer del sistema son: • • • • • • • •
Autores si se trata de un artículo de noticias o de un blog. Conceptos en los que se basa el texto de entrada (CERN + bosón de Higgs = colisionador de hadrones). Fechas. Entidades como personas, sitios, organizaciones. Palabras clave. Idioma. Relaciones: sujeto, acción y objeto en cada una de las sentencias. Taxonomías de hasta 5 niveles de profundidad.
2.1.7.2 AlchemyVision Este servicio es capaz de analizar fotografías y entenderlas sin ningún tipo de entrada adicional, devolviendo como resultado una información detallada de lo que sucede en la escena, detalles como: ● Localización: Si es un paisaje, si están en un edificio, etc. ● Entorno: Limitado a si es en una localización al aire libre, información sobre el entorno, por ejemplo si está nevando. ● Personas: Si es con suficiente claridad su género y edad y, si demás son suficientemente populares, nombre y profesión, pudiendo identificar a múltiples personas a la vez. ● Objetos: Si son objetos suficientemente grandes y significativos dentro de la propia escena, intenta reconocerlos y decir que es.
12
Cada uno de esos outputs, que también pueden estar combinados entre ellos, van acompañados de un nivel de confianza para poder evaluar de algún modo a partir de qué valor se da por válida esa respuesta. 2.1.7.2.1 Detección/reconocimiento facial Este sistema de reconocimiento facial es el más elaborado de los que existe de manera pública actualmente. Te permite reconocer rostros y, en base a ellos extrae 3 tipos de datos: ● Género ● Edad ● Nombre y actividad, sólo si es lo suficientemente reconocido. def getImageData(pathName): global connectionInProgress global alchemyapi connectionInProgress = True faceTaggingResult = alchemyapi.faceTagging('image', pathName) result = {'celebrities':[], 'others':[]} if faceTaggingResult['status'] == "OK": imageFaces = faceTaggingResult['imageFaces'] if len(imageFaces) > 0: for imageFace in imageFaces: if 'identity' in imageFace: result['celebrities'].append(imageFace) else: result['others'].append(imageFace) return result
Código fuente 1 Ejemplo de código usando el SDK de AlchemyAPI para detección de rostros for faceDetected in data['celebrities']: print "Gender: " + faceDetected['gender']['gender'] print "Age: " + faceDetected['age']['ageRange'] print "Name: " + faceDetected['identity']['name'] for faceDetected in data['others']: print "Gender: " + faceDetected['gender']['gender'] print "Age: " + faceDetected['age']['ageRange']
Código fuente 2 Muestreo de información resultado de la detección de rostros
13
2.2
Robot Nao, de Aldebaran Robotics
Nao es un robot humanoide que ha ido evolucionando hasta ser completamente interactivo y personalizable. Para que los usuarios puedan trabajar sin conocimientos de programación viene con un software llamado Choregraphe, basado en programar comportamientos que puede ejecutar el robot usando módulos que utilizan las características concretas del robot. Para poder realizar peticiones a Nao, Aldebaran Robotics nos proporciona una API para acceder a las acciones básicas y datos actuales de los sensores. Entre los lenguajes existentes para utilizar la API, el escogido es Python ya que su comunidad de desarrollo es la más grande y con recursos más útiles.
Figura 3 Robot Nao
14
2.2.1
Actividad actual. Bingo Musical
Figura 4 Configuración actual sin Watson de la actividad
Figura 5 Configuración actual de una canción sin Watson
Con estos ejemplos existentes de la implementación de la actividad se imposibilita bastante la ampliación de la misma con más cantantes y además obliga a replicar a todos los existentes los cambios que se quieran realizar en la ejecución de una canción. Aún así con este proyecto se pueden extraer partes como comportamientos individuales, los cuales será necesarios invocar remotamente con nuestro framework para ahorrarnos trabajo. 15
2.3
Python
El lenguaje escogido para realizar el diseño es Python por la flexibilidad que ofrece, la línea de aprendizaje en el uso de la API con Nao y también por la comodidad de la realización de peticiones REST contra los servidores de Watson para poder usar los módulos anteriormente definidos.
16
3
Diseño
El framework se basará en proporcionar un entorno de desarrollo para poder realizar actividades con Nao facilitando una comunicación entre los dos servicios utilizando sus respectivos SDK. El framework actuará como punto intermedio permitiendo concatenar acciones basadas en eventos, que inicialmente serán emitidos a la hora de terminar unas acciones iniciales, como será explicado más adelante. Entonces el mecanismo de desarrollo de aplicaciones podrá utilizar el sistema anterior, exportando los comportamientos individualmente de Choregraphe y usándolos, una vez instalados en el robot, pudiendo enlazarlo o ejecutarlo paralelamente con otro código, ya sea del propio Nao o de Watson y lanzar cosas en cuando se resuelva la petición de Watson con la petición de datos enviada a sus servicios. La utilización de estos comportamientos diseñados en el programa facilitado por Aldebaran simplifica bastante el desarrollo de actividades ya que programar movimientos, posiciones y algún que otro comportamiento prefabricado como box en Choregraphe son bastante útiles y no son accesibles mediante el SDK ayudándonos a agilizar el proceso de desarrollo de actividades combinadas. También cabe comentar que solo se permite el envío de peticiones a Watson a 1 cada 150 milisegundos por servicio, esto significa que no se puede enviar dos peticiones de detección de rostros consecutivas en menos de 150 milisegundos, pero si una de detección de caras y de análisis de texto de forma contigua. Con esta medida se ahorra bastante tráfico de red innecesario que puede resultar de la ejecución en bucle de datos bastante parecidos dentro de un mismo entorno, por ejemplo dos capturas que se hayan realizado de la misma escena con una pequeña variación que tenga que ser despreciada a causa de un bucle que emita peticiones al detectar algún tipo de cambio en el entorno o un timer descontrolado.
3.1
Promesas
El mecanismo de promesas, basado en el original implementado en JavaScript, se basa en la creación de un hilo de ejecución para permitir correr código de una manera asíncrona. Éste sistema proporciona dos salidas de datos: then(handler) y error(handler). Además, a diferencia del original se proporciona un método que se puede llamar de manera independiente en cualquier momento para poder cancelar la ejecución si así fuese decidido a la hora de preparar la promesa.
17
Figura 6 Esquema del funcionamiento de una promesa en JavaScript
En cualquiera de las dos salidas será ejecutado el código handler, si así es indicado, asociado al tipo de respuesta, cada uno recibirá como parámetro el resultado de la operación ejecutada, siendo el motivo del error, o rechazo, en caso de que haya fallado o se haya interrumpido su ejecución. def pickMicrophone(self): self._nao.runBehavior('coger micro').then(self.thanks).error(self.error)
Código fuente 3 Ejemplo de uso de comportamiento y promesas
Gracias a este sistema se puede realizar una acción mientras se realiza otra a parte como, por ejemplo, que el robot esté bailando y a su vez cantando una canción y que cuando una de las dos actividades termine, cancele la otra de forma automática, como es lógico en alguna de las dos salidas viables programadas then o error. def playRandomMusic(self): pickedFile = random.choice(os.listdir("./" + self._folderName)) self._dancePromise = self._nao.runBehavior('bailar') playPromise = self._nao.playSound(pickedFile); playPromise.then(self._playRandomMusicAfter).error(self.error) self._dancePromise.then(self._playRandomMusicAfter).error(self.error)
def _playRandomMusicAfter(self): self._dancePromise.cancel()
Código fuente 4 Ejemplo de concatenación de promesas
18
3.2
Cacheo de preguntas
Utilizando este sistema almacenamos temporalmente las últimas peticiones realizadas a uno de los servicios con el añadido del momento en el que se hizo esa petición. Con esto podemos conseguir analizar las información que reside dentro de las peticiones y si se han hecho en un corto periodo de tiempo una petición idéntica, o muy parecida, lo que definirá si es válida o no, devolverá ese mismo resultado. Para cada tipo de petición están definidos ciertos parámetros, como en el índice de similitud, que normalmente es idéntico, como el tiempo en el que una petición cacheada es válida. Hay que mencionar que no todas las peticiones pueden ser cacheadas ya que por razones de análisis de datos es más fácil enviar directamente la consulta si la información es difícil de analizar y dejar que Watson realice su análisis.
Figura 7 Funcionamiento del sistema de cacheo
3.3
Comunicación con Watson
La comunicación con los servicios en la nube de IBM se realizarán a través de una serie de peticiones a sus servidores, el único camino viable que ofrecen son peticiones. Éste tipo de peticiones se hacen a través de un sistema de comunicación REST sobre http. Como solo consumiremos datos en forma de consultas a sus servicios, y en este caso no vamos a entrenar los servicios de Watson no se necesita ningún tipo adicional de comunicación. 19
Para poder ejecutar todo esto se requiere una configuración previa para poder registrar cada servicio que se va a utilizar, aunque el framework.
3.4
Comunicación con Nao
Para poder “hablar” con Nao tenemos que hacer uso explícito de su SDK el cual requiere la posibilidad de una conexión a internet, ya sea a través de la red local como externa, requiriendo para trabajar una dirección IP y un puerto por el que el cual esté escuchando el robot, que por defecto es el 9559. El SDK está sujeto a unas instrucciones de instalación y versiones muy concretas para cada sistema operativo siendo solo descargables desde su plataforma web teniendo código de serie del robot asociado a la cuenta del usuario en la misma.
3.5
Demo. Bingo musical
La demostración del uso aplicable del framework realizada es la de la actividad del Bingo Musical, donde se centra en la ejecución de las actividades por separado emulando el comportamiento de la actividad a la que va a sustituir. Ahora el planteamiento inicial de toda la actividad en si es en base a una cantidad predefinida de vueltas la ejecución de una canción. La solución implementada es fácilmente ampliable permitiendo varias canciones por cantante y sin ningún tipo de restricción a la hora de detectar la cara cuando el participante tiene que indicarle al robot de cuál se trata. La ejecución cuando se selecciona un cantante aleatorio y la canción sobre la que se va a realizar la pregunta es el siguiente: 1. Escenificación de la canción. 2. Preguntar qué cantante es y que se lo indiquen mediante una fotografía. 3. Una vez validado el cantante, preguntarle qué canción es.
20
4
4.1
Desarrollo
Watson
El desarrollo de acceso a los servicios de Watson, a parte del mecanismo de peticiones también tiene que tener en cuenta de la configuración de los servicios de forma individual, la cual se realiza a través de su plataforma Bluemix, siendo trabajo de cada entidad que utilice el sistema, el tema de configuración de servicios esta documentado como un anexo.
4.1.1 Mecanismo de peticiones Éste mecanismo envuelve el sistema de comunicación proporcionado por Watson para acceder y realizar consultas a sus servicios utilizando un sistema de comunicación REST a través del protocolo http, si utilizáramos directamente los métodos del SDK que proporciona IBM interpretar los resultados podría llegar a ser algo tedioso. Para el desarrollo de éste mecanismo, analizamos los servicios concretos que más útiles podrían resultar para el desarrollo de aplicaciones. Entonces en lugar de tener que entender y analizar sintácticamente cada tipo de entrada, los errores, los datos inocuos, etc. Gracias a todo esto, acoplamos a las peticiones realizadas a través del SDK de Watson una interpretación posterior que son los datos a los que accederá la persona encargada de la creación de estas actividades interactivas. from alchemyapi import AlchemyAPI alchemyapi = AlchemyAPI() text = “Creo que me va a gustar trabajar con AlchemyAPI” responseData = alchemyapi.sentiment(“text”, text) print “Sentimiento: “, response[“docSentiment”][“type”]
Código fuente 5 Ejemplo de código usando AlchemyAPI (servicio original)
from watson import Watson watson = Watson() text = “Creo que me va a gustar trabajar con AlchemyAPI” sentiments = Watson.analyze(text, Watson.SENTIMENTS) information = Watson.analyze(text) print “Sentimiento: “, sentiments.type print “Sentimiento: “, information.sentiments.type Print “Sentimiento: “, information.language
Código fuente 6 Ejemplo de código usando nuestra abstracción
21
4.2
Nao
Para el correcto funcionamiento de todas las características relacionadas con el robot ha sido creado la clase Nao que gestiona todo lo relacionado con este robot y sus sensores para poder interactuar con el. Durante la inicialización es necesaria la declaración una lista de servicios básicos que se necesitan para el correcto funcionamiento de la actividad bingo musical, siendo fácilmente ampliable a cualquier característica de Nao detallada en su SDK proporcionado por Aldebaran Robotics. En esta clase también se engloba, para simplificar la utilización del framework, a modo de propiedad una instancia, configurada con las propiedades del robot, del mecanismo de suscripción de eventos facilitando los métodos de acceso rápido subscribeTo(sensor, callback) y unsubscribeFrom(sensor, callback).
4.2.1 Tareas de comportamiento Para poder utilizar comportamientos ya definidos previamente en otros proyectos creados en Choregraphe, se ha agregado una propiedad a la clase principal Nao llamada behaviorManager que proporciona una serie de acciones para poder realizar contra los comportamientos actualmente instalados en el robot. Las acciones de acceso rápido facilitadas por la clase son, además del getter getBehaviorManager: def stopAll(self): self.getBehaviorManager().stopAllBehaviors()
Código fuente 7 Método para parar todos los comportamientos ejecutándose en Nao
def runBehavior(self, behaviorName, promise = False): if promise == False: promise = Promise() behaviorManager = self.getBehaviorManager() behaviors = behaviorManager.getInstalledBehaviors() for item in behaviors: if item.equals(behaviorName): self._executeBehavior(item, promise)
Código fuente 8 Método para ejecutar un comportamiento en Nao
Con este ultimo método se ejecutará el comportamiento name sólo si está instalado en el robot.
22
4.2.2
Mecanismo de suscripción a los sensores
4.2.2.1 Controlador de sensores Es el encargado de controlar el sistema de sensores, incorpora un sistema de suscripción a los mismos, el controlador también es el encargado de comprobar el estado de los sensores y notificar a los suscritos de su cambio a un nuevo valor. Este controlador hace uso del proxy ALMemory conectado al robot, extrayendo un listado de los sensores disponibles guardándolos en una lista de sensores disponibles. Una vez inicializado el controlador y extraída la lista de sensores solamente se dedica a esperar a que se realicen solicitudes de información, o subscripción, de cada uno de los sensores por separado. Al suscribirse a un sensor no inicializado éste se inicializa en el controlador y en la siguiente comprobación de valores se enviará el nuevo valor a todos los suscritos a ese sensor, incluido el nuevo suscriptor. def getSensorData(self, sensorToCheck): if sensorToCheck not in self.sensorDataMemory.keys(): self.initSensor(sensorToCheck) self.sensorDataMemory[sensorToCheck].latestValue =self.proxy.getData(sensorToCheck) return self.sensorDataMemory[sensorToCheck].latestValue
Código fuente 9 Método de extracción del valor a un sensor
def subscribe(self, sensor, callback): if sensor not in self.sensorDataMemory.keys(): self.initSensor(sensor) self.sensorDataMemory[sensor].callbacks.append(callback)
Código fuente 10 Método de suscripción a un sensor
def unsubscribe(self, sensor, callback): if sensor in self.sensorDataMemory.keys(): if callback in self.sensorDataMemory[sensor].callbacks: self.sensorDataMemory[sensor].callbacks.remove(callback)
Código fuente 11 Método de desuscripción a un sensor
4.2.2.2 Sensor Cada sensor por separado contiene el nombre, para poder ser identificado en la lista de sensores del controlador, el último valor cargado y una lista de callbacks, para poder realizar las acciones solicitadas por los suscritos a dicho sensor. 23
4.3
Demo. Bingo Musical
Esta clase contiene todas las secciones necesarias para la ejecución de todos los procesos que envuelve una canción. Para el correcto funcionamiento a la hora de inicializarlo hay que pasarle una instancia de Nao para tener robot con el que operar, además del nombre de una carpeta que ha de coincidir con el nombre del cantante con el que se va a ejecutar toda la operación. Para iniciar la actividad hay que llamar al método start() el cual inicializa una promesa general que va a estar presente en toda la actividad y que se resolverá al terminar de algún modo, ya sea bien o cuando ocurra algún error. Una vez iniciada la actividad y creada la promesa inicial se llama al método pickMicrophone() el cual ejecuta una serie de procedimientos: ● Ponerse en la postura stand, comportamiento instalado por defecto. ● Levantar el brazo izquierdo con la mano en posición para poder sujetar el micrófono. ● Esperar a que se le ponga el micrófono en la mano y escuchar las palabras “Aquí tienes”. Si hubiese algún tipo de error durante la ejecución de este proceso se resolvería la promesa con un error, que a su vez propaga el error resolviendo la promesa general con el mismo error, si no se procede como sigue generando, también una promesa: ● Decir “gracias”. ● Escoger una canción aleatoria de la carpeta con la que se ha inicializado, el cantante. ● Ejecutar en paralelo el comportamiento bailar y reproducir la canción escogida, siendo ejecutados por separado, ejecutando bailar en bucle hasta que termine la canción, llamando al método cancel de la promesa de bailar. ● Preguntar por la foto del cantante. ● Capturar una fotografía de lo que se le está enseñando a Nao. ● Envío la imagen a Watson usando su servicio AlchemyVision. ● Recepción del análisis del famoso mostrado, si fuese erróneo se emite el mensaje de “vaya, estuviste cerca, inténtalo de nuevo”. ● Una vez se conoce que cantante es se pregunta por la canción mediante voz. ● Ejecución del comportamiento “dime que canción es”. ● Escucha por micrófono hasta detectar alguna posible solución. ● Si es incorrecta se vuelve a preguntar, diciendo “inténtalo de nuevo”. Una vez terminado el proceso, el robot procede a aplaudir a todos los participantes del taller y, si aún quedan canciones o cantantes por procesar, continuar con el taller. 24
5
Evaluación
La evaluación de este proyecto ha sido basada en el método prueba y error, intentando en cada iteración del proyecto adaptar el sistema a un comportamiento más sencillo y natural pensando en cómo iba a ser desarrollado por la gente encargada de realizar las actividades con el robot.
5.1
Abstracción de Nao
Durante el desarrollo de la abstracción de Nao se hicieron pruebas con el simulador de Choregraphe el cual ejecutaba una instrucción y automáticamente devolvía el estado. Por otro lado la ejecución directamente ejecutando el código con el robot real en la fundación Ave Maria me di cuenta de que la ejecución era síncrona y no continuaba con el demás código necesario a ejecutar en paralelo con la actividad actual. De esta prueba, y error, salió la idea de aplicar el sistema de promesas que actualmente incorpora el lenguaje de programación JavaScript, creando un hilo de ejecución independiente para cada actividad que se vaya a ejecutar en Nao y devolviendo la promesa, que se cumplirá o rechazará cuando el robot Nao termine. Aunque también debido a esta prueba se tuvo que reescribir bastante parte del código para adaptarlo a las restricciones añadidas.
25
6
Conclusiones
Con este proyecto se ha podido crear un framework para que futuros colaboradores o empleados de entidades que generan actividades con Nao no necesiten a una persona con altos conocimientos de programación, siendo solo necesario un nivel intermedio, o incluso aprendiendo Python con el propio framework. El desarrollo de este proyecto en colaboración con la fundación ha sido interesante, por mi parte, debido a que nunca había tenido la oportunidad de poder programar utilizando un robot por medio. Ha sido bastante interesante la metodología de trabajo, tanto por parte del grupo de investigación del Dr. Domènec Puig como por parte de los miembros de la fundación Ave María de Sitges y el Instituto de robótica para la dependencia. Durante toda esta colaboración se han juntado personas de todo tipo como ingenieros informáticos, ingenieros industriales, psicólogos y los enfermeros, que realizan el cuidado y actividades con los pacientes, viendo las posibles aplicaciones de este nuevo sistema desde todos los puntos de vista, siendo estos dos últimos vitales para la implementación de la demostración en la mejora de la actividad del Bingo Musical. Al final de la experiencia ha quedado un buen sabor de boca dejando en el camino el framework realizado que, lejos de ser perfecto, quizás pueda servir como punto de partida para la creación de otros proyectos del mismo tipo o se extienda el mismo. Y, si durante éste mes, el comité de New Friends acepta el extracto extendido enviado se puede hacer una presentación y continuar con el proyecto para ayudar de algún modo a la creación de tecnologías para la ayuda en los empleos terapéuticos, mejor que mejor.
26
7
Anexos
7.1
Configuración del SDK de Nao
7.1.1 Windows Comprobar que se tenga instalada la versión 2.7 de 32 bits. Descargar e instalar pynaoqi-python-2.7-naoqi-x.x.win32.exe descargando la última versión disponible desde la web de descargas de Aldebaran.
7.1.2 Mac Se puede escoger entre dos opciones utilizar la release de Python que viene con MacOS por defecto o instalar la versión 2.7 de 32/64 bits de la página oficial de Python. Descargar e instalar pynaoqi-python-2.6-naoqi-x.x-mac64.tar.gz o pynaoqipython-2.7-naoqi-x.x-mac64.tar.gz dependiendo de la versión de Python que se haya decidido, usando la última versión disponible desde la web de descargas de Aldebaran. Definir la variable PYTHONPATH a /path/hacia/el-sdk-de-python en el caso de instalar otra que no sea la que viene por defecto. Nota para El capitán o posteriores: Hay que deshabilitar SIP con el comando csrutil disable en la consola de recuperación del Mac. A dicha consola se accede reiniciando el dispositivo y manteniendo pulsadas las teclas Comando y R.
7.1.3 Linux Para Ubuntu Natty utilizar la versión 2.7 de Python, para las demás versiones de Linux se puede utilizar tanto la versión 2.6 como la 2.7. Descargar e instalar pynaoqi-python-2.6-naoqi-x.x-linux32.tar.gz o pynaoqi-python-2.7-naoqi-x.x-linux32.tar.gz dependiendo de la versión de Python que se haya decidido, usando la última versión disponible desde la web de descargas de Aldebaran. Definir la variable PYTHONPATH a /path/hacia/el-sdk-de-python en el caso de instalar otra que no sea la que viene por defecto.
27
7.1.4
Comprobando la instalación Una vez realizada la instalación del sistema intentar ejecutar la línea de código y probar a ejecutar el script.
import naoqi
7.2
Configuración de AlchemyAPI
Para poder utilizar la parte de AlchemyAPI se tienen que realizar una serie de pasos para configurar y poder utilizar de manera adecuada el servicio de IBM. AlchemyAPI necesita una API Key (http://www.alchemyapi.com/api/register/) par acceder a sus funciones, la cual va a ser necesariamente incluida en cada petición que se realice. Para hacer más liviano el trabajo con el sistema, durante ésta configuración se configurará el entorno para que utilice de forma automática esta clave y no nos haga falta incluir manualmente la misma. Una vez tengamos la API Key, necesitamos copiar el repositorio del SDK de Python en la carpeta del proyecto. git clone https://github.com/AlchemyAPI/alchemyapi_python.git
Una vez descargado el código fuente necesitamos registrar el SDK con nuestra clave de registro, para ello entraremos a la carpeta alchemyapi_python y ejecutaremos el script pertinente. cd alchemyapi_python python alchemyapi.py NUESTRA_API_KEY
Figura 8 Configuración final de AlchemyAPI
A partir de ahora para utilizar los servicios de AlchemyAPI simplemente tendremos que importar del código la librería alchemyAPI. from alchemyapi import AlchemyAPI alchemyapi = AlchemyAPI() text = “Creo que me va a gustar trabajar con AlchemyAPI” responseData = alchemyapi.sentiment(“text”, text) print “Sentimiento: “, response[“docSentiment”][“type”]
Código fuente 12 Ejemplo de código usando AlchemyAPI después de la configuración
28
7.3
Actividad anterior del Bingo Musical ACTIVIDAD
DESCRIPCIÓN DE LA ACTIVIDAD
OBJETIVOS MATERIAL
EVALUACIÓN A TRABAJAR
BINGO MUSICAL RITUAL DE ENTRADA: El robot humanoide explica el funcionamiento de la actividad. DESARROLLO: Esta actividad consiste en el reconocimiento de diversas canciones. 1º Escuchar la Canción. 2ºel robot humanoide invita a reconocer al cantante mediante una fotografía. 3ºEn tercer lugar, el robot humanoide solicita el título de la canción, respuesta que se dará verbalmente. Finalmente, de forma individual, se coloca una ficha sobre el cantante correspondiente en el plafón individual del bingo. RITUAL DE SALIDA: Escuchar una música tranquila para relajarnos. -Reconocer a los diferentes cantantes -Asociar cada canción con el cantante -Ejercitar la memoria y la atención Imágenes Plafón individual bingo Micrófono Tapones (fichas para el plafón) Mediante el plafón individual se puede evaluar la cantidad de aciertos y errores 1.-Se puede ampliar la actividad con nuevas canciones 2.-Relacionar base de datos de imágenes de crg con pml 3.-Falta comprobar con pml. En crg funcionaba correctamente.
29
7.4
Extended abstract presentado para la conferencia New Friends
Development of interactive activities for patients with intellectual disabilities through Watson development platform and Nao robot Xavier Morenoa , Jainendra Shuklab , Joan Oliverc and Dom`enec Puigd a
School of Engineering, University Rovira i Virgili, Tarragona, Spain
Abstract— The goal of this project is to analyze the specific needs of the patients with intellectual disabilities and, as a response, build a framework which is capable to combine Watson services and Nao robot interfaces. Keywords— Nao, Watson, Framework
1. I NTRODUCTION The main inconvenience of the robotic systems oriented to aid people with intellectual disabilities is mainly
3. N AO SDK ABSTRACTION The purpose of coding an abstraction layer are to enable to actual caretakers or volunteers that have some basic knowledge about coding some simple lines of code to perform a huge variety of tasks using Watson services and mixing them with all Nao actual available behaviours. A. Accessing and monitoring sensors information
that it runs on a predefined circuit on a closed system
As an important part about interacting with Nao
that can not react in front of an unexpected behaviours.
we have to be capable of accessing information about
If there is any chance to give artificial intelligence capabilities to robots in order to simulate that the robot are capable of analyze, process and react based on the environment without the need of modify and re-adapt the code for every single environmental alteration, it would result on a wide way enhancement about the perception that we actually have about intelligent robots. 2. WATSON ’ S ARTIFICIAL INTELLIGENCE
sensors and get notified when its current state switches to a different one. By doing that we can detect when the robot’s hand are being shaked, or his head are pressed. That enables a series of interactions, like when someone salutes Nao and it starts some behaviours or listeners to start an activity that involve the participant’s action. 4. ACTIVITIES ENHANCEMENT We can enhance activities by adding an artificial
Watson development platform offers an artificial intel-
intelligence twist to their actual performance. For ex-
ligence system capable to grant services such as natural
ample for post-processing whole information that can
language processing, data extraction, knowledge repre-
be collected during the activity and, once the activity
sentation, automated reasoning and machine learning
has past, analyze the behaviour of each participant in
applied to the public domain.
relation with the activity.
30
7.5
Configuración de un nuevo servicio en Bluemix
Para poder utilizar los servicios de Bluemix hay que configurar un servicio tal como se indica en la documentación de IBM.
Obtaining credentials for Watson services Your credentials for an IBM Watson™ Developer Cloud service allow you to access the service in Bluemix®. You obtain credentials for a specific Watson service. Credentials for any service can be used only with the service for which they are obtained. You can use your service credentials from a server-side proxy application that serves as an intermediary between your client application and a Watson service. You can also use the credentials to obtain a token for direct interaction between a client and a service. For more information about the different programming models, see Programming models for Watson services. The following sections show you how to obtain your service credentials either from the Bluemix interface or from a Node.js application programmatically. Service credentials are HTTP basic authentication credentials for a specific Watson service. They are not the same as Bluemix login credentials, which are the ID and password that you use to log in to Bluemix.
Getting service credentials in Bluemix Complete the following steps to obtain your service credentials from the Bluemix interface. You can also watch a quick video that shows the steps being executed. You must already have an active Bluemix ID to obtain credentials for a service; for more information, see Registering for Bluemix. 1. Log in to Bluemix. Click the LOG IN button in the upper right corner of the page at console.ng.bluemix.net and enter your Bluemix ID and password on the authentication page that appears. 2. View the available services. Click the USE SERVICES OR APIS link on the Services & APIs tile that appears near the top of the page.
31
1. Select a Watson service. Click the tile for the Watson service you want to work with; for example, click thePersonality Insights tile to work with that service.
2. Create a service instance. Click the CREATE button at the right of the page to create an instance of the service you selected. Use the default values for the new service.
3. View your credentials. Click the Service Credentials link in the list of contents on the left of the page to view your Bluemix credentials. 4. Save your credentials. Save the contents of the JSON output that appears beneath the heading SERVICE CREDENTIALS to a permanent location such as a local text file. Specifically, you need the values of theusername and password keys to work with your application. The following credentials were obtained for the Personality Insights service.
If you plan to work with an application outside of Bluemix, you are now done using the Bluemix interface and can close the browser page in which you are working.
Getting service credentials programmatically Once you create a service instance in Bluemix, you can also obtain your credentials programmatically from an application that runs in Bluemix. This is necessary regardless of whether you plan to use a server-side proxy as an intermediary between your client and the service or plan to use tokens for direct interaction. 32
The following example code is available from the file named bluemix.js that is included in the config directory of most of the Node.js sample applications from the Watson Developer Cloud namespace on GitHub. The nameargument to the getServiceCreds function identifies the service for which credentials are to be obtained (for example, text_to_speech or tradeoff_analytics). The code extracts the URL for the service instance and the username and password for the service credentials from the VCAP_SERVICES environment variable; for more information, see The VCAP_SERVICES environment variable.
'use strict'; module.exports.getServiceCreds = function(name) { if (process.env.VCAP_SERVICES) { var services = JSON.parse(process.env.VCAP_SERVICES); for (var service_name in services) { if (service_name.indexOf(name) === 0) { var service = services[service_name][0]; return { url: service.credentials.url, username: service.credentials.username, password: service.credentials.password }; } } } return {}; };
The following snippet of code from the app.js file for a Node.js application shows the use of the bluemix.js file to obtain credentials for the specified service_name. This file defines a Bluemix proxy application that handles all communications between the client and the service. If the application is run in Bluemix, the call to thegetServiceCreds function parses the URL, username, and password from the variable and overrides the values specified in the local credentials variable. If the application is run locally, the code uses the specified local values. (The service_version must be specified locally.) The final line of code uses the credentials in a call to the constructor for a service in the Watson Developer Cloud Node.js Software Development Kit (SDK). The call returns an instance of an object that you can use to work with the service; it assigns the instance to the service variable. For more information about the SDK, see the node-sdk repository on GitHub. var bluemix = require('./config/bluemix'), watson = require('watson-developer-cloud'), extend = require('util')._extend;
33
var credentials = extend({ version: '', username: '', password: '' }, bluemix.getServiceCreds(''));
var service = watson.(credentials);
Getting new credentials for a service instance Complete the following steps to obtain new service credentials for an existing instance of a service instance by using the the Bluemix interface.
1. Log in to Bluemix. Click the LOG IN button in the upper right corner of the page at console.ng.bluemix.net and enter your Bluemix ID and password on the authentication page that appears.
2. If you are using the new Bluemix interface, you will see a Go to Classic Experience link in the header. Click Go to Classic Experience to ensure that you can follow the remainder of these instructions.
3. Select the service for which you want to obtain new credentials. Click the DASHBOARD link in the header of the page, and click the name of the service for which you want to obtain new credentials from the list of services that displays at left.
4. Display current credential information. Click the Service Credentials link in the lefthand navigation. 5. Delete your existing credentials. Click DELETE to delete your existing credentials for this service instance. A confirmation dialog displays. Click DELETE to confirm that you want to delete the current credentials. If you have multiple sets of credentials for a service, you must delete and recreate each of them.
6. Add new credentials. Click ADD CREDENTIALS to add new credentials to this service instance. The Add Credentials dialog displays, showing a default name for the set of credentials that you are creating. You can modify this name, if desired. Click ADD to create the new set of credentials, which display in the SERVICE CREDENTIALS section after they are created. 34
7. You will see a Try the new Bluemix link in the header of the page. If you were using the new Bluemix interface before following these steps and want to return to using the new Bluemix interface, click Try the new Bluemix.
After deleting existing credentials and creating new ones for an instance of a service, you must ensure that any applications that are using that service instance use the new credentials: •
If your application obtains its credentials programmatially, you must stop and restart your application.
•
If your credentials are embedded in the source code for your application, you must stop your application, update its source code to include the new credentials, and the relaunch the application. For Bluemix instructions on updating applications and getting new credentials while temporarily using your existing ones to minimize potential downtime, see Updating Apps
in the Bluemix documentation.
35
7.5.1
Recursos utilizados
7.5.1.1 Enlaces destacados •
Stackoverflow: El conocidísimo sitio web de preguntas y respuestas de programación, ha sido útil a la hora de documentarse sobre los problemas más comunes a la hora de desarrollar utilizando threads, el SDK de Watson o el de Nao. o http://stackoverflow.com/
•
Documentación de Aldebaran: Sitio web con la documentación de desarrollo de Nao, con ejemplos, tutoriales básicos y una lista de todas las clases y métodos disponibles en el SDK de Python. o http://doc.aldebaran.com/2-1/dev/python/index.html
•
Página web de la conferencia New Friends: Sitio que recoge información destacada referente a los robots aplicados a niveles terapéuticos y educacionales. o http://newfriends2015.org/
•
Documentación de Watson: Sitio web que recoge toda la información acerca de Watson y de cómo funciona cada servicio y de su modo de uso. o https://www.ibm.com/smarterplanet/us/en/ibmwatson/developercl oud/doc/
7.5.1.2 Tecnologías utilizadas • • •
Python 2.7: Lenguaje de programación utilizado en el desarrollo del proyecto. Bitbucket: Versión alternativa a GitHub utilizada por la fundación Ave María para el control de versiones de código y recursos. pyCharm: IDE para el desarrollo en Python, por su ayuda en la escritura de código accediendo a las descripciones de los métodos de los dos SDK tanto el de Watson como el de Nao.
36
7.5.2
Glosario
Framework: Estructura conceptual de soporte definido con módulos concretos de software que se usan como base para el desarrollo de software. Pudiendo incluir soporte para programas, librerías, y demás herramientas para así ayudar a desarrollar y unir distintos componentes de un proyecto. API: Conjunto de subrutinas, funciones y procedimientos que ofrece cierta biblioteca, o servicio, para ser usado por otro software como una capa de abstracción. SDK: Conjunto de herramientas de desarrollo de software que permite al programador crear aplicaciones para un sistema concreto. REST: Estilo de arquitectura de software para sistemas como el protocolo http con un conjunto de operaciones definidas: POST, GET, PUT y DELETE. Release: Estadio final en el ciclo de desarrollo de una aplicación, incrementando el número de versión de una aplicación dedicada a su uso para el usuario final. IDE: Aplicación que proporciona servicios integrales para facilitar a los programadores la escritura de código fuente y herramientas de compilación en algunos casos.
37