Panoramica di Runtime SDK

Questa sezione offre una panoramica generale di Object Anchors Runtime SDK, usata per rilevare gli oggetti usando un modello di ancoraggi a oggetti. Si apprenderà come viene rappresentato un oggetto e quali componenti vengono usati.

Tutti i tipi descritti di seguito sono disponibili in uno degli spazi dei nomi seguenti: Microsoft.Azure.ObjectAnchors, Microsoft.Azure.ObjectAnchors.Diagnostics e Microsoft.Azure.ObjectAnchors.SpatialGraph.

Tipi

ObjectModel

Un ObjectModel rappresenta la geometria di un oggetto fisico e codifica i parametri necessari per il rilevamento e la stima della posizione. Deve essere creato usando il servizio Ancoraggi oggetti. Un'applicazione può quindi caricare il file del modello generato usando l'API Ancoraggi oggetti ed eseguire una query sulla mesh incorporata in tale modello per la visualizzazione.

ObjectSearchArea

ObjectSearchArea specifica lo spazio da cercare uno o più oggetti. Viene definito da un ID nodo del grafo spaziale e da limiti spaziali nel sistema di coordinate rappresentato dall'ID del nodo del grafo spaziale. L'SDK runtime di Ancoraggi oggetti supporta quattro tipi di limiti, ovvero il campo della visualizzazione, il rettangolo di selezione, la sfera e una posizione.

AccountInformation

Un AccountInformation archivia l'ID, la chiave e il dominio per l'account di Ancoraggi oggetti di Azure.

ObjectAnchorsSession

ObjectAnchorsSession rappresenta una sessione di Ancoraggi oggetti di Azure usata per creare istanze objectObserver usate per rilevare oggetti nel mondo fisico.

ObjectObserver

Un objectObserver carica i modelli a oggetti, rileva le relative istanze e segnala le pose 6-DoF di ogni istanza nel sistema di coordinate HoloLens.

Anche se qualsiasi modello a oggetti o istanza viene creato da un osservatore, le loro durate sono indipendenti. Un'applicazione può eliminare un osservatore e continuare a usare il modello a oggetti o l'istanza.

Objectquery

ObjectQuery indica a un osservatore oggetto come trovare oggetti di un determinato modello. Fornisce i parametri ottimizzabili seguenti, i cui valori predefiniti possono essere recuperati da un modello a oggetti.

MinSurfaceCoverage

La proprietà MinSurfaceCoverage indica il valore da considerare come un'istanza rilevata.

Per ogni candidato all'oggetto, un osservatore calcola il rapporto tra le superfici sovrapposte tra il modello a oggetti trasformato e la scena, quindi segnala il candidato all'applicazione solo quando il rapporto di copertura è superiore a una determinata soglia.

IsExpectedToBeStandingOnGroundPlane

La proprietà IsExpectedToBeStandingOnGroundPlane indica se l'oggetto di destinazione deve essere in piedi sul piano di terra.

Un piano terra è il piano orizzontale più basso nell'area di ricerca. Fornisce un buon vincolo sulle possibili pose dell'oggetto. L'attivazione di questo flag guiderà l'osservatore a stimare la posizione in uno spazio limitato e potrebbe migliorare l'accuratezza. Questo parametro verrà ignorato se il modello non deve stare sul piano terra.

ExpectedMaxVerticalOrientationInDegrees

La proprietà ExpectedMaxVerticalOrientationInDegrees indica l'angolo massimo previsto in gradi tra la direzione superiore di un'istanza dell'oggetto e la gravità.

Questo parametro fornisce un altro vincolo sulla direzione in su di una posizione stimata. Ad esempio, se un oggetto è a destra, questo parametro può essere 0. Gli ancoraggi di oggetti non devono rilevare oggetti diversi dal modello. Se un modello è verso l'alto, non rileverà un'istanza impostata side-down. Per il layout side-down verrà usato un nuovo modello. La stessa regola si applica per l'articolazione.

MaxScaleChange

La proprietà MaxScaleChange indica la modifica massima della scala degli oggetti (entro 0 ~ 1) rispetto al mapping spaziale. La scala stimata viene applicata ai vertici oggetto trasformati centrati in corrispondenza dell'origine e allineati all'asse. Le scale stimate potrebbero non essere la scala effettiva tra un modello CAD e la relativa rappresentazione fisica, ma alcuni valori che consentono all'app di eseguire il rendering di un modello a oggetti vicino al mapping spaziale sull'oggetto fisico.

SearchAreas

La proprietà SearchAreas indica una matrice di limiti spaziali in cui trovare gli oggetti.

L'osservatore cercherà gli oggetti nello spazio unione di tutte le aree di ricerca specificate in una query. In questa versione verrà restituito al massimo un oggetto con maggiore attendibilità per ridurre la latenza.

Objectinstance

ObjectInstance rappresenta una posizione ipotetica in cui un'istanza di un determinato modello potrebbe trovarsi nel sistema di coordinate HoloLens. Ogni istanza viene fornita con una SurfaceCoverage proprietà per indicare quanto sia buona la posizione stimata.

Un'istanza viene creata chiamando ObjectObserver.DetectAsync il metodo , quindi aggiornata automaticamente in background quando attiva. Un'applicazione può ascoltare l'evento di modifica dello stato in una determinata istanza o modificare la modalità di rilevamento per sospendere o riprendere l'aggiornamento. Un'istanza verrà rimossa automaticamente dall'osservatore quando il rilevamento viene perso.

ObjectDiagnosticsSession

ObjectDiagnosticSession registra la diagnostica e scrive i dati in un archivio.

Un archivio di diagnostica include il cloud del punto di scena, lo stato dell'osservatore e le informazioni sui modelli. Queste informazioni sono utili per identificare i possibili problemi di runtime. Per altre informazioni, vedere la sezione Domande frequenti.

Dettagli e utilizzo dell'SDK di runtime

Questa sezione contiene le nozioni di base su come usare Runtime SDK. Dovrebbe fornire un contesto sufficiente per esplorare le applicazioni di esempio per vedere come vengono usati gli ancoraggi di oggetti in modo olistico.

Inizializzazione

Le applicazioni devono chiamare l'API ObjectObserver.IsSupported() per determinare se gli ancoraggi di oggetti sono supportati nel dispositivo prima di usarlo. Se l'API ObjectObserver.IsSupported() restituisce false, verificare che l'applicazione abbia abilitato la funzionalità spatialPerception e\o eseguire l'aggiornamento al sistema operativo HoloLens più recente.

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
}

Successivamente, l'applicazione crea un osservatore oggetto e carica i modelli necessari generati dal servizio di conversione del modello Ancoraggi oggetti.

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.

L'applicazione crea una query per rilevare le istanze di tale modello all'interno di uno spazio.

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

Per impostazione predefinita, ogni istanza rilevata verrà rilevata automaticamente dall'osservatore. Facoltativamente, è possibile modificare queste istanze modificando la modalità di rilevamento o ascoltando l'evento di modifica dello stato.

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

Nell'evento di modifica dello stato è possibile eseguire una query sullo stato più recente o eliminare un'istanza se ha perso il rilevamento.

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

Inoltre, un'applicazione può registrare facoltativamente una o più sessioni di diagnostica per il debug 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"));

Infine, le risorse vengono rilasciate eliminando tutti gli oggetti.

using Microsoft.Azure.ObjectAnchors;

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

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