Gestione dell'energia elettrica e delle termiche

Quando l'HoloLens 2 è in esecuzione in ambienti ad accesso frequente o con requisiti di prestazioni elevati (utilizzo cpu/GPU, utilizzo delle periferiche e così via), potrebbe risultare abbastanza caldo che vengano eseguite azioni automaticamente per evitare il surriscaldamento. Queste azioni includono elementi come:

  • Regolazione delle prestazioni di ricarica
  • Fornire commenti e suggerimenti degli utenti
  • Chiusura delle applicazioni

... e negli scenari peggiori:

  • Arresto del HoloLens 2

Se l'applicazione richiede prestazioni periferiche elevate, è consigliabile usare PowerTermalNotification Software Development Kit (SDK) per sottoscrivere gli eventi di notifica e implementare azioni personalizzate. In questo modo il dispositivo può funzionare più a lungo in situazioni in cui in caso contrario un'applicazione può essere terminata dal sistema.

Nota

Il supporto per Microsoft.MixedReality.PowerTermalNotification SDK è incluso nella versione 22H1.

Questo articolo descrive PowerTermalNotification SDK e il relativo utilizzo di base per iniziare.

Dove si ottiene l'SDK?

PowerTermalNotification SDK è scaricabile tramite Realtà mista Feature Tool.

PowerTermalNotification SDK supporta proiezioni del linguaggio per C# e C++, consentendo agli sviluppatori di sviluppare applicazioni per piattaforme Win32 o UWP.

Panoramica dei concetti

La potenza consumata dal HoloLens 2 è dissasa in calore. Un dispositivo PC tradizionale avrebbe una ventola per risolvere questo problema, ma un dispositivo indossabile deve essere leggero. Per questo motivo, la soluzione di raffreddamento è più complessa. HoloLens 2 dispone di funzionalità predefinite per la sicurezza hardware e software per garantire che il visore VR non sia troppo caldo per l'utente, ma queste funzionalità devono essere bilanciate anche con l'esperienza utente. Ad esempio, se sappiamo quale parte del HoloLens 2 sta riscaldando, possiamo scegliere di limitare le periferiche responsabili di questo calore. Come ultima risorsa, potremmo chiudere un'applicazione che si pensa di essere responsabile della potenza che ha portato a questo calore.

HoloLens 2 gestisce i problemi di calore usando sensori di temperatura. Un framework termico collega gruppi di sensori a periferiche diverse nel dispositivo. I sensori sono raggruppati perché potrebbe essere impossibile determinare quale periferica in un'area fisica è responsabile del disegno di alimentazione che riscalda la HoloLens 2.

PowerTermalNotification SDK espone le API necessarie per monitorare questi gruppi di sensori. Gli eventi DELL'SDK vengono attivati quando una periferica usata dall'applicazione indica che potrebbe essere necessaria una mitigazione. L'applicazione può quindi adattare l'esperienza del cliente per ridurre l'impatto termico. La riduzione dell'impatto comporta un minor rischio di azione del sistema, ad esempio l'arresto dell'applicazione o del dispositivo.

Un semplice esempio è un'applicazione che usa la CPU per elaborare una grande quantità di dati video. L'applicazione potrebbe sottoscrivere una notifica delle prestazioni per il componente CPU. Quando l'applicazione riceve una notifica, può ridurre il carico di lavoro della CPU. Se viene ricevuto un altro evento che indica che non è necessaria ulteriore mitigazione, è possibile ripristinare il carico di lavoro della CPU.

Risposta della piattaforma

La tabella seguente è una suddivisione delle azioni di sistema per periferica. Le azioni descritte di seguito possono essere eliminate tramite l'SDK. Vedere Eliminazione delle mitigazioni predefinite del sistema

Periferica MinimumUserImpact MediumUserImpact MaximumUserImpact Ultima risorsa Arresto software Failsafe
GPU Limitare l'intervallo VSYNC per la regolazione della qualità
MRC
Visualizza Riduzione degli FPS di profondità
Qualsiasi periferica Visualizza avviso
Chiusura applicazione
Arresta acquisizione MRC
Arresto del sistema operativo Arresto hardware

Nota

Le azioni nelle colonne "Last Resort", "Arresto software" e "Failsafe" non possono essere eliminate.

Suggerimenti per la risposta dell'applicazione

Di seguito è riportata una suddivisione delle mitigazioni suggerite che un'applicazione può adottare in base alle periferiche che richiedono la mitigazione. Spetta allo sviluppatore dell'applicazione determinare quale di queste azioni può avere un effetto più significativo su ogni periferica, perché ogni applicazione è diversa. Gli sviluppatori devono classificare in ordine di priorità le azioni eseguite in base all'impatto per l'utente finale.

