All rites reversed. Reprint what you like.
Salvo diversa indicazione

mercoledì 28 aprile 2010

Pubblicati i primi dati della sonda LRO-LOLA

Assenza prolungata, ma la Nasa ha rilasciato i primi dati rilevati dalla sonda LRO_LOLA, e siccome sono più dettagliati di quelli della sonda Kaguya della Jaxa ho iniziato a lavorarci sopra.

Qui si possono trovare i dati altimetrici:

LRO-LOLA Grid

Si possono trovare le griglie globali della luna a varie risoluzioni:
LDEM_4: 4 pixel/grado
LDEM_16: 16 pixel/grado
LDEM_32: 32 pixel/grado come quella della sonda Kaguya
LDEM_64: 64 pixel/grado credo sia la griglia della luna completa a più alta risoluzione mai prodotta fino ad ora. Praticamente all'equatore c'è un punto ogni 474 metri, più ci avviciniamo ai poli più aumenta la densità.
A quel che ho capito per ora non ne faranno più dettagliate.
Sono inoltre presenti un'altra serie di dataset parziali delle regioni polari che arrivano anche a più di 300 pixel/grado

Ogni dataset è composto da 4 file, i più importanti sono:
file con estensione IMG: che contiene i dati altimetrici veri e propri
file con estensione LBL: che descrive i dati presenti nel file IMG
file con estensione JP2: contiene gli stessi dati del file IMG ma compressi con formato JPEG2000
file con estensione XML: contiene dei dati da utlizzare con il file JP2 in certi programmi

Questa è un confronto, a parità di griglia fra i dati Kaguya e i dati LRO (32 px/grado):

Da Moon Map Laboratory: Kaguya

Da Moon Map Laboratory: LRO-LOLA

Premere per un ingrandimento

Non so perchè ma quelli della NASA sembrano un po' più definiti.

I dati IMG sono memorizzati come quelli della sonda KAGUYA.
Formato binario, intero 16 bit, ogni numero corrisponde all'altezza in metri a una determinata coordinata.
Le coordinate vanno da +90 a - 90 di latitudine e da 0 a 360 di longitudine.
Nella griglia LDEM 64 ci sono 11520 righe composte ognuna da 23040 punti, quindi in tutto ci sono la bellezza di 265.420.800 punti.

