Případová studie – rozšíření možností prostorového mapování HoloLens

Při vytváření našich prvních aplikací pro Microsoft HoloLens jsme se dychtili podívat, jak daleko bychom mohli na zařízení posunout hranice prostorového mapování. Jeff Evertt, softwarový inženýr v microsoftových studiích, vysvětluje, jak byla vyvinuta nová technologie z potřeby větší kontroly nad tím, jak se hologramy umístí do prostředí reálného světa uživatele.

Poznámka

HoloLens 2 implementuje nový modul runtime Scene Understanding Runtime,který vývojářům Mixed Reality poskytuje strukturované znázornění prostředí vysoké úrovně navržené tak, aby bylo vývoj pro intuitivní aplikace, které jsou vědomé.

Přehrát video

Nad rámec prostorového mapování

Zatímco jsme pracovali na fragmentech a Young Conkerovi, dvě z prvních her pro HoloLens, zjistili jsme, že když jsme postupově umisťování hologramů ve fyzickém světě, potřebovali jsme vyšší úroveň porozumění prostředí uživatele. Každá hra měla vlastní specifické potřeby umístění: Například ve fragmentech jsme chtěli být schopni rozlišovat mezi různými povrchy , například podlahou nebo tabulkou, a umístit tak vodítka do relevantních míst. Chtěli jsme také být schopni identifikovat povrchy, na které by mohly být holografické znaky v životní velikosti, jako je například pohoutová nebo mislí. V Young Conkeru jsme chtěli, aby Conker a jeho přátelé mohli používat vyvýšené povrchy v místnosti hráče jako platformy.

Asobo Studia, náš vývojový partner pro tyto hry, čelili tomuto problému a vytvořili technologii, která rozšiřuje možnosti prostorového mapování HoloLens. Pomocí toho můžeme analyzovat místnost hráče a identifikovat povrchy, jako jsou stěny, tabulky, stolu a podlahy. Také nám to dalo možnost optimalizovat se vzhledem k sadě omezení, aby bylo možné určit nejlepší umístění holografických objektů.

Kód prostorového porozumění

Vzali jsme původní kód asobo a vytvořili jsme knihovnu, která tuto technologii zapouzdřuje. Microsoft a Asobo teď tento kód s otevřeným zdrojem zprotohověly a z dostupného na MixedRealityToolkitu, abyste ho měli k dispozici ve svých vlastních projektech. Součástí je veškerý zdrojový kód, který vám umožní přizpůsobit ho vašim potřebám a sdílet vylepšení s komunitou. Kód řešitel C++ byl zabalen do knihovny DLL UPW a vystavený Unity pomocí předfabu rozevíracího seznamu obsaženého v mixedRealityToolkit.

Ukázka Unity obsahuje mnoho užitečných dotazů, které vám umožní najít prázdné prostory na zdech, umístit objekty na strop nebo na velké prostory na podlaží, identifikovat místa, kde se znaky nachází, a nesčetné množství dalších prostorových dotazů.

I když řešení prostorového mapování, které poskytuje HoloLens, je navržené tak, aby bylo dostatečně obecné, aby splňovalo potřeby celé škály problémových prostorů, modul prostorového porozumění byl vytvořen tak, aby podporoval potřeby dvou konkrétních her. Jeho řešení je proto strukturované kolem konkrétního procesu a sady předpokladů:

  • Playspace s pevnouvelikostí: Uživatel určuje maximální velikost playspace ve volání init.
  • Proces kontroly jednou:Tento proces vyžaduje samostatnou fázi kontroly, ve které se uživatel prochází a definuje playspace. Funkce dotazů nebudou fungovat, dokud se kontrola nedokoní.
  • Uživatelem řízený playspace "obraz":Během fáze skenování se uživatel přesune a podívá se na playspace a v podstatě vykresluje oblasti, které by měly být zahrnuty. Vygenerovaná síť je důležitá k poskytnutí zpětné vazby uživatelů během této fáze.
  • Vnitřní domácí nebo kancelářské funkce:Dotazovací funkce jsou navržené kolem plochých povrchů a zdí v pravém úhlu. Jedná se o omezení. Během fáze skenování se ale dokončí analýza primární osy, aby se optimalizovala tholace sítě podél hlavní a dílčí osy.

