Gestion de l’alimentation et de l’énergie thermique

Lorsque le HoloLens 2 s’exécute dans des environnements chauds ou avec des exigences de performances élevées (utilisation du processeur/GPU, utilisation des périphériques, etc.), il peut devenir suffisamment chaud pour qu’il prenne automatiquement des mesures pour éviter toute surchauffe. Ces actions incluent des éléments tels que :

  • Ajustement des performances de charge
  • Fournir des commentaires des utilisateurs
  • Fermeture d’applications

... et dans les pires scénarios :

  • Arrêt du HoloLens 2

Si votre application exige des performances périphériques élevées, envisagez d’utiliser le Kit de développement logiciel (SDK) PowerThermalNotification pour vous abonner aux événements de notification et implémenter vos propres actions personnalisées. Cela peut permettre à l’appareil de fonctionner plus longtemps dans des situations où, sinon, une application peut être arrêtée par le système.

Notes

La prise en charge du Kit de développement logiciel (SDK) Microsoft.MixedReality.PowerThermalNotification est incluse dans la version 22H1.

Cet article décrit le Kit de développement logiciel (SDK) PowerThermalNotification et son utilisation de base pour vous aider à démarrer.

Où puis-je obtenir le Kit de développement logiciel (SDK) ?

Le Kit de développement logiciel (SDK) PowerThermalNotification est téléchargeable via l’outil de fonctionnalité Mixed Reality.

Le Kit de développement logiciel (SDK) PowerThermalNotification prend en charge les projections de langage pour C# et C++, ce qui permet aux développeurs de développer des applications pour les plateformes Win32 ou UWP.

Vue d'ensemble conceptuelle

L’énergie consommée par le HoloLens 2 est dissipée en chaleur. Un appareil PC traditionnel aurait un ventilateur pour résoudre ce problème, mais un appareil portable doit être léger. Pour cette raison, la solution de refroidissement est plus complexe. HoloLens 2 dispose de fonctionnalités de sécurité matérielles et logicielles intégrées pour garantir que le casque ne soit pas trop chaud pour l’utilisateur, mais ces fonctionnalités doivent également être équilibrées avec l’expérience utilisateur. Par exemple, si nous savons quelle partie du HoloLens 2 chauffe, nous pouvons choisir de limiter les périphériques responsables de cette chaleur. En dernier recours, nous pourrions fermer une application qui est considérée comme responsable de l’énergie qui a conduit à cette chaleur.

HoloLens 2 gère les problèmes de chaleur à l’aide de capteurs de température. Une infrastructure thermique lie des groupes de capteurs à différents périphériques sur l’appareil. Les capteurs sont regroupés, car il peut être impossible de déterminer quel périphérique dans une zone physique est responsable de la prise d’alimentation qui chauffe le HoloLens 2.

Le Kit de développement logiciel (SDK) PowerThermalNotification expose les API nécessaires pour surveiller ces groupes de capteurs. Les événements du KIT de développement logiciel (SDK) se déclenchent lorsqu’un périphérique utilisé par l’application montre des signes indiquant qu’une atténuation peut être nécessaire. L’application peut ensuite adapter son expérience client pour réduire l’impact thermique. La réduction de l’impact signifie moins de risques d’action système, comme l’arrêt de l’application ou de l’appareil.

Un exemple simple serait une application qui utilise le processeur pour traiter une grande quantité de données vidéo. L’application peut s’abonner à une notification de performances pour le composant processeur. Lorsque l’application reçoit une notification, elle peut réduire la charge de travail du processeur. Si un autre événement est reçu indiquant qu’aucune atténuation supplémentaire n’est nécessaire, la charge de travail du processeur peut être restaurée.

Réponse de la plateforme

Le tableau suivant présente une répartition des actions système par périphérique. Les actions décrites ci-dessous peuvent être supprimées à l’aide du Kit de développement logiciel (SDK). Consultez Suppression des atténuations système par défaut

