Introduction
Le pendule double est un problème classique en physique et en mathématiques. Il implique deux pendules attachés l'un à l'autre, et le mouvement du second pendule est influencé par le mouvement du premier pendule. Dans ce laboratoire, nous allons utiliser Python et Matplotlib pour simuler le mouvement d'un pendule double.
Conseils sur la VM
Une fois le démarrage de la VM terminé, cliquez dans le coin supérieur gauche pour basculer vers l'onglet Notebook pour accéder à Jupyter Notebook pour pratiquer.
Parfois, vous devrez peut-être attendre quelques secondes pour que Jupyter Notebook ait fini de charger. La validation des opérations ne peut pas être automatisée en raison des limites de Jupyter Notebook.
Si vous rencontrez des problèmes pendant l'apprentissage, n'hésitez pas à demander à Labby. Donnez votre feedback après la session, et nous réglerons rapidement le problème pour vous.
Importation des bibliothèques requises
Nous allons commencer par importer les bibliothèques nécessaires à notre simulation.
from collections import deque
import matplotlib.pyplot as plt
import numpy as np
from numpy import cos, sin
import matplotlib.animation as animation
Configuration des paramètres
Ensuite, nous allons définir les paramètres de notre simulation. Ces paramètres incluent l'accélération due à la gravité, la longueur et la masse de chaque pendule, ainsi que l'intervalle de temps pour la simulation.
G = 9.8 ## acceleration due to gravity, in m/s^2
L1 = 1.0 ## length of pendulum 1 in m
L2 = 1.0 ## length of pendulum 2 in m
L = L1 + L2 ## maximal length of the combined pendulum
M1 = 1.0 ## mass of pendulum 1 in kg
M2 = 1.0 ## mass of pendulum 2 in kg
t_stop = 2.5 ## how many seconds to simulate
history_len = 500 ## how many trajectory points to display
Définition de la fonction des dérivées
Nous allons définir une fonction qui calcule les dérivées du système à un instant donné. Cette fonction prend l'état actuel du système (les angles et les vitesses angulaires de chaque pendule) et renvoie les dérivées de ces valeurs.
def derivs(t, state):
dydx = np.zeros_like(state)
dydx[0] = state[1]
delta = state[2] - state[0]
den1 = (M1+M2) * L1 - M2 * L1 * cos(delta) * cos(delta)
dydx[1] = ((M2 * L1 * state[1] * state[1] * sin(delta) * cos(delta)
+ M2 * G * sin(state[2]) * cos(delta)
+ M2 * L2 * state[3] * state[3] * sin(delta)
- (M1+M2) * G * sin(state[0]))
/ den1)
dydx[2] = state[3]
den2 = (L2/L1) * den1
dydx[3] = ((- M2 * L2 * state[3] * state[3] * sin(delta) * cos(delta)
+ (M1+M2) * G * sin(state[0]) * cos(delta)
- (M1+M2) * L1 * state[1] * state[1] * sin(delta)
- (M1+M2) * G * sin(state[2]))
/ den2)
return dydx
Configuration des conditions initiales et intégration de l'EDO
Nous allons maintenant définir les conditions initiales de notre simulation. Nous allons fixer les angles initiaux et les vitesses angulaires de chaque pendule, ainsi que l'intervalle de temps de la simulation. Nous allons ensuite intégrer l'EDO en utilisant la méthode d'Euler pour obtenir la position et la vitesse de chaque pendule à chaque pas de temps.
## create a time array from 0..t_stop sampled at 0.02 second steps
dt = 0.01
t = np.arange(0, t_stop, dt)
## th1 and th2 are the initial angles (degrees)
## w10 and w20 are the initial angular velocities (degrees per second)
th1 = 120.0
w1 = 0.0
th2 = -10.0
w2 = 0.0
## initial state
state = np.radians([th1, w1, th2, w2])
## integrate the ODE using Euler's method
y = np.empty((len(t), 4))
y[0] = state
for i in range(1, len(t)):
y[i] = y[i - 1] + derivs(t[i - 1], y[i - 1]) * dt
Calculer la position de chaque pendule
Nous allons maintenant utiliser la position et la vitesse de chaque pendule à chaque pas de temps pour calculer les coordonnées x et y de chaque pendule.
x1 = L1*sin(y[:, 0])
y1 = -L1*cos(y[:, 0])
x2 = L2*sin(y[:, 2]) + x1
y2 = -L2*cos(y[:, 2]) + y1
Préparer la représentation graphique
Nous allons maintenant préparer la représentation graphique de notre simulation. Nous allons créer une figure avec des limites x et y égales à la longueur maximale du pendule, définir le rapport d'aspect pour être égal et ajouter une grille.
fig = plt.figure(figsize=(5, 4))
ax = fig.add_subplot(autoscale_on=False, xlim=(-L, L), ylim=(-L, 1.))
ax.set_aspect('equal')
ax.grid()
Définir la fonction d'animation
Nous allons définir une fonction qui animera le mouvement du pendule double. Cette fonction prendra le pas de temps actuel et l'utilisera pour mettre à jour la position de chaque pendule. Elle mettra également à jour la trajectoire du second pendule.
line, = ax.plot([], [], 'o-', lw=2)
trace, = ax.plot([], [], '.-', lw=1, ms=2)
time_template = 'time = %.1fs'
time_text = ax.text(0.05, 0.9, '', transform=ax.transAxes)
history_x, history_y = deque(maxlen=history_len), deque(maxlen=history_len)
def animate(i):
thisx = [0, x1[i], x2[i]]
thisy = [0, y1[i], y2[i]]
if i == 0:
history_x.clear()
history_y.clear()
history_x.appendleft(thisx[2])
history_y.appendleft(thisy[2])
line.set_data(thisx, thisy)
trace.set_data(history_x, history_y)
time_text.set_text(time_template % (i*dt))
return line, trace, time_text
Créer l'animation
Nous allons maintenant créer l'animation en utilisant la fonction FuncAnimation de Matplotlib.
ani = animation.FuncAnimation(
fig, animate, len(y), interval=dt*1000, blit=True)
plt.show()
Sommaire
Dans ce laboratoire, nous avons utilisé Python et Matplotlib pour simuler le mouvement d'un pendule double. Nous avons défini les paramètres de notre simulation, défini une fonction pour calculer les dérivées du système, intégré l'EDO en utilisant la méthode d'Euler, calculé la position de chaque pendule à chaque pas de temps et créé une animation du mouvement du pendule double.