Proces prohledávání místnosti

Když načtete modul prostorového porozumění, první věc, kterou budete dělat, je naskenovat prostor, aby se identifikovaly a označily všechny použitelné povrchy , jako je podlahy, strop a zdi. Během procesu skenování se podíváte do místnosti a "vymalujte" oblasti, které by měly být součástí kontroly.

Síť vidět v této fázi je důležitou součástí vizuální zpětné vazby, která uživatelům umožňuje vědět, které části místnosti se prohledanou. Knihovna DLL pro modul spatial understanding interně ukládá playspace jako mřížku datových krychlí vo velikosti 8cm. Během počáteční části kontroly se dokončí analýza primární komponenty, která určí osy místnosti. Interně ukládá svůj prostor vo zarovnaný s těmito osami. Síť se generuje přibližně každou sekundu extrahováním izolace z objemu vo extract.

Síť prostorového mapování v bílé barvě a principy sítě playprostorů zeleně

Síť prostorového mapování v bílé barvě a principy sítě playprostorů zeleně

Zahrnutý soubor SpatialUnderstanding.cs spravuje proces fáze kontroly. Volá následující funkce:

  • SpatialUnderstanding_Init:Volá se jednou na začátku.
  • GeneratePlayspace_InitScan: Označuje, že má začít fáze kontroly.
  • GeneratePlayspace_UpdateScan_DynamicScan:Pro aktualizaci procesu kontroly se volá každý snímek. Pozice a orientace kamery se předává a používá se pro proces obrazování playspace popsaný výše.
  • GeneratePlayspace_RequestFinish: Volána k dokončení playspace. Ve fázi skenování se k definování a uzamčení playspace využijí oblasti, které se používají jako "neschůdné". Aplikace se může během fáze kontroly dotazovat na statistiky a také dotazovat vlastní síť pro poskytnutí zpětné vazby uživatelů.
  • Import_UnderstandingMesh:Při kontrole se chování SpatialUnderstandingCustomMesh poskytované modulem a umístěné na principu předfabu bude pravidelně dotazovat vlastní síť vygenerovanou procesem. Kromě toho se to provádí znovu po dokončení kontroly.

Tok skenování řízený chováním SpatialUnderstanding volá InitScana pak UpdateScan každý snímek. Když statistický dotaz hlásí přiměřené pokrytí, může uživatel airtap zavolat RequestFinish, aby indikuje konec fáze kontroly. UpdateScan se bude volat, dokud vrácená hodnota neznačí, že knihovna DLL dokončila zpracování.

Dotazy

Po dokončení kontroly budete mít v rozhraní přístup ke třem různým typům dotazů:

  • Dotazy topologie:Jedná se o rychlé dotazy založené na topologii naskenované místnosti.
  • Dotazy tvarů:Tyto dotazy využívají výsledky dotazů topologie k vyhledání vodorovných povrchů, které se dobře shodují s vlastními tvary, které definujete.
  • Dotazy pro umístění objektů:Jedná se o složitější dotazy, které na základě sady pravidel a omezení pro objekt najdou nejlepší umístění.

Kromě tří primárních dotazů je k dispozici rozhraní paprskového vysílání, které lze použít k načtení označených typů povrchu, a lze zkopírovat vlastní, nenávasnou síť místností.

Dotazy topologie

V rámci knihovny DLL zpracovává správce topologie popisování prostředí. Jak už bylo zmíněno výše, velká část dat se ukládá do přímek, která jsou obsažena v objemu virtuálního počítače. Kromě toho se struktura PlaySpaceInfos používá k ukládání informací o playspace, včetně světového zarovnání (další podrobnosti o tom níže), podlaží a výšky stropu.

Heuristika se používá k určení podlahy, stropu a zdí. Za podlahu se považuje například největší a nejnižší vodorovná plocha s povrchovou plochou větší než 1 m2. Všimněte si, že v tomto procesu se používá také cesta fotoaparátu během procesu kontroly.

