HoloLens (1.ª geração) e Azure 303: Compreensão de linguagem natural (LUIS)
Nota
Os tutoriais da Academia de Realidade Mista foram projetados com HoloLens (1ª geração) e Headsets Imersivos de Realidade Mista em mente. Como tal, sentimos que é importante deixar estes tutoriais no lugar para desenvolvedores que ainda estão procurando orientação no desenvolvimento para esses dispositivos. Esses tutoriais não serão atualizados com os conjuntos de ferramentas ou interações mais recentes que estão sendo usados para o HoloLens 2. Eles serão mantidos para continuar trabalhando nos dispositivos suportados. Haverá uma nova série de tutoriais que serão publicados no futuro que demonstrarão como desenvolver para o HoloLens 2. Este aviso será atualizado com um link para esses tutoriais quando eles forem publicados.
Neste curso, você aprenderá como integrar o Entendimento de Idiomas em um aplicativo de realidade mista usando os Serviços Cognitivos do Azure, com a API de Compreensão de Idiomas.
Language Understanding (LUIS) é um serviço do Microsoft Azure, que fornece aplicativos com a capacidade de fazer significado da entrada do usuário, como através da extração do que uma pessoa pode querer, em suas próprias palavras. Isso é conseguido através do aprendizado de máquina, que entende e aprende as informações de entrada e, em seguida, pode responder com informações detalhadas e relevantes. Para obter mais informações, visite a página Azure Language Understanding (LUIS).
Tendo concluído este curso, você terá um aplicativo de fone de ouvido imersivo de realidade mista que será capaz de fazer o seguinte:
- Capture a fala de entrada do usuário, usando o microfone conectado ao fone de ouvido imersivo.
- Envie o ditado capturado para o Serviço Inteligente de Compreensão de Linguagem do Azure (LUIS).
- Faça com que o LUIS extraia o significado das informações enviadas, que serão analisadas, e tente determinar a intenção do pedido do usuário será feita.
O desenvolvimento incluirá a criação de um aplicativo onde o usuário poderá usar voz e/ou olhar para alterar o tamanho e a cor dos objetos na cena. A utilização de controladores de movimento não será abrangida.
Na sua aplicação, cabe-lhe a si decidir como irá integrar os resultados com o seu design. Este curso foi criado para ensiná-lo a integrar um Serviço do Azure ao seu Projeto Unity. É seu trabalho usar o conhecimento que você ganha com este curso para melhorar sua aplicação de realidade mista.
Esteja preparado para treinar LUIS várias vezes, o que é abordado no Capítulo 12. Você obterá melhores resultados quanto mais vezes o LUIS tiver sido treinado.
Suporte de dispositivos
Curso | HoloLens | Auriculares imersivos |
---|---|---|
MR e Azure 303: Compreensão de linguagem natural (LUIS) | ✔️ | ✔️ |
Nota
Embora este curso se concentre principalmente em fones de ouvido imersivos (VR) do Windows Mixed Reality, você também pode aplicar o que aprendeu neste curso ao Microsoft HoloLens. À medida que você acompanha o curso, você verá anotações sobre quaisquer alterações que você possa precisar empregar para dar suporte ao HoloLens. Ao utilizar o HoloLens, poderá notar algum eco durante a captura de voz.
Pré-requisitos
Nota
Este tutorial foi projetado para desenvolvedores que têm experiência básica com Unity e C#. Por favor, esteja ciente de que os pré-requisitos e instruções escritas neste documento representam o que foi testado e verificado no momento da redação (maio de 2018). Você é livre para usar o software mais recente, conforme listado no artigo instalar as ferramentas , embora não se deva presumir que as informações neste curso corresponderão perfeitamente ao que você encontrará em software mais recente do que o listado abaixo.
Recomendamos o seguinte hardware e software para este curso:
- Um PC de desenvolvimento, compatível com Windows Mixed Reality para desenvolvimento imersivo (VR) de auriculares
- Windows 10 Fall Creators Update (ou posterior) com o modo de desenvolvedor ativado
- O SDK mais recente do Windows 10
- Unidade 2017.4
- Visual Studio 2017
- Um auricular imersivo (VR) Windows Mixed Reality ou Microsoft HoloLens com o modo de programador ativado
- Um conjunto de auscultadores com microfone incorporado (se o auricular não tiver um microfone e altifalantes incorporados)
- Acesso à Internet para configuração do Azure e recuperação de LUIS
Antes de começar
Para evitar encontrar problemas ao criar este projeto, é altamente recomendável que você crie o projeto mencionado neste tutorial em uma pasta raiz ou quase raiz (caminhos de pasta longos podem causar problemas em tempo de compilação).
Para permitir que a sua máquina ative o Ditado, aceda a Definições do > Windows Privacidade > Fala, Escrita à tinta e Digitação e prima o botão Ativar serviços de voz e sugestões de escrita.
O código neste tutorial permitirá que você grave a partir do dispositivo de microfone padrão definido em sua máquina. Verifique se o dispositivo de microfone padrão está definido como aquele que você deseja usar para capturar sua voz.
Se o auricular tiver um microfone incorporado, certifique-se de que a opção "Quando usar o auricular, mude para o microfone do auricular" está ativada nas definições do Portal de Realidade Mista.
Capítulo 1 – Configurar o Portal do Azure
Para usar o serviço de Compreensão de Idiomas no Azure, você precisará configurar uma instância do serviço a ser disponibilizada para seu aplicativo.
Inicie sessão no Portal do Azure.
Nota
Se ainda não tiver uma conta do Azure, terá de criar uma. Se você estiver seguindo este tutorial em uma situação de sala de aula ou laboratório, peça ajuda ao seu instrutor ou a um dos proctors para configurar sua nova conta.
Depois de iniciar sessão, clique em Novo no canto superior esquerdo, procure Compreensão de Línguas e clique em Enter.
Nota
A palavra Novo pode ter sido substituída por Criar um recurso, em portais mais recentes.
A nova página à direita fornecerá uma descrição do serviço de Compreensão de Línguas. No canto inferior esquerdo desta página, selecione o botão Criar para criar uma instância deste serviço.
Depois de clicar em Criar:
Insira o Nome desejado para esta instância de serviço.
Selecione uma Subscrição.
Selecione o Nível de Preço apropriado para você, se esta for a primeira vez que cria um Serviço LUIS, um nível gratuito (chamado F0) deve estar disponível para você. A atribuição gratuita deve ser mais do que suficiente para este curso.
Escolha um Grupo de Recursos ou crie um novo. Um grupo de recursos fornece uma maneira de monitorar, controlar o acesso, provisionar e gerenciar a cobrança de uma coleção de ativos do Azure. É recomendável manter todos os serviços do Azure associados a um único projeto (por exemplo, como esses cursos) em um grupo de recursos comum).
Se desejar ler mais sobre os Grupos de Recursos do Azure, visite o artigo do grupo de recursos.
Determine a Localização do seu grupo de recursos (se estiver a criar um novo Grupo de Recursos). O ideal seria que o local fosse na região onde o aplicativo seria executado. Alguns ativos do Azure só estão disponíveis em determinadas regiões.
Você também precisará confirmar que compreendeu os Termos e Condições aplicados a este Serviço.
Selecione Criar.
Depois de clicar em Criar, você terá que esperar que o serviço seja criado, isso pode levar um minuto.
Uma notificação aparecerá no portal assim que a instância de serviço for criada.
Clique na notificação para explorar sua nova instância de serviço.
Clique no botão Ir para recurso na notificação para explorar sua nova instância de serviço. Você será levado para sua nova instância de serviço LUIS.
Dentro deste tutorial, seu aplicativo precisará fazer chamadas para o seu serviço, o que é feito usando a Chave de Assinatura do seu serviço.
Na página Início rápido , do seu serviço API LUIS , navegue até a primeira etapa, Pegue suas chaves e clique em Chaves (você também pode fazer isso clicando nas teclas de hiperlink azul, localizadas no menu de navegação de serviços, indicado pelo ícone de chave). Isso revelará suas chaves de serviço.
Tire uma cópia de uma das chaves exibidas, pois você precisará disso mais tarde em seu projeto.
Na página Serviço, clique em Language Understanding Portal para ser redirecionado para a página web que irá utilizar para criar o seu novo Serviço, dentro da App LUIS.
Capítulo 2 – O Portal de Compreensão de Línguas
Nesta secção irá aprender a fazer uma App LUIS no Portal LUIS.
Importante
Por favor, esteja ciente de que configurar as Entidades, Intenções e Declarações neste capítulo é apenas o primeiro passo na construção do seu serviço LUIS: você também precisará treinar novamente o serviço, várias vezes, para torná-lo mais preciso. A reciclagem do seu serviço é abordada no último capítulo deste curso, portanto, certifique-se de concluí-lo.
Ao chegar ao Portal de Compreensão de Idiomas, talvez seja necessário fazer login, se ainda não estiver, com as mesmas credenciais do seu portal do Azure.
Se esta é a sua primeira vez usando o LUIS, você precisará rolar para baixo até a parte inferior da página de boas-vindas, para encontrar e clicar no botão Criar aplicativo LUIS.
Depois de fazer login, clique em Meus aplicativos (se você não estiver nessa seção atualmente). Em seguida, você pode clicar em Criar novo aplicativo.
Dê um nome ao seu aplicativo.
Se o seu aplicativo deve entender um idioma diferente do inglês, você deve alterar a Cultura para o idioma apropriado.
Aqui você também pode adicionar uma descrição do seu novo aplicativo LUIS.
Depois de pressionar Done, você entrará na página Build do seu novo aplicativo LUIS .
Existem alguns conceitos importantes para entender aqui:
- Intent, representa o método que será chamado após uma consulta do usuário. Uma intenção pode ter uma ou mais ENTIDADES.
- Entidade, é um componente da consulta que descreve informações relevantes para a INTENT.
- Enunciados, são exemplos de consultas fornecidas pelo desenvolvedor, que o LUIS usará para se treinar.
Se esses conceitos não estiverem perfeitamente claros, não se preocupe, pois este curso irá esclarecê-los mais detalhadamente neste capítulo.
Você começará criando as Entidades necessárias para construir este curso.
No lado esquerdo da página, clique em Entidades e, em seguida, clique em Criar nova entidade.
Chame a nova cor da entidade, defina seu tipo como Simples e pressione Concluído.
Repita este processo para criar mais três (3) Entidades Simples nomeadas:
- tamanho superior
- redução do tamanho
- público-alvo
O resultado deve ficar parecido com a imagem abaixo:
Neste ponto, você pode começar a criar Intents.
Aviso
Não exclua a intenção Nenhum .
No lado esquerdo da página, clique em Intenções e, em seguida, clique em Criar nova intenção.
Chame a nova intenção de ChangeObjectColor.
Importante
Esse nome de intenção é usado dentro do código mais adiante neste curso, portanto, para obter melhores resultados, use esse nome exatamente como fornecido.
Depois de confirmar o nome, você será direcionado para a Página de Intenções.
Você notará que há uma caixa de texto solicitando que você digite 5 ou mais Enunciados diferentes.
Nota
LUIS converte todos os enunciados em minúsculas.
- Insira o seguinte Enunciado na caixa de texto superior (atualmente com o texto Digite cerca de 5 exemplos... ) e pressione Enter:
The color of the cylinder must be red
Você notará que o novo Enunciado aparecerá em uma lista abaixo.
Seguindo o mesmo processo, insira os seguintes seis (6) Enunciados:
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 Enunciado que você criou, você deve identificar quais palavras devem ser usadas pelo LUIS como Entidades. Neste exemplo, você precisa rotular todas as cores como uma Entidade de cor e toda a referência possível a um destino como uma Entidade de destino .
Para fazer isso, tente clicar na palavra cilindro no primeiro Enunciado e selecione o destino.
Agora clique na palavra vermelha no primeiro Enunciado e selecione a cor.
Rotule a próxima linha também, onde cubo deve ser um alvo, e preto deve ser uma cor. Observe também o uso das palavras 'isto', 'ele' e 'este objeto', que estamos fornecendo, para ter tipos de alvos não específicos disponíveis também.
Repita o processo acima até que todos os Enunciados tenham as Entidades rotuladas. Veja a imagem abaixo se precisar de ajuda.
Gorjeta
Ao selecionar palavras para rotulá-las como entidades:
- Para palavras simples, basta clicar nelas.
- Para um conjunto de duas ou mais palavras, clique no início e, em seguida, no final do conjunto.
Nota
Você pode usar o botão de alternância Tokens View para alternar entre Entities / Tokens View!
Os resultados devem ser como visto nas imagens abaixo, mostrando a visualização de Entidades/Tokens:
Neste ponto, pressione o botão Train no canto superior direito da página e aguarde até que o pequeno indicador redondo fique verde. Isso indica que o LUIS foi treinado com sucesso para reconhecer essa intenção.
Como um exercício para você, crie uma nova intenção chamada ChangeObjectSize, usando o destino Entidades, upsize e downsize.
Seguindo o mesmo processo da intenção anterior, insira os seguintes oito (8) Enunciados para alteração de tamanho :
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
O resultado deve ser como o da imagem abaixo:
Depois que ambas as intenções, ChangeObjectColor e ChangeObjectSize, tiverem sido criadas e treinadas, clique no botão PUBLISH na parte superior da página.
Na página Publicar irá finalizar e publicar a sua App LUIS para que possa ser acedida pelo seu código.
Defina a lista suspensa Publicar em como produção.
Defina o fuso horário para o seu fuso horário.
Marque a caixa Incluir todas as pontuações de intenção previstas.
Clique em Publicar no slot de produção.
Na secção Recursos e Chaves:
- Selecione a região definida para instância de serviço no Portal do Azure.
- Você notará um elemento Starter_Key abaixo, ignore-o.
- Clique em Adicionar chave e insira a chave que você obteve no Portal do Azure quando criou sua instância de serviço. Se o seu Azure e o portal LUIS estiverem conectados ao mesmo usuário, você receberá menus suspensos para Nome do locatário, Nome da assinatura e a chave que deseja usar (terá o mesmo nome que você forneceu anteriormente no Portal do Azure.
Importante
Abaixo do Endpoint, pegue uma cópia do endpoint correspondente à chave que você inseriu, você logo a usará em seu código.
Capítulo 3 – Criar o projeto Unity
O seguinte é uma configuração típica para desenvolver com a realidade mista e, como tal, é um bom modelo para outros projetos.
Abra o Unity e clique em Novo.
Agora você precisará fornecer um nome de Projeto Unity, inserir MR_LUIS. Verifique se o tipo de projeto está definido como 3D. Defina o Local para algum lugar apropriado para você (lembre-se, mais perto de diretórios raiz é melhor). Em seguida, clique em Criar projeto.
Com o Unity aberto, vale a pena verificar se o Editor de Scripts padrão está definido como Visual Studio. Vá para Editar > Preferências e, na nova janela, navegue até Ferramentas Externas. Altere o Editor de Scripts Externo para Visual Studio 2017. Feche a janela Preferências .
Em seguida, vá para Configurações de compilação de arquivos > e mude a plataforma para a Plataforma Universal do Windows, clicando no botão Alternar plataforma.
Vá para Configurações de compilação de arquivo > e certifique-se de que:
O Dispositivo de Destino está definido como Qualquer Dispositivo
Para o Microsoft HoloLens, defina Target Device como HoloLens.
O tipo de compilação está definido como D3D
O SDK está definido como Instalado mais recente
Versão do Visual Studio está definida como A versão mais recente instalada
Build and Run está definido como Máquina Local
Salve a cena e adicione-a à compilação.
Faça isso selecionando Adicionar cenas abertas. Será exibida uma janela de salvamento.
Crie uma nova pasta para esta e qualquer cena futura e, em seguida, selecione o botão Nova pasta , para criar uma nova pasta, nomeie-a Cenas.
Abra a pasta Cenas recém-criada e, no campo de texto Nome do arquivo:, digite MR_LuisScene e pressione Salvar.
As configurações restantes, em Configurações de compilação, devem ser deixadas como padrão por enquanto.
Na janela Configurações de compilação, clique no botão Configurações do player, isso abrirá o painel relacionado no espaço onde o inspetor está localizado.
Neste painel, algumas configurações precisam ser verificadas:
Na guia Outras configurações:
A versão do Scripting Runtime deve ser estável (equivalente ao .NET 3.5).
O back-end de scripts deve ser .NET
O nível de compatibilidade da API deve ser .NET 4.6
Na guia Configurações de publicação , em Recursos, verifique:
InternetClient
Microfone
Mais abaixo no painel, em Configurações XR (encontradas abaixo de Configurações de publicação), marque Realidade Virtual suportada, verifique se o SDK de realidade mista do Windows foi adicionado.
De volta às configurações de compilação, o Unity C# Projects não está mais acinzentado, marque a caixa de seleção ao lado disso.
Feche a janela Configurações de compilação.
Salve sua cena e projeto (FILE > SAVE SCENE / FILE > SAVE PROJECT).
Capítulo 4 – Criar a cena
Importante
Se você deseja pular o componente Unity set deste curso e continuar direto no código, sinta-se à vontade para baixar este .unitypackage, importá-lo para seu projeto como um pacote personalizado e, em seguida, continuar a partir do Capítulo 5.
Clique com o botão direito do mouse em uma área vazia do Painel de Hierarquia, em Objeto 3D, adicione um Plano.
Lembre-se de que, quando você clicar com o botão direito do mouse na Hierarquia novamente para criar mais objetos, se ainda tiver o último objeto selecionado, o objeto selecionado será o pai do novo objeto. Evite clicar com o botão esquerdo do rato num espaço vazio dentro da Hierarquia e, em seguida, clique com o botão direito do rato.
Repita o procedimento acima para adicionar os seguintes objetos:
- Esfera
- Cilindro
- Cubo
- Texto 3D
A cena resultante Hierarquia deve ser como a da imagem abaixo:
Clique com o botão esquerdo na câmera principal para selecioná-lo, olhe para o painel do inspetor você verá o objeto da câmera com todos os seus componentes.
Clique no botão Adicionar componente localizado na parte inferior do Painel do inspetor.
Procure o componente chamado Fonte de áudio, como mostrado acima.
Certifique-se também de que o componente Transformar da câmera principal está definido como (0,0,0), isso pode ser feito pressionando o ícone de engrenagem ao lado do componente Transformar da câmera e selecionando Redefinir. O componente Transformar deve então ter a seguinte aparência:
- A posição é definida como 0, 0, 0.
- A rotação é definida como 0, 0, 0.
Nota
Para o Microsoft HoloLens, você também precisará alterar o seguinte, que fazem parte do componente Câmera , que está na sua câmera principal:
- Clear Flags: Cor sólida.
- Fundo 'Preto, Alpha 0' – Cor hexadecimal: #00000000.
Clique com o botão esquerdo no avião para selecioná-lo. No painel Inspetor, defina o componente Transformar com os seguintes valores:
Eixo X Eixo Y Eixo Z 0 -1 0 Clique com o botão esquerdo na esfera para selecioná-la. No painel Inspetor, defina o componente Transformar com os seguintes valores:
Eixo X Eixo Y Eixo Z 2 1 2 Clique com o botão esquerdo no cilindro para selecioná-lo. No painel Inspetor, defina o componente Transformar com os seguintes valores:
Eixo X Eixo Y Eixo Z -2 1 2 Clique com o botão esquerdo no cubo para selecioná-lo. No painel Inspetor, defina o componente Transformar com os seguintes valores:
Transformar - Posição
X | Y | Z |
---|---|---|
0 | 1 | 4 |
Transformar - Rotação
X | Y | Z |
---|---|---|
45 | 45 | 0 |
- Clique com o botão esquerdo no objeto New Text para selecioná-lo. No painel Inspetor, defina o componente Transformar com os seguintes valores:
Transformar - Posição
X | Y | Z |
---|---|---|
-2 | 6 | 9 |
Transformar - Escala
X | Y | Z |
---|---|---|
0.1 | 0.1 | 0.1 |
Altere o tamanho da fonte no componente Malha de texto para 50.
Altere o nome do objeto Text Mesh para Dictation Text.
Sua estrutura do Painel de Hierarquia agora deve ter esta aparência:
A cena final deve se parecer com a imagem abaixo:
Capítulo 5 – Criar a classe MicrophoneManager
O primeiro Script que você vai criar é a classe MicrophoneManager . Depois disso, você criará o LuisManager, a classe Behaviours e, por último, a classe Gaze (sinta-se à vontade para criar tudo isso agora, embora ela seja abordada à medida que você chegar a cada Capítulo).
A classe MicrophoneManager é responsável por:
- Detetar o dispositivo de gravação conectado ao fone de ouvido ou à máquina (o que for o padrão).
- Capture o áudio (voz) e use o ditado para armazená-lo como uma cadeia de caracteres.
- Uma vez pausada a voz, envie o ditado para a classe LuisManager .
Para criar esta classe:
Clique com o botão direito do mouse no Painel Projeto, Criar > pasta. Chame a pasta Scripts.
Com a pasta Scripts criada, clique duas vezes nela para abrir. Em seguida, dentro dessa pasta, clique com o botão direito do mouse em Criar > script C#. Nomeie o script MicrophoneManager.
Clique duas vezes em MicrophoneManager para abri-lo com o Visual Studio.
Adicione os seguintes namespaces à parte superior do arquivo:
using UnityEngine; using UnityEngine.Windows.Speech;
Em seguida, adicione as seguintes variáveis dentro da classe 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
O código para os métodos Awake() e Start() agora precisa ser adicionado. Estes serão chamados quando a classe inicializar:
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"); } }
Agora você precisa do método que o aplicativo usa para iniciar e parar a captura de voz, e passá-lo para a classe LuisManager , que você criará em breve.
/// <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..."); }
Adicione um manipulador de ditado que será invocado quando a voz pausar. Esse método passará o texto do ditado para a classe 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
Exclua o método Update(), pois essa classe não o usará.
Certifique-se de salvar suas alterações no Visual Studio antes de retornar ao Unity.
Nota
Neste ponto, você notará um erro aparecendo no Painel do Console do Editor Unity. Isso ocorre porque o código faz referência à classe LuisManager que você criará no próximo capítulo.
Capítulo 6 – Criar a classe LUISManager
É hora de criar a classe LuisManager , que fará a chamada para o serviço LUIS do Azure.
O objetivo dessa classe é receber o texto de ditado da classe MicrophoneManager e enviá-lo para a API de Compreensão de Linguagem do Azure para ser analisado.
Essa classe desserializará a resposta JSON e chamará os métodos apropriados da classe Behaviours para disparar uma ação.
Para criar esta classe:
Clique duas vezes na pasta Scripts para abri-la.
Clique com o botão direito do mouse dentro da pasta Scripts , clique em Criar > script C#. Nomeie o script LuisManager.
Clique duas vezes no script para abri-lo com o Visual Studio.
Adicione os seguintes namespaces à parte superior do arquivo:
using System; using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; using UnityEngine.Networking;
Você começará criando três classes dentro da classe LuisManager (dentro do mesmo arquivo de script, acima do método Start()) que representará a resposta JSON desserializada do 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; }
Em seguida, adicione as seguintes variáveis dentro da classe 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";
Certifique-se de colocar o seu endpoint LUIS agora (que você terá do seu portal LUIS).
O código para o método Awake() agora precisa ser adicionado. Este método será chamado quando a classe inicializar:
private void Awake() { // allows this class instance to behave like a singleton instance = this; }
Agora você precisa dos métodos que este aplicativo usa para enviar o ditado recebido da classe MicrophoneManager para LUIS e, em seguida, receber e desserializar a resposta.
Uma vez determinado o valor da Intenção e das Entidades associadas, elas são passadas para a instância da classe Behaviours para acionar a ação pretendida.
/// <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; } }
Crie um novo método chamado AnalyseResponseElements() que lerá o resultado AnalysedQuery e determinará as Entidades. Uma vez que essas Entidades sejam determinadas, elas serão passadas para a instância da classe Behaviours para usar nas ações.
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
Exclua os métodos Start() e Update(), pois essa classe não os usará.
Certifique-se de salvar suas alterações no Visual Studio antes de retornar ao Unity.
Nota
Neste ponto, você notará vários erros aparecendo no Painel do Console do Editor Unity. Isso ocorre porque o código faz referência à classe Behaviours que você criará no próximo capítulo.
Capítulo 7 – Criar a classe Comportamentos
A classe Behaviours acionará as ações usando as Entidades fornecidas pela classe LuisManager .
Para criar esta classe:
Clique duas vezes na pasta Scripts para abri-la.
Clique com o botão direito do mouse dentro da pasta Scripts , clique em Criar > script C#. Nomeie o script como Comportamentos.
Clique duas vezes no script para abri-lo com o Visual Studio.
Em seguida, adicione as seguintes variáveis dentro da classe Behaviours :
public static Behaviours instance; // the following variables are references to possible targets public GameObject sphere; public GameObject cylinder; public GameObject cube; internal GameObject gazedTarget;
Adicione o código do método Awake( ). Este método será chamado quando a classe inicializar:
void Awake() { // allows this class instance to behave like a singleton instance = this; }
Os métodos a seguir são chamados pela classe LuisManager (que você criou anteriormente) para determinar qual objeto é o destino da consulta e, em seguida, disparar a ação apropriada.
/// <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); }
Adicione o método FindTarget() para determinar qual dos GameObjects é o destino da intenção atual. Esse método padroniza o destino para o GameObject que está sendo "olhado" se nenhum destino explícito for definido nas 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
Exclua os métodos Start() e Update(), pois essa classe não os usará.
Certifique-se de salvar suas alterações no Visual Studio antes de retornar ao Unity.
Capítulo 8 – Criar a Classe do Olhar
A última classe que você precisará para completar este aplicativo é a classe Gaze . Esta classe atualiza a referência ao GameObject atualmente no foco visual do usuário.
Para criar esta classe:
Clique duas vezes na pasta Scripts para abri-la.
Clique com o botão direito do mouse dentro da pasta Scripts , clique em Criar > script C#. Nomeie o script como Gaze.
Clique duas vezes no script para abri-lo com o Visual Studio.
Insira o seguinte código para esta classe:
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; } } }
Certifique-se de salvar suas alterações no Visual Studio antes de retornar ao Unity.
Capítulo 9 – Concluindo a configuração da cena
Para concluir a configuração da cena, arraste cada script que você criou da pasta Scripts para o objeto Main Camera no painel Hierarchy.
Selecione a câmera principal e olhe para o painel do inspetor, você deve ser capaz de ver cada script que você anexou, e você vai notar que há parâmetros em cada script que ainda estão a ser definidos.
Para definir esses parâmetros corretamente, siga estas instruções:
MicrofoneManager:
- No Painel Hierarquia, arraste o objeto Texto de Ditado para a caixa Valor do parâmetro Texto de Ditado.
Comportamentos, do Painel de Hierarquia:
- Arraste o objeto Sphere para a caixa de destino de referência Sphere .
- Arraste o cilindro para a caixa de destino de referência do cilindro .
- Arraste o cubo para a caixa de destino de referência do cubo.
Olhar:
- Defina a distância máxima do olhar para 300 (se ainda não estiver).
O resultado deve ficar parecido com a imagem abaixo:
Capítulo 10 – Teste no Editor Unity
Teste se a configuração do Scene está implementada corretamente.
Certifique-se de que:
- Todos os scripts são anexados ao objeto Main Camera .
- Todos os campos no painel principal do inspetor da câmera são atribuídos corretamente.
Pressione o botão Reproduzir no Editor Unity. O aplicativo deve ser executado dentro do fone de ouvido imersivo conectado.
Tente alguns enunciados, tais como:
make the cylinder red change the cube to yellow I want the sphere blue make this to green change it to white
Nota
Se você vir um erro no console Unity sobre a alteração do dispositivo de áudio padrão, a cena pode não funcionar conforme o esperado. Isso se deve à forma como o portal de realidade mista lida com microfones embutidos para fones de ouvido que os possuem. Se você vir esse erro, basta parar a cena e iniciá-la novamente e as coisas devem funcionar como esperado.
Capítulo 11 – Criar e fazer sideload da solução UWP
Depois de garantir que o aplicativo está funcionando no Editor Unity, você estará pronto para criar e implantar.
Para construir:
Salve a cena atual clicando em Salvar arquivo>.
Vá para Configurações de compilação de arquivo>.
Marque a caixa chamada Projetos Unity C# ( útil para ver e depurar seu código depois que o projeto UWP for criado.
Clique em Adicionar cenas abertas e, em seguida, clique em Compilar.
Ser-lhe-á pedido para selecionar a pasta onde pretende criar a Solução.
Crie uma pasta BUILDS e dentro dessa pasta crie outra pasta com um nome apropriado de sua escolha.
Clique em Selecionar pasta para iniciar a compilação nesse local.
Quando o Unity terminar de construir (pode levar algum tempo), ele deve abrir uma janela do Explorador de Arquivos no local da sua compilação.
Para implantar na máquina local:
No Visual Studio, abra o arquivo de solução que foi criado no capítulo anterior.
Na Plataforma de Solução, selecione x86, Máquina Local.
Na Configuração da Solução, selecione Depurar.
Para o Microsoft HoloLens, você pode achar mais fácil definir isso como Máquina Remota, para que você não esteja preso ao seu computador. No entanto, você também precisará fazer o seguinte:
- Conheça o endereço IP do seu HoloLens, que pode ser encontrado nas Configurações > de Rede e Opções Avançadas de Wi-Fi > da Internet>, o IPv4 é o endereço que você deve usar.
- Verifique se o Modo de Desenvolvedor está Ativado, encontrado em Atualização de Configurações > e Segurança > para desenvolvedores.
Vá para o menu Build e clique em Deploy Solution para fazer sideload do aplicativo para sua máquina.
Seu aplicativo agora deve aparecer na lista de aplicativos instalados, pronto para ser iniciado!
Uma vez iniciado, o aplicativo solicitará que você autorize o acesso ao microfone. Use os controladores de movimento, a entrada de voz ou o teclado para pressionar o botão SIM .
Capítulo 12 – Melhorar o seu serviço LUIS
Importante
Este capítulo é incrivelmente importante e pode precisar ser repetido várias vezes, pois ajudará a melhorar a precisão do seu serviço LUIS: certifique-se de concluir isso.
Para melhorar o nível de compreensão fornecido pelo LUIS você precisa capturar novos enunciados e usá-los para treinar novamente seu aplicativo LUIS.
Por exemplo, você pode ter treinado o LUIS para entender "Aumentar" e "Aumentar", mas não gostaria que seu aplicativo também entendesse palavras como "Ampliar"?
Depois de ter utilizado a sua aplicação algumas vezes, tudo o que disse será recolhido pelo LUIS e disponibilizado no PORTAL LUIS.
Vá para o aplicativo do seu portal seguindo este LINK e faça login.
Depois de iniciar sessão com as suas credenciais MS, clique no nome da sua aplicação.
Clique no botão Revisar declarações do ponto de extremidade à esquerda da página.
Ser-lhe-á mostrada uma lista dos Enunciados que foram enviados para o LUIS pela sua Aplicação de realidade mista.
Você notará algumas Entidades destacadas.
Ao passar o mouse sobre cada palavra realçada, você pode revisar cada Enunciado e determinar qual Entidade foi reconhecida corretamente, quais Entidades estão erradas e quais Entidades foram perdidas.
No exemplo acima, verificou-se que a palavra "lança" havia sido destacada como alvo, por isso foi necessário corrigir o erro, o que é feito passando o mouse sobre a palavra e clicando em Remover Rótulo.
Se você encontrar Enunciados que estão completamente errados, você pode excluí-los usando o botão Excluir no lado direito da tela.
Ou se você achar que o LUIS interpretou o enunciado corretamente, você pode validar seu entendimento usando o botão Adicionar à intenção alinhada .
Depois de classificar todos os Enunciados exibidos, tente recarregar a página para ver se há mais disponíveis.
É muito importante repetir este processo o maior número de vezes possível para melhorar a compreensão da sua aplicação.
Divertir-se!
A sua aplicação LUIS integrada concluída
Parabéns, você criou um aplicativo de realidade mista que aproveita o Serviço de Inteligência de Compreensão de Linguagem do Azure para entender o que um usuário diz e agir com base nessas informações.
Exercícios de bónus
Exercício 1
Ao usar este aplicativo, você pode notar que, se você olhar para o objeto Floor e pedir para mudar sua cor, ele o fará. Você consegue descobrir como impedir que seu aplicativo altere a cor do piso?
Exercício 2
Tente estender os recursos do LUIS e do aplicativo, adicionando funcionalidade adicional para objetos em cena; como exemplo, crie novos objetos no ponto de acerto do Olhar, dependendo do que o usuário diz, e então seja capaz de usar esses objetos ao lado de objetos de cena atuais, com os comandos existentes.