[C] mouvement d'un double pendule

mouvement d'un double pendule [C] - C - Programmation

Marsh Posté le 25-02-2007 à 15:32:26    

Salut à tous,
j'aimerais representer à l'écran (avec SDL) le mouvement d'un double pendule attaché a un plafond par une barre indeformable.Les equations differentielles du mouvement sont là: http://fr.wikipedia.org/wiki/Double_pendule et je pense qu'utiliser la methode d'integration de runge kutta d'ordre 4 permettrai d'avoir quelquechose de stable. Mais j'arrive pas a traduire cette methode en code. Si vous pouviez m'expliquer clairement le principe ce serait cool (même si ce n'est que pour un pendule simple). J'ai à peine 6 mois de C derriere moi.
Merci

Reply

Marsh Posté le 25-02-2007 à 15:32:26   

Reply

Marsh Posté le 25-02-2007 à 16:33:42    

http://www.cpt.univ-mrs.fr/~grapperon/oldpdf/mip.pdf


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 25-02-2007 à 18:22:48    

Pour utiliser ta méthode de Runge Kutta, il faut dans un premier temps que tu te ramènes à sa situation d'application, c'est à dire dx/dt=f(x)
f est ici très fortement non linéaire, sinon ce ne serait pas drôle.
Tu te prends un double x[4];
x[0]=theta1
x[1]=theta2
x[2]=dtheta1/dt
x[3]=dtheta2/dt
 
à t=0, tu sais le remplir, ce sont tes conditions initiales.
 
Tu te prends un double y[4], c'est ton dx/dt.
y[0]=dtheta1/dt
y[1]=dtheta2/dt
y[2]=d2theta1/dt2
y[3]=d2theta2/dt2
 
Pour y[0] et y[1], pas trop difficile, y[0]=x[2] et y[1]=x[3]. (pas certain qu'on s'en serve...)
Pour y[2] et y[3], tu mets tes équations de mouvement en fonction de x[0], x[1], etc...
 
Ca, c'était pour t=0. Tu te choisis un pas de calcul h ad hoc. S'il est trop grand, le calcul part dans le décors.
Tu te prends un double k[4] et tu calcules les k1,k2,k3,k4 de la méthode de Runge Kutta. http://en.wikipedia.org/wiki/Runge-Kutta. Ici les équations de mouvement ne dépendent pas du temps, donc sur la page wiki f(t,y) tu zappes et c'est f(y). Avec ça, tu obtiens tes nouvelles positions et vitesses à t0+h, que tu réinjectes dans x[] et tu boucles.


Message édité par GrosBocdel le 25-02-2007 à 18:25:51
Reply

Marsh Posté le 25-02-2007 à 23:21:45    

merci de vos réponses.
Donc d'après ce que j'ai compris, il faut que je ramene d'abord mes equa diff a une forme:    d²théta1/dt²=f(théta2,théta2) et d²théta2/dt²=f(théta2,théta1)      
je vais ensuite me servir de cette fonction f pour calculer mes k1,k2...  
Je vais obtenir mes nouveaux thétas, mais est ce que ma vitesse sera la dérivée de mon théta? En plus j'ai du cos et sin dans mes equa diff, il existe pas des bibliotheques qui ont deja ces fonctions?
Je crois avoir compris le principe pour une equa diff du 1e degré à une seule inconnue mais la avec ces deux equa diff du second degré liée c'est plus dur.

Message cité 1 fois
Message édité par pedigus1 le 25-02-2007 à 23:23:21
Reply

Marsh Posté le 26-02-2007 à 15:38:43    

Pour y[2] et y[3], je dois mettre mes équations de mouvement en fonction de x[0], x[1], etc... c'est la que je bloque.Est-ce que je dois isoler dans chaque equation mon terme qui est dérivé 2 fois? Et comment est ce que je peut calculer mes K1,K2,K3,K4 de runge kutta avec deux equa diff en même temps?

Reply

Marsh Posté le 26-02-2007 à 17:36:12    

pedigus1 a écrit :


Je vais obtenir mes nouveaux thétas, mais est ce que ma vitesse sera la dérivée de mon théta? En plus j'ai du cos et sin dans mes equa diff, il existe pas des bibliotheques qui ont deja ces fonctions?


 
Oui et non. Ce qu'on veut ici c'est intégrer les équations du mouvement, pour ça, on prend un pas de calcul h, et on suppose un truc du style :
d2theta/dt2 * h = dtheta/dt
donc v(t+h)=v(t)+a(t)*h. Les k1, k2 etc calculent juste une pente.
sin et cos sont dans math.h.  L'intérêt de cette méthode c'est de ne pas avoir à linéariser les sinus, en ayant une solution exacte (même si elle n'est pas analytique)
 

pedigus1 a écrit :


Pour y[2] et y[3], je dois mettre mes équations de mouvement en fonction de x[0], x[1], etc... c'est la que je bloque.Est-ce que je dois isoler dans chaque equation mon terme qui est dérivé 2 fois?


Oui, tu mets tes theta'' à gauche, le reste à droite. Faut juste recopier les équations que tu as, en remplaçant theta1' par x[2], theta2' par x[3], etc...
 

pedigus1 a écrit :


 Et comment est ce que je peut calculer mes K1,K2,K3,K4 de runge kutta avec deux equa diff en même temps?


Arrivé à ce stade du calcul, tu n'as plus 2 équa diff du second ordre, mais une seule du premier ordre, dx/dt=f(x), avec x qui est un vecteur à 4 valeurs. Tu as dû voir dans tes cours un truc qui s'appelle l'espace des phases.
Je me suis mal exprimé sur cette partie : Les K1, K2, K3, K4 sont chacun des double[4]. K1 te donne une estimation de la variation de chacun de tes paramètres, K2 une autre un peu plus loin, etc... La somme pondérée de chacun des K te donne une estimation plus précise de la variation de chacun des paras.
Sinon, tu peux faire une recherche anglophone sur le pendule double, il y a un code en c qui traine. Comme ce que tu fais a l'air d'un exo, je ne te le donne pas  ;)  

