HoloLens (1ª geração) e Azure 303: LUIS (Reconhecimento de Linguagem Natural)
Observação
Os tutoriais do Mixed Reality Academy foram projetados com o HoloLens (1ª geração) e os headsets imersivos de realidade misturada em mente. Dessa forma, achamos que é importante continuar disponibilizando esses tutoriais para os desenvolvedores que ainda buscam obter diretrizes para o desenvolvimento visando esses dispositivos. Esses tutoriais não serão atualizados com os conjuntos de ferramentas mais recentes nem com as interações usadas para o HoloLens 2. Eles serão mantidos para continuar funcionando nos dispositivos compatíveis. Haverá uma nova série de tutoriais que serão postados no futuro que demonstrarão como desenvolver para o HoloLens 2. Este aviso será atualizado com um link para esses tutoriais quando eles forem postados.
Neste curso, você aprenderá a integrar o Reconhecimento vocal em um aplicativo de realidade misturada usando os Serviços Cognitivos do Azure, com a API de Reconhecimento vocal.
O LUIS (Reconhecimento vocal) é um serviço do Microsoft Azure, que fornece aos aplicativos a capacidade de entender a entrada do usuário, por exemplo, extraindo o que uma pessoa pode querer, em suas próprias palavras. Isso é obtido por meio 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 LUIS (Reconhecimento Vocal) do Azure.
Depois de concluir este curso, você terá um aplicativo de headset imersivo de realidade mista que poderá 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 LUIS (Serviço Inteligente de Reconhecimento Vocal) do Azure.
- Faça com que o LUIS extraia o significado das informações de envio, que serão analisadas, e a tentativa de determinar a intenção da solicitação do usuário será feita.
O desenvolvimento incluirá a criação de um aplicativo onde o usuário poderá usar a voz e/ou o olhar para alterar o tamanho e a cor dos objetos na cena. O uso de controladores de movimento não será coberto.
Em sua aplicação, cabe a você como integrará os resultados ao seu design. Este curso foi desenvolvido para ensinar como integrar um Serviço do Azure ao seu projeto do Unity. É seu trabalho usar o conhecimento adquirido com este curso para aprimorar seu aplicativo de realidade misturada.
Esteja preparado para treinar o LUIS várias vezes, o que é abordado no Capítulo 12. Você obterá melhores resultados quanto mais vezes o LUIS tiver sido treinado.
Suporte a dispositivos
Curso | HoloLens | Headsets imersivos |
---|---|---|
MR e Azure 303: LUIS (Reconhecimento de Linguagem Natural) | ✔️ | ✔️ |
Observação
Embora este curso se concentre principalmente em headsets imersivos (VR) do Windows Mixed Reality, você também pode aplicar o que aprendeu neste curso ao Microsoft HoloLens. Ao acompanhar o curso, você verá anotações sobre as alterações que talvez precise empregar para dar suporte ao HoloLens. Ao usar o HoloLens, você pode observar algum eco durante a captura de voz.
Pré-requisitos
Observação
Este tutorial foi desenvolvido para desenvolvedores que têm experiência básica com Unity e C#. Esteja ciente também de que os pré-requisitos e as 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 softwares mais recentes do que os listados abaixo.
Recomendamos o seguinte hardware e software para este curso:
- Um computador de desenvolvimento, compatível com Windows Mixed Reality para desenvolvimento de headset imersivo (VR)
- Windows 10 Fall Creators Update (ou posterior) com o modo de desenvolvedor habilitado
- O SDK mais recente do Windows 10
- Unidade 2017.4
- Visual Studio 2017
- Um headset imersivo (VR) Windows Mixed Reality ou Microsoft HoloLens com o modo Desenvolvedor habilitado
- Um conjunto de fones de ouvido com microfone embutido (se o fone de ouvido não tiver microfone e alto-falantes embutidos)
- Acesso à Internet para configuração do Azure e recuperação do LUIS
Antes de começar
Para evitar 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 no momento da compilação).
Para permitir que sua máquina habilite o Ditado, vá para Configurações > > do Windows Privacidade Fala, Tinta e Digitação e pressione o botão Ativar serviços de fala e sugestões de digitação.
O código neste tutorial permitirá que você grave a partir do dispositivo de microfone padrão definido em sua máquina. Certifique-se de que o dispositivo de microfone padrão esteja definido como o que você deseja usar para capturar sua voz.
Se o fone de ouvido tiver um microfone interno, verifique se a opção "Quando eu usar meu fone de ouvido, alternar para o microfone do fone de ouvido" está ativada nas configurações do Portal de Realidade Misturada.
Capítulo 1 – Configurar o Portal do Azure
Para usar o serviço de Reconhecimento vocal no Azure, você precisará configurar uma instância do serviço a ser disponibilizada para seu aplicativo.
Faça logon no Portal do Azure.
Observação
Se você ainda não tiver uma conta do Azure, precisará criar uma. Se você estiver seguindo este tutorial em uma sala de aula ou laboratório, peça ajuda ao seu instrutor ou a um dos supervisores para configurar sua nova conta.
Depois de fazer login, clique em Novo no canto superior esquerdo, procure por Reconhecimento vocal e clique em Enter.
Observação
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 Reconhecimento vocal. Na parte inferior esquerda desta página, selecione o botão Criar para criar uma instância desse serviço.
Depois de clicar em Criar:
Insira o Nome desejado para esta instância de serviço.
Selecione uma Assinatura.
Selecione o Tipo de Preço apropriado para você, se esta for a primeira vez que cria um Serviço LUIS, uma camada gratuita (chamada F0) deverá 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 você quiser ler mais sobre os Grupos de Recursos do Azure, visite o artigo do grupo de recursos.
Determine o Local do seu grupo de recursos (se você estiver criando um novo Grupo de Recursos). O local seria idealmente 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 entendeu 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 será exibida 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 o recurso na notificação para explorar sua nova instância de serviço. Você será levado para sua nova instância de serviço do LUIS.
Neste tutorial, seu aplicativo precisará fazer chamadas para seu serviço, o que é feito usando a Chave de Assinatura do serviço.
Na página Início rápido do serviço de API do LUIS, navegue até a primeira etapa, Pegue suas chaves e clique em Chaves (você também pode fazer isso clicando no hiperlink azul Chaves, localizado no menu de navegação de serviços, indicado pelo ícone de chave). Isso revelará suas chaves de serviço.
Faça uma cópia de uma das chaves exibidas, pois você precisará dela mais tarde em seu projeto.
Na página Serviço, clique em Portal de Reconhecimento Vocal para ser redirecionado para a página da Web que você usará para criar seu novo Serviço, dentro do Aplicativo LUIS.
Capítulo 2 – O Portal de Reconhecimento Vocal
Nesta seção, você aprenderá a criar um aplicativo LUIS no Portal do LUIS.
Importante
Lembre-se de que a configuração de Entidades, Intenções e Enunciados neste capítulo é apenas a primeira etapa na criação do serviço LUIS: você também precisará treinar novamente o serviço, várias vezes, para torná-lo mais preciso. O treinamento de seu serviço é abordado no último capítulo deste curso, portanto, certifique-se de concluí-lo.
Ao acessar o Portal de Reconhecimento Vocal, talvez seja necessário fazer logon, se ainda não estiver, com as mesmas credenciais do portal do Azure.
Se esta for a primeira vez que você usa o LUIS, você precisará rolar para baixo até a parte inferior da página de boas-vindas para localizar e clicar no botão Criar aplicativo LUIS.
Depois de fazer login, clique em Meus aplicativos (se você não estiver nessa seção no momento). Você pode então clicar em Criar novo aplicativo.
Dê um Nome para o aplicativo.
Se o 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 Concluído, você entrará na página Compilar do seu novo aplicativo LUIS .
Existem alguns conceitos importantes para entender aqui:
- Intenção, representa o método que será chamado após uma consulta do usuário. Um INTENT pode ter uma ou mais ENTIDADES.
- Entidade, é um componente da consulta que descreve informações relevantes para o INTENT.
- Enunciados, são exemplos de consultas fornecidas pelo desenvolvedor, que o LUIS usará para treinar a si mesmo.
Se esses conceitos não estiverem perfeitamente claros, não se preocupe, pois este curso irá esclarecê-los ainda mais neste capítulo.
Você começará criando as Entidades necessárias para criar 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 esse processo para criar mais três (3) Entidades Simples denominadas:
- upsize
- Reduzir
- destino
O resultado deve ser semelhante à imagem abaixo:
Neste ponto, você pode começar a criar intenções.
Aviso
Não exclua a intenção None .
No lado esquerdo da página, clique em Intenções e, em seguida, clique em Criar nova intent.
Chame a nova intenção de ChangeObjectColor.
Importante
Esse nome de intenção é usado no código posteriormente 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.
Observação
O LUIS converte todos os enunciados em letras 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 criado, 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 todas as referências possíveis 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 vermelho 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 'this', 'it' e 'this object', que estamos fornecendo, para ter tipos de destino 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.
Dica
Ao selecionar palavras para rotulá-las como entidades:
- Para palavras isoladas, basta clicar nelas.
- Para um conjunto de duas ou mais palavras, clique no início e depois no final do conjunto.
Observação
Você pode usar o botão de alternância Visualização de Tokens para alternar entre a Visualização de Entidades/Tokens!
Os resultados devem ser como vistos nas imagens abaixo, mostrando a Visualização de Entidades/Tokens:
Neste ponto, pressione o botão Treinar no canto superior direito da página e espere que o pequeno indicador redondo fique verde. Isso indica que o LUIS foi treinado com êxito para reconhecer essa Intenção.
Como um exercício para você, crie uma nova Intent chamada ChangeObjectSize, usando o destino, upsize e downsize de Entities.
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 PUBLICAR na parte superior da página.
Na página Publicar, você finalizará e publicará seu aplicativo LUIS para que ele possa ser acessado pelo seu código.
Defina o menu suspenso 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 seção Recursos e chaves:
- Selecione a região definida para a 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 ao criar sua instância de Serviço. Se o portal do Azure e do LUIS estiver conectado 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 fornecido anteriormente no portal do Azure.
Importante
Abaixo de Endpoint, faça uma cópia do endpoint correspondente à chave que você inseriu, em breve você a usará em seu código.
Capítulo 3 – Configurar o projeto Unity
A seguir está uma configuração típica para desenvolvimento com a realidade misturada e, como tal, é um bom modelo para outros projetos.
Abra o Unity e clique em Novo.
Agora você precisará fornecer um nome de projeto do Unity e inserir MR_LUIS. Certifique-se de que o tipo de projeto esteja definido como 3D. Defina o local para algum lugar apropriado para você (lembre-se, mais perto dos 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 Script Externo para Visual Studio 2017. Feche a janela Preferências.
Em seguida, vá para Configurações de Build de Arquivo > e alterne a plataforma para Plataforma Universal do Windows, clicando no botão Alternar Plataforma.
Vá para Configurações de Build de Arquivo > e certifique-se de que:
O dispositivo de destino está definido como Qualquer dispositivo
Para o Microsoft HoloLens, defina Dispositivo de Destino como HoloLens.
O Tipo de Construção está definido como D3D
O SDK está definido como Instalado mais recente
A versão do Visual Studio está definida como Mais recente instalado
Build and Run está definido como Computador Local
Salve a cena e adicione-a à compilação.
Faça isso selecionando Adicionar cenas abertas. Uma janela de salvamento aparecerá.
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 como 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 Build, devem ser deixadas como padrão por enquanto.
Na janela Configurações de construçã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 tempo de execução de script deve ser estável (equivalente ao .NET 3.5).
O back-end de script deve ser .NET
O nível de compatibilidade da API deve ser .NET 4.6
Na guia Configurações de Publicação, em Recursos, marque:
InternetClient
Microfone
Mais abaixo no painel, em Configurações XR (encontradas abaixo de Configurações de Publicação), marque Realidade Virtual com Suporte, verifique se o SDK do Windows Mixed Reality foi adicionado.
De volta às configurações de compilação Os projetos do Unity C# não estão mais esmaecidos; marque a caixa de seleção ao lado dela.
Feche a janela Configurações de Build.
Salve sua cena e projeto (FILE > SAVE SCENE / FILE > SAVE PROJECT).
Capítulo 4 – Crie a cena
Importante
Se você quiser ignorar o componente de configuração do Unity deste curso e continuar direto para o código, sinta-se à vontade para baixar este .unitypackage, importá-lo para o seu projeto como um pacote personalizado e 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 você ainda tiver o último objeto selecionado, o objeto selecionado será o pai do novo objeto. Evite clicar com o botão esquerdo em um espaço vazio dentro da hierarquia e, em seguida, clicar com o botão direito do mouse.
Repita o procedimento acima para adicionar os seguintes objetos:
- Esfera
- Cilindro
- Cube
- Texto 3D
A hierarquia da cena resultante deve ser como a da imagem abaixo:
Clique com o botão esquerdo na Câmera Principal para selecioná-la, olhe para o Painel Inspetor e você verá o objeto Câmera com todos os seus componentes.
Clique no botão Adicionar componente localizado na parte inferior do painel Inspetor.
Procure o componente chamado Fonte de áudio, conforme mostrado acima.
Certifique-se também de que o componente Transform da câmera principal esteja definido como (0,0,0), isso pode ser feito pressionando o ícone de engrenagem ao lado do componente Transform da câmera e selecionando Redefinir. O componente Transform deve ter a seguinte aparência:
- A posição é definida como 0, 0, 0.
- A rotação é definida como 0, 0, 0.
Observação
Para o Microsoft HoloLens, você também precisará alterar o seguinte, que faz parte do componente Câmera , que está em sua Câmera Principal:
- Bandeiras Claras: Cor Sólida.
- Plano de fundo 'Preto, Alfa 0' – Cor hexadecimal: #00000000.
Clique com o botão esquerdo no plano 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 Novo texto 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 Malha de texto para Texto de ditado.
Sua estrutura do Painel de Hierarquia agora deve ter esta aparência:
A cena final deve ser parecida 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 Behaviors e, por último, a classe Gaze (sinta-se à vontade para criar tudo isso agora, embora seja abordado à medida que você chegar a cada capítulo).
A classe MicrophoneManager é responsável por:
- Detectando 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 string.
- Depois que a voz for pausada, envie o ditado para a classe LuisManager .
Para criar essa classe:
Clique com o botão direito do mouse no painel Projeto, Criar > pasta. Chame a pasta de Scripts.
Com a pasta Scripts criada, clique duas vezes nela para abri-la. Em seguida, dentro dessa pasta, clique com o botão direito do mouse em Criar > Script C#. Nomeie o script como 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. Eles serão chamados quando a classe for inicializada:
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 for pausada. 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.
Observação
Neste ponto, você notará um erro aparecendo no painel do console do Unity Editor. 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 você criar a classe LuisManager , que fará a chamada para o serviço LUIS do Azure.
A finalidade dessa classe é receber o texto de ditado da classe MicrophoneManager e enviá-lo para a API de Reconhecimento Vocal do Azure para ser analisado.
Essa classe desserializará a resposta JSON e chamará os métodos apropriados da classe Behaviours para acionar uma ação.
Para criar essa 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ão 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 seu ponto de extremidade do LUIS agora (que você terá no portal do LUIS).
O código para o método Awake() agora precisa ser adicionado. Este método será chamado quando a classe for inicializada:
private void Awake() { // allows this class instance to behave like a singleton instance = this; }
Agora você precisa dos métodos que esse aplicativo usa para enviar o ditado recebido da classe MicrophoneManager para o LUIS e, em seguida, receber e desserializar a resposta.
Depois que o valor da Intenção e das Entidades associadas forem determinados, eles serão passados 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 AnalysedQuery resultante e determinará as entidades. Depois que essas Entidades forem determinadas, elas serão passadas para a instância da classe Behaviours para uso 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 esta classe não os usará.
Certifique-se de salvar suas alterações no Visual Studio antes de retornar ao Unity.
Observação
Neste ponto, você notará vários erros aparecendo no painel do console do Unity Editor. 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 Behaviors
A classe Behaviors acionará as ações usando as Entidades fornecidas pela classe LuisManager .
Para criar essa 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 for inicializada:
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 do Intent atual. Esse método padroniza o destino para o GameObject que está sendo "gazed" 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 esta 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 Gaze
A última aula que você precisará para concluir este aplicativo é a classe Gaze . Essa 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 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 – Completando a configuração da cena
Para concluir a configuração da cena, arraste cada script criado da Pasta Scripts para o objeto Câmera principal no Painel de hierarquia.
Selecione a câmera principal e olhe para o painel do inspetor, você poderá ver cada script anexado e notará que existem parâmetros em cada script que ainda não foram definidos.
Para definir esses parâmetros corretamente, siga estas instruções:
Gerenciador de microfone:
- No Painel de hierarquia, arraste o objeto Texto de ditado para a caixa de valor do parâmetro Texto de ditado.
Comportamentos, no Painel de Hierarquia:
- Arraste o objeto Esfera para a caixa Destino de referência da Esfera .
- Arraste o Cilindro para a caixa Destino de referência do Cilindro .
- Arraste o Cubo para a caixa 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 ser semelhante à imagem abaixo:
Capítulo 10 – Teste no Editor do Unity
Teste se a configuração da cena está implementada corretamente.
Verifique se:
- Todos os scripts são anexados ao objeto Main Camera .
- Todos os campos no Painel Inspetor de Câmera Principal são atribuídos corretamente.
Pressione o botão Reproduzir no Editor do Unity. O aplicativo deve estar em execução no headset imersivo conectado.
Experimente alguns enunciados, como:
make the cylinder red change the cube to yellow I want the sphere blue make this to green change it to white
Observação
Se você vir um erro no console do Unity sobre a alteração do dispositivo de áudio padrão, a cena pode não funcionar conforme o esperado. Isso se deve à maneira como o portal de realidade misturada lida com microfones internos para fones de ouvido que os possuem. Se você vir esse erro, simplesmente pare a cena e reinicie-a e as coisas devem funcionar conforme o esperado.
Capítulo 11 – Criar e fazer sideload da solução UWP
Depois de garantir que o aplicativo esteja funcionando no Unity Editor, você estará pronto para criar e implantar.
Para construir:
Salve a cena atual clicando em Salvar arquivo>.
Vá para Configurações de Build de Arquivo>.
Marque a caixa chamada Projetos C# do Unity (ú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 Construir.
Você será solicitado a selecionar a pasta onde deseja 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.
Depois que o Unity terminar de compilar (pode levar algum tempo), ele deverá abrir uma janela do Explorador de Arquivos no local da compilação.
Para implantar no computador local:
No Visual Studio, abra o arquivo de solução que foi criado no capítulo anterior.
Na Plataforma de Solução, selecione x86, Computador Local.
Na Configuração da Solução, selecione Depurar.
Para o Microsoft HoloLens, talvez seja mais fácil definir isso como Computador Remoto, para que você não fique preso ao computador. No entanto, você também precisará fazer o seguinte:
- Conheça o endereço IP do HoloLens, que pode ser encontrado nas Configurações > Opções avançadas de Wi-Fi > de rede e Internet>; o IPv4 é o endereço que você deve usar.
- Certifique-se de que o Modo de desenvolvedor esteja ativado; encontrado em Atualização de configurações > e segurança > Para desenvolvedores.
Vá para o menu Compilar e clique em Implantar Solução para fazer o sideload do aplicativo em seu computador.
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 – Melhorando 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 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 "Upsizing", mas não gostaria que seu aplicativo também entendesse palavras como "Ampliar"?
Depois de usar seu aplicativo algumas vezes, tudo o que você disse será coletado pelo LUIS e disponibilizado no PORTAL do LUIS.
Vá para o aplicativo do portal seguindo este LINK e faça login.
Depois de fazer login com suas credenciais MS, clique no nome do seu aplicativo.
Clique no botão Revisar enunciados de ponto de extremidade à esquerda da página.
Você verá uma lista dos Enunciados que foram enviados ao LUIS pelo seu aplicativo de realidade misturada.
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 estão ausentes.
No exemplo acima, verificou-se que a palavra "lança" havia sido destacada como alvo, por isso é necessário corrigir o erro, o que é feito passando o mouse sobre a palavra e clicando em Remover rótulo.
Se você encontrar Enunciados completamente errados, poderá excluí-los usando o botão Excluir no lado direito da tela.
Ou, se você achar que o LUIS interpretou o Enunciado corretamente, poderá validar sua compreensão 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 esse processo quantas vezes for possível para melhorar a compreensão do seu aplicativo.
Divertir-se!
Seu aplicativo integrado LUIS concluído
Parabéns, você criou um aplicativo de realidade misturada que aproveita o Serviço de Inteligência de Reconhecimento Vocal 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 olhar para o objeto Floor e pedir para alterar sua cor, ele o fará. Você consegue descobrir como impedir que seu aplicativo mude a cor do piso?
Exercício 2
Tente estender os recursos do LUIS e do aplicativo, adicionando funcionalidade adicional para objetos na cena; por exemplo, crie novos objetos no ponto de ocorrência do Gaze, dependendo do que o usuário disser, e então poderá usar esses objetos junto com os objetos de cena atuais, com os comandos existentes.