Skip to content

Instantly share code, notes, and snippets.

@ilmanzo
Last active December 19, 2019 16:45
Show Gist options
  • Save ilmanzo/6753127c20011f1eb0c9dfafef3f1227 to your computer and use it in GitHub Desktop.
Save ilmanzo/6753127c20011f1eb0c9dfafef3f1227 to your computer and use it in GitHub Desktop.
scheletro per AstroPi "life in space" con display spinner integrato
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