Périphérique MinimumUserImpact MediumUserImpact MaximumUserImpact Dernier recours Arrêt logiciel Sécurité automatique
GPU Limiter l’intervalle VSYNC d’ajustement de la qualité
du CRM
Affichage Réduction des FPS de profondeur
N’importe quel périphérique Afficher l’avertissement
Fermer la capture CRM d’arrêt de l’application
Arrêt du système d’exploitation Arrêt matériel

Notes

Les actions des colonnes « Dernier recours », « Arrêt logiciel » et « Sécurité automatique » ne peuvent pas être supprimées.

Suggestions de réponse d’application

Voici une répartition des mesures d’atténuation suggérées qu’une application peut prendre en fonction des périphériques qui doivent être atténués. Il appartient au développeur d’applications de déterminer laquelle de ces actions peut avoir un effet plus significatif sur chaque périphérique, car chaque application est différente. Les développeurs doivent hiérarchiser les actions qu’ils effectuent en fonction de l’impact sur l’utilisateur final.

Atténuations suggérées par périphérique

UC

GPU

DRAM

Réseau

Batterie

Affichage

  • Augmenter le nombre de pixels noirs dans la scène
  • Utiliser des couleurs de faible puissance (par exemple, le vert)
  • Tamiser l’affichage

Appareil photo/vidéo

  • Vue d'ensemble
  • Réduire la résolution de la caméra
  • Réduire la fréquence d’images de la caméra
  • Réduire le post-traitement des images d’appareil photo par l’application
  • Arrêter d’utiliser l’appareil photo/vidéo

Cas d’usage de l’implémentation

Le Kit de développement logiciel (SDK) est conçu pour prendre en charge deux cas d’usage standard pour obtenir des informations :

  • Basé sur un événement
  • Basé sur l’interrogation

La notification basée sur les événements fournit le chemin d’accès de commentaires le plus rapide à l’application au cas où elle doit prendre des mesures. Toutefois, dans certains cas, il peut être plus pratique pour le développeur d’utiliser l’interrogation.

Notes

Les informations d’état sont mises à jour, au maximum, toutes les quelques secondes pour chaque périphérique, de sorte que l’interrogation plus rapide que cela peut gaspiller des cycles de processeur.

Utilisation de l’API basée sur les événements

Inscription aux événements

Pour recevoir des notifications, trois conditions sont requises :

Vous ne recevrez pas d’événements si votre application ne répond pas à ces exigences.

Le premier élément peut être vérifié à l’aide de la fonction IsSupported . Si le système prend en charge les notifications pour au moins l’un des périphériques du masque, la fonction retourne true. Vous pouvez choisir de ne pas case activée prise en charge à l’aide de cette fonction tant que votre application ne dépend pas explicitement des événements du SDK PowerThermalNotification.

Une fois que vous répondez aux trois exigences ci-dessus, vous recevrez des notifications initiales pour tous les périphériques Pris en charge. Si vous modifiez plus tard PeripheralsOfInterest ou l’un des gestionnaires d’événements, vous recevrez un autre ensemble de notifications en fonction de la status actuelle.

Voici un extrait de code permettant de saisir la classe PowerThermalNotification instance et de la configurer pour les notifications pour PowerThermalPeripheralFlags.Cpu et 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;
    }  
}

Gestion des événements

Lorsque l’événement PowerThermalMitigationLevelChanged se déclenche, il est fourni avec PowerThermalEventArgs. Ceux-ci doivent être utilisés pour comprendre l’événement.

De même, lorsque l’événement PowerThermalThermalScoreChanged se déclenche, il est fourni avec PowerThermalScoreArgs.

Lorsqu’un événement est reçu, le gestionnaire d’événements doit inspecter les args. ImpactedPeripherals, qui identifie les périphériques qui sont affectés (il peut y en avoir plusieurs).

Pour les événements PowerThermalMitigationLevelChanged , les args. MitigationLevel indique la gravité d’une atténuation recommandée pour les périphériques spécifiés. Si les arguments. MitigationLevel est PowerThermalMitigationLevel.NoUserImpact , puis toutes les atténuations associées aux périphériques spécifiés doivent être supprimées.

Pour les événements PowerThermalThermalScoreChanged , les args. ThermalScore indique un score de 100 à 0 reflétant une échelle linéaire proche d’un événement d’arrêt d’application (zéro). La plage de score thermique commence en dehors de la plage de rapports d’atténuation pour permettre une notification plus tôt à l’application lorsqu’elle approche du besoin d’atténuations.

Voici un exemple de gestionnaire :

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

Notes

Le paramètre ImpactedPeripherals d’args identifie uniquement les périphériques qui ont été tous deux affectés et faisant partie de PeripheralsOfInterest. Les autres périphériques impactés qui n’étaient pas inclus dans PeripheralsOfInterest ne seront pas identifiés.

Notes

Les niveaux d’atténuation pour les périphériques ont une hystérèse. Une fois que le niveau augmente, il ne diminue pas tant qu’il n’est pas libéré. La mise en production est un événement avec des args. MitigationLevel défini sur PowerThermalMitigationLevel.NoUserImpact.

Mise en place (modèle basé sur les événements)

Voici un exemple simple d’un ensemble de scripts qui peuvent être utilisés dans Unity pour activer cette fonctionnalité. La classe NotificationComponent peut être ajoutée à n’importe quel objet de jeu et cet objet de jeu peut suivre le niveau d’atténuation du périphérique affecté. La classe NotificationManager traite du KIT de développement logiciel (SDK) qui gère les abonnements via la instance unique de la classe PowerThermalNotification.

Voici 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;
        }
    }
}

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

}

Utilisation de l’API basée sur l’interrogation

Mise à jour des périphériques intéressants

À l’instar de l’utilisation basée sur les événements, la définition de la propriété PeripheralsOfInterest est nécessaire pour interroger un périphérique donné.

Avertissement

Si vous tentez d’appeler GetLastPeripheralState pour un périphérique donné sans définir au préalable cet indicateur dans PeripheralsOfInterest, une exception est levée. De même, si vous essayez d’utiliser GetLastPeripheralState avec une valeur non valide (plusieurs bits d’indicateur définis ou un bit non pris en charge), une exception est levée.

Appel des API d’interrogation

Une fois que PeripheralsOfInterest a défini le ou les bits périphériques que vous souhaitez interroger, vous pouvez appeler GetLastPeripheralState.

L’état PowerThermalPeripheralState retourné contient les valeurs les plus récentes pour le score thermique et le niveau d’atténuation pour le périphérique donné.

Notes

Il est possible que dans les futures plateformes, certains périphériques ne soient pas pris en charge. Dans ce cas, l’API retourne un score thermique de 100 et un niveau d’atténuation noUserImpact. L’application peut case activée le champ IsSupportedPeripheral de la structure pour case activée si c’est le cas ou non pour un périphérique donné.

Pour plus d’informations sur la gestion du score thermique et de l’mitigationLevel retournés par PowerThermalPeripheralState, consultez Gestion des événements.

Voici un petit extrait de code montrant l’interrogation :

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

Suppression des atténuations système par défaut

Si vous ne souhaitez pas que le système tente d’atténuer certains périphériques, vous pouvez les supprimer. Pour ce faire, il suffit de mettre à jour la propriété SuppressedPlatformMitigationForPeripherals ou d’appeler la fonction SuppressPlatformMitigation .

Voici un petit extrait de code :

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

Notes

Les API de suppression ne fonctionnent que si le processus utilisant la classe PowerThermalNotification se trouve au premier plan. Les processus en arrière-plan peuvent toujours s’abonner à des événements, mais ne peuvent pas désactiver HoloLens 2 actions.

Test

Une fois que vous avez intégré le Kit de développement logiciel (SDK) à votre application, vous pouvez le tester. Pour HoloLens 2 systèmes d’exploitation qui prennent en charge le SDK, une page développeur sera disponible dans Device Portal. À partir de cette page, vous pouvez contrôler les niveaux d’atténuation et les scores thermiques pour chaque périphérique. Vous pouvez également surveiller les périphériques dont les atténuations sont activement supprimées.

Vous pouvez également tirer parti des API REST pour surveiller/tester les niveaux d’atténuation et les scores thermiques d’un autre appareil. Pour plus d’informations, consultez la référence de l’API Device Portal