HoloLens (1ª generación) y Azure 303: Reconocimiento del lenguaje natural (LUIS)


Nota

Los tutoriales de Mixed Reality Academy se han diseñado teniendo en cuenta HoloLens (1.ª generación) y los cascos envolventes de realidad mixta. Por lo tanto, creemos que es importante conservar estos tutoriales para los desarrolladores que sigan buscando instrucciones sobre el desarrollo para esos dispositivos. Estos tutoriales no se actualizarán con los conjuntos de herramientas o las interacciones más recientes que se usan para HoloLens 2. Se mantendrán para que sigan funcionando en los dispositivos compatibles. Habrá una nueva serie de tutoriales que se publicarán en el futuro que demostrarán cómo desarrollar para HoloLens 2. Este aviso se actualizará con un vínculo a esos tutoriales cuando se publiquen.


En este curso, aprenderá a integrar Language Understanding en una aplicación de realidad mixta mediante Azure Cognitive Services, con la API de Language Understanding.

Resultado del laboratorio

Language Understanding (LUIS) es un servicio de Microsoft Azure, que proporciona a las aplicaciones la capacidad de hacer significado de la entrada del usuario, por ejemplo, mediante la extracción de lo que una persona puede querer, en sus propias palabras. Esto se logra a través del aprendizaje automático, que comprende y aprende la información de entrada y, a continuación, puede responder con información detallada, relevante. Para más información, visite la página azure Language Understanding (LUIS).

Después de completar este curso, tendrá una aplicación de casco envolvente de realidad mixta que podrá hacer lo siguiente:

  1. Capture la voz de entrada del usuario mediante el micrófono conectado al casco envolvente.
  2. Envíe el dictado capturado a Azure Language Understanding Intelligent Service (LUIS).
  3. Hacer que LUIS extraiga significado de la información de envío, que se analizará e intente determinar la intención de la solicitud del usuario se realizará.

El desarrollo incluirá la creación de una aplicación en la que el usuario podrá usar la voz o la mirada para cambiar el tamaño y el color de los objetos de la escena. No se tratará el uso de controladores de movimiento.

En la aplicación, dependerá de usted cómo integrará los resultados con el diseño. Este curso está diseñado para enseñar a integrar un servicio de Azure con el proyecto de Unity. Es su trabajo usar los conocimientos que obtiene de este curso para mejorar la aplicación de realidad mixta.

Prepárese para entrenar LUIS varias veces, que se trata en el capítulo 12. Obtendrá mejores resultados las veces que se ha entrenado LUIS.

Compatibilidad con dispositivos

Curso HoloLens Cascos envolventes
MR y Azure 303: Reconocimiento del lenguaje natural (LUIS) ✔️ ✔️

Nota

Aunque este curso se centra principalmente en Windows Mixed Reality cascos envolventes (VR), también puede aplicar lo que aprende en este curso para Microsoft HoloLens. A medida que sigas con el curso, verás notas sobre los cambios que puedas necesitar para admitir HoloLens. Al usar HoloLens, es posible que observe algún eco durante la captura de voz.

Requisitos previos

Nota:

Este tutorial está diseñado para desarrolladores que tienen experiencia básica con Unity y C#. Tenga en cuenta también que los requisitos previos y las instrucciones escritas dentro de este documento representan lo que se ha probado y comprobado en el momento de la escritura (mayo de 2018). Puede usar el software más reciente, como se muestra en el artículo sobre la instalación de las herramientas , aunque no debe asumirse que la información de este curso coincidirá perfectamente con lo que encontrará en el software más reciente que lo que se muestra a continuación.

Se recomienda el siguiente hardware y software para este curso:

Antes de empezar

  1. Para evitar encontrar problemas al compilar este proyecto, se recomienda encarecidamente crear el proyecto mencionado en este tutorial en una carpeta raíz o casi raíz (las rutas de acceso de carpetas largas pueden causar problemas en tiempo de compilación).

  2. Para permitir que la máquina habilite Dictado, vaya a Configuración > de Windows Privacy > Speech, Inking & Typing (Escritura manuscrita) y presione el botón Activar servicios de voz y escribir sugerencias.

  3. El código de este tutorial le permitirá grabar desde el dispositivo micrófono predeterminado establecido en la máquina. Asegúrese de que el dispositivo micrófono predeterminado está establecido como el que desea usar para capturar la voz.

  4. Si los auriculares tienen un micrófono integrado, asegúrese de que la opción "Cuando use mis auriculares, cambie al micrófono de auriculares" esté activada en la configuración del portal de Mixed Reality.

    Configuración de cascos envolventes

Capítulo 1: Configuración de Azure Portal

