Tutorial · Principiante · 17 min de lectura
Ruido de sensores, sesgo y filtrado en robótica
Comprende y limpia las señales de sensores ruidosos: ruido, sesgo y deriva, cómo elegir filtro, el retardo que introduce y cuándo aplicar fusión.
Todos los robots actúan sobre mediciones que son ruidosas, retrasadas, sesgadas y a veces ausentes. Tratar una lectura cruda como verdad es la forma más rápida de construir un robot que se comporta de forma impredecible. Esta guía cubre el vocabulario y los intercambios que necesitas antes de fiarte de un sensor. Experimenta con cada efecto en el Robot Sensor Simulator.
Ruido, sesgo y deriva son problemas distintos
- Ruido varía aleatoriamente de una muestra a otra. Promediar o filtrar lo reduce.
- Sesgo es un desplazamiento fijo respecto al valor verdadero. Filtrar no lo elimina; tienes que medirlo durante la calibración y restarlo.
- Deriva es un sesgo que cambia lentamente a lo largo del tiempo, normalmente con la temperatura. Una calibración tomada al arrancar deja de coincidir con la realidad poco a poco, y por eso las pasadas largas necesitan recalibración periódica o una referencia contra la que corregir.
Confundir estos tres lleva al arreglo equivocado—más filtrado nunca cura un sesgo.
Elegir un filtro
Tres filtros comunes cubren la mayoría de los casos:
- Una media móvil y un paso bajo exponencial suavizan ambos el ruido aleatorio, intercambiando reactividad por suavidad mediante su ventana o su constante de tiempo.
- Un filtro de mediana es mejor quitando picos y caídas ocasionales, porque unas pocas muestras malas no mueven el valor central.
Elige el filtro más ligero que cumpla el requisito de lo que consuma la medición—no el que produzca la gráfica de aspecto más suave.
Filtrar siempre añade retardo
Todo filtro de suavizado retrasa la señal verdadera, y más suavizado significa más retardo. Un filtro paso bajo con constante de tiempo larga rechaza más ruido pero se queda más atrás ante los cambios rápidos. Representa siempre la estimación filtrada junto a las muestras crudas y a la verdad, para que el retardo sea visible antes de meter el filtro dentro de un lazo de control, donde el retardo puede causar inestabilidad.
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
Lo que la fusión de sensores puede y no puede hacer
La fusión combina varios sensores en una sola estimación, y solo ayuda cuando los sensores aportan información complementaria y su incertidumbre se representa honestamente. Combinar dos mediciones sesgadas no crea verdad. Un filtro complementario, por ejemplo, se fía de un sensor a altas frecuencias y de otro a bajas frecuencias; un filtro de Kalman pondera cada fuente según su incertidumbre. Pase lo que pase, empieza por la calibración, las marcas de tiempo y los marcos de coordenadas compartidos antes de fusionar nada.
Pon marca de tiempo a todo
Las muestras rara vez llegan a un intervalo perfectamente fijo, y tanto el filtrado como la fusión asumen que sabes cuándo se midió cada valor. Las marcas de tiempo te permiten detectar jitter, alinear datos de sensores distintos y descartar lecturas obsoletas. Registra los valores crudos junto a los procesados para que fallos como el recorte y las caídas sigan siendo reproducibles.
Mide tu sensor antes de filtrarlo
Elegir un filtro antes de saber cómo es el ruido es adivinar. Diez minutos de registro lo resuelven, y el procedimiento es el mismo para cualquier sensor:
- Sujeta el sensor perfectamente quieto contra una entrada conocida y constante.
- Registra unos miles de muestras crudas con marcas de tiempo.
- Calcula la media y la desviación típica.
- Representa las muestras, y representa un histograma de ellas.
Esos cuatro números y dos gráficas te dicen cuál de los tres fallos tienes:
| Qué observas | Qué es | El arreglo |
|---|---|---|
| La media coincide con la verdad, los valores se dispersan simétricamente | Ruido | Fíltralo |
| La media está desplazada respecto a la verdad, la dispersión es pequeña | Sesgo | Mídelo y réstralo — filtrar nunca ayudará |
| La media se aleja a lo largo de minutos | Deriva | Recalibra periódicamente, o corrige contra una referencia |
| Mayormente ajustados, con valores salvajes ocasionales | Valores atípicos | Mediana, no una media |
| Los valores caen en escalones discretos | Cuantificación | Lo esperable; acota tu resolución |
El histograma es la parte que la gente se salta, y es la más informativa. El ruido gaussiano hace una campana; los valores atípicos hacen una campana con unos pocos puntos muy lejos en las colas. Esos dos necesitan filtros distintos, y ninguna cantidad de mirar fijamente una gráfica de serie temporal los distingue con la misma claridad.
Elegir un filtro, cuantificado
| Filtro | Mata ruido gaussiano | Mata valores atípicos | Retardo | Coste |
|---|---|---|---|---|
| Media móvil, N muestras | Sí — por √N | No — difumina un pico sobre N muestras | (N−1)/2 muestras | Buffer de N muestras |
| Paso bajo exponencial (EMA) | Sí | No | ≈ (1−α)/α muestras | Un float |
| Mediana de N | En parte | Completamente, hasta N/2 atípicos | (N−1)/2 muestras | Ordenar, trivial con N pequeña |
| Mediana y luego EMA | Sí | Sí | Ambos | Ambos |
El √N de la primera fila es el número útil: promediar 4 muestras reduce el ruido a la mitad; promediar 100 muestras lo reduce a la décima parte, al precio de 50 muestras de retardo. La reducción de ruido tiene rendimientos decrecientes muy marcados y el retardo no, y por eso las medias muy largas casi siempre son la respuesta equivocada.
Para un EMA, la constante de tiempo se relaciona con α así:
tau = dt x (1 - alpha) / alpha
Así que en un bucle de 10 ms, α = 0.1 da una constante de tiempo de 90 ms. Ajustar α a ojo es como la gente acaba con filtros mucho más lentos de lo que cree — calcúlalo una vez y sabrás lo que tienes.
El retardo no es gratis, y aquí está lo que cuesta
Todo filtro de suavizado retrasa la señal, y dentro de un lazo de control ese retardo es indistinguible de que la planta responda más despacio. Reduce directamente cuánta ganancia el lazo puede tolerar antes de oscilar.
| Filtro | Retardo en un bucle de 10 ms | Distancia recorrida a 0,3 m/s |
|---|---|---|
| Mediana de 3 | 10 ms | 3 mm |
| Mediana de 5 | 20 ms | 6 mm |
| Media móvil de 10 | 45 ms | 14 mm |
| EMA, α = 0.1 | 90 ms | 27 mm |
| EMA, α = 0.02 | 490 ms | 147 mm |
Esa última fila merece que te detengas a mirarla. Un α de 0.02 produce una gráfica preciosamente suave y medio segundo de retardo — el robot está guiándose por donde estaba el obstáculo hace 15 cm. Esta es la forma más habitual de que un filtro bienintencionado empeore un robot, y es invisible salvo que representes filtrado contra crudo con la verdad al lado.
Elige el filtro más ligero que cumpla el requisito, y comprueba siempre cuánto cuesta el retardo en las unidades que le importan al robot — milímetros, o grados, no muestras.
Un filtro complementario, y cómo elegir su constante
El filtro complementario es el caballo de batalla de la robótica de hobby porque son tres líneas y resuelve el problema real: dos sensores que fallan de maneras opuestas.
// gyroRate in deg/s, accelAngle in degrees, dt in seconds.
angle = alpha * (angle + gyroRate * dt) + (1.0f - alpha) * accelAngle;
alpha fija la frecuencia de cruce — por encima te fías del giroscopio, por debajo del
acelerómetro:
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 | Constante de tiempo | Cruce | Comportamiento |
|---|---|---|---|
| 0.90 | 45 ms | 3.5 Hz | Muy reactivo, visiblemente ruidoso por el acelerómetro |
| 0.98 | 245 ms | 0.65 Hz | El valor por defecto habitual — buen equilibrio |
| 0.995 | 1.0 s | 0.16 Hz | Muy suave, deriva de forma perceptible antes de corregir |
| 0.999 | 5.0 s | 0.03 Hz | En la práctica solo giroscopio durante cualquier maniobra corta |
Elígelo a partir de la física y no a ojo: la constante de tiempo debería ser larga comparada con las perturbaciones que quieres rechazar, y corta comparada con la tasa de deriva del giroscopio. Un giroscopio con un sesgo de 1 °/s alcanza 1° de error en un segundo, así que una constante de tiempo de varios segundos deja acumularse error real antes de que el acelerómetro lo corrija.
Fíjate también en que α depende de dt. Copiar un α de un proyecto con otra tasa de bucle te da un
filtro distinto — una fuente común e invisible de «estas ganancias no me funcionan».
Lo que la fusión no puede hacer
La fusión no es magia, y hay tres límites que merece la pena enunciar sin rodeos:
No puede quitar un sesgo compartido. Dos acelerómetros que ambos leen 2° alto producen una estimación fusionada que lee 2° alto. La fusión explota errores independientes; un error en modo común sobrevive intacto.
No puede crear información que no está. Ninguna cantidad de filtrado le da a una IMU de seis ejes un rumbo absoluto. El guiñada no tiene referencia de gravedad, así que deriva, y solo un magnetómetro o una referencia externa lo arregla.
No puede arreglar marcas de tiempo malas. Fusionar un fix de GPS de 10 Hz con un giroscopio de 200 Hz exige saber cuándo se midió cada uno, con una fracción del intervalo más rápido. Un fix con 100 ms de antigüedad tratado como actual corromperá activamente una estimación que el giroscopio solo tenía bien.
Marcas de tiempo, en concreto
«Pon marca de tiempo a todo» es fácil de—asentir y fácil de saltarse. La versión práctica:
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;
}
Captura la marca de tiempo tan cerca de la medida como puedas — dentro de la interrupción, no después del procesado. Una frase de GPS analizada 80 ms después de tomar el fix y marcada con la hora del análisis tiene 80 ms de error, y nada de lo que viene después puede recuperar eso.
Resolución de problemas
| Síntoma | Causa probable | Solución |
|---|---|---|
| Más filtrado, ninguna mejora | Es sesgo, no ruido | Mide el desplazamiento en reposo y réstralo |
| La estimación se aleja poco a poco | Deriva | Recalibración periódica, o una referencia absoluta |
| Un pico puntual sobrevive al filtro | Estás usando una media | La mediana rechaza atípicos; una media los difumina |
| El lazo de control oscila tras añadir un filtro | El retardo redujo la ganancia estable | Filtro más ligero, o reajusta |
| Gráfica suave, el robot reacciona tarde | Constante de tiempo mucho más larga de lo previsto | Calcula τ a partir de α — no ajustes α a ojo |
| La estimación fusionada es peor que cualquiera de los sensores | Marcas de tiempo obsoletas, o un sesgo compartido | Marca el tiempo en la medida; comprueba los desplazamientos de ambos sensores |
| El filtro funciona en el banco, no en el robot | La vibración es una señal real, no ruido | Monta el sensor con goma; el filtro no puede distinguirlas |
| El filtro complementario se comporta distinto que en un tutorial | α depende de dt |
Calcula α para tu tasa de bucle |
Pruébalo tú mismo
En el Robot Sensor Simulator puedes ajustar ruido, sesgo, deriva y caídas, y luego comparar los datos crudos con las estimaciones de paso bajo, media móvil y mediana. Es la forma más rápida de sentir el intercambio entre ruido y retardo—el mismo intercambio que decide cómo reacciona un robot en el Obstacle Avoidance Simulator.
Explora el grafo
Forma parte de estos montajes
Proyectos y rutas de aprendizaje que incluyen este tutorial.
Lecturas adicionales