Filtros Lineales

El primer tipo (y más comúnmente empleado) de filtros que WPILib admite es el filtro lineal o, más específicamente un filtro lineal invariante en el tiempo (LTI).

Un filtro LTI, básicamente, una media móvil ponderada – el valor del flujo de salida en un momento dado es localizado, un promedio ponderado de las entradas cercanas a ese momento. La diferencia entre los diferentes tipos de filtros LTI es, reducible a la diferencia en la elección de la función ponderada (también conocida como “función de ventana” o “respuesta de impulso”) usada. Matemáticamente, este tipo de media móvil es conocida como una circunvolución.

Hay dos amplios tipos de respuestas de impulso: respuesta infinita de impulsos (IIR) y respuesta finita de impulsos (FIR).

Las respuestas infinitas de impulsos tiene un «apoyo» infinito - esto es, ellas son distintas a cero en una región infinitamente grande. Esto significa, que también tienen «memoria» infinita – cuando un valor aparece en el flujo de entrada este influirá en todas las salidas subsecuentes, para siempre. Esto es típicamente indeseable desde una perspectiva estricta de procesamiento de señales, sin embargo los filtros con respuestas infinitas de impulsos tienden calcularse fácilmente, ya que se pueden expresar mediante relaciones de recursión simples.

Las respuestas finitas de impulsos tiene un «apoyo» finito – es decir, las respuestas son distintas a cero en una región definida. El «arquetipo» del filtro FIR es un promedio móvil plano – es decir, configurando la salida igual al promedio de n entradas pasadas. Los filtros FIR tienden a tener propiedades más deseadas que los filtros IIR, pero son más complicados para calcular.

Los filtros lineales están soportados en WPILib a través de la clase LinearFilter (Java, C++).

Crear un Filtro Lineal

Nota

La clase C++ LinearFilter se basa en el tipo de información usada en el entrada.

Nota

Debido a que los filtros tienen «memoria», cada flujo de entrada requiere su propio objeto de filtro. No intente usar el mismo objeto de filtro para múltiples flujos de entradas.

Mientras sea posible instanciar directamente la clase LinearFilter para construir un filtro personalizado, es mucho más conveniente (y común) usar uno de los Factory methods suministrados, en su lugar:

singlePoleIIR

A graph with two peaks with the input closely following the target signal.

El método de fábrica singlePoleIIR() crea un filtro monopolar de respuesta infinitas de impulsos (también conocido como exponential smoothing, teniendo en cuenta la respuesta de impulso exponencial). Este es el «para partir», «primer intento» en la mayoría de aplicaciones de filtro bajo paso; es computacionalmente trivial y trabaja en la mayoría de los casos.

// Creates a new Single-Pole IIR filter
// Time constant is 0.1 seconds
// Period is 0.02 seconds - this is the standard FRC main loop period
LinearFilter filter = LinearFilter.singlePoleIIR(0.1, 0.02);

El parámetro de la «constante de tiempo» determina la «escala de tiempo característica» del impulso de respuesta del filtro; el filtro cancelará cualquier dinámica que ocurra en la escala de tiempo significativamente menor que esto. Relacionada, también está la escala de tiempo aproximada de la introducción del phase lag. El recíproco de esta escala de tiempo, multiplicado por 2 pi, es la «frecuencia de corte» del filtro.

El parámetro «periodo» es el periodo en el cual el método calculate() del filtro será llamado. Para la mayoría de las implementaciones, esto será el periodo cíclico estándar de 0.02 segundos del main robot.

Media Móvil

A graph with two peaks with the input closely following the target signal.

El método de fabrica de media móvil crea un filtro simple de media móvil plana. Este es el filtro paso bajo FIR más simple, y es útil en muchos contextos iguales como los filtros monopolar IIR. Es un poco más complicado de calcular, pero generalmente se comporta de una manera más suave.

// Creates a new flat moving average filter
// Average will be taken over the last 5 samples
LinearFilter filter = LinearFilter.movingAverage(5);

El parámetro «taps» es el nombre de ejemplos que serán incluidos en la media móvil plana. Esto se comporta similarmente a la «constante de tiempo» anterior – se le llama constante de tiempo efectiva al número de fases de tiempo multiplicado por el periodo en cual calculate() es llamado.

highPass

A graph with two peaks except the highpass only shows the rate of change centered around 0.

El método de fábrica highPass crea un filtro simple de respuesta de impulso infinita de primer orden. Esto es la «contraparte» del IIR monopolar.

// Creates a new high-pass IIR filter
// Time constant is 0.1 seconds
// Period is 0.02 seconds - this is the standard FRC main loop period
LinearFilter filter = LinearFilter.highPass(0.1, 0.02);

El parámetro de la «constante de tiempo» determina la «escala de tiempo característica» de la respuesta del impulso del filtro; el filtro cancelará cualquier dinámica de la señal que ocurra en la escala de tiempo significativamente más larga que esta. Relacionado, esta también es la escala de tiempo aproximada del phase lead introducida. El recíproco de esta escala de tiempo, multiplicado por 2 pi, es la «frecuencia de corte» del filtro.

El parámetro «periodo» es el periodo en el cual el método calculate() del filtro será llamado. Para la mayoría de las implementaciones, esto será el periodo cíclico estándar de 0.02 segundos del main robot.

Usando un filtro Lineal

Nota

En orden para que el filtro creado obedezca el parámetro de tiempo de escala especificado, la función calculate() deberá ser llamada constantemente en el periodo especificado. Si, por alguna razón, un lapso significante en calculate() debe ocurrir, el método de reset() del filtro deberá ser llamado antes para su uso futuro.

Una vez que su filtro sea creado, usarlo es fácil – solamente llame el método calculate() con la entrada más reciente para obtener la salida filtrada.

// Calculates the next value of the output
filter.calculate(input);