Prostřednictvím knihovny DLL se zveřejňuje podmnožina dotazů vystavených správcem topologie. Vystavené dotazy topologie jsou následující:

  • QueryTopology_FindPositionsOnWalls
  • QueryTopology_FindLargePositionsOnWalls
  • QueryTopology_FindLargestWall
  • QueryTopology_FindPositionsOnFloor
  • QueryTopology_FindLargestPositionsOnFloor
  • QueryTopology_FindPositionsSittable

Každý z dotazů má sadu parametrů specifických pro typ dotazu. V následujícím příkladu uživatel určí minimální šířku výšky požadovaného svazku, minimální výšku umístění nad podlahou a minimální velikost výšky před & svazkem. Všechna měření jsou v metrech.

EXTERN_C __declspec(dllexport) int QueryTopology_FindPositionsOnWalls(
          _In_ float minHeightOfWallSpace,
          _In_ float minWidthOfWallSpace,
          _In_ float minHeightAboveFloor,
          _In_ float minFacingClearance,
          _In_ int locationCount,
          _Inout_ Dll_Interface::TopologyResult* locationData)

Každý z těchto dotazů přebírá předem přidělené pole struktur TopologyResult. Parametr locationCount určuje délku předa ového pole. Vrácená hodnota hlásí počet vrácených umístění. Toto číslo není nikdy větší než předaný parametr locationCount.

Hodnota TopologyResult obsahuje středovou pozici vráceného svazku, směr orientace (tj. normální) a rozměry nalezené mezery.

struct TopologyResult
     {
          DirectX::XMFLOAT3 position;
          DirectX::XMFLOAT3 normal;
          float width;
          float length;
     };

Všimněte si, že v ukázce Unity je každý z těchto dotazů propojený s tlačítkem na panelu virtuálního uživatelského rozhraní. Ukázka pevným kódem parametrů pro každý z těchto dotazů na rozumné hodnoty. Další příklady najdete v souboru SpaceVisualizer.cs v ukázkovém kódu.

Tvarování dotazů

Uvnitř knihovny DLL používá analyzátor tvaru (ShapeAnalyzer_W) ke shodě s vlastními tvary definovanými uživatelem analyzátor topologie. Ukázka Unity má předdefinované sady tvarů, které se zobrazují v nabídce dotazu na kartě obrazce.

Všimněte si, že analýza obrazce funguje pouze na vodorovných površích. Například poschůdka je definována plochým povrchem sedadel a plochým horním okrajem zadní části. Dotaz obrazce hledá dva povrchy určité velikosti, výšky a rozsahu stran a tyto dva povrchy jsou zarovnané a propojené. S využitím terminologie rozhraní API jsou sesedačky a horní část zadní části posype tvarové součásti a požadavky na zarovnání jsou omezení tvarových komponent.

Příklad dotazu definovaného v ukázce Unity (ShapeDefinition.cs) pro "sittable" objekty je následující:

shapeComponents = new List<ShapeComponent>()
     {
          new ShapeComponent(
               new List<ShapeComponentConstraint>()
               {
                    ShapeComponentConstraint.Create_SurfaceHeight_Between(0.2f, 0.6f),
                    ShapeComponentConstraint.Create_SurfaceCount_Min(1),
                    ShapeComponentConstraint.Create_SurfaceArea_Min(0.035f),
               }),
     };
     AddShape("Sittable", shapeComponents);

Každý dotaz obrazce je definován pomocí sady součástí obrazce, z nichž každá má sadu omezení komponent a sadu omezení tvarů, která uvádí závislosti mezi komponentami. Tento příklad obsahuje tři omezení v jedné definici komponenty a žádná omezení tvaru mezi komponentami (protože existuje pouze jedna komponenta).

Naproti tomu tvar poschodky má dvě tvarové součásti a čtyři tvarová omezení. Všimněte si, že komponenty jsou identifikovány podle indexu v seznamu součástí uživatele (0 a 1 v tomto příkladu).

shapeConstraints = new List<ShapeConstraint>()
        {
              ShapeConstraint.Create_RectanglesSameLength(0, 1, 0.6f),
              ShapeConstraint.Create_RectanglesParallel(0, 1),
              ShapeConstraint.Create_RectanglesAligned(0, 1, 0.3f),
              ShapeConstraint.Create_AtBackOf(1, 0),
        };

