«Filtre passe-bas» dans des contextes d'API logiciels non EE


12

Je suis un ingénieur logiciel expérimenté et je travaille sur les capteurs de smartphones. J'ai suivi des cours d'EE fondamentaux en DSP et j'essaie d'appliquer mes connaissances. Je crois que je comprends la convolution, les fonctions de transfert, la transformation z, etc. Je connais un peu les filtres FIR et IIR.

Maintenant, en lisant les API logicielles et la documentation, je vois que les gens appliquent un LPF aux données des capteurs dans le domaine temporel. Je sais que vous le faites en utilisant des équations de différence (par exemple y [i] = y [i-1] + 2 * x [i]), mais j'ai appris dans ma classe EE que les LPF sont généralement appliqués par le biais de l'opération de convolution où vous convoluez le signal temporel avec les coefficients d'une onde sinc (par exemple) et avec une fréquence de coupure spécifique. Donc, l'utilisation familière du "filtre passe-bas" n'est pas assez exacte pour moi.

Par exemple, l'API Google Android possède cette documentation: http://developer.android.com/reference/android/hardware/SensorEvent.html#values

 public void onSensorChanged(SensorEvent event)
 {
      // alpha is calculated as t / (t + dT)
      // with t, the low-pass filter's time-constant
      // and dT, the event delivery rate

      final float alpha = 0.8;

      gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0];
      gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
      gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2];

      linear_acceleration[0] = event.values[0] - gravity[0];
      linear_acceleration[1] = event.values[1] - gravity[1];
      linear_acceleration[2] = event.values[2] - gravity[2];
 }

Comment interpréter ce filtre passe-bas? Quelle est la fréquence de coupure? Quelle est la bande passante de transition? Utilisent-ils ce LPF uniquement pour faire la moyenne?


bon ça me dérange aussi
Sibbs Gambling

Réponses:


11

Le filtre de votre exemple est un filtre de réponse impulsionnelle infinie (IIR) du premier ordre . Sa fonction de transfert est:

H(z)=1α1αz1

ce qui correspond à une équation de différence de:

y[n]=αy[n1]+(1α)x[n]

où est l'entrée du filtre et est la sortie du filtre.y [ n ]x[n]y[n]

Ce type de filtre est souvent utilisé comme filtre passe-bas de faible complexité et est souvent appelé intégrateur qui fuit . Il est favorisé en raison de sa mise en œuvre simple, de sa faible complexité de calcul et de son accordabilité: sa fréquence de coupure dépend de la valeur de . peut prendre des valeurs sur l'intervalle . ne produit aucun filtrage (la sortie est égale à l'entrée); lorsque augmente, la fréquence de coupure du filtre diminue. Vous pouvez considérer comme un cas limite où la fréquence de coupure est infiniment basse (la sortie du filtre est nulle pour toujours).α [ 0 , 1 ) α = 0 α α = 1αα[0,1)α=0αα=1

Vous pouvez penser à cela intuitivement en remarquant que l'entrée du filtre est pondérée par , de sorte que lorsque le paramètre augmente, la quantité diminue, de sorte que chaque échantillon d'entrée a un effet proportionnel plus petit sur la valeur d'un échantillon de sortie particulier. Cela a pour effet d'étaler la réponse impulsionnelle du filtre sur une plus longue période de temps. La sommation sur une plus longue période de temps est similaire au calcul d'une longue moyenne mobile. Lorsque la longueur d'une moyenne mobile augmente, la fréquence de coupure de la moyenne diminue.1 - αα1α

Pour votre exemple, où , la réponse en fréquence du filtre est la suivante: α=0.8entrez la description de l'image ici

D'après l'exemple, je suppose que ce filtre est utilisé pour atténuer le bruit haute fréquence à partir d'une série chronologique de mesures provenant d'un capteur, essayant de démêler un signal d'intérêt relativement basse fréquence. Ce serait une application très typique pour ce type de filtre.

Sur votre autre sous-question, vous avez raison de dire que le filtrage est souvent mis en œuvre par convolution du signal d'entrée avec la réponse impulsionnelle du filtre. Dans la plupart des cas, cela se fait uniquement avec des filtres à réponse impulsionnelle finie (FIR) . Les filtres IIR tels que celui-ci sont généralement mis en œuvre en utilisant l'équation de différence du filtre; comme la réponse impulsionnelle d'un système IIR est infiniment longue, vous devez la tronquer à une certaine longueur finie pour rendre la convolution avec elle traitable, point auquel le filtre n'est plus IIR. Le format de l'équation de différence est presque toujours moins cher à implémenter par calcul, bien que la rétroaction inhérente à cette structure puisse conduire à des problèmes numériques qui doivent être résolus (tels que le débordement interne et l'accumulation d'erreurs d'arrondi).


Merci! Quelques questions complémentaires: (1) Vous avez dit que votre équation H (z) = ... est une équation de différence; c'est vraiment une fonction de transfert, non? Je pensais qu'une équation de différence est strictement pour le domaine temporel. (2) Dans votre intégrateur qui fuit, 1.0 correspond-il à sample_frequency / 2 (comme dans Matlab)? (3) Concernant FIR vs IIR, ma compréhension est-elle correcte que l'équation de différence IIR peut être appliquée dans O (N) mais la convolution est O (N ^ 2) ou O (N lgN) avec une convolution basée sur FFT? (4) Pouvez-vous recommander un livre aux programmeurs de logiciels pour implémenter ces idées DSP? Comme ce que fait l'exemple de code Android.
stackoverflowuser2010

π+πO(N)NN

Je sais que (i) l'application de l'équation de différence est O (N). Mais je pensais que (ii) l'opération de convolution utilisant la sommation sur multiplier et ajouter (songho.ca/dsp/convolution/convolution.html) est O (N ^ 2) ou O (N lgN) avec une implémentation basée sur FFT . Dans tous les cas, N est l'ordre du filtre - où je suppose que l'ordre du filtre et la longueur du signal temporel sont du même ordre de grandeur (par exemple les 256). Donc (i) et (ii) ne sont-ils pas différents? J'ai également vu ce livre lyonnais sur Amazon.com, mais j'espérais quelque chose de plus écrit pour les programmeurs de logiciels C / Java.
stackoverflowuser2010

1
O(N) NO(N2)MNO(MN)MN
Jason R

O(M×(N+M))iNO(N2)O(NM)
stackoverflowuser2010

2

Pour résumer, les filtres IIR basés sur des modèles physiques idéalisés simples, tels qu'un filtre RC, ont un petit nombre de pôles et de zéros, et sont donc généralement implémentés comme une équation de différence, car un petit nombre de pôles ou de zéros implique très peu d'opérations arithmétiques par échantillon en utilisant une équation de différence.

Comme un IIR implique une réponse impulsionnelle de longueur infinie, la convolution nécessiterait soit une éternité pour le calcul, soit l'utilisation d'une approximation.

Les filtres FIR sont généralement mis en œuvre par convolution avec la réponse impulsionnelle de longueur finie (ou par convolution rapide FFT si le filtre est suffisamment long pour que cela soit efficace sur le plan des calculs). Ces types de filtres sont plus souvent utilisés lorsque l'on peut approximer une spécification de réponse en fréquence souhaitée avec une réponse impulsionnelle de longueur finie, plutôt que de savoir où les pôles et les zéros du plan Z pourraient être situés.

Cependant, comme un filtre avec des spécifications précises implique une longue convolution FIR, la mise en œuvre des filtres FIR peut être beaucoup plus lente et la configuration peut impliquer beaucoup plus de lignes de code, ce qui peut expliquer pourquoi les filtres FIR peuvent ne pas être utilisés aussi souvent dans un logiciel simple. exemples.


0

Je reviens à maintes reprises à ce poste. Merci d'avoir posé la question. Voici une excellente implémentation, facile à calculer, de l'intégrateur qui fuit en C (destiné à un microcontrôleur).

Tout d'abord, certains réarrangements: y = α * x + (1 - α) * y_last = α * (x - y_last) + y_last

si nous limitons α à environ 12%, 25%, 50%, (1/8, 1/4, 1/2, ...). Nous pouvons profiter d'un certain décalage de bits efficace. En prenant le cas de 1/8, 8 => 2 ^ 3 => (rétrogradation 3 fois)

= (x - y_last) / 8 + y_last

#define SMOOTHING_FACTOR       (3)

int16_t FilterSample(int16_t new_sample)
{
  static int16_t last_result = 0;

  // Each bit shift down is equivalent to dividing-by-two
  last_result = (new_sample - last_result) >> SMOOTHING_FACTOR) + last_result;

  return last_result;
}

J'espère que cela aide.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.