Mitigazioni suggerite per periferica

CPU

GPU

DRAM

Rete

Batteria

Visualizza

  • Aumentare il numero di pixel neri nella scena
  • Usare colori a basso consumo (ad esempio, verde)
  • Dim il display

Fotocamera/videocamera

  • Panoramica
  • Ridurre la risoluzione della fotocamera
  • Ridurre la frequenza dei fotogrammi della fotocamera
  • Ridurre l'elaborazione post-elaborazione delle immagini della fotocamera
  • Interrompere l'uso della fotocamera/videocamera

Casi d'uso dell'implementazione

L'SDK è progettato per supportare due casi d'uso standard per ottenere informazioni:

  • Basato su eventi
  • Basato sul polling

La notifica basata su eventi fornirà il percorso di feedback più rapido all'applicazione nel caso in cui sia necessario eseguire l'azione. Tuttavia, in alcuni casi potrebbe essere più conveniente per lo sviluppatore usare il polling.

Nota

Le informazioni sullo stato vengono aggiornate, al massimo, ogni pochi secondi per ogni periferica, in modo che il polling sia più veloce di quello che potrebbe perdere cicli di CPU.

Utilizzo dell'API basata su eventi

Registrazione per gli eventi

Per ottenere notifiche, sono previsti tre requisiti:

Non si riceveranno eventi se l'applicazione non soddisfa questi requisiti.

Il primo elemento può essere controllato usando la funzione IsSupported . Se il sistema supporta le notifiche per almeno una delle periferiche nella maschera, la funzione restituirà true. È possibile scegliere di non controllare il supporto usando questa funzione, purché l'applicazione non dipende in modo esplicito da eventi di PowerTermalNotification SDK.

Dopo aver soddisfatto i tre requisiti precedenti, si riceveranno le notifiche iniziali per tutte le periferiche supportateOfInterest. Se successivamente si modifica PerifericheOfInterest o uno dei gestori eventi, si riceverà un altro set di notifiche in base allo stato corrente.

Ecco un frammento di codice per acquisire l'istanza della classe PowerTermalNotification e configurarla per le notifiche per powerTermalPeripheralFlags.Cpu e PowerTermalPeripheralFlags.PhotoVideoCamera:

using Microsoft.MixedReality.PowerThermalNotification;

private void NotificationHandler(object sender, PowerThermalEventArgs args)
{
    //  Notification handling can be done here using information contained in args
}

private void InitializeThermalNotifications()
{
    PowerThermalNotification p = PowerThermalNotification.GetForCurrentProcess();
    
    PowerThermalPeripheralFlags requestedFlags = PowerThermalPeripheralFlags.Cpu | PowerThermalPeripheralFlags.PhotoVideoCamera;
     if (PowerThermalNotification.IsSupported(requestedFlags))
    {
        //At least one of these peripherals is supported by the system
        p.PeripheralsOfInterest = requestedFlags;
        p.PowerThermalMitigationLevelChanged += NotificationHandler;
    }  
}

Gestione degli eventi

Quando viene attivato l'evento PowerTermalMitigationLevelChanged , viene fornito con PowerTermalEventArgs. Questi devono essere usati per comprendere l'evento.

Analogamente, quando viene attivato l'evento PowerTermalTermalScoreChanged , viene fornito con PowerTermalScoreArgs.

Quando viene ricevuto un evento, il gestore eventi deve controllare args. InteressatiPeriferiferi, che identifica quali periferiche sono interessate (potrebbero esserci più di una).

Per gli eventi PowerTermalMitigationLevelChanged , l'args. MitigazioneLevel indica la gravità di una mitigazione consigliata per le periferiche specificate. Se l'args. MitigationLevel è PowerTermalMitigationLevel.NoUserImpact , quindi è necessario rimuovere eventuali mitigazioni associate alle periferiche specificate.

Per gli eventi PowerTermalTermalScoreChanged , gli args. ThermalScore indica un punteggio compreso tra 100 e 0 che riflette una scala lineare che avvicina un evento di arresto dell'applicazione (zero). L'intervallo di punteggio termica inizia all'esterno dell'intervallo di report di mitigazione per consentire la notifica precedente all'applicazione quando si avvicina la necessità di mitigazioni.

Ecco un gestore di esempio:

bool doCpuThrottle = false;

