Runtime SDK – áttekintés

Ez a szakasz magas szintű áttekintést nyújt az Object Anchors Runtime SDK-ról, amely objektumhorgony-modellel észleli az objektumokat. Megismerheti az objektumok ábrázolásának módját és a különböző összetevők használatát.

Az alábbiakban ismertetett összes típus megtalálható a következő névterek egyikében: Microsoft.Azure.ObjectAnchors, Microsoft.Azure.ObjectAnchors.Diagnostics és Microsoft.Azure.ObjectAnchors.SpatialGraph.

Típusok

ObjectModel

Az ObjectModel egy fizikai objektum geometriája, és kódolja az észleléshez és a becsléshez szükséges paramétereket. Az Objektumhorgonyok szolgáltatással kell létrehozni. Ezután egy alkalmazás betöltheti a létrehozott modellfájlt az Object Anchors API-val, és lekérdezheti a modellbe beágyazott hálót vizualizáció céljából.

ObjectSearchArea

Az ObjectSearchArea egy vagy több objektum keresésének területét adja meg. Ezt a térbeli gráfcsomópont azonosítója és a térbeli gráfcsomópont azonosítója által képviselt koordinátarendszer térbeli határai határozzák meg. Az Object Anchors Runtime SDK négyféle határt támogat: a nézetmezőt, a határolókeretet, a gömböt és a helyet.

AccountInformation

Az AccountInformation tárolja az Azure Object Anchors-fiók azonosítóját, kulcsát és tartományát.

ObjectAnchorsSession

Az ObjectAnchorsSession egy Azure Object Anchors-munkamenetet jelöl, amely a fizikai világ objektumainak észlelésére használt ObjectObserver-példányok létrehozására szolgál.

ObjectObserver

Az ObjectObserver betölti az objektummodelleket, észleli a példányokat, és a HoloLens koordinátarendszer minden példányának 6-DoF-pózolását jelenti.

Bár bármely objektummodell vagy -példány egy megfigyelőtől jön létre, élettartamuk független. Az alkalmazások megsemmisíthetnek egy megfigyelőt, és továbbra is használhatják az objektummodellt vagy -példányt.

ObjectQuery

Az ObjectQuery segítségével az objektum megfigyelője megkeresi egy adott modell objektumait. Az alábbi, az objektummodellből lekérhető alapértelmezett értékeket biztosít.

MinSurfaceCoverage

A MinSurfaceCoverage tulajdonság azt az értéket jelzi, amelyet észlelni kell egy példányban.

Minden objektumjelölt esetében a megfigyelő kiszámítja az átfedő felületek arányát az átalakított objektummodell és a jelenet között, majd azt jelenti, hogy a jelölt csak akkor alkalmazható, ha a lefedettségi arány egy adott küszöbérték felett van.

IsExpectedToBeStandingOnGroundPlane

Az IsExpectedToBeStandingOnGroundPlane tulajdonság azt jelzi, hogy a célobjektum várhatóan a földi síkon fog-e állni.

A földi sík a keresési terület legalsó vízszintes padlója. Jó kényszert biztosít a lehetséges objektumokra. Ha bekapcsolja ezt a jelzőt, a megfigyelő felméri a pózolást egy korlátozott térben, és javíthatja a pontosságot. Ez a paraméter figyelmen kívül lesz hagyva, ha a modellnek nem kell a földi síkon állnia.

ExpectedMaxVerticalOrientationInDegrees

A ExpectedMaxVerticalOrientationInDegrees tulajdonság az objektumpéldány felfelé irányuló iránya és a gravitáció közötti várható maximális szöget jelzi.

Ez a paraméter egy másik korlátozást is biztosít a becsült pózok felfelé irányára. Ha például egy objektum jobbra áll, ez a paraméter 0 lehet. Az objektumhorgonyoknak nem a modelltől eltérő objektumokat kell észlelniük. Ha egy modell jobbról felfelé halad, akkor nem észleli az oldalról lefektetett példányt. A rendszer egy új modellt használ a lefelé irányuló elrendezéshez. Ugyanez a szabály vonatkozik az artikulációra is.

MaxScaleChange

A MaxScaleChange tulajdonság a térbeli leképezés tekintetében az objektumméretek maximális változását jelzi (0 ~ 1-ben). A becsült skálát az átalakított objektum csúcspontjaira alkalmazza a rendszer, amely a forrás és a tengely igazítása szerint van igazítva. Előfordulhat, hogy a becsült skálázás nem a CAD-modell és fizikai ábrázolása közötti tényleges skálázás, de bizonyos értékek lehetővé teszik, hogy az alkalmazás a fizikai objektum térbeli leképezéséhez közel jelenítsen meg egy objektummodellt.

SearchAreas

A SearchAreas tulajdonság térbeli határokat tartalmazó tömböt jelöl, ahol objektum(ok) találhatók.

A megfigyelő objektumokat fog keresni a lekérdezésben megadott összes keresési terület egyesítő területén. Ebben a kiadásban legfeljebb egy, a legnagyobb megbízhatósággal rendelkező objektumot adunk vissza a késés csökkentése érdekében.

ObjectInstance

Az ObjectInstance egy hipotetikus pozíció, ahol egy adott modell példánya a HoloLens koordinátarendszerben lehet. Minden példányhoz tartozik egy SurfaceCoverage tulajdonság, amely jelzi, hogy milyen jó a becsült póz.

A rendszer hívási ObjectObserver.DetectAsync metódussal hoz létre egy példányt, majd automatikusan frissíti a háttérben, ha életben van. Az alkalmazások figyelhetik egy adott példány állapotváltozását, vagy módosíthatják a nyomkövetési módot a frissítés szüneteltetésére/folytatására. A rendszer automatikusan eltávolít egy példányt a megfigyelőből, amikor a nyomon követés elveszik.

ObjectDiagnosticsSession

Az ObjectDiagnosticSession rögzíti a diagnosztikát, és adatokat ír egy archívumba.

A diagnosztikai archívum tartalmazza a jelenetpont felhőjét, a megfigyelő állapotát és a modellekre vonatkozó információkat. Ez az információ hasznos a futásidejű problémák azonosításához. További információt a gyakori kérdések között talál.

FuttatókörnyezetI SDK használata és részletei

Ez a szakasz a Futtatókörnyezet SDK használatának alapjait ismerteti. Elegendő kontextust kell adnia ahhoz, hogy végigböngészhesse a mintaalkalmazásokat, hogy lássa, hogyan használják holisztikusan az Objektumhorgonyokat.

Inicializálás

Az alkalmazásoknak meg kell hívniuk az ObjectObserver.IsSupported() API-t annak megállapításához, hogy az objektumhorgonyok támogatottak-e az eszközön a használat előtt. Ha az ObjectObserver.IsSupported() API visszatér false, ellenőrizze, hogy az alkalmazás engedélyezte-e a spatialPerception képességet, és\vagy frissítsen a legújabb HoloLens operációs rendszerre.

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
}

Ezután az alkalmazás létrehoz egy objektumfigyelőt, és betölti az Object Anchors modellkonvertálási szolgáltatás által létrehozott szükséges modelleket.

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.

Az alkalmazás létrehoz egy lekérdezést a modell példányainak egy térben való észleléséhez.

#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);

Alapértelmezés szerint a megfigyelő automatikusan nyomon követi az észlelt példányokat. Ezeket a példányokat tetszés szerint módosíthatjuk a nyomkövetési módjuk módosításával vagy az állapotváltozásuk eseményének figyelésével.

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();
}

A módosított állapotú eseményben lekérdezhetjük a legújabb állapotot, vagy eltávolíthatunk egy példányt, ha az elvesztette a nyomon követést.

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.
    }
}

Az alkalmazások emellett egy vagy több diagnosztikai munkamenetet is rögzíthetnek offline hibakeresés céljából.

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"));

Végül az összes objektum eltávolításával felszabadítjuk az erőforrásokat.

using Microsoft.Azure.ObjectAnchors;

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

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