Ce TP est dédié à l'acquisition d'une capacité numérique: Mettre en oeuvre différentes méthodes numérique afin d'apprendre à simuler le comportement d'un oscillateur.

Vous allez effectuer vos simulations à l'aide du langage de programmation python dans le Notebook ci-dessous.

Importations des outils¶

QUESTION 1

Commençons par importer les librairies numpy avec le préfixe np ainsi que la librairie matplotlib.pyplot avec le préfixe plt

In [ ]:
 

Les oscillateurs que nous avons étudiés sont constitués de deux blocs en cascade. Pour l'oscillateur quasi-sinusoïdal ce sont les blocs amplificateur et filtre passe-bande du second ordre, Pour l'oscillateur de relaxation ce sont les blocs comparateur à hystérésis et intégrateur.

Nous allons donc commencer par simuler le fonctionnement de chaque bloc indépendamment.

Blocs de l'oscillateur quasi-sinusoïdal¶

Bloc amplificateur¶

Le bloc amplificateur est caractérisé par deux éléments :

  • son gain $A$ qui est le rapport entre les tensions de sortie et d'entrée en fonctionnement linéaire, soit $v_s = A\times v_e$
  • ses tensions de saturation $V_{sat,+}$ et $V_{sat,-}$ qui sont les tensions limites de sa sortie

QUESTION 2

Définir une fonction

def sortie_amplificateur(v_e:float, V_sat_p:float, V_sat_m:float, A:float) -> v_s:float :

qui prends en argument les nombres :

  • v_e, tension à l'entrée de l'amplificateur $v_e$
  • V_sat_p, tension de saturation positive de l'amplificateur $V_{sat,+}$
  • V_sat_m, tension de saturation négative de l'amplificateur $V_{sat,-}$
  • A, le gain de l'amplificateur $A$

et qui renvoie le nombre :

  • v_s, tension à la sortie de l'amplificateur $v_s$

Nous ferons attention à distinguer les cas de saturation et de régime linéaire pour écrire notre fonction.

In [ ]:
 

Testons notre fonction sortie_amplificateur

QUESTION 3

Définissez des variables et assignez des valeurs pour les paramètres :

  • V_sat_p tension de saturation positive (par exemple 15 V)
  • V_sat_m tension de saturation négative (par exemple -15 V)
  • A gain de l'amplificateur (par exemple 3)
  • N nombre de points calculés pour le test (par exemple 100)