private void NotificationHandler(object sender, PowerThermalEventArgs args)
{
    if (args.ImpactedPeripherals.HasFlag(PowerThermalPeripheralFlags.Cpu))
    {
        if(args.MitigationLevel = PowerThermalMitigationLevel.NoUserImpact)
        {
            doCpuThrottle = false;
        }
        else if(args.MitigationLevel >= PowerThermalMitigationLevel.MinimumUserImpact)
        {
            // Note that this only kicks in at MinimumUserImpact and does not get released until NoUserImpact
            doCpuThrottle = true;
        }
    }

    if (args.ImpactedPeripherals.HasFlag(PowerThermalPeripheralFlags.PhotoVideoCamera))
    {
        SetMitigationStatus(PhotoVideoCameraStatusText, PhotoVideoRectangle, args.MitigationLevel);
    }
}

Nota

Il parametro ImpactedPeripherals di args identifica solo le periferiche interessate e parte di PeripheralsOfInterest. Non verranno identificate altre periferiche interessate non incluse in PerifericheOfInterest.

Nota

I livelli di mitigazione per le periferiche hanno isteesi. Quando il livello aumenta, non diminuisce fino a quando non viene rilasciato. La versione è un evento con args. MitigazioneLevel impostata su PowerTermalMitigationLevel.NoUserImpact.

Messa insieme (modello basato su eventi)

Ecco un semplice esempio di un set di script che possono essere usati in Unity per abilitare questa funzionalità. La classe NotificationComponent può essere aggiunta a qualsiasi oggetto gioco e tale oggetto gioco può tenere traccia del livello di mitigazione della periferica assegnata. La classe NotificationManager gestisce le sottoscrizioni dell'SDK tramite l'unica istanza della classe PowerTermalNotification .

Ecco la classe NotificationManager:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

using Microsoft.MixedReality.PowerThermalNotification;

public class NotificationManager
{
    private static readonly object listLock = new object();
    private static List<NotificationComponent> components = new List<NotificationComponent>();
    private static PowerThermalNotification p = PowerThermalNotification.GetForCurrentProcess();
    private static bool FirstTime = true;

    private static void NotificationHandler(object sender, PowerThermalEventArgs args)
    {
        lock (listLock)
        {
            foreach (NotificationComponent c in components)
            {
                UnityEngine.WSA.Application.InvokeOnAppThread(() =>
                {
                    c.SetMitigationLevel(args.ImpactedPeripherals, args.MitigationLevel);
                }, false);
            }
        } 
    }

    public static void ChangeSuppression(PowerThermalPeripheralFlags peripherals, bool suppress)
    {
        p.SuppressPlatformMitigation(peripherals, suppress);
    }

    public static void AddNotification(NotificationComponent component, PowerThermalPeripheralFlags peripheralsOfInterest)
    {
        if (FirstTime)
        {
            p.PowerThermalMitigationLevelChanged += NotificationHandler;
            FirstTime = false;
        }
        
        if (PowerThermalNotification.IsSupported(peripheralsOfInterest))
        {
            lock (listLock)
            {
                component.SetMitigationLevel(peripheralsOfInterest, (PowerThermalMitigationLevel)0);
                components.Add(component);
            }
            p.PeripheralsOfInterest |= peripheralsOfInterest;
        }
    }
}

Ecco la classe NotificationComponent:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using Microsoft.MixedReality.PowerThermalNotification;

public class NotificationComponent : MonoBehaviour
{
    //Note that this could be multiple peripherals, just need to make sure to look at impactedPeripherals in the handler
    public PowerThermalPeripheralFlags monitoredPeripheral = (PowerThermalPeripheralFlags) 0;
    public bool isSuppressed = false;

    public void SetMitigationLevel(PowerThermalMitigationLevel level)
    {
        Color newColor = Color.white;

        if (level == PowerThermalMitigationLevel.NoUserImpact)
        {
            newColor = Color.green;
        }
        else if (level == PowerThermalMitigationLevel.MinimumUserImpact)
        {
            newColor = Color.yellow;
        }
        else if (level == PowerThermalMitigationLevel.MediumUserImpact)
        {
            newColor = new Color32(255, 127, 37, 255);//Orange
        }
        else
        {
            newColor = Color.red;
        }

        MaterialPropertyBlock props = new MaterialPropertyBlock();
        props.SetColor("_Color", newColor);
        GetComponent<Renderer>().SetPropertyBlock(props);
    }

    public void SetMitigationLevel(PowerThermalPeripheralFlags impactedPeripherals, PowerThermalMitigationLevel level)
    {
        if (impactedPeripherals.HasFlag(monitoredPeripheral))
        {
            SetMitigationLevel(level);
        }
    }

    void Start()
    {
        NotificationManager.AddNotification(this, monitoredPeripheral);
        NotificationManager.ChangeSuppression(monitoredPeripheral, isSuppressed);
    }

}