Reply

Marsh Posté le 26-02-2007 à 20:29:31    

Déjà merci de m'aider c'est très sympa
En fait c'est pour un projet info pour mon école.J'ai trouvé le code in english mais bon je comprend pas tout et j'ai pas vraiment envi de recopier.
Voici ce que j'ai commencé à coder:  

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. int main()
  5. {
  6. double x[4],y[4],K1[4],K2[4],K3[4],K4[4];
  7. int m1,m2,l1,l2;  /*m1 et m2 masses des pendules, l1 et l2 longeurs des fils*/
  8. float h,g=9.81;            /*le pas et la constante de gravitation universelle*/
  9. /* à t=0 */
  10. y[0]=x[2];
  11. y[1]=x[3];
  12. y[2]=(1/((m1+m2)l1))*(-m2*l2*y[3]*cos(x[0]-x[1])-m2*l2*x[3]*x[3]*sin(x[0]-x[1])-(m1+m2)*g*sin(x[0]));
  13. y[3]=(1/l2)(-l1*y[2]*cos(x[0]-x[1])+l1*x[2]*sin(x[0]-x[1])-g*sin(x[1]));
  14. /*Runge-kutta*/
  15. K1[0]=y[0];
  16. K1[1]=y[1];
  17. K1[2]=Y[2];
  18. K1[3]=y[3];
  19. K2[0]=y[0]+(h/2)*K1[0];
  20. K2[1]=y[1]+(h/2)*K1[1];
  21. K2[2]=y[2]+(h/2)*K1[2];
  22. K2[3]=y[3]+(h/2)*K1[3];


 
En fait mon equa serait devenue y=f(x) (avec y et x mes doubles)
Mais est-ce normal que je me retrouve avec du y[3] dans mon y[2]? et j'arrive pas bien à identifier mon f pour le y[2] et y[3].De même pour le calcul des K2 sa devrait être f(y[]+(h/2)K1[]) ,pareil, quel est mon f?

Message cité 1 fois
Message édité par pedigus1 le 28-02-2007 à 21:37:41
Reply

Marsh Posté le 26-02-2007 à 22:47:08    

pedigus1 a écrit :


 y[0]=x[2];
 y[1]=x[3];
 y[2]=(1/((m1+m2)l1))*(-m2*l2*y[3]*cos(x[0]-x[1])-m2*l2*x[3]*x[3]*sin(x[0]-x[1])-(m1+m2)*g*sin(x[0]));
 y[3]=(1/l2)(-l1*y[2]*cos(x[0]-x[1])+l1*x[2]*sin(x[0]-x[1])-g*sin(x[1]));
 


Faut penser à initialiser x avant et à ne pas oublier les * des multiplications.
 

pedigus1 a écrit :


Mais est-ce normal que je me retrouve avec du y[3] dans mon y[2]? et j'arrive pas bien à identifier mon f pour le y[2] et y[3].De même pour le calcul des K2 sa devrait être f(y[]+(h/2)K1[]) ,pareil, quel est mon f?


Non, ce n'est pas normal. Il y a encore un peu de travail à effectuer sur les équations 1 et 2 de la page wikipedia. Deux équations, deux inconnues (theta1'' et theta2'') à isoler. Sinon la fonction f est la même partout dans le programme. C'est celle qui transforme ton x[] en ton y[]. Alors autant la coder séparément.


Message édité par GrosBocdel le 26-02-2007 à 22:51:10
Reply

Marsh Posté le 27-02-2007 à 14:10:40    

J'ai corriger les * des multiplications et les x je verrais sa plus tard.  
En fait il faut que j'arrive a ramener mon système de deux équations a 2 inconnues liées à un système de 4 equations du 1e ordre.c'est sa? Et pour la fonction f, je n'en aurais pas quatres differentes? (une pour y[0] une autre pour y[1] etc..).
Et sinon pour le travail a effectuer sur les equations 1 et 2 de wikipedia, est-ce que je dois remplacer mes y[2] de l'equation y[3] par le y[2] trouvé juste avant?
Merci de ton aide , je suis assez perdu là-dessus.

Reply

Marsh Posté le 27-02-2007 à 20:10:29    

Les équations de wikipedia, dans un premier temps, il faut juste les mettre en forme. Elles n'ont juste pas la tête qu'il faut. La résolution des équa diff, c'est bien Runge Kutta qui s'en occupe.
 
aX+bY=c
dX+eY=d
Je pense que tu sais tirer X et Y d'un système d'équations comme ça. Là c'est pareil, sauf qu'il faut le faire avec theta1'' et theta2''. Juste pour mettre en forme comme il faut.
Une fois que tu as les expressions de theta1'' (sans theta2'' dedans mais avec tout ce que tu veux de theta1' theta2', theta1,theta2) et theta2''(sans theta1'' dedans) c'est tout c'est fini!  Tu remplis y[2] et y[3] avec ça, comme tu avais commencé.
Oui, si tu veux, tu as 4 f différentes. Tu veux voir ça comme ça. T'étais bien parti, ton prog a la bonne forme. Tes y[0] et y[1] sont bons, tu as juste à changer y[2] et y[3].

Reply

Marsh Posté le 27-02-2007 à 20:10:29   

Reply

Marsh Posté le 27-02-2007 à 20:20:40    

Voila l'ébauche du code:

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. int main()
  5. {
  6. double x[4],y[4],x1[4],y1[4];
  7. double K1[4],K2[4],K3[4],K4[4];
  8. int m1,m2,l1,l2; 
  9. float h,g=9.81;
  10. /* à t=0 */
  11. y[0]=x[2];
  12. y[1]=x[3];
  13. y[2]=-(1/((m1+m2*sin(x[0]-x[1])*sin(x[0]-x[1]))*l1))*(m2*(-l1*x[2]*sin(x[0]-x[1])+g*sin(x[1]))*cos(x[0]-x[1])+m2*l2*x[3]*x[3]*sin(x[0]-x[1])+(m1+m2)*g*sin(x[0]));
  14. y[3]=-(1/l2)*(l1*(-(1/((m1+m2*sin(x[0]-x[1])*sin(x[0]-x[1]))*l1))*(m2*(-l1*x[2]*sin(x[0]-x[1])+g*sin(x[1]))*cos(x[0]-x[1])+m2*l2*x[3]*x[3]*sin(x[0]-x[1])+(m1+m2)*g*sin(x[0])))*cos(x[0]-x[1])-l1*x[2]*sin(x[0]-x[1])+g*sin(x[1]));
  15. /*Runge-kutta*/
  16.     /*pour eq0*/
  17. K1[0]=fonction0(x[0]);
  18. K2[0]=fonction0(x[0]+(h/2)*K1[0]);
  19. K3[0]=fonction0(x[0]+(h/2)*K2[0]);
  20. K4[0]=fonction0(x[0]+h*K2[0]);
  21. x1[0]=x[0]+(h/6)(K1[0]+2*K2[0]+2*K3[0]+K4[0]);
  22.  
  23.    /*pour eq1*/
  24. K1[1]=fonction1(x[1]);
  25. K2[1]=fonction1(x[1]+(h/2)*K1[1]);
  26. K3[1]=fonction1(x[1]+(h/2)*K2[1]);
  27. K4[1]=fonction1(x[1]+h*K2[1]);
  28. x1[1]=x[1]+(h/6)(K1[1]+2*K2[1]+2*K3[1]+K4[1]);
  29.    /*pour eq2*/
  30. K1[2]=fonctionf(x[2]);
  31. K2[2]=fonctionf(x[2]+(h/2)*K1[2]);
  32. K3[2]=fonctionf(x[2]+(h/2)*K2[2]);
  33. K4[2]=fonctionf(x[2]+h*K2[2]);
  34. x1[2]=x[2]+(h/6)(K1[2]+2*K2[2]+2*K3[2]+K4[2]);
  35.    /*pour eq3*/     
  36. K1[3]=fonctiong(x[3]);
  37. K2[3]=fonctiong(x[3]+(h/2)*K1[3]);
  38. K3[3]=fonctiong(x[3]+(h/2)*K2[3]);
  39. K4[3]=fonctiong(x[3]+h*K2[3]);
  40. x1[3]=x[3]+(h/6)(K1[3]+2*K2[3]+2*K3[3]+K4[3]);
  41.  
  42.    /*injection des nouvelles valeurs dans les anciennes*/
  43. x[0]=x1[0];
  44. x[1]=x1[1];
  45. x[2]=x1[2];
  46. x[3]=x1[3];


 
 
Avec ces fonctions (qui d'ailleur devraient me permettre de supprimer mon paragraphe de /*à t=0*/ non?):

Code :
  1. double fonction0(double t[0])
  2. {
  3. double f[0];
  4. f[0]=t[0];
  5. return f[0];
  6. }
  7. double fonction1(double s[1])
  8. {
  9. double j[1];
  10. j[1]=s[1];
  11. return j[1];
  12. }
  13. double fonctionf(double v[2])
  14. {
  15. double F[2];
  16. F[2]=-(1/((m1+m2*sin(x[0]-x[1])*sin(x[0]-x[1]))*l1))*(m2*(-l1*v[2]*sin(x[0]-x[1])+g*sin(x[1]))*cos(x[0]-x[1])+m2*l2*x[3]*x[3]*sin(x[0]-x[1])+(m1+m2)*g*sin(x[0]));
  17. return F[2];
  18. }
  19. double fonctiong(double w[3])
  20. {
  21. double G[3];
  22. G[3]=-(1/l2)*(l1*(-(1/((m1+m2*sin(x[0]-x[1])*sin(x[0]-x[1]))*l1))*(m2*(-l1*x[2]*sin(x[0]-x[1])+g*sin(x[1]))*cos(x[0]-x[1])+m2*l2*w[3]*w[3]*sin(x[0]-x[1])+(m1+m2)*g*sin(x[0])))*cos(x[0]-x[1])-l1*x[2]*sin(x[0]-x[1])+g*sin(x[1]));
  23. return G[3];
  24. }


Message édité par pedigus1 le 28-02-2007 à 21:37:17
Reply

Marsh Posté le 27-02-2007 à 20:43:15    

Bon c'est pas super optimisé, mais si tu ne t'es pas gouré dans les équations (trouves en des toutes faites sur le net, là les tiennes sont simplifiables), si tu mets tout ça dans une boucle for et que tu initialises tes x avant, ça doit pouvoir te sortir des résultats. Peut-être.
Oui tu peux virer ton paragraphe à t=0


Message édité par GrosBocdel le 27-02-2007 à 20:56:00
Reply

Marsh Posté le 27-02-2007 à 21:31:52    

Comment est-ce que je pourrais optimiser plus?Et est-ce que mes fonctions sont correctes?J'ai mis des tableux en argument, je devrai pas rajouter une étoile devant?est est-ce que je ne pourrais pas remplacer ces tableux par juste des doubles?
Sinon j'ai chercher sur le net,et je n'ai pas trouver q'autres equations.
Merci de ton aide

Reply

Marsh Posté le 28-02-2007 à 06:58:18    

pedigus1 a écrit :

Comment est-ce que je pourrais optimiser plus?Et est-ce que mes fonctions sont correctes?J'ai mis des tableux en argument, je devrai pas rajouter une étoile devant?est est-ce que je ne pourrais pas remplacer ces tableux par juste des doubles?
Sinon j'ai chercher sur le net,et je n'ai pas trouver q'autres equations.
Merci de ton aide


 
Bon, j'ai parlé trop vite. Des fois avec des trucs comme ça, sur un heureux hasard, ça peut marcher mais là, non.
Dans un premier temps, ouvre vite un bouquin de c. Là tu n'y coupes pas.
Après, je t'ai dis qu'une fonction f, il n'y en a qu'une. Donc à toi de coder une void f(double x[], double y[]), qui te prend ton x et te calcule y.
Mais là, il faut que tu ouvres un bouquin de c. C'est obligatoire.
 
Pour te donner une idée : actuellement, ta fonction0 prend un double en paramètre, ta fonction1 en prend deux, fonctionf en prend trois, fonctiong en prend quatre ! Et aucune ne peut savoir qui est x avec lequel elles travaillent.
Donc un bouquin de c et après on en rediscute si tu rebloques sur des trucs pas expliqués dans le bouquin.
Sinon c'est un début, hein, pas de problème.


Message édité par GrosBocdel le 28-02-2007 à 07:08:11
Reply

Marsh Posté le 28-02-2007 à 14:08:07    

Je n'ai pas beaucoup de C derriere moi mais j'y travaille.
Mais je ne vois pas comment je pourrais avoir qu'une seule fonction f , j'ai en tout quatre equa diff qui sont differentes et il faut que j'applique runge-kutta a chacune d'elles.Pour moi sa fait quatre fonctions.
J'ai changé mes paramètres de fonctions pour des doubles simples (et non plus des tableaux comme j'avais mis). Est- ce que sa merde juste pour les fonctions? ou y a t il de grosses erreurs ailleurs?

Message cité 2 fois
Message édité par pedigus1 le 28-02-2007 à 14:11:25
Reply

Marsh Posté le 28-02-2007 à 18:14:24    

Bon j'ai trvaillé sur le code (avec l'aide du site du zero) et je suis arrivé à un truc qui marche(compile et execute sans problèmes). Mais comment est-ce que je pourrais verifier mes resultats? j'imprime mes théta dans un fchier txt.
Voila le code:
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include "entete.h"
  5. #include <SDL/SDL.h>
  6. double x[4];
  7. int m1,m2,l1,l2;
  8. int main(int argc, char *argv[])
  9. {
  10. double y[4],x1[4],y1[4];
  11. double K1[4],K2[4],K3[4],K4[4]; 
  12. float h;
  13. FILE *fi;
  14. int duree,tpsfin=0,tpsactuel=0;
  15. /*conditions intiales*/
  16. x[0]=10;
  17. x[1]=20;
  18. x[2]=30;
  19. x[3]=10;
  20. y[0]=10;
  21. y[1]=20;
  22. y[2]=30;
  23. y[3]=10;
  24. duree=100;
  25. m1=20;
  26. m2=10;
  27. l1=3;
  28. l2=6;
  29. h=0.05;
  30. fi=fopen("donnee.txt","w" );
  31. tpsfin = SDL_GetTicks()+duree;
  32. while(tpsactuel<tpsfin)
  33. {
  34. /*Runge-kutta*/
  35. fprintf(fi,"%f %f\n",x[0],x[1]);
  36.    /*pour eq0*/     
  37. K1[0]=fonction0(x[0]);
  38. K2[0]=fonction0(x[0]+(h/2)*K1[0]);
  39. K3[0]=fonction0(x[0]+(h/2)*K2[0]);
  40. K4[0]=fonction0(x[0]+h*K2[0]);
  41. x1[0]=x[0]+(h/6)*(K1[0]+2*K2[0]+2*K3[0]+K4[0]);
  42.  
  43.   /*pour eq0*/     
  44. K1[1]=fonction1(x[1]);
  45. K2[1]=fonction1(x[1]+(h/2)*K1[1]);
  46. K3[1]=fonction1(x[1]+(h/2)*K2[1]);
  47. K4[1]=fonction1(x[1]+h*K2[1]);
  48. x1[1]=x[1]+(h/6)*(K1[1]+2*K2[1]+2*K3[1]+K4[1]);
  49.    /*pour eq2*/     
  50. K1[2]=fonctionf(x[2]);
  51. K2[2]=fonctionf(x[2]+(h/2)*K1[2]);
  52. K3[2]=fonctionf(x[2]+(h/2)*K2[2]);
  53. K4[2]=fonctionf(x[2]+h*K2[2]);
  54. x1[2]=x[2]+(h/6)*(K1[2]+2*K2[2]+2*K3[2]+K4[2]);
  55.    /*pour eq3*/     
  56. K1[3]=fonctiong(x[3]);
  57. K2[3]=fonctiong(x[3]+(h/2)*K1[3]);
  58. K3[3]=fonctiong(x[3]+(h/2)*K2[3]);
  59. K4[3]=fonctiong(x[3]+h*K2[3]);
  60. x1[3]=x[3]+(h/6)*(K1[3]+2*K2[3]+2*K3[3]+K4[3]);
  61.  
  62.    /*injection des nouvelles valeurs dans les anciennes*/
  63. x[0]=x1[0];
  64. x[1]=x1[1];
  65. x[2]=x1[2];
  66. x[3]=x1[3];
  67. tpsactuel=SDL_GetTicks();
  68. }
  69. system("PAUSE" ); 
  70. return 0;
  71. }


 
Avec le fichier des fonctions:

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. double x[4];
  5. int m1,m2,l1,l2;
  6. float g=9.81;
  7. double fonction0(double t)
  8. {
  9. double f;
  10. f=t;
  11. return f;
  12. }
  13. double fonction1(double s)
  14. {
  15. double j;
  16. j=s;
  17. return j;
  18. }
  19. double fonctionf(double v)
  20. {
  21. double F;
  22. F=-(1/((m1+m2*sin(x[0]-x[1])*sin(x[0]-x[1]))*l1))*(m2*(-l1*v*sin(x[0]-x[1])+g*sin(x[1]))*cos(x[0]-x[1])+m2*l2*x[3]*x[3]*sin(x[0]-x[1])+(m1+m2)*g*sin(x[0]));
  23. return F;
  24. }
  25. double fonctiong(double w)
  26. {
  27. double G;
  28. G=-(1/l2)*(l1*(-(1/((m1+m2*sin(x[0]-x[1])*sin(x[0]-x[1]))*l1))*(m2*(-l1*x[2]*sin(x[0]-x[1])+g*sin(x[1]))*cos(x[0]-x[1])+m2*l2*w*w*sin(x[0]-x[1])+(m1+m2)*g*sin(x[0])))*cos(x[0]-x[1])-l1*x[2]*sin(x[0]-x[1])+g*sin(x[1]));
  29. return G;
  30. }


 
En tous cas, merci beaucoup pour ton aide !!!

Reply

Marsh Posté le 28-02-2007 à 18:24:46    

pedigus1 a écrit :

Je n'ai pas beaucoup de C derriere moi mais j'y travaille.
Mais je ne vois pas comment je pourrais avoir qu'une seule fonction f , j'ai en tout quatre equa diff qui sont differentes et il faut que j'applique runge-kutta a chacune d'elles.Pour moi sa fait quatre fonctions.
J'ai changé mes paramètres de fonctions pour des doubles simples (et non plus des tableaux comme j'avais mis). Est- ce que sa merde juste pour les fonctions? ou y a t il de grosses erreurs ailleurs?


 
Tu définis juste ta fonction  

