Ejemplo n.º 1
0
def getSatelliteVisable(satelliteName):
    #stations_url = 'http://celestrak.com/NORAD/elements/amateur.txt'
    stations_url = 'https://www.amsat.org/tle/current/nasabare.txt'
    satellites = load.tle_file(stations_url)
    #print('Loaded', len(satellites), 'satellites')

    ts = load.timescale()

    # San Diego
    home = Topos('32.48 N', '117.22 W')

    today = datetime.today()

    # timeframe to search for passes
    plus_time = 2
    t0 = ts.utc(today.year, today.month, today.day, today.hour)
    t1 = ts.utc(today.year, today.month, today.day + plus_time)


    # get visible time for requested satellite
    by_name = {sat.name: sat for sat in satellites}
    satellite = by_name[satelliteName]

    t, events = satellite.find_events(home, t0, t1, altitude_degrees=10.0)
    for ti, event in zip(t, events):
            name = ('rise above 10°', 'culminate', 'set below 10°')[event]
            print(ti.utc_strftime('%Y %b %d %H:%M:%S'), name)
Ejemplo n.º 2
0
def loadSatellites(val):
    satellites = load.tle_file(constellationToLink[val]["link"],
                               filename="%s.txt" % val)

    redisServer = constellationRedis[val]

    for satellite in satellites:
        data = {}
        tle = tlefile.read(satellite.name, "%s.txt" % val)
        data['platform'] = tle.platform
        data['line1'] = tle.line1
        data['line2'] = tle.line2
        json_data = json.dumps(data)
        redisServer.set(tle.platform, json_data)

    os.remove("%s.txt" % val)

    message = "Loaded " + str(
        len(satellites)) + " satellites to " + str(val) + " database"
    print(message)
    connection = pika.BlockingConnection(
        pika.ConnectionParameters(host=rabbitMQHost))
    logChannel = connection.channel()
    logChannel.exchange_declare(exchange='logs', exchange_type='topic')
    logChannel.basic_publish(exchange='logs',
                             routing_key='databaseUpdater.info',
                             body=message)
Ejemplo n.º 3
0
    def loadSatellites(self):
        '''

        :return:
        '''
        self.satellites = load.tle_file(self.url)
        return
Ejemplo n.º 4
0
def get_satellites():
    """
    Gets a list of satellites from celestrak and returns a dictionary of
    skyfield EarthSatellites
    """
    STATIONS_URL = "http://celestrak.com/NORAD/elements/stations.txt"

    satellites = load.tle_file(STATIONS_URL)

    return {sat.name: sat for sat in satellites}
Ejemplo n.º 5
0
    def load_tles(self):
        """Get all the amateur satellite TLEs from celestrak and
            save the TLEs in text file `satellites.tle`.
            """

        # Get the satelliteBodyObjects from the TLEs file
        stations_url = 'http://celestrak.com/NORAD/elements/amateur.txt'
        self.satellite_body_objects = load.tle_file(stations_url)

        QMessageBox.information(self, "Ephemera", 'TLEs Downloaded!',
                                QMessageBox.Ok)
Ejemplo n.º 6
0
 def __init__(self):
     self.gps = load.tle_file("https://celestrak.com/NORAD/elements/gps-ops.txt")
     self.galileo = load.tle_file("https://celestrak.com/NORAD/elements/galileo.txt")
     self.glonass = load.tle_file("https://celestrak.com/NORAD/elements/glo-ops.txt")
     self.beidou = load.tle_file("https://celestrak.com/NORAD/elements/beidou.txt")
     self.allsat = self.gps+self.galileo+self.glonass+self.beidou
     print('Loaded', len(self.allsat), 'satellites')
     # create dict where we can fetch a satellite using its name as key
     self.sats_by_name = {sat.name: sat for sat in self.allsat}
     # Define observatory for az,el calculation
     self.obs = Topos('57.393109 N', '11.917798 E') # OSO25m
     # Define timerange, https://rhodesmill.org/skyfield/time.html
     self.ts = load.timescale()
     self.tgps = False
     self.tgalileo = False
     self.tglonass = False
     self.tbeidou = False
     #self.sat2plot = self.gps+self.galileo
     self.sat2plot = []
     # Plot the data, awaiting key-press events
     self.plot()
Ejemplo n.º 7
0
def processTLE(
    tlefilename
):  #removes duplicates from a 3le file. The satellites need to be ordered by norad id number
    list_of_satellites = load.tle_file(tlefilename)
    print('Loaded', len(list_of_satellites), 'satellites')
    processed_list = []
    for i in range(len(list_of_satellites)):
        if i + 1 < len(list_of_satellites) and list_of_satellites[
                i + 1].model.satnum == list_of_satellites[i].model.satnum:
            continue
        else:
            processed_list.append(list_of_satellites[i])

    print('Removed duplicates,', len(processed_list), 'satellites remaining')
    return processed_list
Ejemplo n.º 8
0
def getData(sat_url):
    #removeFile.remCall()
    satellites = load.tle_file(sat_url)
    print('Loaded', len(satellites), 'satellites')
    t = ts.now()
    for sat in satellites:
        geocentric = sat.at(t)
        subpoint = geocentric.subpoint()
        satList.append({
            'name': str(sat.name),
            'number': str(sat.model.satnum),
            'Latitude': str(subpoint.latitude.degrees),
            'Longitude': str(subpoint.longitude.degrees),
            'altitude': str(round(subpoint.elevation.m)),
            'Inclination-rad': str(sat.model.inclo),
            'position-GCRS': str(geocentric.position.km)
        })
    def getTLEs(self):
        """Get TLEs of a given satellite from Internet and save into a file"""

        url = 'https://celestrak.com/satcat/tle.php?CATNR={}'.format(
            self.catnr)
        self.filename = 'tle-CATNR-{}.txt'.format(self.catnr)

        try:
            # TODO: Use logger for logging
            print("Fetching TLEs for satellite with catalog number {}.".format(
                self.catnr))
            tle = load.tle_file(url, filename=self.filename, reload=True)
        except OSError:
            print("An error occurred while fetching the TLEs")
            print("Are you connected to Internet?")
        else:
            print("TLEs are saved in {}".format(self.filename))
