DOURNAC.ORG
Français  English
Accueil
Astronomie
Sciences
Philosophie
Informatique
Cv

Informatique > Simulation Pendule Triple Amorti avec RK4 à pas variable - version HTML5 Canvas



  • 1.Introduction
  • 2.Système différentiel via Euler-Lagrange
  • 3.Lagrangien et fonction de dissipation de Rayleigh
  • 4.Equations dynamiques du système
  • 5.Résolution avec Runge-Kutta ordre 4
  • 6.Simulation en canvas HTML5
  • 7.Runge-Kutta 4 à pas variable

1.Introduction :

Cette page décrit une simulation en HTML5 Canvas modélisant le mouvement d'un pendule triple amorti. Nous obtiendrons les équations du mouvement grâce aux équations d'Euler-Lagrange puis implémenterons la méthode numérique RK4 à pas variable (Runge Kutta ordre 4).

2.Système différentiel via Euler-Lagrange :

Le système différentiel est obtenu grâce aux équations d'Euler-Lagrange. En notant $L$ le Lagrangien du système, $q_{i}$ chacune des 3 coordonnées et $\dot{q_{i}}$ leur dérivée par rapport au temps, on peut écrire :

\begin{equation} \dfrac{\text{d}}{\text{d}t}\bigg(\dfrac{\partial\,L}{\partial\,\dot{q_{i}}}\bigg)-\dfrac{\partial\,L}{\partial\,q_{i}}=0 \end{equation} Cette équation est valable lorsque le système est conservatif (le travail des forces non-conservatives est nul). Quand il existe des forces non conservatives dont le travail est non nul, on les qualifie de forces d'amortissement. Il faut rajouter alors au membre de droite la force de frottement $\overrightarrow{F_{f}}=-\overrightarrow{\nabla_{v}}\,D_{r}$ avec $D_{r}$ la fonction de dissipation de Rayleigh. On obtient : \begin{equation} \dfrac{\text{d}}{\text{d}t}\bigg(\dfrac{\partial\,L}{\partial\,\dot{q_{i}}}\bigg)-\dfrac{\partial\,L}{\partial\,q_{i}}=-\dfrac{\partial\,D_{r}}{\partial\,\dot{q_{i}}} \end{equation}

3.Lagrangien et fonction de dissipation de Rayleigh :

Ci-dessous un schéma qui représente l'ensemble des variables du pendule triple :



Figure 1 : Représentation du pendule triple

Tous les calculs ci-dessous sont effectués en supposant que la masse de chaque barre est négligeable devant la masse de chaque sphère.

La définition du Lagrangien est :

\begin{equation} L=\mathcal{E}_{k}-\mathcal{E}_{p} \end{equation}

avec

\begin{equation} \mathcal{E}_{k}=\sum\limits_{i=1}^{3}\dfrac{1}{2}m_{i}v_{i}^{2}\,\,\,\,\,\,\,\,\, \text{et} \,\,\,\,\,\,\,\,\, \mathcal{E}_{p}=\sum\limits_{i=1}^{3}m_{i}gh_{i} \label{eq-kinetic-potential} \end{equation}

avec $v_{i}^{2}=\left\Vert\dfrac{\text{d}\overrightarrow{OM_{i}}}{\text{d}t}\right\Vert^{2}=\dfrac{\text{d}\overrightarrow{OM_{i}}}{\text{d}t}\cdot\dfrac{\text{d}\overrightarrow{OM_{i}}}{\text{d}t}$ et $h_{i}$ qui correspond à la hauteur par rapport au sol de la masse $i$.

Calcul de l'énergie cinétique - Les termes $v_{i}^{2}$ sont égaux à :