Para usar el servicio Language Understanding en Azure, deberá configurar una instancia del servicio para que esté disponible para la aplicación.

  1. Inicie sesión en Azure Portal.

    Nota

    Si aún no tiene una cuenta de Azure, deberá crear una. Si sigue este tutorial en una situación de clase o laboratorio, pida a su instructor o a uno de los proctores que le ayuden a configurar la nueva cuenta.

  2. Una vez que haya iniciado sesión, haga clic en Nuevo en la esquina superior izquierda y busque Language Understanding y haga clic en Entrar.

    Creación de un recurso de LUIS

    Nota

    Es posible que la palabra New se haya reemplazado por Create a resource (Crear un recurso) en portales más recientes.

  3. La nueva página a la derecha proporcionará una descripción del servicio Language Understanding. En la parte inferior izquierda de esta página, seleccione el botón Crear para crear una instancia de este servicio.

    Creación del servicio LUIS: aviso legal

  4. Una vez que haya hecho clic en Crear:

    1. Inserte el nombre deseado para esta instancia de servicio.

    2. Seleccione una opción en Suscripción.

    3. Seleccione el plan de tarifa adecuado para usted, si es la primera vez que se crea un servicio de LUIS, debe estar disponible un nivel gratuito (denominado F0). La asignación gratuita debe ser más que suficiente para este curso.

    4. Elija un grupo de recursos o cree uno nuevo. Un grupo de recursos proporciona una manera de supervisar, controlar el acceso, aprovisionar y administrar la facturación de una colección de recursos de Azure. Se recomienda mantener todos los servicios de Azure asociados a un único proyecto (por ejemplo, estos cursos) en un grupo de recursos común).

      Si desea obtener más información sobre los grupos de recursos de Azure, visite el artículo sobre el grupo de recursos.

    5. Determine la ubicación del grupo de recursos (si va a crear un nuevo grupo de recursos). La ubicación ideal sería en la región donde se ejecutaría la aplicación. Algunos recursos de Azure solo están disponibles en determinadas regiones.

    6. También deberá confirmar que ha comprendido los Términos y Condiciones aplicados a este Servicio.

    7. Seleccione Crear.

      Creación de un servicio luis: entrada de usuario

  5. Una vez que haya hecho clic en Crear, tendrá que esperar a que se cree el servicio, esto puede tardar un minuto.

  6. Una notificación aparecerá en el portal una vez creada la instancia de servicio.

    Nueva imagen de notificación de Azure

  7. Haga clic en la notificación para explorar la nueva instancia de servicio.

    Notificación correcta de creación de recursos

  8. Haga clic en el botón Ir al recurso en la notificación para explorar la nueva instancia de servicio. Se le llevará a la nueva instancia de servicio de LUIS.

    Acceso a claves de LUIS

  9. En este tutorial, la aplicación tendrá que realizar llamadas al servicio, que se realiza mediante el uso de la clave de suscripción del servicio.

  10. En la página Inicio rápido , del servicio de API de LUIS , vaya al primer paso, Grabe las claves y haga clic en Claves (también puede hacerlo haciendo clic en el hipervínculo azul Claves, que se encuentra en el menú de navegación de servicios, indicado por el icono de clave). Esto revelará las claves de servicio.

  11. Realice una copia de una de las claves mostradas, ya que lo necesitará más adelante en el proyecto.

  12. En la página Servicio, haga clic en Language Understanding Portal para que se le redirija a la página web que usará para crear el nuevo servicio, dentro de la aplicación de LUIS.

Capítulo 2: El portal de Language Understanding

En esta sección aprenderá a crear una aplicación de LUIS en el portal de LUIS.

Importante

Tenga en cuenta que la configuración de las entidades, las intenciones y las expresiones dentro de este capítulo es solo el primer paso para crear el servicio de LUIS: también tendrá que volver a entrenar el servicio, varias veces, para que sea más preciso. El reentrenamiento del servicio se trata en el último capítulo de este curso, por lo que debe asegurarse de completarlo.

  1. Al llegar al portal de Language Understanding, es posible que tenga que iniciar sesión, si aún no lo está, con las mismas credenciales que su Azure Portal.

    Página de inicio de sesión de LUIS

  2. Si es la primera vez que usa LUIS, deberá desplazarse hacia abajo hasta la parte inferior de la página principal para buscar y hacer clic en el botón Crear aplicación de LUIS .

    Página Crear aplicación de LUIS

  3. Una vez que haya iniciado sesión, haga clic en Mis aplicaciones (si no está en esa sección actualmente). A continuación, puede hacer clic en Crear nueva aplicación.

    LUIS: imagen de mis aplicaciones

  4. Asigne un Nombre a la aplicación.

  5. Si se supone que la aplicación entiende un idioma diferente del inglés, debes cambiar la referencia cultural al idioma adecuado.

  6. Aquí también puede agregar una descripción de la nueva aplicación de LUIS.

    LUIS: creación de una aplicación

  7. Una vez que presione Listo, escribirá la página Compilar de la nueva aplicación de LUIS .

  8. Hay algunos conceptos importantes para comprender aquí:

    • Intención, representa el método al que se llamará después de una consulta del usuario. Una INTENCIÓN puede tener una o varias ENTIDADES.
    • Entity, es un componente de la consulta que describe la información relevante para la INTENCIÓN.
    • Las expresiones son ejemplos de consultas proporcionadas por el desarrollador, que LUIS usará para entrenarse a sí mismo.

Si estos conceptos no están perfectamente claros, no se preocupe, ya que este curso los aclarará aún más en este capítulo.

Comenzará por crear las entidades necesarias para crear este curso.

  1. En el lado izquierdo de la página, haga clic en Entidades y, a continuación, haga clic en Crear nueva entidad.

    Creación de una nueva entidad

  2. Llame al nuevo color de entidad, establezca su tipo en Simple y presione Listo.

    Creación de una entidad simple: color

  3. Repita este proceso para crear tres (3) más entidades simples denominadas:

    • upsize
    • Downsize
    • Destino

El resultado debe tener un aspecto similar al de la imagen siguiente:

Resultado de la creación de entidades

En este momento, puede empezar a crear intenciones.

Advertencia

No elimine la intención None .

  1. En el lado izquierdo de la página, haga clic en Intenciones y, a continuación, haga clic en Crear nueva intención.

    Creación de intenciones

  2. Llame al nuevo IntentChangeObjectColor.

    Importante

    Este nombre de intención se usa en el código más adelante en este curso, por lo que, para obtener mejores resultados, use este nombre exactamente como se proporciona.

Una vez que confirme el nombre, se le dirigirá a la página Intenciones.

LUIS: página de intenciones

Observará que hay un cuadro de texto que le pide que escriba 5 o más expresiones diferentes.

Nota

LUIS convierte todas las expresiones en minúsculas.

  1. Inserte la siguiente expresión en el cuadro de texto superior (actualmente con el texto Tipo sobre 5 ejemplos... ) y presione Entrar:
