La fusion de capteurs consiste à combiner les mesures de plusieurs capteurs pour obtenir un résultat plus précis, plus stable ou plus complet que ce qu'un capteur seul pourrait fournir. Pour les développeurs IoT, c'est souvent ce qui fait la différence entre un signal instable qui dérive et un signal digne de confiance dans un tableau de bord ou un modèle. Cet article explique simplement les principales approches de fusion, indique quand fusionner en edge plutôt que dans le cloud, et fournit du code ESP32 et Python fonctionnel qui publie les valeurs fusionnées via MQTT.
Pourquoi combiner des capteurs
Chaque capteur a ses faiblesses. Un accéléromètre mesure bien l'inclinaison quand l'appareil est immobile, mais la moindre vibration le perturbe. Un gyroscope mesure la rotation de façon fluide, mais l'angle obtenu par intégration dérive avec le temps. Le GPS donne une position absolue, mais se met à jour lentement et saute sous les arbres ; l'odométrie des roues est fluide mais accumule les erreurs. Deux sondes de température bon marché placées dans la même cuve divergent légèrement et présentent chacune des pics occasionnels.
La fusion exploite le fait que ces faiblesses sont différentes. Si un capteur est bruité en haute fréquence et qu'un autre dérive en basse fréquence, leur combinaison donne un signal bon sur toute la bande. Si deux capteurs mesurent la même grandeur avec des bruits indépendants, une combinaison pondérée est plus précise que chacun d'eux pris isolément. Et lorsqu'un capteur tombe en panne, une estimation fusionnée peut détecter l'incohérence au lieu de rapporter silencieusement une valeur erronée.
Les trois niveaux de fusion de capteurs
| Niveau | Ce qui est combiné | Exemple | Méthode typique |
|---|---|---|---|
| Bas niveau (données) | Mesures brutes d'une même grandeur | Deux sondes de température, accéléromètre plus gyroscope | Moyenne pondérée, filtre complémentaire, filtre de Kalman |
| Niveau caractéristiques | Caractéristiques dérivées de différents capteurs | RMS vibratoire plus courant moteur plus température | Vecteurs de caractéristiques pour un modèle de ML |
| Niveau décision | Sorties de détecteurs distincts | La caméra indique « personne », le PIR indique « mouvement » | Vote, règles, combinaison bayésienne |
Cet article se concentre sur la fusion bas niveau, car c'est là que se situent des filtres comme le filtre complémentaire et le filtre de Kalman. La fusion au niveau des caractéristiques est l'entrée quotidienne des modèles de machine learning, comme dans le machine learning pour la maintenance prédictive, où vibrations, température et courant révèlent ensemble une dégradation qu'aucun ne montre clairement seul.
Le filtre complémentaire
Le filtre complémentaire est la méthode de fusion utile la plus simple et un bon point de départ pour les capteurs inertiels. Pour estimer un angle d'inclinaison, il intègre la vitesse angulaire du gyroscope pour les variations à court terme et ramène doucement le résultat vers l'angle de l'accéléromètre pour éliminer la dérive à long terme :
angle = alpha * (angle + gyro_rate * dt) + (1 - alpha) * accel_angle
Avec alpha autour de 0,98 et une période d'échantillonnage de 10 ms, le gyroscope domine sur des fractions de seconde et l'accéléromètre sur quelques secondes. Le filtre ne nécessite aucune matrice, s'exécute en quelques microsecondes sur un microcontrôleur et se règle facilement : augmentez alpha si la sortie est bruitée, diminuez-le si elle dérive.
Le filtre de Kalman
Le filtre de Kalman généralise la même idée. Il conserve une estimation de l'état et de sa propre incertitude, prédit l'évolution de l'état, puis corrige cette prédiction à chaque mesure en pondérant la correction selon la confiance qu'il accorde à la mesure par rapport à la prédiction. Quand la mesure est bruitée, le filtre s'appuie sur la prédiction ; quand la prédiction est incertaine, il s'appuie sur la mesure.
Pour une seule grandeur mesurée par deux capteurs, la mise à jour de Kalman est assez courte pour être lue en entier :
import json
import random
import time
import uuid
import paho.mqtt.client as mqtt
class Kalman1D:
def __init__(self, x0, p0=1.0, q=0.001):
self.x, self.p, self.q = x0, p0, q # estimation, sa variance, bruit de processus
def predict(self):
self.p += self.q
def update(self, z, r):
k = self.p / (self.p + r) # gain de Kalman
self.x += k * (z - self.x)
self.p *= (1 - k)
return self.x
BASE = f"connectmq/demo/{uuid.uuid4().hex[:8]}/tank1"
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="fusion-" + uuid.uuid4().hex[:8])
client.connect("broker.connectmq.com", 1883, keepalive=60)
client.loop_start()
kf = Kalman1D(x0=20.0)
true_temp = 20.0
R_PT100, R_NTC = 0.05 ** 2, 0.4 ** 2 # variances de mesure issues des fiches techniques ou d'essais
for _ in range(300):
true_temp += random.gauss(0, 0.02)
pt100 = true_temp + random.gauss(0, 0.05)
ntc = true_temp + random.gauss(0, 0.4) + (5 if random.random() < 0.02 else 0) # pic occasionnel
kf.predict()
if abs(ntc - kf.x) < 3 * (R_NTC + kf.p) ** 0.5: # écarter les mesures invraisemblables
kf.update(ntc, R_NTC)
fused = kf.update(pt100, R_PT100)
payload = {"ts": int(time.time() * 1000), "value": round(fused, 3), "variance": round(kf.p, 6),
"raw": {"pt100": round(pt100, 3), "ntc": round(ntc, 3)}}
client.publish(f"{BASE}/temperature/fused", json.dumps(payload))
time.sleep(1)
client.loop_stop()
client.disconnect()
Installez la dépendance avec pip install paho-mqtt et abonnez-vous avec mosquitto_sub -h broker.connectmq.com -p 1883 -i fusion-watch-$RANDOM -t "connectmq/demo/+/tank1/#" -v pour voir la valeur fusionnée à côté des mesures brutes. Remarquez le filtrage : les mesures qui s'écartent de l'estimation courante de plus de trois écarts-types sont ignorées, et c'est ainsi que le filtre rejette les pics de la sonde NTC. Publier la variance avec la valeur permet aux consommateurs de connaître le degré de confiance de l'estimation.
Pour les problèmes multidimensionnels, comme la position et la vitesse issues d'un GPS et d'une IMU, la même structure utilise des matrices, et les systèmes non linéaires recourent au filtre de Kalman étendu ou unscented. Des bibliothèques comme FilterPy en Python ou les filtres de Madgwick et de Mahony pour l'orientation vous évitent de les implémenter à la main.
Fusionner en edge : exemple ESP32
La fusion inertielle doit s'exécuter au plus près du capteur, car elle a besoin d'échantillons rapides et régulièrement espacés, souvent à 100 Hz ou plus. Publier chaque échantillon brut via MQTT gaspillerait bande passante et batterie, et ajouterait de la gigue. La meilleure approche consiste à fusionner sur l'appareil et à publier le résultat à une cadence modérée.
Ce sketch lit un MPU6050 en I2C sur un ESP32, exécute un filtre complémentaire à 100 Hz et publie l'angle de tangage fusionné deux fois par seconde vers broker.connectmq.com. Il utilise les bibliothèques Adafruit MPU6050 et PubSubClient.
#include <WiFi.h>
#include <PubSubClient.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
const char* WIFI_SSID = "YOUR_WIFI";
const char* WIFI_PASS = "YOUR_WIFI_PASSWORD";
const char* BROKER = "broker.connectmq.com";
const char* TOPIC = "connectmq/demo/imu-7f3a/arm1/pitch";
WiFiClient net;
PubSubClient mqtt(net);
Adafruit_MPU6050 mpu;
float pitch = 0.0f;
const float ALPHA = 0.98f;
unsigned long lastSample = 0, lastPublish = 0;
void connectMqtt() {
while (!mqtt.connected()) {
String id = "esp32-imu-" + String((uint32_t)ESP.getEfuseMac(), HEX);
if (!mqtt.connect(id.c_str())) delay(2000);
}
}
void setup() {
Serial.begin(115200);
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) delay(500);
mqtt.setServer(BROKER, 1883);
if (!mpu.begin()) {
Serial.println("MPU6050 not found");
while (true) delay(1000);
}
mpu.setGyroRange(MPU6050_RANGE_250_DEG);
mpu.setFilterBandwidth(MPU6050_BAND_44_HZ);
lastSample = micros();
}
void loop() {
if (!mqtt.connected()) connectMqtt();
mqtt.loop();
if (micros() - lastSample >= 10000) { // 100 Hz
float dt = (micros() - lastSample) / 1e6f;
lastSample = micros();
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
float accelPitch = atan2f(-a.acceleration.x,
sqrtf(a.acceleration.y * a.acceleration.y + a.acceleration.z * a.acceleration.z)) * 180.0f / PI;
float gyroRate = g.gyro.y * 180.0f / PI; // rad/s vers deg/s
pitch = ALPHA * (pitch + gyroRate * dt) + (1.0f - ALPHA) * accelPitch;
}
if (millis() - lastPublish >= 500) { // 2 messages par seconde
lastPublish = millis();
char payload[64];
snprintf(payload, sizeof(payload), "{\"pitch\":%.2f,\"unit\":\"deg\"}", pitch);
mqtt.publish(TOPIC, payload);
}
}
Remplacez le segment de topic imu-7f3a par une valeur unique. Pour un appareil en production, passez à WiFiClientSecure sur le port 8883 avec vos nom d'utilisateur, mot de passe et client ID ConnectMQ ; le tutoriel ESP32 MQTT détaille la configuration TLS.
Fusion en edge ou dans le cloud : comment choisir
- Fusionnez en edge lorsque les capteurs sont sur le même appareil, que les fréquences d'échantillonnage sont élevées, que la latence compte (équilibrage, stabilisation, sécurité) ou que la bande passante et la batterie sont limitées.
- Fusionnez dans le cloud ou sur un serveur lorsque les capteurs sont sur des appareils différents, que les cadences sont faibles, que vous avez besoin du contexte historique ou que vous voulez modifier l'algorithme sans mise à jour du firmware.
- Publiez les deux pendant un temps lors du développement : les valeurs brutes à cadence réduite et les valeurs fusionnées, afin de vérifier le filtre par rapport à la réalité.
- Horodatez toujours à la source lorsque vous fusionnez des données de plusieurs appareils, car l'ordre d'arrivée au broker n'est pas l'ordre des mesures.
C'est le même compromis que celui présenté dans qu'est-ce que l'edge AI : le calcul se déplace là où se trouvent les données et les exigences de latence.
Les pièges courants de la fusion de capteurs
- Paramètres de bruit erronés. Un filtre de Kalman ne vaut que ce que valent ses hypothèses sur le bruit de mesure et de processus. Mesurez le bruit à partir d'un enregistrement à l'arrêt plutôt que de le deviner.
- Axes et unités incohérents. Les gyroscopes renvoient souvent des rad/s ; les axes de l'accéléromètre peuvent être montés différemment de ce que vous supposez. Vérifiez les signes en inclinant la carte à la main.
- Échantillonnage irrégulier. Les filtres supposent un
dtconnu. Calculez-le à partir des horodatages plutôt que de supposer une constante. - Sources non synchronisées. Fusionner deux appareils dont les horloges diffèrent de plusieurs secondes produit des artefacts. Synchronisez-les avec NTP et transmettez les horodatages de la source.
- Masquage des défauts de capteur. La fusion peut masquer un capteur défaillant. Publiez des indicateurs de santé bruts ou les valeurs d'innovation pour que les défauts restent visibles, ce qui alimente aussi la détection d'anomalies IoT.
Où vont ensuite les données fusionnées
Les valeurs fusionnées constituent de meilleures entrées pour les tableaux de bord, les alertes et les modèles. ConnectMQ joue le rôle de broker MQTT managé qui les achemine des appareils vers les consommateurs : l'explorateur de topics en direct affiche côte à côte les topics fusionnés et bruts, et des règles d'alerte à seuil peuvent se déclencher sur une valeur fusionnée, par exemple un angle d'inclinaison au-delà d'une limite de sécurité. Pour voir plus largement comment modèles et objets connectés fonctionnent ensemble, consultez le guide IA et IoT.
Démarrer avec ConnectMQ
Essayez d'abord les exemples sur le serveur MQTT public gratuit, réservé aux tests et aux prototypes et non aux données de production, puis créez gratuitement un broker Serverless sur app.connectmq.com, sans carte bancaire, pour obtenir des identifiants privés et le TLS pour vos appareils.
Questions fréquentes
Qu'est-ce que la fusion de capteurs en IoT ?
La fusion de capteurs combine les mesures de plusieurs capteurs pour produire une estimation plus précise, plus stable ou plus complète que celle d'un capteur seul, par exemple un angle d'inclinaison sans dérive obtenu à partir d'un accéléromètre et d'un gyroscope.
Faut-il utiliser un filtre complémentaire ou un filtre de Kalman ?
Commencez par un filtre complémentaire pour les problèmes d'orientation simples sur microcontrôleur. Utilisez un filtre de Kalman lorsque vous devez combiner des capteurs aux caractéristiques de bruit connues, estimer plusieurs états liés ou indiquer une incertitude.
La fusion de capteurs doit-elle s'exécuter sur l'appareil ou dans le cloud ?
Exécutez-la sur l'appareil lorsque les capteurs sont locaux et rapides, car envoyer chaque échantillon brut coûte cher et ajoute de la gigue. Exécutez-la de manière centralisée lorsque les capteurs sont sur des appareils différents ou que la fréquence de mise à jour est faible.
Puis-je encore accéder aux données brutes si je fusionne en edge ?
Oui. Une approche courante consiste à publier en continu les valeurs fusionnées et, sur des topics séparés, les valeurs brutes à cadence réduite ou à la demande, ce qui limite la bande passante tout en permettant la vérification.



