Zugriff auf Tschebyscheff-Koeffizienten aus JPL-Ephemeriden

Ich möchte eine Ephemeridendatei mit den Chebyshev-Koeffizienten generieren, ähnlich wie wir mit dem Horizon-Tool ( https://ssd.jpl.nasa.gov/horizons/app.html#/ ) eine Ephemeridendatei mit Positionen generieren können . Ich würde gerne das Gleiche tun, dh in der Lage sein, den Zielkörper, das Koordinatenzentrum und die Daten auszuwählen und die Ephemeridendatei mit den zugehörigen Tschebyscheff-Koeffizienten zu erstellen.

Kennen Sie ein Tool oder ein Programm, das das kann? Ich habe viel recherchiert, aber ich habe keinen gefunden.

Ich habe es mit SPICE versucht, aber ich habe keine Methode gefunden, mit der Chebyshev-Koeffizienten wie diese extrahiert werden können.

Ich verwende meistens einen CSPICE-Python-Wrapper namens SpiceyPy, wenn ich mit SPICE-Kerneln arbeite. Insbesondere die Funktion spkw03 schreibt SPK (.bsp)-Kernel unter Verwendung von Tschebyscheff-Polynomen. Sie übergeben die Positions- und Geschwindigkeitsvektoren und es erstellt die Binärdatei ( naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/spkw03_c.html ). Wenn Sie jedoch nur die Chebyshev-Polynomwerte wünschen, kann dies bedeuten, dass die Binärdatei auf andere Weise gelesen wird (möglicherweise eine benutzerdefinierte Funktion).
@AlfonsoGonzalez Ich lese die Frage so, dass der Fragesteller fragt, wie die Chebyshev-Koeffizienten generiert werden, und nicht, wie die Koeffizienten in eine Datei geschrieben werden. Das ist nicht trivial.
@AlfonsoGonzalez Ja, ich suche nach einer solchen Funktion, die diese Chebyshev-Polynomwerte erhalten kann.
@DavidHammen Ich möchte die Chebyshev-Koeffizienten nicht generieren, ich möchte nur einen Teil einer Ephemeridendatei extrahieren, die mich interessiert. Zum Beispiel können wir uns eine Funktion vorstellen, der wir Daten und den Zielkörper als Eingabe geben und die Chebyshev-Koeffizienten zurückgeben, indem wir einfach den entsprechenden Teil in der Ephemeridendatei extrahieren.

Antworten (4)

Ihre Frage ist etwas mehrdeutig, eine Datei mit den Chebyshev-Koeffizienten wäre keine Ephemeride, aber Sie könnten damit eine Ephemeride generieren. Ungeachtet dessen wird der Artikel Format der JPL-Ephemeridendateien beantworten, wie man die Koeffizienten erhält und wie man sie verwendet, um eine Ephemeride zu generieren.

Der Artikel geht auf mehr Details ein, aber die kurze Antwort: Sehen Sie sich die Header-Datei für die JPL Development Ephemeris an, die Sie verwenden möchten. Der Abschnitt „Gruppe 1050“ enthält die wichtigsten Informationen. Die erste Spalte ist für Merkur, dann Venus, Erde-Mond Baryzentrum ... 9. ist Pluto, Mond und Sonne.

Die Koeffizienten sind in Blöcken von 32 Tagen zusammengefasst und mit den Julianischen Tagen gekennzeichnet, für die sie gültig sind. Die obigen Informationen zur Gruppe 1050 zeigen, wie jeder Block aufgeschlüsselt ist. Die erste Reihe zeigt den Offset in den Block, wo die Koeffizienten für diesen Planeten beginnen, die zweite ist die Anzahl der Koeffizienten für jede Eigenschaft (z. B. X, Y und Z), und die letzte Reihe ist die Anzahl der Teilintervalle, jeweils 32 Tagesblock wird unterteilt in.

Zum Beispiel ist die Mercury-Zeile 3, 14, 4. Sie beginnt also bei Offset 3, hat 14 Koeffizienten pro Eigenschaft (x, y, z) = 3 * 14 = 42 und ist insgesamt in 4 Unterintervalle unterteilt von 42 * 3 = 168 Koeffizienten. Beachten Sie, dass die Spalte für Venus einen Versatz von 171 hat, was dem Versatz von Merkur plus den Gesamtkoeffizienten entspricht.

Sobald Sie die 168 Koeffizienten haben, müssen Sie bestimmen, welches Unterintervall Sie benötigen, da Quecksilber in 4 Unterintervalle unterteilt ist, oder 4 / 32 = 8-Tages-Intervalle. Die ersten beiden Einträge jedes Blocks liefern den gültigen Julianischen Tagesbereich, also bestimmen Sie einfach, für welches Intervall Sie berechnen möchten, und wählen Sie die entsprechenden 42 Koeffizienten für diesen Bereich.

Bei diesen 42 Koeffizienten sind die ersten 14 für die x-Koordinate, die nächsten 14 für die y-Koordinate und die letzten für die z-Koordinate. Dies sind die zu verwendenden Tschebyscheff-Koeffizienten. Der erste Link oben enthält ein Beispiel für das Extrahieren der Koeffizienten und das Durchführen der Berechnung sowie den Quellcode in JavaScript.

Dieses Github-Repository enthält Quellcode in mehreren Sprachen, JavaScript, Python, Java, C#, Perl und vielleicht anderen.

Ja, das ist es, was ich möchte, um die Chebyshev-Koeffizienten zu extrahieren, aber nur über einen bestimmten Zeitraum und das für einige Planeten, um sie dann in einer viel kleineren Datei speichern zu können. Ihr Code scheint es zu tun, ich werde das überprüfen, vielen Dank !!
Das ist eine wirklich gute Erklärung, danke!

Die beste Methode, die ich gefunden habe, ist die Verwendung von Brandon Rhodes 'Python "jplephem" von here , insbesondere unter Verwendung der _load()Funktion eines SPK-Segments. Beim Laden einer BSP-Datei erhalten Sie eine Liste der SPK-Segmente.

Als schneller Plug bin ich Teil eines Teams von vier Leuten, die erst vor ein paar Tagen mit der Arbeit an ANISE begonnen haben: https://github.com/anise-toolkit/ . Es ist geplant, eine Open-Source-Version (Mozilla Public License 2.0) von SPICE zu erstellen, die für die Flugsoftware bereit ist. Ich habe zuvor ähnliche Arbeiten für ein privates Unternehmen durchgeführt (und daher ist diese Arbeit proprietär, sodass ich keinen Zugriff darauf habe), da CSPICE zu diesem Zeitpunkt keine praktikable Alternative war. Für ANISE suchen wir weitere Mitarbeiter für das Gesprächs- und Entwicklungsteam. Wenn Sie also interessiert sind, wenden Sie sich bitte an unseren Element/Matrix-Bereich ( https://matrix.to/#/#anise:matrix. org ).

Danke, ich werde dieses Python-Tool überprüfen. Das ist interessant, weil ich auch Ephemeriden für eine Flugsoftware verwenden möchte, und dazu Tschebyscheff-Koeffizienten an Bord speichern möchte, um dann eine Interpolation einer Ephemeride zu machen.
sehr sehr cool !!

Aktualisieren :

Ich habe einen Weg gefunden, Tschebyscheff-Koeffizienten zu einem gewünschten Datum für einen bestimmten Körper mit CSPICE zu extrahieren.

Hier das Programm, das dies ermöglicht:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "SpiceUsr.h"

/* 
Author : G. Juif
spk_to_asc.c

Computation : gcc spk_to_asc.c -Iinclude lib/cspice.a -lm -o spk_to_asc

Input : meta-kernel file (name must be modified in the code)

This script extract Chebyshev coefficients from a SPICE bsp file. 
The body for which we want the coefficients must be defined in the code. It is by default MARS BARYCENTER.
List of name bodies can be find here : https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html#Planets%20and%20Satellites 
Care to have the associated bsp file. 
The coefficients are written in 3 differents files for X, Y and Z components.

At execution several parameters must be given :
  - Start date in calendar format AAAA/MM/JJ. It is date from which the coefficients will be extract. 
    By default this date is in TDB time scale but it can be modified in the code. 
  - Duration in days (integer) : duration from the start date
  - Time step in days (integer) : Chebyshev coefficients will be extract at each of theses days step

Output 3 files : coeffs_x ; ceffs_y ; coeffs_z
In these files, at each time step, it gives :
# Step_number Date Order Date_start Date_end
Coefficients at each order line per line


Dates are written in CJD format (number of julian days since January 1st, 1950 0h). 
It can be modified to have J2000 julian days by deleting 18262.5 additions in this code. 

- Step_number : gives the step number
- Date : Date (TDB by default) corresponding of Chebyshev coefficients given below
- Order : Order of the Chebyshev polynom
- Date_start Date_end : dates where Chebyshev coefficients are defined in JPL file in CJD days. 
  It is usefull in particular to compute scaled time for the Chebyshev polynom. 


*/
      int main()
      {
         /*
         Local parameters
         */
         #define ND                       2
         #define NI                       6
         #define DSCSIZ                   5
         #define SIDLEN1                 41
         #define MAXLEN                  50
         #define utclen 35

         /*
         Local variables
         */
         SpiceBoolean            found;

         SpiceChar               segid   [ SIDLEN1 ];
         SpiceChar               utcstr[ utclen  ];
         SpiceChar               calendar[ utclen  ];
         SpiceChar               frname [MAXLEN];
         SpiceChar               cname [MAXLEN];
         SpiceChar               bname [MAXLEN];

         SpiceDouble             dc      [ ND ];
         SpiceDouble             descr   [ DSCSIZ ];
         SpiceDouble             et;
         SpiceDouble             record [99];
         SpiceDouble             date [99];
         SpiceDouble             dateCJD;
         SpiceDouble             Cheby_order;
         SpiceDouble             Interv_length;
         SpiceDouble             Start_interv_cheby;
         SpiceDouble             End_interv_cheby;

         SpiceInt                handle;
         SpiceInt                ic      [ NI ];
         SpiceInt                idcode;
         SpiceInt                temp;
         SpiceInt                i = 0;
         SpiceInt                j = 0;
         SpiceInt                nbJours = 0;
         SpiceInt                nbInterv = 0;
         SpiceInt                nbCoeffs = 0;
         
         FILE * eph_file_x;
         FILE * eph_file_y;
         FILE * eph_file_z;

         eph_file_x = fopen("coeffs_x", "w");
         eph_file_y = fopen("coeffs_y", "w");
         eph_file_z = fopen("coeffs_z", "w");
         /*
         Load a meta-kernel that specifies a planetary SPK file
         and leapseconds kernel. The contents of this meta-kernel
         are displayed above.
         */
         furnsh_c ( "spksfs_ex1.tm" );
         printf("Retrieve Chebyshev coefficients at a given date with duration and time step in days\n");
         /*
         Get the NAIF ID code for the Pluto system barycenter.
         This is a built-in ID code, so something's seriously
         wrong if we can't find the code.
         */
         bodn2c_c ( "MARS BARYCENTER", &idcode, &found );

         if ( !found )
         {
            sigerr_c( "SPICE(BUG)" );
         }

         /*
         Pick a request time; convert to seconds past J2000 TDB.
         */
         printf("Enter start date aaaa/mm/jj (TDB time scale):\n");
         scanf("%12s", calendar);
         strcat(calendar," TDB");

         str2et_c ( calendar, &et );
         et2utc_c ( et, "J", 7, utclen, utcstr );
         printf ( "Date : %s \n",calendar);
         
         printf("Enter duration in days :\n");
         scanf("%d", &nbInterv);
         
         printf("Enter time step in days :\n");
         scanf("%d", &nbJours);
         
         /* Loop on et */ 
         nbInterv /= nbJours;
         date[0] = et;
         
         
         for (i = 0 ; i < nbInterv ; i++)
         {
           /*
           Find a loaded segment for the specified body and time.
           */
           spksfs_c ( idcode, date[i], SIDLEN1, &handle, descr, segid, &found );
           
           if ( !found )
           {
              printf ( "No descriptor was found for ID %d at "
                       "TDB %24.17e\n",
                       (int) idcode,
                       et                                       );
           }
           else
           {
              /* Convert date in CJD CNES date */
              dateCJD = (date[i]/86400 ) + 18262.5;
              
              /*
              Display the segment ID.
              Unpack the descriptor. Display the contents.
              */
              dafus_c ( descr, ND, NI, dc, ic );
              temp = spkr02_(&handle,descr,&date[i],record);
              /* Chebyshev polynom order (minus 2 because length of record doesn't consider first element, see fortran spice doc)*/
              Cheby_order = (record[0] - 2)/3;
              /* Interval length of chebyshev coefficients in days */
              Interv_length = (record[2]/86400)*2;
              /* Start and end interval dates where Chebyshev coefficients are defined in JPL file in CJD days*/
              Start_interv_cheby = (record[1]/86400) + 18262.5 - Interv_length/2 ;
              End_interv_cheby = (record[1]/86400) + 18262.5 + Interv_length/2 ;
              
              /* Print informations in files */
              fprintf(eph_file_x, "# %ld %lf %lf %lf %lf\n", i+1, dateCJD, Cheby_order, Start_interv_cheby, End_interv_cheby); 
              fprintf(eph_file_y, "# %ld %lf %lf %lf %lf\n", i+1, dateCJD, Cheby_order, Start_interv_cheby, End_interv_cheby); 
              fprintf(eph_file_z, "# %ld %lf %lf %lf %lf\n", i+1, dateCJD, Cheby_order, Start_interv_cheby, End_interv_cheby); 
              
              nbCoeffs = (int) Cheby_order ;
              /* Coeffs for X,Y,Z component */         
              for (j = 0 ; j < nbCoeffs ; j++)
              {         
                fprintf(eph_file_x, "%24.17e\n", record[3+j]);
                fprintf(eph_file_y, "%24.17e\n", record[3+nbCoeffs+j]);
                fprintf(eph_file_z, "%24.17e\n", record[3+2*nbCoeffs+j]);
              }
           }
           /* Compute next date in seconds past J2000 TDB */
           date[i+1] = date[i] + 86400*nbJours;
          }
          /* Translate SPICE codes into common names */
           frmnam_c ( (int) ic[2], MAXLEN, frname );
           bodc2n_c ( (int) ic[1], MAXLEN, cname, &found );
           bodc2n_c ( (int) ic[0], MAXLEN, bname, &found );
           /* Print configuration*/
            printf ( "Segment ID:        %s\n"
                      "\n--------Configuration-------\n"
                     "Body ID code:      %s\n"
                     "Center ID code:    %s\n"
                     "Frame ID code:     %s\n"
                     "SPK data type:     %d\n"
                     "Start ephemeris file time (TDB):  %24.17e\n"
                     "Stop ephemeris file time  (TDB):  %24.17e\n"
                     "\n--------Chenbyshev polynom informations-------\n"
                     "Chebyshev polynom order:     %lf\n"
                     "Time step in days where Chebyshev coefficients are defined:     %lf\n",
                     segid,
                     bname,
                     cname,
                     frname,
                     (int) ic[3],
                     dc[0],
                     dc[1],
                     Cheby_order,
                     Interv_length                             );
        fclose(eph_file_x);
        fclose(eph_file_y);
        fclose(eph_file_z);
         return ( 0 );
      }

Und die Meta-Kernel-Datei:

KPL/MK

\begindata

   KERNELS_TO_LOAD = ( 'de430.bsp',
                       'naif0011.tls'  )

\begintext

End of meta-kernel

Vielleicht hilft das?

https://www.orekit.org/static/xref/org/orekit/bodies/PosVelChebyshev.html

Dies ist von Orekit, einer Open-Source-Java-Bibliothek