Cas d'étude : Suspension de voiture : Système mécanique composé d'un ressort et d'un amortisseur qui relie la roue au châssis, permettant d'absorber les irrégularités de la route.
- Identifier la problématique : Comment optimiser le confort et la tenue de route ?
- Analyser le système : Masse suspendue, ressort, amortisseur
- Établir le modèle mathématique : Équations différentielles
- Simuler le comportement : Réponse aux perturbations
- Valider les résultats : Comparer avec des mesures réelles
- Proposer des améliorations : Optimisation des paramètres
La suspension est modélisée comme un système masse-ressort-amortisseur :
• Masse suspendue (m) : 300 kg par roue
• Raideur du ressort (k) : 20000 N/m
• Coefficient d'amortissement (c) : 2000 N.s/m
Équation du mouvement : \(m\ddot{z} + c\dot{z} + kz = c\dot{y} + ky\)
Où z est le déplacement de la masse suspendue et y est l'excitation du sol
Pulsation propre : \(\omega_0 = \sqrt{\frac{k}{m}} = \sqrt{\frac{20000}{300}} = 8.16\) rad/s
Amortissement réduit : \(\delta = \frac{c}{2\sqrt{mk}} = \frac{2000}{2\sqrt{300 \times 20000}} = 0.41\)
Le système est sous-amorti (\(\delta < 1\))
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
def suspension_model(state, t, m, c, k, y_sol, dy_sol):
z, dzdt = state
d2zdt2 = (c*dy_sol + k*y_sol - c*dzdt - k*z) / m
return [dzdt, d2zdt2]
# Paramètres
m = 300 # kg
k = 20000 # N/m
c = 2000 # N.s/m
# Excitation du sol (bosse)
t = np.linspace(0, 2, 1000)
y_sol = 0.05 * np.exp(-10*(t-0.5)**2) # Bosse gaussienne
dy_sol = np.gradient(y_sol, t[1]-t[0])
# Conditions initiales
z0 = 0
dz0 = 0
state0 = [z0, dz0]
# Résolution
solution = odeint(suspension_model, state0, t, args=(m, c, k, y_sol[0], dy_sol[0]))
# Correction pour l'excitation variable
z = np.zeros_like(t)
dzdt = np.zeros_like(t)
z[0] = z0
dzdt[0] = dz0
for i in range(1, len(t)):
k1_z, k1_v = suspension_model([z[i-1], dzdt[i-1]], t[i-1], m, c, k, y_sol[i-1], dy_sol[i-1])
k2_z, k2_v = suspension_model([z[i-1] + 0.5*dt*k1_z, dzdt[i-1] + 0.5*dt*k1_v], t[i-1] + 0.5*dt, m, c, k, y_sol[i-1], dy_sol[i-1])
k3_z, k3_v = suspension_model([z[i-1] + 0.5*dt*k2_z, dzdt[i-1] + 0.5*dt*k2_v], t[i-1] + 0.5*dt, m, c, k, y_sol[i-1], dy_sol[i-1])
k4_z, k4_v = suspension_model([z[i-1] + dt*k3_z, dzdt[i-1] + dt*k3_v], t[i-1] + dt, m, c, k, y_sol[i-1], dy_sol[i-1])
z[i] = z[i-1] + (dt/6)*(k1_z + 2*k2_z + 2*k3_z + k4_z)
dzdt[i] = dzdt[i-1] + (dt/6)*(k1_v + 2*k2_v + 2*k3_v + k4_v)
dt = t[1] - t[0]
# Tracé
plt.figure(figsize=(12, 8))
plt.subplot(2, 2, 1)
plt.plot(t, y_sol, label='Excitation du sol', color='red')
plt.plot(t, z, label='Réponse de la suspension', color='blue')
plt.title('Réponse de la suspension à une bosse')
plt.xlabel('Temps (s)')
plt.ylabel('Déplacement (m)')
plt.legend()
plt.grid(True, alpha=0.3)
plt.subplot(2, 2, 2)
plt.plot(t, z - y_sol)
plt.title('Déplacement relatif (z - y)')
plt.xlabel('Temps (s)')
plt.ylabel('Déplacement relatif (m)')
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
• Temps de réponse : ~0.5s
• Dépassement : ~15%
• Oscillations : 2-3 cycles avant stabilisation
• Amortissement : Satisfaisant pour le confort
La suspension modélisée avec m=300kg, k=20000N/m et c=2000N.s/m présente un amortissement réduit de 0.41, ce qui correspond à un système sous-amorti convenant à un bon compromis entre confort et tenue de route.
• Équation du mouvement : \(m\ddot{z} + c\dot{z} + kz = c\dot{y} + ky\)
• Amortissement réduit : \(\delta = \frac{c}{2\sqrt{mk}}\)
• Pulsation propre : \(\omega_0 = \sqrt{\frac{k}{m}}\)
Cas d'étude : Moteur à courant continu : Système électromécanique convertissant l'énergie électrique en énergie mécanique, modélisé par des équations couplant les phénomènes électriques et mécaniques.
Le moteur CC est caractérisé par :
• Résistance d'armature (R) : 0.5 Ω
• Inductance d'armature (L) : 0.01 H
• Constante de couple (K) : 0.1 N.m/A
• Moment d'inertie (J) : 0.001 kg.m²
• Coefficient de frottement (f) : 0.001 N.m.s/rad
Équations du moteur :
\(u(t) = Ri(t) + L\frac{di}{dt} + e(t)\) (électrique)
\(e(t) = K\omega(t)\) (force contre-électromotrice)
\(J\frac{d\omega}{dt} + f\omega(t) = K i(t) - T_L(t)\) (mécanique)
Fonction de transfert en boucle ouverte (sans charge) :
\(\frac{\Omega(s)}{U(s)} = \frac{K}{(Ls + R)(Js + f) + K^2}\)
Constante de temps électrique : \(\tau_e = \frac{L}{R} = 0.02\) s
Constante de temps mécanique : \(\tau_m = \frac{JR}{K^2} = 0.5\) s
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
def motor_model(state, t, R, L, K, J, f, u, TL):
i, omega = state
di_dt = (u - R*i - K*omega) / L
domega_dt = (K*i - f*omega - TL) / J
return [di_dt, domega_dt]
# Paramètres du moteur
R = 0.5 # Résistance (Ohms)
L = 0.01 # Inductance (H)
K = 0.1 # Constante de couple (N.m/A)
J = 0.001 # Moment d'inertie (kg.m²)
f = 0.001 # Frottement (N.m.s/rad)
# Tension d'entrée
t = np.linspace(0, 0.5, 1000)
u = np.ones_like(t) * 12 # Tension constante de 12V
TL = np.zeros_like(t) # Pas de couple de charge
# Conditions initiales
i0 = 0
omega0 = 0
state0 = [i0, omega0]
# Résolution
solution = odeint(motor_model, state0, t, args=(R, L, K, J, f, u[0], TL[0]))
# Correction pour la tension variable
i = np.zeros_like(t)
omega = np.zeros_like(t)
i[0] = i0
omega[0] = omega0
dt = t[1] - t[0]
for i_idx in range(1, len(t)):
k1_i, k1_omega = motor_model([i[i_idx-1], omega[i_idx-1]], t[i_idx-1], R, L, K, J, f, u[i_idx-1], TL[i_idx-1])
k2_i, k2_omega = motor_model([i[i_idx-1] + 0.5*dt*k1_i, omega[i_idx-1] + 0.5*dt*k1_omega], t[i_idx-1] + 0.5*dt, R, L, K, J, f, u[i_idx-1], TL[i_idx-1])
k3_i, k3_omega = motor_model([i[i_idx-1] + 0.5*dt*k2_i, omega[i_idx-1] + 0.5*dt*k2_omega], t[i_idx-1] + 0.5*dt, R, L, K, J, f, u[i_idx-1], TL[i_idx-1])
k4_i, k4_omega = motor_model([i[i_idx-1] + dt*k3_i, omega[i_idx-1] + dt*k3_omega], t[i_idx-1] + dt, R, L, K, J, f, u[i_idx-1], TL[i_idx-1])
i[i_idx] = i[i_idx-1] + (dt/6)*(k1_i + 2*k2_i + 2*k3_i + k4_i)
omega[i_idx] = omega[i_idx-1] + (dt/6)*(k1_omega + 2*k2_omega + 2*k3_omega + k4_omega)
# Tracé
plt.figure(figsize=(12, 8))
plt.subplot(2, 2, 1)
plt.plot(t, i, label='Courant d\'armature', color='blue')
plt.title('Courant d\'armature en fonction du temps')
plt.xlabel('Temps (s)')
plt.ylabel('Courant (A)')
plt.grid(True, alpha=0.3)
plt.legend()
plt.subplot(2, 2, 2)
plt.plot(t, omega, label='Vitesse de rotation', color='red')
plt.title('Vitesse de rotation en fonction du temps')
plt.xlabel('Temps (s)')
plt.ylabel('Vitesse (rad/s)')
plt.grid(True, alpha=0.3)
plt.legend()
plt.subplot(2, 2, 3)
plt.plot(i, omega)
plt.title('Portrait de phase (i, ω)')
plt.xlabel('Courant (A)')
plt.ylabel('Vitesse (rad/s)')
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
• Vitesse finale : ~118 rad/s
• Courant de démarrage : ~24 A
• Temps de réponse : ~0.2 s
• Régime permanent : Courant ~0.2 A
Le moteur à courant continu avec les paramètres donnés atteint une vitesse de 118 rad/s en 0.2s environ, avec un courant de démarrage de 24A qui diminue à 0.2A en régime permanent.
• Équations électromécaniques : Couplage électrique/mécanique
• Force contre-électromotrice : \(e = K\omega\)
• Constantes de temps : Électrique et mécanique
Cas d'étude : Système de climatisation : Système thermique permettant de maintenir une température intérieure constante malgré les variations extérieures, modélisé par des équations de transfert thermique.
Le système de climatisation est caractérisé par :
• Volume à climatiser (V) : 100 m³
• Capacité thermique volumique (ρc) : 1200 J/m³.K
• Coefficient de transfert thermique (h) : 0.1 W/m².K
• Surface d'échange (S) : 100 m²
• Puissance frigorifique (P) : 2000 W
Équation de bilan thermique :
\(\rho V c \frac{dT}{dt} = hS(T_{ext} - T) - P \cdot u(t)\)
Où T est la température intérieure, T_ext la température extérieure, u(t) le signal de commande
Constante de temps thermique : \(\tau = \frac{\rho V c}{hS} = \frac{1200 \times 100}{0.1 \times 100} = 12000\) s
Soit environ 3.33 heures pour atteindre 63% de l'écart de température
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
def climate_model(T, t, rho_V_c, hS, P, Text, u):
dT_dt = (hS * (Text - T) - P * u) / rho_V_c
return dT_dt
# Paramètres du système
rho_V_c = 1200 * 100 # Capacité thermique (J/K)
hS = 0.1 * 100 # Conductance thermique (W/K)
P = 2000 # Puissance frigorifique (W)
# Température extérieure (variable)
t = np.linspace(0, 24*3600, 1000) # 24 heures en secondes
Text = 25 + 10 * np.sin(2*np.pi*t/(24*3600)) # Température variant entre 15 et 35°C
# Signal de commande (0 ou 1)
u = np.where(t % (12*3600) < 6*3600, 1, 0) # Climatisation ON 6h sur 12h
# Conditions initiales
T0 = 22 # Température initiale
# Résolution
T = np.zeros_like(t)
T[0] = T0
dt = t[1] - t[0]
for i in range(1, len(t)):
T[i] = T[i-1] + dt * climate_model(T[i-1], t[i-1], rho_V_c, hS, P, Text[i-1], u[i-1])
# Tracé
plt.figure(figsize=(12, 10))
plt.subplot(2, 2, 1)
plt.plot(t/3600, T, label='Température intérieure', color='blue')
plt.plot(t/3600, Text, label='Température extérieure', color='red', linestyle='--')
plt.title('Évolution de la température')
plt.xlabel('Temps (h)')
plt.ylabel('Température (°C)')
plt.legend()
plt.grid(True, alpha=0.3)
plt.subplot(2, 2, 2)
plt.plot(t/3600, u, label='Signal de commande', color='green')
plt.title('Signal de commande de la climatisation')
plt.xlabel('Temps (h)')
plt.ylabel('État (ON/OFF)')
plt.grid(True, alpha=0.3)
plt.subplot(2, 2, 3)
plt.plot(Text, T, '.')
plt.title('Corrélation température int/ext')
plt.xlabel('Température extérieure (°C)')
plt.ylabel('Température intérieure (°C)')
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
• Température intérieure maintenue entre 19 et 25°C
• Fluctuations atténuées par rapport à l'extérieur
• Constante de temps : 3.33 heures
• Puissance de climatisation suffisante
Le système de climatisation avec une puissance de 2000W maintient la température intérieure entre 19 et 25°C malgré les variations extérieures de ±10°C, avec une constante de temps de 3.33 heures.
• Équation de bilan thermique : Conservation de l'énergie
• Constante de temps : \(\tau = \frac{\rho V c}{hS}\)
• Transfert thermique : \(hS(T_{ext} - T)\)
Cas d'étude : Bras robotisé : Système articulé composé de segments reliés par des actionneurs, permettant de positionner un organe terminal dans l'espace, modélisé par des équations cinématiques et dynamiques.
Le bras robotisé à 2 degrés de liberté est caractérisé par :
• Longueur du premier segment (L₁) : 0.5 m
• Longueur du deuxième segment (L₂) : 0.4 m
• Masse du premier segment (m₁) : 1.0 kg
• Masse du deuxième segment (m₂) : 0.8 kg
• Centre de gravité : Milieu de chaque segment
Coordonnées de l'organe terminal :
\(x = L_1\cos(\theta_1) + L_2\cos(\theta_1 + \theta_2)\)
\(y = L_1\sin(\theta_1) + L_2\sin(\theta_1 + \theta_2)\)
Équations de Lagrange pour un bras à 2 articulations :
\(\mathbf{M(q)}\ddot{\mathbf{q}} + \mathbf{C(q,\dot{q})}\dot{\mathbf{q}} + \mathbf{G(q)} = \boldsymbol{\tau}\)
Où \(\mathbf{q} = [\theta_1, \theta_2]^T\) et \(\boldsymbol{\tau} = [\tau_1, \tau_2]^T\)
import numpy as np
import matplotlib.pyplot as plt
def forward_kinematics(theta1, theta2, L1, L2):
"""Calcul des coordonnées de l'organe terminal"""
x1 = L1 * np.cos(theta1)
y1 = L1 * np.sin(theta1)
x2 = x1 + L2 * np.cos(theta1 + theta2)
y2 = y1 + L2 * np.sin(theta1 + theta2)
return x1, y1, x2, y2
# Paramètres du bras
L1 = 0.5 # m
L2 = 0.4 # m
# Trajectoire articulaire
t = np.linspace(0, 10, 1000)
theta1 = np.pi/4 + 0.2 * np.sin(0.5 * t) # Mouvement sinusoidal
theta2 = np.pi/6 + 0.1 * np.cos(0.3 * t)
# Calcul des positions
x1, y1, x2, y2 = forward_kinematics(theta1, theta2, L1, L2)
# Tracé de la trajectoire
fig, ax = plt.subplots(figsize=(10, 10))
# Tracé de la trajectoire
ax.plot(x2, y2, 'b-', linewidth=2, label='Trajectoire de l\'organe terminal')
ax.scatter([0], [0], color='red', s=100, zorder=5, label='Base')
# Animation de quelques positions
for i in range(0, len(t), 100):
ax.plot([0, x1[i], x2[i]], [0, y1[i], y2[i]], 'o-', color='green', markersize=6)
ax.set_xlim(-1.2, 1.2)
ax.set_ylim(-0.5, 1.2)
ax.set_aspect('equal')
ax.grid(True, alpha=0.3)
ax.legend()
ax.set_title('Trajectoire du bras robotisé')
ax.set_xlabel('X (m)')
ax.set_ylabel('Y (m)')
plt.tight_layout()
plt.show()
• Espace de travail : Zone accessible par l'organe terminal
• Précision : Dépend des capteurs et actionneurs
• Vitesse maximale : Liée aux couples moteurs
• Singularités : Zones où le bras perd des degrés de liberté
Le bras robotisé à 2 degrés de liberté avec des segments de 0.5m et 0.4m a un espace de travail défini par un cercle annulaire de rayon intérieur 0.1m et extérieur 0.9m, permettant une grande variété de mouvements.
• directe : Relation angles/articulations → position
• Équations de Lagrange : Modèle dynamique du bras
• Espace de travail : Zone accessible par l'organe terminal
Cas d'étude : Panneau photovoltaïque : Système convertissant l'énergie lumineuse en énergie électrique, modélisé par une caractéristique électrique non-linéaire dépendant de l'éclairement et de la température.
Le panneau photovoltaïque est caractérisé par :
• Courant de court-circuit (I_sc) : 8.5 A
• Tension à vide (V_oc) : 22.5 V
• Point de puissance maximale (V_mp, I_mp) : (18.0 V, 8.0 A)
• Température de fonctionnement (T) : 25°C
• Coefficient de température du courant : 0.0004 A/°C
Modèle à une diode :
\(I = I_L - I_0\left(e^{\frac{V + I R_s}{n V_T}} - 1\right) - \frac{V + I R_s}{R_{sh}}\)
Où \(I_L\) est le courant photocourant, \(I_0\) le courant de saturation
Puissance maximale : \(P_{max} = V_{mp} \times I_{mp} = 18.0 \times 8.0 = 144\) W
Rendement : \(\eta = \frac{P_{max}}{P_{incident}} = \frac{144}{1000 \times A}\) où A est la surface
Facteur de forme : \(FF = \frac{V_{mp} \times I_{mp}}{V_{oc} \times I_{sc}} = \frac{18.0 \times 8.0}{22.5 \times 8.5} = 0.756\)
import numpy as np
import matplotlib.pyplot as plt
def pv_characteristic(V, I_sc, V_oc, n, Rs, Rsh):
"""Calcul de la caractéristique I-V d'un panneau PV"""
# Paramètres simplifiés
I0 = 1e-9 # Courant de saturation (A)
VT = 0.0257 # Tension thermique à 300K (V)
# Calcul du courant
I = I_sc - I0 * (np.exp((V + 1e-6*Rs)/(n*VT)) - 1) - (V + 1e-6*Rs)/Rsh
return I
# Paramètres du panneau
I_sc = 8.5 # Courant de court-circuit (A)
V_oc = 22.5 # Tension à vide (V)
n = 1.3 # Facteur d'idéalité
Rs = 0.1 # Résistance série (Ω)
Rsh = 100 # Résistance shunt (Ω)
# Tensions de simulation
V = np.linspace(0, V_oc, 1000)
# Calcul des courants
I = pv_characteristic(V, I_sc, V_oc, n, Rs, Rsh)
# Correction pour une caractéristique plus réaliste
I = np.clip(I, 0, I_sc)
for i in range(1, len(V)):
if I[i] > I[i-1]: # Correction pour la zone descendante
I[i] = I[i-1] - 0.01
# Calcul de la puissance
P = V * I
# Tracé
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))
# Caractéristique I-V
ax1.plot(V, I, linewidth=2, label='Caractéristique I-V')
ax1.axvline(x=V_oc, color='red', linestyle='--', alpha=0.7, label=f'Voc = {V_oc}V')
ax1.axhline(y=I_sc, color='red', linestyle='--', alpha=0.7, label=f'Isc = {I_sc}A')
ax1.set_xlabel('Tension (V)')
ax1.set_ylabel('Courant (A)')
ax1.set_title('Caractéristique I-V du panneau photovoltaïque')
ax1.grid(True, alpha=0.3)
ax1.legend()
# Puissance en fonction de la tension
ax2.plot(V, P, linewidth=2, color='orange', label='Puissance')
ax2.axvline(x=18.0, color='green', linestyle='--', alpha=0.7, label='Pmax à Vmp = 18.0V')
ax2.set_xlabel('Tension (V)')
ax2.set_ylabel('Puissance (W)')
ax2.set_title('Puissance en fonction de la tension')
ax2.grid(True, alpha=0.3)
ax2.legend()
plt.tight_layout()
plt.show()
• Point de puissance maximale : (18.0V, 8.0A)
• Puissance maximale : 144W
• Facteur de forme : 0.756
• Rendement dépendant de l'éclairement et de la température
Le panneau photovoltaïque avec les caractéristiques données atteint une puissance maximale de 144W au point (18.0V, 8.0A), avec un facteur de forme de 0.756, typique des panneaux commerciaux.
• Modèle à une diode : Représentation électrique du PV
• Point de puissance maximale : MPPT
• Facteur de forme : \(FF = \frac{V_{mp} \times I_{mp}}{V_{oc} \times I_{sc}}\)
- Compréhension du problème : Identifier la problématique centrale
- Analyse du système : Observer, comprendre les composants
- Identification des paramètres : Variables d'entrée, sortie, perturbations
- Modélisation : Établir les équations du système
- Simulation : Résoudre les équations, tracer les résultats
- Validation : Comparer avec des mesures ou des ordres de grandeur
- Conclusion : Synthèse des résultats et implications techniques
- Un cas d'étude doit toujours répondre à une problématique clairement formulée
- La modélisation nécessite des hypothèses simplificatrices justifiées
- Les résultats doivent être interprétés dans le contexte du problème initial
- La validation est essentielle pour garantir la pertinence du modèle
- Les limites du modèle doivent être explicitées
- Mécanique : Systèmes vibratoires, transmissions, structures
- Électrique : Circuits, machines électriques, électronique
- Thermique : Transfert de chaleur, systèmes frigorifiques
- Automatique : Systèmes asservis, commande, robotique
- Énergétique : Conversion d'énergie, rendements, bilans
- Le cas d'étude est une méthode structurée pour analyser un système technique
- La modélisation est l'étape centrale pour comprendre le comportement
- La validation garantit la pertinence des résultats obtenus
- Les ordres de grandeur aident à vérifier la cohérence des résultats
- La communication des résultats est aussi importante que leur obtention