Gestion de l’alimentation et des thermiques

Lorsque le HoloLens 2 est en cours d’exécution dans des environnements chauds ou avec des exigences de performances élevées (utilisation du processeur/GPU, utilisation de périphérique, etc.), il peut être assez chaud qu’il prend automatiquement des mesures pour s’empêcher de surchauffer. Ces actions incluent des éléments tels que :

  • Ajustement des performances de chargement
  • Fournir des commentaires sur l’utilisateur
  • Fermeture d’applications

... et dans les pires scénarios :

  • Arrêt de la HoloLens 2

Si votre application exige des performances périphériques élevées, envisagez d’utiliser le Kit de développement logiciel PowerThermalNotification (SDK) 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ù 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 commencer.

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.

PowerThermalNotification SDK 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 dans la chaleur. Un appareil PC traditionnel aurait un ventilateur pour s’attaquer à cela, mais un appareil portable doit être léger. En raison de cela, la solution de refroidissement est plus complexe. HoloLens 2 dispose de fonctionnalités de sécurité matérielle et logicielle intégrées pour s’assurer que le casque n’est 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 de la HoloLens 2 se ré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 la puissance 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 du tirage de l’alimentation qui ré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 affiche 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 risque d’action système telle que 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 qui indique 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 est 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). Voir Suppression des atténuations système par défaut

Périphérique MinimumUserImpact MediumUserImpact MaximumUserImpact Dernier recours Arrêt logiciel Échec de la sécurité
GPU Limiter l’intervalle VSYNC de la qualité
du CRM
Affichage Réduction du FPS de profondeur
Tout périphérique Afficher la capture d’arrêt
de l’application de fermeture d’application
Arrêt du système d’exploitation Arrêt matériel

Notes

Les actions dans les colonnes « Last Resort », « Arrêt logiciel » et « Failsafe » ne peuvent pas être supprimées.

Suggestions pour la réponse d’application

Voici une répartition des atténuations suggérées qu’une application peut prendre en fonction des périphériques qui ont besoin d’atténuation. Il est possible que le développeur d’applications détermine lequel 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 prennent 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 à faible puissance (par exemple, vert)
  • Imez 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 de l’application des images de caméra
  • Arrêter d’utiliser l’appareil photo/vidéo

Cas d’usage d’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 les événements
  • Basé sur l’interrogation

La notification basée sur les événements fournit le chemin 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, afin d’interroger plus rapidement que cela peut gaspiller les cycles du processeur.

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

Inscription aux événements

Pour recevoir des notifications, il existe trois exigences :

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 un des périphériques dans le masque, la fonction retourne true. Vous pouvez choisir de ne pas vérifier la prise en charge à l’aide de cette fonction tant que votre application ne dépend pas explicitement des événements du Kit de développement logiciel (SDK) PowerThermalNotification.

Une fois que vous avez satisfait aux trois exigences ci-dessus, vous recevrez les notifications initiales pour tous les PériphériquesOfInterest 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 l’état actuel.

Voici un extrait de code pour saisir l’instance de classe PowerThermalNotification et 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 arguments. ImpactedPeripherals, qui identifie les périphériques affectés (il peut y en avoir plusieurs).

Pour les événements PowerThermalMitigationLevelChanged , les arguments. 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 , toutes les atténuations associées aux périphériques spécifiés doivent être supprimées.

Pour les événements PowerThermalThermalScoreChanged , les arguments. ThermalScore indique un score compris entre 100 et 0 reflétant une échelle linéaire qui approche 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 antérieure à l’application lors de l’approche de la nécessité 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 tous deux été affectés et faisant partie de PeripheralsOfInterest. Les autres périphériques affectés qui n’ont pas été 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 version est un événement avec des arguments. MitigationLevel défini sur PowerThermalMitigationLevel.NoUserImpact.

Mise en place (modèle basé sur des é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 de la gestion des abonnements par le biais de l’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 d’abord cet indicateur dans PeripheralsOfInterest, une exception est levée. De même, si vous tentez 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.

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 de NoUserImpact. L’application peut vérifier le champ IsSupportedPeripheral de la structure pour vérifier s’il s’agit ou non du cas d’un périphérique donné.

Pour plus d’informations sur la gestion du score thermique et de 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, mettez simplement à jour la propriété SuppressedPlatformMitigationForPeripherals ou appelez 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 fonctionnent uniquement si le processus utilisant la classe PowerThermalNotification est au premier plan. Les processus en arrière-plan peuvent toujours s’abonner aux é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 souhaiterez le tester. Pour HoloLens 2 systèmes d’exploitation qui prennent en charge le Kit de développement logiciel (SDK), une page de 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. Vous trouverez plus d’informations sur la référence de l’API Device Portal