\begin{eqnarray} \left\{ \begin{aligned} v_{1}^{2}&=\dfrac{\text{d}\overrightarrow{OM_{1}}}{\text{d}t}\cdot\dfrac{\text{d}\overrightarrow{OM_{1}}}{\text{d}t}=l_{1}^{2}\dot{\theta_{1}}^{2}\\ v_{2}^{2}&=\dfrac{\text{d}\overrightarrow{OM_{2}}}{\text{d}t}\cdot\dfrac{\text{d}\overrightarrow{OM_{2}}}{\text{d}t}=\dfrac{\text{d}(\overrightarrow{OM_{1}}+\overrightarrow{M_{1}M_{2}})}{\text{d}t}\cdot\dfrac{\text{d}(\overrightarrow{OM_{1}}+\overrightarrow{M_{1}M_{2}})}{\text{d}t}\\ &=\dfrac{\text{d}\overrightarrow{OM_{1}}}{\text{d}t}\cdot\dfrac{\text{d}\overrightarrow{OM_{1}}}{\text{d}t}+\dfrac{\text{d}\overrightarrow{M_{1}M_{2}}}{\text{d}t}\cdot\dfrac{\text{d}\overrightarrow{M_{1}M_{2}}}{\text{d}t}+2\dfrac{\text{d}\overrightarrow{OM_{1}}}{\text{d}t}\cdot\dfrac{\text{d}\overrightarrow{M_{1}M_{2}}}{\text{d}t} \\ &=v_{1}^{2}+l_{2}^{2}\dot{\theta_{2}}^{2}+2 l_{1}l_{2}\dot{\theta_{1}}^{2}\dot{\theta_{2}}^{2}\cos(\theta_{1}-\theta_{2})\\ &=l_{1}^{2}\dot{\theta_{1}}^{2}+l_{2}^{2}\dot{\theta_{2}}^{2}+2 l_{1}l_{2}\dot{\theta_{1}}^{2}\dot{\theta_{2}}^{2}\cos(\theta_{1}-\theta_{2})\\ v_{3}^{2}&=\dfrac{\text{d}\overrightarrow{OM_{3}}}{\text{d}t}\cdot\dfrac{\text{d}\overrightarrow{OM_{3}}}{\text{d}t}=\dfrac{\text{d}(\overrightarrow{OM_{2}}+\overrightarrow{M_{2}M_{3}})}{\text{d}t}\cdot\dfrac{\text{d}(\overrightarrow{OM_{2}}+\overrightarrow{M_{2}M_{3}})}{\text{d}t}\\ &=\dfrac{\text{d}\overrightarrow{OM_{2}}}{\text{d}t}\cdot\dfrac{\text{d}\overrightarrow{OM_{2}}}{\text{d}t}+\dfrac{\text{d}\overrightarrow{M_{2}M_{3}}}{\text{d}t}\cdot\dfrac{\text{d}\overrightarrow{M_{2}M_{3}}}{\text{d}t} +2\dfrac{\text{d}\overrightarrow{OM_{2}}}{\text{d}t}\cdot\dfrac{\text{d}\overrightarrow{M_{2}M_{3}}}{\text{d}t}\\ &=v_{2}^{2}+l_{3}^{2}\dot{\theta_{3}}^{2}+2\dfrac{\text{d}(\overrightarrow{OM_{1}}+\overrightarrow{M_{1}M_{2}})}{\text{d}t}\cdot\dfrac{\text{d}\overrightarrow{M_{2}M_{3}}}{\text{d}t}\\ &=v_{2}^{2}+l_{3}^{2}\dot{\theta_{3}}^{2}+2 l_{1}l_{3}\dot{\theta_{1}}\dot{\theta_{3}}\cos(\theta_{1}-\theta_{3}) +2 l_{2}l_{3}\dot{\theta_{2}}\dot{\theta_{3}}\cos(\theta_{2}-\theta_{3})\\ \end{aligned} \right. \label{eq-vi2} \end{eqnarray}

Calcul de l'énergie potentielle :

Le calcul de la hauteur des 3 masses nous conduit à :

\begin{eqnarray} \begin{aligned} \mathcal{E}_{p}&=g(l_{1}+l_{2}+l_{3})(m_{1}+m_{2}+m_{3})-gl_{1}(m_{1}+m_{2}+m_{3})\cos(\theta_{1})\\ &\,\,\,\,-gl_{2}(m_{2}+m_{3})\cos(\theta_{2})-gl_{3}m_{3}\cos(\theta_{3})\\ \end{aligned} \end{eqnarray}

Calcul de la fonction de dissipation de Rayleigh :

Elle s'écrit sous la forme :

\begin{equation} D_{r}=\dfrac{1}{2}\sum\limits_{i=1}^{3}k_{i}v_{i}^{2}\end{equation}

où $k_{i}$ correspond au coefficient d'amortissement selon l'angle $\theta_{i}$ et $v_{i}^{2}$ sont les vitesses calculées en \eqref{eq-vi2}. Le terme de droite dans l'équation d'Euler-Lagrange est alors donné par :

\begin{equation} F_{f,i}=-\dfrac{\partial D_{r}}{\partial \dot{q_{i}}} \end{equation}

4.Equations dynamiques du système :

Le calcul du système d'équations peut se faire à la main mais il est relativement lourd. Une façon plus rapide consiste à utiliser la Symbolic Math Toolbox. Après avoir calculé l'expression symbolique du Lagrangien, on pose le système différentiel de manière automatique grâce au code Matlab suivant : compute_diff_system.m.

Nous décrivons brièvement ce code :

En partant des expressions de \eqref{eq-kinetic-potential} et de $v_{i}^{2}$, avec les variables $t_{i}=\theta_{i}$, $dt_{i}=\dot{\theta_{i}}$, on obtient le Lagrangien suivant :

% Kinetic Energy 
T=1/2*l1*l1*dt1*dt1*(m1+m2+m3)...
  +1/2*l2*l2*dt2*dt2*(m2+m3)...
  +1/2*l3*l3*dt3*dt3*m3...
  +l1*l2*dt1*dt2*cos(t1-t2)*(m2+m3)...
  +l2*l3*dt2*dt3*cos(t2-t3)*m3...
  +l1*l3*dt1*dt3*cos(t1-t3)*m3;

% Potential Energy 
V=g*(l1+l2+l3)*(m1+m2+m3)...
  -g*l1*(m1+m2+m3)*cos(t1)...
  -g*l2*(m2+m3)*cos(t2)...
  -g*l3*m3*cos(t3);

% Lagrangian 
L=T-V;

Ecrivons maintenant l'expression de la fonction de dissipation :

% Rayleigh Dissipation function
Dr=1/2*l1*l1*dt1*dt1*(k1+k2+k3)...
   +1/2*l2*l2*dt2*dt2*(k2+k3)...
   +1/2*l3*l3*dt3*dt3*k3...
   +l1*l2*dt1*dt2*cos(t1-t2)*(k2+k3)...
   +l2*l3*dt2*dt3*cos(t2-t3)*k3...
   +l1*l3*dt1*dt3*cos(t1-t3)*k3;

% Derivative of Rayleigh function
f1=diff(Dr,dt1);
f2=diff(Dr,dt2);
f3=diff(Dr,dt3);

Il faut maintenant établir le système différentiel à résoudre. Ceci se fait de la manière suivante :

% Get Lagrange equations and solve for expressing theta_second
Equations=Lagrange(L,[t1,dt1,ddt1,t2,dt2,ddt2,t3,dt3,ddt3]);
[theta1_second theta2_second theta3_second]=solve(Equations(1)==-f1,...
    Equations(2)==-f2,Equations(3)==-f3,ddt1,ddt2,ddt3);

On obtient finalement les 3 équations dynamiques du système.

Remarque :

Le langage Javascript ne reconnaît pas les exposants avec le caractère '^'. Pour pouvoir par exemple convertir l'expression 'm1^2' sous Matlab dans une syntaxe Javascript valide, c'est-à-dire 'm1*m1', nous pouvons utiliser la commande sed suivante :

sed -i 's/\([^(*+\/^-]*\(([^)]*)\)\?\)\^2/\1\*\1/g' diff_system.txt

Nous avons choisi de ne pas utiliser la fonction 'Math.pow' car elle est pénalisante d'un point de vue optimisation pour des puissances entières.

5.Résolution avec Runge-Kutta ordre 4 :

Cette méthode numérique s'applique dans sa forme initiale aux problèmes de la forme :

\begin{equation} \dfrac{\text{d}y}{\text{d}t}=\Psi(t,y) \label{eq-rk4-basic} \end{equation}

avec les conditions initiales $t_{0}$ et $y_{0}$ connues. La formule itérative est la suivante :

\begin{equation} y_{i+1}=y_{i}+\dfrac{(k_{1}+2k_{2}+2k_{3}+k_{4})}{6} \end{equation} avec \begin{equation} k_{1}=h\Psi(t_{i},y_{i})\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,k_{2}=h\Psi(t_{i}+\dfrac{h}{2},y_{i}+\dfrac{k_{1}}{2})\\ k_{3}=h\Psi(t_{i}+\dfrac{h}{2},y_{i}+\dfrac{k_{2}}{2})\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,k_{4}=h\Psi(t_{i}+h,y_{i}+k_{3})\\ \end{equation}

Pour un système d'équations faisant intervenir des dérivées seconde, on utilise une approche vectorielle; Dans notre cas, on a le système différentiel suivant :

\begin{eqnarray} \left\{ \begin{aligned} x"&=F(x,x',y,y',z,z')\\ y"&=G(x,x',y,y',z,z')\\ z"&=H(x,x',y,y',z,z') \end{aligned} \right. \label{eq-diff-rk4} \end{eqnarray}

En écrivant $u=\dfrac{\text{d}x}{\text{d}t}$, $v=\dfrac{\text{d}y}{\text{d}t}$, $w=\dfrac{\text{d}z}{\text{d}t}$, et en posant le vecteur $\overrightarrow{V}$ :

\begin{equation} \overrightarrow{V}=\begin{bmatrix} x \\ u \\ y \\ v \\ z \\ w\end{bmatrix} \end{equation}

On peut mettre le système différentiel sous une forme vectorielle équivalente à \eqref{eq-rk4-basic} :

\begin{equation} \dfrac{\text{d}\overrightarrow{V}}{\text{d}t}=\overrightarrow{U}(\overrightarrow{V})=\begin{bmatrix} u(x,x',y,y',z,z') \\ F(x,x',y,y',z,z') \\ v(x,x',y,y',z,z') \\ G(x,x',y,y',z,z') \\ w(x,x',y,y',z,z') \\ H(x,x',y,y',z,z')\end{bmatrix} \end{equation} Les coefficients de Runge-Kutta se calculent alors de manière identique : \begin{equation} \overrightarrow{k_{1}}=h\overrightarrow{U}(\overrightarrow{V_{n}})\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\overrightarrow{k_{2}}=h\overrightarrow{U}(\overrightarrow{V_{n}}+\dfrac{\overrightarrow{k_{1}}}{2})\\ \overrightarrow{k_{3}}=h\overrightarrow{U}(\overrightarrow{V_{n}}+\dfrac{\overrightarrow{k_{2}}}{2})\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\overrightarrow{k_{4}}=h\overrightarrow{U}(\overrightarrow{V_{n}}+\overrightarrow{k_{3}})\\ \end{equation}

et la formule de récurrence s'écrit :

\begin{equation} \overrightarrow{V_{n+1}}=\overrightarrow{V_{n}}+\dfrac{\overrightarrow{k_{1}}+2\overrightarrow{k_{2}}+2\overrightarrow{k_{3}}+\overrightarrow{k_{4}}}{6} \end{equation}

6.Simulation en canvas HTML5 :

Voici un canvas permettant de simuler le mouvement d'un pendule triple. La longueur totale des axes est fixée à 3 mètres, la masse initiale de chaque masse prise à 1 kg et la vitesse de départ à $5\,\text{rad.s}^{-1}$. Vous pouvez faire un drag'n drop sur chaque masse du pendule pour leur affecter la position initiale désirée.




Le source du Canvas HTML5 est disponible sur ce lien triple_pendulum.js. On commence par initialiser l'interface graphique puis on définit les fonctions correspondant au système différentiel. La méthode Runge-Kutta ordre 4 à pas variable est alors implémentée pour calculer les prochaines valeurs. Une fois ces valeurs obtenues, nous mettons à jour l'affichage du pendule.

7.Runge-Kutta 4 à pas variable :

Il se peut que selon les choix de la longueur des axes, ou une différence de rapports importante entre les 3 masses du pendule, les angles $\theta_{i}$ soient amener à varier très rapidement. Il faut dans ces cas là choisir un pas de temps plus petit que celui utilisé par défaut dans la simulation ($h=0.005$) afin d'éviter la divergence des valeurs calculées. On utilise alors la méthode RK4 à pas variable aussi appelée RK4 à pas adaptatif. Le principe est d'obtenir un pas de temps qui s'adapte en fonction de la variabilité des valeurs calculées : le pas de temps doit diminuer quand celles-ci changent brutalement et augmenter quand elles varient lentement.

Pour évaluer cette variabilité, on fixe une erreur minimale au delà de laquelle il faut diminuer le pas de temps. Pour cela, on compare les valeurs calculées sur le pas de temps courant $h$ avec les valeurs obtenues sur 2 itérations en prenant $h/2$. Si la différence est supérieure à l'erreur fixée, nous prenons un pas plus petit. Dans le cas contraire, nous l'augmentons.

Voici le résumé de l'algorithme :

 1 function ProcessNext() {
 2 
 3    // Correction for current step
 4    var factor_correction;
 5 
 6    // Compute RK4 coefficients
 7    k[0][0]=h*dt1;
 8    k[0][1]=h*F1(t1, dt1, t2, dt2, t3, dt3, g, l1, l2, l3, ...
 9    ...
10    ...
11    k[3][4]=h*(dt3+k[2][5]);
12    k[3][5]=h*F3(t1+k[2][0], dt1+k[2][1], t2+k[2][2], ...
13    
14    // Save first computed variables
15    t1_1=t1;
16    dt1_1=dt1;
17    ...
18    ...
19    t3_1=t3;
20    dt3_1=dt3;
21    
22    t1_2=t1;
23    dt1_2=dt1;
24    ...
25    ...  
26    t3_2=t3;
27    dt3_2=dt3;
28    
29    // Compute Next positions 
30    t1=t1+(k[0][0]+2*k[1][0]+2*k[2][0]+k[3][0])/6;
31    dt1=dt1+(k[0][1]+2*k[1][1]+2*k[2][1]+k[3][1])/6;
32    ...
33    ...  
34    t3=t3+(k[0][4]+2*k[1][4]+2*k[2][4]+k[3][4])/6;
35    dt3=dt3+(k[0][5]+2*k[1][5]+2*k[2][5]+k[3][5])/6;
36    
37    // 2 Loops for RK4 with h/2
38    for (i=0; i<2; i++) {
39       // Compute RK4 coefficients with h/2
40       k[0][0]=h/2*dt1_1;
41       k[0][1]=h/2*F1(t1_1, dt1_1, t2_1, dt2_1, t3_1, dt3_1, g,  ...
42       ...
43       ...
44       k[3][4]=h/2*(dt3_1+k[2][5]);
45       k[3][5]=h/2*F3(t1_1+k[2][0], dt1_1+k[2][1], t2_1+k[2][2], ...
46       
47       // Compute Next positions 
48       t1_1=t1_1+(k[0][0]+2*k[1][0]+2*k[2][0]+k[3][0])/6;
49       dt1_1=dt1_1+(k[0][1]+2*k[1][1]+2*k[2][1]+k[3][1])/6;
50       ...
51       ...       
52       t3_1=t3_1+(k[0][4]+2*k[1][4]+2*k[2][4]+k[3][4])/6;
53       dt3_1=dt3_1+(k[0][5]+2*k[1][5]+2*k[2][5]+k[3][5])/6;
54    }
55    
56    // Comparison with h and h/2 results
57    max_delta = Math.max(Math.abs(t1-t1_1),Math.abs(t2-t2_1),Math.abs(t3-t3_1));
58    
59    // Factor correction
60    factor_correction=Math.pow(Err/max_delta,0.2);
61    
62    // Set new step
63    h=h*factor_correction;
64    
65    if (max_delta >= Err) {
66      // Restore initial values
67      t1=t1_2;
68      dt1=dt1_2;
69      ...
70      ...        
71      t3=t3_2;
72      dt3=dt3_2;
73      // Recompute with a smaller step (factor_correction < 1)
74      ProcessNext();
75    }
76    else {
77      // Draw Canvas - max_delta less than error (factor_correction > 1)
78      DrawPend(canvas);
79    }
80 }

ps : contribuez comme moi au projet Cosmology@Home dont le but est d'affiner le modèle décrivant le mieux notre Univers.

    Accueil | Astronomie | Sciences | Philosophie | Informatique | Cv    
- dournac.org © 2003 by fab -

Haut de Page