Aller au contenu

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

ClasseDescription
coronaType de décharge couronne (Corona discharge)
floatingType de décharge sur électrode flottante (Floating electrode)
surfaceType de décharge de surface (cheminement superficiel, Surface)
noiseBruit 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/status depuis un navigateur, ou vérifiez la valeur firmware_version dans la réponse de l’API REST GET /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émentValeur
Nom du topic/fx_{hardware_id}/prpd
Type de messagefx_stream_msgs/msg/Prpd
Taille du message52 B/message
Bande passante moyenneenviron 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).

ChampTypeDescription
noisefloat32[3]logit de la classe noise pour les canaux CH0~CH2 (score sans dimension)
coronafloat32[3]logit de la classe corona pour les canaux CH0~CH2 (score sans dimension)
floatingfloat32[3]logit de la classe floating pour les canaux CH0~CH2 (score sans dimension)
surfacefloat32[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.

Canalnoise (logit)corona (logit)floating (logit)surface (logit)Résultat de classification (argmax)Probabilité (softmax)
ch0-0.962.98-3.550.30corona0.918 ( 91.8 % )
ch14.485.88-5.45-1.51corona0.802 ( 80.2 % )
ch2-6.54-1.390.730.45floating0.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 :

softmax(xi)=exij=1Kexj\text{softmax}(x_i) = \frac{e^{x_i}}{\sum_{j=1}^{K} e^{x_j}}

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 :

softmax(xi)=eximax(x)j=1Kexjmax(x)\text{softmax}(x_i) = \frac{e^{x_i - \max(x)}}{\sum_{j=1}^{K} e^{x_j - \max(x)}}

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/prpd figurant 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 commande ros2 topic list.

import numpy as np
import rclpy
from 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.msg
LABELS = ['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).

Fenêtre de terminal
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=123
python3 prpd_subscriber.py

Sortie 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 prpd n’apparaît pas :

    • Vérifiez que la version du firmware est bien v1.0.3c ou ultérieure. Accédez à {CAMERA_IP}/setting/status depuis un navigateur ou vérifiez la valeur firmware_version de GET /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_ID côté réception correspond à celui de la caméra. La valeur par défaut de la caméra est 123 ; à 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 list que le topic /fx_{hardware_id}/prpd apparaî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.bash de l’espace de travail, puis relancez le script.
  • 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).
  • 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