Synthèse d’un filtre passe-bande#
Ce tutorial montre le process complet pour synthétiser un filtre d’ordre N à partir d’un cahier des charges. La méthodologie décrite ici est applicable à n’importe quel filtre.
Cahier des charges#
Type de filtre: passe-bande,
Technique de synthèse: Butterworth,
Bande passante : \(\omega \in [900, 1111]\) rad/s,
Bande rejetée : \(\omega \in [0, 500[ \cup [2000, +\infty[\) rad/s,
Atténuation maximale dans la bande passante: \(3\) dB,
Atténuation minimale dans la bande rejetée: \(40\) dB.
Détermination du Gabarit Normalisé#
Dans un premier temps, nous allons revenir à la conception d’un filtre passe-bas normalisé (\(\omega_c=1\) rad/s). Pour réaliser cette étape de normalisation, nous allons utiliser la formule liant la pulsation normalisée \(\omega\) et la pulsation dénormalisée \(\widehat{\omega}\) (voir Mapping Fréquentiel)
Application Numérique#
Bande passante: \(\Delta \omega=1111-900=211\) rad/s.
Pulsation centrale : \(\omega_0=\sqrt{900\times 1111}=1000\) rad/s.
Valeur du module en \(\widehat{\omega}=1111\) rad/s: \(T_c=10^{-3/20}=0.707\),
Valeur du module en \(\widehat{\omega}=2000\) rad/s: \(T_s=10^{-40/20}=0.01\).
En utilisant la formule, nous obtenons :
Représentation du Gabarit#
Détermination de l’ordre#
Il est possible de déterminer l’ordre du filtre passe-bas normalisé en utilisant le comportement asymptotique :
Synthèse du Filtre Normalisé#
Pour synthétiser le filtre, nous allons utiliser la technique de synthèse de Butterworth. La fonction de transfert du filtre normalisé peut s’exprimer sous la forme factorisée suivante (zpk):
Il est possible d’obtenir les pôles \(p_l\) et les zéros \(z_l\) ainsi que le gain k du filtre normalisé en utilisant scipy:
from scipy.signal import butter
z,p,k = butter(3, 1, "low", analog=True, output="zpk")
Nous obtenons les paramètres suivants:
zéros: \(z_l=\{\}\),
pôles: \(p_l=\{-0.5+0.8660254, -1, -0.5-0.8660254j\}\),
gain: \(k=1\)
Dénormalisation du Filtre#
Pour dénormaliser le filtre, nous allons opérer un mapping des pôles et zéros. Dans le cas d’un passe-bande, le mapping des pôles est donné par (voir Mapping des pôles et zéros).
\(\alpha=\Delta \omega/2=211/2=105.5\) rad/s désigne la moitié de la bande passante,
\(p_l\) correspond aux pôles du filtre normalisé,
\(\widehat{p}_l\) correspond aux pôles du filtre dénormalisé.
Après dénormalisation, nous obtenons un filtre d’ordre \(2N=6\). Pour conserver un gain maximum unitaire dans la bande passante, il est également nécessaire de changer le coefficient \(k\) de la manière suivante:
Application Numérique#
Après dénormalisation, nous obtenons un filtre d’ordre 6 avec les paramètres suivants :
- zéros: 3 zéros en 0 (filtre passe-bande d’ordre 6)
\(\widehat{z}_l=\{0, 0, 0\}\),
- pôles: 3 paires de pôles complexes-conjugués
\(\widehat{p}_1=-47.943-911.424j\) et \(\widehat{p}_1^*=-47.943+911.424j\),
\(\widehat{p}_2=-57.556-1094.155j\) et \(\widehat{p}_2^*=-57.556+1094.155j\)
\(\widehat{p}_3=-105.5-994.419j\) et \(\widehat{p}_3^*=-105.5+994.419j\),
- gain k:
\(\widehat{k} = 1 \times (211)^3 =9393931\)
Vérification#
Pour vérifier que le filtre dénormalisé respecte bien les contraintes du cahier des charges, une solution naturelle consiste à afficher la réponse fréquentielle du filtre dénormalisé.
from scipy.signal import lti
import matplotlib.pyplot as plt
k2 = 9393931
z2 = [0.+0.j, 0.+0.j, 0.+0.j]
p2 = [ -47.943-911.374j, -105.5-994.369j, -47.943 +911.374j, -57.556+1094.106j, -105.5 +994.369j, -57.556-1094.106j]
H = lti(z2, p2, k2)
w, Hjw = H.freqresp()
plt.loglog(w, np.abs(Hjw))
plt.xlabel("pulsation (rad/s)")
plt.ylabel("module")