Go Down

Topic: [Résolu] Fonctions trigonométriques et variables à virgule flottante (Read 7427 times) previous topic - next topic

Uzuma

Bonsoir,

Je dois écrire un code nécessitant l'utilisation de fonctions trigonométriques simple (genre sin, cos) et aussi l'utilisation de variables à virgule flottante.

Pour commencer, j'ai d'abord fait les calculs suivant à l'aide d'une calculatrice dont j'ai noté les résultats sur une feuille :
M = 357 + 0,9856 x 140  ce qui m'a donné : 494, 984
C = 1,914 x sin(M) + 0,02 x sin(2M) ce qui m'a donné : 1,3337

Ensuite j'ai rentré les même formules dans mon code Arduino puis j'ai affiché les résultats via le moniteur série. Cependant je n'obtient pas les même résultats que les calculs fait sur papier.
Arduino me renvoi :
- M = 494,98 (sans le 4 mais ça ce n'est pas un problème, je peux spécifier les nombres de chiffre après la virgule)
- C = 1.89 (ce qui ne concorde pas du tout avec l'opération précédente sachant que j'ai des tonnes d'autres calculs à faire nécessite l'utilisation de fonction trigonométrique)

Au vu de cela j'en ai conclu que cela venait de la ligne de code avec le "SINUS". Mon problème étant mit en évidence, je vous laisse me donner quelques éléments de réponses. Merci.

PS : J'ai prit soins de déclarer C et M comme des variables de type "float".

nulentout

Bonjour les copains,
Oui, les calculs avec Arduino peuvent présenter des pièges dans lesquels j'ai pas mal pateaugé. Soit la limite à 7 chiffres significatifs, mais surtout des problèmes d'homogénéité de type dans les éléments d'un calcul, soit des débordements intermédiaires dans des expressions numériques.
Rassures-toi, une fois avoir codé pour parrer ces problèmes, on obtient des résultats corrects, avec toutefois une limitation à 7 chiffres significatifs ce qui en général est suffisant "en robotique".
Pour pouvoir trouver la source des imprécisions de calcul que tu constates, peux-tu nous fournir le code de ton programme. Ainsi il nous sera possible de déterminer la source de ton problème et surtout te proposer des lignes d'instructions qui conduisent au comportement attendu du code généré. (Choix de types homogène, forçage des calculs avec une "taille" suffisante etc)

haifger

Bonjour,
les fonctions trigonométriques de la libc attendent des valeurs d'angles en radians, or il est probable que lors de tes calculs manuels ta calculatrice était en mode degrés.

Essaie de définir M de cette façon :
Code: [Select]

float M = (357 + 0.9856 * 140) * M_PI / 180.;

pour voir ce que cela donne.

bricoleau

Tu cherches à calculer les heures de lever / coucher du soleil ?
Tutoriels arduino : http://forum.arduino.cc/index.php?topic=398112.0

fdufnews


Bonjour,
les fonctions trigonométriques de la libc attendent des valeurs d'angles en radians, or il est probable que lors de tes calculs manuels ta calculatrice était en mode degrés.

Essaie de définir M de cette façon :
Code: [Select]

float M = (357 + 0.9856 * 140) * M_PI / 180.;

pour voir ce que cela donne.

Calcul fait, l'erreur vient bien d'un mélange radians/degrés

Uzuma

Bonjour,

Merci pour ces quelques réponses.


Pour pouvoir trouver la source des imprécisions de calcul que tu constates, peux-tu nous fournir le code de ton programme.


Comme je l'ai dit, ce n'était qu'un petit bout de code pour comparer les résultats :

Code: [Select]

float M, C;

Void  setup()
{
   Serial.begin(9600);
}

void loop()
{
   M = 357 + 0.9856 * 140;
   C = 1.914 * sin(M) + 0.02 * sin(2*M);
   Serial.println(M);
   Serial.println(C);
   delay(10000);
}



Essaie de définir M de cette façon :
Code: [Select]

float M = (357 + 0.9856 * 140) * M_PI / 180.;

pour voir ce que cela donne.


J'ai essayé mais j'ai comme réponse 8.64 à la place de 494.984. J'aimerais préciser que les valeurs de M et de C doivent être en degré. Et oui effectivement quand j'ai utilisé la calculatrice elle était en mode degré.


Tu cherches à calculer les heures de lever / coucher du soleil ?


Wouah bravo pour ta perspicacité. Et oui effectivement je cherche à calculer les heures de lever et de coucher du soleil.


Calcul fait, l'erreur vient bien d'un mélange radians/degrés


Je n'ai pas conclu de la même manière puisqu'il semblerait que nous n'ayons pas trouvé les même résultats. Comment dois-je m'y prendre ?

bricoleau

C'est bien une erreur de degré / radian

Ta fonction sinus doit prendre une entrée exprimée en radians pour donner un résultat correct.
Avec M=8,64 tu obtiendras bien C=1,33 d'après ta formule

Essaye ça :
Code: [Select]
float M, Mrad, C;

Void  setup()
{
   Serial.begin(9600);
}

void loop()
{
   M = 357 + 0.9856 * 140;
   Mrad = M * 3.141592654 / 180.0;
   C = 1.914 * sin(Mrad) + 0.02 * sin(2*Mrad);
   Serial.println(M);
   Serial.println(Mrad);
   Serial.println(C);
   delay(10000);
}
Tutoriels arduino : http://forum.arduino.cc/index.php?topic=398112.0

bricoleau

#7
May 22, 2014, 02:30 pm Last Edit: May 22, 2014, 02:34 pm by bricoleau Reason: 1
Pour les calculs de lever et coucher du soleil, je suis en train de regarder ça en ce moment.

J'ai reconnu les premières équations, bien que tu utilises une version simplifiée.
Après avoir pas mal farfouillé sur le net, je me suis fixé cette page comme référence :
http://aa.quae.nl/en/reken/zonpositie.html
A mon sens, tout y est.

Tu n'en n'es qu'au début, donc toi t'es pas encore couché  ;)

Il te faudra aussi au moins une fonction trigonométrique inverse (arc-cosinus)

De mon côté, j'arrive à des résultats corrects (calcul de l'éphéméride en fonction de la date et des coordonnées latitude / longitude)... au moins sous excel !!  :)

Je ne suis pas encore passé au coding sous arduino.
Juste un doute sur la précision des calculs.



Tutoriels arduino : http://forum.arduino.cc/index.php?topic=398112.0

Uzuma


C'est bien une erreur de degré / radian


Oui merci, je viens de constater l'erreur à l'instant en essayant d'utiliser la formule dans excel. C'est comme tu as dit ou encore Sin(M*PI/180).



Pour les calculs de lever et coucher du soleil, je suis en train de regarder ça en ce moment.

J'ai reconnu les premières équations, bien que tu utilises une version simplifiée.
Après avoir pas mal farfouillé sur le net, je me suis fixé cette page comme référence :
http://aa.quae.nl/en/reken/zonpositie.html
A mon sens, tout y est.


Merci je vais jeter un coup d'œil. J'utilise actuellement les formules fourni sur ce site : http://www.jean-paul.cornec.pagesperso-orange.fr/heures_lc.htm et comme tu l'as si bien dit c'est une version simplifiée. Cependant j'ai obtenu une heure de lever avec une erreur de 30 min environ. J'ai utilisé ceci entre temps : www.imcce.fr/en/grandpublic/systeme/promenade/pages3/367.html mais faute de compréhension sur le calcul de l'ascension droite et de déclinaison je l'ai mit de côté.

J'aimerais sollicité ton aide pour le calcul de ces heures puisque toi tu en es arrivé à des résultats tout de même satisfaisant.

bricoleau

En moins indigeste que le lien exhaustif ci-dessus :

http://users.electromagnetic.net/bu/astro/sunrise-set.php

C'est le mode d'emploi simplifié (mais précis) pour le calcul qui t'intéresse
Tutoriels arduino : http://forum.arduino.cc/index.php?topic=398112.0

bricoleau


J'aimerais sollicité ton aide pour le calcul de ces heures puisque toi tu en es arrivé à des résultats tout de même satisfaisant.


Si tu es pressé :
Prends le fichier xml joint et ouvre-le dans excel.
C'est là où j'en suis actuellement. Y a toutes les formules de calcul.
A partir de là, ce n'est que du code en c à produire pour obtenir la même chose.
NB : j'ai utilisé les facilités excel de manipulation de dates. Y a un peu de taf pour reproduire ça en c
NB2 : faisabilité certaine, sous réserve du niveau de précision offert par arduino sur les float et les fonctions trigonométriques.

Si tu n'es pas pressé :
Tu attends quelques jours (délai non garanti) que je mette au point la librairie qui va bien
Tutoriels arduino : http://forum.arduino.cc/index.php?topic=398112.0

Uzuma

Bonsoir,


Si tu es pressé :
Prends le fichier xml joint et ouvre-le dans excel.


Merci, je suis en train de le voir actuellement.


Si tu n'es pas pressé :
Tu attends quelques jours (délai non garanti) que je mette au point la librairie qui va bien


Je vais me contenter de ton fichier pour le moment en attendant que tu finisses de créer ta librairie. Encore merci.

Heloderma-kris

#12
May 23, 2014, 08:40 am Last Edit: May 23, 2014, 09:01 am by Heloderma-kris Reason: 1
si ça vous dit voici une lib que j'ai fait peut'etre que ça vous ira  pour moi elle fonctionne de magniere plutot correcte
et pour le calcule de l'heure de lever et de coucher :
bon j'ai extrai de mon code sans trop d'arengement
Code: [Select]

int n =rangJour(rtcD->j,rtcD->m,rtcD->a);
 float HO=angleHoraireSoeil(n,(latD+(latM/60))); //lat D=latitude degree //latM Minute
 float ET=equationDuTemps(n);
heure de lever
hOn=int(12-(HO/15)+((lonD+(lonM/60))/15)+(ET/60)+fuso);//lon D=laongitude degree //lonM Minute
minute de lever
 hOn.m=int(((12-(HO/15)+((lonD+(lonM/60))/15)+(ET/60)+fuso)-(hOn.h))*60);
heure de couché
hOff=int(12+(HO/15)+((lonD+(lonM/60))/15)+(ET/60)+fuso);
minute du couché
hOff.m=int(((12+(HO/15)+(.lonD+.lonM/60))/15)+(ET/60).fuso)-(hOff.h))*60);


perso je l'ai intégré depuis pas mal de temps j'ai un décalage par raport au valeur donné sur certain site qui vien du fait que je n'est pas pris les meme valeur pour le crépuscule
je vous joint le lien a partir du quel j'ai construit les equationde la lib
http://jean-paul.cornec.pagesperso-orange.fr/heures_lc.htm

Heloderma-kris

#13
May 23, 2014, 09:04 am Last Edit: May 23, 2014, 09:08 am by Heloderma-kris Reason: 1
ha je vien de voir que je vous ai pas joint l'autre lib pour la manipulation des date et heure  :smiley-mr-green: sans ça ma lib ephemeride marchera moin bien

il y notament la formule pour verifier si l'année est bisextil car du coup le rang du jour N change !

Uzuma

Bonjour,

merci pour ton bon vouloir. Cependant, pourrais-tu faire un exemple avec ta lib, genre un exemple de calcul en prenant la date d'aujourd'hui comme exemple ?!

Go Up