Code :
  1. void f(double x[], double y[])
  2. {
  3. y[0]=x[2];
  4. y[1]=x[3];
  5. y[2]=-(1/((m1+m2*sin(x[0]-x[1])*sin(x[0]-x[1]))*l1))*(m2*(-l1*x[2]*sin(x[0]-x[1])+g*sin(x[1]))*cos(x[0]-x[1])+m2*l2*x[3]*x[3]*sin(x[0]-x[1])+(m1+m2)*g*sin(x[0]));
  6. y[3]=-(1/l2)*(l1*(-(1/((m1+m2*sin(x[0]-x[1])*sin(x[0]-x[1]))*l1))*(m2*(-l1*x[2]*sin(x[0]-x[1])+g*sin(x[1]))*cos(x[0]-x[1])+m2*l2*x[3]*x[3]*sin(x[0]-x[1])+(m1+m2)*g*sin(x[0])))*cos(x[0]-x[1])-l1*x[2]*sin(x[0]-x[1])+g*sin(x[1]));
  7. }


 
Ca ne fait bien qu'une fonction. Le faire de cette manière va t'obliger à réécrire ton prog un peu différemment. Note que je ne vérifie pas la liste des sinus et cos qu'il y a dans tes expressions. Il y a peut-être une erreur, je ne sais pas.

