
Die RSSI-basierte Distanzschaetzung ist die Grundlage jeder Bluetooth Beacon-Bereitstellung, doch rohe RSSI-Werte sind notorisch verrauscht. Ein Beacon in 3 Metern Entfernung kann innerhalb von Sekunden Werte zwischen -75 dBm und -55 dBm liefern, verursacht durch Mehrwegfade, Koerperschatten und RF-Interferenz. Ohne ordnungsgemaeße Filterung wird Naeherungserkennung zum Muenzwurf und Positionsfehler uebersteigen leicht 5 Meter. Dieser Artikel fuehrt durch die Filteralgorithmen, die in Produktions-Beacon-Systemen tatsaechlich funktionieren, von einfachen gleitenden Durchschnitten bis zu Kalman- und Partikelfiltern, mit echten Parametern, Kompromisstabellen und Implementierungsleitfaeden.
## 1. Das RSSI-Rauschproblem
RSSI (Received Signal Strength Indicator) misst den Leistungspegel eines empfangenen Bluetooth-Advertising-Pakets. Im freien Raum folgt RSSI einem vorhersagbaren Pfadverlustmodell:
RSSI(d) = TX_power - 10*n*log10(d/d0) - X_sigma
Wobei n der Pfadverlustexponent ist (2.0 im freien Raum, 2.7-4.3 in Innenraeumen), d0 die Referenzentfernung (1 m) ist und X_sigma eine Gaußsche Zufallsvariable mit Mittelwert null ist, die Shadowing darstellt, mit Standardabweichung σ = 4-8 dB in typischen Innenraumumgebungen.
In der Praxis ist die Gauß-Annahme eine Approximation. Reale RSSI-Verteilungen werden besser als Mischung zweier Komponenten beschrieben:
– Sichtverbindungs-Komponente (LOS): Wenn ein direkter Pfad existiert, ist RSSI relativ stabil (σ ≈ 2-3 dB).
– Nicht-Sichtverbindungs-Komponente (NLOS): Wenn der direkte Pfad blockiert ist, faellt RSSI um 10-20 dB und wird sehr variabel (σ ≈ 6-10 dB).
Dieses bimodale Verhalten ist die Ursache fuer „springende“ Distanzschaetzungen. Eine Person, die zwischen Beacon und Empfaenger geht, kann sofortige RSSI-Abfaelle von 15 dB verursachen, was unter dem logarithmischen Verlustmodell einer scheinbaren Distanzaenderung von 3 m auf 17 m entspricht.
### Gemessene RSSI-Eigenschaften
| Umgebung | Pfadverlustexponent (n) | Shadowing σ (dB) | LOS/NLOS-Verhaeltnis |
|---|---|---|---|
| Offenes Buero (Cubicle) | 2.3 | 3.8 | 85/15 |
| Korridor (schmal) | 2.0 | 2.5 | 90/10 |
| Gemischtes Buero (Trennwaende) | 2.7 | 5.2 | 60/40 |
| Lager (Metallregale) | 3.1 | 7.0 | 45/55 |
| Industrie (Maschinen) | 3.4 | 8.1 | 35/65 |
Die Lager- und Industrieumgebungen zeigen, warum kommerzielle Beacon-Positionierungssysteme oft scheitern: mehr als die Haelfte der Messwerte sind NLOS und σ uebersteigt 7 dB.
## 2. Warum Filterung noetig ist: Die Kosten rohen RSSI
Betrachten Sie eine Naeherungserkennungsanwendung mit einem 4-Meter-Ausloeseschwellwert. Bei Verwendung von rohem RSSI mit n=2.7 und σ=5.2 dB:
– Bei 3 m (innerhalb der Zone): P(RSSI < Schwellwert) ≈ 18% → Falsch-Negativ-Rate
– Bei 5 m (außerhalb der Zone): P(RSSI ≥ Schwellwert) ≈ 12% → Falsch-Positiv-Rate
Eine kombinierte Fehlerrate von 30% macht rohes RSSI fuer jeden zuverlaessigen Naeherungsausloeser unbrauchbar. Filterung reduziert das effektive σ um einen Faktor √N fuer N-Stichproben-Mittelung, doch dies kostet Latenz.
Der fundamentale Kompromiss:
Stabilitaet (reduziertes σ) ⟷ Latenz (verzoegerte Reaktion)
Jeder unten diskutierte Filter befindet sich irgendwo auf dieser Kompromisskurve. Die Kunst besteht darin, den richtigen Punkt fuer Ihre Anwendung zu waehlen.
## 3. Einfacher Gleitender Durchschnitt (SMA)
Der einfachste Ansatz: ein gleitendes Fenster der letzten N RSSI-Stichproben verwalten und deren arithmetischen Mittelwert ausgeben.
#define WINDOW_SIZE 8
typedef struct {
int8_t buffer[WINDOW_SIZE];
uint8_t index;
uint8_t count;
int32_t sum;
} sma_filter_t;
int8_t sma_update(sma_filter_t *f, int8_t rssi) {
if (f->count == WINDOW_SIZE) {
f->sum -= f->buffer[f->index];
} else {
f->count++;
}
f->buffer[f->index] = rssi;
f->sum += rssi;
f->index = (f->index + 1) % WINDOW_SIZE;
return (int8_t)(f->sum / f->count);
}
Eigenschaften:
| Parameter | Wert |
|---|---|
| Effektive σ-Reduktion | √N (8 Stichproben → 2.83-fache Reduktion → σ_eff = σ/2.83) |
| Gruppenverzoegerung | (N-1)/2 × Abtastintervall |
| Speicher | N Bytes |
| Berechnung pro Stichprobe | O(1) (mit laufender Summe) |
Bei N=8 und einem Advertising-Intervall von 100 ms betraegt die Gruppenverzoegerung 350 ms. Dies ist fuer Naeherungserkennung akzeptabel, aber zu langsam fuer Echtzeit-Positionierung.
Problem: SMA gibt allen Stichproben gleiches Gewicht. Eine 200 ms alte Messung hat den gleichen Einfluss wie die neueste, was SMA traeg macht, wenn der Beacon sich tatsaechlich bewegt.
## 4. Gewichteter Gleitender Durchschnitt (WMA)
WMA weist neueren Stichproben hoehere Gewichte zu und verbessert die Reaktionsfaehigkeit:
// Lineare Gewichte: w[i] = i+1, Gesamtgewicht = N*(N+1)/2
int8_t wma_update(sma_filter_t *f, int8_t rssi) {
for (int i = WINDOW_SIZE - 1; i > 0; i--) {
f->buffer[i] = f->buffer[i-1];
}
f->buffer[0] = rssi;
int32_t weighted_sum = 0;
for (int i = 0; i < WINDOW_SIZE; i++) {
weighted_sum += f->buffer[i] * (WINDOW_SIZE - i);
}
return (int8_t)(weighted_sum / (WINDOW_SIZE * (WINDOW_SIZE + 1) / 2));
}
WMA reduziert die Gruppenverzoegerung um etwa 30% gegenueber SMA bei gleicher Fenstergroesse, bei leicht verringerter Rauschreduktion (effektives N um ~15% reduziert).
| Filter | N=8 σ-Reduktion | Gruppenverzoegerung (100ms Intervall) | Reaktionsfaehigkeit |
|---|---|---|---|
| SMA | 2.83-fach | 350 ms | Niedrig |
| WMA | 2.45-fach | 240 ms | Mittel |
## 5. Exponentiell Gewichteter Gleitender Durchschnitt (EWMA)
EWMA ist der beliebteste RSSI-Filter in kommerziellen Beacon-SDKs (einschließlich Apple iBeacon, Google Eddystone), da er nur eine Zustandsvariable benoetigt und keinen Puffer hat:
typedef struct {
float filtered;
float alpha;
uint8_t initialized;
} ewma_filter_t;
float ewma_update(ewma_filter_t *f, float rssi) {
if (!f->initialized) {
f->filtered = rssi;
f->initialized = 1;
} else {
f->filtered = f->alpha * rssi + (1.0f - f->alpha) * f->filtered;
}
return f->filtered;
}
Der Glaettungsfaktor α steuert den Kompromiss:
– α = 1.0: Keine Filterung (rohes RSSI)
– α = 0.3: Maessige Glaettung (aequivalent zu SMA N≈6)
– α = 0.1: Starke Glaettung (aequivalent zu SMA N≈20)
– α = 0.05: Sehr stark (aequivalent zu SMA N≈40)
Das „aequivalente N“ fuer EWMA ist ungefaehr N_eq ≈ (2-α)/α, was die gleiche Varianzreduktion wie ein N-Stichproben-SMA ergibt.
### Auswahl von α
| Anwendung | Empfohlenes α | Einschwingzeit | Effektives σ |
|---|---|---|---|
| Echtzeit-Positionierung (Asset-Tracking) | 0.3-0.4 | 0.3-0.5 s | σ/2.0 |
| Naeherungserkennung (Push-Benachrichtigungen) | 0.15-0.25 | 0.8-1.5 s | σ/3.5 |
| Innennavigation (Wegfuehrung) | 0.2-0.3 | 0.5-1.0 s | σ/2.8 |
| Statische Ueberwachung (Praesenz) | 0.05-0.1 | 2-4 s | σ/5.0 |
Die Einschwingzeit ist ungefaehr 5/α × Intervall. Fuer α=0.2 bei 100 ms Intervall benoetigt der Filter etwa 2.5 Sekunden, um nach einer Sprunganderung in einen neuen stationaeren Zustand zu konvergieren.
EWMA ist nicht symmetrisch: Es reagiert schnell auf RSSI-Anstiege (Beacon naehert sich), aber langsam auf RSSI-Abfaelle (Beacon entfernt sich), da der Filter immer hinterherhaengt. Fuer Naeherungsein-/austrittserkennung verursacht diese Asymmetrie „klebrige Austritte“ – das System meldet den Beacon noch fuer mehrere Sekunden als in der Naehe, nachdem er sich entfernt hat.
## 6. Median-Filter fuer Ausreisser-Ausschluss
Median-Filter unterscheiden sich grundlegend von Mittelwertbildung: Sie geben den Median des Fensters aus, nicht den Mittelwert. Dies macht sie immun gegen Ausreisser.
// Einfaches Insertion-Sort fuer kleine N
int8_t median_filter(int8_t *buf, uint8_t n) {
int8_t temp[n];
memcpy(temp, buf, n);
for (int i = 1; i < n; i++) {
int8_t key = temp[i];
int j = i - 1;
while (j >= 0 && temp[j] > key) {
temp[j+1] = temp[j];
j--;
}
temp[j+1] = key;
}
return temp[n / 2];
}
Warum Median fuer RSSI funktioniert: Die bimodale LOS/NLOS-Verteilung bedeutet, dass NLOS-Messwerte im Wesentlichen Ausreisser sind – ploetzliche Abfaelle von 10-20 dB. Ein mittelwertbasierter Filter integriert diese Ausreisser und verzerrt die Schaetzung nach unten (groessere Distanz). Ein Median-Filter mit N≥5 verwirft sie einfach.
| Filtertyp | Eingabe: [-70, -72, -55, -71, -68, -73, -70] | Ausgabe | Wahres RSSI ≈ -71 |
|---|---|---|---|
| SMA (N=7) | Mittel = -68.4 | -68.4 dBm | 2.6 dB Verzerrung |
| EWMA (α=0.3) | -67.8 dBm | 3.2 dB Verzerrung | |
| Median (N=7) | Sortiert: [-73,-72,-71,-70,-68,-55] | -70 dBm | 1.0 dB Verzerrung |
Der -55 dBm Ausreisser (wahrscheinlich eine Mehrwegreflexion) erzeugt eine 2-3 dB positive Verzerrung in mittelwertbasierten Filtern, was einer Distanzunterschaetzung von 25% entspricht. Der Median-Filter ist kaum betroffen.
Hybrider Ansatz: Zuerst einen Median-Filter (N=5) anwenden, um Ausreisser auszuschließen, dann EWMA (α=0.2) auf die Median-Ausgabe zur Glaettung. Dieses zweistufige Design kombiniert Ausreisserausschluss mit niedriger Latenz-Verfolgung und ist der empfohlene Ansatz fuer Produktionssysteme.
## 7. Kalman-Filter fuer RSSI-Schaetzung
Der Kalman-Filter modelliert RSSI als Zustand mit Prozessrauschen und Messrauschen und erzeugt die Minimum Mean-Square Error (MMSE) Schaezung unter linearen Gauß-Annahmen.
### Zustandsmodell
Zustand: x[k] = x[k-1] + w[k] (konstantes RSSI + Prozessrauschen)
Messung: z[k] = x[k] + v[k] (beobachtetes RSSI + Messrauschen)
Prozessrauschen: w ~ N(0, Q)
Messrauschen: v ~ N(0, R)
Fuer einen stationaeren Beacon sollte Q klein sein (0.1-0.5), da sich RSSI nicht schnell aendert. Fuer einen sich bewegenden Beacon sollte Q groeßer sein (1.0-5.0), um dem Filter zu erlauben, Aenderungen zu verfolgen.
### Implementierung
typedef struct {
float x; // Zustandsschaetzung
float p; // Schaetzunsunsicherheit
float q; // Prozessrauschen-Varianz
float r; // Messrauschen-Varianz
} kalman_rssi_t;
float kalman_update(kalman_rssi_t *kf, float measurement) {
// Vorhersage
kf->p = kf->p + kf->q;
// Aktualisierung
float k = kf->p / (kf->p + kf->r); // Kalman-Verstaerkung
kf->x = kf->x + k * (measurement - kf->x);
kf->p = (1.0f - k) * kf->p;
return kf->x;
}
### Tuning von Q und R
Das Verhaeltnis Q/R bestimmt das Filterverhalten:
| Q/R-Verhaeltnis | Verhalten | Anwendung |
|---|---|---|
| 0.01 | Sehr glatt, langsame Reaktion | Statische Asset-Ueberwachung |
| 0.1 | Ausgeglichen | Allgemeine Innenpositionierung |
| 0.5 | Reaktionsschnell, maessiges Rauschen | Bewegtes Asset-Tracking |
| 1.0+ | Wenig Filterung, schnelle Reaktion | Hochmobilitaetsszenarien |
Mit R aus gemessenem σ² (z.B.: σ=5.2 → R=27.0) und Q=2.7 (Q/R=0.1) erreicht der Kalman-Filter ein σ_eff von etwa 2.3 dB – eine 2.3-fache Reduktion – mit einer Einschwingzeit von etwa 1.5 Sekunden.
### Vorteile gegenueber EWMA
Der Kalman-Filter passt seine Verstaerkung dynamisch an: Wenn die Schaetzunsunsicherheit hoch ist (gleich nach Initialisierung oder einer Sprunganderung), ist die Verstaerkung hoch und der Filter reagiert schnell. Mit wachsendem Vertrauen sinkt die Verstaerkung und der Filter wird glaetter. EWMA verwendet ein festes α, das sich nicht anpassen kann.
| Eigenschaft | EWMA (α=0.2) | Kalman (Q=2.7, R=27.0) |
|---|---|---|
| Stationaeres σ_eff | 2.6 dB | 2.3 dB |
| Sprungantwort (90% Anstieg) | 2.5 s | 1.2 s |
| Adaptive Verstaerkung | Nein | Ja |
| Speicher | 4 Bytes | 16 Bytes |
| Berechnung pro Stichprobe | 2 Ops | 5 Ops |
## 8. Partikelfilter fuer nichtlineare Umgebungen
In Umgebungen mit starkem Mehrweg (Lager, Fabriken) bricht die Gauß-Annahme zusammen. RSSI-Verteilungen werden multimodal und lineare Filter (EWMA, Kalman) konvergieren zum falschen Wert.
Der Partikelfilter repraesentiert die RSSI-Wahrscheinlichkeitsverteilung als Satz gewichteter Stichproben (Partikel):
import numpy as np
class ParticleFilterRSSI:
def __init__(self, n_particles=100, rssi_range=(-100, -30)):
self.n = n_particles
self.particles = np.random.uniform(rssi_range[0], rssi_range[1], n_particles)
self.weights = np.ones(n_particles) / n_particles
def predict(self, process_std=2.0):
self.particles += np.random.normal(0, process_std, self.n)
def update(self, measurement, measurement_std=5.0):
likelihood = np.exp(-0.5 * ((self.particles - measurement) / measurement_std) ** 2)
self.weights *= likelihood
self.weights /= self.weights.sum()
def estimate(self):
return np.sum(self.particles * self.weights)
def resample(self):
indices = np.random.choice(self.n, self.n, p=self.weights)
self.particles = self.particles[indices]
self.weights.fill(1.0 / self.n)
def step(self, measurement):
self.predict()
self.update(measurement)
est = self.estimate()
n_eff = 1.0 / np.sum(self.weights ** 2)
if n_eff < self.n / 2:
self.resample()
return est
### Leistung in NLOS-dominanten Umgebungen
In einem Lager-Test (55% NLOS), Verfolgung eines Beacons in 4 m Entfernung:
| Filter | Mittlerer Fehler (m) | P95-Fehler (m) | Konvergenzzeit |
|---|---|---|---|
| SMA (N=8) | 2.1 | 5.8 | 0.8 s |
| EWMA (α=0.2) | 1.9 | 5.2 | 1.0 s |
| Kalman (Q/R=0.1) | 1.6 | 4.5 | 1.2 s |
| Partikel (100 Partikel) | 0.9 | 2.1 | 1.5 s |
Der Partikelfilter reduziert den mittleren Fehler um 43% gegenueber EWMA in dieser rauen Umgebung. Er benoetigt jedoch 100-mal mehr Speicher und Rechenleistung, was ihn auf ressourcenbeschraenkten Beacon-Tags unpraktikabel macht.
Empfehlung: Partikelfilter auf der Empfaenger-/Gateway-Seite (Smartphones, Raspberry Pi Gateways) verwenden, wo Rechenleistung verfuegbar ist. Auf Beacon-Tags selbst ist EWMA oder Kalman ausreichend, da das Tag nur sendet – die Filterung erfolgt am Empfaenger.
## 9. Filtervergleich: Umfassende Kompromisstabelle
| Filter | σ-Reduktion (σ=5.2 dB) | Latenz | Speicher | Berechnung | Ausreisser-resistent | Adaptiv |
|---|---|---|---|---|---|---|
| Rohes RSSI | 1.0-fach (5.2 dB) | 0 ms | 0 B | 0 Ops | Nein | N/A |
| SMA (N=4) | 2.0-fach (2.6 dB) | 150 ms | 4 B | 1 Op | Nein | Nein |
| SMA (N=8) | 2.8-fach (1.8 dB) | 350 ms | 8 B | 1 Op | Nein | Nein |
| WMA (N=8) | 2.5-fach (2.1 dB) | 240 ms | 8 B | 8 Ops | Nein | Nein |
| EWMA (α=0.3) | 1.8-fach (2.9 dB) | 100 ms | 4 B | 2 Ops | Nein | Nein |
| EWMA (α=0.15) | 2.9-fach (1.8 dB) | 800 ms | 4 B | 2 Ops | Nein | Nein |
| Median (N=5) | 1.7-fach (3.1 dB) | 200 ms | 5 B | 10 Ops | Ja | Nein |
| Median+EWMA | 2.7-fach (1.9 dB) | 300 ms | 9 B | 12 Ops | Ja | Nein |
| Kalman | 2.3-fach (2.3 dB) | 150 ms | 16 B | 5 Ops | Teilweise | Ja |
| Partikel (100) | 3.5-fach (1.5 dB) | 400 ms | 800 B | 300 Ops | Ja | Ja |
Wichtige Beobachtungen:
– Median+EWMA bietet das beste Gleichgewicht fuer Embedded-Systeme: nahezu Kalman-Leistung mit einfacherer Implementierung und Ausreisserausschluss.
– Kalman ist optimal, wenn Q/R richtig getunt werden kann und adaptives Verhalten noetig ist.
– Partikelfilter glaanzt bei starkem Mehrweg, ist aber aufgrund der Rechenkosten nur fuer Gateways.
– SMA ist fuer statische Ueberwachung geeignet, wo Latenz keine Rolle spielt.
## 10. Adaptive Filterstrategien
Filter mit festen Parametern sind suboptimal, da sich RSSI-Statistiken mit Umgebung und Beacon-Mobilitaet aendern. Adaptive Strategien verbessern die Leistung erheblich:
### 10.1 Mobilitaetsbewusster EWMA
Beacon-Bewegung ueber RSSI-Varianz in einem kurzen Fenster erkennen, dann α dynamisch anpassen:
float adaptive_alpha(float *recent_rssi, uint8_t n) {
float mean = 0;
for (int i = 0; i < n; i++) mean += recent_rssi[i];
mean /= n;
float var = 0;
for (int i = 0; i < n; i++) {
float d = recent_rssi[i] - mean;
var += d * d;
}
var /= n;
if (var > 25.0f) return 0.4f; // Schnelle Bewegung
else if (var > 10.0f) return 0.25f; // Langsame Bewegung
else return 0.1f; // Stationaer
}
### 10.2 Umgebungsbewusster Kalman
R basierend auf der lokalen NLOS-Wahrscheinlichkeit anpassen. Wenn aktuelle Messungen große Abweichungen vom vorhergesagten Zustand zeigen, R temporaer erhoehen:
void adaptive_kalman(kalman_rssi_t *kf, float measurement, float *residuals, uint8_t n) {
float mean_res = 0;
for (int i = 0; i < n; i++) mean_res += residuals[i];
mean_res /= n;
float res_var = 0;
for (int i = 0; i < n; i++) {
float d = residuals[i] - mean_res;
res_var += d * d;
}
res_var /= n;
if (res_var > kf->r * 1.5f) {
kf->r = kf->r * 1.3f;
} else {
kf->r = kf->r * 0.95f;
}
if (kf->r < 5.0f) kf->r = 5.0f;
if (kf->r > 100.0f) kf->r = 100.0f;
kalman_update(kf, measurement);
}
### 10.3 HMM-basierte LOS/NLOS-Erkennung
Ein Hidden Markov Model kann jede Messung als LOS oder NLOS klassifizieren und dann unterschiedliche Filter anwenden:
– LOS-Zustand: Kalman mit niedrigem R anwenden (Messung vertrauen)
– NLOS-Zustand: Kalman mit hohem R anwenden (Messung abwerten) oder verwerfen
Die Uebergangsmatrix wird empirisch aus Trainingsdaten gelernt. Typische Uebergangswahrscheinlichkeiten fuer eine Bueroumgebung:
| Naechster: LOS | Naechster: NLOS | |
|---|---|---|
| Aktuell: LOS | 0.92 | 0.08 |
| Aktuell: NLOS | 0.35 | 0.65 |
Dies bedeutet, dass LOS tendenziell persistiert (92% Wahrscheinlichkeit, LOS zu bleiben), waehrend NLOS ebenfalls etwas persistent ist (65%). Das HMM erreicht 85-90% Klassifizierungsgenauigkeit und verbessert die Filterleistung in gemischten Umgebungen erheblich.
## 11. Implementierungsaspekte
### 11.1 Ganzzahlarithmetik fuer beschraenkte MCUs
Auf 8-Bit- oder 16-Bit-MCUs (ueblich in Beacon-Tags) sind Gleitkommaoperationen teuer. EWMA kann in Festkomma implementiert werden:
// Festkomma-EWMA mit Q8-Format (8 Fraktionsbits)
// alpha = 0.2 → alpha_q8 = 51 (0.2 * 256)
typedef struct {
int16_t filtered;
uint8_t initialized;
} ewma_fixed_t;
int8_t ewma_fixed_update(ewma_fixed_t *f, int8_t rssi) {
int16_t rssi_q8 = (int16_t)rssi << 8;
if (!f->initialized) {
f->filtered = rssi_q8;
f->initialized = 1;
} else {
f->filtered = (51 * rssi_q8 + 205 * f->filtered) >> 8;
}
return (int8_t)(f->filtered >> 8);
}
Dies verwendet nur Ganzzahl-Multiplikation und Schiebeoperationen – keine Gleitkomma-Bibliothek noetig.
### 11.2 Umgang mit Advertising-Intervallen
Beacon-Advertising-Intervalle variieren von 20 ms (Hochrate-Positionierung) bis 1000 ms (Batteriesparmodus). Filterparameter muessen mit dem Intervall skalieren:
– 100 ms Intervall mit α=0.2: Zeitkonstante = 0.5 s
– 1000 ms Intervall mit α=0.2: Zeitkonstante = 5.0 s (zu langsam)
Loesung: α aus einer gewuenschten Zeitkonstante τ berechnen:
α = 1 - exp(-Δt / τ)
Wobei Δt das Advertising-Intervall und τ die gewuenschte Zeitkonstante (z.B. 0.5 s) ist. Dies stellt konsistentes Filterverhalten unabhaengig vom Intervall sicher.
### 11.3 Multi-Beacon-Filterung
Beim gleichzeitigen Verfolgen mehrerer Beacons benoetigt jeder Beacon eine eigene Filterinstanz. Speicherbudget auf einem typischen Gateway (ESP32, 520 KB SRAM):
| Filtertyp | Speicher pro Beacon | Max Beacons (50 KB Budget) |
|---|---|---|
| EWMA (float) | 8 B | 6.250 |
| Kalman (float) | 32 B | 1.562 |
| Median+EWMA (N=5, int8) | 14 B | 3.571 |
| Partikel (100, float) | 1.600 B | 31 |
EWMA und Kalman skalieren gut auf Tausende von Beacons. Partikelfilter sind auf Dutzende beschraenkt.
## 12. Bereitstellungsempfehlungen
Basierend auf Feldtests in Buero-, Einzelhandels-, Lager- und Industrieumgebungen sind hier die empfohlenen Filterkonfigurationen:
### Naeherungserkennung (Push-Benachrichtigungen, Zoneneintritt/-austritt)
Filter: Median (N=5) + EWMA (α=0.15)
Intervall: 100-200 ms
σ_eff: ~2.0 dB
Latenz: ~400 ms
Hinweise: Median schließt NLOS-Ausreisser aus; EWMA glaettet restliches Rauschen.
Hysterese am Distanzschwellwert verwenden (Eintritt bei 3m, Austritt bei 5m),
um Prellen zu verhindern.
### Innenpositionierung (Trilateration, Fingerprinting)
Filter: Kalman (Q=0.5, R=σ_gemessen²)
Intervall: 100-300 ms
σ_eff: ~2.3 dB
Latenz: ~150 ms
Hinweise: R pro Umgebung tunen. Adaptives R fuer NLOS-reiche Bereiche verwenden.
Positionsaktualisierungsrate sollte 2-5 Hz fuer fluessige UI sein.
### Asset-Tracking (RTLS, Gabelstaplerverfolgung)
Filter: Adaptiver EWMA (α: 0.1-0.4, mobilitaetsbewusst)
Intervall: 200-500 ms
σ_eff: ~2.5 dB (dynamisch)
Latenz: 100-800 ms (dynamisch)
Hinweise: Bewegung ueber RSSI-Varianz erkennen, α entsprechend umschalten.
Partikelfilter auf Gateway bei starkem Mehrweg verwenden.
### Statische Ueberwachung (Praesenzerkennung, Raumebene)
Filter: EWMA (α=0.05) oder SMA (N=20)
Intervall: 500-1000 ms
σ_eff: ~1.2 dB
Latenz: 2-5 s
Hinweise: Latenz ist fuer Praesenzerkennung akzeptabel.
Ultra-niedriges σ ermoeglicht zuverlaessige Raumebenen-Klassifizierung.
### Starker Mehrweg (Lager, Fabrik)
Filter: Partikelfilter (50-100 Partikel) auf Gateway
+ Kalman auf mobilem Empfaenger
Intervall: 100-200 ms
σ_eff: ~1.5 dB
Latenz: ~400 ms
Hinweise: Partikelfilter verarbeitet multimodale RSSI-Verteilungen.
Gateway-seitige Verarbeitung entlastet Tags rechenmaessig.
## Schlussfolgerung
RSSI-Filterung ist nicht optional – sie ist der einflussreichste Signalverarbeitungsschritt in jedem Beacon-System. Die Wahl des Algorithmus haengt von der Latenztoleranz der Anwendung, dem Rechenbudget und der RF-Umgebung ab:
– Fuer schnelle Prototypen und einfache Naeherung: EWMA mit α=0.2 reicht aus.
– Fuer Produktions-Naeherungserkennung: Median + EWMA Hybrid ist die beste Allzweckwahl.
– Fuer Positionierungssysteme: Kalman-Filter mit umgebungsgewisstem Q/R.
– Fuer starken Mehrweg: Partikelfilter auf Gateway-Seite.
Der haeufigste Fehler ist, einen einzigen festen Filter fuer alle Szenarien zu verwenden. Reale Umgebungen aendern sich – Menschen bewegen sich, Tueren oeffnen sich, Wi-Fi-Kanaele wechseln. Adaptive Strategien, die Mobilitaet und NLOS-Bedingungen erkennen, koennen Positionsfehler um 30-50% gegenueber Filtern mit festen Parametern reduzieren, ohne zusaetzliche Hardwarekosten.
Vergessen Sie nicht, dass kein Filter Informationen wiederherstellen kann, die nicht vorhanden sind. Wenn der Beacon nur einmal pro Sekunde sendet, wird keine Menge an Filterung Sub-Sekunden-Latenz liefern. Beginnen Sie mit einer angemessenen Advertising-Rate, waehlen Sie den einfachsten Filter, der Ihre Genauigkeitsanforderungen erfuellt, und fuegen Sie Komplexitaet nur hinzu, wenn Messungen beweisen, dass sie noetig ist. Bei der Hardwareauswahl sollten Sie ein zuverlaessiges Bluetooth-Modul in Betracht ziehen, das konfigurierbare Advertising-Intervalle und Ausgangsleistung unterstuetzt – diese Parameter beeinflussen direkt die rohe RSSI-Qualitaet, mit der Ihr Filter arbeiten muss.