Utilizzo dell'API basata sul polling

Aggiornamento delle periferiche di interesse

Analogamente all'utilizzo basato su eventi, è necessario impostare la proprietà PeripheralsOfInterest per eseguire il polling di una determinata periferica.

Avviso

Se si tenta di chiamare GetLastPeripheralState per una determinata periferica senza prima impostare tale flag in PeripheralsOfInterest, verrà generata un'eccezione. Analogamente, se si tenta di usare GetLastPeripheralState con un valore non valido (più bit di flag impostati o un bit non supportato), verrà generata un'eccezione.

Chiamata delle API di polling

Dopo aver impostato i bit di perifericheOfInterest che si desidera eseguire il polling, è possibile chiamare getLastPeripheralState.

L'oggetto PowerTermalPeripheralState restituito contiene i valori più recenti per il punteggio termica e il livello di mitigazione per la periferica specificata.

Nota

È possibile che in piattaforme future, alcune periferiche potrebbero non essere supportate. In questi casi l'API restituirà un punteggio termica pari a 100 e un livello di mitigazione di NoUserImpact. L'applicazione può controllare il campo IsSupportedPeripheral della struttura per verificare se si tratta o meno di una determinata periferica.

Vedere Gestione degli eventi per informazioni dettagliate sulla gestione del punteggio termica e sulla mitigazioneLevel restituita da PowerTermalPeripheralState.

Ecco un piccolo frammento che mostra il polling:

private async void timerCallback(object state)
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        PowerThermalNotification p = PowerThermalNotification.GetForCurrentProcess();

        PowerThermalPeripheralState CpuState = p.GetLatestPeripheralState(PowerThermalPeripheralFlags.Cpu);
        PowerThermalPeripheralState PhotoVideoCameraState = p.GetLatestPeripheralState(PowerThermalPeripheralFlags.PhotoVideoCamera);
        
        CpuScoreText.Text = CpuState.ThermalScore.ToString();
        PhotoVideoScoreText.Text = PhotoVideoCameraState.ThermalScore.ToString();
    });
}

private void InitializeThermalNotifications()
{
    PowerThermalNotification p = PowerThermalNotification.GetForCurrentProcess();

    PowerThermalPeripheralFlags requestedFlags = PowerThermalPeripheralFlags.Cpu | PowerThermalPeripheralFlags.PhotoVideoCamera;
    p.SuppressedPlatformMitigationForPeripherals = requestedFlags;//Suppress any platform mitigation on CPU or PhotoVideoCamera

    if (PowerThermalNotification.IsSupported(requestedFlags))
    {
        p.PeripheralsOfInterest = requestedFlags;

        Timer timer = new Timer(timerCallback, null, 0, 3000);
    }
    else
    {
        TitleLabel.Text = "Not Supported";
    }
}

Eliminazione delle mitigazioni predefinite del sistema

Se non si vuole che il sistema tenti di attenuare determinate periferiche, è possibile eliminarle. A tale scopo, è sufficiente aggiornare la proprietà SuppressedPlatformMitigationForPeripherals o chiamare la funzione SuppressPlatformMitigation .

Ecco un piccolo frammento di codice:

PowerThermalNotification p = PowerThermalNotification.GetForCurrentProcess();
PowerThermalPeripheralFlags requestedFlags = PowerThermalPeripheralFlags.Cpu | PowerThermalPeripheralFlags.PhotoVideoCamera;

//You can do this to set the property explicitly
p.SuppressedPlatformMitigationForPeripherals = requestedFlags;

//Or you can do this to manipulate the property mask. 
//This specific example clears the CPU, leaving the PhotoVideoCamera suppressed
p.SuppressPlatformMitigation(PowerThermalPeripheralFlags.Cpu, false);

Nota

Le API di eliminazione funzioneranno solo se il processo che usa la classe PowerTermalNotification è in primo piano. I processi in background possono comunque sottoscrivere eventi, ma potrebbero non disabilitare le azioni di HoloLens 2.

Test

Dopo aver integrato l'SDK nell'applicazione, si vuole testarlo. Per HoloLens 2 sistemi operativi che supportano l'SDK, una pagina per sviluppatori sarà disponibile in Device Portal. Da questa pagina è possibile controllare i livelli di mitigazione e i punteggi termica per ogni periferica. È anche possibile monitorare le periferiche con mitigazioni che vengono eliminate attivamente.

È anche possibile sfruttare le API REST per monitorare o testare i livelli di mitigazione e i punteggi termici da un altro dispositivo. Altre informazioni sono disponibili nella guida di riferimento all'API Portale dispositivi