Reply

Marsh Posté le 28-02-2007 à 18:28:25    

mon dieu que cest compliqué !
tout ca pour trouver deux angles x[0] et x[1]!???

Reply

Marsh Posté le 28-02-2007 à 18:30:01    

Effectivement c'est plus pratique, mais j'avais mal interpreté ce que tu voulais dire par fonction. Je pensais que tu parlais des fonctions mathematiques ( par exemple d²théta1/dt²=f(théta1,etc..)   et théta2/dt²=g(théta2,etc..) et f et g étaient differentes).
Mais je pense qu'il y quelquechose dans la méthode de runge kutta que je n'avais pas compris (je me fait aussi aider sur un forum de maths http://les-mathematiques.u-strasbg [...] ?15,357592 ).Donc je vais devoir changer pas mal de choses ce soir.


Message édité par pedigus1 le 28-02-2007 à 18:39:20
Reply

Marsh Posté le 28-02-2007 à 18:38:13    

red faction a écrit :

mon dieu que cest compliqué !
tout ca pour trouver deux angles x[0] et x[1]!???


 
Tu as mieux à proposer? parce que c'est quand même un grand moment de solitude pour moi depuis le début, là !  :)

Reply

Marsh Posté le 28-02-2007 à 18:40:49    

GrosBocdel a écrit :

Tu as mieux à proposer? parce que c'est quand même un grand moment de solitude pour moi depuis le début, là !  :)


 
Je suis d'accord (mais je m'en plains pas :) )

