scieee AI-readable full text Open interactive document viewer

Plataforma para gestión de modelos 3D en entornos de realidad aumentada

Morato Perdiguero, Alejandro

Abstract

DecorAR es un sistema software de gestión de modelos 3D para ayudar a la decoración de interiores mediante técnicas de realidad aumentada (AR). La Página Web es capaz de gestionar catálogos de modelos 3D asociados a cuentas de usuario y la App móvil accede a los modelos para renderizarlos con AR.

Full text

Título: DecorAR – Plataforma de decoración con realidad aumentada. Autor: Alejandro Morato Perdiguero Fecha: Segundo cuatrimestre 2016-2017 Directora: Marta Fairen González Departamento: Dept. de Ciencias de la Computación Titulación: Enginyeria en Informàtica pla 2003 Centro: Facultat d'Informàtica de Barcelona (FIB) Universidad: Universitat Politècnica de Catalunya (UPC) BarcelonaTech DecorAR PFC 2016 -17 1 ÍNDICE 1. Introducción ................................................................................................................. 5 1.1. Motivación del proyecto ................................................................................... 5 1.2. Objetivo del proyecto ....................................................................................... 6 2. Estado del arte ............................................................................................................. 7 2.1. Que es la Realidad Aumentada ........................................................................ 7 2.2. Historia .............................................................................................................. 7 2.3. Aplicaciones en el mercado ............................................................................ 10 2.3.1. Tylko ................................................................................................. 10 2.3.2. Catálogo IKEA ................................................................................... 11 2.3.3. iStaging ............................................................................................. 11 2.3.4. WayFair ............................................................................................ 12 2.3.5. Home AR Design .............................................................................. 12 2.3.6. Tabla comparativa ........................................................................... 13 3. Descripción funcional ................................................................................................ 15 3.1. Aplicación web ................................................................................................ 15 3.1.1. Inicio ................................................................................................. 15 3.1.2. Nuevo Modelo ................................................................................. 16 3.1.3. Renderizar modelo........................................................................... 17 3.1.4. Detalles del modelo ......................................................................... 18 3.1.5. Editar datos del modelo ................................................................... 19 3.1.6. Gestión de texturas .......................................................................... 20 3.1.7. Buscador de modelos ...................................................................... 20 3.1.8. Registro de usuarios ........................................................................ 21 3.2. Aplicación movil .............................................................................................. 22 3.2.1. Inicio ................................................................................................. 22 3.2.2. Buscar modelos ................................................................................ 25 3.2.3. Detalles de modelo .......................................................................... 26 3.2.4. Realidad aumentada ........................................................................ 27 3.2.5. Target definido por usuario ............................................................. 28 3.2.6. Configuración del target .................................................................. 29 3.2.7. Modelos básicos .............................................................................. 29 DecorAR PFC 2016 -17 2 3.2.8. Captura de URL ................................................................................ 30 4. Diseño técnico............................................................................................................ 33 4.1. Arquitectura del sistema ................................................................................ 33 4.1.1. Aplicación servidor ........................................................................... 34 4.1.2. Aplicación móvil ............................................................................... 35 4.2. Infraestructura ................................................................................................ 36 4.2.1. Aplicación servidor ........................................................................... 36 4.2.2. Aplicación móvil ............................................................................... 38 4.3. Arquitectura en N-Capas ................................................................................ 40 4.4. Principios SOLID .............................................................................................. 41 4.4.1. Single Responsibility Principle ......................................................... 42 4.4.2. Open/Close Principle ....................................................................... 43 4.4.3. Liskov Substitution Principle ............................................................ 44 4.4.4. Interface Segregation Principle........................................................ 46 4.4.5. Dependency Inversion Principle ...................................................... 47 4.5. Patrón IoC (Inversion of Control) .................................................................... 48 4.5.1. Inyección de dependencias.............................................................. 48 4.5.2. Service Locator y Autofac ................................................................ 50 5. Implementación ......................................................................................................... 55 5.1. Entornos de desarrollo ................................................................................... 55 5.2. Repositorios de código ................................................................................... 55 5.3. SDK Vuforia ..................................................................................................... 56 5.3.1. Flujo de vuforia ................................................................................ 57 5.3.2. Licencia vuforia ................................................................................ 59 5.3.3. Targets ............................................................................................. 60 5.3.4. Código fuente Vuforia ...................................................................... 64 5.4. AR y OpenGL ................................................................................................... 66 5.5. WebServices ................................................................................................... 70 5.5.1. NewSession ...................................................................................... 71 5.5.2. SearchModels .................................................................................. 72 5.5.3. GetModel ......................................................................................... 73 5.5.4. GetModelVersión ............................................................................. 74 DecorAR PFC 2016 -17 3 5.6. WebGL y ThreeJs............................................................................................. 75 5.7. Entity Framework ........................................................................................... 80 5.8. LOGs ................................................................................................................ 83 5.9. Ficheros de Configuración .............................................................................. 87 6. Conclusiones .............................................................................................................. 89 6.1. Planificación .................................................................................................... 89 6.2. Revisión de la planificación............................................................................. 92 6.3. Análisis económico ......................................................................................... 94 6.3.1. Coste hardware ................................................................................ 94 6.3.2. Coste Software ................................................................................. 95 6.3.3. Costes en recursos humanos ........................................................... 95 6.3.4. Coste total del desarrollo................................................................. 95 6.3.5. Costes de explotación ...................................................................... 96 6.4. Valoraciones personales ................................................................................. 96 6.5. Líneas futuras .................................................................................................. 97 7. Bibliografía ................................................................................................................. 99 DecorAR PFC 2016 -17 4 DecorAR PFC 2016 -17 5 1. INTRODUCCIÓN 1.1. MOTIVACIÓN DEL PROYECTO Una de la partes clave del proyecto es la Realidad Aumentada (desde ahora AR por sus siglas en inglés, Augmented Reality). La AR (no confundir con Realidad Virtual) enriquece la realidad que estamos viendo con información extra. Aunque pueda sonar que es bastante novedoso, es una tecnología que ya tiene unos cuantos años. Sin embargo, aunque esta tecnología es muy útil no se usa mucho en el día a día. La mayoría de gente, más o menos sabe lo que es la AR y alguna vez la ha usado, ya sea en algún videojuego o con alguna App de asistencia en museos o en la calle para encontrar algún servicio (restaurante, metro, etc). Sin embargo, no se suele usar con asiduidad. Probablemente sea debido a que las aplicaciones de AR no sean muy usables o que la información que podría proporcionar se encuentre más rápido realizando una simple consulta a Google. A pesar de este trasfondo tan poco prometedor siempre he tenido en mente hacer una aplicación de AR que fuera útil para todo el mundo y que cualquiera con un mínimo de conocimientos podría hacerla funcionar. El proyecto consistirá en el desarrollo de un sistema para la visualización de elementos virtuales 3D en entornos reales, principalmente para decoración. De hecho el proyecto se llama DecorAR, “Decor” de decoración en inglés y “AR” de Augmented Reality. Sin embargo, gracias a su gran flexibilidad se podrá utilizar para más usos. Cuando vamos a comprar un mueble tenemos que coger medidas e ir a la tienda (ya sea física o por internet) a buscar algún producto que encaje e imaginar cómo quedaría en nuestra casa. Con esta aplicación éste último paso ya no será necesario porque podremos ver ese mueble en nuestra casa antes de comprarlo y así tomar una decisión mucho más acertada. En el mercado hay algunas aplicaciones similares pero ninguna como esta. He analizado la mayoría de ellas y casi todas tienen debilidades respecto a este proyecto. - Biblioteca de modelos 3D muy limitada y sin posibilidad de añadir nuevos. En este proyecto los usuarios podrán guardar todos los modelos 3D que quieran. - Objetos sin proporciones reales. En la mayoría de Apps, los objetos virtuales no tienen una correspondencia a medidas reales. En este proyecto los objetos que se estén visualizando en tiempo real tendrán las proporciones correctas según las medidas del usuario/fabricante. - Solo los fabricantes poderosos se pueden permitir tener Apps de AR, con este sistema cualquiera podrá crearse una cuenta de su tienda y exponer sus productos al público. DecorAR PFC 2016 -17 6 1.2. OBJETIVO DEL PROYECTO Desarrollar un sistema software para la visualización de elementos virtuales en entornos reales mediante técnicas de realidad aumentada. El sistema estará formado por 2 partes principales, la aplicación móvil y la parte servidora. La parte servidora tendrá una aplicación web donde se podrán crear cuentas de usuarios. Estos usuarios podrán crear y gestionar sus colecciones de modelos 3D. Cada usuario registrado tendrá disponible una colección de modelos privados donde solo los propietarios podrán ver esos modelos y una colección pública donde esos modelos serán visibles para el resto de usuarios. La web tendrá un visualizador 3D para ver los modelos sin necesidad de AR. Además de la web la parte servidora expondrá unos WebServices para la explotación de los datos del sistema desde otras aplicaciones. La aplicación móvil (App) será la encargada de proporcionar al usuario una experiencia de realidad aumentada mediante la cámara del dispositivo. La App solo se podrá ejecutar en sistemas operativos Android. Se accederá a la App mediante cuentas de usuario para una experiencia personalizada aunque también tendrá una opción para usuarios invitados sin registro. Tendrá conectividad con la aplicación servidora mediante internet para la gestión de los usuarios y la descarga de los modelos 3D. Los modelos descargados podrán guardarse en la App y estar disponibles sin conexión a internet. Los modelos que se visualicen en AR tendrán dimensiones reales, es decir, su relación de aspecto será el adecuado para que el espacio que ocupe virtualmente coincida con las medidas introducidas por los usuarios. DecorAR PFC 2016 -17 7 2. ESTADO DEL ARTE 2.1. QUE ES LA REALIDAD AUMENTADA La realidad aumentada (AR) es una tecnología que consiste en sobreponer en tiempo real información digital a la realidad mediante un dispositivo. No hay que confundir la realidad aumentada con la realidad virtual ya que esta primera no sustituye la realidad física como sí lo hace la virtual sino que añade información digital al mundo real en vivo y en directo. La realidad virtual (VR) es la fabricación de un mundo virtual que el cerebro entiende como real. La tecnología simula los estímulos, especialmente visuales, que consiguen sumergir al espectador dentro de un universo creado a modo de simulación. Se suele utilizar mediante gafas y sistemas donde no podemos apreciar la realidad existente, la imagen reproducida se mueve en la misma dirección que la cabeza del individuo. De esta manera resulta posible notar las mismas sensaciones que proporcionaría el mundo creado, generalmente, de manera informática. El siguiente esquema muestra la interacción entre el entorno real y virtual. Para poder experimentar la AR son indispensables tres elementos. En primer lugar, una cámara que capture la información del mundo real para transmitirla al software de realidad aumentada. Segundo, el software para procesar dicha información y para gestionar datos externos que complementen a la realidad. Y por último un componente que plasme el contenido de ambos como por ejemplo una pantalla. Hay un cuarto componente que aunque no es indispensable es muy utilizado, el target o disparador. El target es un elemento físico que el software utiliza para reconocerlo y poder calcular una posición y dirección, es la puerta de entrada del mundo virtual al real. Puede ser un código QR, un marcador, una imagen o un objeto. 2.2. HISTORIA Se considera que la primera referencia que hubo a la realidad aumentada fue hace más de 100 años. En 1901, el autor de “Mago de Oz” L. Frank Baum escribió la novela “The Master Key” en la que se usaba por primera vez un dispositivo de realidad aumentada. La novela habla de un muchacho de 15 años que accidentalmente toca “The Master Key of Electricity” y encuentra a un demonio que le da varios regalos, entre ellos unas gafas que al ponérselas podría ver a la gente con una letra superpuesta en sus frentes, esa letra informaría al chicho si las personas eran buenas o malas. DecorAR PFC 2016 -17 14 DecorAR PFC 2016 -17 15 3. DESCRIPCIÓN FUNCIONAL En este apartado se describen las funcionalidades del sistema DecorAR. El sistema se divide en dos partes diferenciadas, la aplicación servidora (Web) y la aplicación móvil (App). 3.1. APLICACIÓN WEB La aplicación web permitirá a los usuarios registrados la gestión de sus modelos 3D y a los usuarios anónimos la visualización de los modelos que sean públicos. 3.1.1. INICIO Esta es la pantalla de inicio donde se da la bienvenida al usuario y donde podrá acceder a todas las funcionalidades que le ofrece el sistema DecorAR. En la barra de menú de la parte de arriba de la pantalla tendrá el acceso a las opciones disponibles para los dos tipos de usuario: usuario anónimo y usuario registrado. Este es el menú para el usuario anónimo. - DecorAR: vuelve a la pantalla de inicio - Buscador: Pantalla para la búsqueda de modelos. - Regístrate: Registrar un nuevo usuario en sistema. - Log in: Iniciar sesión de un usuario registrado.  Menú  Bienvenida  Últimos modelos DecorAR PFC 2016 -17 16 Este es el menú para un usuario registrado. Las funcionalidades extra a las que tiene acceso respecto al usuario anónimo son: - Mis modelos: Pantalla para la búsqueda de modelos de los que es propietario. - Nuevo modelo: Pantalla para crear un nuevo modelo. - Hello user!: Pantalla para edición del perfil de usuario. - Log off: Cerrar la sesión. Debajo del menú se muestra un mensaje de bienvenida donde cualquier usuario podrá descargar la App y el Target necesario para la experiencia de realidad aumentada. En la parte final de la pantalla se muestra un mosaico de los últimos modelos que se han modificado en el sistema DecorAR, de esta manera el usuario podrá, de un vistazo rápido, ver las últimas novedades que hay. Al clicar un modelo nos redirigirá a la pantalla de detalles del modelo. 3.1.2. NUEVO MODELO En esta pantalla un usuario registrado podrá añadir un nuevo modelo a su colección personal. Los datos a introducir son un subconjunto del total de datos que puede tener el modelo, sin embargo estos datos son los imprescindibles para crear la experiencia de realidad aumentada. El título es para poder identificar el modelo en el sistema DecorAR. Los parámetros ancho, profundo y alto determinarán sus medidas y su aspecto durante la experiencia de realidad aumentada. El fichero .OBJ debe contener la información que define el modelo (vértices, caras, coordenadas de textura). Los ficheros .OBJ usan un formato que está ampliamente usado en el mundo de la computación de gráficos 3D. DecorAR PFC 2016 -17 17 Por último añadir la textura del modelo y el nombre de la misma. El fichero textura puede ser JPEG y PNG, este último permite transparencias durante la experiencia de realidad virtual para simular cristal o algún otro tipo de material translúcido. El nombre de la textura identifica la misma. El usuario tiene la posibilidad de poder asociar a un mismo modelo diferentes texturas, por ejemplo un sofá podría tener diferentes texturas para los diferentes tipos de tejido y color. En el caso de que alguna propiedad no tenga el formato correcto o no se haya informado el usuario recibirá un mensaje de advertencia. Una vez estén todas las propiedades definidas al clicar el botón “Añadir nuevo modelo” el sistema procesará los datos introducidos, registrará el nuevo modelo en el sistema y se iniciará la pantalla de “renderizar modelo”. 3.1.3. RENDERIZAR MODELO Es esta pantalla cualquier usuario podrá visualizar en 3D un modelo. Con el ratón tendrá control total de la cámara. Podrá rotar la cámara para poder ver el modelo desde cualquier ángulo. Podrá modificar el nivel de zoom para alejar o acercar el modelo. Y podrá mover el modelo para enfocar alguna parte del modelo en concreto. Los botones tienen las siguientes funcionalidades: DecorAR PFC 2016 -17 18 Este botón redirige a la pantalla “Detalles del modelo”. Este botón solo estará disponible si el modelo tiene más de una textura. Al clicar el botón, la textura que se use para determinar el color del modelo será la siguiente disponible Los botones “Girar X”, “Girar Y”, “Girar Z” solo están disponible para los usuarios registrados que sean propietarios del modelo. La función es la de aplicar una rotación al modelo del 90º según el eje X, Y o Z. 3.1.4. DETALLES DEL MODELO En la pantalla de detalles del modelo se muestra toda la información relativa a un modelo. A continuación se muestra una captura de la pantalla de detalles del modelo cuando el modelo no es de propiedad del usuario registrado, si fuera el propietario esta pantalla tendría las funcionalidades extra para modificación de los datos. En esta pantalla se encuentran todos los datos del modelo: el nombre o título, las medidas, descripción y propiedades. Las fechas de creación y modificación son calculadas. Y el número de versión representa la cantidad de cambios que ha sufrido el modelo. Se mostrará una imagen fija del modelo que representa la previsualización del mismo, esta imagen es muy útil para que otros usuarios puedan tener una idea de la forma del modelo en los buscadores del sistema DecorAR. Y a la derecha las texturas disponibles que tiene el modelo. El botón redirige a la pantalla “Renderizar modelo”. DecorAR PFC 2016 -17 19 Si el modelo pertenece al usuario registrado, la pantalla “Detalles del modelo” tendrá las funcionalidades de editar el modelo. En los recuadros rojos de la imagen anterior vemos las funcionalidades de edición extra que sólo estarán disponibles para el propietario del modelo. Este botón redirige a la pantalla “Editar datos del modelo” donde el usuario puede actualizar los datos del modelo. Elimina el modelo del sistema. Actualiza la imagen de previsualización del modelo. Este botón redirige a la pantalla “Gestión de Texturas” donde se podrán modificar las texturas del modelo. 3.1.5. EDITAR DATOS DEL MODELO En esta pantalla se podrán actualizar los datos del modelo: Título, medidas, descripción. En esta pantalla hay que destacar el CheckBox que permite publicar el modelo o dejarlo oculto. Si el modelo no está público, solo puede ser visualizado por el propietario. Esta opción se usará para que el propietario pueda realizar todas las modificaciones que crea conveniente antes de publicar su modelo al resto de usuarios. Antes de publicar el DecorAR PFC 2016 -17 20 modelo el propietario puede dejarlo en modo privado y así poder ver el modelo en Realidad Aumentada y comprobar cómo queda y si fuera necesario modificar los datos, medidas o texturas del modelo. 3.1.6. GESTIÓN DE TEXTURAS En esta pantalla se gestionan las texturas de un modelo en concreto. Hay dos apartados principales, añadir nueva textura y gestión de las texturas existentes. Para añadir una nueva textura solo hay que seleccionar un fichero de imagen del explorador de archivos y darle un nombre a la textura. En el listado de texturas, el usuario podrá ver las texturas que tiene el modelo. Puede eliminarlas, o seleccionar cual quiere que sea la textura principal. La textura principal es la primera textura que se aplicará al modelo cuando se visualice en 3D ya sea en la web como en la realidad aumentada. 3.1.7. BUSCADOR DE MODELOS En esta pantalla se listarán todos los modelos del sistema DecorAR en una tabla. A las columnas de las tablas se podrá aplicar filtros para restringir la búsqueda de modelos que cumplan unas características. Se podrá filtrar por el usuario del cual es propietario el modelo, el nombre o título del modelo, la fecha de actualización, las medidas o por la descripción. DecorAR PFC 2016 -17 21 Cada fila de la tabla representa un modelo del sistema y se mostrará la imagen de previsualización del modelo en caso de que la tenga. En la fila también habrá un botón “Ver” que redirigirá al usuario a la pantalla “Detalles del modelo”. Los modelos pueden ser filtrados aplicando filtros a las columnas con el botón de embudo. En este ejemplo se ha filtrado la columna Nombre de manera que en la tabla solo aparezcan los modelos en los que en su título contenga la palabra “mesa”. 3.1.8. REGISTRO DE USUARIOS En esta pantalla se mostrará un formulario para la creación de un nuevo miembro del sistema DecorAR. El username y password que se introduzcan serán las credenciales para iniciar sesión tanto en la aplicación web como en al app móvil. Si algún parámetro es incorrecto o el usuario ya está registrado se mostrará un error indicando los motivos. Filtrado por columnas Paginación de resultados Ver Detalles DecorAR PFC 2016 -17 22 3.2. APLICACIÓN MOVIL La aplicación móvil será la encargada de proporcionar al usuario una experiencia de realidad aumentada con los modelos del sistema DecorAR. A continuación se explican todas las funcionalidades de la App. 3.2.1. INICIO Splash screen Cuando se inicia la aplicación nos aparecerá la pantalla “splash screen”. Las splash screen son un recurso muy sencillo que consiste en mostrar un fondo simple con el color de la aplicación junto con el logotipo de nuestra App. Es útil porque según el hardware de los distintos dis positivos que hay en el mercado la App DecorAR puede tardar más o menos en cargar, por eso esta pantalla es el punto intermedio perfecto entre el escritorio y la aplicación. Inicio de sesión Esta es la pantalla que se ejecutará después de la “splash screen” si no hay ningún usuario registrado en el sistema todavía. Si hubiera alguien registrado iría directamente al menú de la aplicación. El usuario que quiera iniciar sesión deberá introducir las credenciales que definió al crear su cuenta en la aplicación web de DecorAR. Si un usuario no tiene cuenta todavía, en la parte inferior se muestra un mensaje indicando que para registrarse debe ir a una página de la aplicación web. Hay un link que le redirigirá a dicha página web. Cuando se clique en el botón “Iniciar sesión” se comprobaran las credenciales y si hay algún error se le informará con los mensajes: “La contraseña es incorrecta” y “El usuario <XXX> no existe”. La aplicación también tendrá un acceso para los usuarios que no tengan cuenta registrada con el botón “Entrar como invitado”. Esta modalidad tendrá lógicamente alguna función menos. DecorAR PFC 2016 -17 23 Menú Esta es la pantalla principal de la aplicación donde el usuario puede escoger entre las diferentes funcionalidades del sistema. En la parte superior derecha se indica el usuario que tiene la sesión abierta. En caso de que el usuario hubiera entrado como invitado aquí aparecería el texto invitado y la primero opción del menú no sería “LogOff”, sería “Log In”. Esta pantalla será la última a la que llegue el usuario en caso de que durante el uso de la App DecoAR se pulse repetidas veces el botón de atrás del sistema Android. Para salir de la aplicación deberá estar en esta pantalla y apretar el botón de atrás 2 veces consecutivas. DecorAR PFC 2016 -17 30 3.2.8. CAPTURA DE URL Uno de los objetivos de este proyecto es usar la realidad aumentada de una manera fácil y natural para que cualquier persona con un teléfono móvil pueda disfrutar de sus ventajas. Imagina que cuando estés visitando un catálogo de muebles y veas un producto que te gusta puedas ser capaz de verlo en tu casa con un par de clics. Cuando un usuario registrado cree un modelo en el sistema DecorAR tiene la posibilidad de poner en su web un enlace a la web de DecorAR. Si este enlace o URL se selecciona desde un dispositivo móvil con la aplicación DecorAR instalada, la app la captura y le preguntará al usuario si desea abrirla con realidad aumentada. En la imagen vemos un ejemplo de una web de muebles “muebles Morato” que tiene incrustado un botón de DecorAR. El responsable de la web ha tenido que c rear un usuario en DecorAR, añadir el modelo de la silla a su colección y configurarlo como público y finalmente copiar el enlace DecorAR y asignárselo a un botón en su propia web. Si se clica el botón desde el navegador web del móvil, se nos abrirá un diálogo preguntándonos si deseamos abrir el modelo en la App de DecorAR. Al hacerlo la App descarga el modelo y nos abrirá la pantalla de “Detalles del modelo”. Una vez en esa pantalla solo tendremos que pulsar el botón de “Iniciar AR” para ver el modelo en realidad aumentada. Con solo 3 clics hemos pasado de ver un producto en una web de terceros a verlo como quedaría en nuestra casa con AR. DecorAR PFC 2016 -17 31 3.2.8.1) DIAGRAMA DE FLUJO DE CAPTURA DE URL A continuación se muestra un diagrama de flujo de la interacción del usuario. DecorAR PFC 2016 -17 32 DecorAR PFC 2016 -17 33 4. DISEÑO TÉCNICO En este apartado se explicarán las decisiones técnicas que se han tomado para desarrollar el sistema DecorAR, la arquitectura del sistema, metodologías de programación y patrones de diseño. 4.1. ARQUITECTURA DEL SISTEMA En este apartado se describen los diferentes componentes y tecnologías que se han usado para la implementación del sistema DecorAR. El sistema se compone de dos subsistemas, la aplicación móvil y la aplicación servidor. Estos dos sistemas son autónomos, podrían usarse de manera independiente uno del otro pero lo interesante es cuando interactúan entre ellos y hay traspaso de información entre ambos. Como se puede observar en el esquema, la interacción de los usuarios con el sistema DecorAR es a través de la interfaz de usuario (UI siglas en inglés de “User Interface”) de la aplicación Android o a través de la UI de aplicación Web. La transmisión de información entre sistemas se lleva a cabo mediante los WebServices que están publicados en la parte del servidor. La dirección de la trasmisión de la información será en un único sentido, será la App la que haga peticiones al servidor y éste enviará los datos solicitados. Los Servicios Web nos sirven perfectamente para integrar aplicaciones creadas en lenguajes y plataformas diferentes mediante internet o intranet. En nuestro caso tenemos un sistema desarrollado para Android con lenguaje Java y lo integramos con un sistema Windows desarrollado en framework .NET. DecorAR PFC 2016 -17 34 4.1.1. APLICACIÓN SERVIDOR La aplicación servidor está desarrollada con tecnologías Microsoft, con el framework .NET 4.5. El lenguaje de programación usado es C# (C Sharp). El sistema sigue una arquitectura en NCapas, este tipo de arquitectura es un patrón de diseño que se explica con detalle en el capítulo 4.3. En la capa de presentación se usa el patrón MVC (Modelo – Vista – Controlador). Los controladores son los encargados de comunicarse con la capa de Aplicación donde está ubicada la lógica de negocio. Las vistas o pantallas que verá el usuario usan una combinación de HTML, CSS para renderizar el contenido y Javascript para la gestión de los eventos. Para el visualizador de modelos 3D se usa Three.js, que es un framework que ayuda a los desarrolladores a usar WebGL, la tecnología que usan los navegadores para el renderizado de contenido 3D. La lógica de negocio está compuesta por las capas de aplicación y dominio. Esta parte es el corazón del sistema, aquí están las reglas y procesos que definen DecorAR. Para el desarrollo solo se usará el framework .NET y el lenguaje de programación C#. La capa de Infraestructura se encarga del control de la persistencia de datos, se asegura también de la integridad de los datos. Se usa Entity Framework para la gestión y el acceso a los datos guardados en base de datos. Entity se explica con detalle en el capítulo 5.7. La base de datos “Server_DB” se implementará con SQL Server. SQL Server es un sistema de manejo de bases de datos de modelos relacionales, desarrollado por Microsoft. Finalmente, los Servicios Web se implementan con ASP.NET. Estos servicios permitirán a componentes externos acceder a las funcionalidades del sistema mediante los protocolos Web estándar, como HTTP GET y SOAP (Simple Access Protocol) que se basa en la utilización del protocolo HTTP para el transporte de mensajes y el lenguaje XML para la escritura del cuerpo de los mensajes. DecorAR PFC 2016 -17 35 4.1.2. APLICACIÓN MÓVIL La aplicación móvil esta desarrollada para el sistema operativo Android y el lenguaje usado es Java. La capa de presentación se encarga de la gestión de las distintas pantallas de la aplicación. El diseño visual de las pantallas está definido en ficheros XML, aunque su apariencia en algunos casos se determinará de manera dinámica en tiempo de ejecución. Para la experiencia de Realidad Aumentada se utiliza la combinación del SDK de Vuforia que interpreta la realidad capturada por la cámara y OpenGL que se encarga de renderizar los elementos virtuales 3D. El SDK de Vuforia se explicará con detalle en el capítulo 5.3. La lógica de negocio se encarga de los aspectos de gestión de los datos del sistema y aplicación de las reglas de negocio. En este módulo se gestionan las comunicaciones con los WebServices del servidor mediante llamadas SOAP, se encarga de la construcción de las peticiones y la posterior recepción, deserialización y procesamiento de las respuestas. La capa de Infraestructura será la encargada de persistir la información a disco. Las entidades complejas que ocupan mucho espacio como los modelos y las texturas de los modelos se guardarán en base de datos. No todo se guarda en base de datos, Android provee a los desarrolladores mecanismos para la persistencia de información en ficheros XML tipo diccionarios con pares “clave-valor” donde se guardaran información relacionada con el usuario registrado. Los datos que se necesiten persistir se guardarán en la base de datos “App_DB”. Esta base de datos está ubicada en el dispositivo móvil. Está diseñada y desarrollado con la tecnología SQLite. DecorAR PFC 2016 -17 36 4.2. INFRAESTRUCTURA La infraestructura es la parte del sistema que se encarga de persistir los datos en disco, normalmente mediante bases de datos. En este apartado vamos a explicar en detalle el diseño los sistemas de almacenamiento de datos que usará DecorAR para guardar la información del sistema. 4.2.1. APLICACIÓN SERVIDOR A continuación se muestra el diagrama del modelo de base de datos del servidor con sus tablas y sus relaciones. En la tabla “User” se almacenan los usuarios registrados del sistema. Estos serán los propietarios de sus modelos y responsables de los mismos. Columna Tipo de dato Descripción Id NVARCHAR (128) (PRIMARY KEY) Identificador interno de la base de datos. Email NVARCHAR (256) Email EmailConfirmed BIT Indica si el mail ha sido confirmado. PasswordHash NVARCHAR (MAX) Contraseña encriptada. SecurityStamp NVARCHAR (MAX) Marca de seguridad para la desencriptación de la constraseña. UserName NVARCHAR (256) Nombre de usuario visible al público. En la tabla “Session” se almacenan las sesiones vinculadas con la aplicación móvil. Se necesita una sesión válida asociada a un usuario para poder consultar información privada desde el móvil. En el WebUI no son necesarias las sesiones porque la gestión de usuarios registrados se hace mediante cookies en el navegador. DecorAR PFC 2016 -17 37 Columna Tipo de dato Descripción Id INT (PRIMARY KEY) Identificador interno de la base de datos. SessionToken UNIQUEIDENTIFIER Identificador único global que identifica una sesión fuera de la base de datos. ExpiredDate DATETIME Fecha de expiración de la sesión. UserName NVARCHAR (256) Nombre de usuario de la sesión. UserId NVARCHAR (128) Identificador de usuario de la sesión. Es “Foreign Key” a la tabla “AspNetUsers” En la tabla “Model” se almacenan los datos de los modelos del sistema. Columna Tipo de dato Descripción Id INT (PRIMARY KEY) Identificador interno de la base de datos. ModelGuid UNIQUEIDENTIFIER Identificador único global visible en la url de los modelos. Title NVARCHAR (MAX) Título del modelo. Description NVARCHAR (MAX) Descripción del modelo. Indices NVARCHAR (MAX) Array de indices Vertices NVARCHAR (MAX) Array de vértices. Normals NVARCHAR (MAX) Array de normales TexCoords NVARCHAR (MAX) Array de coordenadas de textura PreviewImage NVARCHAR (MAX) Imagen de previsualización almacenada en string base64 SizeX INT Tamaño del modelo en ancho SizeY INT Tamaño del modelo en profundidad SizeZ INT Tamaño del modelo en altura Public BIT Indica si el modelo es público y visible a otros usuarios. UserId NVARCHAR (128) Indica el propietario del modelo. Es “Foreign Key” a la tabla “AspNetUsers”. CreatedDate DATETIME Fecha de creación del modelo. LastUpdateDate DATETIME Fecha de actualización del modelo. Version INT Numero de versión del modelo. En la tabla “Texture” están las texturas de los modelos. Cada modelo tendrá entre 1 y N texturas asociadas. Las texturas representan el material o los colores con el que están hechos los modelos. Por ejemplo, una silla puede estar fabricada en madera y en metal, en este caso, el modelo silla tendrá dos texturas, una por cada material. Columna Tipo de dato Descripción Id INT (PRIMARY KEY) Identificador interno de la base de datos. Content VARBINARY(MAX) Contenido de la textura en array de bytes. ModelId INT Descripción del modelo. Main BIT Indica si la textura es la principal. Name NVARCHAR (MAX) Nombre de la textura. DecorAR PFC 2016 -17 38 4.2.2. APLICACIÓN MÓVIL La persistencia de datos en la aplicación móvil se divide en dos partes, la base de datos SQLite y el fichero de preferencias de la App. SQLite es un ligero motor de bases de datos de código abierto, que se caracteriza por mantener el almacenamiento de información de forma persistente. A diferencia de otros gestores de bases de datos como MySQL, SQL Server y Oracle DB, SQLite no requiere el soporte de un servidor. SQLite no necesita de un proceso para administrar la información, se usan unas librerías para la gestión de la base de datos. Usa un archivo para el esquema de la base de datos, este fichero solo puede ser accedido por la aplicación que lo haya creado. Y no necesita configuración, libera al programador el tener que configurar puertos, ubicación, tamaños de propiedades, etc. En la base de datos SQLite de la aplicación móvil solo se guardarán los modelos y las texturas. En la tabla “Model” se guardan los modelos que se han descargado desde el servidor. La función de esta tabla es que el usuario tenga la posibilidad visualizar modelos sin la necesidad de tener conexión a internet. Columna Tipo de dato Descripción ID INT (PRIMARY KEY) Identificador interno de la base de datos. ModelGuid TEXT Identificador único global visible en la url de los modelos. Title TEXT Título del modelo. Description TEXT Descripción del modelo. Indices TEXT Array de indices Vertices TEXT Array de vértices. Normals TEXT Array de normales TexCoords TEXT Array de coordenadas de textura PreviewImage BLOB Imagen de previsualización almacenada en string base64 SizeX INTEGER Tamaño del modelo en ancho. SizeY INTEGER Tamaño del modelo en profundidad SizeZ INTEGER Tamaño del modelo en altura Public INTEGER Indica si el modelo es público y visible a otros usuarios. UserId INTEGER Indica el propietario del modelo. Es “Foreign Key” a la tabla “AspNetUsers”. CreatedDate INTEGER Fecha de creación del modelo. LastUpdateDate INTEGER Fecha de actualización del modelo. Version INTEGER Numero de versión del modelo. SQLite tiene la particularidad de que no dispone de tantos tipos de datos. Por ejemplo el tipo “DateTime” de SQLServer no está en SQLite. Lo que se ha hecho para poder persistir este tipo de datos es convertir el DateTime en milisegundos y lo guardamos como integer. La propiedad “Public” tiene el tipo “BIT” en SQLServer, pero en SQLite no está disponible, pero lo guardamos como integer. Si el integer es 0 el valor es “false”, y “true” en cualquier otro caso. DecorAR PFC 2016 -17 39 La tabla “Texture” guarda las texturas asociadas al modelo. Columna Tipo de dato Descripción ID INT (PRIMARY KEY) Identificador interno de la base de datos. ModelGUID TEXT Identificador único global que identifica la el modelo al que pertenece la textura. Es “Foreign Key” a la tabla “model” de su columna “ModelGUID”. Main INTEGER Indica si la textura es la principal Name TEXT Nombre de la textura. Content BLOB Contenido de la imagen que representa la textura. El resto de información que la App necesita persistir se guardará en los ficheros de preferencias de Android. Android ofrece la posibilidad de guardar una colección de pares clave-valor en los denominados “SharedPreferences”. El término “shared” implica que ese fichero puede ser compartido entre aplicaciones del mismo terminal pero en el caso de DecorAR se configurará para que el acceso a ese fichero sea privado y solo la App de DecorAR tenga permisos de lectura y escritura. En el fichero de “SharedPreferences” de DecorAR se guardará la siguiente información: Clave Valor Descripción Username STRING Indica el nombre de usuario que se haya registrado por última vez SessionToken STRING Identifica la sesión actual. Este valor ha sido enviado por el servidor. ExpirationDate INTEGER Indica la fecha de expiración de la sesión actual TargetX INTEGER El tamaño del target en el eje de la X TargetY INTEGER El tamaño del target en el eje de la Y DecorAR PFC 2016 -17 46 interface IDatabase { void GuardarDB(); } interface IDiscount { void AplicarDescuento(); } class Cliente : IDatabase, IDiscount { public string Nombre; public double Importe; public virtual void AplicarDescuento() { //No tiene descuento por defecto } public void GuardarDB() { //Guardar Nombre + Importe en BD } } class ClienteVIP : Cliente { public override void AplicarDescuento() { Importe = Importe * 0.5; } } class ClienteInvitado : IDiscount { public double Importe; public void AplicarDescuento() { Importe = Importe * 0.5; } } Con la modificación, la clase “Cliente” implementa las responsabilidades de guardar en base de datos “IDatabase” y la de calcular el descuento “IDiscount”. Ahora la clase “ClienteVIP” hereda de “Cliente” pero la clase “ClienteInvitado” solo implementa la responsabilidad de calcular el descuento “IDiscount”. Ahora no hay confusión, podemos crear una lista de instancias de tipo “Cliente” y de sus subclases para guardarla en base de datos. En caso de que hagamos el error de añadir la clase “Invitado” a la lista, el compilador se queja como se muestra en el anterior fragmento de código. 4.4.4. INTERFACE SEGREGATION PRINCIPLE “Depender de las abstracciones no de las concreciones.” Este principio está pensado para mantener a un sistema desacoplado respecto a los sistemas de los que depende, y así resulte más fácil refactorizarlo, modificarlo y redesplegarlo. DecorAR PFC 2016 -17 47 Ya hemos visto en los anteriores principios de SOLID como las interfaces nos facilitan el diseño y desarrollo del sistema software. Es importante hacer abstracciones pequeñas que no estén sobrecargadas. Los clientes no deben verse obligados a implementar interfaces que no utilizan. En lugar de una interfaz sobrecargada se prefieren muchas interfaces pequeñas basadas en grupos de métodos, cada uno de los cuales sirve un submódulo. 4.4.5. DEPENDENCY INVERSION PRINCIPLE “Un módulo de alto nivel no debe depender de módulo de bajo nivel. Ambos deben depender de abstracciones. Las abstracciones no deben depender de detalles. Los detalles deben depender de las abstracciones.” La arquitectura de las aplicaciones convencionales tiene un enfoque de diseño de arriba hacia abajo, donde un problema de alto nivel se divide en partes más pequeñas. En otras palabras, el diseño de alto nivel se describe en términos de estas partes más pequeñas. Como resultado, los módulos de alto nivel que se escribe directamente dependen de los módulos más pequeños (de bajo nivel). En la siguiente imagen tenemos un diseño típico, la capa de dominio tiene una dependencia directa con la capa de infraestructura. Para aplicar este último principio SOLID invertimos la dependencia. Ahora la capa de dominio no tiene ninguna dependencia con ninguna otra capa, solo tiene dependencia con la abstracción “IUserRepository” que se encuentra dentro de la propia capa. Ahora es la capa de infraestructura la que tiene una dependencia con la capa de dominio, las dependencias se han invertido. DecorAR PFC 2016 -17 48 4.5. PATRÓN IOC (INVERSION OF CONTROL) En los métodos de programación tradicionales las clases son las encargadas de instanciar otras clases para que realicen parte de la lógica de la aplicación, el patrón IoC invierte esta lógica. Este patrón está muy relacionado con el último principio de SOLID “Dependency Inversión principle”. 4.5.1. INYECCIÓN DE DEPENDENCIAS Es un patrón de diseño en la programación orientada a objetos, en el que se suministran objetos (Inyección) a una clase en lugar de ser la propia clase la que cree el objeto. Este término apareció por primera vez en el artículo “Inversion of Control Containers and the Dependency Injection pattern” por Martin Fowler en 2004[7]. Las dependencias no se instancian de forma explícita, simplemente se inyectan en los componentes que los van a usar. Sigue el principio de Hollywood "No nos llames, nosotros te llamaremos". Permite desarrollar código desacoplado. Permite pasar las referencias necesarias a una clase sin necesidad de la clase sea la encargada de crear las instancias que resuelvan esas dependencias. En la figura de arriba, vemos como la clase “SessionService” tiene una dependencia con la interfaz “ISessionRepository”. Según el patrón de Inyección de dependencias, la clase no tiene la responsabilidad de resolver su dependencia. Es el cliente quien detecta la dependencia, instancia la clase “SessionRepository” la cual implementa la dependencia y se la inyecta a la clase dependiente. La figura de cliente está ubicada en las capas superiores de la arquitectura de sistema, en DecorAR el cliente estará en el WebUI y los WebServices. Más adelante en el apartado de Autofac veremos cómo implementamos el concepto de Cliente. Existen distintos métodos para inyectar las dependencias: - Inyección por constructor. - Inyección por propiedad. - Inyección por parámetro. En el sistema DecorAR se ha usado la inyección por constructor pero antes vamos a ver cómo funcionan los otras dos alternativas. SessionService SessionRepository «interface» ISessionRepository Dependencia Crea Inyecta Cliente DecorAR PFC 2016 -17 49 3.2.8.2) INYECCIÓN POR PARÁMETRO Con este tipo cada dependencia será un parámetro en la firma del método. public class Cliente { public void Ejecutar() { var sessionService = new SessionService(); sessionService.NewSession("user", "pass", new SessionRepository()); } } public class SessionService { public string NewSession(string username, string password, ISessionRepository repository) { return repository.NewSession(username, password); } } En el ejemplo de arriba el “Cliente” utiliza el servicio/clase “SessionService” que tiene un método “NewSession” con una dependencia en el tercer parámetro de la firma del método, “ISessionRepository”. Es el cliente el encargado de inyectar la dependencia resuelta “SessionRepository” como parámetro cuando se llama al método “NewSession”. Esta alternativa no es muy recomendable ya que modifica la firma del método e incrementa el número de parámetros del método. Además hace menos explícitas las dependencias de una clase (con la inyección en constructor son totalmente explícitas), hacen más difícil el seguimiento de principios de diseño como SRP (Single Resposability) y se puede tender a crear componentes demasiado complejos, con código duplicado, extensos, y con múltiples responsabilidades. 3.2.8.3) INYECCIÓN POR PROPIEDAD En este caso la dependencia es una propiedad de la clase, la clase que la esté usando tendrá que asignarle el valor a esta propiedad/dependencia. public class Cliente { public void Ejecutar() { var sessionService = new SessionService(); sessionService.SessionRepository = new SessionRepository(); sessionService.NewSession("user", "pass"); } } public class SessionService { public ISessionRepository SessionRepository { get; set; } public string NewSession(string username, string password) { return SessionRepository.NewSession(username, password); } } DecorAR PFC 2016 -17 50 Esta opción es muy flexible, la dependencia puede cambiar en cualquier momento del flujo del proceso. La contra es que los objetos pueden encontrarse en un estado inválido desde la construcción hasta la asignación de la dependencia. Al igual que la anterior, es difícil saber rastrear las dependencias que tiene una clase. 3.2.8.4) INYECCIÓN POR CONSTRUCTOR En este caso es el constructor de la clase es el que tiene como parámetros las dependencias de la misma. public class Cliente { public void Ejecutar() { var sessionService = new SessionService(new SessionRepository()); sessionService.NewSession("user", "pass"); } } public class SessionService { ISessionRepository _sessionRepository; public SessionService(ISessionRepository sessionRepository) { _sessionRepository = sessionRepository; } public string NewSession(string username, string password) { return _sessionRepository.NewSession(username, password); } } En esta opción las clases se auto documentan ya que es el constructor el que define qué otros componentes necesita para hacer su trabajo. Una vez creadas las clases estas se encuentran en un estado válido. La inyección por constructor es la que se ha usado en la implementación de la solución DecorAR. La conclusión es que la inyección de dependencias es un patrón de diseño orientado a objetos que nos permite desarrollar código desacoplado. Usando este patrón trae como beneficios: testeabilidad, extensibilidad, mantenimiento, desarrollo en paralelo y el acople tardío de las piezas de software. 4.5.2. SERVICE LOCATOR Y AUTOFAC Hasta ahora hemos visto como diseñar un sistema desacoplado inyectando dependencias entre capas y servicios. Estas dependencias son abstracciones que deben ser resueltas, aquí entra en acción el patrón service locator. DecorAR PFC 2016 -17 51 Es patrón service locator expone que una clase (ServiceLocator) será la encargada de traducir las abstracciones de la aplicación a sus instancias. Las clases que necesiten usar una abstracción tendrán que solicitárselo a ServiceLocator. En la imagen anterior vemos como la clase “Cliente” tiene dependencias con las abstracciones IServiceA e IServiceB. Si tuviera que resolver las dependencias tendría que tener el código de creación de las instancias de los servicios que implementan estas abstracciones. Este código estaría repetido por todas las clases con dependencias. En la imagen anterior hemos incorporado la clase “ServiceLocator”. Ella se encarga de localizar las clases que implementan las abstracciones solicitadas. Podemos decir que es un contenedor de abstracciones, o como se conoce en el diseño software, un contenedor de IoC. Existen muchos contenedores de este estilo en el mercado (Ninject, SimpleInjector, Castle.Windsor, etc) pero en DecorAR se ha utilizado Autofac ya que es una tecnología con que estoy familiarizado ya que he trabajado con ella anteriormente. Autofac es un contenedor de IoC para .NET que se encarga de administrar las dependencias entre clases de forma que la aplicación sea fácilmente actualizable y por tanto, escalable en tamaño y complejidad. Usa «interface» IServicioA «interface» IServicioB Cliente Usa ServicioA ServicioA Usa «interface» IServicioA «interface» IServicioB Cliente ServicioA ServicioA Service Locator Localiza Localiza DecorAR PFC 2016 -17 52 public class ServiceLocator { static ServiceLocator() { Container = CreateContainer(); } private static readonly IContainer Container; public static IContainer CreateContainer() { var containerBuilder = new Autofac.ContainerBuilder(); RegisterServices(containerBuilder); var result = containerBuilder.Build(); return result; } private static void RegisterServices(ContainerBuilder containerBuilder) { containerBuilder.RegisterType<DecorAR.Impl.ServiceLibrary.SessionService>() .As<DecorAR.Contracts.ServiceLibrary.ISessionService>(); //registro de las demás dependencias del proyecto } public static Type Resolve<Type>() { var result = Container.Resolve<Type>(); return result; } } En el código anterior vemos la clase singleton “ServiceLocator” que implementa el patrón ServiceLocator gracias al contenedor Autofac en el sistema DecorAR. En el recuadro azul, el método de “CreateContainer” es el encargado de construir el contenedor de IoC que posteriormente resolverá las dependencias que se han inyectado en la plataforma DecorAR. En el objeto “containerBuilder” de Autofac se registran qué clases implementan las abstracciones/dependencias de la solución, esta acción se hace en el método “RegisterServices”. En el método “RegisterServices” solo se ha resuelto una abstracción a modo de ejemplo, se puede observar que la clase “SessionService” implementa la abstracción “ISessionService”. En el recuadro verde, está el método “Resolve” que usarán los clientes para resolver las dependencias de las primeras capas. De manera recursiva las dependencias que hayan sido inyectadas en las capas inferiores se resolverán mediante Autofac. DecorAR PFC 2016 -17 53 Pongamos como ejemplo el WebService “DecorARWebService” en la capa de Servicios distribuidos del sistema Decor. namespace DecorAR.WebService { [WebService(Namespace = "http://tempuri2.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.ComponentModel.ToolboxItem(false)] public class DecorARWebService : System.Web.Services.WebService { [WebMethod] public string NewSession (string username, string password) { ISessionService sessionService = ServiceLocator.Resolve<ISessionService>(); SessionResponseDTO session = sessionService.NewSession(username, password); return JSONserializer.SerializeJSON(session); } } } En el código anterior tenemos la clase “DecorARWebService”. Es la implementación del WebService de la capa más externa, la de Servicios distribuidos, con la que interactúa el cliente y donde se deben resolver todas las dependencias. En la primera línea del método “NewSession” se pide al “ServiceLocator” que resuelva la abstracción “ISessionService”. Esta abstracción es una dependencia del método, en la segunda línea llamamos al método “NewSession” de la instancia que esta implementado la lógica de la abstracción y en este caso de nuestro negocio. Que el ServiceLocator sea capaz de proporcionar la clase que implementa una abstracción parece sencillo, ya que como hemos visto antes se ha registrado en un diccionario donde se explicitaba que clase iba con cada abstracción. Pero en aplicaciones normales la correlación de dependencias es mucho más complicada, veámoslo con un ejemplo. En el diagrama de clases de arriba, la clase “SessionService” de capa de aplicación tiene a su vez dependencias con las demás capas del sistema. SessionService usa/depende de la abstracción “IUserDomainService”. La clase que implementa esta abstracción depende de “ILibraryConfig” y de “IUserRepository”. La clase “UserRepository” a su vez depende de “IInfrastructureConfig”. DecorAR PFC 2016 -17 54 Como hemos visto en el capítulo de dependencias, se ha decidido que todas estas dependencias sean inyectadas a través de los constructores de la clase. Y es gracias a este tipo de inyección donde “Autofac” nos facilita muchísimo el trabajo detectado a través de los constructores que dependencias tiene que ir resolviendo. De esta manera solo es necesario registrar y resolver las dependencias del sistema en las capas superiores, en el caso de DecorAR en los WebServices (Capa de servicios distribuidos) y en los WebUI (Capa de presentación). En el caso de que alguna abstracción no estuviera registrada, al intentar resolver alguna clase que la tuviera como dependencia en el constructor, Autofac nos indicaría un mensaje de error del tipo: “No se puede invocar <UserRepository> porque en su constructor tiene el parámetro <IInfrastructureConfig> y no lo puedo resolver”. En la captura del código que se muestra a continuación se ha creado un escenario para que se produzca justamente este error. La inyección de dependencias y el uso de Autofac son realmente útiles para crear sistemas software fáciles de escalar y mantener. No se puede resolver la dependencia: “DecorAR.Infrastructure.Config.IInfrastructureConfig” Porque no se ha registrado en el contenedor de dependencias de Autofac DecorAR PFC 2016 -17 55 5. IMPLEMENTACIÓN En este apartado se explicarán cómo se han implementado las partes más importantes del sistema. 5.1. ENTORNOS DE DESARROLLO Un IDE (Integrated Development Environment) es un entorno de desarrollo que ayuda a los desarrolladores a programar nuevos componentes software. Los IDEs disponen de todas las herramientas necesarias como editores de código, compiladores e intérpretes, depuradores de código. En este proyecto se usan dos IDE uno para la App y otra para el servidor. Para el desarrollo de la parte del servidor se usará Microsoft Visual Studio. Este IDE soporta múltiples lenguajes de programación y sirve para crear aplicaciones que corran en servidores Windows como Servicios Web o Aplicaciones Web, justo lo que se necesita para este proyecto. Como es un IDE que utilizo diariamente en el trabajo no ha sido necesaria una investigación previa. Para el desarrollo de la App se usará Android Studio el IDE oficial de Google para la creación de aplicaciones Android. Anteriormente a este proyecto los desarrollos que había hecho para Android los había hecho con el IDE Eclipse, pero desde 2015 Android Studio lo substituyó. La manera de trabajar en los dos entornos es muy similar, y ha sido muy rápido adaptarse al nuevo sistema. 5.2. REPOSITORIOS DE CÓDIGO Los repositorios de código o control de versiones de código son sistemas para guardar ficheros y registrar los cambios realizados a lo largo del tiempo de un desarrollo. Es muy útil cuando varias personas están trabajando sobre el mismo proyecto y tienen que modificar los mismos ficheros. Aunque en este proyecto solo ha trabajado una persona es muy interesante implantar este sistema ya que a parte del control de las versiones de los ficheros de código fuente también servirá como backup de seguridad. Algunos de los más conocidos son Subversion, Fossil, Mercurial, etc. El repositorio de código con el que he trabajado más es TFS “Team Foundation Server” que está especialmente diseñado para integrarse con Visual Studio con el que trabajo asiduamente. Aunque también se puede integrar con Android Studio se ha decido no usarlo ya que es de pago y requiere un sistema SQL server para el guardado de los datos. Se ha decidido usar el control de versión de software libre Git y GitHub como sistema de hosting en la nube, además se integra perfectamente en los dos IDEs que se van a utilizar. Para usarlo es muy sencillo, hay que crear un repositorio online en GitHub.com y vincularlo con la carpeta local donde está el código del proyecto. A través de la herramienta de DecorAR PFC 2016 -17 62 Como podemos observar, en el cuadro de texto de la imagen está la matriz ModelView. La matriz 3x3 de la derecha es la matriz de rotación y el vector de la izquierda es la traslación. Sin tener en cuenta la translación, efectivamente la matriz de rotación que nos proporcionar Vuforia corresponde a la rotación de 180º que se esperaba teóricamente. Ejemplo 2: Cámara y target paralelos, pero en este caso el target está en horizontal y el móvil está vertical. En este ejemplo podemos considerar que es como el ejemplo 1 pero al cual se le ha aplicado al móvil previamente una rotación en el eje de la Z de 90 grados. Recordar que el vector Z sale del móvil en la dirección a la que apunta la cámara. Una rotación de -90 grados respecto al eje Z dejará el SCcam como el ejemplo 1. Si a esta se le añade la rotación de 180 grados en el eje X se obtiene el SCtar. 𝑅𝑂𝑇𝑍(𝜃)=(cos 𝜃 −𝑠𝑒𝑛 𝜃 0 𝑠𝑒𝑛 𝜃 cos 𝜃 0 0 0 1)→𝑅𝑂𝑇𝑧(−90)=(0 1 0 −1 0 0 0 0 1) 𝑅𝑂𝑇𝑥(𝜃)=(1 0 0 0cos 𝜃 𝑠𝑒𝑛 𝜃 0 𝑠𝑒𝑛 𝜃 cos𝜃)→ 𝑅𝑂𝑇𝑥(180)=(1 0 0 0 −1 0 0 0 −1) 𝑅𝑂𝑇𝑧(−90)∗𝑅𝑂𝑇𝑥(180)=(0 1 0 −1 0 0 0 0 1)∗(1 0 0 0 −1 0 0 0 −1)=(𝟎 −𝟏 𝟎 −𝟏 𝟎 𝟎 𝟎 𝟎 −𝟏) DecorAR PFC 2016 -17 63 Aquí tenemos una captura del móvil en la posición que hemos descrito en el escenario del ejemplo 2. Se puede observar que efectivamente la matriz que nos proporciona Vuforia corresponde con la teoría planteada de la combinación de las rotaciones básicas. 𝑅𝑂𝑇𝑧(−90)∗𝑅𝑂𝑇𝑥(180)=(0 −1 0 −1 0 0 0 0 −1) = El orden de multiplicación de las matrices de rotación es muy importante porque la multiplicación de matrices no tiene la propiedad conmutativa. Aunque curiosamente en este ejemplo 2 el resultado de hacer rotar -90 grados en Z y luego rotar 180 grados en X es el mismo que el de rotar primero 180 grados en X y luego los -90 grados en Z. Estos ejemplos nos sirven como referencia para entender el significado de la matriz GetPose() o lo que es lo mismo la matriz ModeloViewMatrix que nos proporciona Vuforia. Con esta matriz podemos identificar dónde se encuentra el target en el mundo real y poder renderizar un modelo 3D encima del target. DecorAR PFC 2016 -17 64 5.3.4. CÓDIGO FUENTE VUFORIA DecorAR PFC 2016 -17 65 En este apartado se esplican que clases y métodos son necesarios para crear una aplicación de AR con Vuforia. En la imagen de la página anterior se muestra el diagrama de clases mínimo para hacer funcionar el SDK de Vuforia y poder pintar un modelo 3D en OpenGL. Todo empieza con una Activity. Las Activities son los componentes que forman una aplicación Android. Cada Activity tiene asociada una pantalla donde los usuarios pueden ver información e interactuar para realizar acciones como pulsar un botón, tomar una foto, etc. En el diagrama tenemos “app.DecorAR_Activity” que sobrescribe algunos de los métodos de “android.Activity” que gestionan el ciclo de vida (onCreate, onStart, onPause…) de una aplicación. Estos métodos serán usados para iniciar y liberar los recursos de Vuforia. Las Activities de Android se encargan de gestionar los elementos visuales que ve el usuario en la pantalla, en este caso la pantalla se compone únicamente de un elemento “openGL.GLSurfaceView” que es un componente donde se pueden imprimir primitivas OpenGL como polígonos, texturas, etc. Al “openGL.GLSurfaceView” se le tiene que asignar un renderizador del tipo “openGL. GLSurfaceView.Renderer” que es el encargado de pintar las diferentes primitivas OpenGL en cada frame en el método “onDrawFrame()”. Con esto sería suficiente para pintar modelos 3D en nuestra app, lo único que se necesita es saber en qué posición pintarlos para crear una experiencia de AR. El SDK de Vuforia proporcionará la información necesaria para calcular esta posición. Para poder usar Vuforia tenemos que iniciar el motor AR con un código de licencia que nos proporciona la web de Vuforia. En nuestro diagrama la clase encargada de ello es “app.VuforiaSession” que será llamada desde nuestra Activity principal. Esta clase/sesión también se encarga de iniciar y liberar los recursos de Vuforia según el ciclo de vida de la Activity (onStart, onPause, onDestroy…). Una vez inicializado correctamente la sesión, la Activity inicializa los recursos que necesita Vuforia para la detección del target, el módulo Tracker. La inicialización y la gestión del Tracker lo hace la Activity con los métodos de la clase “app.VuforiaControl”. A partir de aquí ya tenemos el Vuforia funcionado, la cámara capturando imágenes y el Tracker procesándolas y detectando targets reconocibles. Toda esta información está en el “Estado” de Vuforia, recordemos que el “Estado” contiene la posición del target respecto a la cámara, el identificador del target reconocido y la imagen captura. Ahora falta utilizar ese “Estado” para renderizar el modelo 3D en el sitio correcto. Recordar que donde se renderiza el modelo en OpenGL es la clase GLSurfaceView a partir de un Renderer que en nuestro caso lo implementaba “app.DecorAR_Renderer”. Para obtener el “Estado” desde nuestro renderer se lo pedimos a la clase “app.VuforiaRenderer” con el método “Render()”. En este método lo que hace el coger el “Estado” y generar la matriz “ProjectionMatrix” de la cámara y pasárnosla otra vez a nuestro renderer a través del DecorAR PFC 2016 -17 66 método “renderFrame(State, ProjectionMatrix)” de la interfaz “app.VuforiaRenderControl”. Con esto ya tenemos todos los elementos para poder pintar los modelos 3D en la posición del target. Pero antes de pintar el modelo debemos pintar el frame que está capturando la cámara. Para ello usamos otra vez la clase “app.VuforiaRenderer”, el método “renderVideoBackground()” que se encarga de obtener el frame de la cámara, asociarlo a una textura y pintarlo sobre un quad que ocupe toda la GLSurfaceView. Y ahora sí, ya estaremos observado un modelo virtual sobreimpresionado encima de la realidad. En la imagen podemos observar la captura de una experiencia AR de nuestra App. A la derecha se encuentra un objeto real y a la izquierda el objeto virtual que intenta copiar su apariencia en colores y tamaño. 5.4. AR Y OPENGL En este apartado se va explicar el código implementado para el renderizado de objetos 3D con OpenGL a partir de la información que nos facilitar el SDK de Vuforia. Lo primero es ver qué datos tenemos para el renderizado: DecorAR PFC 2016 -17 67 - El modelo 3D que contiene la malla de vértices, esta malla es el esqueleto que da forma al modelo. - Las texturas son las que darán color a los vértices, podríamos decir que será la piel que recubrirá el esqueleto definido por la malla del objeto. - El tamaño que queremos que tenga el objeto cuando se esté visualizando durante la AR. - El tamaño del target, a partir de este tamaño deberemos calcular qué escalado se tiene que aplicar al modelo para que el aspecto coincida con las dimensiones del modelo. - La imagen que está capturando la cámara en cada frame cuando estamos renderizando el modelo virtual. Esta imagen será la realidad que mostraremos en la pantalla del móvil y sobre la cual se pintarán los objetos virtuales. - La posición del móvil respecto al target, ésta posición nos la facilitará Vuforia. Cuando el usuario haya seleccionado un modelo e inicie la pantalla de AR lo primero es calcular es el escalado que tendremos que aplicar al modelo. public void Calculate_mmByUd() { float mmByUdX = 4.0630f * target_X; float mmByUdY = 5.7790f * target_Y; mmByUd = (mmByUdX + mmByUdY) / 2; } Este método configura la variable “mmByUd” a partir del tamaño del target. Esta variable nos dice cuántos milímetros corresponden a una unidad del modelo. Si el modelo es un caja de 10x10x10 unidades y el valor de mmByUd es 3 y no se le aplica ningún escalado durante el render lo que vera el usuario será una caja virtual de 30x30x30 milímetros. Los números 4.0630 y 5.7790 se han obtenido mediante ingeniería inversa, probando diferentes tamaños de modelos virtuales con diferentes tamaños de targets. Estos números son la clave para poder ver los objetos con el tamaño que queramos. Ahora que sabemos que cuantos milímetros corresponde cada unidad del modelo vamos a calcular el escalado que tendremos que aplicar a OpenGL. private void UpdateScale() { MeshObject object = _singletonModelConfig.objectToRender; UserSize userSize = _singletonModelConfig.UserSize; float escalaX = GetScale(mmByUd, UserSize.X, object.Xunits()); float escalaY = GetScale(mmByUd, UserSize.Y, object.Yunits()); float escalaZ = GetScale(mmByUd, UserSize.Z, object.Zunits()); mRenderer.mEscala = new Escala(escalaX, escalaY, escalaZ); } A partir del objeto a renderizar “singletonModelConfig.objectToRender” calculamos cuántas unidades ocupa en X, Y y Z y que medidas reales queremos que tenga el modelo DecorAR PFC 2016 -17 68 “UserSize.(X,Y,Z)” calculamos la escala que tendremos que aplicar en el renderizador “mRenderer” donde se aplican las operaciones de OpenGL. private float GetScale(float mmByud, float real_mm, float uds) { if (uds == 0 || mmByud == 0) return 0; return real_mm / uds / mmByud; } Una vez tenemos la información necesaria para dar la forma correcta al modelo vamos cargar las texturas a OpenGL. for (Texture t : mTextures) { //Generamos el espacio en OpenGL para cargar una nueva textura GLES20.glGenTextures(1, t.mTextureID, 0); //Indicamos que la textura será 2D y la vinculamos con el //identificador que nos ha dado openGL en la linea anterior. GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, t.mTextureID[0]); //Cargamos en OpenGL los pixeles que representa la textura GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, t.mWidth, t.mHeight, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, t.mData); } Este código se ejecuta solo una vez en la inicialización del Renderer. Además de la carga de las texturas se inicializan otras variables básicas para el renderizado. //Función para la inicializacion del Renderer private void initRendering() { (...) //Carga de texturas //generar el Id de los shaders (vertex & fragment) shaderProgramID = Utils.createProgramFromShaderSrc( SingletonModelConfig.getInstance().vertexShader, SingletonModelConfig.getInstance().fragmentShader); //Estas son las referencias a los VBO usados por los shaders vertexHandle = GLES20.glGetAttribLocation(shaderProgramID, "vertexPosition"); textureCoordHandle = GLES20.glGetAttribLocation(shaderProgramID, "vertexTexCoord"); //Estos son los Uniforms usados por los shaders mvpMatrixHandle = GLES20.glGetUniformLocation(shaderProgramID, "modelViewProjectionMatrix"); texSampler2DHandle = GLES20.glGetUniformLocation(shaderProgramID, "texSampler2D"); } En la línea “SampleUtils.createProgramFromShaderSrc” creamos el identificador OpenGL que asociará los siguientes Shaders: DecorAR PFC 2016 -17 69 Vertex Shader Fragment Shader attribute vec4 vertexPosition; attribute vec2 vertexTexCoord; varying vec2 texCoord; uniform mat4 modelViewProjectionMatrix; void main() { gl_Position = modelViewProjectionMatrix * vertexPosition; texCoord = vertexTexCoord; } precision mediump float; varying vec2 texCoord; uniform sampler2D texSampler2D; void main() { gl_FragColor = texture2D(texSampler2D, texCoord); } En la inicialización también se crean los identificadores de las variables usadas en los shaders, los VBO (Vertex buffers) que se usarán para pasar la malla de vértices (vertexPosition) y la textura (vertexTexCoord) para dar color a los vértices y los fragmentos. El siguiente código es donde se produce la realidad aumentada a partir de la ejecución de instrucciones OpenGL. El código al ser un poco grande está comentado línea a línea explicando que se hace en cada parte. public void renderFrame(State state, float[] projectionMatrix) { // Pintar la imagen de la realidad que ha capturado la cámara y con // la que ha calculado la posición del target mVuforiaRenderer.renderVideoBackground(); // El parámetro de entrada “state” // tiene la informacion del target detectado por Vuforia TrackableResult trackable = state.getTrackableResult(); if(trackable == null) return; // Calculo de la matriz modelViewMatrix que nos pasa del sistema // de coordenadas la cámara al sistema de coordenadas del target. Matrix34F poseMatrix = trackable.getPose(); Matrix44F modelViewMatrix44F = Tool.convertPose2GLMatrix(poseMatrix); float[] modelViewMatrix = modelViewMatrix44F.getData(); // Con la siguiente translación movemos el sistema de coordenadas por encima // del target, si no se hiciera el centro del modelo estaría en el centro del target // y lo que se quiere es que la parte baja del modelo este en el plano del target. Matrix.translateM(modelViewMatrix, 0, 0.0f, 0.0f, escalaZ); // Escalado para que el modelo se pinte con las medidas reales Matrix.scaleM(modelViewMatrix, 0, escalaX, escalaY, escalaZ); // Calculo de la matriz ModelViewProjection que se pasará al VertexShader float[] modelViewProjection = new float[16]; Matrix.multiplyMM(modelViewProjection, 0, projectionMatrix, 0, modelViewMatrix, 0); // Se activa del shader y se vincula los VBO GLES20.glUseProgram(shaderProgramID); // VBO de los vértices del modelos GLES20.glVertexAttribPointer(vertexHandle, 3, GLES20.GL_FLOAT, false, 0, mMeshObject.getVertices()); // VBO de las coordenadas de textura GLES20.glVertexAttribPointer(textureCoordHandle, 2, GLES20.GL_FLOAT, false, 0, mMeshObject.getTexCoords()); // Se activa la textura que haya seleccionado el usuario. DecorAR PFC 2016 -17 70 GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextures.get(_textureIndex).mTextureID[0]); // Esta textura se asocia al Uniform del shader GLES20.glUniform1i(texSampler2DHandle, 0); // Pasamos la matriz ModelViewProjectionMatrix al shader GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, modelViewProjection, 0); // Finalmente indicamos a OpenGL que renderize el modelo que tiene // guardado en los VBO. Indicamos que // el modelo está compuesto por triángulos “GLES20.GL_TRIANGLES”. // Los índices de esos triángulos son “mMeshObject.getIndices()” GLES20.glDrawElements(GLES20.GL_TRIANGLES, mMeshObject.getNumObjectIndex(), GLES20.GL_UNSIGNED_SHORT, mMeshObject.getIndices()); } Cuando se haya ejecutado el código descrito anteriormente ya tendremos el modelo 3D virtual encima del target y podremos disfrutar de una experiencia de realidad aumentada. 5.5. WEBSERVICES Como ya se ha comentado, la App tiene que consumir información del servidor mediante WebServices. Actualmente hay muchas librerías para Android que abstraen la lógica interna de networking como por ejemplo Volley, RestLib, Ksoap. Se optado por usar esta última porque tiene bastante documentación y las pruebas que se hicieron en la etapa de análisis dieron unos muy buenos resultados. El escenario que se ha montado para realizar las pruebas es el siguiente. DecorAR PFC 2016 -17 71 Por un lado tenemos en un ordenador el Servidor Web IIS de Microsoft donde se alojan los WebServices de DecoAR que serán consumidos por la App. Para que haya visibilidad entre los dispositivos se han conectado a un router doméstico para que estén en la misma red local. En todos los métodos del WebService de DecorAR los parámetros de entrada son cadenas de texto simples que se encuentran dentro de la propia petición XML del protocolo SOAP. Pero la respuesta que se espera del WebService son objetos complejos con más de una propiedad. Estos objetos vendrán serializados en JSON y será la App quien se encargue de deserializarlos y construir el objeto complejo para poder usarlo en la lógica interna de la App. JSON es un formato de texto ligero para el intercambio de datos muy similar a XML pero que optimiza el espacio usado en los mensajes. Son cuatro los WebServices que necesita consumir la App. A continuación se detallan. 5.5.1. NEWSESSION El método “NewSession” tiene como objetivo generar una sesión asociada a un usuario registrado del sistema DecorAR. La sesión resultante permitirá al usuario registrado acceso a sus modelos privados. El método tiene dos parámetros. El primer parámetro es “username” que representa el nombre del usuario, y el segundo parámetro es el “password” como medida de control para evitar suplantaciones de identidad. El objeto que devuelve es “SessionResponseDTO” y tiene los siguientes parámetros: public class SessionResponseDTO { public String ErrorMessage; public SessionDTO Session; } public class SessionDTO { public String SessionToken; public long ExpiredDateTicks; } El campo “ErrorMessage” indicará a la App si hay algún error y que mensaje tiene que mostrar al usuario como por ejemplo “El usuario <XXX> no existe”. DecorAR PFC 2016 -17 78 image.src = "data:image/jpg;base64," + data; return new THREE.Texture(image); } Antes de asignar la textura al material de “THREE.MeshBasicMaterial” tenemos que crearla, para eso se ha implementado la función “LoadTexture” a la que se le pasa por parámetro la textura codificada en un String en base64. Se ha encapsulado en una función porque se reutilizará más adelante para cuando el usuario decida cambiar la textura durante la reproducción del modelo. En este método se utiliza de nuevo un objeto de Three.js, el objeto “THREE.Texture”. mesh = new THREE.Mesh(geometry, material); scene = new THREE.Scene(); scene.add(new THREE.AmbientLight(0xffffff)); scene.add(mesh); En la primera línea creamos el objeto con “THREE.Mesh” con la geometría y el material que hemos creado anteriormente. En la segunda parte del trozo de código creamos la escena “THREE.Scene”. Las escenas nos permiten configurar qué y dónde va a reproducirse en Three.js. Aquí es donde se colocan los objetos, luces y cámaras. Three.js dispone de dos cámaras diferentes: cámara ortográfica (OrthographicCamera) y cámara de perspectiva (PerspectiveCamera). La cámara de perspectiva está diseñada para imitar la forma en que el ojo humano ve. Es el modo de proyección más común utilizado para la representación de una escena 3D y es el que nosotros usaremos. camera = new THREE.PerspectiveCamera(27, window.innerWidth / window.innerHeight, 1, 350000); Creamos la cámara con “THREE.PerspectiveCamera” los parámetros son: el ángulo de visión vertical en grados (27), relación de aspecto (window.innerWidth / window.innerHeight), y la distancia de los planos que definen el prisma que es capaz de visualizar la cámara (1, 350000). Hasta aquí todo lo que hemos hecho ha sido inicializar todos los elementos que se necesitan para la renderización. Ahora lo único que tenemos que hacer es renderizar la sucesión de frames o fotogramas que será nuestra experiencia 3D de nuestro modelo. init(); //Inicializar los componentes Three.js animate(); //animar la escena function init() { //(...) renderer = new THREE.WebGLRenderer({ antialias: false }); container = document.getElementById('container'); container.appendChild(renderer.domElement); } function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } Después de inicializar los componentes y haber creado el contexto WebGL como vimos al inicio del capítulo, con la función “THREE.WebGLRenderer” se llama a nuestra función DecorAR PFC 2016 -17 79 JavaScript “animate()” que se encargará de renderizar un nuevo frame y auto llamarse de manera recursiva. El elemento “requestAnimationFrame” informa al navegador que quieres realizar una animación y solicita que el navegador programe el repintado de la ventana para el próximo ciclo de animación. El método acepta como argumento una función a la que llamar antes de efectuar el repintado, en nuestro caso es la propia función que contiene la llamada de repintado. Con esto sería suficiente para ver el modelo, ahora lo que queremos es poder mover el modelo para verlo desde todos los ángulos. En vez de mover el modelo lo que haremos será mover la cámara, para esto Three.js también facilita mucho la tarea al desarrollador con el elemento “THREE.OrbitControls”. function init() { //camera = new THREE.PerspectiveCamera(...); //renderer = new THREE.WebGLRenderer(...); controls = new THREE.OrbitControls(camera, renderer.domElement); window.addEventListener('resize', onWindowResize, false); window.addEventListener('wheel', onMouseWheel, false); } En la primera línea creamos un “THREE.OrbitControls” asociado a nuestra cámara y al contexto de renderización de Three.js. Este objeto nos permite rotar la cámara clicando y moviendo el ratón. Hacer zoom clicando con el botón de en medio del mouse. Y hacer pan para mover la posición de la cámara sin modificar la dirección con el botón derecho del ratón. A parte de estos controles vamos a capturar con “window.addEventListener” otros eventos que son muy comunes como el giro de la rueda del ratón y la modificación del tamaño de la pantalla. function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); } function onMouseWheel(ev) { var amount = ev.deltaY; if (amount === 0) return; var dir = amount / Math.abs(amount); camera.position.z = camera.position.z + dir * 10; } En estas funciones se modifican parámetros de la escena y de la cámara de Three.js para que el usuario tenga una experiencia completa y satisfactoria visualizando nuestros modelos 3D. DecorAR PFC 2016 -17 80 5.7. ENTITY FRAMEWORK La parte servidora del sistema DecorAR es la que se encarga de persistir los datos (modelos, texturas, etc). Microsoft pone a disposición de los desarrolladores la tecnología ADO.NET[10] que sirve para el acceso a datos, esta tecnología está basada en el framework .NET. Se usa para acceder y para modificar los datos almacenados en un Sistema Gestor de Bases de Datos relacionales como es el caso de la base de datos de DecorAR. Los componentes de ADO.NET están diseñados para separar el acceso a datos de la manipulación de datos. ADO.NET tiene dos componentes principales para cumplir esta función: el DataSet y el proveedor de datos de .NET Framework, que es un conjunto de componentes entre los que se incluyen los objetos Connection, Command, DataReader y DataAdapter. El proveedor de datos de .NET Framework sirve para conectarse a una base de datos, ejecutar comandos y recuperar resultados. Esos resultados se procesan directamente o se colocan en un DataSet de ADO.NET con el fin de exponerlos al usuario. public UserEntity GetUser_ADO_NET(string username) { UserEntity result; var connection = "Data Source=.;Initial Catalog=DecorAR;User ID=decorAR;Password=XXX;"; using (var sqlConnection = new SqlConnection(connection)) { sqlConnection.Open(); var cmdText = @"SELECT * FROM AspNetUsers WHERE Username = @param1"; using (var command = new SqlCommand(cmdText, sqlConnection)) { command.Parameters.AddWithValue("@param1", username); SqlDataReader dataReader = command.ExecuteReader(); while (dataReader.Read()) { result = new UserEntity { UserName = Convert.ToString(dataReader["UserName"]), Email = Convert.ToString(dataReader["Email"]), //completar el resto de propiedades }; } } } } DecorAR PFC 2016 -17 81 En el código anterior tenemos un ejemplo de la función “GetUser_ADO_NET” que utiliza la tecnología ADO.NET para recuperar un usuario a partir de su username. Los objetos que constituyen el proveedor de datos de .NET Framework son: Connection Establece una conexión a un origen de datos determinado. using (var sqlConnection = new SqlConnection("connectionString")) Command Ejecuta un comando en un origen de datos, al que se le pueden asignar Parámetros. using (var command = new SqlCommand(cmdText, sqlConnection)) command.Parameters.AddWithValue("@param1", username); DataReader Lee una secuencia de datos de sólo avance y sólo lectura desde un origen de datos. SqlDataReader dataReader = command.ExecuteReader(); while (dataReader.Read()) { dataReader["columnName"] } DataAdapter Llena un DataSet y realiza las actualizaciones necesarias en el origen de datos. Sirve para hacer volcado de datos. En nuestro ejemplo no lo hemos usado. Cuando son pocas las funciones de acceso a la base de datos, esta manera de acceso con ADO.NET puede ser una buena alternativa. Sin embargo en nuestro sistema tenemos muchas clases (Modelo, Textura, Usuarios, Sesiones, etc) y muchas funciones que modifican estas tablas (insertar, modificar, leer y borrar). Con ADO.NET tenemos que implementar por cada función la conexión, el comando, ejecutar o leer los datos. Sin duda un trabajo tedioso y muchísima repetición de código lo cual contradice las buenas prácticas de programación (Code Smell). Sin embargo vamos a usar una alternativa a la manera tradicional de explotación de los datos, la alternativa es Entity Framework[11]. Entity Framework (EF) es un conjunto de tecnologías ADO.NET que facilita a los desarrolladores .NET la creación de aplicaciones orientadas a datos. Los desarrolladores deben trabajar con los distintos gestores de bases de datos que hay en el mercado. Hay multitud de ellos y cada uno tiene sus propios protocolos. EF permite la abstracción del acceso y explotación de la base de datos de la aplicación. Estos son algunos de los gestores de bases de datos que son compatibles para poder ser usados con EF: Microsoft SQL Server (usado para DecorAR), Oracle, Firebird, MySQL, PosgreSQL y alguno más. EF permite a los desarrolladores trabajar con datos en forma de objetos y propiedades de dominio específico, sin tener que preocuparse por las tablas de bases de datos subyacentes y columnas donde se almacenan estos datos. Con el marco de la entidad, los desarrolladores pueden trabajar a un nivel más alto de abstracción cuando se relacionan con los datos, y pueden crear y mantener aplicaciones orientadas a datos con menos código que en las aplicaciones tradicionales. DecorAR PFC 2016 -17 82 Lo primero es crear un fichero .edmx (Entity Data Model) a partir de la base de datos ya creada de DecorAR. Este fichero define los siguientes 3 esquemas: El modelo conceptual (CSDL - Conceptual schema definition language) que describe las entidades, relaciones y funciones que compone el modelo conceptual de una aplicación basada en datos. El modelo de almacenamiento (SSDL - Store schema definition language) que describe la definición de la base de datos, el nombre de las tablas, definición de columna, keys, relaciones, etc. Y el mapeo entre los dos modelos (MSL - Mapping specification language). La creación del fichero .edmx genera un modelo conceptual “Entities” de clases/entidades lógicas que representan las tablas de la base de datos de DecorAR. public partial class DecorAREntities : DbContext { public DecorAREntities() : base("name=DecorAREntities") { } public virtual DbSet<AspNetRoles> AspNetRoles { get; set; } public virtual DbSet<Model> Model { get; set; } public virtual DbSet<Sessions> Sessions { get; set; } public virtual DbSet<Texture> Texture { get; set; } } La clase “Entities” hereda de la clase DbContext (contexto de la base de datos). La clase DbContext gestiona las entidades durante el tiempo de ejecución, lo que incluye rellenar objetos con los datos de la base de datos, el control de cambios, y la persistencia de los datos a la base de datos. En nuestro código usaremos “Entities” como si fuera la base de datos misma. public class UserRepository : IUserRepository { protected DecorAREntities Entities; public UserRepository(IInfrastructureConfig config) { //Iniciamos el contexto que representa nuestra BD Entities = DecorAREntities.CreateEntitiesForSpecificDatabaseName(config); } public UserEntity GetUser(string username) { var user = Entities.AspNetUsers.FirstOrDefault(x => x.UserName == username); var mapper = new AspNetUsersDBToEntity(); var result = mapper.Get<AspNetUsers, UserEntity>(user); return result; } } DecorAR PFC 2016 -17 83 Gracias a EF el acceso y la manipulación de los datos de la base de datos se simplifica mucho respecto a la primera implementación con ADO.NET. En el código vemos la implementación del repositorio “UserRepository”. En el constructor se inicializa la clase “DecorAREntities” que tiene el acceso a nuestra base de datos. En la función “GetUser()” con una simple línea de código var user = Entities.AspNetUsers.FirstOrDefault(x => x.UserName == username); hemos accedido a la tabla “AspNetUsers”, y hemos obtenido el registro que coincide con el “username” del parámetro de entrada de la función. Y si quisiéramos modificar un registro o añadir nuevas entradas a las tablas simplemente tendríamos que modificar las entidades de la clase “DecorAREntities” e indicar al contexto “DbContext” que guarde los cambios con a la instrucción “SaveChanges()”. public void NewSession(string username, DateTime expiredDate) { //Creamos un objeto logico la tabla "Sessions" de BD var session = new DecorAR.Infrastructure.Repositories.Sessions { ExpiredDate = expiredDate, SessionToken = Guid.NewGuid(), UserName = username, }; //La añadimos al conjunto "DbSet<Sessions>" Entities.Sessions.Add(session); //Persistimos los cambios en la BD Entities.SaveChanges(); } Con Entity Framework hemos podido reducir muchísimo código repetido y hacer que sea más fácil el mantenimiento de la aplicación. 5.8. LOGS En un sistema software es muy importante registrar la actividad que ocurre durante el funcionamiento del mismo. Los desarrolladores que implementan software necesitan encontrar problemas en sus aplicaciones durante y después del desarrollo. Para los administradores de aplicaciones les es muy útil también porque pueden supervisar si todo está funcionando correctamente y también se pueden extraer que tipo de actividad se está produciendo y detectar usos malintencionados. En el sistema DecorAR, en la parte del servidor, se ha implantado un registro de actividad mediante trazas. Las trazas son instrucciones de código que lo que hacen es enviar un mensaje al sistema donde se está ejecutando la aplicación. Además esas trazas pueden tener diferentes niveles de criticidad (Info, Warning o Error). Si no indicamos que queremos hacer con esa traza, el mensaje solo se mostrará en la pantalla de depuración. Si la aplicación se ejecutara en el servidor de explotación, la traza DecorAR PFC 2016 -17 84 se perdería. Lo que se puede hacer es implantar un “TraceListener” (Un escuchador de trazas) que lo que hace es capturar los mensajes y una vez capturado el programador tendría que persistirlo en algún medio no volátil como una base de datos o ficheros de texto. En DecorAR se ha utilizado la librería “Log4Net” que tiene licencia de Apache Sofware. Lo que hace Log4Net es guardar en ficheros de texto mensajes relativos a las trazas del sistema. En las capas más externas de la parte servidora de DecorAR (WebApplication y WebService) se ha implementado un “TraceListener” para capturar todas las trazas del sistema. El fichero “Log4NetTraceListener” se encargará de capturar todas las trazas del sistema. Hay que indicar en el fichero de configuración “Web.config” de la aplicación que hemos desarrollado un “Listener”. Este es un extracto del fichero de configuración del WebService indicando que la clase “DecorAR.WebService.Helpers.Log4netTraceListener” es nuestro “Listener”. <system.diagnostics> <trace autoflush="true"> <listeners> <add name="Log4netTraceListener" type="DecorAR.WebService.Helpers.Log4netTraceListener, DecorAR.WebService" /> </listeners> </trace> </system.diagnostics> Capas con “TraceListener” Implementación del “TraceListener” con “Log4Net” Fichero de configuración de la capa Aquí se configura el “TraceListener” y “Log4Net”. DecorAR PFC 2016 -17 85 La clase “DecorAR.WebService.Helpers.Log4netTraceListener” implementará la clase abstracta “System.Diagnostics.TraceListener” de esta manera cada vez que se lance una traza en el sistema ésta será capturada por nuestra clase. public class Log4netTraceListener : System.Diagnostics.TraceListener Una vez tenemos el mensaje capturado hay que decidir que se hace con él. Aquí es donde entra la librería “Log4Net”. En nuestro “Log4netTraceListener” tendremos una instancia de un objeto “log4net.ILog” que usaremos para reenviar el mensaje que hemos capturado. Sera Log4Net el que se encargue de persistir ese mensaje a fichero. A continuación se muestra un fragmento de código donde se instancia el objeto de Log4Net y en el envío de tres mensajes con diferentes niveles de criticidad. private static readonly log4net.ILog _log = log4net.LogManager.GetLogger("DecorAR.WebService"); (...) _log.Info(message); _log.Warn(message); _log.Error(message); En el fichero de configuración de la aplicación “Web.config” configuraremos el comportamiento de “Log4Net”. Como por por ejemplo donde guardará el fichero, el nivel de severidad que queremos registrar, etc. A continuación se muestra la configuración del “Log4Net” para el WebService. <log4net> <root> <level value="ALL" />  Nivel de severidad a registrar <appender-ref ref="DecorArAppender" />  nombre de la configuración </root> <appender name=" DecorArAppender" type="log4net.Appender.RollingFileAppender"> <file value="C:\Logs\DecorAR.WebService.log" />  Fichero de guardado <appendToFile value="true" /> <rollingStyle value="Composite" /> <maximumFileSize value="10MB" />  tamaño máximo de fichero de log <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%d [%-5level] %m%n" /> </layout> </appender> </log4net> Se puede configurar el nivel de severidad que se quiere registrar:  Info: trazas informativas normalmente de eventos o comportamiento.  Warn: para notificar de “warnings” en la aplicación.  Error: errores no fatales para registrar excepciones.  ALL: captura todo tipo de severidades. DecorAR PFC 2016 -17 86 Y con esto ya tenemos el sistema de registro y monitorización para el sistema DecorAR. En cualquier parte/módulo/capa del código de la aplicación podremos lanzar una traza con la instrucción <Trace.TraceNivelLog(‘mesaje’)> y nuestro “TraceListener” capturará el mensaje y con la ayuda de Log4Net se guardará en un fichero de texto. A continuación tenemos un ejemplo de código que usa trazas para el registro de actividad. Se trata del método “obtener un modelo” donde se registra a nivel de “Info” cuándo se ejecuta el método, quién lo ejecuta, qué modelo se ha pedido y cuándo finaliza el método. También envía una traza a nivel de “Error” si se produce algún error inesperado durante la ejecución. [WebMethod] public string GetModel(string modelGUID, string sessionToken) { try { Trace.TraceInformation("GetModel. Model=({0}), session=({1})", modelGUID, sessionToken); // aplicar lógica interna de DecorAR Trace.TraceInformation("Model({0})", title); return serialization; } catch (Exception ex) { Trace.TraceError(ex.ToString()); throw; } } Con la configuración de “Log4Net” que se ha mostrado anteriormente se generarán los ficheros de log en la ubicación indicada con el nombre que se haya definido. A continuación se muestra una captura real de los ficheros generados durante el desarrollo del sistema DecorAR. DecorAR PFC 2016 -17 87 Y a continuación un ejemplo de un fichero de log del WebService. Es muy interesante el hecho de que podamos tener una configuración de log cuando estemos desarrollando código con nivel de severidad “ALL” o “Debug” para mostrar todos los mensajes. Y otra configuración distinta para la instancia del sistema que se esté ejecutando en producción y todo el público esté accediendo al sistema con un nivel de severidad más crítico como “Warning” o “Error”. Sólo habría que modificar el fichero “Web.Config” sin la necesidad de modificar el código interno o tener que recompilar la aplicación. 5.9. FICHEROS DE CONFIGURACIÓN Como hemos visto en el capítulo anterior es muy útil tener ficheros de configuración donde se define el comportamiento de una parte de la aplicación sin tener que modificar el código interno y recompilar. En el sistema DecorAR se ha ideado un sistema de configuración basado en ficheros en las capas o módulos del sistema que lo necesitan. Donde cobra más relevancia la configuración por ficheros es en la capa de infraestructura. Recordemos que la capa de infraestructura es la encargada de la persistencia y de la conexión con la base de datos. Este es el fichero de configuración “app.config” de la capa de infraestructura. <?xml version="1.0" encoding="utf-8"?> <configuration> <connectionStrings> <add name="DecorAR.ConnectionString" connectionString="Data Source=192.168.3.138;Initial Catalog=DecorAR;User ID=decorAR;Password=356$UCeOFEox;" /> </connectionStrings> <appSettings> <add key="DecorAR.TimeOutInMinutes" value="60" /> </appSettings> </configuration> En el apartado de conexión de base de datos “ConnectionStrings” se indica donde tenemos alojado el servidor de base de datos (Data Source=192.168.3.138), cual es el nombre de la Conexión de base de datos Valor de configuración simple DecorAR PFC 2016 -17 94 6.3. ANÁLISIS ECONÓMICO En este apartado se va analizar el coste económico del proyecto. Los gastos asociados a la realización del proyecto se dividen en tres partes: hardware, software y recursos humanos. 6.3.1. COSTE HARDWARE En el apartado de coste de Hardware se tiene en consideración el equipo informático que se ha necesitado para el desarrollo del proyecto. Un ordenador de gama media para la creación de los componentes software, un equipo capaz de ejecutar y debugar los IDEs de Visual Studio y Android Studio. El ordenador también tiene que ser capaz de ejecutar un Servidor Web IIS de Microsoft con las instancias de la Aplicación Web y de los Servicios Web de DecorAR. También se ha necesitado un Smartphone de gama media con sistema operativo Android para ejecutar y probar la aplicación DecorAR. Y finalmente un router doméstico para crear una red interna y que permita la conectividad entre el móvil y los servicios web alojados en el PC. Hardware Especificaciones Precio Ordenador portátil HP EliteBook 840 - Procesador Intel® Core™ i7 - RAM 16GB - Disco duro SSD de 500GB 1.500 € Smartphone Nexus 4 de Google - GPU Adreno 320 - RAM 2GB - Quad Core Qualcomm APQ8064T - Cámara 8 megapixeles 200 € Router inalámbrico TL-WR841N - Velocidad 300 Mbps 30 € Hay que tener en cuenta que el precio de la compra del hardware usado no repercute en su totalidad al coste final del proyecto. Los equipos se van amortizando con el tiempo, y pasado el tiempo total de amortización se considera que el precio de los equipos es cero. Considerando que el ordenador en 3 años esta amortizado, el Smartphone en 1 año, y el router en 4 años en la siguiente tabla se calcula el valor imputable del hardware al proyecto. Hardware Precio Plazo de amortización % Imputable Coste Imputable Portátil 1.500 € 36 meses (5/36)*100 = 14% 210 € Smartphone 200 € 12 meses (5/12)*100 = 42% 84 € Router 30 € 48 meses (5/48)*100 = 10% 3 € Contando que el proyecto ha tenido una duración de unos 5 meses el coste imputable de hardware es de 297€. DecorAR PFC 2016 -17 95 6.3.2. COSTE SOFTWARE Hay que valorar también el software que se ha utilizado durante el proyecto. Herramienta Coste Windows 8.1 Pro 50 € IDE Visual Studio 2015 Profesional 500 € IDE Android Studio gratis SQL Server Express gratis Sistema operativo Android gratis Repositorio de código gratis Vuforia Licencia de Desarrollo gratis Total: 550 € La mayoría de herramientas has sido gratuitas. El IDE Visual Studio que se ha utilizado tiene un coste aproximado de 500€ por licencia y la de Windows unos 50€, aunque en mi caso no he tenido que pagar nada ya que he usado el portátil del trabajo y ya tenía estas herramientas instaladas. 6.3.3. COSTES EN RECURSOS HUMANOS En este apartado se explica el precio que costaría realizar las diferentes etapas del proyecto. El precio se calcula con las horas de cada etapa multiplicadas por el precio que cuesta contratar al profesional adecuado. Etapa Profesional €/hora Horas Precio Definición del proyecto Analista 45 € 10 450 € Estudio de tecnologías Analista 45 € 130 5.850 € Diseño Analista 45 € 30 1.350 € Implementación Programador 35 € 380 13.300 € Pruebas Programador 35 € 45 1.575 € Documentación Programador 35 € 160 5.600 € Total: 28.125 € 6.3.4. COSTE TOTAL DEL DESARROLLO Sumando los costes de cada uno de los apartados anteriores se puede tener una idea del coste de desarrollo de este proyecto. A pesar de que el coste de las herramientas software DecorAR PFC 2016 -17 96 para este proyecto has sido cero se han incluido en el total para dar una idea aproximada de cuál hubiera sido el coste real del desarrollo del sistema DecorAR. Concepto Coste Hardware 297 € Software 550 € Recursos humanos 28.125 € Total: 28.125 € 6.3.5. COSTES DE EXPLOTACIÓN Hasta ahora solo se ha hablado de cuanto ha costado desarrollar el sistema DecorAR. Sin embargo, también existen los costes de explotación, estos son los relacionados a poner el sistema DecorAR al mercado. Concepto Coste Cuota Android 25 $ Hosting de servidor web. 50 – 100 €/mes Android pide a los desarrolladores una cuota de 25$ para abrir una cuenta a la que asociar las Apps que se quieran subir a su Android Market. Se podría ahorrar esta cuota y publicar el instalable en la propia Web de DecorAR, pero se considera que tener la App en el Market de Android implicaría mucha más visibilidad y aumentaría potencialmente el número de usuarios. Por último para publicar el servidor web DecorAR se necesita un hosting que ofrezca posibilidad de ejecutar instancias .NET para la Página Web y los Servicios Web. Además que permita alojar la base de datos Microsoft SQL Server. Hay multitud de empresas que ofrecen estos servicios con precios muy diferentes dependiendo del rendimiento de los servidores. Para un volumen de tráfico medio y servidores con buena disponibilidad los precios rondan entre los 50 y 100€ al mes. 6.4. VALORACIONES PERSONALES El objetivo de este proyecto era el de crear un sistema de gestión de modelos 3D con el objetivo de ayudar a la decoración de interiores mediante realidad aumentada. En líneas generales se han cumplido todos los objetivos propuestos al inicio del proyecto, se ha creado una Página Web capaz de gestionar catálogos de modelos 3D asociados a cuentas de usuario y también se ha creado una aplicación móvil capaz de acceder a los modelos creados en la Página Web DecorAR y poder visualizarlos con realidad aumentada en cualquier sitio de nuestro hogar. DecorAR PFC 2016 -17 97 Uno de los objetivos más importantes era que el sistema fuera fácil de usar. Gracias al sistema de acceso sin necesidad de registro cualquier usuario con la App instalada podría tener a su alcance una gran lista de modelos 3D. Además con el sistema de captura de URLs cuando alguien esté mirando una web de terceros de muebles y esté interesado en ver cómo quedaría ese mueble en sus casas simplemente con un par de clicks podría verlo con realidad aumentada. En el momento de lanzar al mercado el sistema DecorAR habría que crear un catálogo de modelos básicos para que el público viera las posibilidades del sistema, pero después serían los usuarios (tiendas de muebles, modelistas 3D, etc.) quienes crearían esos modelos poniéndolos al alcance de todo el mundo. Sería un sistema colaborativo, donde la gente es la que añade valor a la aplicación similar a aplicaciones de redes sociales como Facebook, Twitter. DecorAR ofrece una plataforma, y son los usuarios los que irían añadiendo valor con sus modelos 3D. Después de mucho trabajo y horas invertidas en líneas generales estoy muy satisfecho del resultado final. Me hubiera gustado mejorar la interfaz gráfica para que fuera más atractiva y comercial, aunque con los nulos conocimientos de UX Design (User Experience Design) ya sabía que no conseguiría una maravilla gráfica y es por eso que desde el principio me centré en las funcionalidades del sistema. 6.5. LÍNEAS FUTURAS DecorAR no acaba aquí, hay varias líneas que en el futuro se podrían hacer para mejorar y dar más valor al sistema. Sistema de pagos: Una posibilidad sería habilitar un sistema de pagos para cuentas con mucho tráfico. El sistema está ideado para que cualquiera pueda usarlo de manera gratuita y aprovecharse de la AR para decorar su hogar. Pero si por ejemplo una tienda de muebles utiliza la plataforma DecorAR para alojar ahí todos sus modelos la plataforma tiene que darle el espacio en disco suficiente para persistir los datos de sus modelos y si tiene muchas visitas asegurar la disponibilidad del sistema. Por lo tanto, una medida sería permitir que las cuentas registradas en DecorAR tengan un numero X de modelos de forma gratuita, y en el caso que necesitaran añadir más modelos a su colección tendría que pagar una cantidad. En ningún caso se cobraría a los usuarios para poder visualizar los modelos, solo a las cuentas que quieran tener un catálogo con muchos modelos. Mejoras en UX: Como ya se ha comentado anteriormente los escasos conocimientos en las tecnologías que definen el aspecto de las pantallas tanto de la Web como de App móvil ha provocado que el resultado haya sido una sistema que se puede mejorar bastante en su apartado de experiencia de usuario. Por lo tanto una mejora en el futuro sería enviar el sistema a un profesional que se dedique a la experiencia de usuario para que el sistema DecorAR sea un producto no sólo funcional sino moderno y atractivo. DecorAR PFC 2016 -17 98 Mejoras en la usabilidad: Analizar nuevas maneras para poder facilitar el uso de DecorAR a los usuarios. Por ejemplo con lecturas de códigos QR, la idea sería que alguien que esté mirando una revista o catálogo en papel de muebles o de decoración al lado de cada modelo haya un código QR con el texto “escanea el código con la App DecorAR y mira el modelo en tu casa”. Entonces el usuario tendría que abrir la App en su móvil y activar la función escanear QR y una vez reconocido el código comenzaría la descarga. No sólo para revistas, esta funcionalidad también serviría para vallas publicitarias y otros sectores no solo de muebles y decoración. Valoración de los usuarios: Sería muy interesante implantar un sistema de puntuación de los modelos del tipo “me gusta” o “no me gusta”, o con puntuaciones de 1 a 10 o similar. Esto permitiría identificar los modelos que más gustan a la comunidad de DecorAR. Esa puntuación se podría usar para la búsqueda de modelos y ordenar o filtrar por valoración de los usuarios. También sería interesante que se pudieran comentar los modelos para dar su opinión de la experiencia o ayudar al propietario del modelo a detectar errores o sugerir mejoras. La participación de los usuarios crearía una comunidad y añadiría más valor al sistema, aunque habría que definir el rol de administrador para vigilar los comentarios inapropiados que pudieran producirse. Mantenimiento y rendimiento: Una de las más importantes líneas de futuro sería hacer un seguimiento al sistema. Si la plataforma DecorAR tiene éxito, el número de usuarios se irá incrementando y habrá que ir monitorizando el rendimiento e ir aplicando los ajustes necesarios para soportar el tráfico existente. La monitorización se podría hacer mediante el análisis de los registros de la actividad del sistema, con consultas a las tablas de base de datos y con pruebas reales de las funciones de la App midiendo los tiempos de respuesta. Después de mucho trabajo y horas invertidas en este proyecto tenemos un producto de decoración que puede resultar muy útil para mucha gente. Pero sin duda el trabajo no acaba aquí, el sistema puede evolucionar de muchas formas distintas, y porque no, en el futuro ser una aplicación de referencia y que todo el mundo al ver o escuchar la palabra DecorAR lo asocie al sistema de decoración con Realidad Aumentada desarrollado en este PFC. DecorAR PFC 2016 -17 99 7. BIBLIOGRAFÍA [1] AFIPS, Conference proceedings. Volume 33 Part One. 1968 Fall Joint Computer conferenre. San Francisco, California December 1968 http://portalparts.acm.org/1480000/1476589/fm/frontmat ter.pdf?ip=79.151.100.183&CFID=781430769&CFTOKEN=42647 745 (página 6) [2] Proceedings of the Twenty-Fifth Hawaii International Conference on System Sciences - Kauai, HI, USA – 1992 http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumbe r=672478 [3] Steven Feiner, Blair MacIntyre, Dorée Seligmann - Knowledge-based Augmented Reality for Maintenance Assistance - Department of Computer Science, Columbia University, NewYork USA - 1996 http://monet.cs.columbia.edu/projects/karma/karma.html [4] Steven Feiner, Blair MacIntyre, Tobias Höllerer - A Touring Machine: Prototyping 3D Mobile Augmented Reality Systems for Exploring the Urban Environment - Department of Computer Science, Columbia University, NewYork USA - 1997 https://www.researchgate.net/publication/221240775_A_T ouring_Machine_Prototyping_3D_Mobile_Augmented_Reality _Systems_for_Exploring_the_Urban_Environment [5] César de la Torre Llorente, Unai Zorrilla Castro, Javier Calvarro Nelson, Miguel Ángel Ramos Barroso – Guía de Arquitectura N-Capas orientada al Dominio con .NET 4.0 – Microsoft Architecture – Editado por Krasis Consulting – 2010 https://blogs.msdn.microsoft.com/cesardelatorre/2010/0 3/11/nuestro-nuevo-libro-guia-de-arquitectura-n-capasddd-net-4-0-y-aplicacion-ejemplo-en-disponibles-paradownload-en-msdn-y-codeplex/ [6] Barbara Liskov – Data Abstraction and Hierarchy - Publicado por SIGPLAN - Proceeding OOPSLA '87 Addendum to the proceedings on Object-oriented programming systems, languages and applications (Addendum) Páginas 17-34 - Orlando, Florida, USA — 1987 Enlace del artículo: https://pdfs.semanticscholar.org/36be/babeb72287ad9490 e1ebab84e7225ad6a9e5.pdf [7] Martin Fowler - Inversion of Control Containers and the Dependency Injection pattern - 23 January 2004 https://martinfowler.com/articles/injection.html [8] Página oficial para desarrolladores del SDK de realidad aumentada Vuforia https://developer.vuforia.com/home-page [9] Página oficial de la tecnología WebGL desarrollada por KHRONOS Group. https://www.khronos.org/webgl/ DecorAR PFC 2016 -17 100 [10] Ado.NET - Web para desarrolladores de Microsoft https://msdn.microsoft.com/eses/library/e80y5yhx(v=vs.110).aspx [11] Entity Framework - Web para desarrolladores de Microsoft https://msdn.microsoft.com/enus/library/aa937723(v=vs.113).aspx DecorAR PFC 2016 -17 101 Agradecimientos, A mi familia y amigos por apoyarme. Y sobre todo a Mayra que me ha dado la ilusión y la fuerza para realizar este proyecto.