diseño de filtro de paso bajo para acelerómetro

3

Encuentro el siguiente código para una implementación simple de un filtro de paso bajo.

#define alpha 0.1

accelX = (acceleration.x * alpha) + (accelX * (1.0 - alpha));

He estado experimentando con el valor de alfa. Pero quiero saber exactamente cómo podemos encontrar este valor para los datos del acelerómetro (en Android). Entiendo que necesitaríamos la frecuencia de muestreo y la frecuencia de corte. ¿Cómo puedo encontrar la frecuencia de corte para este tipo de datos (supongo que esto implica modelar el ruido y encontrar su rango de frecuencia? Si es así, ¿cómo debería hacerlo?)

    
pregunta user2155669

2 respuestas

4

Y [n] = aX [n] + (1-a) Y [n-1]

Es una media móvil autorregresiva: un filtro de respuesta de impulso infinito. Comience con la ecuación anterior, tome la transformada z, y eso da la respuesta de frecuencia. No tiene nada que ver con el modelo de ruido.

Aquí está la respuesta de frecuencia para alpha = 0.9, el eje de frecuencia se escala de 0 a su frecuencia de Nyquist (la mitad de su frecuencia de muestreo) generada en Octava por freqz (0.9, [1 -0.1])

alfa=0.6Frecuencia(0.6,[1-0.4])

    
respondido por el Scott Seidman
0

Lo que tienes es la ecuación para un filtro de paso bajo de un solo polo. Este es el equivalente discreto del filtro R-C analógico. Si bien tu ecuación es correcta, me gusta escribirla como

FILT < - FILT + FF (NUEVO - FILT)

porque esto es un poco más conveniente de realizar en un microcontrolador en la mayoría de los casos.

Por lo general, la vista del dominio del tiempo del filtro se puede utilizar más directamente al implementar uno de estos en un microcontrolador. La mayoría de las veces le preocupa más la frecuencia de muestreo y el tiempo de respuesta que la reducción de frecuencia. Sin embargo, este último sí aparece, por lo que construí algunas facilidades para manipular esto en mi preprocesador PIC. El fragmento de documentación de las dos funciones en línea relevantes es:

  FFTC2 tcfilt sfreq

       Computes the filter fraction of a single pole low pass filter.
       TCFILT is the 1/2 decay time of the filter, and SFREQ is the sample
       frequency.  The filter fraction is the weighting fraction of the
       incoming signal each filter iteration.  The result data type is
       floating point.

  FFFREQ ffreq sfreq

       Computes the filter fraction of a single pole low pass filter.
       FFREQ is the desired -3dB rolloff frequency of the filter, and
       SFREQ is the sample frequency.

Calculé las matemáticas en el momento en que escribí el código para esas funciones, por lo que te referiré a eso en lugar de volver a derivarlo ahora:

*   FFTC2 tcfilt sfreq
}
4: begin
  if not term_get (fstr, p, val) then goto arg_missing;
  a1 := val_fp (val);                  {get power of 2 time constant}
  if not term_get (fstr, p, val) then goto arg_missing;
  a2 := val_fp (val);                  {get sampling frequency}

  r := 1.0 - 0.5 ** (1.0 / (a1 * a2)); {make the filter fraction}

ret_r:                                 {common code to return FP value in R}
  str_from_fp (r, tk);                 {make floating point string in TK}
  string_append (lot, tk);             {append floating point string to the output}
  end;
{
********************
*
*   FFFREQ ffreq sfreq
}
5: begin
  if not term_get (fstr, p, val) then goto arg_missing;
  a1 := val_fp (val);                  {get filter rolloff frequency}
  if not term_get (fstr, p, val) then goto arg_missing;
  a2 := val_fp (val);                  {get sampling frequency}

  r := pi2nv / a1;                     {make standard power of E time constant}
  r := 1.0 - env ** (1.0 / (r * a2));  {make the filter fraction}
  goto ret_r;                          {return the value in R}
  end;

Las matemáticas reales de la función FFFREQ son solo dos líneas de código, por lo que puedes averiguarlo. Parece que esto se basa en algunas definiciones en la parte superior del archivo:

{
*   Physical constants.  Don't mess with these.
}
  pi = 3.14159265358979323846;         {what it sounds like, don't touch}
  e = 2.718281828;                     {ditto}
  pi2 = 2.0 * pi;                      {2 Pi}
  pi2nv = 1.0 / pi2;                   {1 / 2Pi}
  env = 1.0 / e;                       {1 / e}
  ln2 = ln(2.0);                       {natural log of 2}

Si está haciendo esto en un PIC, es posible que desee utilizar el preprocesador. Se incluye en el lanzamiento de PIC Development Tools en enlace . El código fuente del preprocesador se incluye en la versión de Código fuente del host y todo .

    
respondido por el Olin Lathrop

Lea otras preguntas en las etiquetas