Verwalten von Energie und Thermik
Wenn die HoloLens 2 in warmen Umgebungen oder mit hohen Leistungsanforderungen (CPU-/GPU-Auslastung, Peripherienutzung usw.) ausgeführt wird, kann es so heiß werden, dass automatisch Aktionen ausgeführt werden, um eine Überhitzung zu gewährleisten. Diese Aktionen umfassen z. B.:
- Anpassen der Ladeleistung
- Bereitstellen von Benutzerfeedback
- Schließen von Anwendungen
... und im schlimmsten Fall:
- Herunterfahren des HoloLens 2
Wenn Ihre Anwendung eine hohe Peripherieleistung erfordert, sollten Sie das PowerThermalNotification Software Development Kit (SDK) verwenden, um Benachrichtigungsereignisse zu abonnieren und Ihre eigenen benutzerdefinierten Aktionen zu implementieren. Dies kann es dem Gerät ermöglichen, in Situationen länger zu arbeiten, in denen andernfalls eine Anwendung vom System beendet werden kann.
Hinweis
Unterstützung für das Microsoft.MixedReality.PowerThermalNotification SDK ist im Release 22H1 enthalten.
In diesem Artikel werden das PowerThermalNotification SDK und seine grundlegende Verwendung für die ersten Schritte beschrieben.
Wo erhalte ich das SDK?
Das PowerThermalNotification SDK kann über das Mixed Reality Feature-Tool heruntergeladen werden.
PowerThermalNotification SDK unterstützt Sprachprojektionen für C# und C++, sodass Entwickler Anwendungen für Win32- oder UWP-Plattformen entwickeln können.
Konzeptionelle Übersicht
Der vom HoloLens 2 verbrauchte Strom wird durch Wärme abgeführt. Ein herkömmliches PC-Gerät hätte einen Lüfter, um dies zu beheben, aber ein tragbares Gerät muss leicht sein. Aus diesem Grund ist die Kühllösung komplexer. HoloLens 2 verfügt über integrierte Hardware- und Softwaresicherheitsfeatures, um sicherzustellen, dass das Headset für den Benutzer nicht zu heiß wird, aber diese Features müssen auch mit der Benutzererfahrung ausgeglichen werden. Wenn wir beispielsweise wissen, welcher Teil der HoloLens 2 sich erwärmt, können wir die für diese Hitze verantwortlichen Peripheriegeräte drosseln. Als letztes Mittel könnten wir eine Anwendung schließen, von der angenommen wird, dass sie für die Leistung verantwortlich ist, die zu dieser Hitze führte.
HoloLens 2 behandelt Hitzeprobleme mithilfe von Temperatursensoren. Ein thermisches Framework bindet Gruppen von Sensoren an verschiedene Peripheriegeräte des Geräts. Die Sensoren sind gruppiert, da es unmöglich ist, zu bestimmen, welches Peripheriegerät in einem physischen Bereich für die Stromaufnahme verantwortlich ist, die die HoloLens 2 erwärmt.
Das PowerThermalNotification SDK macht die APIs verfügbar, die zum Überwachen dieser Sensorgruppen erforderlich sind. SDK-Ereignisse werden ausgelöst, wenn ein von der Anwendung verwendetes Peripheriegerät Anzeichen dafür anzeigt, dass eine Entschärfung erforderlich ist. Die Anwendung kann dann ihre Kundenerfahrung anpassen, um die thermischen Auswirkungen zu verringern. Die Verringerung der Auswirkungen bedeutet ein geringeres Risiko für Systemaktionen wie das Herunterfahren der Anwendung oder des Geräts.
Ein einfaches Beispiel wäre eine Anwendung, die die CPU verwendet, um eine große Menge an Videodaten zu verarbeiten. Die Anwendung kann eine Leistungsbenachrichtigung für die CPU-Komponente abonnieren. Wenn die Anwendung eine Benachrichtigung empfängt, kann die CPU-Workload reduziert werden. Wenn ein anderes Ereignis empfangen wird, das darauf hinweist, dass keine weitere Entschärfung erforderlich ist, kann die CPU-Workload wiederhergestellt werden.
Plattformantwort
Die folgende Tabelle enthält eine Aufschlüsselung der Systemaktionen nach Peripherie. Die unten beschriebenen Aktionen können mithilfe des SDK unterdrückt werden. Weitere Informationen finden Sie unter Unterdrücken von Standardsystemminderungen.
Periperiegerät | MinimumUserImpact | MediumUserImpact | MaximumUserImpact | Letzter Ausweg | Herunterfahren der Software | Failsafe |
---|---|---|---|---|---|---|
GPU | Drosseln des MRC-Qualitätsanpassungs-VSYNC-Intervalls |
|||||
Anzeige | Tiefen-FPS-Reduzierung | |||||
Beliebige Peripheriegeräte | Warnung anzeigen Schließen der Anwendung beenden MRC-Erfassung |
Herunterfahren des Betriebssystems | Herunterfahren der Hardware |
Hinweis
Aktionen in den Spalten "Last Resort", "Software Shutdown" und "Failsafe" können nicht unterdrückt werden.
Vorschläge zur Anwendungsantwort
Im Folgenden finden Sie eine Aufschlüsselung der vorgeschlagenen Entschärfungen, die eine Anwendung ergreifen kann, je nachdem, welche Peripheriegeräte eine Entschärfung benötigen. Es liegt beim Anwendungsentwickler, zu bestimmen, welche dieser Aktionen möglicherweise einen größeren Einfluss auf jedes Peripheriegerät haben, da jede Anwendung anders ist. Entwickler sollten Aktionen priorisieren, die sie basierend auf den Auswirkungen auf den Endbenutzer ausführen.
Vorgeschlagene Entschärfungen nach Peripherie
CPU
- Anpassen der Workload pro Frame
GPU
- Reduzieren der Renderauflösung
- Die App kann dann das Sichtfeld (Field of View, FOV) reduzieren, um die Unschärfe von Inhalten zu verrechnen.
- Reduzieren der Szenenkomplexität (Anzahl von Dreiecken und Textur)
- Reduzieren der Verarbeitung von Foto-/Videokameras
- Verringern der Kameraauflösung
- Reduzieren der Kamerabildrate
- Reduzieren der App-Nachbearbeitung von Kamerabildern
- Beenden der Verwendung der Foto-/Videokamera
DRAM
Netzwerk
- Reduzieren der Bandbreite
- Reduzieren der Bildfrequenz für Videoanrufe
- Beenden der Hintergrundnetzwerkaktivität (z. B. Anwendungstelemetrie)
Akku
- Wechseln zu einer kühleren Umgebung
- Verwenden eines Geräts ohne Ladegerät
- Vermeiden Sie das Laufen auf einem Ladegerät mit einer Aufladung von unter 50 %.
Anzeige
- Erhöhen der Anzahl schwarzer Pixel in der Szene
- Verwenden Von Low-Power-Farben (z. B. Grün)
- Abdunkeln der Anzeige
Foto-/Videokamera
- Übersicht
- Verringern der Kameraauflösung
- Reduzieren der Kamerabildrate
- Reduzieren der App-Nachbearbeitung von Kamerabildern
- Beenden der Verwendung der Foto-/Videokamera
Anwendungsfälle für die Implementierung
Das SDK wurde entwickelt, um zwei Standardanwendungsfälle zum Abrufen von Informationen zu unterstützen:
- Ereignisbasiert
- Polling-basiert
Die ereignisbasierte Benachrichtigung bietet den schnellsten Feedbackpfad für die Anwendung, falls maßnahmen erforderlich sind. In einigen Fällen kann es jedoch für den Entwickler bequemer sein, Abrufe zu verwenden.
Hinweis
Zustandsinformationen werden höchstens alle paar Sekunden für jedes Peripheriegerät aktualisiert, sodass bei einer schnelleren Abfrage CPU-Zyklen verschwendet werden können.
Ereignisbasierte API-Nutzung
Registrieren von Ereignissen
Um Benachrichtigungen zu erhalten, gibt es drei Anforderungen:
- Systemunterstützung für die API einschließlich des angegebenen Peripheriegeräts
- Eine nicht leere PeripheralsOfInterest-Eigenschaft
- Ein nicht leerer PowerThermalMitigationLevelChanged-Ereignishandler oder ein nicht leerer PowerThermalThermalScoreChanged-Ereignishandler
Sie erhalten keine Ereignisse, wenn Ihre Anwendung diese Anforderungen nicht erfüllt.
Das erste Element kann mithilfe der IsSupported-Funktion überprüft werden. Wenn das System Benachrichtigungen für mindestens eines der Peripheriegeräte in der Maske unterstützt, gibt die Funktion true zurück. Sie können die Unterstützung mithilfe dieser Funktion nicht überprüfen, solange Ihre Anwendung nicht explizit von PowerThermalNotification SDK-Ereignissen abhängig ist.
Sobald Sie die drei oben genannten Anforderungen erfüllt haben, erhalten Sie erste Benachrichtigungen für alle unterstützten PeripheriegeräteOfInterest. Wenn Sie später PeripheralsOfInterest oder einen der Ereignishandler ändern, erhalten Sie basierend auf der aktuellen status einen weiteren Satz von Benachrichtigungen.
Im Folgenden finden Sie einen Codeausschnitt zum Abrufen der PowerThermalNotification-Klasse instance und zum Konfigurieren dieser Klasse für Benachrichtigungen für PowerThermalPeripheralFlags.Cpu und PowerThermalPeripheralFlags.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;
}
}
Behandeln von Ereignissen
Wenn das PowerThermalMitigationLevelChanged-Ereignis ausgelöst wird , enthält es PowerThermalEventArgs. Diese sollten verwendet werden, um das Ereignis zu verstehen.
Analog dazu wird powerThermalScoreArgs verwendet, wenn das PowerThermalThermalScoreChanged-Ereignis ausgelöst wird.
Wenn ein Ereignis empfangen wird, sollte der Ereignishandler Args überprüfen. ImpactedPeripherals, das identifiziert, welche Peripheriegeräte betroffen sind (es kann mehrere geben).
Für PowerThermalMitigationLevelChanged-Ereignisse die Argumente. MitigationLevel gibt an, wie schwerwiegend eine Entschärfung für die angegebenen Peripheriegeräte empfohlen wird. Wenn die Argumente. MitigationLevel ist PowerThermalMitigationLevel.NoUserImpact . Dann sollten alle Entschärfungen, die den angegebenen Peripheriegeräten zugeordnet sind, entfernt werden.
Für PowerThermalThermalScoreChanged-Ereignisse die Argumente. ThermalScore gibt eine Bewertung von 100 bis 0 an, die eine lineare Skalierung widerspiegelt, die sich einem Herunterfahren der Anwendung nähert (Null). Der Wärmebewertungsbereich beginnt außerhalb des Berichtsbereichs für die Risikominderung, um eine frühere Benachrichtigung an die Anwendung zu ermöglichen, wenn die Notwendigkeit von Entschärfungen erreicht wird.
Hier ist ein Beispielhandler:
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);
}
}
Hinweis
Der ImpactedPeripherals-Parameter von args identifiziert nur die Peripheriegeräte, die sowohl betroffen als auch Teil von PeripheralsOfInterest waren. Andere betroffenen Peripheriegeräte, die nicht in PeripheralsOfInterest enthalten waren, werden nicht identifiziert.
Hinweis
Entschärfungsstufen für Peripheriegeräte weisen Hysterese auf. Sobald der Level steigt, wird er erst ab dem Release abnimmt. Das Release ist ein Ereignis mit Args. MitigationLevel auf PowerThermalMitigationLevel.NoUserImpact festgelegt.
Zusammensetzen (ereignisbasiertes Modell)
Hier sehen Sie ein einfaches Beispiel für eine Reihe von Skripts, die in Unity verwendet werden können, um diese Funktionalität zu aktivieren. Die NotificationComponent-Klasse kann jedem Spielobjekt hinzugefügt werden, und dieses Spielobjekt kann die Entschärfungsstufe des zugewiesenen Peripheriegeräts nachverfolgen. Die NotificationManager-Klasse befasst sich mit dem SDK, das Abonnements über die einzelne instance der PowerThermalNotification-Klasse verwaltet.
Dies ist die NotificationManager-Klasse:
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;
}
}
}
Dies ist die NotificationComponent-Klasse:
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);
}
}
Api-Nutzung auf Abrufbasis
Aktualisieren von Peripheriegeräten von Interesse
Ähnlich wie bei der ereignisbasierten Verwendung ist das Festlegen der PeripheralsOfInterest-Eigenschaft erforderlich, um ein bestimmtes Peripheriegerät abzufragen.
Warnung
Wenn Sie versuchen , GetLastPeripheralState für ein bestimmtes Peripheriegerät aufzurufen, ohne dieses Flag zuerst in PeripheralsOfInterest festzulegen, wird eine Ausnahme ausgelöst. Wenn Sie versuchen, GetLastPeripheralState mit einem ungültigen Wert (mehrere festgelegte Flagbits oder ein nicht unterstütztes Bit) zu verwenden, wird eine Ausnahme ausgelöst.
Aufrufen der Abruf-APIs
Sobald PeripheralsOfInterest die Peripheriebits festgelegt hat, die Sie abfragen möchten, können Sie getLastPeripheralState aufrufen.
Der zurückgegebene PowerThermalPeripheralState enthält die neuesten Werte für wärmetechnische Bewertung und Entschärfungsgrad für das angegebene Peripheriegerät.
Hinweis
Es ist möglich, dass bestimmte Peripheriegeräte in zukünftigen Plattformen möglicherweise nicht unterstützt werden. In diesen Fällen gibt die API den Wärmewert 100 und den Entschärfungsgrad NoUserImpact zurück. Die Anwendung kann das Feld IsSupportedPeripheral der Struktur überprüfen, um zu überprüfen, ob dies für ein bestimmtes Peripheriegerät der Fall ist.
Ausführliche Informationen zur Behandlung des von PowerThermalPeripheralState zurückgegebenen Wärmebewertungs- und Entschärfungsgrads finden Sie unter Behandeln von Ereignissen.
Hier sehen Sie einen kleinen Codeausschnitt, der die Abfrage zeigt:
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";
}
}
Unterdrücken von Standardsystemminderungen
Wenn Sie nicht möchten, dass das System versucht, bestimmte Peripheriegeräte zu entschärfen, können Sie sie unterdrücken. Aktualisieren Sie dazu einfach die SuppressedPlatformMitigationForPeripherals-Eigenschaft , oder rufen Sie die SuppressPlatformMitigation-Funktion auf .
Hier ist ein kleiner Codeausschnitt:
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);
Hinweis
Die Unterdrückungs-APIs funktionieren nur, wenn sich der Prozess, der die PowerThermalNotification-Klasse verwendet, im Vordergrund befindet. Hintergrundprozesse können weiterhin Ereignisse abonnieren, aber möglicherweise nicht HoloLens 2 Aktionen deaktivieren.
Testen
Nachdem Sie das SDK in Ihre Anwendung integriert haben, sollten Sie es testen. Für HoloLens 2 Betriebssysteme, die das SDK unterstützen, ist im Geräteportal eine Entwicklerseite verfügbar. Auf dieser Seite können Sie die Entschärfungsstufen und wärmetechnischen Bewertungen für jedes Peripheriegerät steuern. Sie können auch überwachen, welche Peripheriegeräte aktiv unterdrückt werden.
Sie können die REST-APIs auch nutzen, um Risikominderungsstufen und wärmetechnische Bewertungen von einem anderen Gerät aus zu überwachen/zu testen. Weitere Informationen finden Sie in der Referenz zur Geräteportal-API.