Last active
December 19, 2019 16:45
-
-
Save ilmanzo/6753127c20011f1eb0c9dfafef3f1227 to your computer and use it in GitHub Desktop.
scheletro per AstroPi "life in space" con display spinner integrato
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import ephem | |
from math import radians, degrees, cos, sin, asin, sqrt | |
from sense_hat import SenseHat | |
import time | |
import math | |
import os | |
import datetime | |
from time import sleep,strftime | |
import logging | |
import logzero | |
from logzero import logger | |
''' | |
two line element. | |
formato posizionale con tutti i dati del satellite, inclinazione eccentricità | |
non è obbligatiorio conoscere a menadito questo formato | |
per maggiori informazioni visitare il sito | |
https://spaceflight.nasa.gov/realdata/sightings/SSapplications/Post/JavaSSOP/SSOP_Help/tle_def.html | |
l'ultimo dato aggiornato lo trovi su | |
http://www.celestrak.com/NORAD/elements/stations.txt | |
prima di inviare ad ESA l'elaborato ricordarsi di aggiornare le righe qui sotto | |
''' | |
name = "ISS (ZARYA)" | |
line1 = "1 25544U 98067A 19352.98291280 -.00000451 00000-0 16927-6 0 9991" | |
line2 = "2 25544 51.6430 165.1707 0007614 51.0107 86.0364 15.50119867203926" | |
#Qui mi calcolo tutte le informazioni sulla posizione della ISS | |
iss = ephem.readtle(name, line1, line2) | |
#Stessa cosa ma su un oggetto un po più grande | |
sun = ephem.Sun() | |
#Angolo del crepuscolo qui maggiori informazioni | |
# https://www.timeanddate.com/astronomy/astronomical-twilight.html | |
twilight = 0 | |
#durata massima dell'esperimento | |
#sostituire con 178 oppure un numero minore di 180 | |
minutes = 2 | |
#queste variabili non vanno cambiate | |
measure = 0 #conteggio delle misurazioni | |
#questa riga serve per sapere in quale cartella sono | |
dir_path = os.path.dirname(os.path.realpath(__file__)) | |
measure_file = dir_path + "/data01.csv" | |
formatter = logging.Formatter('%(levelname)s, %(message)s') | |
logzero.formatter(formatter) | |
logzero.logfile(measure_file) | |
# questa classe serve a visualizzare un pixel in rotazione sul display | |
# funziona conservando un array di coordinate x,y per ogni punto del cerchio | |
# ad ogni step l'indice dell'array avanza di uno, viene spento il pixel vecchio | |
# e acceso quello nuovo. Se l'indice supera la dimensione dell'array, ritorna a zero | |
# e il cerchio ricomincia da capo. | |
class Spinner(): | |
def __init__(self,sensehat): | |
self.s=sensehat # si salva un riferimento al device sensehat | |
self.points=[] # inizializza array di coordinate | |
#calcola i punti sul cerchio | |
for r in range(0,628,30): | |
x=int(4+3.5*math.cos(r/100)) | |
y=int(4+3.5*math.sin(r/100)) | |
#aggiunge la coppia x,y alla lista dei punti | |
self.points+=[(x,y)] | |
self.curpos=0 | |
self.s.clear() | |
def plot(self,n): | |
#cancella ultimo pixel | |
self.s.set_pixel(self.points[n][0],self.points[n][1],(0,0,0)) | |
n=(n+1)%len(self.points) | |
#colora i successivi con intensita' crescente | |
self.s.set_pixel(self.points[n][0],self.points[n][1],(64,0,0)) | |
n=(n+1)%len(self.points) | |
self.s.set_pixel(self.points[n][0],self.points[n][1],(96,0,0)) | |
n=(n+1)%len(self.points) | |
self.s.set_pixel(self.points[n][0],self.points[n][1],(255,0,0)) | |
#a ogni passo incrementa la posizione nell'array | |
#se supera la lunghezza, riparte da zero | |
def spin(self): | |
self.plot(self.curpos) | |
self.curpos+=1 | |
if self.curpos==len(self.points): | |
self.curpos=0 | |
def get_latlon(time = None): | |
''' | |
Questa funzione calcola la posizione attuale della ISS | |
ricordarsi di commentare le print | |
''' | |
if(time is None): | |
iss.compute() | |
else: | |
iss.compute(time) | |
#print("ISS position lon {0} lat {1}".format(iss.sublong,iss.sublat)) | |
return (iss.sublat,iss.sublong) | |
def isDayLight(lat,lon,time = None): | |
''' | |
Calcolo l'angolo del sole del punto a terra della ISS se l'angolo è maggiore di quello | |
del crepuscolo sono baciato dal sole | |
''' | |
observer = ephem.Observer() | |
observer.lat = lat | |
observer.long = lon | |
observer.elevation = 0 | |
sun.compute(observer) | |
sun_angle = degrees(sun.alt) | |
''' | |
if sun_angle > twilight: | |
print("Iss is in daylight") | |
else: | |
print("Sleep") | |
''' | |
return sun_angle,sun_angle > twilight | |
def haversine(lat1, lon1,time = None): | |
''' | |
Questa funzione restituisce la distanza in kilometri di un certo punto | |
data la posizione della ISS | |
''' | |
#raggio approssimato della terra in kilometri | |
R = 6373.0 | |
lat,lon = get_latlon(time) | |
dlon = lon1 - lon | |
dlat = lat1 - lat | |
a = sin(dlat/2)**2 + cos(lat) * cos(lat1) * sin(dlon/2)**2 | |
c = 2 * asin(sqrt(a)) | |
return c * R | |
# mi salvo in una variabile quando l'orario attuale | |
now_time = datetime.datetime.now() | |
# mi salvo in una variabile quando il programma è partito | |
start_time = datetime.datetime.now() | |
# riferimento ai sensori, da usare per le misure o per accedere al display | |
sensehat = SenseHat() | |
sensehat.low_light = True | |
#inizializzo l'oggetto spinner e gli do un nome corto: sp | |
sp=Spinner(sensehat) | |
try: | |
while (now_time < start_time + datetime.timedelta(minutes=minutes)): | |
try: | |
sp.spin() | |
timer = strftime("%Y%m%d%H%M%S") | |
lat,lon = get_latlon() | |
angle,day = isDayLight(lat,lon) | |
sleep(1) | |
print(haversine(lat,lon)) | |
logger.info("%s,%s,%s,%s,%s,%s",measure,timer,lat,lon,angle,day) | |
measure += 1 | |
now_time = datetime.datetime.now() #aggiorno l'orario attuale | |
except(Exception) as e: | |
logger.error("An error occurred: " + str(e)) | |
except (KeyboardInterrupt, SystemExit): | |
logger.debug("Kill signal received") | |
# alla fine del programma chiudere sensori, spegnere display eccetera | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment