HoloLens (1. generace) a Azure 312: Integrace robotů
Poznámka:
Kurzy Mixed Reality Academy byly navrženy s HoloLensem (1. generace) a imerzivními náhlavními soupravami hybridní reality. Proto máme pocit, že je důležité nechat tyto kurzy zavedené pro vývojáře, kteří stále hledají pokyny při vývoji těchto zařízení. Tyto kurzy nebudou aktualizovány nejnovějšími sadami nástrojů ani interakcemi používanými pro HoloLens 2. Budou zachovány, aby pokračovaly v práci na podporovaných zařízeních. Bude k dispozici nová série kurzů, které budou publikovány v budoucnu, které předvádějí, jak vyvíjet pro HoloLens 2. Toto oznámení se při publikování aktualizuje odkazem na tyto kurzy.
V tomto kurzu se dozvíte, jak vytvořit a nasadit robota pomocí rozhraní Microsoft Bot Framework V4 a komunikovat s ním prostřednictvím aplikace Windows Mixed Reality.
Microsoft Bot Framework V4 je sada rozhraní API navržená tak, aby vývojářům poskytovala nástroje pro vytvoření rozšiřitelné a škálovatelné aplikace robota. Další informace najdete na stránce Microsoft Bot Framework nebo v4 úložišti Git.
Po dokončení tohoto kurzu budete mít vytvořenou aplikaci Windows Mixed Reality, která bude moct provést následující akce:
- Pomocí gesta klepnutím spusťte robota, který naslouchá hlasu uživatelů.
- Když uživatel něco řekl, robot se pokusí poskytnout odpověď.
- Zobrazí roboty odpověď jako text umístěný u robota ve scéně Unity.
V aplikaci je na vás, jak integrovat výsledky s návrhem. Tento kurz je navržený tak, aby vás naučil, jak integrovat službu Azure s projektem Unity. Vaším úkolem je využít znalosti získané z tohoto kurzu k vylepšení aplikace hybridní reality.
Podpora zařízení
Kurz | HoloLens | Imerzivní náhlavní soupravy |
---|---|---|
MR a Azure 312: Integrace robota | ✔️ | ✔️ |
Poznámka:
I když se tento kurz primárně zaměřuje na HoloLens, můžete také použít to, co se v tomto kurzu naučíte, na imerzivní náhlavní soupravy Windows Mixed Reality (VR). Vzhledem k tomu, že imerzivní náhlavní soupravy (VR) nemají přístupné kamery, budete potřebovat externí kameru připojenou k počítači. Jak budete postupovat podle kurzu, uvidíte poznámky o všech změnách, které možná budete muset použít pro podporu imerzivních náhlavních souprav (VR).
Požadavky
Poznámka:
Tento kurz je určený pro vývojáře, kteří mají základní zkušenosti s Unity a C#. Mějte také na paměti, že požadavky a písemné pokyny v tomto dokumentu představují to, co bylo otestováno a ověřeno v době psaní (červenec 2018). Můžete používat nejnovější software, jak je uvedeno v článku o instalaci nástrojů , i když by se nemělo předpokládat, že informace v tomto kurzu budou dokonale odpovídat tomu, co najdete v novějším softwaru, než je uvedeno níže.
Pro tento kurz doporučujeme následující hardware a software:
- Vývojový počítač kompatibilní s Windows Mixed Reality pro vývoj imerzivních náhlavních souprav (VR)
- Windows 10 Fall Creators Update (nebo novější) s povoleným režimem vývojáře
- Nejnovější sada Windows 10 SDK
- Unity 2017.4
- Visual Studio 2017
- Imerzivní náhlavní souprava Windows Mixed Reality (VR) nebo Microsoft HoloLens s povoleným režimem vývojáře
- Přístup k internetu pro Azure a načítání robota Azure. Další informace najdete na tomto odkazu.
Než začnete
- Abyste se vyhnuli problémům při sestavování tohoto projektu, důrazně doporučujeme vytvořit projekt uvedený v tomto kurzu v kořenové nebo téměř kořenové složce (dlouhé cesty ke složkám můžou způsobovat problémy v době sestavení).
- Nastavte a otestujte HoloLens. Pokud potřebujete podporu k nastavení HoloLens, nezapomeňte navštívit článek o nastavení HoloLens.
- Při vývoji nové aplikace HoloLens je vhodné provést kalibraci a ladění senzorů (někdy může pomoct tyto úlohy provádět pro každého uživatele).
Nápovědu k kalibraci najdete v tomto odkazu na článek o kalibraci HoloLens.
Nápovědu k ladění senzorů najdete v tomto odkazu na článek o ladění snímačů HoloLens.
Kapitola 1 – Vytvoření aplikace robota
Prvním krokem je vytvoření robota jako místní webové aplikace ASP.Net Core. Jakmile ho dokončíte a otestujete, publikujete ho na webu Azure Portal.
Otevřete sadu Visual Studio. Vytvořte nový projekt, jako typ projektu vyberte webovou aplikaci ASP NET Core (najdete ji pod pododdílem .NET Core) a pojmenujte ji MyBot. Klikněte na OK.
V okně, které se zobrazí, vyberte Prázdné. Také se ujistěte, že cíl je nastavený na ASP NET Core 2.0 a ověřování je nastavené na Žádné ověřování. Klikněte na OK.
Řešení se teď otevře. Klikněte pravým tlačítkem na řešení Mybot v Průzkumník řešení a klikněte na Spravovat balíčky NuGet pro řešení.
Na kartě Procházet vyhledejte Microsoft.Bot.Builder.Integration.AspNet.Core (ujistěte se, že máte zaškrtnuté předběžné verze). Vyberte balíček verze 4.0.1-preview a zaškrtněte políčka projektu. Potom klikněte na Nainstalovat. Teď jste nainstalovali knihovny potřebné pro bot Framework verze 4. Zavřete stránku NuGet.
V Průzkumník řešení klikněte pravým tlačítkem na projekt, MyBot a klikněte na Přidat | třídu.
Pojmenujte třídu MyBot a klikněte na Přidat.
Opakujte předchozí bod a vytvořte další třídu s názvem ConversationContext.
Klikněte pravým tlačítkem myši na wwwroot v Průzkumník řešení a klikněte na Přidat | novou položku. Vyberte stránku HTML (najdete ji pod pododdílem Web). Pojmenujte soubor default.html. Klikněte na tlačítko Přidat.
Seznam tříd / objektů v Průzkumník řešení by měl vypadat jako na obrázku níže.
Poklikejte na třídu ConversationContext . Tato třída zodpovídá za uchovávání proměnných používaných robotem k udržování kontextu konverzace. Tyto hodnoty kontextu konverzace jsou zachovány v instanci této třídy, protože každá instance třídy MyBot se aktualizuje při každém přijetí aktivity. Do třídy přidejte následující kód:
namespace MyBot { public static class ConversationContext { internal static string userName; internal static string userMsg; } }
Poklikejte na třídu MyBot . Tato třída bude hostovat obslužné rutiny volané všemi příchozími aktivitami od zákazníka. V této třídě přidáte kód použitý k sestavení konverzace mezi robotem a zákazníkem. Jak už bylo zmíněno dříve, instance této třídy se inicializuje při každém přijetí aktivity. Do této třídy přidejte následující kód:
using Microsoft.Bot; using Microsoft.Bot.Builder; using Microsoft.Bot.Schema; using System.Threading.Tasks; namespace MyBot { public class MyBot : IBot { public async Task OnTurn(ITurnContext context) { ConversationContext.userMsg = context.Activity.Text; if (context.Activity.Type is ActivityTypes.Message) { if (string.IsNullOrEmpty(ConversationContext.userName)) { ConversationContext.userName = ConversationContext.userMsg; await context.SendActivity($"Hello {ConversationContext.userName}. Looks like today it is going to rain. \nLuckily I have umbrellas and waterproof jackets to sell!"); } else { if (ConversationContext.userMsg.Contains("how much")) { if (ConversationContext.userMsg.Contains("umbrella")) await context.SendActivity($"Umbrellas are $13."); else if (ConversationContext.userMsg.Contains("jacket")) await context.SendActivity($"Waterproof jackets are $30."); else await context.SendActivity($"Umbrellas are $13. \nWaterproof jackets are $30."); } else if (ConversationContext.userMsg.Contains("color") || ConversationContext.userMsg.Contains("colour")) { await context.SendActivity($"Umbrellas are black. \nWaterproof jackets are yellow."); } else { await context.SendActivity($"Sorry {ConversationContext.userName}. I did not understand the question"); } } } else { ConversationContext.userMsg = string.Empty; ConversationContext.userName = string.Empty; await context.SendActivity($"Welcome! \nI am the Weather Shop Bot \nWhat is your name?"); } } } }
Poklikejte na třídu Startup . Tato třída inicializuje robota. Do třídy přidejte následující kód:
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Bot.Builder.BotFramework; using Microsoft.Bot.Builder.Integration.AspNet.Core; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; namespace MyBot { public class Startup { public IConfiguration Configuration { get; } public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) .AddEnvironmentVariables(); Configuration = builder.Build(); } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddSingleton(_ => Configuration); services.AddBot<MyBot>(options => { options.CredentialProvider = new ConfigurationCredentialProvider(Configuration); }); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseDefaultFiles(); app.UseStaticFiles(); app.UseBotFramework(); } } }
Otevřete soubor třídy Program a ověřte, že kód je stejný jako následující:
using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; namespace MyBot { public class Program { public static void Main(string[] args) { BuildWebHost(args).Run(); } public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .Build(); } }
Nezapomeňte uložit změny, abyste to udělali, přejděte na Soubor>Uložit vše na panelu nástrojů v horní části sady Visual Studio.
Kapitola 2 – Vytvoření služby Azure Bot Service
Teď, když jste vytvořili kód robota, musíte ho publikovat do instance služby Web App Bot Service na webu Azure Portal. V této kapitole se dozvíte, jak vytvořit a nakonfigurovat službu Bot Service v Azure a pak do ní publikovat svůj kód.
Nejprve se přihlaste k webu Azure Portal (https://portal.azure.com).
- Pokud ještě nemáte účet Azure, budete ho muset vytvořit. Pokud tento kurz sledujete v situaci v učebně nebo testovacím prostředí, požádejte svého instruktora nebo některého z proktorů, aby vám pomohli nastavit nový účet.
Po přihlášení klikněte v levém horním rohu na Vytvořit prostředek a vyhledejte robota webové aplikace a klikněte na Enter.
Na nové stránce se zobrazí popis služby Web App Bot Service. V levém dolním rohu této stránky vyberte tlačítko Vytvořit a vytvořte přidružení k této službě.
Po kliknutí na Vytvořit:
Vložte požadovaný název pro tuto instanci služby.
Vyberte nějaké předplatné.
Zvolte skupinu prostředků nebo vytvořte novou. Skupina prostředků poskytuje způsob, jak monitorovat, řídit přístup, zřizovat a spravovat fakturaci pro kolekci prostředků Azure. Doporučujeme zachovat všechny služby Azure přidružené k jednomu projektu (např. tyto kurzy) v rámci společné skupiny prostředků).
Pokud si chcete přečíst další informace o skupinách prostředků Azure, postupujte podle tohoto odkazu.
Určete umístění vaší skupiny prostředků (pokud vytváříte novou skupinu prostředků). Umístění by ideálně bylo v oblasti, ve které by aplikace běžela. Některé prostředky Azure jsou dostupné jenom v určitých oblastech.
Vyberte cenovou úroveň, která je pro vás vhodná, pokud se jedná o první vytvoření služby Web App Bot Service, měla by vám být k dispozici bezplatná úroveň (s názvem F0).
Název aplikace může zůstat stejný jako název robota.
Ponechte šablonu robota jako základní (C#).
Plán služby App Service / umístění by měl být automaticky vyplněný pro váš účet.
Nastavte službu Azure Storage, kterou chcete použít k hostování robota. Pokud ho ještě nemáte, můžete ho tady vytvořit.
Budete také muset potvrdit, že jste porozuměli podmínkám a ujednáním použitým pro tuto službu.
Klikněte na Vytvořit.
Jakmile kliknete na Vytvořit, budete muset počkat, až se služba vytvoří, může to chvíli trvat.
Po vytvoření instance služby se na portálu zobrazí oznámení.
Kliknutím na oznámení můžete prozkoumat novou instanci služby.
Kliknutím na tlačítko Přejít k prostředku v oznámení můžete prozkoumat novou instanci služby. Přejdete do nové instance služby Azure.
V tomto okamžiku musíte nastavit funkci s názvem Direct Line , která klientské aplikaci umožní komunikovat s touto službou Bot Service. Klikněte na Kanály a potom v části Přidat doporučený kanál klikněte na Konfigurovat kanál Direct Line.
Na této stránce najdete tajné klíče , které umožní klientské aplikaci ověřit pomocí robota. Klikněte na tlačítko Zobrazit a pořídit kopii jednoho ze zobrazených klíčů, protože to budete potřebovat později v projektu.
Kapitola 3 – Publikování robota do služby Azure Web App Bot Service
Teď, když je vaše služba připravená, musíte publikovat kód robota, který jste vytvořili dříve, do nově vytvořené služby Web App Bot Service.
Poznámka:
Robota budete muset publikovat do služby Azure Pokaždé, když provedete změny řešení robota nebo kódu.
Vraťte se k dříve vytvořenému řešení sady Visual Studio.
Klikněte pravým tlačítkem myši na projekt MyBot v Průzkumník řešení a potom klikněte na Publikovat.
Na stránce Vybrat cílovou stránku publikování klikněte na App Service a pak vyberte Existující a nakonec klikněte na Vytvořit profil (možná budete muset kliknout na šipku rozevíracího seznamu vedle tlačítka Publikovat, pokud to není vidět).
Pokud ještě nejste přihlášení ke svému účtu Microsoft, musíte to udělat tady.
Na stránce Publikovat zjistíte, že musíte nastavit stejné předplatné, které jste použili k vytvoření služby Web App Bot Service. Potom nastavte zobrazení jako skupinu prostředků a v rozevírací struktuře složek vyberte skupinu prostředků, kterou jste vytvořili dříve. Klikněte na OK.
Teď klikněte na tlačítko Publikovat a počkejte, až se robot publikuje (může to trvat několik minut).
Kapitola 4 – Nastavení projektu Unity
Následuje typická sada pro vývoj s hybridní realitou a jako taková je vhodná šablona pro jiné projekty.
Otevřete Unity a klikněte na Nový.
Teď budete muset zadat název projektu Unity. Vložení robota HoloLens Ujistěte se, že je šablona projektu nastavená na 3D. Nastavte umístění na místo, které je pro vás vhodné (nezapomeňte, že blíže ke kořenovým adresářům je lepší). Potom klikněte na Vytvořit projekt.
Při otevření Unity stojí za to zkontrolovat, jestli je výchozí editor skriptů nastavený na Visual Studio. Přejděte na Upravit předvolby a pak v novém okně přejděte na Externí nástroje. > Změňte editor externích skriptů na Visual Studio 2017. Zavřete okno Předvolby.
Dále přejděte do Nastavení sestavení souboru > a vyberte Univerzální platforma Windows a kliknutím na tlačítko Přepnout platformu použijte svůj výběr.
Zůstaňte v nastavení sestavení souboru > a ujistěte se, že:
Cílové zařízení je nastavené na HoloLens.
U imerzivních náhlavních souprav nastavte cílové zařízení na libovolné zařízení.
Typ sestavení je nastavený na D3D.
Sada SDK je nastavená na nejnovější nainstalovanou verzi.
Verze sady Visual Studio je nastavená na nejnovější nainstalovanou verzi.
Sestavení a spuštění je nastavené na místní počítač.
Uložte scénu a přidejte ji do sestavení.
Uděláte to tak, že vyberete Přidat otevřené scény. Zobrazí se okno pro uložení.
Vytvořte novou složku pro tuto a jakoukoli budoucí scénu a pak vyberte tlačítko Nová složka a vytvořte novou složku, pojmenujte ji Scény.
Otevřete nově vytvořenou složku Scény a potom v názvu souboru: textové pole, zadejte BotScene a klikněte na Uložit.
Zbývající nastavení v nastavení sestavení by teď měla zůstat ve výchozím nastavení.
V okně Nastavení sestavení klikněte na tlačítko Nastavení přehrávače, otevře se související panel v prostoru, kde se nachází inspektor.
Na tomto panelu je potřeba ověřit několik nastavení:
Na kartě Další nastavení:
Skriptovací verze modulu runtime by měla být experimentální (ekvivalent NET 4.6) a změna bude vyžadovat restartování editoru.
Back-end skriptování by měl být .NET.
Úroveň kompatibility rozhraní API by měla být .NET 4.6
Na kartě Nastavení publikování v části Možnosti zaškrtněte:
InternetClient
Mikrofon
Dále na panelu v nastavení XR (v části Nastavení publikování níže) zaškrtněte možnost Podpora virtuální reality a ujistěte se, že je přidaná sada SDK pro Windows Mixed Reality.
Zpět v projektech Unity Nastavení sestavení v jazyce C# se už nezobrazuje šedě. Zaškrtněte políčko vedle tohoto příkazu.
Zavřete okno Nastavení sestavení.
Uložte scénu a projekt (FILE SAVE SCENE / FILE > > SAVE PROJECT).
Kapitola 5 – Nastavení kamery
Důležité
Pokud chcete přeskočit komponentu Nastavení Unity v tomto kurzu a pokračovat přímo do kódu, můžete si stáhnout tuto sadu Azure-MR-312-Package.unitypackage, importovat ji do projektu jako vlastní balíček a pokračovat z kapitoly 7.
Na panelu Hierarchie vyberte hlavní kameru.
Po výběru uvidíte všechny součásti hlavní kamery na panelu inspektoru.
- Objekt Fotoaparát musí mít název Hlavní kamera (všimněte si pravopisu).
- Značka hlavní kamery musí být nastavená na MainCamera (všimněte si pravopisu).
- Ujistěte se, že je pozice transformace nastavená na hodnotu 0, 0, 0.
- Nastavte jasné příznaky na plnou barvu.
- Nastavte barvu pozadí komponenty Fotoaparát na Black, Alpha 0 (Šestnáctkový kód: #00000000)
Kapitola 6 – Import knihovny Newtonsoft
Pro usnadnění deserializace a serializace objektů přijatých a odesílaných do služby Bot Service, musíte stáhnout knihovnu Newtonsoft . Najdete tu kompatibilní verzi uspořádanou se správnou strukturou složek Unity.
Pokud chcete do projektu importovat knihovnu Newtonsoft, použijte balíček Unity, který byl součástí tohoto kurzu.
Přidejte do Unity balíček .unitypackage pomocí možnosti nabídky Vlastní balíček>importu prostředků.>
V okně Import Unity Package (Importovat balíček Unity), které se zobrazí, zkontrolujte, že je vybrané vše v části (a včetně) modulů plug-in.
Kliknutím na tlačítko Importovat přidáte položky do projektu.
Přejděte do složky Newtonsoft v části Moduly plug-in v zobrazení projektu a vyberte modul plug-in Newtonsoft.
Pokud je vybraný modul plug-in Newtonsoft, ujistěte se, že je nezaškrtnutá žádná platforma, a ujistěte se, že je také nezaškrtnutá možnost WSAPlayer, a klikněte na tlačítko Použít. Stačí jenom ověřit, že jsou soubory správně nakonfigurované.
Poznámka:
Označení těchto modulů plug-in konfiguruje jejich použití pouze v Unity Editoru. Ve složce WSA existuje jiná sada, která se použije po exportu projektu z Unity.
Dále musíte otevřít složku WSA v rámci složky Newtonsoft . Zobrazí se kopie stejného souboru, který jste právě nakonfigurovali. Vyberte soubor a pak v inspektoru zkontrolujte, že
- Libovolná platforma není zaškrtnutá.
- Je zaškrtnuto pouze WSAPlayer.
- Proces dont je zaškrtnutý.
Kapitola 7 – Vytvoření značky BotTag
Vytvořte nový objekt Tag s názvem BotTag. Vyberte hlavní kameru ve scéně. Na panelu inspektoru klikněte na rozevírací nabídku Značka. Klikněte na Přidat značku.
Klikněte na + symbol. Pojmenujte novou značku botTag a uložte ji.
Upozorňující
Nepoužívejte botTag na hlavní kameru. Pokud jste to omylem udělali, nezapomeňte změnit značku hlavní kamery zpět na MainCamera.
Kapitola 8 – Vytvoření třídy BotObjects
Prvním skriptem, který potřebujete vytvořit, je třída BotObjects , což je prázdná třída vytvořená tak, aby řada jiných objektů třídy byla uložena ve stejném skriptu a přístup k jiným skriptům ve scéně.
Vytvoření této třídy je čistě architektonické volby, tyto objekty mohou být hostovány ve skriptu robota, který vytvoříte později v tomto kurzu.
Vytvoření této třídy:
Klikněte pravým tlačítkem myši na panel Projekt a pak vytvořte > složku. Pojmenujte složky Skripty.
Poklikáním otevřete složku Skripty . Pak v této složce klikněte pravým tlačítkem myši a vyberte Vytvořit > skript jazyka C#. Pojmenujte skript BotObjects.
Poklikáním otevřete nový skript BotObjects pomocí sady Visual Studio.
Odstraňte obsah skriptu a nahraďte ho následujícím kódem:
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public class BotObjects : MonoBehaviour{} /// <summary> /// Object received when first opening a conversation /// </summary> [Serializable] public class ConversationObject { public string ConversationId; public string token; public string expires_in; public string streamUrl; public string referenceGrammarId; } /// <summary> /// Object including all Activities /// </summary> [Serializable] public class ActivitiesRootObject { public List<Activity> activities { get; set; } public string watermark { get; set; } } [Serializable] public class Conversation { public string id { get; set; } } [Serializable] public class From { public string id { get; set; } public string name { get; set; } } [Serializable] public class Activity { public string type { get; set; } public string channelId { get; set; } public Conversation conversation { get; set; } public string id { get; set; } public From from { get; set; } public string text { get; set; } public string textFormat { get; set; } public DateTime timestamp { get; set; } public string serviceUrl { get; set; } }
Než se vrátíte do Unity, nezapomeňte změny uložit v sadě Visual Studio.
Kapitola 9 – Vytvoření třídy GazeInput
Další třídou, kterou vytvoříte, je Třída GazeInput . Tato třída zodpovídá za:
- Vytvoření kurzoru , který bude představovat pohled hráče.
- Detekce objektů, které udeří pohledem hráče, a podržení odkazu na zjištěné objekty.
Vytvoření této třídy:
Přejděte do složky Scripts , kterou jste vytvořili dříve.
Klikněte pravým tlačítkem do složky a vytvořte > skript jazyka C#. Zavolejte skript GazeInput.
Poklikáním otevřete nový skript GazeInput v sadě Visual Studio.
Vložte následující řádek vpravo nad název třídy:
/// <summary> /// Class responsible for the User's gaze interactions /// </summary> [System.Serializable] public class GazeInput : MonoBehaviour
Pak do třídy GazeInput nad metodu Start() přidejte následující proměnné:
[Tooltip("Used to compare whether an object is to be interacted with.")] internal string InteractibleTag = "BotTag"; /// <summary> /// Length of the gaze /// </summary> internal float GazeMaxDistance = 300; /// <summary> /// Object currently gazed /// </summary> internal GameObject FocusedObject { get; private set; } internal GameObject _oldFocusedObject { get; private set; } internal RaycastHit HitInfo { get; private set; } /// <summary> /// Cursor object visible in the scene /// </summary> internal GameObject Cursor { get; private set; } internal bool Hit { get; private set; } internal Vector3 Position { get; private set; } internal Vector3 Normal { get; private set; } private Vector3 _gazeOrigin; private Vector3 _gazeDirection;
Měla by se přidat metoda Code for Start(). Tato možnost bude volána při inicializaci třídy:
/// <summary> /// Start method used upon initialization. /// </summary> internal virtual void Start() { FocusedObject = null; Cursor = CreateCursor(); }
Implementujte metodu, která vytvoří instanci a nastaví kurzor pohledu:
/// <summary> /// Method to create a cursor object. /// </summary> internal GameObject CreateCursor() { GameObject newCursor = GameObject.CreatePrimitive(PrimitiveType.Sphere); newCursor.SetActive(false); // Remove the collider, so it does not block Raycast. Destroy(newCursor.GetComponent<SphereCollider>()); newCursor.transform.localScale = new Vector3(0.05f, 0.05f, 0.05f); Material mat = new Material(Shader.Find("Diffuse")); newCursor.GetComponent<MeshRenderer>().material = mat; mat.color = Color.HSVToRGB(0.0223f, 0.7922f, 1.000f); newCursor.SetActive(true); return newCursor; }
Implementujte metody, které nastaví Raycast z hlavní kamery a budou sledovat aktuální prioritní objekt.
/// <summary> /// Called every frame /// </summary> internal virtual void Update() { _gazeOrigin = Camera.main.transform.position; _gazeDirection = Camera.main.transform.forward; UpdateRaycast(); } /// <summary> /// Reset the old focused object, stop the gaze timer, and send data if it /// is greater than one. /// </summary> private void ResetFocusedObject() { // Ensure the old focused object is not null. if (_oldFocusedObject != null) { if (_oldFocusedObject.CompareTag(InteractibleTag)) { // Provide the OnGazeExited event. _oldFocusedObject.SendMessage("OnGazeExited", SendMessageOptions.DontRequireReceiver); } } } private void UpdateRaycast() { // Set the old focused gameobject. _oldFocusedObject = FocusedObject; RaycastHit hitInfo; // Initialize Raycasting. Hit = Physics.Raycast(_gazeOrigin, _gazeDirection, out hitInfo, GazeMaxDistance); HitInfo = hitInfo; // Check whether raycast has hit. if (Hit == true) { Position = hitInfo.point; Normal = hitInfo.normal; // Check whether the hit has a collider. if (hitInfo.collider != null) { // Set the focused object with what the user just looked at. FocusedObject = hitInfo.collider.gameObject; } else { // Object looked on is not valid, set focused gameobject to null. FocusedObject = null; } } else { // No object looked upon, set focused gameobject to null. FocusedObject = null; // Provide default position for cursor. Position = _gazeOrigin + (_gazeDirection * GazeMaxDistance); // Provide a default normal. Normal = _gazeDirection; } // Lerp the cursor to the given position, which helps to stabilize the gaze. Cursor.transform.position = Vector3.Lerp(Cursor.transform.position, Position, 0.6f); // Check whether the previous focused object is this same. If so, reset the focused object. if (FocusedObject != _oldFocusedObject) { ResetFocusedObject(); if (FocusedObject != null) { if (FocusedObject.CompareTag(InteractibleTag)) { // Provide the OnGazeEntered event. FocusedObject.SendMessage("OnGazeEntered", SendMessageOptions.DontRequireReceiver); } } } }
Než se vrátíte do Unity, nezapomeňte změny uložit v sadě Visual Studio.
Kapitola 10 – Vytvoření třídy robota
Skript, který teď vytvoříte, se nazývá Robot. Toto je základní třída vaší aplikace, ve které se ukládá:
- Přihlašovací údaje robota webové aplikace
- Metoda, která shromažďuje uživatelské hlasové příkazy
- Metoda potřebná k zahájení konverzací s web app botem
- Metoda potřebná k odesílání zpráv do robota webové aplikace
Pokud chcete odesílat zprávy do služby Bot Service, korutin SendMessageToBot() sestaví aktivitu, což je objekt rozpoznaný službou Bot Framework jako data odesílaná uživatelem.
Vytvoření této třídy:
Poklikáním otevřete složku Skripty .
Klikněte pravým tlačítkem do složky Scripts (Skripty ) a klikněte na Create C# Script (Vytvořit > skript jazyka C#). Pojmenujte skript robota.
Poklikáním na nový skript ho otevřete v sadě Visual Studio.
Aktualizujte obory názvů tak, aby byly stejné jako v horní části třídy Robot :
using Newtonsoft.Json; using System.Collections; using System.Text; using UnityEngine; using UnityEngine.Networking; using UnityEngine.Windows.Speech;
Uvnitř třídy Bot přidejte následující proměnné:
/// <summary> /// Static instance of this class /// </summary> public static Bot Instance; /// <summary> /// Material of the sphere representing the Bot in the scene /// </summary> internal Material botMaterial; /// <summary> /// Speech recognizer class reference, which will convert speech to text. /// </summary> private DictationRecognizer dictationRecognizer; /// <summary> /// Use this variable to identify the Bot Id /// Can be any value /// </summary> private string botId = "MRBotId"; /// <summary> /// Use this variable to identify the Bot Name /// Can be any value /// </summary> private string botName = "MRBotName"; /// <summary> /// The Bot Secret key found on the Web App Bot Service on the Azure Portal /// </summary> private string botSecret = "-- Add your Secret Key here --"; /// <summary> /// Bot Endpoint, v4 Framework uses v3 endpoint at this point in time /// </summary> private string botEndpoint = "https://directline.botframework.com/v3/directline"; /// <summary> /// The conversation object reference /// </summary> private ConversationObject conversation; /// <summary> /// Bot states to regulate the application flow /// </summary> internal enum BotState {ReadyToListen, Listening, Processing} /// <summary> /// Flag for the Bot state /// </summary> internal BotState botState; /// <summary> /// Flag for the conversation status /// </summary> internal bool conversationStarted = false;
Poznámka:
Ujistěte se, že do proměnné botSecret vložíte tajný klíč robota. Na začátku tohoto kurzu jste si poznamenali tajný klíč robota v kapitole 2 kroku 10.
Teď je potřeba přidat kód pro Probuzené() a Start().
/// <summary> /// Called on Initialization /// </summary> void Awake() { Instance = this; } /// <summary> /// Called immediately after Awake method /// </summary> void Start() { botState = BotState.ReadyToListen; }
Přidejte dva obslužné rutiny, které volají knihovny řeči při zahájení a ukončení hlasového zachycení. DiktováníRecognizer automaticky zastaví zachytávání hlasu uživatele, když uživatel přestane mluvit.
/// <summary> /// Start microphone capture. /// </summary> public void StartCapturingAudio() { botState = BotState.Listening; botMaterial.color = Color.red; // Start dictation dictationRecognizer = new DictationRecognizer(); dictationRecognizer.DictationResult += DictationRecognizer_DictationResult; dictationRecognizer.Start(); } /// <summary> /// Stop microphone capture. /// </summary> public void StopCapturingAudio() { botState = BotState.Processing; dictationRecognizer.Stop(); }
Následující obslužná rutina shromažďuje výsledek uživatelského hlasového vstupu a volá korutin zodpovědný za odeslání zprávy do služby Web App Bot Service.
/// <summary> /// This handler is called every time the Dictation detects a pause in the speech. /// </summary> private void DictationRecognizer_DictationResult(string text, ConfidenceLevel confidence) { // Update UI with dictation captured Debug.Log($"User just said: {text}"); // Send dictation to Bot StartCoroutine(SendMessageToBot(text, botId, botName, "message")); StopCapturingAudio(); }
K zahájení konverzace s robotem se volá následující korutin. Všimněte si, že po dokončení hovoru konverzace bude volání SendMessageToCoroutine() předáním řady parametrů, které nastaví aktivitu, která se odešle do služby Bot Service jako prázdná zpráva. Tím se zobrazí výzva k zahájení dialogu službou Bot Service.
/// <summary> /// Request a conversation with the Bot Service /// </summary> internal IEnumerator StartConversation() { string conversationEndpoint = string.Format("{0}/conversations", botEndpoint); WWWForm webForm = new WWWForm(); using (UnityWebRequest unityWebRequest = UnityWebRequest.Post(conversationEndpoint, webForm)) { unityWebRequest.SetRequestHeader("Authorization", "Bearer " + botSecret); unityWebRequest.downloadHandler = new DownloadHandlerBuffer(); yield return unityWebRequest.SendWebRequest(); string jsonResponse = unityWebRequest.downloadHandler.text; conversation = new ConversationObject(); conversation = JsonConvert.DeserializeObject<ConversationObject>(jsonResponse); Debug.Log($"Start Conversation - Id: {conversation.ConversationId}"); conversationStarted = true; } // The following call is necessary to create and inject an activity of type //"conversationUpdate" to request a first "introduction" from the Bot Service. StartCoroutine(SendMessageToBot("", botId, botName, "conversationUpdate")); }
K sestavení aktivity, která se má odeslat do služby Bot Service, se volá následující korutin.
/// <summary> /// Send the user message to the Bot Service in form of activity /// and call for a response /// </summary> private IEnumerator SendMessageToBot(string message, string fromId, string fromName, string activityType) { Debug.Log($"SendMessageCoroutine: {conversation.ConversationId}, message: {message} from Id: {fromId} from name: {fromName}"); // Create a new activity here Activity activity = new Activity(); activity.from = new From(); activity.conversation = new Conversation(); activity.from.id = fromId; activity.from.name = fromName; activity.text = message; activity.type = activityType; activity.channelId = "DirectLineChannelId"; activity.conversation.id = conversation.ConversationId; // Serialize the activity string json = JsonConvert.SerializeObject(activity); string sendActivityEndpoint = string.Format("{0}/conversations/{1}/activities", botEndpoint, conversation.ConversationId); // Send the activity to the Bot using (UnityWebRequest www = new UnityWebRequest(sendActivityEndpoint, "POST")) { www.uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(json)); www.downloadHandler = new DownloadHandlerBuffer(); www.SetRequestHeader("Authorization", "Bearer " + botSecret); www.SetRequestHeader("Content-Type", "application/json"); yield return www.SendWebRequest(); // extrapolate the response Id used to keep track of the conversation string jsonResponse = www.downloadHandler.text; string cleanedJsonResponse = jsonResponse.Replace("\r\n", string.Empty); string responseConvId = cleanedJsonResponse.Substring(10, 30); // Request a response from the Bot Service StartCoroutine(GetResponseFromBot(activity)); } }
Následující korutin je volán k vyžádání odpovědi po odeslání aktivity do služby Bot Service.
/// <summary> /// Request a response from the Bot by using a previously sent activity /// </summary> private IEnumerator GetResponseFromBot(Activity activity) { string getActivityEndpoint = string.Format("{0}/conversations/{1}/activities", botEndpoint, conversation.ConversationId); using (UnityWebRequest unityWebRequest1 = UnityWebRequest.Get(getActivityEndpoint)) { unityWebRequest1.downloadHandler = new DownloadHandlerBuffer(); unityWebRequest1.SetRequestHeader("Authorization", "Bearer " + botSecret); yield return unityWebRequest1.SendWebRequest(); string jsonResponse = unityWebRequest1.downloadHandler.text; ActivitiesRootObject root = new ActivitiesRootObject(); root = JsonConvert.DeserializeObject<ActivitiesRootObject>(jsonResponse); foreach (var act in root.activities) { Debug.Log($"Bot Response: {act.text}"); SetBotResponseText(act.text); } botState = BotState.ReadyToListen; botMaterial.color = Color.blue; } }
Poslední metoda, která se má přidat do této třídy, je nutná k zobrazení zprávy ve scéně:
/// <summary> /// Set the UI Response Text of the bot /// </summary> internal void SetBotResponseText(string responseString) { SceneOrganiser.Instance.botResponseText.text = responseString; }
Poznámka:
V konzole Unity Editoru se může zobrazit chyba týkající se chybějící třídy SceneOrganiser . Ignorujte tuto zprávu, protože tuto třídu vytvoříte později v kurzu.
Než se vrátíte do Unity, nezapomeňte změny uložit v sadě Visual Studio.
Kapitola 11 – Vytvoření třídy Interakce
Třída, kterou teď vytvoříte, se nazývá Interakce. Tato třída se používá ke zjištění vstupu HoloLens Tap od uživatele.
Pokud uživatel klepne při prohlížení objektu robota ve scéně a robot je připravený naslouchat hlasovým vstupům, objekt Robot změní barvu na červenou a začne naslouchat hlasovým vstupům.
Tato třída dědí z GazeInput třídy, a tak je schopna odkazovat na Metodu Start() a proměnné z této třídy, které jsou označeny použitím základu.
Vytvoření této třídy:
Poklikáním otevřete složku Skripty .
Klikněte pravým tlačítkem do složky Scripts (Skripty ) a klikněte na Create C# Script (Vytvořit > skript jazyka C#). Pojmenujte interakce skriptu.
Poklikáním na nový skript ho otevřete v sadě Visual Studio.
Aktualizujte obory názvů a dědičnost tříd tak, aby byly stejné jako v horní části třídy Interakce :
using UnityEngine.XR.WSA.Input; public class Interactions : GazeInput {
Uvnitř třídy Interactions přidejte následující proměnnou:
/// <summary> /// Allows input recognition with the HoloLens /// </summary> private GestureRecognizer _gestureRecognizer;
Pak přidejte metodu Start():
/// <summary> /// Called on initialization, after Awake /// </summary> internal override void Start() { base.Start(); //Register the application to recognize HoloLens user inputs _gestureRecognizer = new GestureRecognizer(); _gestureRecognizer.SetRecognizableGestures(GestureSettings.Tap); _gestureRecognizer.Tapped += GestureRecognizer_Tapped; _gestureRecognizer.StartCapturingGestures(); }
Přidejte obslužnou rutinu, která se aktivuje, když uživatel provede gesto klepnutí před fotoaparátem HoloLens.
/// <summary> /// Detects the User Tap Input /// </summary> private void GestureRecognizer_Tapped(TappedEventArgs obj) { // Ensure the bot is being gazed upon. if(base.FocusedObject != null) { // If the user is tapping on Bot and the Bot is ready to listen if (base.FocusedObject.name == "Bot" && Bot.Instance.botState == Bot.BotState.ReadyToListen) { // If a conversation has not started yet, request one if(Bot.Instance.conversationStarted) { Bot.Instance.SetBotResponseText("Listening..."); Bot.Instance.StartCapturingAudio(); } else { Bot.Instance.SetBotResponseText("Requesting Conversation..."); StartCoroutine(Bot.Instance.StartConversation()); } } } }
Než se vrátíte do Unity, nezapomeňte změny uložit v sadě Visual Studio.
Kapitola 12 – Vytvoření třídy SceneOrganiser
Poslední požadovaná třída v tomto cvičení se nazývá SceneOrganiser. Tato třída programově nastaví scénu přidáním komponent a skriptů do hlavní kamery a vytvořením příslušných objektů ve scéně.
Vytvoření této třídy:
Poklikáním otevřete složku Skripty .
Klikněte pravým tlačítkem do složky Scripts (Skripty ) a klikněte na Create C# Script (Vytvořit > skript jazyka C#). Pojmenujte skript SceneOrganiser.
Poklikáním na nový skript ho otevřete v sadě Visual Studio.
Uvnitř SceneOrganiser třídy přidejte následující proměnné:
/// <summary> /// Static instance of this class /// </summary> public static SceneOrganiser Instance; /// <summary> /// The 3D text representing the Bot response /// </summary> internal TextMesh botResponseText;
Pak přidejte metody Awake() a Start():
/// <summary> /// Called on Initialization /// </summary> private void Awake() { Instance = this; } /// <summary> /// Called immediately after Awake method /// </summary> void Start () { // Add the GazeInput class to this object gameObject.AddComponent<GazeInput>(); // Add the Interactions class to this object gameObject.AddComponent<Interactions>(); // Create the Bot in the scene CreateBotInScene(); }
Přidejte následující metodu, která odpovídá za vytvoření objektu robota ve scéně a nastavení parametrů a komponent:
/// <summary> /// Create the Sign In button object in the scene /// and sets its properties /// </summary> private void CreateBotInScene() { GameObject botObjInScene = GameObject.CreatePrimitive(PrimitiveType.Sphere); botObjInScene.name = "Bot"; // Add the Bot class to the Bot GameObject botObjInScene.AddComponent<Bot>(); // Create the Bot UI botResponseText = CreateBotResponseText(); // Set properties of Bot GameObject Bot.Instance.botMaterial = new Material(Shader.Find("Diffuse")); botObjInScene.GetComponent<Renderer>().material = Bot.Instance.botMaterial; Bot.Instance.botMaterial.color = Color.blue; botObjInScene.transform.position = new Vector3(0f, 2f, 10f); botObjInScene.tag = "BotTag"; }
Přidejte následující metodu, která odpovídá za vytvoření objektu uživatelského rozhraní ve scéně představující odpovědi robota:
/// <summary> /// Spawns cursor for the Main Camera /// </summary> private TextMesh CreateBotResponseText() { // Create a sphere as new cursor GameObject textObject = new GameObject(); textObject.transform.parent = Bot.Instance.transform; textObject.transform.localPosition = new Vector3(0,1,0); // Resize the new cursor textObject.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f); // Creating the text of the Label TextMesh textMesh = textObject.AddComponent<TextMesh>(); textMesh.anchor = TextAnchor.MiddleCenter; textMesh.alignment = TextAlignment.Center; textMesh.fontSize = 50; textMesh.text = "Hi there, tap on me and I will start listening."; return textMesh; }
Než se vrátíte do Unity, nezapomeňte změny uložit v sadě Visual Studio.
V Unity Editoru přetáhněte skript SceneOrganiser ze složky Scripts do hlavní kamery. Komponenta Organizátor scény by se teď měla objevit na hlavním objektu kamery, jak je znázorněno na obrázku níže.
Kapitola 13 – Před budovou
Pokud chcete provést důkladný test aplikace, budete ji muset načíst na HoloLens bokem. Než to uděláte, ujistěte se, že:
- Všechna nastavení uvedená v kapitole 4 jsou správně nastavena.
- Skript SceneOrganiser je připojen k objektu hlavní kamery .
- Ve třídě Robot se ujistěte, že jste do proměnné botSecret vložili tajný klíč robota.
Kapitola 14 – Sestavení a zkušební načtení do HoloLensu
Všechno potřebné pro oddíl Unity tohoto projektu bylo dokončeno, takže je čas ho sestavit z Unity.
Přejděte na Nastavení sestavení, Nastavení sestavení souboru > ....
V okně Nastavení sestavení klikněte na Sestavit.
Pokud ještě ne, zaškrtněte projekty Unity C#.
Klikněte na Sestavit. Unity spustí okno Průzkumník souborů, ve kterém potřebujete vytvořit a pak vybrat složku pro sestavení aplikace. Vytvořte teď složku a pojmenujte ji App. Potom s vybranou složkou Aplikace klikněte na Vybrat složku.
Unity začne sestavovat projekt do složky Aplikace .
Po dokončení sestavování Unity (může to nějakou dobu trvat), otevře se okno Průzkumník souborů na místě sestavení (zkontrolujte hlavní panel, protože se nemusí vždy zobrazovat nad okny, ale upozorní vás na přidání nového okna).
Kapitola 15 – Nasazení do HoloLens
Nasazení na HoloLens:
Budete potřebovat IP adresu vašeho HoloLensu (pro vzdálené nasazení) a zajistit, aby byl HoloLens v režimu vývojáře. Akce:
- Když nosíte HoloLens, otevřete Nastavení.
- Přejít na možnosti Rozšířené možnosti sítě a internetu > Wi-Fi >
- Poznamenejte si adresu IPv4 .
- Pak přejděte zpět na Nastavení a pak přejděte na Aktualizovat a zabezpečení > pro vývojáře.
- Nastavte režim vývojáře.
Přejděte do nového sestavení Unity ( složka aplikace ) a otevřete soubor řešení v sadě Visual Studio.
V konfiguraci řešení vyberte Ladit.
Na platformě řešení vyberte x86, Vzdálený počítač.
Přejděte do nabídky Sestavení a kliknutím na Nasadit řešení načtěte aplikaci do holoLensu bokem.
Vaše aplikace by se teď měla zobrazit v seznamu nainstalovaných aplikací na holoLensu, připravených ke spuštění!
Poznámka:
Pokud chcete nasadit do imerzivní náhlavní soupravy, nastavte platformu řešení na místní počítač a nastavte konfiguraci na Ladění s platformou x86. Potom nasaďte na místní počítač pomocí nabídky Sestavení a vyberte Nasadit řešení.
Kapitola 16 – Použití žádosti o HoloLens
Po spuštění aplikace uvidíte robota jako modrou kouli před vámi.
Pokud chcete zahájit konverzaci, použijte gesto klepnutí na kouli.
Počkejte, až se konverzace spustí (uživatelské rozhraní zobrazí zprávu, když k ní dojde). Jakmile dostanete úvodní zprávu od robota, klepněte znovu na robota, aby se zčervenal a začal poslouchat váš hlas.
Jakmile přestanete mluvit, vaše aplikace odešle zprávu robotovi a zobrazí se okamžitě odpověď, která se zobrazí v uživatelském rozhraní.
Opakováním procesu odešlete robotovi další zprávy (musíte klepnout pokaždé, když chcete poslat zprávu).
Tato konverzace ukazuje, jak může robot uchovávat informace (vaše jméno), a zároveň poskytuje známé informace (například položky, které jsou na skladě).
Několik otázek, které robota položí:
what do you sell?
how much are umbrellas?
how much are raincoats?
Hotová aplikace Web App Bot (v4)
Blahopřejeme, vytvořili jste aplikaci hybridní reality, která využívá Azure Web App Bot, Microsoft Bot Framework v4.
Bonusová cvičení
Cvičení 1
Struktura konverzací v tomto cvičení je velmi základní. Využijte Microsoft LUIS k tomu, abyste robotovi poskytli možnosti porozumění přirozenému jazyku.
Cvičení 2
Tento příklad nezahrnuje ukončení konverzace a restartování nové konverzace. Pokud chcete funkci robota dokončit, zkuste do konverzace implementovat uzavření.