Présentation du classificateur PRPD basé sur l'IA du FX
Présentation
À partir du firmware BATCAM FX v1.0.3c, une fonction de classification des décharges partielles basée sur l’IA, développée en interne par nos soins, est intégrée au firmware. Cette fonction s’appuie sur CUDA et ONNX Runtime et a été conçue pour classifier en temps réel les types de décharges partielles au sein de l’appareil.
Le PRPD (Phase-Resolved Partial Discharge) est une technique de diagnostic des décharges partielles qui analyse les signaux de décharge partielle par rapport à la phase de l’alimentation ; le classificateur IA du BATCAM FX prend ces données PRPD en entrée et détermine le type de décharge partielle.
Ce document explique comment l’utilisateur de cette fonction peut recevoir et exploiter les résultats de classification basés sur l’IA. Le firmware prend en charge quatre résultats de classification au total (Corona, Floating, Surface, Noise), et un résultat distinct est fourni pour chaque canal Audio LPoint (CH0~CH2).
| Classe | Description |
|---|---|
corona | Type de décharge couronne (Corona discharge) |
floating | Type de décharge sur électrode flottante (Floating electrode) |
surface | Type de décharge de surface (cheminement superficiel, Surface) |
noise | Bruit de fond ou signal ne correspondant pas à une décharge partielle |
Les résultats de classification sont fournis via deux canaux : ROS 2 et WebSocket. Pour chaque canal Audio LPoint, un logit score est fourni pour chaque type de décharge partielle pris en charge, et l’utilisateur peut en déduire le résultat de classification.
💡 Remarque : ce document porte sur le BATCAM FX. Pour les fonctions IA du BATCAM FX2, reportez-vous au document Gestionnaire d’appareils — Intelligence artificielle.
Prérequis
-
Version du firmware : firmware BATCAM FX v1.0.3c ou ultérieur. La sortie ROS 2 a été ajoutée pour la première fois en v1.0.3b, et l’ensemble des fonctionnalités, y compris la sortie WebSocket, est disponible à partir de la v1.0.3c. Pour l’historique détaillé des modifications, reportez-vous aux Notes de version du firmware.
-
Méthode de vérification de la version : accédez à la page
{CAMERA_IP}/setting/statusdepuis un navigateur, ou vérifiez la valeurfirmware_versiondans la réponse de l’API RESTGET /setting/status. (voir le Playground de l’API FX) -
Environnement ROS 2 côté réception : les fonctions ROS 2 du BATCAM FX reposent sur ROS 2 Humble Hawksbill ; le paquet de messages fx-stream-msgs, destiné à être utilisé sous Humble, a été compilé et validé avec Python 3.10.16 sous ROS 2 Jazzy (Ubuntu 24.04). (voir la Présentation de ROS)
-
Concordance du ROS_DOMAIN_ID : le ROS_DOMAIN_ID par défaut de la caméra est
123. L’environnement côté réception doit utiliser la même valeur pour que les topics soient visibles. (voir la Configuration du ROS Domain ID)
Réception des données
Topics ROS 2
Le BATCAM FX crée le topic des résultats de classification PRPD à partir de l’ID matériel de la caméra.
| Élément | Valeur |
|---|---|
| Nom du topic | /fx_{hardware_id}/prpd |
| Type de message | fx_stream_msgs/msg/Prpd |
| Taille du message | 52 B/message |
| Bande passante moyenne | environ 220 B/s |
Le message Prpd fournit, pour chacune des quatre classes, un tableau de longueur 3 contenant les valeurs de logit par canal (CH0~CH2).
| Champ | Type | Description |
|---|---|---|
noise | float32[3] | logit de la classe noise pour les canaux CH0~CH2 (score sans dimension) |
corona | float32[3] | logit de la classe corona pour les canaux CH0~CH2 (score sans dimension) |
floating | float32[3] | logit de la classe floating pour les canaux CH0~CH2 (score sans dimension) |
surface | float32[3] | logit de la classe surface pour les canaux CH0~CH2 (score sans dimension) |
Les valeurs de logit sont des scores non normalisés ; comme elles peuvent être aussi bien positives que négatives, elles doivent être interprétées d’après leurs grandeurs relatives.
La liste complète des topics ROS 2 et les définitions des messages sont rassemblées dans le paragraphe consacré aux définitions de messages de la Présentation de ROS, et la définition d’origine du format des messages peut être consultée dans le dépôt SMI OSS - fx-stream-msgs.
Flux WebSocket (Protobuf)
À partir du firmware v1.0.3c, les mêmes résultats de classification sont également fournis sous forme de flux Protobuf basé sur WebSocket. Les événements Prpd sont reçus sur le canal d’abonnement avec le Subscribe ID 3 et sont émis à environ 4 Hz sur le BATCAM FX.
Pour un exemple Python couvrant l’ensemble du processus de connexion, d’abonnement et d’analyse WebSocket, reportez-vous au document Exemple Python Protobuf. Ce document récapitule également les différences entre le FX et le FX2.
Méthode de classification
Pour chaque canal, l’utilisateur sélectionne l’élément présentant la valeur la plus élevée (argmax) parmi les valeurs de logit des quatre classes. Si vous souhaitez en outre calculer la probabilité de chaque résultat, vous devez extraire de chaque canal les valeurs correspondant aux éléments concernés et leur appliquer un softmax.
| Canal | noise (logit) | corona (logit) | floating (logit) | surface (logit) | Résultat de classification (argmax) | Probabilité (softmax) |
|---|---|---|---|---|---|---|
| ch0 | -0.96 | 2.98 | -3.55 | 0.30 | corona | 0.918 ( 91.8 % ) |
| ch1 | 4.48 | 5.88 | -5.45 | -1.51 | corona | 0.802 ( 80.2 % ) |
| ch2 | -6.54 | -1.39 | 0.73 | 0.45 | floating | 0.533 ( 53.3 % ) |
💡 Remarque d’interprétation : la probabilité softmax correspond au degré de confiance relatif entre les quatre classes. Lorsque la probabilité maximale est faible (53.3 %), comme pour le ch2 de l’exemple, cela signifie que l’écart de logit entre floating (0.73) et surface (0.45) est faible et que les deux classes sont en concurrence. Le critère de décision (seuil) déterminant l’adoption ou non d’un résultat de classification varie selon le domaine d’application et les conditions sur site ; définissez-le et appliquez-le en fonction des exigences du système que vous utilisez.
Softmax
La fonction softmax convertit un vecteur de logits en distribution de probabilité ; sa formule générale est la suivante :
Toutefois, si les valeurs de logit sont excessivement grandes ou petites, un dépassement supérieur (Overflow) ou un dépassement inférieur (Underflow) peut se produire ; le calcul s’effectue donc généralement sous la forme normalisée suivante :
La transposition de la formule ci-dessous en Python donne l’exemple suivant :
Implémentation Python
import numpy as np
def softmax(logits): logits = np.array(logits) exps = np.exp(logits - np.max(logits)) # softmax numériquement stable return exps / np.sum(exps) # renvoie les valeurs de probabilitéImplémentation Common Lisp
(defun softmax (logits) "Prend une liste ou un vecteur LOGITS et renvoie un vecteur de probabilités softmax" (let* ((vec (coerce logits 'vector)) (maxval (reduce #'max vec)) (exps (map 'vector (lambda (x) (exp (- x maxval))) vec)) (sum (reduce #'+ exps))) (map 'vector (lambda (x) (/ x sum)) exps)))Exemple complet : nœud d’abonnement rclpy
Voici un nœud Python (rclpy) complet qui s’abonne au topic PRPD et journalise le résultat de classification et la probabilité de chaque canal. Vous pouvez l’enregistrer dans un fichier unique (prpd_subscriber.py) et l’exécuter tel quel.
💡 Remarque : le nom de topic
/fx_276730383020104/prpdfigurant dans le code est un exemple ; vous devez le remplacer par celui correspondant à l’ID matériel de la caméra utilisée. Le nom réel du topic peut être vérifié avec la commanderos2 topic list.
import numpy as npimport rclpyfrom rclpy.node import Node
from fx_stream_msgs.msg import Prpd
# Libellés définis dans le même ordre que les champs de Prpd.msgLABELS = ['noise', 'corona', 'floating', 'surface']
def softmax(logits): logits = np.array(logits) exps = np.exp(logits - np.max(logits)) # softmax numériquement stable return exps / np.sum(exps)
class PrpdSubscriber(Node): def __init__(self): super().__init__('prpd_subscriber') # Remplacez le nom du topic par celui correspondant à l'ID matériel de la caméra utilisée. self.subscription = self.create_subscription( Prpd, '/fx_276730383020104/prpd', self.listener_callback, 10)
def listener_callback(self, msg: Prpd): results = []
# Pour 3 canaux (CH0 ~ CH2) for ch in range(3): logits = [ msg.noise[ch], msg.corona[ch], msg.floating[ch], msg.surface[ch], ] probs = softmax(logits) idx = int(np.argmax(probs)) results.append({ 'channel': f'CH{ch}', 'label': LABELS[idx], 'probability': round(float(probs[idx]), 3), })
# Affichage des journaux for result in results: self.get_logger().info( f"{result['channel']}: {result['label']} " f"({result['probability'] * 100:.1f}%)" )
def main(args=None): rclpy.init(args=args) node = PrpdSubscriber() try: rclpy.spin(node) except KeyboardInterrupt: pass finally: node.destroy_node() rclpy.shutdown()
if __name__ == '__main__': main()Méthode d’exécution
Sourcez l’environnement ROS 2 ainsi que l’espace de travail dans lequel le paquet de messages fx-stream-msgs a été compilé, puis lancez le script. Vous devez utiliser le même ROS_DOMAIN_ID que la caméra (valeur par défaut 123).
source /opt/ros/humble/setup.bash# Sourcez également l'espace de travail dans lequel le paquet de messages fx-stream-msgs a été compilé.export ROS_DOMAIN_ID=123python3 prpd_subscriber.pySortie attendue
En supposant que les valeurs de logit de l’exemple de la section « Méthode de classification » ci-dessus soient reçues, les journaux suivants sont affichés :
[INFO] [1748324429.123456789] [prpd_subscriber]: CH0: corona (91.8%)[INFO] [1748324429.123512345] [prpd_subscriber]: CH1: corona (80.2%)[INFO] [1748324429.123556789] [prpd_subscriber]: CH2: floating (53.3%)Implémentation de référence en Common Lisp
Voici une implémentation de référence en Common Lisp de la même logique de classification (softmax + argmax). La partie réception des messages doit être raccordée à l’environnement utilisé ; le code ci-dessous suppose que msg contient, pour (noise corona floating surface), des vecteurs de longueur 3 chacun.
; Define labels for the discharge types(defparameter *labels* #("noise" "corona" "floating" "surface"))
; Softmax function(defun softmax (logits) "Prend une liste ou un vecteur LOGITS et renvoie un vecteur de probabilités softmax" (let* ((vec (coerce logits 'vector)) (maxval (reduce #'max vec)) (exps (map 'vector (lambda (x) (exp (- x maxval))) vec)) (sum (reduce #'+ exps))) (map 'vector (lambda (x) (/ x sum)) exps)))
(defun classify-channel (noise corona floating surface) "Prend les valeurs de logit d'un canal et renvoie le libellé / la probabilité" (let* ((logits (vector noise corona floating surface)) (probs (softmax logits)) (idx (position (reduce #'max probs) probs))) (list :label (aref *labels* idx) :probability (aref probs idx))))
(defun listener-callback (msg) "On suppose que msg contient, pour (noise corona floating surface), des vecteurs de longueur 3 chacun" (loop for ch from 0 below 3 for result = (classify-channel (aref (getf msg :noise) ch) (aref (getf msg :corona) ch) (aref (getf msg :floating) ch) (aref (getf msg :surface) ch)) do (format t "CH~A: ~A (~,1F%)~%" ch (getf result :label) (* (getf result :probability) 100))))Résolution des problèmes (Troubleshooting)
-
Le topic
prpdn’apparaît pas :-
Vérifiez que la version du firmware est bien v1.0.3c ou ultérieure. Accédez à
{CAMERA_IP}/setting/statusdepuis un navigateur ou vérifiez la valeurfirmware_versiondeGET /setting/status; s’il s’agit d’une version antérieure, mettez le firmware à jour au moyen de la mise à jour par le web ou de la mise à jour par le shell. -
Vérifiez que le
ROS_DOMAIN_IDcôté réception correspond à celui de la caméra. La valeur par défaut de la caméra est123; à partir du firmware 1.0.3, elle peut être consultée et modifiée via l’API REST (/ros/domain). (voir Playground de l’API FX, Configuration du ROS Domain ID) -
Vérifiez de nouveau avec
ros2 topic listque le topic/fx_{hardware_id}/prpdapparaît bien.
-
-
L’erreur
ModuleNotFoundError: No module named 'fx_stream_msgs'se produit :- L’espace de travail dans lequel le paquet de messages fx-stream-msgs a été compilé n’est pas sourcé. Sourcez le fichier
setup.bashde l’espace de travail, puis relancez le script.
- L’espace de travail dans lequel le paquet de messages fx-stream-msgs a été compilé n’est pas sourcé. Sourcez le fichier
-
Des avertissements d’overflow/underflow apparaissent lors du calcul du softmax :
- N’exponentiez pas les valeurs de logit telles quelles ; utilisez la forme normalisée du paragraphe « Softmax » ci-dessus (exponentiation après soustraction de
np.max).
- N’exponentiez pas les valeurs de logit telles quelles ; utilisez la forme normalisée du paragraphe « Softmax » ci-dessus (exponentiation après soustraction de
-
La probabilité maximale calculée est faible :
- Il ne s’agit pas d’une erreur : cela signifie que les logits d’au moins deux classes sont proches et que ces classes sont en concurrence. Reportez-vous à la remarque d’interprétation du paragraphe « Méthode de classification » ci-dessus.
Documents associés
-
Présentation de ROS — liste complète des topics, définitions des messages et points de vigilance
-
Configuration du ROS Domain ID — méthode de modification de l’ID de domaine
-
Coordonnées du Listening Point — concept des canaux LPoint et limites de configuration
-
Notes de version du firmware — historique des modifications de la fonction PRPD par version
-
Exemple Python Protobuf — exemple d’abonnement au flux WebSocket (commun à FX/FX2)
-
Playground de l’API FX — référence des API REST telles que
/setting/status,/ros/domain, etc.