The color of the cylinder must be red

Observará que la nueva expresión aparecerá en una lista debajo.

Después del mismo proceso, inserte las seis (6) expresiones siguientes:

make the cube black

make the cylinder color white

change the sphere to red

change it to green

make this yellow

change the color of this object to blue

Para cada expresión que haya creado, debe identificar qué palabras debe usar LUIS como entidades. En este ejemplo, debe etiquetar todos los colores como entidad de color y todas las posibles referencias a un destino como entidad de destino .

  1. Para ello, intente hacer clic en el cilindro de palabras en la primera expresión y seleccionar destino.

    Identificación de destinos de expresiones

  2. Ahora haga clic en la palabra rojo en la primera expresión y seleccione color.

    Identificación de entidades de expresión

  3. Etiquete también la siguiente línea, donde el cubo debe ser un destino y el negro debe ser un color. Observe también el uso de las palabras "this","it" y "this object", que se proporcionan, por lo que también hay tipos de destino no específicos disponibles.

  4. Repita el proceso anterior hasta que todas las expresiones tengan etiquetadas las entidades. Consulte la imagen siguiente si necesita ayuda.

    Sugerencia

    Al seleccionar las palabras que quiere etiquetar como entidades:

    • Para las palabras simples, simplemente haga clic en ellas.
    • Para un conjunto de dos o más palabras, haga clic al principio y, a continuación, al final del conjunto.

    Nota

    Puede usar el botón de alternancia Vista de tokens para cambiar entre la vista Entidades o tokens.

  5. Los resultados deben ser como se muestran en las imágenes siguientes, en las que se muestra la vista Entidades/tokens:

    Tokens & vistas de entidades

  6. En este punto, presione el botón Entrenar en la parte superior derecha de la página y espere a que el pequeño indicador redondo en él se vuelva verde. Esto indica que LUIS se ha entrenado correctamente para reconocer esta intención.

    Entrenamiento de LUIS

  7. Como ejercicio, cree una intención denominada ChangeObjectSize con el destino Entities, upsize y downsize.

  8. Siguiendo el mismo proceso que la intención anterior, inserte las ocho (8) expresiones siguientes para cambio de tamaño :

    increase the dimensions of that
    
    reduce the size of this
    
    i want the sphere smaller
    
    make the cylinder bigger
    
    size down the sphere
    
    size up the cube
    
    decrease the size of that object
    
    increase the size of this object
    
  9. El resultado debe ser similar al de la imagen siguiente:

    Configuración de tokens o entidades ChangeObjectSize

  10. Una vez creadas y entrenadas las intenciones, ChangeObjectColor y ChangeObjectSize, haga clic en el botón PUBLICAR de la parte superior de la página.

    Publicación del servicio LUIS

  11. En la página Publicar finalizará y publicará la aplicación de LUIS para que el código pueda acceder a ella.

    1. Establezca la lista desplegable Publicar en como producción.

    2. Establezca la zona horaria en la zona horaria.

    3. Active la casilla Incluir todas las puntuaciones de intención previstas.

    4. Haga clic en Publicar en ranura de producción.

      Configuración de publicación

  12. En la sección Recursos y claves:

    1. Seleccione la región que establezca para la instancia de servicio en Azure Portal.
    2. Observará un elemento Starter_Key siguiente, omitalo.
    3. Haga clic en Agregar clave e inserte la clave que obtuvo en Azure Portal al crear la instancia de servicio. Si azure y el portal de LUIS han iniciado sesión en el mismo usuario, se le proporcionarán menús desplegables para nombre de inquilino, nombre de suscripción y la clave que desea usar (tendrá el mismo nombre que proporcionó anteriormente en Azure Portal.

    Importante

    Debajo del punto de conexión, tome una copia del punto de conexión correspondiente a la clave que ha insertado, pronto lo usará en el código.

Capítulo 3: Configuración del proyecto de Unity

A continuación se muestra una configuración típica para desarrollar con la realidad mixta y, como tal, es una buena plantilla para otros proyectos.

  1. Abra Unity y haga clic en Nuevo.

    Inicie el nuevo proyecto de Unity.

  2. Ahora tendrá que proporcionar un nombre de proyecto de Unity, insertar MR_LUIS. Asegúrese de que el tipo de proyecto está establecido en 3D. Establezca la ubicación en un lugar adecuado para usted (recuerde, más cerca de los directorios raíz es mejor). A continuación, haga clic en Crear proyecto.

    Proporcione detalles para el nuevo proyecto de Unity.

  3. Con Unity abierto, vale la pena comprobar que el Editor de scripts predeterminado está establecido en Visual Studio. Vaya a Editar > preferencias y, a continuación, en la nueva ventana, vaya a Herramientas externas. Cambie el Editor de scripts externos a Visual Studio 2017. Cierre la ventana Preferencias.

    Actualizar la preferencia del editor de scripts.

  4. A continuación, vaya a Configuración de compilación de archivos > y cambie la plataforma a Plataforma universal de Windows, haciendo clic en el botón Cambiar plataforma.

    Ventana Configuración de compilación, cambie la plataforma a UWP.

  5. Vaya a Configuración de compilación de archivos > y asegúrese de que:

    1. El dispositivo de destino se establece en Cualquier dispositivo.

      Para la Microsoft HoloLens, establezca Dispositivo de destino en HoloLens.

    2. El tipo de compilación se establece en D3D.

    3. El SDK se establece en Latest installed (Versión más reciente instalada)

    4. La versión de Visual Studio se establece en Latest installed (Versión más reciente instalada)

    5. Compilar y ejecutar está establecido en Equipo local

    6. Guarde la escena y agréguela a la compilación.

      1. Para ello, seleccione Agregar escenas abiertas. Aparecerá una ventana de guardado.

        Haga clic en el botón Agregar escenas abiertas.

      2. Cree una nueva carpeta para esto y cualquier escena futura y, a continuación, seleccione el botón Nueva carpeta para crear una carpeta nueva, asígnela el nombre Scenes.

        Creación de una carpeta de scripts

      3. Abra la carpeta Escenas recién creada y, a continuación, en el campo Nombre de archivo: texto, escriba MR_LuisScene y presione Guardar.

        Asigne un nombre a la nueva escena.

    7. La configuración restante, en Configuración de compilación, debe dejarse como predeterminada por ahora.

  6. En la ventana Configuración de compilación, haga clic en el botón Configuración del reproductor ; se abrirá el panel relacionado en el espacio donde se encuentra el Inspector .

    Abra la configuración del reproductor.

  7. En este panel, es necesario comprobar algunas opciones de configuración:

    1. En la pestaña Otros valores:

      1. La versión del entorno de ejecución de scripting debe ser estable (equivalente a .NET 3.5).

      2. El back-end de scripting debe ser .NET

      3. El nivel de compatibilidad de API debe ser .NET 4.6

        Actualice otras opciones de configuración.

    2. En la pestaña Configuración de publicación , en Funcionalidades, active:

      1. InternetClient

      2. Micrófono

        Actualización de la configuración de publicación.

    3. Más abajo del panel, en Configuración de XR (que se encuentra a continuación de Configuración de publicación), marque Virtual Reality Supported (Compatible con La realidad virtual), asegúrese de que se agrega el SDK de Windows Mixed Reality.

      Actualice la configuración de X R.

  8. De nuevo en Configuración de compilación, los proyectos de C# de Unity ya no están atenuados; marque la casilla situada junto a esta.

  9. Cierre la ventana Build Settings (Configuración de compilación).

  10. Guarde la escena y el proyecto (ARCHIVO > SAVE SCENE/FILE > SAVE PROJECT).

Capítulo 4: Crear la escena

Importante

Si desea omitir el componente De configuración de Unity de este curso y continuar directamente en el código, no dude en descargar este paquete .unitypackage, importarlo en el proyecto como un paquete personalizado y, a continuación, continuar desde el capítulo 5.

  1. Haga clic con el botón derecho en un área vacía del Panel de jerarquía, en Objeto 3D, agregue un plano.

    Cree un plano.

  2. Tenga en cuenta que, al hacer clic con el botón derecho en la jerarquía de nuevo para crear más objetos, si aún tiene seleccionado el último objeto, el objeto seleccionado será el elemento primario del nuevo objeto. Evite hacer clic con el botón izquierdo en un espacio vacío dentro de la jerarquía y, a continuación, haga clic con el botón derecho.

  3. Repita el procedimiento anterior para agregar los siguientes objetos:

    1. Sphere
    2. Cilindro
    3. Cubo
    4. Texto 3D
  4. La jerarquía de escena resultante debe ser similar a la de la imagen siguiente:

    Configuración de la jerarquía de escenas.

  5. Haga clic con el botón izquierdo en la Cámara principal para seleccionarla, examine el Panel inspector que verá el objeto Camera con todos sus componentes.

  6. Haga clic en el botón Agregar componente situado en la parte inferior del Panel inspector.

    Agregar origen de audio

  7. Busque el componente denominado Origen de audio, como se muestra anteriormente.

  8. Asegúrese también de que el componente Transformar de la cámara principal esté establecido en (0,0,0), esto se puede hacer presionando el icono engranaje junto al componente Transformar de la cámara y seleccionando Restablecer. A continuación, el componente Transformar debe tener el siguiente aspecto:

    1. Position se establece en 0, 0, 0.
    2. La rotación se establece en 0, 0, 0.

    Nota

    Para la Microsoft HoloLens, también tendrá que cambiar lo siguiente, que forma parte del componente Cámara, que se encuentra en la cámara principal:

    • Borrar marcas: Color sólido.
    • Fondo 'Negro, Alfa 0' – Color hexadecimal: #000000000.
  9. Haga clic con el botón izquierdo en plano para seleccionarlo. En el Panel inspector , establezca el componente Transformar con los valores siguientes:

    Eje X Eje Y Eje Z
    0 -1 0
  10. Haga clic con el botón izquierdo en La esfera para seleccionarla. En el Panel inspector , establezca el componente Transformar con los valores siguientes:

    Eje X Eje Y Eje Z
    2 1 2
  11. Haga clic con el botón izquierdo en cilindro para seleccionarlo. En el Panel inspector , establezca el componente Transformar con los valores siguientes:

    Eje X Eje Y Eje Z
    -2 1 2
  12. Haga clic con el botón izquierdo en el cubo para seleccionarlo. En el Panel inspector , establezca el componente Transformar con los valores siguientes:

Transformar: posición

X S Z
0 1 4

Transformación: rotación

X S Z
45 45 0
  1. Haga clic con el botón izquierdo en el nuevo objeto Text para seleccionarlo. En el Panel inspector , establezca el componente Transformar con los valores siguientes:

Transformar: posición

X S Z
-2 6 9

Transformación: escalado

X S Z
0,1 0,1 0,1
  1. Cambie el tamaño de fuente del componente Text Mesh a 50.

  2. Cambie el nombre del objeto Text Mesh a Dictation Text.

    Creación de un objeto de texto 3D

  3. La estructura del Panel de jerarquía ahora debería tener este aspecto:

    malla de texto en la vista de escena

  4. La escena final debe ser similar a la imagen siguiente:

    Vista de escena.

Capítulo 5: Creación de la clase MicrophoneManager

El primer script que va a crear es la clase MicrophoneManager . Después de esto, creará el LuisManager, la clase Behaviors y, por último, la clase Gaze (no dude en crear todos estos ahora, aunque se tratará a medida que llegue a cada capítulo).

La clase MicrophoneManager es responsable de:

  • Detectar el dispositivo de grabación conectado al casco o a la máquina (lo que sea el predeterminado).
  • Capture el audio (voz) y use el dictado para almacenarlo como una cadena.
  • Una vez que la voz se haya pausado, envíe el dictado a la clase LuisManager .

Para crear esta clase:

  1. Haga clic con el botón derecho en el Panel del proyecto, Crear > carpeta. Llame a la carpeta Scripts.

    Cree la carpeta Scripts.

  2. Con la carpeta Scripts creada, haga doble clic en ella para abrirla. A continuación, en esa carpeta, haga clic con el botón derecho en Crear > script de C#. Asigne al script el nombre MicrophoneManager.

  3. Haga doble clic en MicrophoneManager para abrirlo con Visual Studio.

  4. Agregue los siguientes espacios de nombres a la parte superior del archivo:

        using UnityEngine;
        using UnityEngine.Windows.Speech;
    
  5. A continuación, agregue las siguientes variables dentro de la clase MicrophoneManager :

        public static MicrophoneManager instance; //help to access instance of this object
        private DictationRecognizer dictationRecognizer;  //Component converting speech to text
        public TextMesh dictationText; //a UI object used to debug dictation result
    
  6. Ahora es necesario agregar código para los métodos Awake() y Start(). Se llamará cuando se inicialice la clase:

        private void Awake()
        {
            // allows this class instance to behave like a singleton
            instance = this;
        }
    
        void Start()
        {
            if (Microphone.devices.Length > 0)
            {
                StartCapturingAudio();
                Debug.Log("Mic Detected");
            }
        }
    
  7. Ahora necesita el método que usa la aplicación para iniciar y detener la captura de voz y pasarla a la clase LuisManager , que compilará pronto.

        /// <summary>
        /// Start microphone capture, by providing the microphone as a continual audio source (looping),
        /// then initialise the DictationRecognizer, which will capture spoken words
        /// </summary>
        public void StartCapturingAudio()
        {
            if (dictationRecognizer == null)
            {
                dictationRecognizer = new DictationRecognizer
                {
                    InitialSilenceTimeoutSeconds = 60,
                    AutoSilenceTimeoutSeconds = 5
                };
    
                dictationRecognizer.DictationResult += DictationRecognizer_DictationResult;
                dictationRecognizer.DictationError += DictationRecognizer_DictationError;
            }
            dictationRecognizer.Start();
            Debug.Log("Capturing Audio...");
        }
    
        /// <summary>
        /// Stop microphone capture
        /// </summary>
        public void StopCapturingAudio()
        {
            dictationRecognizer.Stop();
            Debug.Log("Stop Capturing Audio...");
        }
    
  8. Agregue un controlador de dictado que se invocará cuando la voz se detenga. Este método pasará el texto de dictado a la clase LuisManager .

        /// <summary>
        /// This handler is called every time the Dictation detects a pause in the speech. 
        /// This method will stop listening for audio, send a request to the LUIS service 
        /// and then start listening again.
        /// </summary>
        private void DictationRecognizer_DictationResult(string dictationCaptured, ConfidenceLevel confidence)
        {
            StopCapturingAudio();
            StartCoroutine(LuisManager.instance.SubmitRequestToLuis(dictationCaptured, StartCapturingAudio));
            Debug.Log("Dictation: " + dictationCaptured);
            dictationText.text = dictationCaptured;
        }
    
        private void DictationRecognizer_DictationError(string error, int hresult)
        {
            Debug.Log("Dictation exception: " + error);
        }
    

    Importante

    Elimine el método Update(), ya que esta clase no la usará.

  9. Asegúrese de guardar los cambios en Visual Studio antes de volver a Unity.

    Nota

    En este momento, observará un error que aparece en el Panel de consola del Editor de Unity. Esto se debe a que el código hace referencia a la clase LuisManager que creará en el capítulo siguiente.

Capítulo 6: Creación de la clase LUISManager

Es el momento de crear la clase LuisManager , que realizará la llamada al servicio De LUIS de Azure.

El propósito de esta clase es recibir el texto de dictado de la clase MicrophoneManager y enviarlo a la API de Azure Language Understanding que se va a analizar.

Esta clase deserializará la respuesta JSON y llamará a los métodos adecuados de la clase Behaviors para desencadenar una acción.

Para crear esta clase:

  1. Haga doble clic en la carpeta Scripts para abrirla.

  2. Haga clic con el botón derecho en la carpeta Scripts y haga clic en Crear > script de C#. Asigne al script el nombre LuisManager.

  3. Haga doble clic en el script para abrirlo con Visual Studio.

  4. Agregue los siguientes espacios de nombres a la parte superior del archivo:

        using System;
        using System.Collections;
        using System.Collections.Generic;
        using System.IO;
        using UnityEngine;
        using UnityEngine.Networking;
    
  5. Comenzará creando tres clases dentro de la clase LuisManager (dentro del mismo archivo de script, encima del método Start() que representará la respuesta JSON deserializada de Azure.

        [Serializable] //this class represents the LUIS response
        public class AnalysedQuery
        {
            public TopScoringIntentData topScoringIntent;
            public EntityData[] entities;
            public string query;
        }
    
        // This class contains the Intent LUIS determines 
        // to be the most likely
        [Serializable]
        public class TopScoringIntentData
        {
            public string intent;
            public float score;
        }
    
        // This class contains data for an Entity
        [Serializable]
        public class EntityData
        {
            public string entity;
            public string type;
            public int startIndex;
            public int endIndex;
            public float score;
        }
    
  6. A continuación, agregue las siguientes variables dentro de la clase LuisManager :

        public static LuisManager instance;
    
        //Substitute the value of luis Endpoint with your own End Point
        string luisEndpoint = "https://westus.api.cognitive... add your endpoint from the Luis Portal";
    
  7. Asegúrese de colocar el punto de conexión de LUIS en ahora (que tendrá desde el portal de LUIS).

  8. Ahora es necesario agregar código para el método Awake(). Se llamará a este método cuando se inicialice la clase :

        private void Awake()
        {
            // allows this class instance to behave like a singleton
            instance = this;
        }
    
  9. Ahora necesita los métodos que usa esta aplicación para enviar el dictado recibido de la clase MicrophoneManager a LUIS y, a continuación, recibir y deserializar la respuesta.

  10. Una vez determinado el valor de la intención y las entidades asociadas, se pasan a la instancia de la clase Behaviors para desencadenar la acción prevista.

        /// <summary>
        /// Call LUIS to submit a dictation result.
        /// The done Action is called at the completion of the method.
        /// </summary>
        public IEnumerator SubmitRequestToLuis(string dictationResult, Action done)
        {
            string queryString = string.Concat(Uri.EscapeDataString(dictationResult));
    
            using (UnityWebRequest unityWebRequest = UnityWebRequest.Get(luisEndpoint + queryString))
            {
                yield return unityWebRequest.SendWebRequest();
    
                if (unityWebRequest.isNetworkError || unityWebRequest.isHttpError)
                {
                    Debug.Log(unityWebRequest.error);
                }
                else
                {
                    try
                    {
                        AnalysedQuery analysedQuery = JsonUtility.FromJson<AnalysedQuery>(unityWebRequest.downloadHandler.text);
    
                        //analyse the elements of the response 
                        AnalyseResponseElements(analysedQuery);
                    }
                    catch (Exception exception)
                    {
                        Debug.Log("Luis Request Exception Message: " + exception.Message);
                    }
                }
    
                done();
                yield return null;
            }
        }
    
  11. Cree un nuevo método denominado AnalyzerResponseElements() que leerá la consulta AnalyseQuery resultante y determinará las entidades. Una vez determinadas esas entidades, se pasarán a la instancia de la clase Behaviors que se usará en las acciones.

        private void AnalyseResponseElements(AnalysedQuery aQuery)
        {
            string topIntent = aQuery.topScoringIntent.intent;
    
            // Create a dictionary of entities associated with their type
            Dictionary<string, string> entityDic = new Dictionary<string, string>();
    
            foreach (EntityData ed in aQuery.entities)
            {
                entityDic.Add(ed.type, ed.entity);
            }
    
            // Depending on the topmost recognized intent, read the entities name
            switch (aQuery.topScoringIntent.intent)
            {
                case "ChangeObjectColor":
                    string targetForColor = null;
                    string color = null;
    
                    foreach (var pair in entityDic)
                    {
                        if (pair.Key == "target")
                        {
                            targetForColor = pair.Value;
                        }
                        else if (pair.Key == "color")
                        {
                            color = pair.Value;
                        }
                    }
    
                    Behaviours.instance.ChangeTargetColor(targetForColor, color);
                    break;
    
                case "ChangeObjectSize":
                    string targetForSize = null;
                    foreach (var pair in entityDic)
                    {
                        if (pair.Key == "target")
                        {
                            targetForSize = pair.Value;
                        }
                    }
    
                    if (entityDic.ContainsKey("upsize") == true)
                    {
                        Behaviours.instance.UpSizeTarget(targetForSize);
                    }
                    else if (entityDic.ContainsKey("downsize") == true)
                    {
                        Behaviours.instance.DownSizeTarget(targetForSize);
                    }
                    break;
            }
        }
    

    Importante

    Elimine los métodos Start() y Update(), ya que esta clase no las usará.

  12. Asegúrese de guardar los cambios en Visual Studio antes de volver a Unity.

Nota

En este momento, observará que aparecen varios errores en el Panel de consola del Editor de Unity. Esto se debe a que el código hace referencia a la clase Behaviors que creará en el capítulo siguiente.

Capítulo 7: Crear la clase Behaviors

La clase Behaviors desencadenará las acciones mediante las entidades proporcionadas por la clase LuisManager .

Para crear esta clase:

  1. Haga doble clic en la carpeta Scripts para abrirla.

  2. Haga clic con el botón derecho en la carpeta Scripts y haga clic en Crear > script de C#. Asigne el nombre Behaviors al script.

  3. Haga doble clic en el script para abrirlo con Visual Studio.

  4. A continuación, agregue las siguientes variables dentro de la clase Behaviors :

        public static Behaviours instance;
    
        // the following variables are references to possible targets
        public GameObject sphere;
        public GameObject cylinder;
        public GameObject cube;
        internal GameObject gazedTarget;
    
  5. Agregue el código del método Awake(). Se llamará a este método cuando se inicialice la clase :

        void Awake()
        {
            // allows this class instance to behave like a singleton
            instance = this;
        }
    
  6. La clase LuisManager llama a los métodos siguientes (que ha creado anteriormente) para determinar qué objeto es el destino de la consulta y, a continuación, desencadenar la acción adecuada.

        /// <summary>
        /// Changes the color of the target GameObject by providing the name of the object
        /// and the name of the color
        /// </summary>
        public void ChangeTargetColor(string targetName, string colorName)
        {
            GameObject foundTarget = FindTarget(targetName);
            if (foundTarget != null)
            {
                Debug.Log("Changing color " + colorName + " to target: " + foundTarget.name);
    
                switch (colorName)
                {
                    case "blue":
                        foundTarget.GetComponent<Renderer>().material.color = Color.blue;
                        break;
    
                    case "red":
                        foundTarget.GetComponent<Renderer>().material.color = Color.red;
                        break;
    
                    case "yellow":
                        foundTarget.GetComponent<Renderer>().material.color = Color.yellow;
                        break;
    
                    case "green":
                        foundTarget.GetComponent<Renderer>().material.color = Color.green;
                        break;
    
                    case "white":
                        foundTarget.GetComponent<Renderer>().material.color = Color.white;
                        break;
    
                    case "black":
                        foundTarget.GetComponent<Renderer>().material.color = Color.black;
                        break;
                }          
            }
        }
    
        /// <summary>
        /// Reduces the size of the target GameObject by providing its name
        /// </summary>
        public void DownSizeTarget(string targetName)
        {
            GameObject foundTarget = FindTarget(targetName);
            foundTarget.transform.localScale -= new Vector3(0.5F, 0.5F, 0.5F);
        }
    
        /// <summary>
        /// Increases the size of the target GameObject by providing its name
        /// </summary>
        public void UpSizeTarget(string targetName)
        {
            GameObject foundTarget = FindTarget(targetName);
            foundTarget.transform.localScale += new Vector3(0.5F, 0.5F, 0.5F);
        }
    
  7. Agregue el método FindTarget() para determinar cuál de los objetos GameObjects es el destino de la intención actual. Este método usa como valor predeterminado el destino del objeto GameObject que se está "mirando" si no se define ningún destino explícito en las entidades.

        /// <summary>
        /// Determines which object reference is the target GameObject by providing its name
        /// </summary>
        private GameObject FindTarget(string name)
        {
            GameObject targetAsGO = null;
    
            switch (name)
            {
                case "sphere":
                    targetAsGO = sphere;
                    break;
    
                case "cylinder":
                    targetAsGO = cylinder;
                    break;
    
                case "cube":
                    targetAsGO = cube;
                    break;
    
                case "this": // as an example of target words that the user may use when looking at an object
                case "it":  // as this is the default, these are not actually needed in this example
                case "that":
                default: // if the target name is none of those above, check if the user is looking at something
                    if (gazedTarget != null) 
                    {
                        targetAsGO = gazedTarget;
                    }
                    break;
            }
            return targetAsGO;
        }
    

    Importante

    Elimine los métodos Start() y Update(), ya que esta clase no las usará.

  8. Asegúrese de guardar los cambios en Visual Studio antes de volver a Unity.

Capítulo 8: Crear la clase Gaze

La última clase que tendrás que completar esta aplicación es la clase Gaze . Esta clase actualiza la referencia a GameObject actualmente en el foco visual del usuario.

Para crear esta clase:

  1. Haga doble clic en la carpeta Scripts para abrirla.

  2. Haga clic con el botón derecho en la carpeta Scripts y haga clic en Crear > script de C#. Asigne al script el nombre Gaze.

  3. Haga doble clic en el script para abrirlo con Visual Studio.

  4. Inserte el código siguiente para esta clase:

        using UnityEngine;
    
        public class Gaze : MonoBehaviour
        {        
            internal GameObject gazedObject;
            public float gazeMaxDistance = 300;
    
            void Update()
            {
                // Uses a raycast from the Main Camera to determine which object is gazed upon.
                Vector3 fwd = gameObject.transform.TransformDirection(Vector3.forward);
                Ray ray = new Ray(Camera.main.transform.position, fwd);
                RaycastHit hit;
                Debug.DrawRay(Camera.main.transform.position, fwd);
    
                if (Physics.Raycast(ray, out hit, gazeMaxDistance) && hit.collider != null)
                {
                    if (gazedObject == null)
                    {
                        gazedObject = hit.transform.gameObject;
    
                        // Set the gazedTarget in the Behaviours class
                        Behaviours.instance.gazedTarget = gazedObject;
                    }
                }
                else
                {
                    ResetGaze();
                }         
            }
    
            // Turn the gaze off, reset the gazeObject in the Behaviours class.
            public void ResetGaze()
            {
                if (gazedObject != null)
                {
                    Behaviours.instance.gazedTarget = null;
                    gazedObject = null;
                }
            }
        }
    
  5. Asegúrese de guardar los cambios en Visual Studio antes de volver a Unity.

Capítulo 9: Finalización de la configuración de la escena

  1. Para completar la configuración de la escena, arrastre cada script que haya creado desde la carpeta Scripts al objeto Cámara principal en el Panel jerarquía.

  2. Seleccione la cámara principal y examine el panel inspector, debería poder ver cada script que haya asociado y observará que hay parámetros en cada script que aún no se han establecido.

    Establecer los destinos de referencia de la cámara.

  3. Para establecer estos parámetros correctamente, siga estas instrucciones:

    1. MicrophoneManager:

      • En el Panel de jerarquía, arrastre el objeto Texto de dictado al cuadro de valor del parámetro Texto de dictado .
    2. Comportamientos, desde el Panel de jerarquía:

      • Arrastre el objeto Sphere al cuadro De destino de referencia de Sphere .
      • Arrastre el cilindro al cuadro de destino de referencia cilindro .
      • Arrastre el cubo al cuadro Destino de referencia de cubo .
    3. Mirada:

      • Establezca la distancia máxima de mirada en 300 (si aún no está).
  4. El resultado debe tener un aspecto similar al de la imagen siguiente:

    Se muestran los destinos de referencia de la cámara, ahora establecidos.

Capítulo 10: Prueba en el Editor de Unity

Compruebe que la configuración de la escena está implementada correctamente.

Asegúrese de que:

  • Todos los scripts se adjuntan al objeto Cámara principal .
  • Todos los campos del Panel inspector de cámara principal se asignan correctamente.
  1. Presione el botón Reproducir en el Editor de Unity. La aplicación debe ejecutarse dentro de los cascos envolventes conectados.

  2. Pruebe algunas expresiones, como:

    make the cylinder red
    
    change the cube to yellow
    
    I want the sphere blue
    
    make this to green
    
    change it to white
    

    Nota

    Si ve un error en la consola de Unity sobre el cambio predeterminado del dispositivo de audio, es posible que la escena no funcione según lo previsto. Esto se debe a la forma en que el portal de realidad mixta trata con micrófonos integrados para auriculares que los tienen. Si ve este error, basta con detener la escena e iniciarla de nuevo y las cosas deberían funcionar según lo previsto.

Capítulo 11: Compilar y transferir localmente la solución para UWP

Una vez que haya asegurado de que la aplicación funciona en el Editor de Unity, está listo para compilar e implementar.

Para compilar:

  1. Para guardar la escena actual, haga clic en Guardar archivo>.

  2. Vaya a Configuración de compilación de archivos>.

  3. Marque la casilla denominada Proyectos de C# de Unity (útil para ver y depurar el código una vez creado el proyecto de UWP.

  4. Haga clic en Agregar escenas abiertas y, a continuación, haga clic en Compilar.

    Ventana Configuración de compilación

  5. Se le pedirá que seleccione la carpeta donde desea compilar la solución.

  6. Cree una carpeta BUILDS y, dentro de esa carpeta, cree otra carpeta con el nombre adecuado de su elección.

  7. Haga clic en Seleccionar carpeta para comenzar la compilación en esa ubicación.

    Crear carpeta decompilaciones Seleccione carpeta Compilaciones

  8. Una vez que Unity haya terminado de compilarse (es posible que tarde algún tiempo), debe abrir una ventana de Explorador de archivos en la ubicación de la compilación.

Para implementar en el equipo local:

  1. En Visual Studio, abra el archivo de solución que se ha creado en el capítulo anterior.

  2. En la Plataforma de soluciones, seleccione x86, Máquina local.

  3. En Configuración de la solución , seleccione Depurar.

    Para la Microsoft HoloLens, es posible que le resulte más fácil establecer esto en Equipo remoto, para que no esté anclado a su equipo. Sin embargo, también deberá hacer lo siguiente:

    • Conoce la dirección IP de holoLens, que se puede encontrar en la red de configuración > & Internet > Wi-Fi > Opciones avanzadas; IPv4 es la dirección que debes usar.
    • Asegúrese de que el modo de desarrollador está activado; se encuentra en Configuración > Update & Security > Para desarrolladores.

    Implementación de una aplicación

  4. Vaya al menú Compilar y haga clic en Implementar solución para transferir localmente la aplicación a la máquina.

  5. La aplicación debería aparecer ahora en la lista de aplicaciones instaladas, lista para iniciarse.

  6. Una vez iniciada, la aplicación le pedirá que autorice el acceso al micrófono. Use los controladores de movimiento, o la entrada de voz, o el teclado para presionar el botón .

Capítulo 12: Mejora del servicio luis

Importante

Este capítulo es increíblemente importante y es posible que tenga que iterarse varias veces, ya que ayudará a mejorar la precisión del servicio luis: asegúrese de completarlo.

Para mejorar el nivel de comprensión proporcionado por LUIS, debe capturar nuevas expresiones y usarlas para volver a entrenar la aplicación de LUIS.

Por ejemplo, es posible que haya entrenado a LUIS para comprender "Aumentar" y "Upsize", pero ¿no desea que la aplicación también comprenda palabras como "Ampliar"?

Una vez que haya usado la aplicación varias veces, LUIS recopilará todo lo que ha dicho y estará disponible en el PORTAL de LUIS.

  1. Vaya a la aplicación del portal siguiendo este vínculo e inicie sesión.

  2. Una vez que haya iniciado sesión con sus credenciales de MS, haga clic en el nombre de la aplicación.

  3. Haga clic en el botón Revisar expresiones de punto de conexión a la izquierda de la página.

    Revisión de expresiones

  4. Se le mostrará una lista de las expresiones enviadas a LUIS por la aplicación de realidad mixta.

    Lista de expresiones

Observará algunas entidades resaltadas.

Al mantener el puntero sobre cada palabra resaltada, puede revisar cada expresión y determinar qué entidad se ha reconocido correctamente, qué entidades son incorrectas y qué entidades se pierden.

En el ejemplo anterior, se encontró que la palabra "lanza" se había resaltado como destino, por lo que es necesario corregir el error, que se hace al mantener el puntero sobre la palabra con el mouse y hacer clic en Quitar etiqueta.

Comprobar expresionesQuitar imagen de etiqueta

  1. Si encuentra expresiones completamente incorrectas, puede eliminarlas mediante el botón Eliminar en el lado derecho de la pantalla.

    Eliminación de expresiones incorrectas

  2. O bien, si cree que LUIS ha interpretado correctamente la expresión, puede validar su comprensión mediante el botón Agregar a intención alineada .

    Agregar a la intención alineada

  3. Una vez que haya ordenado todas las expresiones mostradas, pruebe y vuelva a cargar la página para ver si hay más disponibles.

  4. Es muy importante repetir este proceso tantas veces como sea posible para mejorar la comprensión de la aplicación.

¡Que te diviertas!

La aplicación integrada de LUIS finalizada

Enhorabuena, ha creado una aplicación de realidad mixta que aprovecha Azure Language Understanding Intelligence Service, para comprender lo que dice un usuario y actuar sobre esa información.

Resultado del laboratorio

Ejercicios extra

Ejercicio 1

Mientras usa esta aplicación, es posible que observe que si observa el objeto Floor y le pide que cambie su color, lo hará. ¿Puede averiguar cómo impedir que la aplicación cambie el color de piso?

Ejercicio 2

Intente ampliar las funcionalidades de LUIS y Aplicación, agregando funcionalidad adicional para los objetos de la escena; Por ejemplo, cree nuevos objetos en el punto de acierto de mirada, en función de lo que diga el usuario y, a continuación, pueda usar esos objetos junto con los objetos de escena actuales, con los comandos existentes.