Thursday, March 7, 2019

Calcolo di posizione con JPL toolkit - nuove funzioni

Per completare il nucleo essenziale delle funzioni usate per pilotare l'accesso al jpl toolkit scriviamo tre nuove, e per il momento, ultime, funzioni. Il toolkit è molto ampio, c'è ancora parecchio da sviluppare, ma per l'astrologia serve molto poco.

Spekzr_c

Questa funzione serve per il calcolo di posizione, espressa in coordinate rettangolari e vettore velocità, di un corpo celeste dati il corpo obiettivo, il punto di osservazione, l'istante temporale e alcune altre variabili che non utilizzeremo. Vediamo per prima cosa la signature, ripetendo quello che abbiamo già visto con le ctypes di Python:

   void spkezr_c ( ConstSpiceChar     *targ,
                   SpiceDouble         et,
                   ConstSpiceChar     *ref,
                   ConstSpiceChar     *abcorr,
                   ConstSpiceChar     *obs,
                   SpiceDouble         starg[6],
                   SpiceDouble        *lt        )

   Variable  I/O  Description 
   --------  ---  -------------------------------------------------- 
   targ       I   Target body name. 
   et         I   Observer epoch. 
   ref        I   Reference frame of output state vector. 
   abcorr     I   Aberration correction flag. 
   obs        I   Observing body name. 
   starg      O   State of target. 
   lt         O   One way light time between observer and target. 
 
   starg       is a Cartesian state vector representing the position 
               and velocity of the target body relative to the 
               specified observer. `starg' is corrected for the 
               specified aberrations, and is expressed with respect 
               to the reference frame specified by `ref'. The first 
               three components of `starg' represent the x-, y- and 
               z-components of the target's position; the last three 
               components form the corresponding velocity vector. 
 
               The position component of `starg' points from the 
               observer's location at `et' to the aberration-corrected 
               location of the target. Note that the sense of the 
               position vector is independent of the direction of 
               radiation travel implied by the aberration 
               correction. 
 
               The velocity component of `starg' is the derivative
               with respect to time of the position component of
               `starg.'
 
               Units are always km and km/sec. 

La documentazione ci dice che, dati il target body name (stringa), l'observer epoch (double), il reference frame (il nostro opzionale kernel), il flag di correzione dell'aberrazione (che non usiamo), il nome del corpo di osservazione (la Terra nel nostro caso - Stringa) e dun vettore double di 6 elementi e un eventuale puntatore a double (light time, non utilizzato), possiamo accedere ad un vettore posizione (coordinate x,y,z) e un vettore velocità (vx, vy, vz) deferenziando il vettore double che abbiamo fornito in input).

Siccome il codice sta diventando troppo lungo per incorporarlo per intero, scrivo solo i segmenti, avrete capito che i suguenti frammenti vanno accodati al codice già scritto nei post precedenti, uno all'interno della public interface CLibrary e uno in coda. Attenti però a come definiamo il valore di ritorno, nel caso vogliamo dereferenziare un vettore: nella dichiarazione dentro l'interface indicheremo solo il tipo di dati, nella definizione il double sarà dichiarato come array:

public class CSpice {
    private static final CLibrary INSTANCE;

    static {
        INSTANCE = Native.load("cspice", CLibrary.class);
    }

    public interface CLibrary extends Library {
     ...........

        double spkezr_c(String targ, double et, String ref, 
                     String abcorr, String obs, 
                     double[] starg, DoubleByReference lt);
        }

     // funzione spekzr_c
    }
 
    double[] spkezr_c(String targ, double et, String ref, 
                      String abcorr, String obs, double[] starg, DoubleByReference lt){
        
             for (int i = 0; i < 6; i++){        
                 starg[0] = 0.0;
             }
             INSTANCE.spkezr_c(targ, et, ref, abcorr, obs, starg, lt);
             return starg;
    }

L'array starg, come valore di ritorno, andrà scandito con un ciclo for per recuperare i singoli valori dei due vettori.

Estendiamo il file Main.java:

        ....
        DoubleByReference p = new DoubleByReference();
        System.out.println("Secondi dal J2000: "+spice.str2et_c("2000-01-01T12:00:00", p));
        System.out.println("\n");
        
        // spkezr_c        
        String timestring = "2017-08-10T18:53:22";
        double et = spice.str2et_c(timestring, p);
        String ref = "J2000";
        String target = "SATURN_BARYCENTER";
        String observer = "EARTH";
        String abcorr = "NONE";
        double[] starg = new double[6];
        DoubleByReference lt = new DoubleByReference();
        double[] d = new double[6]; 
        d = spice.spkezr_c(target, et, ref, abcorr, observer, starg, lt);
        String[] elem = {" x: "," y: "," z: ","vx: ","vy: ","vz: "};
        System.out.println("Vettore posizione e velocità di Saturno baricentro per il " + timestring + "\n");
        for (int i = 0; i < 6; i++){
            System.out.println(elem[i]+ " " + d[i]);            
        }
        System.out.println("\n");

In breve, inizializziamo le variabili di input, comprese quelle che serviranno per estrarre i valori di ritorno, secondo il loro tipo, chiamiamo la funzione e scompattiamo l'array.

Facciamo una prova:

ubuntu@ubuntu-desktop:~/Scrivania/CSpice$ javac -classpath .:jna-5.2.0.jar -g Main.java
ubuntu@ubuntu-desktop:~/Scrivania/CSpice$ java -classpath .:jna-5.2.0.jar Main
Valore di Pi greco: 3.141592653589793
Secondi in un giorno: 86400.0
Numero di gradi per radiante: 57.29577951308232
OK Kernel caricati
Secondi dal J2000: 64.18392728473108


Vettore posizione e velocità di Saturno baricentro per il 2017-08-10T18:53:22

 x:  -2.1891291720093992E8
 y:  -1.2962750669325852E9
 z:  -5.289702916654781E8
vx:  -10.299865176779855
vy:  -20.74633831944049
vz:  -9.37634837706102




OK Kernel dismessi
ubuntu@ubuntu-desktop:~/Scrivania/CSpice$ 

Come potete verificare, ho ottenuto gli stessi valori, ma in notazione decimale anzichè esponenziale, che avevo ottenuto con python ctypes; per le verifiche di accuratezza potere rifarvi a questo post precedente. Gli input erano identici, quindi non occorre ripetere le verifiche di accuratezza.

Nei prossimi post aggiungeremo le funzioni di conversione da coordinate rettangoli a sferiche equatoriali ed eclittiche utilizzando due diversi frame di riferimento.

No comments:

Post a Comment

How to create a virtual linux machine with qemu under Debian or Ubuntu with near native graphics performance

It's been a long time since my latest post. I know, I'm lazy. But every now and then I like to publish something that other people c...