Funkce obálky jsou k dispozici v modulu Unity pro snadné vytváření definic vlastních tvarů. Úplný seznam omezení komponent a obrazců najdete v SpatialUnderstandingDll. cs v rámci ShapeComponentConstraint a struktur ShapeConstraint .

Modrý obdélník zvýrazní výsledky dotazu obrazce židle.

Modrý obdélník zvýrazní výsledky dotazu obrazce židle.

Řešitel umístění objektu

Dotazy na umístění objektu lze použít k identifikaci ideálních míst ve fyzické místnosti pro umístění vašich objektů. Řešitel vyhledá nejlepší umístění podle pravidel a omezení pro dané objekty. Kromě toho jsou dotazy objektů trvalé, dokud není objekt odstraněn pomocí Solver_RemoveObject nebo Solver_RemoveAllObjects volání, což umožňuje omezené umístění více objektů.

Dotazy na umístění objektu se skládají ze tří částí: typ umístění s parametry, seznam pravidel a seznam omezení. Pokud chcete spustit dotaz, použijte následující rozhraní API:

public static int Solver_PlaceObject(
                [In] string objectName,
                [In] IntPtr placementDefinition,	// ObjectPlacementDefinition
                [In] int placementRuleCount,
                [In] IntPtr placementRules,     	// ObjectPlacementRule
                [In] int constraintCount,
                [In] IntPtr placementConstraints,	// ObjectPlacementConstraint
                [Out] IntPtr placementResult)

Tato funkce přijímá název objektu, definici umístění a seznam pravidel a omezení. Obálky C# poskytují pomocné funkce konstrukce, které usnadňují konstrukci pravidla a omezení. Definice umístění obsahuje typ dotazu, což je jedna z následujících:

public enum PlacementType
                {
                    Place_OnFloor,
                    Place_OnWall,
                    Place_OnCeiling,
                    Place_OnShape,
                    Place_OnEdge,
                    Place_OnFloorAndCeiling,
                    Place_RandomInAir,
                    Place_InMidAir,
                    Place_UnderFurnitureEdge,
                };

Každé typy umístění má sadu parametrů, které jsou pro daný typ jedinečné. Struktura ObjectPlacementDefinition obsahuje sadu statických pomocných funkcí pro vytváření těchto definic. Chcete-li například najít místo pro vložení objektu do podlahy, můžete použít následující funkci:

public static ObjectPlacementDefinition Create_OnFloor(Vector3 halfDims)

Kromě typu umístění můžete zadat sadu pravidel a omezení. Pravidla nelze porušovat. Možná umístění umístění, která odpovídají typu a pravidla, jsou optimalizována proti sadě omezení pro výběr optimálního umístění umístění. Každé pravidlo a omezení lze vytvořit pomocí funkcí statického vytvoření. Ukázková funkce pravidla a konstrukce omezení je uvedená níže.

public static ObjectPlacementRule Create_AwayFromPosition(
                    Vector3 position, float minDistance)
               public static ObjectPlacementConstraint Create_NearPoint(
                    Vector3 position, float minDistance = 0.0f, float maxDistance = 0.0f)

Níže uvedený dotaz na umístění objektu vyhledává místo pro vložení datové krychle o poloviční měřiči na okraji povrchu, a to od jiných objektů, které dříve umístily do středu místnosti.

List<ObjectPlacementRule> rules = 
          new List<ObjectPlacementRule>() {
               ObjectPlacementRule.Create_AwayFromOtherObjects(1.0f),
          };

     List<ObjectPlacementConstraint> constraints = 
          new List<ObjectPlacementConstraint> {
               ObjectPlacementConstraint.Create_NearCenter(),
          };

     Solver_PlaceObject(
          “MyCustomObject”,
          new ObjectPlacementDefinition.Create_OnEdge(
          new Vector3(0.25f, 0.25f, 0.25f), 
          new Vector3(0.25f, 0.25f, 0.25f)),
          rules.Count,
          UnderstandingDLL.PinObject(rules.ToArray()),
          constraints.Count,
          UnderstandingDLL.PinObject(constraints.ToArray()),
          UnderstandingDLL.GetStaticObjectPlacementResultPtr());

V případě úspěchu se vrátí struktura ObjectPlacementResult obsahující umístění umístění, rozměry a orientaci. Kromě toho je umístění přidáno do interního seznamu umístěných objektů knihovny DLL. Další dotazy na umístění budou tento objekt brát v úvahu. Soubor LevelSolver. cs v ukázce Unity obsahuje další příklady dotazů.

Modré čtverečky zobrazují výsledek ze tří míst v dotazech na podlaze s pravidly

Modré čtverečky zobrazují výsledek ze tří míst v dotazech na podlaze s pravidly "od pozice kamery".

Tipy:

  • Při řešení umístění umístění více objektů potřebných pro určitý scénář nebo pro aplikaci nejprve vyřešte nepostradatelné a velké objekty, aby bylo možné maximalizovat pravděpodobnost, že se místo nachází.
  • Pořadí umístění je důležité. Pokud nejde najít umístění objektu, zkuste méně omezené konfigurace. Sada záložních konfigurací je zásadní pro podporu funkcí napříč mnoha konfiguracemi místností.

Obsazení Ray

Navíc k třem primárním dotazům lze použít rozhraní Ray k načtení typů tagovaných povrchů a vlastní vodotěsnou Playspace síť lze zkopírovat poté, co byla místnost prohledávána a dokončena, popisky jsou interně generovány pro povrchy, jako je podlahová plocha, strop a zdi. Funkce PlayspaceRaycast přebírá v poli ray a vrátí, zda se v Ray a v případě, že dojde ke konfliktu se známým povrchem, a pokud ano, informace o tomto povrchu ve formě RaycastResult.

struct RaycastResult
     {
          enum SurfaceTypes
          {
               Invalid,	// No intersection
               Other,
               Floor,
               FloorLike,         // Not part of the floor topology, 
                                  //     but close to the floor and looks like the floor
               Platform,          // Horizontal platform between the ground and 
                                  //     the ceiling
               Ceiling,
               WallExternal,
               WallLike,          // Not part of the external wall surface, 
                                  //     but vertical surface that looks like a 
                                  //	wall structure
               };
               SurfaceTypes SurfaceType;
               float SurfaceArea;	// Zero if unknown 
                                        //	(i.e. if not part of the topology analysis)
               DirectX::XMFLOAT3 IntersectPoint;
               DirectX::XMFLOAT3 IntersectNormal;
     };

Interně je raycast vypočítán proti vypočtené 8CM na třetí Voxel reprezentaci Playspace. Každý Voxel obsahuje sadu prvků povrchu se zpracovanými daty topologie (označuje se také jako surfels). Surfels obsažená v buňce protínající Voxel je porovnána s nejlepší shodou použitou k vyhledání informací o topologii. Tato data topologie obsahují označení vracené ve formě výčtu SurfaceTypes a také oblast povrchu protínající se plochy.

V ukázce Unity přetypování ukazatelem na každý snímek. Nejdřív, proti kolizím v Unity; za sekundu, s ohledem na světové reprezentace modulu. a nakonec s prvky uživatelského rozhraní. V této aplikaci má uživatelské rozhraní prioritu, pak porozumění výsledkům a nakonec kolizím v Unity. SurfaceType je hlášen jako text vedle kurzoru.

Raycast vytváření sestav výsledků s podlahou.

Raycast vytváření sestav výsledků s podlahou.

Získání kódu

Open source kód je k dispozici v MixedRealityToolkit. pokud použijete kód v projektu, dejte nám prosím na HoloLens fóra pro vývojáře . Nemůžeme počkat na to, co dělat s!

O autorovi

Jan Evertt, vedoucí softwarového inženýrství v Microsoftu jan Evertt je vedoucí softwaru, který od začátku dne HoloLens pracoval od inkubací po dobu od inkubací až po vývoj zkušeností. před HoloLens pracovali na Kinect Xbox a v rámci her na široké škále platforem a her. Jan je zapálených o robotech, grafikách a akcích pomocí blikajících indikátorů, které se dostanou pípnutím. Požívá učení nových věcí a práci na softwaru, hardwaru a zejména v prostoru, kde se dva protínají.

Viz také