Ejemplo n.º 10
0
def get_data():
    """
    Downloads satellite data and creates a list of satellite objects

        Parameters:
        Returns:
            satellites: array of skyfield satellite objects
    """
    # download satellite data
    with open("urls.txt", "r") as f:
        satellites = list()
        for line in f.readlines():
            # you could switch this appendage around if you wanted
            # to have your sources ranked in a reverse priority
            satellites = satellites + load.tle_file(line.replace('\n', ''))
            os.remove(line.replace('\n', '').split('/')[-1])
    return satellites
Ejemplo n.º 11
0
    def set_up_satellite_data(self):
        """Set up the satellite data."""

        # Get the satelliteBodyObjects from the TLEs file
        stations_url = 'http://celestrak.com/NORAD/elements/amateur.txt'
        self.satellite_body_objects = load.tle_file(stations_url)

        self.by_number = {
            sat.model.satnum: sat
            for sat in self.satellite_body_objects
        }

        # Get the satellite data from the json file
        with open('satslist.json', 'r') as f:
            self.satellite_data = json.load(f)

        # Merge the two

        # list of NORAD numbers in self.satelliteBodyObjects
        numbers = {
            sat.model.satnum: sat
            for sat in self.satellite_body_objects
        }

        # Create a dict of satellite_data dicts where the NORAD numbers are also
        # in satellite_body_objects, i.e. where we have both TLEs and satellite_name info
        self.satellites = {
            s: self.satellite_data[s]
            for s in self.satellite_data
            if (self.satellite_data[s]['Number'] in str(numbers.keys()) and
                self.satellite_data[s]['Status'] in ['active', 'operational'])
        }

        # Fill the modes and Select Satellite combo boxes
        self.fill_combo_box_with_list_of_modes()
        self.fill_select_satellite_combo()

        # Start the Auto-updater
        self.auto_update_timer = QTimer()
        self.auto_update_timer.timeout.connect(self.on_auto_update_timer)
        self.auto_update_timer.start(1 * 1000)

        # Start the clock-updater
        self.clock_update_timer = QTimer()
        self.clock_update_timer.timeout.connect(self.on_clock_update)
        self.clock_update_timer.start(1000)
Ejemplo n.º 12
0
    def __init__(self):
        global load, utc, Topos
        global TEME_to_ITRF, SatrecArray, angle_between, length_of, tau, DAY_S
        global np
        from skyfield.api import load, utc, Topos
        from skyfield.sgp4lib import TEME_to_ITRF
        from sgp4.api import SatrecArray
        from skyfield.functions import angle_between, length_of
        from skyfield.constants import tau, DAY_S
        import numpy as np

        filename="tracking/iridium-NEXT.txt"
        self.satlist = load.tle_file(filename)
        if config.verbose:
            print(("%i satellites loaded into list"%len(self.satlist)))
        self.epoc = self.satlist[0].epoch
        self.ts=load.timescale(builtin=True)

        if config.verbose:
            tnow = self.ts.utc(datetime.datetime.now(datetime.timezone.utc))
            days = tnow - self.epoc
            print('TLE file is %.2f days old'%days)
Ejemplo n.º 13
0
def finding_satellite_ele():
    # Finding and loading satellite elements:

    stations_url = 'http://celestrak.com/NORAD/elements/stations.txt'  
    # last_30_days = 'http://celestrak.com/NORAD/elements/tle-new.txt'
    # satellites = load.tle_file(last_30_days)
    satellites = load.tle_file(stations_url)
    # # print('Loaded', len(satellites), 'satellites')
    by_name = {sat.name: sat for sat in satellites}
    # satellite = by_name['ISS (ZARYA)']
    # # print(satellite)
    planets = load('de421.bsp')
    #finding sunligth in earth from mars
    earth, venus = planets['earth'], planets['moon']
    satellite = by_name['ISS (ZARYA)']
    ts = load.timescale()
    two_hours = ts.utc(2019, 8, 14, 0, range(0, 120, 20))
    p = (earth + satellite).at(two_hours).observe(venus).apparent()
    # print(p)
    sunlit = p.is_behind_earth()
    sunlight = []
    for t_h, sunlit_i in zip(two_hours, sunlit):
        data = '{}  {} is in {}'.format(
            t_h.utc_strftime('%Y-%m-%d %H:%M'),
            satellite.name,
            'sunlight' if sunlit_i else 'shadow')
        sunlight.append(data)
    
    bluffton = Topos('20.5937 N', '78.9629 E', elevation_m=43)
    t0 = ts.utc(2020, 8, 13)
    t1 = ts.utc(2020, 8, 14)
    tn, events = satellite.find_events(bluffton, t0, t1, altitude_degrees=30.0)
    sunlight_time = []
    for ti, event in zip(tn, events):
        name = ('rise above 30°', 'culminate', 'set below 30°')[event]
        time = ti.utc_strftime('%Y %b %d %H:%M:%S'), name
        sunlight_time.append(time)
    return jsonify({"earth_light":sunlight,"sunlight_time":sunlight_time})
Ejemplo n.º 14
0
2020
'''

from skyfield.api import EarthSatellite, load, Topos
import datetime, pytz
import numpy as np

# The resolution of the calculated path of the satellite
RES = 20000
# The host of the tle dataset
TLE_HOST = 'https://www.celestrak.com/NORAD/elements/active.txt'
# A specific satellite chosen from the tle dataset
SAT_CHOSEN = 'KEPLER-1 (CASE)'

# Get the tle data of the satellite chosen
tle_sats = load.tle_file(TLE_HOST)
print("loaded {} satellites from {}".format(len(tle_sats), TLE_HOST))
sats_by_name = {sat.name: sat for sat in tle_sats}
sat_chosen = sats_by_name[SAT_CHOSEN]
print(sat_chosen)

# Get current time, end time, and time difference (delta) between each sample based on RES
ts = load.timescale()
ti = datetime.datetime.now(pytz.utc)  # pytz.utc ensures utc encodding
tf = ti + datetime.timedelta(days=1)
delta = (tf - ti) / RES

latitude = []
longitude = []

# Using the delta calculated earlier, we find the longitude and latitude at a time
Ejemplo n.º 15
0
from skyfield.api import load
from skyfield.framelib import ICRS_to_J2000
import numpy as np

z_vector = np.array([0, 0, 1])

ts = load.timescale()

junk = load.tle_file("spacejunk.tle")
sats = load.tle_file("sats.tle")

killed = []
for i in range(60, 3600 * 24, 60):
    if len(killed) == 59:  #>= 51:
        break

    t = ts.utc(2021, 6, 26, i // 3600, (i // 60) % 60, i % 60)

    jks_xyz = []
    sats_xyz = []
    for ii, jk in enumerate(junk):
        if ii in killed:
            jks_xyz.append(np.array([0., 0., 0.]))
        else:
            pos = np.dot(ICRS_to_J2000, jk.at(t).position.km)
            jks_xyz.append(pos)
    for sat in sats:
        pos = np.dot(ICRS_to_J2000, sat.at(t).position.km)
        sats_xyz.append(pos)

    for sidx, sat_xyz in enumerate(sats_xyz):
Ejemplo n.º 16
0
def loadTLE(filename):
    satlist = load.tle_file(filename)
    if verbose:
        print("%i satellites loaded into list" % len(satlist))
    return satlist
Ejemplo n.º 17
0
                               epoch='>now-30',
                               format='3le')

with open('data.txt', 'w') as f:
    for line in data_generator:
        f.write(line + '\n')

df = load_dataframe('data.txt')

df['a'] = df['n'].apply(lambda n: (8681663.653 / n)**(2 / 3))
df['ah'] = df['a'] * (1 - df['ecc']) - 6371
df['ph'] = df['a'] * (1 + df['ecc']) - 6371

satellites_tle = []

satellites = load.tle_file('data.txt')

print(len(satellites))

ts = load.timescale()
t = ts.now()

# Высокоэллиптические орбиты
HEO = df[(df['ah'] <= 2000) & (df['ph'] >= 35786)]

# «Молния»
molniya = HEO[(HEO['inc'].between(60.8, 64.8))
              & (HEO['n'].between(2.004, 2.01))]

# «Тундра»
tundra = df[(df['argp'].between(240, 300))
Ejemplo n.º 18
0
import matplotlib.pyplot as plt
import numpy as np

# The list of links with TLE data
#GPS https://celestrak.com/NORAD/elements/gps-ops.txt
#GALILEO https://celestrak.com/NORAD/elements/galileo.txt
#GLONASS https://celestrak.com/NORAD/elements/glo-ops.txt
#BEIDOU https://celestrak.com/NORAD/elements/beidou.txt
#stations 'http://celestrak.com/NORAD/elements/stations.txt'

import time
from skyfield.api import Topos, load

#https://rhodesmill.org/skyfield/earth-satellites.html
gps = load.tle_file("https://celestrak.com/NORAD/elements/gps-ops.txt")
galileo = load.tle_file("https://celestrak.com/NORAD/elements/galileo.txt")
glonass = load.tle_file("https://celestrak.com/NORAD/elements/glo-ops.txt")
beidou = load.tle_file("https://celestrak.com/NORAD/elements/beidou.txt")
#satellites = gps + galileo + glonass + beidou
#satellites = galileo + glonass
#satellites = gps + galileo
satellites = gps + beidou
#print('Loaded', len(satellites), 'satellites')

# create dict where we can fetch a satellite using its name as key
sats_by_name = {sat.name: sat for sat in satellites}

# Define observatory for az,el calculation
obs = Topos('57.393109 N', '11.917798 E')  # OSO25m

# Define timerange. First time will be used for azelplot,
Ejemplo n.º 19
0
from skyfield.api import Topos, load
import numpy as np

ts = load.timescale()

satellites = load.tle_file(
    'https://www.celestrak.com/NORAD/elements/stations.txt')
sat = satellites[0]


def getLocationData():
    print('Loaded', sat)
    t = ts.now()
    geocentric = sat.at(t)
    subpoint = geocentric.subpoint()
    return ({
        'name': str(sat.name),
        'number': str(sat.model.satnum),
        'Latitude': str(subpoint.latitude.degrees),
        'Longitude': str(subpoint.longitude.degrees),
        'altitude': str(round(subpoint.elevation.m)),
        'Inclination-rad': str(sat.model.inclo),
        'position-GCRS': str(geocentric.position.km)
    })


def getOrbits():
    t_utc = ts.now().utc_datetime()
    minutes = np.arange(0, 200, 0.1)  # about two orbits
    year = int(t_utc.strftime("%Y"))
    month = int(t_utc.strftime("%m"))
Ejemplo n.º 20
0
from skyfield.api import Topos, load
from spack_track import getTLESatellites

station_url2 = getTLESatellites("2019-09-25--2019-09-26")

f = open("demofile4.txt", "w")
f.write(station_url2)
f.close()

ts = load.timescale()
t = ts.now()
bluffton = Topos('37.67 N', '122.08 W')
satellites = load.tle_file("demofile4.txt", reload=True)

print('Loaded', len(satellites), 'satellites')
print(bluffton)

for satellite in satellites:
    geometry = satellite.at(t)
    subpoint = geometry.subpoint()
    latitude = subpoint.latitude
    longitude = subpoint.longitude
    elevation = subpoint.elevation
    difference = satellite - bluffton
    print(satellite)
    topocentric = difference.at(t)
    print(topocentric.position.km[2])
    # print("Latitude, Lng, Ele", latitude, longitude, elevation)
Ejemplo n.º 21
0
#!/usr/bin/env python
from skyfield.api import EarthSatellite
from skyfield.api import load
from skyfield.positionlib import Geocentric
from skyfield.units import Angle

ts = load.timescale()
# Time used to find correct satellite
t = ts.utc(2020, 3, 18, 6, 17, 23.0)

# Coordinates used to find correct satellite
loc = Geocentric([-393.9579313710918, -4609.1758828158, -4905.812181143784])

stations = load.tle_file('wheres_the_sat.tle')
print('Loaded', len(stations), 'stations')

# Zero degrees separation
nada = Angle(degrees=0)

# Iterate over stations looking for a collision (zero degrees separation)
for station in stations:
	geocentric = station.at(t)
	if geocentric.separation_from(loc).degrees == nada.degrees:
		# Found a collision
		print(station.name)
		tgt = station

# Time used to find next waypoint
t2 = ts.utc(2020, 3, 18, 22, 44, 49.0)
# Coordinates of next waypoint
geocentric = tgt.at(t2)
Ejemplo n.º 22
0
def fetch(sat_name):
    stations_url = 'http://www.celestrak.com/NORAD/elements/amateur.txt' #URL for pulling TLE data
    satellites = load.tle_file(stations_url,reload=True) #Object for storing TLE data for all satellites
    by_name = {sat.name: sat for sat in satellites} #Dictionary of satellite data
    sat = by_name[sat_name] #create sat object with ISS data
    return sat
Ejemplo n.º 23
0
def run(challenge):
    '''
    CHALLENGE:\n
        [challenge0, challenge1, challenge2, challenge3, challenge4, live]
    '''
    if challenge not in CHALLENGES:
        print('invalid challenge')
        return
    challenge = CHALLENGES[challenge]
    found_sat = None
    try:
        sats = load.tle_file('examples/active.txt')
        for sat in sats:
            if sat.name == challenge['satellite_name']:
                found_sat = sat
                break

        assert found_sat
        print(sat)
        print()
    except:
        print('no sat')
        sys.exit(-1)

    ts = load.timescale(builtin=True)

    trackasat = Topos(challenge['trackasat_lat'], challenge['trackasat_long'])
    difference = sat - trackasat

    current_time = datetime.fromtimestamp(challenge['start_time_gmt'],
                                          timezone.utc)
    final_time = current_time + timedelta(0, DURATION_SECONDS)

    t_current = ts.utc(current_time)
    topocentric = difference.at(t_current)
    start_elevation, start_azimuth, distance = topocentric.altaz()
    print('start_azimuth:', start_azimuth.degrees)
    print('start_elevation:', start_elevation.degrees)

    t_final = ts.utc(final_time)
    topocentric = difference.at(t_final)
    final_elevation, final_azimuth, distance = topocentric.altaz()
    print('final_azimuth:', final_azimuth.degrees)
    print('final_elevation:', final_elevation.degrees)

    azimuth_range = start_azimuth.degrees - final_azimuth.degrees
    azimuth_range = abs((azimuth_range + 180) % 360 - 180)
    print('azimuth range:', azimuth_range)

    with open(OUTPUT_FILE, 'w') as f:
        for _ in range(DURATION_SECONDS):
            t_current = ts.utc(current_time)
            topocentric = difference.at(t_current)
            elevation, current_azimuth, distance = topocentric.altaz()

            if (current_azimuth.degrees >= 180
                    and current_azimuth.degrees < 360):
                orientation = 180
                elevation_inverted = True
            else:
                orientation = 0
                elevation_inverted = False

            trackasat_azimuth = abs(
                (current_azimuth.degrees - orientation + 180) % 360 - 180)
            trackasat_azimuth_pwm = (trackasat_azimuth * 4915 / 180) + 2457

            if elevation_inverted:
                trackasat_elevation_pwm = \
                    (4915 * (180 - elevation.degrees) / 180) + 2457
            else:
                trackasat_elevation_pwm = \
                    (4915 * elevation.degrees / 180) + 2457

            f.write(
                str(current_time.timestamp()) + ', ' +
                str(int(trackasat_azimuth_pwm)) + ', ' +
                str(int(trackasat_elevation_pwm)) + '\n')

            current_time = current_time + timedelta(0, 1)

        f.write('\n\n')
        print('\nwrote', OUTPUT_FILE)
        f.close()

    diff = challenge['diff']
    if diff:
        print()

        diff_string = EXAMPLES_FOLDER + '/' + diff + ' ' + OUTPUT_FILE
        print('diff', diff_string)
        print('vimdiff', diff_string)
Ejemplo n.º 24
0
def run(verbose, challenge, signal):
    'CHALLENGE: [examples, live], SIGNAL: [signal_0, signal_1, signal_2]'
    if challenge not in CHALLENGES:
        print('invalid challenge')
        return
    if signal not in ['signal_0', 'signal_1', 'signal_2']:
        print('invalid signal')
        return
    challenge = CHALLENGES[challenge]

    positions = []
    with open(challenge['directory'] + '/' + signal + '.csv',
              'r') as input_file:
        if not input_file:
            'file not found. did you run signal_to_pwm.py?'
            return
        for line in input_file:
            positions.append(eval(line))
    assert positions
    print('loaded', len(positions), 'positions\n')

    if verbose:
        print('positions[0].azimuth:', positions[0]['azimuth'])
        print('positions[0].elevation:', positions[0]['elevation'])
        print('positions[len(positions) - 1][\'azimuth\']',
              positions[len(positions) - 1]['azimuth'])
        print('positions[len(positions) - 1][\'elevation\']',
              positions[len(positions) - 1]['elevation'])

        positions_azimuth_range = \
            positions[0]['azimuth'] - positions[len(positions) - 1]['azimuth']
        positions_azimuth_range = \
            abs((positions_azimuth_range + 180) % 360 - 180)

        print('azimuth range:', positions_azimuth_range)
        print(
            'elevation range:',
            abs(positions[0]['elevation'] - \
                positions[len(positions) - 1]['elevation'])
        )
        print()

    sats = load.tle_file('examples/active.txt')
    print('loaded', len(sats), 'sats')

    ts = load.timescale(builtin=True)
    matches = []
    for sat in sats:
        print(sat)
        trackasat = Topos(challenge['trackasat_lat'],
                          challenge['trackasat_long'])
        difference = sat - trackasat

        starting_time = datetime.fromtimestamp(challenge['start_time_gmt'],
                                               timezone.utc)
        final_time = starting_time + timedelta(0, 120)

        if verbose:
            t_starting = ts.utc(starting_time)
            topocentric = difference.at(t_starting)
            start_elevation, start_azimuth, distance = topocentric.altaz()
            print('start_azimuth:', start_azimuth.degrees)
            print('start_elevation:', start_elevation.degrees)

            t_final = ts.utc(final_time)
            topocentric = difference.at(t_final)
            final_elevation, final_azimuth, distance = topocentric.altaz()
            print('final_azimuth:', final_azimuth.degrees)
            print('final_elevation:', final_elevation.degrees)
            azimuth_range = start_azimuth.degrees - final_azimuth.degrees
            azimuth_range = abs((azimuth_range + 180) % 360 - 180)
            print('azimuth range:', azimuth_range)
            elevation_range = abs(start_elevation.degrees -
                                  final_elevation.degrees)
            print('elevation range:', elevation_range)

        success = True
        fail_count = 0
        for position in positions:
            working_time = starting_time + timedelta(0, position['time'])
            t_working = ts.utc(working_time)
            topocentric = difference.at(t_working)
            elevation, azimuth, distance = topocentric.altaz()

            if elevation.degrees < 0:
                success = False
                break

            if verbose:
                print(azimuth.degrees, elevation.degrees, position['azimuth'],
                      position['elevation'])

            if (
                abs(azimuth.degrees - position['azimuth']) > \
                    AZ_ACCURACY_THRESHOLD or
                abs(elevation.degrees - position['elevation']) > \
                    EL_ACCURACY_THRESHOLD
            ):
                if verbose:
                    print('mismatch:', azimuth.degrees - position['azimuth'],
                          elevation.degrees - position['elevation'])
                fail_count += 1
                if fail_count > FAIL_THRESHOLD:
                    if verbose:
                        print('sat failed with fail_count:', fail_count)
                    success = False
                    break

        if success:
            matches.append({'name': sat.name, 'fail_count': fail_count})

    print()
    print('expected: ' + challenge[signal])
    print('matches:')
    for match in matches:
        print(match)

    stop = timeit.default_timer()
    print('\nruntime:', stop - start)
Ejemplo n.º 25
0
import time
import csv
from skyfield.api import load, wgs84

# create time scale
ts = load.timescale()

# load satellite data from NORAD
url = 'https://www.celestrak.com/NORAD/elements/active.txt'
filename = 'active.txt'
satellites = load.tle_file(url, filename=filename)
saveFile = '../data/{take}/data_{frame:03d}.csv'
take = 'take-001'
numFrames = 60

# start an fixed loop
for frame in range(numFrames):
    outPutFile = saveFile.format(frame=frame, take=take)

    # get current time.
    t = ts.now()

    # create our labels.
    header = ['name', 'x', 'y', 'z']

    # create empty data struct
    data = []

    # add header to data structure
    data.append(header)
    def create_random_challenge(self, seed, num_sats=3) -> RandomChallenge:
        # create rng with the given seed
        random.seed(seed)
        sys.stderr.write("Seed: %d\n" % seed)
        # load LEO satellites
        satellites = load.tle_file(self.tle_filepath)
        leo_satellites = [
            sat for sat in satellites
            if sat.model.no_kozai >= self.TWO_HOUR_ORBIT_RADIANS_PER_MIN
        ]

        # choose a time
        ts = load.timescale(builtin=True)

        time_mid = leo_satellites[0].epoch.astimezone(utc)
        time_min = time_mid - self.ONE_WEEK_TIME
        time_max = time_mid + self.ONE_WEEK_TIME

        time_range_s = (time_max - time_min).total_seconds()
        challenge_time_offset = datetime.timedelta(seconds=time_range_s *
                                                   random.random())
        challenge_t_start = time_min + challenge_time_offset
        challenge_t_end = challenge_t_start + self.CHALLENGE_INTERVAL

        challenge_t_utc = (datetime.datetime.utcfromtimestamp(
            challenge_t_start.timestamp()),
                           datetime.datetime.utcfromtimestamp(
                               challenge_t_end.timestamp()))

        challenge_t_ts = (ts.utc(
            challenge_t_utc[0].year, challenge_t_utc[0].month,
            challenge_t_utc[0].day, challenge_t_utc[0].hour,
            challenge_t_utc[0].minute, challenge_t_utc[0].second +
            challenge_t_utc[0].microsecond / 1000000.0),
                          ts.utc(
                              challenge_t_utc[1].year,
                              challenge_t_utc[1].month, challenge_t_utc[1].day,
                              challenge_t_utc[1].hour,
                              challenge_t_utc[1].minute,
                              challenge_t_utc[1].second +
                              challenge_t_utc[0].microsecond / 1000000.0))

        # retry up to 10 times (very unlikely)
        for i in range(10):
            # choose a groundstation
            groundstations = self.load_groundstations(
                self.groundstations_filepath)
            challenge_groundstation: Groundstation = random.choice(
                groundstations)
            loc = Topos(challenge_groundstation.latitude,
                        challenge_groundstation.longitude)

            # find visible satellites
            candidate_satellites = []
            for sat in leo_satellites:
                _d = sat - loc
                alt_at_t_start, az_at_t_start, distance_at_t_start = _d.at(
                    challenge_t_ts[0]).altaz()
                alt_at_t_end, az_at_t_end, distance_at_t_end = _d.at(
                    challenge_t_ts[1]).altaz()
                if alt_at_t_start.degrees > 0 and alt_at_t_end.degrees > 0 and \
                        abs(alt_at_t_end.degrees - alt_at_t_start.degrees) >= 2*MIN_CANDIDATE_DISTANCE_DEGREES and \
                        abs(az_at_t_end.degrees - az_at_t_start.degrees) >= 2*MIN_CANDIDATE_DISTANCE_DEGREES:
                    candidate_satellites.append(
                        (sat, alt_at_t_start.degrees, az_at_t_start.degrees,
                         alt_at_t_end.degrees, az_at_t_end.degrees))

            if len(candidate_satellites) == 0:
                print(
                    "Unable to find valid sats for this groundstation and this time! "
                    "Retrying...",
                    file=sys.stderr)
                # otherwise, try again with next groundstation (in random sequence)
                # but this is not a problem in this version
                continue

            def satellites_not_too_close(sat1, sat2):
                _, sat1_alt_start, sat1_az_start, sat1_alt_end, sat1_az_end = sat1
                _, sat2_alt_start, sat2_az_start, sat2_alt_end, sat2_az_end = sat2

                return abs(sat1_alt_start - sat2_alt_start) > MIN_CANDIDATE_DISTANCE_DEGREES \
                        and abs(sat1_alt_end - sat2_alt_end) > MIN_CANDIDATE_DISTANCE_DEGREES \
                        and abs(sat1_az_start - sat2_az_start) > MIN_CANDIDATE_DISTANCE_DEGREES \
                        and abs(sat1_az_end - sat2_az_end) > MIN_CANDIDATE_DISTANCE_DEGREES

            def satellites_too_close(sat1, sat2):
                _, sat1_alt_start, sat1_az_start, sat1_alt_end, sat1_az_end = sat1
                _, sat2_alt_start, sat2_az_start, sat2_alt_end, sat2_az_end = sat2

                return abs(sat1_alt_start - sat2_alt_start) < MIN_CANDIDATE_DISTANCE_DEGREES \
                   and abs(sat1_alt_end - sat2_alt_end) < MIN_CANDIDATE_DISTANCE_DEGREES \
                   and abs(sat1_az_start - sat2_az_start) < MIN_CANDIDATE_DISTANCE_DEGREES \
                   and abs(sat1_az_end - sat2_az_end) < MIN_CANDIDATE_DISTANCE_DEGREES

            ambiguous_sats = set()
            for sat1 in candidate_satellites:
                for sat2 in candidate_satellites:
                    if sat1[0] != sat2[0] and satellites_too_close(sat1, sat2):
                        ambiguous_sats.add(sat1)
                        ambiguous_sats.add(sat2)

            def key(sat):
                return sat[0].name

            print("excluding {} ambiguous satellites from candidates".format(
                len(ambiguous_sats)),
                  file=sys.stderr)
            candidate_satellites = set(candidate_satellites).difference(
                ambiguous_sats)
            candidate_satellites = list(candidate_satellites)
            candidate_satellites.sort(key=key)

            # choose random satellite from candidates
            challenge_satellites = []
            retry = False
            for i in range(3):

                if len(candidate_satellites) < 3:
                    print(
                        "Unable to find valid sats for this groundstation and this time! "
                        "Retrying...",
                        file=sys.stderr)
                    # otherwise, try again with next groundstation (in random sequence)
                    # but this is not a problem in this version
                    retry = True
                    break

                challenge_sat = random.choice(candidate_satellites)

                candidate_satellites.remove(challenge_sat)

                challenge_satellites.append(challenge_sat[0])

            if retry:
                continue

            start = challenge_t_utc[0].replace(tzinfo=datetime.timezone.utc)
            end = challenge_t_utc[1].replace(tzinfo=datetime.timezone.utc)
            seconds = int(end.timestamp() - start.timestamp())
            print("{} from {}, {} at {}".format(
                ','.join([sat.name for sat in challenge_satellites]),
                challenge_groundstation.latitude,
                challenge_groundstation.longitude, start),
                  file=sys.stderr)
            return RandomChallenge(challenge_satellites,
                                   challenge_groundstation, start.timestamp(),
                                   seconds)

        raise RuntimeError()
Ejemplo n.º 27
0
        radians(float(arg_pericenter)),  # argpo: argument of perigee (radians)
        radians(float(inclination)),  # inclo: inclination (radians)
        radians(float(mean_anomaly)),  # mo: mean anomaly (radians)
        mean_motion_radians_per_minute,  # no_kozai: mean motion (radians/minute)
        radians(float(ra_asc_node)
                ),  # nodeo: right ascension of ascending node (radians)
    )
    return satrec


MINUTES_PER_DAY = 24 * 60
ONE_METER = 1.0 / AU_M
ONE_KM_PER_HOUR = 1.0 * 24.0 / AU_KM
ts = load.timescale(builtin=True)
# TLE
stations_tle = load.tle_file("stations-tle.txt", reload=False)
# XML
tree = ET.parse("stations.xml")
root = tree.getroot()

t0 = ts.utc(2020, 6, 27)
for sat_tle in stations_tle:
    name = sat_tle.name.strip()
    print(name, sat_tle.model.satnum)
    # Find and parse XML twin
    satrec = satrec_from_XML(root, sat_tle.model.satnum)
    sat_xml = EarthSatellite.from_satrec(satrec, ts)
    p_xml = sat_xml.at(t0)
    p_tle = sat_tle.at(t0)
    #print("XML Location", p_xml.position.au)
    #print("TLE location", p_tle.position.au)
Ejemplo n.º 28
0
import os
import math
from dotenv import load_dotenv
load_dotenv()
from skyfield.api import Topos, load
from datetime import timedelta
from pytz import timezone
from twilio.rest import Client

# load the satellite dataset from Celestrak
starlink_url = 'https://celestrak.com/NORAD/elements/starlink.txt'
starlinks = load.tle_file(starlink_url)
print('Loaded', len(starlinks), 'satellites')

# update city location's latitude and longitude and timezone
location = Topos('37.7749 N', '122.4194 W')
tz = timezone('US/Pacific')

# establish time window of opportunity
ts = load.timescale()
t0 = ts.now()
t1 = ts.from_datetime(t0.utc_datetime() + timedelta(hours=2))

# loop through satellites to find next sighting
first_sighting = {}
for satellite in starlinks:

    # filter out farthest satellites and NaN elevation
    elevation = satellite.at(t0).subpoint().elevation.km
    isNan = math.isnan(elevation)
    if elevation > 400 or isNan: continue
Ejemplo n.º 29
0
def NaticalMilesToStatueMiles(tNaticalMiles):
 return (float(tNaticalMiles) * 1.15)

def StatuteMilesToNaticalMiles(tStatueMiles):
 return (float(tStatueMiles) / 1.15)

def StatuteMilesToKilometers(tStatueMiles):
 return (float(tStatueMiles) * 1.609344)


#stations_url = 'http://celestrak.com/NORAD/elements/stations.txt'
#satellite = by_name['ISS (ZARYA)']
stations_url = "https://www.amsat.org/tle/current/nasabare.txt"
#satellite = by_name['AO-07']

satellites = load.tle_file(stations_url)
print('Loaded', len(satellites), 'satellites')


ts = load.timescale(builtin=True)

def gridCase(input):
    A=''
    B=''
    C=''
    D=''
    E=''
    F=''

    if (len(input)>= 4):
        chars = [char for char in input]  
Ejemplo n.º 30
0
def visible_pass(start_time,
                 end_time,
                 site,
                 timezone=0,
                 cutoff=10,
                 twilight='nautical',
                 visible_duration=120):
    '''
    Generate the visible passes of space targets in a time period.

    Usage: 
    visible_pass(start_time,end_time,site,timezone=8)

    Inputs:
    start_time -> [str] start time, such as '2020-06-01 00:00:00'
    end_time -> [str] end time, such as '2020-07-01 00:00:00'
    site -> [list of str] geodetic coordinates of a station, such as ['21.03 N','157.80 W','1987.05']

    Parameters:
    timezone -> [int, optional, default=0] time zone, such as -10; if 0, then UTC is used.
    cutoff -> [float, optional, default=10] Satellite Cutoff Altitude Angle
    twilight -> [str, or float, optional, default='nautical'] Dark sign or solar cutoff angle; if 'dark', then the solar cutoff angle is less than -18 degrees;
    if 'astronomical', then less than -12 degrees; if 'nautical', then less than -6 degrees; if 'civil', then less than -0.8333 degrees;
    alternatively, it also can be set to a specific number, for example, 4.0 degrees.
    visible_duration -> [int, optional, default=120] Duration[seconds] of a visible pass

    Outputs:
    VisiblePasses_bysat.csv -> csv-format files that record visible passes in sort of target
    VisiblePasses_bydate.csv -> csv-format files that record visible passes in sort of date
    xxxx.txt -> one-day prediction files for targets
    '''
    home = str(Path.home())
    direc_eph = home + '/src/skyfield-data/ephemeris/'
    direc_time = home + '/src/skyfield-data/time_data/'
    de430 = direc_eph + 'de430.bsp'

    load_eph = Loader(direc_eph)
    load_time = Loader(direc_time)

    print('\nDownloading JPL ephemeris DE430 and timescale files',
          end=' ... \n')

    # URL of JPL DE430
    url = 'http://www.shareresearch.me/wp-content/uploads/2020/05/de430.bsp'
    '''
    url = 'http://naif.jpl.nasa.gov/pub/naif/generic_kernels/spk/planets/de430.bsp'
    url = 'https://repos.cosmos.esa.int/socci/projects/SPICE_KERNELS/repos/juice/browse/kernels/spk/de430.bsp'
    '''
    if not path.exists(de430):
        desc = 'Downloading {:s}'.format('de430.bsp')
        tqdm_request(url, direc_eph, 'de430.bsp', desc)

    print('Downloading timescale files', end=' ... \n')
    ts = load_time.timescale()
    planets = load_eph('de430.bsp')

    # Print information about the time system file and ephemeris file
    print(load_time.log)
    print(load_eph.log)

    print(
        '\nCalculating one-day predictions and multiple-day visible passes for targets',
        end=' ... \n')

    if twilight == 'dark':
        sun_alt_cutoff = -18
    elif twilight == 'astronomical':
        sun_alt_cutoff = -12
    elif twilight == 'nautical':
        sun_alt_cutoff = -6
    elif twilight == 'civil':
        sun_alt_cutoff = -0.8333
    elif type(twilight) is int or type(twilight) is float:
        sun_alt_cutoff = twilight
    else:
        raise Exception(
            "twilight must be one of 'dark','astronomical','nautical','civil', or a number."
        )

    dir_TLE = 'TLE/'
    dir_prediction = 'prediction/'
    sun, earth = planets['sun'], planets['earth']
    sats = load.tle_file(dir_TLE + 'satcat_3le.txt')

    lon, lat, ele = site
    observer = Topos(lon, lat, elevation_m=float(ele))

    # local start time
    t_start = Time(start_time) - timezone * u.hour
    # local end time
    t_end = Time(end_time) - timezone * u.hour

    fileList_prediction = glob(dir_prediction + '*')
    if path.exists(dir_prediction):
        for file in fileList_prediction:
            remove(file)
    else:
        mkdir(dir_prediction)

    filename0 = 'VisiblePasses_bysat.csv'
    filename1 = 'VisiblePasses_bydate.csv'

    outfile0 = open(dir_prediction + filename0, 'w')
    header = [
        'Start Time[UTC+' + str(timezone) + ']',
        'End Time[UTC+' + str(timezone) + ']', 'NORADID', 'During[seconds]'
    ]
    outfile0.write('{},{},{},{}\n'.format(header[0], header[1], header[2],
                                          header[3]))

    print('Generate one-day prediction for targets:')

    for sat in sats:
        visible_flag = False
        noradid = sat.model.satnum
        passes = next_pass(ts, t_start, t_end, sat, observer, cutoff)
        if not passes:
            continue
        else:
            outfile = open(dir_prediction + str(noradid) + '.txt', 'w')
            outfile.write(
                '# {:18s} {:8s} {:8s} {:8s} {:8s} {:10s} {:14s} {:7s} \n'.
                format('Date and Time(UTC)', 'Alt[deg]', 'Az[deg]', 'Ra[h]',
                       'Dec[deg]', 'Range[km]', 'Solar Alt[deg]', 'Visible'))

        for pass_start, pass_end in passes:
            t = t_list(ts, Time(pass_start), Time(pass_end), 1)
            sat_observer = (sat - observer).at(t)
            sat_alt, sat_az, sat_distance = sat_observer.altaz()
            sat_ra, sat_dec, sat_distance = sat_observer.radec()
            sun_observer = (earth + observer).at(t).observe(sun).apparent()
            sun_alt, sun_az, sun_distance = sun_observer.altaz()
            sun_beneath = sun_alt.degrees < sun_alt_cutoff
            #shadow = eclipsed(sat,sun,earth,t)
            sunlight = sat.at(t).is_sunlit(planets)
            # Under the premise of satellite transit, visibility requires at least two conditions to be met: dark and outside the earth shadow.
            #visible = sun_beneath & ~shadow
            visible = sun_beneath & sunlight

            if visible.any():
                visible_flag = True
                t_visible = np.array(t.utc_iso())[visible]
                t_visible_0 = (Time(t_visible[0]) + timezone * u.hour).iso
                t_visible_1 = (Time(t_visible[-1]) + timezone * u.hour).iso
                during = round((Time(t_visible[-1]) - Time(t_visible[0])).sec)
                if during >= visible_duration:
                    outfile0.write('{:s},{:s},{:d},{:d}\n'.format(
                        t_visible_0, t_visible_1, noradid, int(during)))

            # Generate a one-day prediction file
            if Time(pass_end) < t_start + 1:
                for i in range(len(t)):
                    outfile.write(
                        '{:20s} {:>8.4f} {:>8.4f} {:>8.5f} {:>8.4f} {:>10.4f} {:>10.4f} {:>7d} \n'
                        .format(
                            t.utc_strftime('%Y-%m-%d %H:%M:%S')[i],
                            sat_alt.degrees[i], sat_az.degrees[i],
                            sat_ra.hours[i], sat_dec.degrees[i],
                            sat_distance.km[i], sun_alt.degrees[i],
                            visible[i]))
                outfile.write('\n')
            '''
            # Generate a one-day prediction in visibility period
            if visible.any():
                t_visible = np.array(t.utc_iso())[visible]
                for i in range(len(t_visible)):
                    outfile.write('{:20s} {:>8.4f} {:>8.4f} {:>8.5f} {:>8.4f} {:>10.4f} \n'.format(t_visible[i],sat_alt.degrees[visible][i],sat_az.degrees[visible][i],sat_ra.hours[visible][i],sat_dec.degrees[visible][i],sat_distance.km[visible][i]))
                outfile.write('\n')
            '''
        if not visible_flag:
            outfile0.write('{:s},{:s},{:d}\n\n'.format('', '', noradid))
        else:
            outfile0.write('\n')
        outfile.close()
        print(noradid)
    outfile0.close()
    print('Generate multiple-day visible passes for all targets.')

    # Sort by the start time of the visible passes
    dates, temp = [], []
    VisiblePasses = pd.read_csv(dir_prediction + filename0, dtype=object)
    for date in VisiblePasses[header[0]]:
        if str(date) != 'nan': dates.append(date[:10])
    dates = np.sort(list(set(dates)))
    for date in dates:
        date_flag = VisiblePasses[header[0]].str.contains(date, na=False)
        temp.append(VisiblePasses[date_flag].sort_values(
            by=[header[0]]).append(pd.Series(dtype=object), ignore_index=True))
    if not temp:
        print('No visible passes are found!')
    else:
        pd.concat(temp).to_csv(dir_prediction + 'VisiblePasses_bydate.csv',
                               index=False,
                               mode='w')
    print('Over!')