Tutorial · Principiante · 17 min di lettura
Rumore dei sensori, bias e filtraggio nella robotica
Comprendi i sensori rumorosi di un robot: differenza tra rumore, bias e deriva, come scegliere un filtro, il ritardo che aggiunge e quando la fusione è utile.
Ogni robot agisce in base a misurazioni rumorose, ritardate, affette da bias e talvolta mancanti. Trattare una lettura grezza come verità è il modo più rapido per costruire un robot che si comporta in modo imprevedibile. Questa guida presenta il vocabolario e i compromessi che devi conoscere prima di fidarti di un sensore. Sperimenta ogni effetto nel Simulatore di sensori robotici.
Rumore, bias e deriva sono problemi diversi
- Il rumore varia casualmente da un campione all’altro. La media o il filtraggio lo riduce.
- Il bias è uno scostamento fisso rispetto al valore vero. Il filtraggio non lo elimina; devi misurarlo durante la calibrazione e sottrarlo.
- La deriva è un bias che cambia lentamente nel tempo, di solito con la temperatura. Una calibrazione eseguita all’avvio smette progressivamente di corrispondere alla realtà, ed è per questo che le sessioni lunghe richiedono ricalibrazioni periodiche o un riferimento su cui effettuare la correzione.
Confonderli porta alla correzione sbagliata: più filtraggio non eliminerà mai un bias.
Scegliere un filtro
Tre filtri comuni coprono la maggior parte dei casi:
- Una media mobile e un passa-basso esponenziale uniformano entrambe il rumore casuale, scambiando reattività con uniformità attraverso la rispettiva finestra o costante di tempo.
- Un filtro mediano è migliore nell’eliminare picchi e interruzioni occasionali, perché pochi campioni errati non spostano il valore centrale.
Scegli il filtro più leggero che soddisfi i requisiti del componente che consumerà la misurazione, non quello che produce il grafico dall’aspetto più uniforme.
Il filtraggio aggiunge sempre ritardo
Ogni filtro di uniformazione ritarda il segnale reale e più uniformazione significa più ritardo. Un filtro passa-basso con una costante di tempo lunga rifiuta più rumore, ma si allontana maggiormente dai cambiamenti rapidi. Traccia sempre la stima filtrata sia accanto ai campioni grezzi sia al valore vero, così il ritardo è visibile prima di inserire il filtro in un loop di controllo, dove può causare instabilità.
class LowPass:
def __init__(self, alpha):
self.alpha = alpha # smaller alpha = smoother but more lag
self.value = None
def update(self, sample):
if self.value is None:
self.value = sample
else:
self.value += self.alpha * (sample - self.value)
return self.value
Che cosa può e che cosa non può fare la fusione dei sensori
La fusione combina più sensori in una sola stima e aiuta soltanto quando i sensori forniscono informazioni complementari e la loro incertezza è rappresentata onestamente. Combinare due misurazioni affette da bias non produce verità. Un filtro complementare, per esempio, si fida di un sensore alle alte frequenze e di un altro alle basse frequenze; un filtro di Kalman pondera ogni fonte in base alla sua incertezza. In ogni caso, inizia dalla calibrazione, dalle marche temporali e dai frame di coordinate condivisi prima di fondere qualcosa.
Aggiungi una marca temporale a tutto
I campioni arrivano raramente a intervalli perfettamente costanti e sia il filtraggio sia la fusione presuppongono che tu sappia quando è stata misurata ogni valore. Le marche temporali ti permettono di rilevare il jitter, allineare i dati di sensori diversi e scartare le letture obsolete. Registra i valori grezzi accanto a quelli elaborati, così guasti come saturazione e interruzioni restano riproducibili.
Misura il sensore prima di filtrarlo
Scegliere un filtro prima di sapere com’è fatto il rumore significa tirare a indovinare. Dieci minuti di registrazione sono sufficienti e la procedura è la stessa per qualsiasi sensore:
- Mantieni il sensore perfettamente fermo contro un ingresso noto e invariabile.
- Registra qualche migliaio di campioni grezzi con marche temporali.
- Calcola la media e la deviazione standard.
- Traccia i campioni e il loro istogramma.
Questi quattro numeri e due grafici ti dicono quale dei tre guasti hai:
| Che cosa osservi | Che cos’è | Correzione |
|---|---|---|
| La media coincide con il valore vero, i valori si disperdono simmetricamente | Rumore | Filtralo |
| La media è scostata dal valore vero, la dispersione è piccola | Bias | Misuralo e sottralo: il filtraggio non aiuterà mai |
| La media si allontana nell’arco di minuti | Deriva | Ricalibra periodicamente o correggi rispetto a un riferimento |
| Per lo più compatti, con valori estremi occasionali | Valori anomali | Mediana, non media |
| I valori si dispongono su gradini discreti | Quantizzazione | Previsto; limita la risoluzione |
L’istogramma è la parte che le persone saltano, ma è quella più informativa. Il rumore gaussiano produce una campana; i valori anomali producono una campana con pochi punti lontanissimi nelle code. Questi due casi richiedono filtri diversi e nessuna ispezione di un grafico temporale li distingue con la stessa chiarezza.
Scegliere un filtro, in modo quantitativo
| Filtro | Elimina il rumore gaussiano | Elimina i valori anomali | Ritardo | Costo |
|---|---|---|---|---|
| Media mobile, N campioni | Sì, di √N | No: distribuisce un picco su N campioni | (N−1)/2 campioni | Buffer di N campioni |
| Passa-basso esponenziale (EMA) | Sì | No | ≈ (1−α)/α campioni | Un float |
| Mediana di N | In parte | Completamente, fino a N/2 valori anomali | (N−1)/2 campioni | Ordinamento, trascurabile con N piccolo |
| Mediana e poi EMA | Sì | Sì | Entrambi | Entrambi |
Il valore √N nella prima riga è il numero utile: la media di 4 campioni dimezza il rumore; la media di 100 campioni lo riduce di dieci, al costo di 50 campioni di ritardo. La riduzione del rumore ha rendimenti decrescenti molto rapidamente, mentre il ritardo no: per questo medie molto lunghe sono quasi sempre la risposta sbagliata.
Per un filtro EMA, la costante di tempo è legata ad α dalla relazione:
tau = dt x (1 - alpha) / alpha
Quindi, con un loop da 10 ms, α = 0.1 dà una costante di tempo di 90 ms. Impostare α a sensazione è il modo in cui le persone finiscono con filtri molto più lenti di quanto credano: calcolalo una volta e saprai cosa hai.
Il ritardo non è gratuito, ed ecco quanto costa
Ogni filtro di uniformazione ritarda il segnale e, all’interno di un loop di controllo, quel ritardo è indistinguibile da un processo che risponde più lentamente. Riduce direttamente quanto guadagno il loop può tollerare prima di oscillare.
| Filtro | Ritardo con un loop da 10 ms | Distanza percorsa a 0.3 m/s |
|---|---|---|
| Mediana di 3 | 10 ms | 3 mm |
| Mediana di 5 | 20 ms | 6 mm |
| Media mobile di 10 | 45 ms | 14 mm |
| EMA, α = 0.1 | 90 ms | 27 mm |
| EMA, α = 0.02 | 490 ms | 147 mm |
Vale la pena riflettere su quest’ultima riga. Un valore α di 0.02 produce un grafico bellissimo e uniforme e mezzo secondo di ritardo: il robot sterza in base a dove si trovava l’ostacolo 15 cm fa. Questo è il modo più comune in cui un filtro ben intenzionato peggiora un robot ed è invisibile a meno che tu non tracci i valori filtrati e grezzi insieme al valore vero.
Scegli il filtro più leggero che soddisfa il requisito e controlla sempre quanto costa il ritardo nelle unità importanti per il robot, millimetri o gradi, non campioni.
Un filtro complementare e come sceglierne la costante
Il filtro complementare è il cavallo di battaglia della robotica hobbistica perché richiede tre righe e risolve il problema reale: due sensori che falliscono in modi opposti.
// gyroRate in deg/s, accelAngle in degrees, dt in seconds.
angle = alpha * (angle + gyroRate * dt) + (1.0f - alpha) * accelAngle;
alpha imposta la frequenza di taglio: sopra essa ti fidi del giroscopio, sotto ti fidi dell’accelerometro:
tau = alpha x dt / (1 - alpha) # the filter's time constant, seconds
f_crossover = 1 / (2 x pi x tau) # Hz
| α con dt = 5 ms | Costante di tempo | Taglio | Comportamento |
|---|---|---|---|
| 0.90 | 45 ms | 3.5 Hz | Molto reattivo, con rumore visibile dall’accelerometro |
| 0.98 | 245 ms | 0.65 Hz | Il valore predefinito comune: un buon compromesso |
| 0.995 | 1.0 s | 0.16 Hz | Molto uniforme, deriva in modo evidente prima di correggere |
| 0.999 | 5.0 s | 0.03 Hz | Praticamente solo giroscopio durante qualsiasi manovra breve |
Sceglila in base alla fisica anziché per tentativi: la costante di tempo deve essere lunga rispetto alle perturbazioni che vuoi rifiutare e breve rispetto alla velocità di deriva del giroscopio. Un giroscopio con un bias di 1 °/s raggiunge un errore di 1° in un secondo, quindi una costante di tempo di diversi secondi permette all’errore reale di accumularsi prima che l’accelerometro lo riporti indietro.
Nota anche che α dipende da dt. Copiare un α da un progetto con una frequenza di loop diversa produce un filtro diverso, una causa comune e invisibile di «questi guadagni non funzionano per me».
Che cosa non può fare la fusione
La fusione non è magia e tre limiti vanno dichiarati chiaramente:
Non può eliminare un bias condiviso. Due accelerometri che indicano entrambi 2° in più producono una stima fusa anch’essa alta di 2°. La fusione sfrutta errori indipendenti; un errore di modo comune sopravvive inalterato.
Non può creare informazioni inesistenti. Nessun filtraggio dà a un IMU a sei assi un orientamento assoluto. Lo yaw non ha un riferimento gravitazionale, quindi deriva; solo un magnetometro o un riferimento esterno lo corregge.
Non può correggere marche temporali errate. Fondere un fix GPS a 10 Hz con un giroscopio a 200 Hz richiede di sapere quando è stata effettuata ogni misurazione, con una precisione pari a una frazione dell’intervallo più veloce. Un fix vecchio di 100 ms e trattato come attuale corromperà attivamente una stima che il solo giroscopio aveva corretto.
Marche temporali, in pratica
«Aggiungi una marca temporale a tutto» è facile da approvare e facile da ignorare. Ecco la versione pratica:
struct Sample {
float value;
unsigned long micros; // when it was MEASURED, not when it was read
};
// Reject anything too old to be useful, rather than fusing it.
bool isFresh(const Sample &s, unsigned long maxAgeUs) {
return (micros() - s.micros) < maxAgeUs;
}
Acquisisci la marca temporale il più vicino possibile alla misurazione, dentro l’interrupt e non dopo l’analisi. Una frase NMEA analizzata 80 ms dopo il fix e marcata al momento dell’analisi ha un errore di 80 ms che nessun passaggio successivo può recuperare.
Risoluzione dei problemi
| Sintomo | Causa probabile | Correzione |
|---|---|---|
| Più filtraggio, nessun miglioramento | È bias, non rumore | Misura lo scostamento da fermo e sottrilo |
| La stima si allontana lentamente | Deriva | Ricalibrazione periodica o riferimento assoluto |
| Un picco sporadico supera il filtro | Stai usando una media | La mediana respinge i valori anomali; una media li distribuisce |
| Il loop di controllo oscilla dopo aver aggiunto un filtro | Il ritardo ha ridotto il guadagno stabile | Filtro più leggero o nuova regolazione |
| Grafico uniforme, robot lento a reagire | Costante di tempo molto più lunga del previsto | Calcola τ da α: non impostare α a sensazione |
| La stima fusa è peggiore di quella di entrambi i sensori | Marche temporali obsolete o bias condiviso | Marchia al momento della misurazione; controlla gli scostamenti di entrambi i sensori |
| Il filtro funziona sul banco, ma non sul robot | Le vibrazioni sono un segnale reale, non rumore | Monta il sensore su un supporto elastico; il filtro non può distinguerle |
| Il filtro complementare si comporta diversamente rispetto a un tutorial | α dipende da dt |
Calcola α per la tua frequenza di loop |
Provala tu stesso
Nel Simulatore di sensori robotici puoi regolare rumore, bias, deriva e interruzioni, poi confrontare i dati grezzi con le stime ottenute mediante passa-basso, media mobile e mediana. È il modo più rapido per percepire il compromesso tra rumore e ritardo, lo stesso che determina la reazione del robot nel Simulatore di evitamento degli ostacoli.
Esplora il grafo
Fa parte di queste costruzioni
Progetti e percorsi di apprendimento che includono questo tutorial.
Per approfondire