Wednesday, March 6, 2019

Caricare i kernel - CSPICE data types - Ulteriori funzioni

Proseguiamo l'estensione delle funzioni del toolkit accessibili tramite JNA. Come già visto nei post dedicati al linguaggio Python, il toolkit fornisce due metodi che possiamo utilizzare per il caricamento e per la dismissione dei kernel. I kernel sono i file dati utilizzati dal toolkit, ce ne sono di vario tipo, per una disamina completa potete leggere questa pagina della documentazione. Per ora ci intereressa caricare il kernel delle effemeridi (de421.bsp o simili) e il naif0012.tls per i leapsecond. Quindi aggiungeremo in seguito il kernel per specificare un frame di riferimento customizzato (trueepoch.tf)

Nel piccolo file interfaccia creato nel post precedente era già integrata la dichiarazione delle due funzioni di libreria furnsh_c e unload_c, ora ne scriveremo la definizione.

Partiamo dalle signature:


        void furnsh_c ( ConstSpiceChar  * file ) 
        void unload_c ( ConstSpiceChar  * file )

In Java le tradurremo come:


        void furnsh_c(String s);
        void unload_c(String s);

e la corrispondente definizione sarà:


    public void furnsh_c(String s){    
        INSTANCE.furnsh_c(s);        
        return;
    }

    public void unload_c(String s){
        INSTANCE.unload_c(s);
        return;
    }

Rivediamo il file CSpice.java e Main.java modificati:

import com.sun.jna.*;
import com.sun.jna.ptr.*;

public class CSpice {
    private static CLibrary INSTANCE;

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

    public interface CLibrary extends Library {
        double pi_c();
        double spd_c();
        double dpr_c();
        void furnsh_c(String s);
        void unload_c(String s);

    }
    public double pi_c() {
        return INSTANCE.pi_c();
    }

    public double spd_c() {
        return INSTANCE.spd_c();
    }

    public double dpr_c() {
        return INSTANCE.dpr_c();
    }

    public void furnsh_c(String s){    
        INSTANCE.furnsh_c(s);        
        return;
    }

    public void unload_c(String s){
        INSTANCE.unload_c(s);
        return;
    }

}

e
public class Main {

     public static void main(String[] args) {
        CSpice spice = new CSpice();
        System.out.println("Valore di Pi greco: " + spice.pi_c());
        System.out.println("Secondi in un giorno: " + spice.spd_c());
        System.out.println("Numero di gradi per radiante: " + spice.dpr_c());
        spice.furnsh_c("de421.bsp");
        spice.furnsh_c("naif0012.tls");
        System.out.println("OK Kernel caricati");
        spice.unload_c("de421.bsp");
        spice.unload_c("naif0012.tls");
        System.out.println("OK Kernel dismessi");        
     }
}

Ricompiliamo il tutto ed eseguiamo:

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
OK Kernel dismessi
ubuntu@ubuntu-desktop:~/Scrivania/CSpice$ 

Siamo pra pronti ad inserire la chiamata alla funzione che, data una stringa di formattazione di data e ora in formato ISO 8601, restituisce il numero di secondi TDB (Temps Dynamique Barycentrique) a partire dalla epoch J2000.

La signature della funzione è la seguente:


void str2et_c ( ConstSpiceChar * str,
                SpiceDouble    * et   )

dove str è la data in formato ISO, et è il puntatore al valore double fornito come parametro e che va recuperato come valore.

per i puntatori abbiamo già considerato l'import delle classi del blocco com.sun.jna.ptr (seconda riga del file CSpice). La traduzione in Java sarà la seguente:


       double str2et_c(String s, DoubleByReference p);

per la dichiarazione e


    double str2et_c(String s, DoubleByReference p){
        INSTANCE.str2et_c(s,p);
        return p.getValue();
    }

per la definizione.

In buona sostanza: la funzione str2et_c, che nel toolkit restituisce un void, viene trasformata da noi in modo da restituire un double, che corrisponde al nuovo contenuto della variabile p, modificato dalla funzione ed estratto (dereferenziato, con la terminologia usata dal linguaggio C) con il metodo getValue(). Molto simile, nel procedimento, a quanto già fatto con python ctypes.

Rivediamo i file CSpice.java e Main.java con le ultime modifiche:

import com.sun.jna.*;
import com.sun.jna.ptr.*;

public class CSpice {
    private static CLibrary INSTANCE;

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

    public interface CLibrary extends Library {
        double pi_c();
        double spd_c();
        double dpr_c();
        void furnsh_c(String s);
        void unload_c(String s);
        double str2et_c(String s, DoubleByReference p);

    }
    public double pi_c() {
        return INSTANCE.pi_c();
    }

    public double spd_c() {
        return INSTANCE.spd_c();
    }

    public double dpr_c() {
        return INSTANCE.dpr_c();
    }

    public void furnsh_c(String s){    
        INSTANCE.furnsh_c(s);        
        return;
    }

    public void unload_c(String s){
        INSTANCE.unload_c(s);
        return;
    }

    double str2et_c(String s, DoubleByReference p){
        INSTANCE.str2et_c(s,p);
        return p.getValue();
    }

}
import com.sun.jna.ptr.DoubleByReference;

public class Main {

     public static void main(String[] args) {
        CSpice spice = new CSpice();
        System.out.println("Valore di Pi greco: " + spice.pi_c());
        System.out.println("Secondi in un giorno: " + spice.spd_c());
        System.out.println("Numero di gradi per radiante: " + spice.dpr_c());
        spice.furnsh_c("de421.bsp");
        spice.furnsh_c("naif0012.tls");
        System.out.println("OK Kernel caricati");

        DoubleByReference et = new DoubleByReference();
        System.out.println("Secondi dal J2000: "+spice.str2et_c("2000-01-01T12:00:00", et));
        
        spice.unload_c("de421.bsp");
        spice.unload_c("naif0012.tls");
        System.out.println("OK Kernel dismessi");        
     }
}

E ricompiliamo

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
OK Kernel dismessi
ubuntu@ubuntu-desktop:~/Scrivania/CSpice$ 

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...