Reply

Marsh Posté le 28-02-2007 à 18:50:21    

Non je n'ai rien de mieux , je pensait juste que cetait bcp plus simple a realiser
 
Je ne sais pas si tu doit faire ca pour lecole ou autre, mais peut etre que tu pourrait obtenir des resultats semblables avec un 3 particules (dont une fixe) connectées par des strings (tres tendues et avec un pas tres fin)
 
mais au final ca doit surement consommer plus de cpu , et donner quelque chose de moins precis que tes equations...

Reply

Marsh Posté le 28-02-2007 à 20:02:37    

pedigus1 a écrit :

ou y a t il de grosses erreurs ailleurs?


pour l'instant ça calcule n'importe quoi, en tout cas.

Reply

Marsh Posté le 28-02-2007 à 21:48:10    

GrosBocdel a écrit :

pour l'instant ça calcule n'importe quoi, en tout cas.


Comment le sais-tu ? Tu as visualisé les résultats ? Le mouvement du pendule est aléatoire, donc en lisant une suite de chiffres, je doute que tu puisses en conclure quoi que ce soit. A part visualiser l'animation, je ne vois pas trop comment on peut vérifier les résultats. Enfin si des points successifs sont disposés un peu partout quelque soit la taille de h, alors oui, c'est n'importe quoi. Il faut au moins qu'ils décrivent une trajectoire, mais après, pour vérifier cette trajectoire, sans visualisation, je ne vois pas trop. Peut-être qu'il y a moyen de vérifier si certains invariants sont conservés.