Molto importante, è stato utilizzato un fattore di scala pari a 0,5, quindi i valori letti vanno moltiplicati per questo fattore (credo si a stato utilizzato per poter rimanere all'interno dei 16 bit.

L'importazione dei dati è praticamente uguale a quella che abbiamo già visto nel post precedente, basta cambiare poche cose.

Con questi dati ho voluto creare una animazione, questa (consigliabile vederla in HD):

Full Moon Map 3D from ValterVB on Vimeo.


La creazione di questo video è stata un po' lunga in quanto chiaramente non potevo gestire un numero così elevato di punti, e quindi ho dovuto farla a spicchi. Ho importato spicchi di 3 gradi di latitudine l'uno creato l'animazione per ogni spicchio e poi unito il tutto nel video editor di Blender.

Nel prossimo post spiegherò nel dettaglio come fare praticamente il tutto.
Ne approfitto per ringraziare il forum di Blender-tutorial per l'aiuto.

Ciao
VB

domenica 28 marzo 2010

Finito!

Finito il primo script per l'importazione della mappa lunare DTMTCO_02_00823N200E0310SC pubblicata dalla JAXA.

Allego la schermata

Come si vede molto semplice, ma funzionante.
Adesso scala il modello in automatico, e le normali sono corrette.
Basta inserire le coordinate della zona che interessa, controllare il numero di vertici che ne risulta e premere Importa.
L'unica mancanza è la possibilità di scegliere il file, per ora è scritto direttamente dentro lo script.
Da qui potete scaricare il file con lo script.

Dal prossimo post, inizierò a lavorare sul dataset a più alta definizione, sempre della sonda Kaguya, ci vorrà un po' di tempo in quanto il formato è completamente diverso, e c'è da gestire la texture.

Ciao
VB

sabato 27 marzo 2010

Alta risoluzione

Ci ho messo un po' di tempo perché nella routine che disegna la sfera c'era qualcosa che non andava e son diventato matto a cercare un routine corretta, adesso il problema l'ho risolto.
Quindi prima di iniziare la parte relativa all'interfaccia riscriviamo la routine precedente.
In questo caso ho fatto che passare direttamente alla risoluzione massima (leggo tutti i punti), ma limito l'importazione a una parte della luna. Per ora gli estremi da visualizzare sono all'interno dello script, basta indicare  latitudine iniziale, latitudine finale, longitudine iniziale e longitudine finale.
Questo è il risultato (clicca sull'immagine per un ingrandimento):



























Questa è la metà destra della luna.come si vede dalla terra, tagliando una fetta sopra e una fetta sotto. E' il massimo che riesco a riprodurre, se aumento ancora i punti Blender va in crash per problemi di memoria.
Qui sotto lo script, non credo servano molti commenti in quanto penso di averlo documentata in maniera sufficiente.
Una volta eseguito lo script, bisogna scalarlo (io lo scalo di 0.001) e bisogna anche ricalcolare le normali, ci deve essere un errore nella routine che unisce i vertici.
Se qualcuno sa come fare da Python queste 2 operazioni me lo faccia sapere così correggo.
Per vedere la luna come la vediamo dalla terra, bisogna mettere la visuale dall'alto.


import math, array, bpy, Blender
from Blender import *


#Dati prelevati direttamente dal file
GRID_RES=0.0625    #Risoluzione della griglia
START_LONG=0.03125 #Prima longitudine
START_LAT=89.96875 #Prima Latitudine
RAGGIO_LUNA=1737.4 #Raggio della luna
PUNTI=5760         #Numero di punti per ogni riga


#Tutte le funzioni trigonometriche utilizzano i radianti.
#er trasformare gradi in radianti basta moltiplicare per Pi greco/180
TO_RAD=math.pi/180 #Serve per trasformare i gradi in radianti




Vertici=[] #Array che conterra' i vertici da disegnare
Facce=[]   #Array che conterra' l'ordine dei vertici per creare le facce


DatiAltezza=[] #Array che contiene tutti i dati del file


#Dando un valore di longitudine
#restituisce il numero del punto piu' vicino in
#maniera da far sempre riferimento a una longitudinhe valida
def Punto(Long):
return round((Long-START_LONG)/GRID_RES+1)


#Dando un valore di latitudine
#restituisce il numero della linea piu' vicina in
#maniera da far sempre riferimento a una latitudine valida
def Linea(Lat):
return round((START_LAT-Lat)/GRID_RES+1)


#Dando un numero di linea restituisce la latitudine
def Lat(Linea):
return START_LAT-(Linea-1)*GRID_RES


#Dando un punto restituisce la longitudine
def Long(Punto):
return START_LONG+(Punto-1)*GRID_RES


#Dando una latitudine e una longitudine
#restituisce l'altezza di quella coordinata
def Altezza(Lat,Long):
return DatiAltezza[int((Linea(Lat)-1)*PUNTI+Punto(Long))]


def LeggoFile(NomeFile):
#Apro il file con i dati
f=open(NomeFile,'rb')
#Leggo i primi 9558 byte per posizionarmi sul primo byte di dati
DatiLetti=f.read(9558)
#Leggo fino alla fine del file
DatiLetti=f.read()
#Assegno i dati letti in un array di tipo float
DatiTemp=array.array("f",DatiLetti)
f.close
return DatiTemp


#Questa funzione disegna la luna
def DisegnaLuna(Da_Lat, A_Lat, Da_Long, A_Long):
tmpDa_Long=Da_Long
#Calcolo il numero di linee da leggere
NumeroLinee=int(Linea(A_Lat)-Linea(Da_Lat)+1)
    #Calcolo il numero di punti da leggere
NumeroPunti=int(Punto(A_Long)-Punto(Da_Long)+1)
while (Da_Lat>=A_Lat): #Loop dalla prima all'ultima latitudine  
while (Da_Long<=A_Long): #Loop dalla prima all'ultima longitudine
Raggio=Altezza(Da_Lat,Da_Long)+RAGGIO_LUNA
RaggioCorrente=Raggio*(math.cos(Da_Lat*TO_RAD))
X=RaggioCorrente*(math.sin(Da_Long*TO_RAD))
Y=Raggio*math.sin(Da_Lat*TO_RAD)
Z=RaggioCorrente*math.cos(Da_Long*TO_RAD)
#Assegna le coordinate al vertice
Vertici.append((float(X),float(Y),float(Z)))
Da_Long = Da_Long+GRID_RES
Da_Long=tmpDa_Long
Da_Lat=Da_Lat-GRID_RES
 #Disegno i vertici
me=Mesh.New('Luna')
me.verts.extend(Vertici)
#Loop per creare le facce
for Linee in range(1,NumeroLinee):
for Punti in range(1, NumeroPunti):
v1=Punti+(Linee-1)*NumeroPunti
v2=v1-1
v3=v1+NumeroPunti-1
v4=v3+1
Facce.append((v1,v2,v3,v4))
me.faces.extend(Facce)


Scene.GetCurrent().objects.new(me,"Luna")
Blender.Redraw()
DatiAltezza=None


#Qui inizia il programma


#Leggo i dati dal file e li inserisco nell'array
DatiAltezza=LeggoFile("E:\Apollo 11\Mappa completa\LALT_GGT_MAP.IMG")


#I valori indicati qua rappresentano la zona che ci interessa disegnare
#Le latitudini vanno dalla piu' grande alla piu' piccola
#le longitudini vanno dalla piu' piccola alla piu' grande
DisegnaLuna(Lat(Linea(-30)),Lat(Linea(-50)),Long(Punto(340)),Long(Punto(360)))



Zona di atterraggio dell'Apollo 11 Confrontata con un'immagine reale da telescopio (qui il link all'originale della NASA)














Ciao
VB

martedì 23 marzo 2010

Varie e eventuali 1

In questi post, riporterò informazioni, domande link e quant'altro, non sono direttamente attinenti con i post precedenti.

- Cominciamo con un link, qui c'è una serie rendering spettacolari per i dettagli, ottenuti con i dati di ultima generazione messi a disposizione dalla NASA rilevati dalla sonda LRO.  Da quel che ho capito in questo forum, credo utilizza un programma fatto da lui, parla di 50-100 milioni di poligoni e chiaramente ha usato le immagini con risoluzione da 5 metri che sono liberamente disponibili. Credo che un risultato del genere potrebbe essere fuori portata utilizzando Blender, ma non dispero, lo vedremo in seguito.

- Risoluzione del dataset utilizzato per il rendering completo della luna:
La circonferenza, all'equatore è di circa10916 Km che diviso per i 5760 punti rilevati per ogni parallelo ci da' una risoluzione all'equatore di 1.89 Km, chiaramente più ci avviciniamo al polo più la risoluzione migliora, anche se però credo ci sia qualche forma di distorsione.
Nei dataset più dettagliati della sonda Kaguya la risoluzione arriva a circa 7 metri.
I dati altimetrici della sonda LRO, se non ho capito male perché non ho ancora approfondito (mi sono scaricato parecchia roba ancora da leggere), sono meno dettagliati, ma ci possiamo appoggiare a delle texture di qualità decisamente superiori.

-Questo è uno screen shot del programma che avevo fatto in Visual Basic per elaborare i dataset dettagliati della sonda Kaguya
Come detto precedentemente, questi dataset oltre ai dati altimetrici, contengono anche i dati di radiance, che possiamo utilizzare per generare una texture da applicare al modello 3D. Il bello di questo programma, è che permette di selezionare una zona del dataset evidenziato dal quadrato rosso, e indicare il campionamento da usare, inoltre riporta un sunto dei dati presenti nel Dataset o il dettaglio premendo sui Tab DTM (dati altimetrici) o IMG (dati radiance). La selezione del fattore d campionamento è stato necessario in quanto questo dataset ha più di 42 milioni di punti. Una volta selezionata la zona premendo i 2 pulsanti sulla destra si ottengono 2 file un file OBJ che contiene la geometria, e un file BMP che contiene un'immagine ottenuta con i dati di radiance, Se qualcuno si chiede, perchè una bitmap e non un file jpg? la risposta è semplice, non sono capace di generare un file jpg (almeno per ora), fra l'altro la bitmap completa è di 122 M.
E' mia intenzione replicare queste caratteristiche direttamente in Blender, anche se mi preoccupa un po' la gestione diretta dell'immagine.

E con questo per ora chiudo.
Alla prossima

Ciao
VB

Prossimi passi

Post veloce, stasera c'era Dr House...
Come detto, precedentemente, i prossimi passi saranno creare una piccola interfaccia per poter selezionare zone specifiche della luna e renderizzare solo quelle.

L'idea è quella di poter inserire una coordinata (latitudine+longitudine), e definire la dimensione che ci interessa, dopo di che si importa solo quei dati, alla massima risoluzione.

Quello che mi serve quindi è un'interfaccia in cui siano presenti 2 caselle in cui inserire le coordinate, 2 caselle o 2 slider con cui definire larghezza e altezza e un tasto con cui lanciare l'esecuzione.

In aggiunta credo che aggiungerò una casella di testo o qualcosa del genere in cui scrivere tutti i dati descrittivi del file. Questa non è fondamentale in questo caso, il file è unico e i dati sono sempre quelli, ma ci servirà più avanti con gli altri dati disponibili.

Il mio punto di partenza è questo script, con questo PDF che lo spiega. Credo siano disponibili tutti i controlli che mi servono.

Ciao
VB

lunedì 22 marzo 2010

Disegniamo la luna...

Ora che ci siamo procurati i dati li dobbiamo visualizzare.
Iniziamo con la mappa completa.
Se analizziamo con un editor il file scaricato, (ne esistono di gratuiti, per esempio qui: HexEditor), vediamo che il file è diviso in 2 parti. La prima parte è composta da testo che spiega il contenuto del file e come sono strutturati i dati, la seconda parte, contiene i dati veri e propri.

Nella prima parte, di importante c'è il commento che riepiloga i dati salienti:

"LALT GGT_MAP is a lunar global topographic MAP data extracted            
from LALT_GGT_NUM that is processed from the LALT_LGT_TS created         
by 'surface' command in Generic Mapping Tool (Wessel and Smith, 1991).   
Altitude values were rounded off to the third decimal place.             
Data are ordered from +89.96875 to -89.96875 degrees in latitude         
and from +0.03125 to +359.96875 degrees in longitude. They are           
referenced to the sphere of 1737.4km radius based on the gravity center of the Mean                                           
Earth/Polar Axis body-fixed coordinates of the Moon. Grid resolution is 0.0625 (1/16) degree.                                 
PI: Dr. Hiroshi ARAKI (arakih@miz.nao.ac.jp)."  

In sintesi, dice che i dati sono ordinati da +89.96875 a -89.96875 gradi di latitude e da +0.03125 to +359.96875 gradi di longitude, la risoluzione della griglia è 1/16 di grado, e che i dati sono riferiti a una sfera di 1737,4 Km di raggio.
Proseguendo si legge la voce Image=9559 BYTE, che ci dice che i dati veri e propri iniziano dopo 9559 BYTE dall'inizio del file.
Poi si legge che i dati sono formati da 2880 linee composte da 5760 punti, praticamente ci sono 2880 paralleli e 5760 meridiani.
Più avanti si legge che i dati sono in formato di Float (4 byte) e che l'unità di miusura è in KM, quello che non è spiegato, è che i dati rappresentano l'altezza rispetto alla sfera di prima, praticamente, se il dato è uguale a 0, il punto dista 1737,4 Km dal centro.

Sapendo come è formato il file non ci resta che darlo in "pasto" in qualche maniera a Blender.
Quello che ci serve è creare un elenco di vertici con coordinate x, y e z dove z rappresenta la distanza dal centro della luna e x e y la latitudine e la longitudine del punto.
Fino a venerdì l'unico metodo che mi era venuto in mente era fare un programma in Visual Basic, che conosco,  per leggere dal file i dati e poi scriverlo in un altro file in formato obj come indicato nel post del 18/03, ma pi mi sono detto che non tutti posseggono visual basic anche se esiste una versione free (http://www.microsoft.com/express/Downloads/#2008-Visual-Basic), e allora mi sono preso il fine settimana pèer studiare un po' di Python, liguaggio per poter fare degli script direttamente utilizzabili dentro BLENDER senza strumentio aggiuntivi. Dopo un po' di tentativi ho ottenuto il seguente programmino:


import math
import Blender
import bpy
import array


from Blender import *


Vertice=[] #Matrice che conterrà i vertici della luna
Facce=[] #Matrice che conterrà l'ordine dei vertici per creare le facce
AngularStep=0.0625*10 #Risoluzione della griglia
StartLat=0+AngularStep/2 #Latitudine del primo punto
StartLong=90-AngularStep/2 #Longitudine del primo punto
Raggio=1737.4/10


#Con le seguenti 4 righe carico il dati in una matrice.
#Il primo read mi posiziona diretamente al primno byte di dati
f = open("E:\Apollo 11\Mappa completa\LALT_GGT_MAP.img", 'rb')
b = f.read(9558) #Salto direttamente al byte n° 9559 byte
s = f.read() # Leggo tutti i bytes
a = array.array("f", s) #Creo un array di float
f.close()


#Nel seguente loop Creo i valori di latitudine , longitudine e
#il valore di altezza assegnato  z
contatore=0
Latitudine=StartLat
while Latitudine<180: #180:
    Latitudine=Latitudine+AngularStep
    Longitudine=StartLong #+AngularStep
    while Longitudine>-270:
        Longitudine=Longitudine-(AngularStep)
        Raggio=(a[contatore]+1737.4)/10
        contatore=contatore+10
        x=Raggio*math.sin(Latitudine*math.pi/180)*math.cos(Longitudine*math.pi/180)
        y=Raggio*math.sin(Latitudine*math.pi/180)*math.sin(Longitudine*math.pi/-180)
        z=Raggio*math.cos(Latitudine*math.pi/180)
        Vertice.append((float(x),float(y),float(z)))
me = Mesh.New('Sfera')
me.verts.extend(Vertice)
print Raggio


#Qui unisco i vertici per creare le facce
for r in range(1, 287):
    for c in range (1, 576):
        v0=c+(r-1)*576
        v1=v0-1
        v2=v0+576-1
        v3=v2+1
        Facce.append((int(v0),
                      int(v1),
                      int(v2),
                      int(v3)))


#Chiudo l'ultima fila di faccie
for r in range (1,287):
v0=576*(r-1)
v1=576*r-1
v2=v1+576
v3=v1+1
Facce.append((int(v0),
                      int(v1),
                      int(v2),
                      int(v3)))


me.faces.extend(Facce)
Scene.GetCurrent().objects.new(me,"Sfera")
Blender.Redraw()



Serve ricalcolare le normali forse c'è un errore nella creazione delle facce

Può essere che questo non sia il modo migliore, ma tenendo conto che fino a 2 giorni fa praticamente non sapevo niente di Python posso considerarmi soddisfatto per ora.
Da notare che ho ridotto il tutto di un fattore 10 (la sfera anzichè un raggio di 1737.4 ha un raggio di 173.74), e che ho disegnato solo 1 punto ogni dieci e quindi la già bassa risoluzione si è ridotta ulteriormente.
Ho provato a fare una lettura di tutti di dati ma va in errore per mancanza di memoria (dopotutto si tratta di 16,588,800 punti), forse con un sistema a 64 bit si riesce a fare.

Se una volta eseguito lo script, non vedete niente, aumentate il clipping.

Questo un render di prova.

Il prossimo passo sarà quello di realizzare un script per ricreare solo una parte di questa griglia a piacere, ma alla massima risoluzione.

Ciao
VB

venerdì 19 marzo 2010

Dati...

Ora vedremo come procurarci i dati altimetrici.
Iniziamo con i dati altimetrici della sonda Kaguya.
Vedremo come scaricare la mappa completa a bassa risoluzione, e una mappa ad alta risoluzione di una zona limitata.
Andate al seguente indirizzo: Kaguya dataset Dopo aver creato un account, potete iniziare a cercare i dati che vi interessano.
Per cominciare premete il tasto blu con scritto DataSearch, se non siete loggati vi sara chiesto di loggarvi. Se non volete scaricare niente ma solo cercare se esiste un determinato data set, potete loggarvi come guest.

Per la mappa completa, fate così:
-Premere Product selection
-Nella nuova finestra scegliere LALT
-Poi selezionare Higher Level
-Poi selezionare Global Topographic MAP of the Moon [ G ] e premere ADD
-Premere Determination
Non serve altro. Premere Search Execution in basso, appare una finestra dei risultati con un solo file, premere su add cart e poi selezionare la casella
order e confermare premendo Confirm Order Contents sul fondo. Vi apparirà un finestra di riepilogo, se tutto è OK premete Order Completion.
L'ultima finestra vi conferma che vi è stata spedita una mail con il n° del vostro ordine.
Una volta che il tutto è stato precessato riceverete un'altra Email con un indirizzo FTP da cui scaricare il file. Normalmente impiega pochi minuti. Il file scaricato circa 63 Mega, ha estensione sl2, ma è un file .tar Nella mail di conferma è indicato come scompattarlo.
Una volta scompattato doveste avere 3 file, un Jpeg che rappresenta una miniatura della luna (poco utile),un file con estensione ctg contenente un riepilogo dei dati scaricati e un file con estensione img. Quest'ultimo contiene i dati che ci interessano.

Per una mappa a risoluzione più elevata, (distanza fra i punti di circa 5 metri), si ripete lo stesso procedimento. C'è da tenere presente che non è disponibile tutta la luna a questa risoluzione, ma solo alcune zone. Questi file sono più coerenti con gli standard PDS elaborati per l'archiviazione di questi dati.
In questo caso selezioneremo la zona dell'allunaggio dell'Apollo 17. Le coordinate sono
Latitudine: 20,19080 Nord
Longitudine: 30,77168 Est
Questa volta nella finestra Product selection selezioneremo come Prodotto:LISM, poi L3D, e infine DTM_TCOrtho [ G ]. Premere Add e poi Determination.
Ora dobbiamo indicare le coordinate che ci interessano, questo va fatto nella zona chiamata Observation range, dobbiamo indicare un zona comprendente il punto che ci interessa, io ho indicato una zona fra 20 e 21 di latitudine e una zona fra 30 e 31 di longitudine.






















Premiamo Search Execution.
Dovrebbero risultare 2 file. Cliccando suil nome del file si ha un riepilogo dei dati, di fianco al nome del file c'è indicata la latitudine e la longitudine del centro della zona, premendo display viene visualizzata una miniatura della zona, che ci permette di selezionare qual'è quella che ci interessa, in questo caso è la prima delle 2.

Come prima bisogna confermare l'ordine e aspettare di ricevere l'indirizzo FTP da cui scaricare il file.
All'interno del file compresso come il precedente si trovano 4 file:file jpg che è una miniatura della zona ripresa,2 file con un riepilogo dei dati e un
file con estensione TGZ, quest'ultimo è un file compresso da scompattare, al suo interno sono presenti altri 3 file: un file DTM, con i dati altimetrici, un file IMG con i dati di radiance, che a quanto ho capito dovrebbero essere un misura della quantità di luce emessa o riflessa da una superficie, che si può usare come texture, e un file dqa che dovrebbe essere qualcosa legato alla qualità dei dati, ma non ho capito esattamente a cosa serve.
Il file img può essere visualizzato con il programma Nasaview, liberamente scaricabile al seguente indirizzo:
Nasaview nelle versioni per Solaris, Linux, Windows e Mac, e vi permette di salvarlo in formato Jpeg o Gif (occhio alle dimensioni, in questo caso sono di 6077x7029 pixel).

Ciao
VB