Binder NbViewer

Réponse harmonique d’un système dynamique#

Ce carnet Jupyter a pour objectif de tracer le diagramme de Bode d’un système dynamique du 2e ordre.

Ses fonctionnalités majeures :

  • Interactivité par utilisation du module ipywidgets

  • Diagramming par utilisation de l’outil Mermaid intégré à Jupyter depuis Jupyter Lab 4.0 et Jupyter Notebook 7.0

Ses autres fonctionnalités

  • Affichage de formules mathématiques insérées dans le texte ou en tant que paragraphe

  • Narratif par utilisation de l’alternance des cellules Markdown et des cellules de code pour expliquer l’usage de la classe TransferFunction du module scipy.signal

  • Affichage de courbe par utilisation du module Matplotlib.

Frontière d’isolement#

flowchart LR
  %% définition d'activité en forme de rectangle [ ]
  entree["e(t)"]
  systeme[Système\ndynamique]
  sortie["s(t)"]
  %% définition d'un style de forme "invisible"
  classDef sansCadre fill:#ffffff, stroke:#ffffff
  %% description du diagramme
  entree:::sansCadre --> systeme --> sortie:::sansCadre 

Modèle#

On considère le système dynamique régi par l’équation différentielle suivante

\[ \frac{1}{\omega_0^2}\frac{d^2s(t)}{dt^2} + \frac{2\xi}{\omega_0}\frac{ds(t)}{dt} + s(t) = Ke(t) \]

  • \(e(t)\) est l’entrée du système

  • \(s(t)\) est la sortie du système

  • \(K\) est le gain statique du système (unité correspondant au rapport des unités de \(s(t)\) et de \(e(t)\))

  • \(\xi\) est le coefficient d’amortissement du système (sans unité)

  • \(\omega_0\) est la pulsation propre du système (\(\text{rad}/\text{s}\) ou \(\text{s}^{-1}\))

Dans le domaine de Laplace, la fonction de transfert de ce système dynamique est

\[ H(p) = \frac{S(p)}{E(p)} = \frac{K}{1 + \frac{2\xi}{\omega_0}p + \frac{p^2 }{\omega_0^2} } \]

Codage avec Python#

Pour représenter la fonction de transfert on utilise la classe TransferFunction (système linéaire invariant sous sa forme de fonction transfert) du module scipy.signal. Dans ce module, une fonction de transfert de type

\[ H(p) = \frac{\sum_{i=0}^n b_{n-i}.p^n}{\sum_{i=0}^m a_{m-i}.p^m} \]

est représentée par TransferFunction(numerateur, denominateur), une instance de la classe TransferFunctionnumerateur est la liste Python \([b_0, b_1 \dots b_n]\) et denominateur est la liste \([a_0, a_1 \dots a_m]\)

Exemple#

La construction de la fonction transfert \(H(p) = \frac{4p + 3}{5p^2 + 2p + 1}\) donne

import scipy.signal as signal

numerateur = [4, 3]  # 4p + 3
denominateur = [5, 2, 1]  # 5p² + 2p + 1
signal.TransferFunction(numerateur, denominateur)
TransferFunctionContinuous(
array([0.8, 0.6]),
array([1. , 0.4, 0.2]),
dt: None
)

Fonction de calcul de la réponse harmonique du système#

def reponse_harmonique(numerateur=[1], denominateur=[1, 1, 1]):
    """
    Renvoie les listes pulsation, amplitude, phase d'une
    sollicitation harmonique faite à un système dont le
    numérateur et le dénominateur sont forni en entrée.

    Parameters
    ----------
    numerateur : list
        numérateur de la fonction de transfert du system
    denominateur: list
        dénominateur de la fonction de transfert du system.

    Returns
    -------
    pulsation : numpy.ndarray
        liste des pulsations d'entrée du système
    amplitude : numpy.ndarray
        liste des amplutides de sortie du système
    phase : numpy.ndarray
        liste des déphasages de sortie du système
    """
    h = signal.TransferFunction(numerateur, denominateur)
    pulsation, amplitude, phase = h.bode()
    return pulsation, amplitude, phase

Fonction qui trace de la réponse du sytème#

import matplotlib.pyplot as plt

def trace_bode(pulsation, amplitude, phase):
    """Trace amplitude et phase en fonction de pulsation."""
    plt.rcParams['figure.figsize'] = [5, 4]
    plt.suptitle('Diagramme de Bode')
    
    plt.subplot(211)
    plt.semilogx(pulsation, amplitude, lw=2)
    plt.ylabel('Amplitude (dB)')
    plt.grid(which='both')

    plt.subplot(212)
    plt.semilogx(pulsation, phase)
    plt.xlabel('Pulsation (rad/s)')
    plt.ylabel('Phase (deg)')
    plt.grid(which='both')

    plt.tight_layout()

Tracé de la réponse harmonique#

trace_bode(*reponse_harmonique())
../_images/2b1e41203c18d8e052a8c6b378da34b6da2996b86027a65a30ce835547d0406c.png

Tracé interactif de la réponse harmonique#

La cellule suivante nécessite l’accès à un noyau d’exécution (kernel) pour être interactive. Chaque mouvement du curseur sur un des trois paramètres du système lance l’exécution de la fonction etude_systeme() qui trace la nouvelle réponse.

import ipywidgets

@ipywidgets.interact(k=(0.1,10.), log_xi=(-2.,2.), w0=(10.,100.))
def etude_systeme(k=5, log_xi=0.50, w0=50):
    numerateur = [k]
    denominateur = [w0**-2, 2*10**log_xi/w0, 1]
    trace_bode(*reponse_harmonique(numerateur, denominateur))