Message cité 2 fois
Message édité par el muchacho le 01-03-2007 à 06:08:09
Reply

Marsh Posté le 28-02-2007 à 22:48:22    

GrosBocdel a écrit :


Code :
  1. void f(double x[], double y[])
  2. {
  3. y[0]=x[2];
  4. y[1]=x[3];
  5. y[2]=-(1/((m1+m2*sin(x[0]-x[1])*sin(x[0]-x[1]))*l1))*(m2*(-l1*x[2]*sin(x[0]-x[1])+g*sin(x[1]))*cos(x[0]-x[1])+m2*l2*x[3]*x[3]*sin(x[0]-x[1])+(m1+m2)*g*sin(x[0]));
  6. y[3]=-(1/l2)*(l1*(-(1/((m1+m2*sin(x[0]-x[1])*sin(x[0]-x[1]))*l1))*(m2*(-l1*x[2]*sin(x[0]-x[1])+g*sin(x[1]))*cos(x[0]-x[1])+m2*l2*x[3]*x[3]*sin(x[0]-x[1])+(m1+m2)*g*sin(x[0])))*cos(x[0]-x[1])-l1*x[2]*sin(x[0]-x[1])+g*sin(x[1]));
  7. }


 


 Je cherche depuis un moment mais je n'arrive pas à utiliser cette fonction.Je pense que sa pourrait beaucoup simplifier le code.
Je pense commencer par là: .
K1[0]=f(x[0],y[0]);
mais je vois pas la suite...

Reply

Marsh Posté le 28-02-2007 à 23:25:00    

J'ai quand même retapé le code (sans utilisé cette fonction).Je pense que cette fois c'est la bonne méthode (enfin j'espere).Sa donne des resultats plus plausibles,à part pour ceux de x[1] qui me semblent bizarre.Mais est-ce que tu pourrais m'expliquer comment implementer la fonction dans mon code.Je poste le nouveau code:

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include "entetes.h"
  5. #include <SDL/SDL.h>
  6. double x[4];
  7. int m1,m2,l1,l2;
  8. int main(int argc, char *argv[])
  9. {
  10. double y[4],x1[4],y1[4];
  11. double K[4],L[4],M[4],N[4]; 
  12. float h;
  13. FILE *fi;
  14. int duree,tpsfin=0,tpsactuel=0;
  15. /*conditions intiales*/
  16. x[0]=10;
  17. x[1]=20;
  18. x[2]=30;
  19. x[3]=10;
  20. y[0]=10;
  21. y[1]=20;
  22. y[2]=30;
  23. y[3]=10;
  24. duree=100;
  25. m1=20;
  26. m2=10;
  27. l1=3;
  28. l2=6;
  29. h=0.05;
  30. fi=fopen("donnee.txt","w" );
  31. tpsfin = SDL_GetTicks()+duree;
  32. while(tpsactuel<tpsfin)
  33. {
  34. /*Runge-kutta*/
  35. fprintf(fi,"%f %f\n",x[0],x[1]);
  36.  
  37.   K[0]=fonctionf(x[0],x[1],x[2],x[3]);
  38.   L[0]=fonctiong(x[0],x[1],x[2],x[3]);
  39.   M[0]=fonctionm(x[2]);
  40.   N[0]=fonctionn(x[3]);
  41.  
  42.   K[1]=fonctionf(x[0]+(h/2)*M[0],x[1]+(h/2)*N[0],x[2]+(h/2)*K[0],x[3]+(h/2)*L[0]);
  43.   L[1]=fonctiong(x[0]+(h/2)*M[0],x[1]+(h/2)*N[0],x[2]+(h/2)*K[0],x[3]+(h/2)*L[0]);
  44.   M[1]=fonctionm(x[2]+(h/2)*K[0]);
  45.   N[1]=fonctionn(x[3]+(h/2)*L[0]);
  46.  
  47.   K[2]=fonctionf(x[0]+(h/2)*M[1],x[1]+(h/2)*N[1],x[2]+(h/2)*K[1],x[3]+(h/2)*L[1]);
  48.   L[2]=fonctiong(x[0]+(h/2)*M[1],x[1]+(h/2)*N[1],x[2]+(h/2)*K[1],x[3]+(h/2)*L[1]);
  49.   M[2]=fonctionm(x[2]+(h/2)*K[1]);
  50.   N[2]=fonctionn(x[3]+(h/2)*L[1]);
  51.  
  52.   K[3]=fonctionf(x[0]+h*M[2],x[1]+h*N[2],x[2]+h*K[2],x[3]+h*L[2]);
  53.   L[3]=fonctiong(x[0]+h*M[2],x[1]+h*N[2],x[2]+h*K[2],x[3]+h*L[2]);
  54.   M[3]=fonctionm(x[2]+h*K[2]);
  55.   N[3]=fonctionn(x[3]+h*L[2]);
  56.  
  57.   x1[2]=x[2]+(h/6)*(K[0]+2*K[1]+2*K[2]+K[3]);
  58.   x1[3]=x[3]+(h/6)*(L[0]+2*L[1]+2*L[2]+L[3]);
  59.   x1[0]=x[0]+(h/6)*(M[0]+2*M[1]+2*M[2]+M[3]);
  60.   x1[1]=x[1]+(h/6)*(N[0]+2*N[1]+2*N[2]+N[3]);
  61.  
  62.  
  63. /*injection des nouvelles valeurs dans les anciennes*/
  64. x[0]=x1[0];
  65. x[1]=x1[1];
  66. x[2]=x1[2];
  67. x[3]=x1[3];
  68. tpsactuel=SDL_GetTicks();
  69. }
  70. system("PAUSE" ); 
  71. return 0;
  72. }


 
Avec les fonctions:

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. double x[4];
  5. int m1,m2,l1,l2;
  6. float g=9.81;
  7. double fonctionm(double t)
  8. {
  9. double f;
  10. f=t;
  11. return f;
  12. }
  13. double fonctionn(double s)
  14. {
  15. double j;
  16. j=s;
  17. return j;
  18. }
  19. double fonctionf(double a,double b,double c,double d)
  20. {
  21. double F;
  22. F=-(1/((m1+m2*sin(a-b)*sin(a-b))*l1))*(m2*(-l1*c*sin(a-b)+g*sin(b))*cos(a-b)+m2*l2*d*d*sin(a-b)+(m1+m2)*g*sin(a));
  23. return F;
  24. }
  25. double fonctiong(double a,double b ,double c,double d)
  26. {
  27. double G;
  28. G=-(1/l2)*(l1*(-(1/((m1+m2*sin(a-b)*sin(a-b))*l1))*(m2*(-l1*c*sin(a-b)+g*sin(b))*cos(a-b)+m2*l2*d*d*sin(a-b)+(m1+m2)*g*sin(a)))*cos(a-b)-l1*c*sin(a-b)+g*sin(b));
  29. return G;
  30. }


Message édité par pedigus1 le 28-02-2007 à 23:31:27
Reply

Marsh Posté le 01-03-2007 à 06:11:22    

Dans un premier temps, tu peux déjà tester ton intégrateur RK sur un pendule simple, avec plusieurs conditions initiales différentes.
Les équations du mvt sont plus simples.
http://fr.wikipedia.org/wiki/Pendule_pesant
http://www.chimix.com/an4/term4/pendule.htm

 

Tu devrais obtenir des mouvements sur un arc de cercle ou un cercle entier.

 

Ah, et puis découpe le calcul de tes fonctions pour qu'elles tiennent sur plusieurs lignes, histoire de les rendre plus digestes, avec des noms qui ont un sens.
Définis des variables temporaires pour sin(theta1-theta2), cos(theta1-theta2), sin(theta1) et sin(theta2), ça évite les recalculs (enfin je pense que le compilo optimise, mais c'est mieux quand même).

 

Ensuite, si ça marche, tu peux essayer les méthodes avec pas adaptatif ou l'algo de Beeman http://en.wikipedia.org/wiki/Beeman%27s_algorithm
(tiens je ne savais pas que l'intégration de Verlet venait de Loup Verlet, un de mes profs à Orsay).


Message édité par el muchacho le 01-03-2007 à 06:37:52
Reply

Marsh Posté le 01-03-2007 à 06:59:25    

el muchacho a écrit :

Comment le sais-tu ? Tu as visualisé les résultats ? Le mouvement du pendule est aléatoire, donc en lisant une suite de chiffres, je doute que tu puisses en conclure quoi que ce soit. A part visualiser l'animation, je ne vois pas trop comment on peut vérifier les résultats. Enfin si des points successifs sont disposés un peu partout quelque soit la taille de h, alors oui, c'est n'importe quoi. Il faut au moins qu'ils décrivent une trajectoire, mais après, pour vérifier cette trajectoire, sans visualisation, je ne vois pas trop. Peut-être qu'il y a moyen de vérifier si certains invariants sont conservés.


 
Juste que les deux angles ne restent pas entre 0 et 2Pi, et que ça diverge aux temps longs...
Je propose qu'on arrète de faire comme si on n'avait pas déjà ce programme
http://www.physics.usyd.edu.au/~wheat/dpend_html/
 
 

Reply

Marsh Posté le 01-03-2007 à 07:40:01    

el muchacho a écrit :

Comment le sais-tu ? Tu as visualisé les résultats ? Le mouvement du pendule est aléatoire, donc en lisant une suite de chiffres, je doute que tu puisses en conclure quoi que ce soit. A part visualiser l'animation, je ne vois pas trop comment on peut vérifier les résultats. Enfin si des points successifs sont disposés un peu partout quelque soit la taille de h, alors oui, c'est n'importe quoi. Il faut au moins qu'ils décrivent une trajectoire, mais après, pour vérifier cette trajectoire, sans visualisation, je ne vois pas trop. Peut-être qu'il y a moyen de vérifier si certains invariants sont conservés.


 
Dans ce système c'est l'énéergie mécanique qui est conservée (suffi de voir la forme de l'hamiltonien pour s'en convaincre), par contre verifier la conservation d'énergie à partir de points ... Je vois pas trop comment faire ...

Message cité 1 fois
Message édité par esox_ch le 01-03-2007 à 07:40:19

---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 01-03-2007 à 07:43:56    

esox_ch a écrit :

Dans ce système c'est l'énéergie mécanique qui est conservée (suffi de voir la forme de l'hamiltonien pour s'en convaincre), par contre verifier la conservation d'énergie à partir de points ... Je vois pas trop comment faire ...


 
Suffit de vérifier que les deux équa diff restent égales à zéro pendant le calcul

Reply

Marsh Posté le 01-03-2007 à 15:03:47    

Sympa ce site GrosBoc ,mais je n'ai pris que les equations simplifiées.
Pour le fait que sa dépasse 2Pi , je pense que c'est normal parceque je n'ai pas encore converti mes angles en radian.
Sinon j'avais une autre question, pour mes conditions initiales, je dois specifier x[0] et x[1] (les deux théta), mais est-ce que je dois mettre les x[2] et [3] et tous les y[] nuls (car ils sont les dérivées de mes angles de départs qui sont constants)?
J'ai fait par exemple un test avec x[0]=50 et x[1]=40 et tout le reste nul, et je vois que x[0] augmente dès le début.Ce n'est pas normal, le pendule devrait descendre.Et si j'initialise tous les x[] et les y[] à 0 ,mon fichier de sortie n'est composé que de zeros (normal).

Message cité 1 fois
Message édité par pedigus1 le 01-03-2007 à 15:09:03
Reply

Marsh Posté le 01-03-2007 à 18:12:32    

pedigus1 a écrit :

Sympa ce site GrosBoc ,mais je n'ai pris que les equations simplifiées.


C'est ton RK qui n'est pas bon. Compare ton programme avec celui tu site web.
 

pedigus1 a écrit :

Pour le fait que sa dépasse 2Pi , je pense que c'est normal parceque je n'ai pas encore converti mes angles en radian.


 
J'ai converti tes angles en radian en compilant ton programme  
 

pedigus1 a écrit :


Sinon j'avais une autre question, pour mes conditions initiales, je dois specifier x[0] et x[1] (les deux théta), mais est-ce que je dois mettre les x[2] et [3] et tous les y[] nuls (car ils sont les dérivées de mes angles de départs qui sont constants)?


Tes y ne sont utilisés nulle part. Sinon tes valeurs initiales, tu en fais ce que tu veux. Tu peux très bien avoir envie de pousser ton pendule au démarrage.
 

pedigus1 a écrit :


J'ai fait par exemple un test avec x[0]=50 et x[1]=40 et tout le reste nul, et je vois que x[0] augmente dès le début.Ce n'est pas normal, le pendule devrait descendre.Et si j'initialise tous les x[] et les y[] à 0 ,mon fichier de sortie n'est composé que de zeros (normal).


Demande toi où est ton pendule quand "il est à 50" et ce que prennent comme arguments les fonctions trigo.
 

Reply

Marsh Posté le 01-03-2007 à 18:29:18    

GrosBocdel a écrit :

C'est ton RK qui n'est pas bon. Compare ton programme avec celui tu site web.
 
J'ai converti tes angles en radian en compilant ton programme  
 
Demande toi où est ton pendule quand "il est à 50" et ce que prennent comme arguments les fonctions trigo.


 
D'accord, je vois pour mon 50 il faut que je le passe en radian avant.
 
Mais pour ce qui est du code du site web, j'ai passé du temps dessus et je vois pas vraiment comment il procède.il utilise des choses que je n'ai pas encore vues.Tu pourrais me dire ou est mon erreur pour runge kutta(ou alors si tout est faux).(le code du site web ne marche pas chez moi, donne une erreur à l'execution du programme).
EDIT: j'ai corrigé quelques trucs dans le code et je trouve des valeurs coherentes (j'ai testé avec le pendule au repos qui reste bien au repos et pour les autres conditions intiales j'ai quelquechose de continu).Je pars pour une semaine, je finirais le code en rentrant.
Merci de votre aide
 
EDIT:
C'est bon sa marche maintenant.
Merci de votre aide

Message cité 1 fois
Message édité par pedigus1 le 14-03-2007 à 12:59:01
Reply

Marsh Posté le 23-03-2007 à 17:37:12    

pedigus1 a écrit :


EDIT:
C'est bon sa marche maintenant.
Merci de votre aide


 
T'es sûr? T'as changé quoi et ça donne quoi?

Reply

Marsh Posté le 23-03-2007 à 19:48:04    

GrosBocdel a écrit :

T'es sûr? T'as changé quoi et ça donne quoi?


 
Oula je pourrais plus te dire, sa remonte, mais on a beaucoup avancé depuis.
Je poste un lien vers le projet complet (qui marche) (il faut avoir la SDL et SDL-ttf d'installé ,ils sont inclus dans le zip)
 
http://rapidshare.com/files/224374 [...] _.zip.html

Reply

Marsh Posté le 24-03-2007 à 10:18:59    

pedigus1 a écrit :

Oula je pourrais plus te dire, sa remonte, mais on a beaucoup avancé depuis.
Je poste un lien vers le projet complet (qui marche) (il faut avoir la SDL et SDL-ttf d'installé ,ils sont inclus dans le zip)
 
http://rapidshare.com/files/224374 [...] _.zip.html


 
Ok d'ac. Je vais regarder ça et aller jouer avec dans mon coin  :)  
 

Reply

Marsh Posté le 24-03-2007 à 22:37:42    

lol ok

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed