Omówienie zestawu SDK środowiska uruchomieniowego

Ta sekcja zawiera ogólne omówienie zestawu SDK środowiska uruchomieniowego zakotwiczenia obiektów, który służy do wykrywania obiektów przy użyciu modelu zakotwiczeń obiektów. Dowiesz się, w jaki sposób obiekt jest reprezentowany i do czego służą różne składniki.

Wszystkie typy opisane poniżej można znaleźć w jednej z następujących przestrzeni nazw: Microsoft.Azure.ObjectAnchors, Microsoft.Azure.ObjectAnchors.Diagnostics i Microsoft.Azure.ObjectAnchors.SpatialGraph.

Typy

ObjectModel

Model ObjectModel reprezentuje geometrię obiektu fizycznego i koduje niezbędne parametry do wykrywania i pozyskuj szacowanie. Należy go utworzyć przy użyciu usługi Zakotwiczenia obiektów. Następnie aplikacja może załadować wygenerowany plik modelu przy użyciu interfejsu API kotwic obiektów i wykonać zapytanie o siatkę osadzoną w tym modelu na potrzeby wizualizacji.

ObjectSearchArea

Obiekt ObjectSearchArea określa miejsce do wyszukania jednego lub wielu obiektów. Jest ona definiowana przez identyfikator węzła grafu przestrzennego i granice przestrzenne w systemie współrzędnych reprezentowanym przez identyfikator węzła grafu przestrzennego. Zestaw SDK środowiska uruchomieniowego usługi Object Anchors obsługuje cztery typy granic, a mianowicie pole widoku, pole ograniczenia, sferę i lokalizację.

AccountInformation

KontoInformation przechowuje identyfikator, klucz i domenę dla konta usługi Azure Object Anchors.

ObjectAnchorsSession

ObiektAnchorsSession reprezentuje sesję usługi Azure Object Anchors używaną do tworzenia wystąpień ObjectObserver używanych do wykrywania obiektów w świecie fizycznym.

ObjectObserver

Obiekt ObjectObserver ładuje modele obiektów, wykrywa ich wystąpienia i zgłasza 6-DoF pozuje do każdego wystąpienia w systemie współrzędnych urządzenia HoloLens.

Mimo że każdy model obiektów lub wystąpienie jest tworzony na podstawie obserwatora, ich okresy istnienia są niezależne. Aplikacja może usunąć obserwatora i nadal używać modelu obiektów lub wystąpienia.

Objectquery

Zapytanie objectQuery informuje obserwatora obiektu, jak znaleźć obiekty danego modelu. Udostępnia on następujące parametry do dostosowania, których wartości domyślne można pobrać z modelu obiektów.

MinSurfaceCoverage

Właściwość MinSurfaceCoverage wskazuje wartość, która ma być uwzględniana jako wykryte wystąpienie.

Dla każdego kandydata obiektu obserwator oblicza stosunek nakładających się powierzchni między przekształconym modelem obiektów a sceną, a następnie zgłasza, że kandydat do aplikacji tylko wtedy, gdy stosunek pokrycia przekracza określony próg.

IsExpectedToBeStandingOnGroundPlane

Właściwość IsExpectedToBeStandingOnGroundPlane wskazuje, czy obiekt docelowy ma stanąć na płaszczyźnie naziemnej.

Płaszczyzna naziemna jest najniższym poziomym podłogą w obszarze wyszukiwania. Zapewnia dobre ograniczenie dotyczące możliwych obiektów. Włączenie tej flagi poprowadzi obserwatora w celu oszacowania pozy w ograniczonej przestrzeni i może poprawić dokładność. Ten parametr zostanie zignorowany, jeśli model nie powinien stać na płaszczyźnie naziemnej.

ExpectedMaxVerticalOrientationInDegrees

Właściwość ExpectedMaxVerticalOrientationInDegrees wskazuje oczekiwany maksymalny kąt w stopniach między kierunkiem w górę wystąpienia obiektu a grawitacją.

Ten parametr zapewnia kolejne ograniczenie kierunku w górę szacowanego pozy. Jeśli na przykład obiekt jest w górę, ten parametr może mieć wartość 0. Kotwice obiektów nie powinny wykrywać obiektów, które różnią się od modelu. Jeśli model jest w górę, nie wykryje wystąpienia określonego po stronie. Nowy model będzie używany do układu bocznego. Ta sama reguła ma zastosowanie do artykulacji.

MaxScaleChange

Właściwość MaxScaleChange wskazuje maksymalną zmianę skali obiektu (w zakresie od 0 do 1) w odniesieniu do mapowania przestrzennego. Szacowana skala jest stosowana do przekształconych wierzchołków obiektów wyśrodkowanych na początku i wyrównanych osi. Szacowane skalowanie może nie być rzeczywistą skalą między modelem CAD i jego fizyczną reprezentacją, ale niektóre wartości, które umożliwiają aplikacji renderowanie modelu obiektów w pobliżu mapowania przestrzennego na obiekcie fizycznym.

Obszar wyszukiwania

Właściwość SearchAreas wskazuje tablicę granic przestrzennych, gdzie można znaleźć obiekty.

Obserwator wyszuka obiekty w przestrzeni unii wszystkich obszarów wyszukiwania określonych w zapytaniu. W tej wersji zwrócimy co najwyżej jeden obiekt z największą pewnością, aby zmniejszyć opóźnienie.

Objectinstance

Klasa ObjectInstance reprezentuje hipotetyczną pozycję, w której wystąpienie danego modelu może znajdować się w systemie współrzędnych urządzenia HoloLens. Każde wystąpienie zawiera SurfaceCoverage właściwość, aby wskazać, jak dobra jest szacowana pozycja.

Wystąpienie jest tworzone przez wywołanie ObjectObserver.DetectAsync metody , a następnie aktualizowane automatycznie w tle, gdy jest aktywne. Aplikacja może nasłuchiwać zdarzenia zmienionego stanu w określonym wystąpieniu lub zmienić tryb śledzenia, aby wstrzymać/wznowić aktualizację. Wystąpienie zostanie automatycznie usunięte z obserwatora po utracie śledzenia.

ObjectDiagnosticsSession

ObjectDiagnosticSession rejestruje diagnostykę i zapisuje dane w archiwum.

Archiwum diagnostyczne zawiera chmurę punktu sceny, stan obserwatora i informacje o modelach. Te informacje są przydatne do identyfikowania możliwych problemów ze środowiskiem uruchomieniowym. Aby uzyskać więcej informacji, zobacz często zadawane pytania.

Użycie i szczegóły zestawu SDK środowiska uruchomieniowego

Ta sekcja powinna zawierać podstawowe informacje na temat korzystania z zestawu SDK środowiska uruchomieniowego. Powinno to dać wystarczający kontekst, aby przeglądać przykładowe aplikacje, aby zobaczyć, jak kotwice obiektów są używane holistyczne.

Inicjalizacja

Aplikacje muszą wywołać interfejs API, ObjectObserver.IsSupported() aby określić, czy kotwice obiektów są obsługiwane na urządzeniu przed jego użyciem. ObjectObserver.IsSupported() Jeśli interfejs API zwróci falsewartość , sprawdź, czy aplikacja włączyła funkcję spatialPerception i\lub uaktualnić do najnowszego systemu operacyjnego HoloLens.

using Microsoft.Azure.ObjectAnchors;

if (!ObjectObserver.IsSupported())
{
    // Handle the error
}

// This call should grant the access we need.
ObjectObserverAccessStatus status = await ObjectObserver.RequestAccessAsync();
if (status != ObjectObserverAccessStatus.Allowed)
{
    // Handle the error
}

Następnie aplikacja tworzy obserwatora obiektu i ładuje niezbędne modele generowane przez usługę konwersji modelu Zakotwiczenia obiektów.

using Microsoft.Azure.ObjectAnchors;

// Note that you need to provide the Id, Key and Domain for your Azure Object
// Anchors account.
Guid accountId = new Guid("[your account id]");
string accountKey = "[your account key]";
string accountDomain = "[your account domain]";

AccountInformation accountInformation = new AccountInformation(accountId, accountKey, accountDomain);
ObjectAnchorsSession session = new ObjectAnchorsSession(accountInformation);
ObjectObserver observer = session.CreateObjectObserver();

// Load a model into a byte array. The model could be a file, an embedded
// resource, or a network stream.
byte[] modelAsBytes;
ObjectModel model = await observer.LoadObjectModelAsync(modelAsBytes);

// Note that after a model is loaded, its vertices and normals are transformed
// into a centered coordinate system for the ease of computing the object pose.
// The rigid transform can be retrieved through the `OriginToCenterTransform`
// property.

Aplikacja tworzy zapytanie w celu wykrywania wystąpień tego modelu w przestrzeni.

#if WINDOWS_UWP || DOTNETWINRT_PRESENT
#define SPATIALCOORDINATESYSTEM_API_PRESENT
#endif

using Microsoft.Azure.ObjectAnchors;
using Microsoft.Azure.ObjectAnchors.SpatialGraph;
using Microsoft.Azure.ObjectAnchors.Unity;
using UnityEngine;

// Get the coordinate system.
SpatialGraphCoordinateSystem? coordinateSystem = null;

#if SPATIALCOORDINATESYSTEM_API_PRESENT
SpatialCoordinateSystem worldOrigin = ObjectAnchorsWorldManager.WorldOrigin;
if (worldOrigin != null)
{
    coordinateSystem = await Task.Run(() => worldOrigin.TryToSpatialGraph());
}
#endif

if (!coordinateSystem.HasValue)
{
    Debug.LogError("no coordinate system?");
    return;
}

// Get the search area.
SpatialFieldOfView fieldOfView = new SpatialFieldOfView
{
    Position = Camera.main.transform.position.ToSystem(),
    Orientation = Camera.main.transform.rotation.ToSystem(),
    FarDistance = 4.0f, // Far distance in meters of object search frustum.
    HorizontalFieldOfViewInDegrees = 75.0f, // Horizontal field of view in
                                            // degrees of object search frustum.
    AspectRatio = 1.0f // Aspect ratio (horizontal / vertical) of object search
                       // frustum.
};

ObjectSearchArea searchArea = ObjectSearchArea.FromFieldOfView(coordinateSystem.Value, fieldOfView);

// Optionally change the parameters, otherwise use the default values embedded
// in the model.
ObjectQuery query = new ObjectQuery(model);
query.MinSurfaceCoverage = 0.2f;
query.ExpectedMaxVerticalOrientationInDegrees = 1.5f;
query.MaxScaleChange = 0.1f;
query.SearchAreas.Add(searchArea);

// Detection could take a while, so we run it in a background thread.
IReadOnlyList<ObjectInstance> detectedObjects = await observer.DetectAsync(query);

Domyślnie każde wykryte wystąpienie będzie śledzone automatycznie przez obserwatora. Opcjonalnie możemy manipulować tymi wystąpieniami, zmieniając ich tryb śledzenia lub słuchając zdarzenia zmienionego stanu.

using Microsoft.Azure.ObjectAnchors;

foreach (ObjectInstance instance in detectedObjects)
{
    // Supported modes:
    // "LowLatencyCoarsePosition"    - Consumes less CPU cycles thus fast to
    //                                 update the state.
    // "HighLatencyAccuratePosition" - Uses the device's camera and consumes more CPU
    //                                 cycles thus potentially taking longer
    //                                 time to update the state.
    // "Paused"                      - Stops to update the state until mode
    //                                 changed to low or high.
    instance.Mode = ObjectInstanceTrackingMode.LowLatencyCoarsePosition;

    // Listen to state changed event on this instance.
    instance.Changed += InstanceChangedHandler;

    // Optionally dispose an instance if not interested in it.
    // instance.Dispose();
}

W przypadku zdarzenia zmienionego stanu możemy wysłać zapytanie do najnowszego stanu lub usunąć wystąpienie, jeśli utraci śledzenie.

using Microsoft.Azure.ObjectAnchors;

void InstanceChangedHandler(object sender, ObjectInstanceChangedEventArgs args)
{
    // Try to query the current instance state.
    ObjectInstanceState state = sender.TryGetCurrentState();

    if (state != null)
    {
        // Process latest state.
        // An object pose includes rotation and translation, applied in
        // the same order to the object model in the centered coordinate system.
    }
    else
    {
        // This object instance is lost for tracking, and will never be recovered.
        // The caller can detach the Changed event handler from this instance
        // and dispose it.
    }
}

Ponadto aplikacja może opcjonalnie rejestrować jedną lub wiele sesji diagnostycznych na potrzeby debugowania w trybie offline.

using Microsoft.Azure.ObjectAnchors;
using Microsoft.Azure.ObjectAnchors.Diagnostics;

string diagnosticsFolderPath = Windows.Storage.ApplicationData.Current.TemporaryFolder.Path;
const uint maxSessionSizeInMegaBytes = uint.MaxValue;

// Recording starts on the creation of a diagnostics session.
ObjectDiagnosticsSession diagnostics = new ObjectDiagnosticsSession(observer, maxSessionSizeInMegaBytes);

// Wait for the observer to do a job.

// Application can report some **pseudo ground-truth** pose for an instance
// acquired from other means.
diagnostics.ReportActualInstanceLocation(instance, coordinateSystem, Vector3.Zero, Quaternion.Identity);

// Close a session and write the diagnostics into an archive at specified location.
await diagnostics.CloseAsync(System.IO.Path.Combine(diagnosticsFolderPath, "diagnostics.zip"));

Na koniec zwalniamy zasoby, dysponując wszystkie obiekty.

using Microsoft.Azure.ObjectAnchors;

foreach (ObjectInstance instance in activeInstances)
{
    instance.Changed -= InstanceChangedHandler;
    instance.Dispose();
}

model.Dispose();
observer.Dispose();