(N'hésitez pas à tester d'autres valeurs plus proche de votre TP2 ou pour en voir l'effet)

Définissez des valeurs de tensions d'entrée à tester avec le np.array entrées qui sera une liste de N valeurs allant de V_sat_m à V_sat_p. On pourra utiliser pour cela la fonction :

  • np.linspace(start,stop,num=50) renvoie un np.array de 50 valeurs espacées équitablement dans l'intervalle [start,stop]

Définissez le np.array sorties qui sera une liste de N zéros dans laquelle on stockera les résultats de notre fonction sortie_amplificateur pour chaque élément d'entrées. On pourra utiliser pour cela la fonction :

  • np.zeros(shape) renvoie un np.array de shape zéros

A l'aide d'une boucle for assignez à chaque éléments sorties[i] la valeur renvoyé par votre fonction sortie_amplificateur prenant en arguments les paramètres précédents V_sat_p, V_sat_m, A et la tension d'entrée entrées[i]

Affichez avec un print() le np.array sorties obtenu.

In [ ]:
 

Affichons les résultats de notre test à l'aide d'un graphique afin de mieux contrôler visuellement le bon fonctionnement de notre fonction.

QUESTION 4

Tracez le np.array sorties en fonction du np.array entrées sous forme de point. On pourra utiliser les fonctions :

  • plt.plot(x,y,'.') trace y en fonction de x avec des points
  • plt.xlabel("abscisses") affiche la chaîne de caractères abscisses sous l'axe des abscisses
  • plt.ylabel("ordonnées") affiche la chaîne de caractères ordonnées à côté de l'axe des ordonnées
  • plt.legend(["légende"]) affiche la chaîne de caractères légende en légende
  • plt.show() affiche le graphique prè-définit
  • plt.close() implique que les prochains tracés se feront sur un autre graphique
In [ ]:
 

Pour la suite de la simulation, nous aurons aussi besoin de calculer la dérivée de la tension de sortie de l'amplificateur $\dfrac{\mathrm{d}v_s}{\mathrm{d}t}$ en fonction de la tension d'entrée de l'amplificateur $v_e$ et de sa dérivée $\dfrac{\mathrm{d}v_e}{\mathrm{d}t}$.

Pour cela nous distinguerons deux régimes :

  • soit l'amplificateur est en régime linéaire et $\dfrac{\mathrm{d}v_s}{\mathrm{d}t} = A\times\dfrac{\mathrm{d}v_e}{\mathrm{d}t}$
  • soit l'amplificateur est en régime saturé et la sortie est constante égale à sa tension de saturation, donc de dérivée nulle $\dfrac{\mathrm{d}v_s}{\mathrm{d}t} = 0$

QUESTION 5

Re-Définir la fonction

def sortie_amplificateur(v_e:float, Dv_e:float, V_sat_p:float, V_sat_m:float, A:float) -> (v_s:float, Dv_s:float) :

(les ":float" et "-> (vs:float, Dv_s:float)" sont là pour vous indiquez les type et sorties attendues, ils ne sont pas à recopier)

qui prends en argument les nombres :

  • v_e, tension à l'entrée de l'amplificateur $v_e$
  • Dv_e, la dérivée de la tension d'entrée de l'amplificateur $\dfrac{\mathrm{d}v_e}{\mathrm{d}t}$
  • V_sat_p, tension de saturation positive de l'amplificateur $V_{sat,+}$
  • V_sat_m, tension de saturation négative de l'amplificateur $V_{sat,-}$
  • A, le gain de l'amplificateur $A$

et qui renvoie un tuple de nombres :

  • v_s, tension à la sortie de l'amplificateur $v_s$
  • Dv_s, la dérivée de la tension de sortie de l'amplificateur $\dfrac{\mathrm{d}v_s}{\mathrm{d}t}$

Nous reprendrons la fonction précédente que nous améliorerons

In [ ]:
 

Bloc filtre passe-bande du second ordre¶

Un filtre passe-bande du second ordre est caractérisé par sa fonction de transfert :

$ \begin{equation} \underline{H} = \dfrac{G}{1+jQ\left(\dfrac{\omega}{\omega_0}-\dfrac{\omega_0}{\omega}\right)} \end{equation} $

Comme nous ferons la simulation de l'évolution temporelle des oscillateurs nous allons nous interesser plutôt à l'équation différentielle correspondante :

$ \begin{equation} \dfrac{\mathrm{d}^2v_s}{\mathrm{d}t^2}+\dfrac{\omega_0}{Q}\dfrac{\mathrm{d}v_s}{\mathrm{d}t}+\omega_0^2v_s = \dfrac{G\omega_0}{Q}\dfrac{\mathrm{d}v_e}{\mathrm{d}t} \end{equation} $

avec $G$ le gain à résonance, $Q$ le facteur de qualité et $\omega_0$ la pulsation propre.

Méthode d'Euler explicite

Cette équation différentielle étant du second ordre nous devons la ré-écrire comme une équation du premier ordre pour appliquer une méthode d'Euler explicite à sa résolution numérique.

Pour cela nous allons définir deux variables pour les tensions d'entrée et de sortie qui sont les fonctions et leurs dérivées : ($v_s$ et $\dfrac{\mathrm{d}v_s}{\mathrm{d}t}$) ainsi que ($v_e$ et $\dfrac{\mathrm{d}v_e}{\mathrm{d}t}$) que nous rassemblerons dans les vecteurs : $ \begin{pmatrix} v_s \\ \dfrac{\mathrm{d}v_s}{\mathrm{d}t} \end{pmatrix} $ et $ \begin{pmatrix} v_e \\ \dfrac{\mathrm{d}v_e}{\mathrm{d}t} \end{pmatrix} $

On obtient donc une nouvelle écriture pour l'équation différentielle : $ \dfrac{\mathrm{d}}{\mathrm{d}t}\left( \begin{pmatrix} v_s \\ \dfrac{\mathrm{d}v_s}{\mathrm{d}t} \end{pmatrix} \right) = \begin{pmatrix} \dfrac{\mathrm{d}v_s}{\mathrm{d}t} \\ -\dfrac{\omega_0}{Q}\dfrac{\mathrm{d}v_s}{\mathrm{d}t}-\omega_0^2v_s + \dfrac{G\omega_0}{Q}\dfrac{\mathrm{d}v_e}{\mathrm{d}t} \end{pmatrix} $

La méthode d'Euler explicite est alors basée sur l'approximation de la dérivée par son taux d'acroissement suivante : $ \begin{equation} \dfrac{\mathrm{d}y}{\mathrm{d}t} = f(y(t),x(t)) \Rightarrow y(t+\mathrm{d}t) \simeq y(t) + f(y(t),x(t))dt \end{equation} $

Ce qui se traduit dans notre cas par l'approximation :

$ \begin{equation} \begin{pmatrix} v_s(t+\mathrm{d}t) \\ \dfrac{\mathrm{d}v_s}{\mathrm{d}t}(t+\mathrm{d}t) \end{pmatrix} \simeq \begin{pmatrix} v_s(t) \\ \dfrac{\mathrm{d}v_s}{\mathrm{d}t}(t) \end{pmatrix}

\begin{pmatrix} \dfrac{\mathrm{d}v_s}{\mathrm{d}t}(t)\times \mathrm{d}t \\ -\dfrac{\omega_0}{Q}\dfrac{\mathrm{d}v_s}{\mathrm{d}t}(t)\times \mathrm{d}t -\omega_0^2v_s(t)\times \mathrm{d}t + \dfrac{G\omega_0}{Q}\dfrac{\mathrm{d}v_e}{\mathrm{d}t}(t)\times \mathrm{d}t \end{pmatrix}

\end{equation} $

Soit deux équations :

$ \begin{equation} v_s(t+\mathrm{d}t) \simeq v_s(t)+\dfrac{\mathrm{d}v_s}{\mathrm{d}t}(t)\times \mathrm{d}t \end{equation} $

et

$ \begin{equation} \dfrac{\mathrm{d}v_s}{\mathrm{d}t}(t+\mathrm{d}t) \simeq \dfrac{\mathrm{d}v_s}{\mathrm{d}t}(t) -\dfrac{\omega_0}{Q}\dfrac{\mathrm{d}v_s}{\mathrm{d}t}(t)\times \mathrm{d}t -\omega_0^2v_s(t)\times \mathrm{d}t + \dfrac{G\omega_0}{Q}\dfrac{\mathrm{d}v_e}{\mathrm{d}t}(t)\times \mathrm{d}t \end{equation} $

QUESTION 6

Définir une fonction

def filtre_passe_bande(v_s:float, Dv_s:float, v_e:float, Dv_e:float, omega_0:float, Q:float, G:float, dt:float) -> (v_s_prime:float, Dv_s_prime:float) :

qui prends en argument les nombres :

  • v_s la tension de sortie à l'instant $t$, soit $v_s(t)$
  • Dv_s la dérivée de la tension de sortie à l'instant $t$, soit $\dfrac{\mathrm{d}v_s}{\mathrm{d}t}(t)$
  • v_e la tension d'entrée à l'instant $t$, soit $v_e(t)$
  • Dv_e la dérivée de la tension d'entrée à l'instant $t$, soit $\dfrac{\mathrm{d}v_e}{\mathrm{d}t}(t)$
  • omega_0 la pulsation de résonance du filtre
  • Q le facteur de qualité du filtre
  • G le gain à résonance du filtre
  • dt le pas de temps choisi pour la méthode d'Euler explicite

et qui renvoie le tuple de nombres :

  • v_s_prime la tension de sortie à l'instant $t+\mathrm{d}t$, soit $v_s(t+\mathrm{d}t)$ obtenue par la méthode d'Euler
  • Dv_s_prime la dérivée de la tension de sortie à l'instant $t+\mathrm{d}t$, soit $\dfrac{\mathrm{d}v_s}{\mathrm{d}t}(t+\mathrm{d}t)$ obtenue par la méthode d'Euler
In [ ]:
 

Testons la simulation du filtre passe-bande en oscillation libre.

QUESTION 7

Définissez des variables et assignez des valeurs aux paramètres :

  • omega_0 pulsation propre du filtre $\omega_0$ (par exemple 1000 rad/s)
  • Q facteur de qualité du filtre $Q$ (par exemple 10)
  • G gain à résonance du filtre $G$ (par exemple 1/3)
  • durée durée totale sur laquelle nous allons calculé l'évolution de la sortie du filtre $\Delta t$ (par exemple 0.1 s)
  • N nombre de points calculés pendant la durée d'évolution de la sortie du filtre (par exmple 10 000)

(n'hésitez pas à tester d'autres valeurs)

Définissez une variable et calculez le pas de temps dt à partir de la durée et du nombre de points N comme $ \begin{equation} \mathrm{d}t = \dfrac{\Delta t}{N} \end{equation} $

Définissez un np.array t qui comporte les $N$ instants de 0 à $\Delta t$. On pourra utiliser pour cela la fonction :

  • np.linspace(start,stop,num=50) renvoie un np.array de 50 valeurs espacées équitablement dans l'intervalle [start,stop]

Définissez les np.array entrées, Dentrées, sorties, Dsorties comportant initialement N éléments égals à 0. On pourra utiliser pour cela la fonction :

  • np.zeros(shape) renvoie un np.array de shape zéros

Fixer les conditions initiales en assignant une valeur non nulle à l'élément d'indice 0 du np.array sorties

A l'aide d'une boucle for remplissez tous les éléments d'indice i+1 des np.array sorties et Dsorties à l'aide de votre fonction filtre_passe_bande qui les calculera à partir des éléments d'indice i des np.array sorties, Dsorties, entrées et Dentrées.

Ainsi vous simulerez l'évolution par pas de $dt$ de 0 à $\Delta t$ de la tension de sortie du filtre $v_s(t)$, avec une tension d'entrée nulle $v_e(t) = 0$.

In [ ]:
 

Affichons le résultat de notre calcul pour observer si la simulation correspond à nos attentes.

QUESTION 8

Tracez le np.array sorties en fonction du np.array t sous forme de point. On pourra utiliser les fonctions :

  • plt.plot(x,y,'.') trace y en fonction de x avec des points
  • plt.xlabel("abscisses") affiche la chaîne de caractères abscisses sous l'axe des abscisses
  • plt.ylabel("ordonnées") affiche la chaîne de caractères ordonnées à côté de l'axe des ordonnées
  • plt.legend(["légende"]) affiche la chaîne de caractères légende en légende
  • plt.show() affiche le graphique prè-définit
  • plt.close() implique que les prochains tracés se feront sur un autre graphique
In [ ]:
 

Mise en cascade des blocs amplificateur et filtre passe-bande du second ordre¶

Nous avons réalisé les blocs nécessaire à la simulation d'un oscillateur quasi-sinusoïdal, nous allons donc utiliser les fonctions filtre_passe_bande() et sortie_amplificateur() précédentes de manière alternée pour simuler le fonction bouclé de l'oscillateur.

Commençons tout d'abord par définir les paramètres des deux blocs.

QUESTION 9

Définissez des variables et assignez des valeurs aux paramètres :

  • V_sat_p tension de saturation positive (par exemple 14.6 V)
  • V_sat_m tension de saturation négative (par exemple -13.4 V)
  • A gain de l'amplificateur (par exemple 3.1)
  • omega_0 pulsation propre du filtre $\omega_0$ (par exemple 1000 rad/s)
  • Q facteur de qualité du filtre $Q$ (par exemple 1/3)
  • G gain à résonance du filtre $G$ (par exemple 1/3)
  • durée durée totale sur laquelle nous allons calculé l'évolution de la sortie du filtre $\Delta t$ (par exemple 0.3 s)
  • N nombre de points calculés pendant la durée d'évolution de la sortie du filtre (par exemple 10 000)

Définissez une variable et calculez le pas de temps dt à partir de la durée et du nombre de points N comme $ \begin{equation} \mathrm{d}t = \dfrac{\Delta t}{N} \end{equation} $

Définissez un np.array t qui comporte les $N$ instants de 0 à $\Delta t$. On pourra utiliser pour cela la fonction :

  • np.linspace(start,stop,num=50) renvoie un np.array de 50 valeurs espacées équitablement dans l'intervalle [start,stop]
In [ ]:
 

Pour la suite nous appelerons $v_1(t)$ l'entrée du filtre et $v_2(t)$ la sortie, définissons les objets dans lesquels nous stockerons ces grandeurs $v_1(t)$, $\dfrac{\mathrm{d}v_1}{\mathrm{d}t}$, $v_2(t)$ et $\dfrac{\mathrm{d}v_2}{\mathrm{d}t}$ ainsi que les conditions initiales correspondantes.

QUESTION 10

Définissez les np.array v_1, Dv_1, v_2, Dv_2 comportant initialement N éléments égals à 0. On pourra utiliser pour cela la fonction :

  • np.zeros(shape) renvoie un np.array de shape zéros

Fixer les conditions initiales en assignant une valeur non nulle au premier élément du np.array Dv_1 (par exemple Dv_1[0] = 1)

In [ ]:
 

Pour le fonctionnement en système bouclé de l'oscillateur, il s'agit donc maintenant d'exécuter de manière alternée les fonctions filtre_passe_bande et sortie_amplificateur pour calculer à chaque pas de temps $\mathrm{d}t$ les valeurs de $v_1(t)$, $\dfrac{\mathrm{d}v_1}{\mathrm{d}t}$, $v_2(t)$ et $\dfrac{\mathrm{d}v_2}{\mathrm{d}t}$.

QUESTION 11

A l'aide d'une boucle for,

calculez d'abord les éléments d'indice i+1 des np.array v_2 et Dv_2 à l'aide de la fonction filtre_passe_bande et des éléments d'indice i des np.array v_1, Dv_1, v_2, Dv_2,

puis calculez les éléments d'indice i+1 des np.array v_1 et Dv_1 à l'aide de la fonction sortie_amplificateur et des éléments d'indice i+1 des np.array v_2 et Dv_2 que vous venez de calculer

In [ ]:
 

Affichons maintenant les résultats obtenus pour visualiser le démarrage et le régime permanent des oscillations.

QUESTION 12

Tracez les np.array v_1 et v_2 en fonction du np.array t sous forme de trait. On pourra utiliser les fonctions :

  • plt.plot(x,y,'-') trace y en fonction de x avec des traits
  • plt.xlabel("abscisses") affiche la chaîne de caractères abscisses sous l'axe des abscisses
  • plt.ylabel("ordonnées") affiche la chaîne de caractères ordonnées à côté de l'axe des ordonnées
  • plt.legend(["légende1","légende2"]) affiche les chaînes de caractères légende1 et légende2 en légende
  • plt.show() affiche le graphique prè-définit
  • plt.close() implique que les prochains tracés se feront sur un autre graphique
In [ ]:
 

Blocs de l'oscillateur de relaxation¶

Bloc comparateur à hystérésis non-inverseur¶

Le bloc comparateur à hystérésis non-inverseur est caractérisé par deux éléments :

  • ses tensions seuil de basculement $V_{0,+}$ et $V_{0,-}$
  • ses tensions de saturation $V_{sat,+}$ et $V_{sat,-}$

QUESTION 13

Définir une fonction

def comparateur_hystérésis(v_e:float, v_s:float, V_sat_p:float, V_sat_m:float, V_0_p:float, V_0_m:float) -> v_s_prime:float :

qui prends en argument les nombres :

  • v_e, tension à l'entrée du comparateur $v_e$
  • v_s, tension précédente à la sortie du comparateur $v_s$
  • V_sat_p, tension de saturation positive du comparateur $V_{sat,+}$
  • V_sat_m, tension de saturation négative du comparateur $V_{sat,-}$
  • V_0_p, tension seuil de basculement positive du comparateur $V_{0,+}$
  • V_0_m, tension seuil de basculement négative du comparateur $V_{0,-}$

et qui renvoie le nombre :

  • v_s_prime, nouvelle tension à la sortie de l'amplificateur $v_s$

Nous ferons attention à distinguer les cas de saturation positive ou négative précédente pour écrire notre fonction.

In [ ]:
 

Testons notre fonction comparateur_hystérésis

QUESTION 14

Définissez des variables et assignez des valeurs pour les paramètres :

  • V_sat_p tension de saturation positive (par exemple +15V)
  • V_sat_m tension de saturation négative (par exemple -15V)
  • V_0_p tension de saturation positive (par exemple 7.5V)
  • V_0_m tension de saturation négative (par exemple -7.5V)
  • N le nombre de points qui doit être pair (par exemple 1000)

(n'hésitez pas à tester d'autres valeurs)

Définissez des valeurs de tensions d'entrée à tester avec le np.array entrées qui sera une liste de N valeurs allant de V_sat_m à V_sat_p puis de V_sat_p à V_sat_m. On pourra utiliser pour cela les fonctions :

  • np.linspace(start,stop,num=50) renvoie un np.array de 50 valeurs espacées équitablement dans l'intervalle [start,stop]
  • np.concatenate((a1,a2),axis=0) renvoie la concaténation des listes a1 et a2

Définissez le np.array sorties qui sera une liste de N zéros dans laquelle on stockera les résultats de notre fonction comparateur_hystérésis pour chaque élément d'entrées. On pourra utiliser pour cela la fonction :

  • np.zeros(shape) renvoie un np.array de shape zéros

Initialisez le premier élément de sorties à V_sat_m

A l'aide d'une boucle for assignez à chaque éléments sorties[i+1] la valeur renvoyé par votre fonction comparateur_hystérésis prenant en arguments les paramètres précédents V_sat_p, V_sat_m, V_0_p, V_0_m, la tension d'entrée entrées[i] et la tension de sortie sorties[i]

In [ ]:
 

Affichons les résultats de notre test à l'aide d'un graphique afin de mieux contrôler visuellement le bon fonctionnement de notre fonction.

QUESTION 15

Tracez le np.array sorties en fonction du np.array entrées sous forme de trait. On pourra utiliser les fonctions :

  • plt.plot(x,y,'-') trace y en fonction de x avec des traits
  • plt.xlabel("abscisses") affiche la chaîne de caractères abscisses sous l'axe des abscisses
  • plt.ylabel("ordonnées") affiche la chaîne de caractères ordonnées à côté de l'axe des ordonnées
  • plt.legend(["légende"]) affiche la chaîne de caractères légende en légende
  • plt.show() affiche le graphique prè-définit
  • plt.close() implique que les prochains tracés se feront sur un autre graphique
In [ ]:
 

Bloc intégrateur inverseur¶

Un montage intégrateur inverseur réel est caractérisé par sa fonction de transfert :

$ \begin{equation} \underline{H} = \dfrac{-\tau^\prime/\tau}{1+j\tau^\prime\omega} \end{equation} $

Comme nous allons étudier l'évolution temporelle des tensions, nous nous interresserons plutôt à l'équation différentielle :

$ \begin{equation} \dfrac{\mathrm{d}v_s}{\mathrm{d}t}+\dfrac{v_s}{\tau^\prime} = -\dfrac{v_e}{\tau} \end{equation} $

avec $\tau^\prime \gg \tau$ afin d'avoir un comportement intégrateur pour les pulsations $\omega \gg \dfrac{1}{\tau^\prime}$.

Méthode d'Euler explicite

L'équation différentielle étant déjà une équation du premier ordre, la méthode d'Euler sera plus facile a explicité comme

$ \begin{equation} \dfrac{\mathrm{d}v_s}{\mathrm{d}t} = -\dfrac{v_s}{\tau^\prime} -\dfrac{v_e}{\tau} \end{equation} $

et que la méthode d'Euler est basée sur l'approximation $v_s(t+\mathrm{d}t) \simeq v_s(t) + \dfrac{\mathrm{d}v_s}{\mathrm{d}t}\times \mathrm{d}t$

On obtient la relation

$ \begin{equation} v_s(t+\mathrm{d}t) \simeq v_s(t) -\left(\dfrac{v_s(t)}{\tau^\prime} + \dfrac{v_e(t)}{\tau}\right)\times\mathrm{d}t \end{equation} $

QUESTION 16

Définir une fonction

def integrateur_inverseur_reel(v_s:float, v_e:float, tau:float, tau_prime:float, dt:float) -> v_s_prime:float :

qui prends en argument les nombres :

  • v_s la tension de sortie à l'instant $t$, soit $v_s(t)$
  • v_e la tension d'entrée à l'instant $t$, soit $v_e(t)$
  • tau la constante de temps d'intégration $\tau$
  • tau_prime la constante de temps de la bande de fréquence intégrée $\tau^\prime$
  • dt le pas de temps choisi pour la méthode d'Euler explicite

et qui renvoie le tuple de nombres :

  • v_s_prime la tension de sortie à l'instant $t+\mathrm{d}t$, soit $v_s(t+\mathrm{d}t)$ obtenue par la méthode d'Euler
In [ ]:
 

Testons la simulation de l'intégrateur inverseur réel en régime sinusoïdal.

QUESTION 17

Définissez des variables et assignez des valeurs aux paramètres :

  • tau la constante de temps d'intégration $\tau$ (par exemple 0.001 s)
  • tau_prime la constante de temps de la bande de fréquence intégrée $\tau^\prime$ (par exemple 0.1 s)
  • durée durée totale sur laquelle nous allons calculé l'évolution de la sortie de l'intégrateur $\Delta t$ (par exemple 0.01 s)
  • N nombre de points calculés pendant la durée d'évolution de la sortie de l'intégrateur (par exemple 10 000)

(n'hésitez pas à tester d'autres valeurs)

Définissez une variable et calculez le pas de temps dt à partir de la durée et du nombre de points N comme $ \begin{equation} \mathrm{d}t = \dfrac{\Delta t}{N} \end{equation} $

Définissez un np.array t qui comporte les $N$ instants de 0 à $\Delta t$. On pourra utiliser pour cela la fonction :

  • np.linspace(start,stop,num=50) renvoie un np.array de 50 valeurs espacées équitablement dans l'intervalle [start,stop]

Définissez le np.array sorties comportant initialement N éléments égals à 0. On pourra utiliser pour cela la fonction :

  • np.zeros(shape) renvoie un np.array de shape zéros

Définissez le np.array entrée comme une fonction cosinus de t.

A l'aide d'une boucle for remplissez tous les éléments d'indice i+1 des np.array sorties à l'aide de votre fonction integrateur_inverseur_reel qui les calculera à partir des éléments d'indice i des np.array sorties et entrées.

Ainsi vous simulerez l'évolution par pas de $dt$ de 0 à $\Delta t$ de la tension de sortie de l'intégrateur $v_s(t)$, avec une tension d'entrée sinusoïdale.

In [ ]:
 

Affichons le résultat de notre calcul pour observer si la simulation correspond à nos attentes.

QUESTION 18

Tracez les np.array entrées et sorties en fonction du np.array t sous forme de point. On pourra utiliser les fonctions :

  • plt.plot(x,y,'.') trace y en fonction de x avec des points
  • plt.xlabel("abscisses") affiche la chaîne de caractères abscisses sous l'axe des abscisses
  • plt.ylabel("ordonnées") affiche la chaîne de caractères ordonnées à côté de l'axe des ordonnées
  • plt.legend(["légende1","légende2"]) affiche les chaînes de caractères légende1 et légende2 en légende
  • plt.show() affiche le graphique prè-définit
  • plt.close() implique que les prochains tracés se feront sur un autre graphique
In [ ]:
 

Mise en cascade des blocs comparateur à hystérésis et intégrateur inverseur réel¶

Nous avons réalisé les blocs nécessaire à la simulation d'un oscillateur de relaxation, nous allons donc utiliser les fonctions comparateur_hystérésis() et integrateur_inverseur_reel() précédentes de manière alternée pour simuler le fonction bouclé de l'oscillateur.

Commençons tout d'abord par définir les paramètres des deux blocs.

QUESTION 19

Définissez des variables et assignez des valeurs aux paramètres :

  • V_sat_p tension de saturation positive
  • V_sat_m tension de saturation négative
  • V_0_p tension seuil de basculement positive
  • V_0_m tension seuil de basculement négative
  • tau la constante de temps de l'intégrateur
  • tau_prime la constante de temps de la bande de pulsation intégrée
  • durée durée totale sur laquelle nous allons calculé l'évolution de la sortie de l'intégrateur $\Delta t$
  • N nombre de points calculés pendant la durée d'évolution de la sortie de l'intégrateur

(par exemple vous pouvez prendre les valeurs précédentes, mais n'hésitez pas à tester ensuite d'autres valeurs)

Définissez une variable et calculez le pas de temps dt à partir de la durée et du nombre de points N comme $ \begin{equation} \mathrm{d}t = \dfrac{\Delta t}{N} \end{equation} $

Définissez un np.array t qui comporte les $N$ instants de 0 à $\Delta t$. On pourra utiliser pour cela la fonction :

  • np.linspace(start,stop,num=50) renvoie un np.array de 50 valeurs espacées équitablement dans l'intervalle [start,stop]
In [ ]:
 

Pour la suite nous appelerons $v_1(t)$ l'entrée de l'intégrateur et $v_2(t)$ la sortie, définissons les objets dans lesquels nous stockerons ces grandeurs $v_1(t)$ et $v_2(t)$ ainsi que les conditions initiales correspondantes.

QUESTION 20

Définissez les np.array v_1 et v_2 comportant initialement N éléments égals à 0. On pourra utiliser pour cela la fonction :

  • np.zeros(shape) renvoie un np.array de shape zéros

Fixer les conditions initiales en assignant une valeur de saturation positive à $v_1(t)$.

In [ ]:
 

Pour le fonctionnement en système bouclé de l'oscillateur, il s'agit donc maintenant d'exécuter de manière alternée les fonctions integrateur_inverseur_reel et comparateur_hystérésis pour calculer à chaque pas de temps $\mathrm{d}t$ les valeurs de $v_1(t)$ et $v_2(t)$.

QUESTION 21

A l'aide d'une boucle for,

calculez d'abord l'élément d'indice i+1 du np.array v_2 à l'aide de la fonction integrateur_inverseur_reel et des éléments d'indice i des np.array v_1 et v_2,

puis calculez l'élément d'indice i+1 du np.array v_1 à l'aide de la fonction comparateur_hystérésis et de l'éléments d'indice i+1 du np.array v_2 que vous venez de calculer ainsi que de l'élément d'indice i du np.array v_1.

In [ ]:
 

Affichons maintenant les résultats obtenus.

QUESTION 22

Tracez les np.array v_1 et v_2 en fonction du np.array t sous forme de trait. On pourra utiliser les fonctions :

  • plt.plot(x,y,'-') trace y en fonction de x avec des traits
  • plt.xlabel("abscisses") affiche la chaîne de caractères abscisses sous l'axe des abscisses
  • plt.ylabel("ordonnées") affiche la chaîne de caractères ordonnées à côté de l'axe des ordonnées
  • plt.legend(["légende1","légende2"]) affiche les chaînes de caractères légende1 et légende2 en légende
  • plt.show() affiche le graphique prè-définit
  • plt.close() implique que les prochains tracés se feront sur un autre graphique
In [ ]:
 
In [ ]: