Librairie Ephemeris: calcul des éphémérides du système solaire

Aller je me lance et vous présente ma première librairie Arduino dispo sur mon github…

Elle s'adresse aux astronomes désireux de calculer les coordonnées des astres du système solaire. Les algos ont été développés en grande partie sur la base de l'ouvrage de Jean Meeus: « Calculs astronomiques à l’usage des amateurs».

Principales fonctionnalités:

  • Calcul des coordonnées équatoriales (RA/Dec), des coordonnées horizontales (Alt/Az), leve/coucher, distance de la Terre (en UA), diamètre apparent (en minutes d'arc) pour le Soleil, Mercure, Venus, notre Lune, Mars, Jupiter, Saturne, Neptune pour une date et un emplacement donné sur Terre.
  • Théorie VSOP87 tronquée pour les planètes.
  • Théorie ELP2000 tronquée pour la Lune.
  • Les calculs de lever/coucher prennent non seulement en compte la position sur Terre mais aussi l'altitude.
  • Les calculs de lever/coucher du Soleil et de la Lune tiennent compte de leur mouvement apparent pendant la journée pour plus de précision.
  • Code optimisé simple précision pour les Arduinos avec refonte des termes VSOP87 et ELP2000 en conséquence afin de ne pas dépasser la dynamique de 32bits.

En bonus:

  • Méthode publique pour la transformation de coordonnées équatoriales (RA/Dec) vers horizontales (Alt/Az).
  • Méthode publique pour la transformation de coordonnées horizontales (Alt/Az) vers équatoriales (RA/Dec).
  • Méthode publique pour le calcul des lever/coucher de n'importe quelles coordonnées équatoriales.

Installation:

  • Compatible avec le gestionnaire de bibliothèque de l'IDE Arduino.
  • Deux exemples inclus: calcul du lever/coucher du soleil à une date et en un lieu donné, calcul et affichage des données de toutes les planètes.

Limitations:

  • Nécessite un Arduino Mega du fait de l'usage mémoire des tables de termes des théories VSOP87 et ELP2000.

Cette librairie s'inscrit dans un plus gros projet perso qui consiste à la refonte intégrale de l'électronique d'une monture équatoriale d'un de mes télescopes. L'idée est de mettre l'électronique au gout du jour avec notamment une fonction de pointage automatique. Plus d'infos sur mon blog pour les curieux… :slight_smile:
http://www.em10-usd-arduino-takahashi.eliotis.com/blog/index.html

En espérant que ce partage puisse être utile à d'autres. :slight_smile:
Seb.

Bonjour,
Bravo et merci pour ce partage.
Une bibliothèque supplémentaire pour les calculs astronomiques.
En général, les formules de notre belge (Jean Meeus) dans ces différents ouvrages font appel à de nombreux termes.
N'as-tu pas peur que les piètres performances des AVR en calcul virgule flottante n'affectent la précision des calculs ?
@

Bonjour, merci pour cette bibliothèque.

En l'essayant (je n'ai rien d'un astronome), j'ai deux petits problèmes :

  • Vous situez Paris à une longitude de -2° 20' 14". De manière classique, les longitudes "Est" sont comptées positivement, il me semble.
  • En mettant la date d'aujourd'hui, le 09/02/2017, j'ai l'erreur suivante :
Arduino : 1.6.7 (Windows XP), Carte : "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

ephemeris_SunriseSunset:36: error: invalid digit "9" in octal constant

                                                                     09,02,2017,

                                                                     ^

exit status 1
invalid digit "9" in octal constant

Merci pour vos informations.

Cordialement.

Pierre

Ce n'est pas lié à la bibliothèque mais à la syntaxe de base du langage de programmation

Enlève le caractère 0 devant le 9.

Une constante littérale (=une valeur codée en dur) commençant par le caractère 0 est interprétée comme étant codée en octal. Elle ne peut donc pas contenir de chiffre 8 ou 9.

De manière similaire, lorsque tu veux écrire une constante littérale en hexadécimal, il faut commencer par 0x...

Oui je sais personne n'utilise plus l'octal aujourd'hui. C'est un des petits pièges à c... du langage dans lequel on tombe régulièrement.

Et encore tu as du bol : tu aurais écrit 010 ça passait à la compil mais la valeur réelle est 8. J'en connais qui se sont arraché les cheveux en debug sur des trucs comme ça. :slight_smile:

bricoleau:
... Oui je sais personne n'utilise plus l'octal aujourd'hui. C'est un des petits pièges à c... du langage dans lequel on tombe régulièrement. ...

A pieds joints que j'y suis tombé !

Merci bricoleau

Cordialement.

Pierre

Merci de vos réactions et retours. :slight_smile:

icare:
N'as-tu pas peur que les piètres performances des AVR en calcul virgule flottante n'affectent la précision des calculs ?

Voici pour exemple les données de Mars à une date de test au hasard (05/02/2017 19:21:00).

Tout d'abord sur Mac Intel Core I5 avec précision double (64bits):

R.A: 00h23m56s.06
Dec: 02d15'35".78
Azi: 250.26d
Alt: 19.33d
Rise: 08:57:58
Set: 21:23:32
Dist: 1.882 AU
Diam: 4.98"

Ensuite en simple précision pour référence toujours sur le Mac Intel:

R.A: 00h23m48s.73
Dec: 02d14'45".76
Azi: 250.28d
Alt: 19.30d
Rise: 08:57:55
Set: 21:23:20
Dist: 1.881 AU
Diam: 4.98"

Et enfin simple précision avec le Arduino Mega:

R.A: 00h23m48s.73
Dec: 02d14'45".76
Azi: 250.28d
Alt: 19.30d
Rise: 08:57:55
Set: 21:23:21
Dist: 1.881 AU
Diam: 4.98"

Déjà bonne nouvelle, en simple précision les résultats Intel/Arduino sont homogènes à un centième près pour le calcul de coucher.

Maintenant si l'on compare simple précision et double précision pour les coordonnées équatoriales:
Delta RA: 00h23m56s - 00h23m49s = 7s = 7*15 = 105" = 1,75'
Delta Dec: 02d15'36" - 02d14'46" = 50" = 0.83'

Pour ordre de grandeur, le diamètre apparent de la pleine Lune dans le ciel est approximativement d'1/2° soit près de 30'. Les résultats me semblent donc tout à fait honorables avec le Arduino pour concevoir le système de pointage automatique d'un télescope amateur.

ChPr:
A pieds joints que j'y suis tombé !

Je m'y suis laissé prendre aussi la première fois avec l'IDE Arduino. Cela semble dépendre des environnements car je le fais habituellement sans problème sous Xcode.

Concernant le signe pour la longitude, en fait il ne semble pas y avoir spécialement consensus en la matière. Je suis calé sur le système GPS qui place l'ouest en négatif et l'est en positif…

La longitude est donc une mesure angulaire sur 360° par rapport à un méridien de référence, avec une étendue de -180° à +180°, ou respectivement de 180° ouest à 180° est.

Source:Coordonnées géographiques — Wikipédia

Ceci dit, ta remarque me fait penser qu'il faut que je vérifie la cohésion dans tous le code car Meeus utilise de mémoire l'Est en négatif et l'Ouest en positif.

Je confirme que vous employez le signe 'moins" pour les longitudes "Est".

J'ai fait quelques comparaisons entre ce que donne votre bibliothèque pour Arduino et ce que donne ce site et celui-ci.

Pour ces deux sites et vos résultats, alors que les données de hauteur, azimut et lever sont dans un mouchoir de poche, les données du coucher dans votre bibliothèque présentent un écart notable, de l'ordre de 4 minutes de temps qui, à mon avis, ne sont pas imputables à la précision de calcul. Voyez le tableau Excel joint.

D'où peut provenir cet écart ?

Mon hypothèse (mais totalement gratuite) : une mauvaise prise en compte de la réfraction de l’atmosphère pour cette donnée.

Ephémérides_SM.zip (3.99 KB)

Bonsoir,
J'avais fait un essai de calculs des heures de lever, au méridien et de coucher du soleil en utilisant la bibliothèque time.h disponible dans avr-libc >= 1.8.0.
Lever et coucher du soleil

Un autre exemple :

/*
icare petibles
Il faut utiliser L'IDE Arduino 1.8.0
27/12/2017
*/
#include <time.h>
#include <util/usa_dst.h>
#include <util/eu_dst.h>

#define ANNEE 2017
#define MOIS 12
#define JOUR 21
#define HEURE 12                                //non nécessaire pour ce calcul
#define MINUTE 0                                //non nécessaire pour ce calcul
#define SECONDE 0                               //non nécessaire pour ce calcul

#define MY_LATITUDE 48.8334 * ONE_HOUR          //latitude Paris en sec d'arc
#define MY_LONGITUDE 2.3334 * ONE_HOUR          //longitude Paris en sec d'arc
#define MY_TIME_ZONE 1 * ONE_HOUR               //fuseau horaire en sec d'arc
//#define MY_DST usa_dst
#define MY_DST eu_dst                           //heure été europe

void setup(){
    time_t now, d;
    struct tm lt, noon, rise, set;
    struct tm tmptr;
    char buff[12];

    Serial.begin(115200);
    Serial.println(F("Calcul Heures Lever, Coucher et au Meridien du Soleil"));
    set_dst(MY_DST);                            //fixe heure été/hiver
    set_zone(MY_TIME_ZONE);                     //fuseau horaire France
    set_position(MY_LATITUDE, MY_LONGITUDE);    //Paris
                                                //référence temporelle
    tmptr.tm_year = ANNEE - 1900;               //voir time.h
    tmptr.tm_mon = MOIS - 1;
    tmptr.tm_mday = JOUR;
    tmptr.tm_hour = HEURE;
    tmptr.tm_min = MINUTE;
    tmptr.tm_sec = SECONDE;
    tmptr.tm_isdst = -1;
    now = mktime(&tmptr);                       //transforme représentation 
                                                //humaide en secondes
    d = solar_noon(&now);                       //calcul au méridien
    localtime_r(&d, &noon);                     //conversion pour humain
    d = sun_set(&now);                          //calcul lever
    localtime_r(&d, &set);                      //conversion pour humain
    d = sun_rise(&now);                         //calcul coucher
    localtime_r(&d, &rise);                     //conversion pour humain
    
    localtime_r(&now, &lt);                     //heure locale
    Serial.print("Pour le : ");
    Serial.println(isotime(&lt));               //affiche jour calcul
    Serial.println();
    
    isotime_r(&noon, buff);                     //transforme en ascii
    Serial.print("Soleil au meridien : ");
    Serial.print(&buff[11]);
    Serial.println(" (Heure locale)");
    Serial.println();
    
    Serial.print("Lever Soleil       : ");
    isotime_r(&rise, buff);                     //transforme en ascii
    Serial.print(&buff[11]);
    Serial.println(" (Heure locale)");
    Serial.println();
    
    Serial.print("Coucher Soleil     : ");
    isotime_r(&set, buff);                      //transforme en ascii
    Serial.print(&buff[11]);
    Serial.println(" (Heure locale)");
    Serial.println();
}

void loop(){
}

Merci de vos retours.

ChPr, l'écart a été élucidé. C'était en fait un souci de conversion de temps sidéral. C'est résolu. J'en ai profité pour améliorer le script d'exemple ephemeris_SunriseSunset.ino en reprenant les données du fichier excel. Voici les logs…

SunRise/Sunset at 10/2/2017:

Paris (UTC+1):
Sunrise: 8h6m57s
Sunset: 18h3m18s
Ref: sunearthtools (10/2/2017): SunRise: 08:07:00 | SunSet: 18:03:19

New York (UTC-5):
Sunrise: 6h55m51s
Sunset: 17h25m8s
Ref: sunearthtools (10/2/2017): SunRise: 06:55:53 | SunSet: 17:25:09

Sydney (UTC+11):
Sunrise: 6h25m24s
Sunset: 19h52m48s
Ref: sunearthtools (10/2/2017): SunRise: 06:25:25 | SunSet: 19:52:49

Sao Paulo (UTC-2):
Sunrise: 6h51m33s
Sunset: 19h49m35s
Ref: sunearthtools (10/2/2017): SunRise: 06:51:35 | SunSet: 19:49:36

La concordance avec sunearthtools est maintenant précises à quelques secondes près. Je précise qu'il s'agit du calcul du dernier/premier rayon et non du centre du disque d'où une différence potentielle d'une minute ou deux avec certains sites. La prise en compte de l'altitude est aussi importante si l'on souhaite quelque chose de précis (compter 2min de décallage à 100m d'altitude).

Pour le fonctionnel, j'ai aussi ajouté une méthode publique pour les conversions de time zone prenant en compte la circularité sur 24h.

// Local time UTC+1
float localTime = Ephemeris::floatingHoursWithUTCOffset(sun.rise,+1);

Pour le signe de la longitude, j'ai standardisé le fonctionnement par défaut sur le GPS à savoir: Est positif et Ouest négatif. Par commodité, on peut néanmoins le permuté et revenir à l'ancien mode via la méthode

Ephemeris::flipLongitude(true);

Dans un autre registre, un nouvel exemple, baptisé PolarisFinder, montre comment utiliser la librairie pour créer un abaque numérique avec un écran TFT pour l'alignement du viseur polaire d'une monture équatoriale (écart de positionnement entre l'étoile polaire et le pôle céleste réel)…

L'abaque prend en compte la dérive de l'étoile polaire (precession des equinoxes) par rapport au pôle nord céleste jusqu'en 2030.

Super, merci.

Cordialement.

Pierre

Les premiers projets concrets avec Ephemeris commencent à pointer le bout du nez. Ici une raquette de commande destinée au pointage d'un Dobson maison en Hollande…

J'adore le look "Startrek rétro". Pour l'anecdote, elle est réalisée entièrement en matériaux de récup (ex: fond de bouteilles de soda). :slight_smile:

Pour les curieux, plus d'infos sur le blog du concepteur Bram Van Zoelen…
http://zoelen.net

Sinon, dernière évolution en date pour la librairie:

  • Méthode de conversion de coordonnées équatoriales d'un équinoxe donné (ex:J2000) vers coordonnées équatoriales actuelles (JNow) pour la prise en compte de la dérive des objets célestes (précession, nutation, aberration et dérive annuelle).

Bonjour,

bravo pour cet article passionnant.

Je reviendrais vers toi très prochainement car je suis sur un projet de suiveur solaire pour des panneaux solaires. Ce projet a été mis de coté (les panneaux sont fixes provisoirement) car je n'arrivais pas a m'en sortir avec mon composant "boussole" multi-axe. Pas sa programmation mais a cause des calculs à faire ... :frowning:

En tout cas, bravo encore.

Merci beaucoup Serge.

Effectivement, aucun problème pour aligner tes panneaux solaire avec Ephemeris. Il y a tout ce qu'il faut avec les conversions alt/azi (vertical/horizontal). Même la boussole est inutile je pense car on peut trouver le nord en calibrant les panneaux avec la librairie. N'hésite pas. Si je peux t'aider ce sera avec plaisir.

Bonjour,

Bravo et merci pour ton remarquable travail.

Voici ma question :
est-il possible de savoir où et quand se trouver sur la terre pour observer une éclipse du soleil par la lune ?

variante :
est-il possible de définir les dates où le soleil ou la lune serait aligné(e) avec l'observateur et un élément en connaissant la position gps et l'altitude des 2 derniers ?
Par exemple :

  • à quel moment la pleine lune sera derrière la tour eiffel en les observant depuis le trocadéro ?
  • où dois je être pour voir le mont saint michel en plein milieu du soleil couchant ?

Bonjour padouet et merci! :slight_smile:

Navré de ne répondre que maintenant mais j'ai l'impression que je ne reçois pas les notifications. :confused:

Alors pour répondre à tes questions, la réponse est non ce n'est pas dans les prérogatives de la librairie. Déjà il nous manque le calcul de Lunaison (nouvelle Lune/pleine Lune) que je n'ai pas implémenté (bien que j'ai hésité). Et ensuite dans l'approche de la libraire, la position GPS est une variable d'entrée et non de sortie.

Il y a fort longtemps j'avais emprunté à la bibliothèque municipale le livre de Jean Meeus pour calculer en Qbasic les jours fériés mobiles en France (à partir de la date de Pâque).

J'ai beaucoup cherché de mon côté, et je n'ai rien trouvé.
Je dois cependant admettre que mon ignorance en astronomie et mes lacunes en anglais (même avec google translate) m'ont certainement permis de passer à côté.

J'ai visé la lune, je l'ai ratée, et maintenant j'erre dans les limbes du cosmos dans l'attente de rencontrer ma bonne étoile...

Bonjour,

Pouvez-vous me dire si l'azimut est donné à partir du Nord géographique ou du nord magnétique?

Merci!

Bonjour,
Pour les astronomes la référence est le SUD (0°)
A partir de cette référence, on trouve deux repérages :

  • 0° pour le sud et des angles positifs vers l'ouest (90° > W, 180° > N) et des angles négatifs vers l'est (-90° > E, -180° > N),
  • 0° pour le sud, 90° pour l'ouest, 180° pour le nord, 270° pour l'est.
    Pour un repérage à partir du Nord (0°), Est (90°), Sud (180°) et l'Ouest (270°), on se trouve dans une vision de marins.
    A partir de ces points, toutes les conversions sont possibles tout va dépendre du type de calcul que tu fais.
    @+

Bonjour,

Je viens de découvrir votre librairie mais j'ai un soucis concernant les coordonnées à entrer.
Je suis situé en Nouvelle Calédonie : 22°16.33200' S et 166°27.34200' E
Comment entrer ces valeurs dans l'exemple "ephemeris_SunriseSunset" ?

-22,16,19 / 166,27,20 ou bien 22,16,19 / 166,27,20

J'obtiens des résultats éronnés à chaque fois ?

Merci par avance.