Travail Collaboratif : Analog Filter#
Acquis d’Apprentissage Visés#
AAv1 (Étude de circuits électronique d’ordre 2) : A l’issue du 4e semestre d’électronique, l’étudiant sera capable de déterminer sous forme analytique ou numérique les paramètres caractéristiques d’un circuit du 2nd ordre en fonction de la valeur de ses composants en déterminant au préalable sa fonction de transfert. Les paramètres caractéristiques comprennent:
le type de filtre;
le coefficient d’amplification;
la fréquence propre;
le coefficient d’amortissement.
AAv4 (Design) : A l’issue du 4e semestre d’électronique, l’étudiant sera capable de proposer un circuit respectant un cahier des charges. Le cahier des charges sera spécifié sous la forme soit par de plusieurs paramètres caractéristiques d’une cellule d’ordre 2 (type, coefficient d’amplification, fréquence propre, coefficient d’amortissement) ou soit par un gabarit fréquentiel. L’étudiant sera en mesure de vérifier la conformité de sa proposition avec le cahier des charges en utilisant un logiciel de simulation (Python/Numpy/Scipy et LTspice).
Description du travail#
Objectifs#
Dans ce travail, nous souhaitons développer des fonctions Python pour analyser des circuits d’ordre 2. Pour chaque filtre d’ordre 2, nous souhaitons traiter les problèmes suivants :
Calcul de la fonction de transfert, puis écriture sous forme normalisée,
Implémentation d’une fonction
lti
permettant d’obtenir la fonction de transfert en Python à partir des composants,Implémentation d’une fonction
get_params
permettant d’obtenir les paramètres de la fonction de transfert,Implémentation d’une fonction
get_components
permettant d’obtenir les composants du filtre à partir des paramètres.Validation sur LTSpice
Fonctions de transfert normalisées#
Passe-bas (LP)
Passe-bande (BP)
Passe-haut (HP)
Exemple#
Dans cet exemple, nous allons considérer l’analyse complète du circuit suivant :
Fonction de transfert#
En utilisant le pont diviseur de tension, nous obtenons
où
Il en vient que :
Implémentation#
Fonction lti_RLC_BP3#
Pour implémenter la fonction de transfert, nous pouvons utiliser la fonction lti du module scipy.
import numpy as np
from scipy.signal import lti
def lti_rlc_bp3(L, C, R1, R2):
"""
Create the transfer function for the RLC_BP3 filter.
Parameters
----------
L : float
C : float
R1 : float
R2 : float
Returns
-------
system : an instance of the LTI class
"""
num = [L/R2,0]
den = [L*C, L*(R1+R2)/(R1*R2), 1]
return lti(num, den)
Fonction get_params#
En identifiant la fonction de transfert avec la fonction de transfert normalisée d’un passe-bande, nous obtenons :
avec
def get_params(L, C, R1, R2):
"""
Compute the maximum gain, the angular frequency and the damping factor of the RLC_BP3 filter.
Parameters
----------
L : float
C : float
R1 : float
R2 : float
Returns
-------
Type: string
Tm : float
w0 : float
m : float
"""
Tm = R1 / (R1+R2)
w0 = 1/ np.sqrt(L*C)
m = 0.5*((R1+R2)/(R1*R2))*np.sqrt(L/C)
return "BP", Tm, w0, m
Fonction get_components#
Comme nous avons 3 équations et 4 composants, nous devons fixer un composant. En fixant la bobine L, nous obtenons alors les équations suivantes :
def get_components(Tm, w0, m, L):
"""
Returns the circuit components from the filter parameters.
Parameters
----------
Tm : float
w0 : float
m : float
L : float
Returns
-------
C : float
R1 : float
R2 : float
"""
C = 1 / (L*(w0**2))
R2 = (1/(2*m*Tm))*np.sqrt(L/C)
R1 = (R2*Tm) / (1-Tm)
return C, R1, R2
Approche Objet#
Au lieu de définir des fonctions, il est d’adopter une approche objet afin de gagner en organisation, clarté et modularité. Il est également possible d’implémenter des tests unitaires pour vérifier le bon comportement de notre classe.
Classe RLC_BP3_Filter#
Pour implémenter notre classe, nous allons créer le fichier filter_RLC.py contenant le code suivant.
1import numpy as np
2from scipy.signal import lti
3
4
5class RLC_BP3_Filter():
6
7 def __init__(self, R1, R2, C, L):
8 """
9 Constructor
10 """
11 self.R1 = R1
12 self.R2 = R2
13 self.C = C
14 self.L = L
15
16 def lti(self):
17 """
18 Create the transfer function for the filter.
19
20 Returns
21 -------
22 system : an instance of the LTI class
23 """
24 num = [self.L/self.R2,0]
25 den = [self.L*self.C, self.L*(self.R1+self.R2)/(self.R1*self.R2), 1]
26 return lti(num, den)
27
28 def get_params(self):
29 """
30 Compute the maximum gain, the angular frequency and the damping factor of the filter.
31
32 Returns
33 -------
34 Tm : float
35 w0 : float
36 m : float
37 """
38 Tm = self.R1 / (self.R1+self.R2)
39 w0 = 1/ np.sqrt(self.L*self.C)
40 m = 0.5*((self.R1+self.R2)/(self.R1*self.R2))*np.sqrt(self.L/self.C)
41 return "BP", Tm, w0, m
42
43 def set_components(self, Tm, w0, m):
44 """
45 Set the circuit components C, R1 et R2 from the filter parameters and the attribute L
46
47 Parameters
48 ----------
49 Tm : float
50 w0 : float
51 m : float
52 """
53
54 C = 1 / (self.L*(w0**2))
55 R2 = (1/(2*m*Tm))*np.sqrt(self.L/C)
56 R1 = (R2*Tm) / (1-Tm)
57 self.R2 = R2
58 self.R1 = R1
59 self.C = C
Test unitaire#
Pour valider le bon fonctionnement de la classe, il est possible de réaliser un test unitaire. Un test unitaire est une méthode de test de logiciel où des unités individuelles (ou composants) d’un logiciel sont testées séparément pour s’assurer qu’elles fonctionnent correctement. L’objectif est d’isoler chaque partie du programme et de vérifier qu’elle fonctionne comme prévu.
En python, les tests unitaires peuvent être réalisés facilement avec le framework unitests. Dans notre cas, nous allons créer le fichier test_filter_RLC.py contenant le code suivant.
1import unittest
2from filter_RLC import RLC_BP3_Filter
3
4class TestRLC_BP3_Filter(unittest.TestCase):
5
6 def setUp(self):
7 self.L = 10**-3
8 self.Tm_ref, self.w0_ref, self.m_ref = 0.5, 10*3, 0.2
9 self.my_filter = RLC_BP3_Filter(10**3, 10**3, 10**-9, self.L)
10
11 def test_set_and_get_params(self):
12 self.my_filter.set_components(self.Tm_ref, self.w0_ref, self.m_ref)
13 _, Tm, w0, m = self.my_filter.get_params()
14
15 self.assertAlmostEqual(Tm, self.Tm_ref, places=20)
16 self.assertAlmostEqual(w0, self.w0_ref, places=20)
17 self.assertAlmostEqual(m, self.m_ref, places=20)
18
19
20if __name__ == "__main__":
21 unittest.main()
Pour tester le bon fonctionnement de la classe RLC_BP3_Filter, il suffit ensuite de lancer le script python suivant
python test_filter_RLC.py
Liste des circuits#
Note
Chaque étudiant devra choisir un filtre passif et un filtre actif.