def main(): ts = load.timescale() t = ts.tt(2018, 1, 22, 9, 9, 20) trial_angles = 10, 20, 30, 40 # the error peaks around 20 degrees trial_elevations = 0, 6000, AU_M print(__doc__) for n in range(1, 5): print('=== {} iterations ==='.format(n)) print('') for elevation_m in trial_elevations: for degrees in trial_angles: top = Topos(latitude_degrees=degrees, longitude_degrees=123, elevation_m=elevation_m) xyz_au = top.at(t).position.au xyz_au = einsum('ij...,j...->i...', t.M, xyz_au) lat, lon, elev = reverse_terra(xyz_au, t.gast, n) lat = lat / DEG2RAD error_mas = 60.0 * 60.0 * 1000.0 * abs(degrees - lat) print('latitude {} degrees, elevation {} m' ' -> error of {:.2f} mas' .format(degrees, elevation_m, error_mas)) print('') print("""\ Given that iterations=3 pushes the maximum error from tens of mas ("mas" means " milli-arcsecond") down to hundredths of a mas, it is the value we have chosen as a default. A fourth iteration, if we ever chose to perform one, pushes the error down to "0.00 mas". """)
def test_bad_subtraction(): planets = load('de421.bsp') earth = planets['earth'] usno = Topos('38.9215 N', '77.0669 W', elevation_m=92.0) with assert_raises(ValueError, 'if they both start at the same center'): earth - usno
ir57 = satellites['IRIDIUM 57 [-]'] ir63 = satellites['IRIDIUM 63 [-]'] ir69 = satellites['IRIDIUM 69 [-]'] ir71 = satellites['IRIDIUM 71 [-]'] ir73 = satellites['IRIDIUM 73 [-]'] ir82 = satellites['IRIDIUM 82 [-]'] ir2 = satellites['IRIDIUM 2 [-]'] ir96 = satellites['IRIDIUM 96 [-]'] iridium = [ ir7, ir5, ir4, ir914, ir16, ir911, ir920, ir921, ir26, ir17, ir22, dm1, dm2, ir29, ir33, ir28, ir36, ir38, ir39, ir42, ir44, ir45, ir24, ir51, ir57, ir63, ir69, ir71, ir73, ir82, ir2, ir96 ] obs = Topos('0 N', '0 W') print('Satelliti considerati') print(ir96) print(ir2) print() ts = load.timescale() t = ts.now() print("Prova con un satellite") print("") ir96pos = ir96.at(t) print() print('Posizioni satelliti considerati')
pid = str(os.getpid()) file("pidfile", 'w').write(pid) lon = config.siteLon lat = config.siteLat planets = load('de421.bsp') body = planets['NEPTUNE_BARYCENTER'] earth = planets['Earth'] while True: ts = load.timescale() t = ts.now() myLocation = earth + Topos(lat, lon) apparent = myLocation.at(t).observe(body).apparent() alt, az, distance = apparent.altaz() print(alt.degrees) print(az.degrees) print(distance) smallAlt = "{0:.2f}".format(alt.degrees) smallAz = "{0:.2f}".format(az.degrees) # Send the position to the arduino. position = "<%s,%s>" % (smallAz, smallAlt) ser = serial.Serial(config.serialPort, config.serialSpeed) ser.write(position) time.sleep(5)
def main(): args = parser.parse_args() satellites = load.tle("https://celestrak.com/NORAD/elements/active.txt") place = Topos(49.2607, 14.6917) _sats_by_name = {sat.name: sat for sat in satellites.values()} soi = _sats_by_name[args.sat] if not (args.dishp or args.print_start or args.print_duration or args.print_end): print_passes(soi, place, args.since, args.ele_th, args.no) return # search for a pass found_pass = pass_search(soi, place, args.since, args.ele_th) if found_pass is not None: start, end, maxele = found_pass found_pass = pass_search( soi, place, start, args.ele_th, search_inc_days=1 / 24 / 60 / 60, horizon_days=1 / 24 / 2, ) if found_pass is not None: start, end, maxele = found_pass print("Found pass between %s and %s with maximum elevation %.1f" % (start.utc_iso(''), end.utc_iso(''), maxele), file=sys.stderr) else: print("No pass found", file=sys.stderr) sys.exit(1) return if args.print_start: print(start.astimezone(pytz.utc).isoformat()) return elif args.print_end: print(end.astimezone(pytz.utc).isoformat()) return elif args.print_duration: print("%.1f" % ((end - start) * 24 * 60 * 60)) return else: pass # dishp points = [] start, end, _ = found_pass relpos = soi - place tt = start.tt while tt < end.tt: t = ts.tt_jd(tt) alt, az, _ = relpos.at(t).altaz() if alt.degrees < 5: tt += 8 / 60 / 60 / 24 continue else: points.append((t, alt.degrees, az.degrees)) tt += 8 / 60 / 60 / 24 ts_ = [t for t, _, _ in points] alts = [alt for _, alt, _ in points] azs = [az for _, _, az in points] good = True for az_start in [-270, -180, -90]: mapped = map_azs(azs, 180, az_start) if azs_continuous(mapped): good = True break if not good: print("No good azimuth mapping into actuator range", file=sys.stderr) sys.exit(1) print("Mapping azimuth into actuator range %d to %d" % (az_start, az_start + 360), file=sys.stderr) if args.mock_start is not None: first = ts_[0] ts_ = [ts.tt_jd(t.tt - first.tt + args.mock_start.tt) for t in ts_] points = zip(ts_, alts, mapped) print("flush") first = True for t, alt, az in points: if first: print("move %.2f %.2f" % ((alt - 5) / 85 * 165 * 100, az * 100)) first = False print("point %d %.2f %.2f" % (t.utc_datetime().timestamp() * 1e6, alt * 100, az * 100)) print("waitidle") print("track") print("waitidle") print("move 0 0") print("waitidle")
planets = load('de421.bsp') earth = planets['earth'] all_planets = [ 'sun', 'mercury', 'venus', 'earth', 'moon', 'mars', 'JUPITER BARYCENTER', 'URANUS BARYCENTER', 'NEPTUNE BARYCENTER', 'PLUTO BARYCENTER' ] stars = [('Polaris', (2, 55, 16), (89, 20, 58)), ('barnard', (17, 57, 48.49803), (4, 41, 36.2072))] # cur_place, _ = get_location() # Todo: Remove comment before release cur_place = DEFAULT_LOCATION # DEBUG ts = load.timescale() t = ts.now() here = earth + Topos(f'{cur_place.latitude} N', f'{cur_place.longitude} E') print('\n\n\n') print(f'{cur_place.city} {cur_place.latitude:.5f}N, {cur_place.longitude:.5f}E\n') print('UTC: ', t.utc_datetime()) tz = timezone('Europe/Lisbon') # tz = timezone('NZ') print('Local:', t.astimezone(tz), '\n') print('\n\nSolar System:') print('=============\n') def is_planet_up(planet, latitude, longitude, time): here = earth + Topos(f'{latitude} N', f'{longitude} E') p = planets[planet]
# alternatively under a commercial licence. # # The terms of the AGPL v3 license can be found in the main directory of this # repository. # Generate a list of ephemerides using Skyfield. # The output of this script is used in the test in src/frame.c from skyfield.api import load from skyfield.api import Topos planets = load('de421.bsp') ts = load.timescale() t = ts.utc(2018, 11, 28, 0, 0, 0) earth = planets['earth'].at(t) atlanta_p = (planets['earth'] + Topos('33.7490 N', '84.3880 W')) atlanta = atlanta_p.at(t) print('TAI = %r' % (t.tai - 2400000.5)) print('TT = %r' % (t.tt - 2400000.5)) print('UT1 = %r' % (t.ut1 - 2400000.5)) def dump_pv(p): print(' {{%.12f, %.12f, %.12f},\n' ' {%.12f, %.12f, %.12f}},' % (p.position.au[0], p.position.au[1], p.position.au[2], p.velocity.au_per_d[0], p.velocity.au_per_d[1], p.velocity.au_per_d[2])) def dump_altazd(p): print(' {%.12f, %.12f, %.12f},' % (p[0].degrees, p[1].degrees, p[2].au))
if isinstance(satellite, str): string_only_satellites.append(satellites[satellite]) #-------------------------------------------# sys.stderr.write("Number of Satellites: %d\n" % len(string_only_satellites)) #Generate random satellite coordinates for player #-------------------------------------------# while True: random_satellite_number = random.randint(0, len(string_only_satellites) - 1) player_satellite_for_input_solver = string_only_satellites[ random_satellite_number] string_only_satellites.pop(random_satellite_number) #Create first topocentric for comparison, testing to ensure satellites are not in a collision path bluffton = Topos('36.17237297 N', '-115.13431754 W') difference = player_satellite_for_input_solver - bluffton #The result will be the position of the satellite relative to you as an observer (bluffton vairable). topocentric = difference.at(t) restart = False for satellite in string_only_satellites: bluffton = Topos('36.17237297 N', '-115.13431754 W') difference = satellite - bluffton #The result will be the position of the satellite relative to you as an observer (bluffton vairable). topocentric2 = difference.at(t) difference_km = (topocentric2 - topocentric).distance().km if difference_km < 10.0: #Another satellite is within 10km
def get_all_passes(tle: [str], lat_deg: float, long_deg: float, start_datetime_utc: datetime, end_datetime_utc: datetime, approved_passes: [OrbitalPass] = None, elev_m: float = 0.0, horizon_deg: float = 0.0, min_duration_s: int = 0) -> [OrbitalPass]: """ Get a list of all passes for a satellite and location for a time span. Wrapper for Skyfield TLE ground station pass functions that produces an OrbitalPass object list of possible passes. Parameters ---------- tle : [str] Can be [tle_line1, tle_line2] or [tle_header, tle_line1, tle_line2] lat_deg : float latitude of ground station in degrees long_deg : float longitude of ground station in degrees start_datetime_utc : datetime The start datetime wanted. end_datetime_utc : datetime The end datetime wanted. approved_passes : [OrbitalPass] A list of OrbitalPass objects for existing approved passes. elev_m : float elevation of ground station in meters horizon_deg : float Minimum horizon degrees min_duration_s : int Minimum duration wanted Raises ------ ValueError If the tle list is incorrect. Returns ------- [OrbitalPass] A list of OrbitalPass. """ pass_list = [] load = Loader('/tmp', verbose=False) ts = load.timescale() t0 = ts.utc(start_datetime_utc.replace(tzinfo=timezone.utc)) t1 = ts.utc(end_datetime_utc.replace(tzinfo=timezone.utc)) # make topocentric object loc = Topos(lat_deg, long_deg, elev_m) loc = Topos(latitude_degrees=lat_deg, longitude_degrees=long_deg, elevation_m=elev_m) # make satellite object from TLE if len(tle) == 2: satellite = EarthSatellite(tle[0], tle[1], "", ts) elif len(tle) == 3: satellite = EarthSatellite(tle[1], tle[2], tle[0], ts) else: raise ValueError("Invalid tle string list\n") # find all events t, events = satellite.find_events(loc, t0, t1, horizon_deg) # make a list of datetimes for passes for x in range(0, len(events)-3, 3): aos_utc = t[x].utc_datetime() los_utc = t[x+2].utc_datetime() duration_s = (los_utc - aos_utc).total_seconds() if duration_s > min_duration_s: new_pass = OrbitalPass(gs_latitude_deg=lat_deg, gs_longitude_deg=long_deg, aos_utc=aos_utc.replace(tzinfo=None), los_utc=los_utc.replace(tzinfo=None), gs_elevation_m=elev_m, horizon_deg=horizon_deg) if not pass_overlap(new_pass, approved_passes): pass_list.append(new_pass) # add pass to list return pass_list
from skyfield.api import load, Topos from skyfield import almanac from datetime import datetime, timedelta from pytz import timezone jkt = timezone('Asia/Jakarta') ts = load.timescale(builtin=True) e = load('de421.bsp') lat = 7 + (49 / 60) + (59 / 3600) long = 110 + (22 / 60) + (49 / 3600) lat = str(lat) + ' S' long = str(long) + ' E' topos = Topos(lat, long) t0 = ts.utc(2021, 1, 15, -7) t1 = ts.utc(2021, 1, 20, -7) f = almanac.sunrise_sunset(e, topos) t, y = almanac.find_discrete(t0, t1, f) for ti, yi in zip(t, y): print(ti.astimezone(jkt), yi)
from spacetrack import SpaceTrackClient from skyfield.api import EarthSatellite, Topos, load from .stconfig.auth import USR, PASS if __name__ == "__main__": st = SpaceTrackClient(USR, PASS) tlelines = [st.tle_latest(norad_cat_id=45438)[0]["TLE_LINE1"], st.tle_latest(norad_cat_id=45438)[0]["TLE_LINE2"]] bcn = Topos(41.414850, 2.165036) ts = load.timescale() t0 = ts.utc(2020,12,23) t1 = ts.utc(2020,12,30) satellite = EarthSatellite(*tlelines, "STARKLINK-61", ts) t, events = satellite.find_events(bcn, t0, t1, altitude_degrees=30.0) for ti, event in zip(t, events): name = ('aos @ 30°', 'culminate', 'los @ < 30°')[event] if (ti.utc.hour >18 ):#and (event == 0): print(ti.utc_strftime('%Y %b %d %H:%M:%S'), name) difference = satellite - bcn topocentric = difference.at(ti) alt, az, distance = topocentric.altaz() print(" ",alt) print(" ",az) print(" ",int(distance.km), 'km')
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)
from skyfield.api import load, Topos from skyfield.units import Angle from datetime import datetime from pytz import timezone jkt = timezone('Asia/Jakarta') ts = load.timescale(builtin=True) e = load('de421.bsp') lat = 7 + (49 / 60) + (59 / 3600) long = 110 + (22 / 60) + (59 / 3600) print(lat) lat = str(lat) + ' S' print(lat) lat = '5.89383333333333 N' long = '95.324 E' # t = jkt.localize(datetime(2020, 1, 1, 0, 0, 0)) topo = Topos(lat, long) loc = e['earth'] + topo print(topo) for d in range(1): t0 = ts.utc(2020, 8 + d, 19, 18 - 7, 50, 55) astrometric = loc.at(t0).observe(e['moon']) alt, az, d = astrometric.apparent().altaz() alt = str(alt).replace('deg ', ':').replace('\' ', ':').replace('"', '') az = str(az).replace('deg ', ':').replace('\' ', ':').replace('"', '') print(alt, az)
def index(request): stars = [] if request.body: req = json.loads(request.body) if req['type'] == 'GET_VISIBLE_STARS': planets = load('de421.bsp') earth = planets['earth'] ts = load.timescale() dt = datetime.strptime(req['date'], '%Y-%m-%dT%H:%M:%S.%fZ') dt = dt.replace(tzinfo=timezone.utc) t = ts.utc(dt) observerLocation = earth + \ Topos(latitude_degrees=req['lat'], longitude_degrees=req['long']) with load.open(hipparcos.URL) as f: df = hipparcos.load_dataframe(f) for key in navigationStarsHip: starname = key hipNo = navigationStarsHip[key] star = Star.from_dataframe(df.loc[hipNo]) apparent = observerLocation.at(t).observe(star).apparent() alt, az, dist = apparent.altaz() eachStar = { 'name': key, 'hip': navigationStarsHip[key], 'alt': alt.degrees, 'az': az.degrees, 'dist': dist.km } if eachStar['alt'] > 0 : stars.append(eachStar) if req['type'] == 'GET_TBRG_STAR': planets = load('de421.bsp') earth = planets['earth'] ts = load.timescale() dt = datetime.strptime(req['date'], '%Y-%m-%dT%H:%M:%S.%fZ') dt = dt.replace(tzinfo=timezone.utc) t = ts.utc(dt) observerLocation = earth + \ Topos(latitude_degrees=req['lat'], longitude_degrees=req['long']) with load.open(hipparcos.URL) as f: df = hipparcos.load_dataframe(f) starname = req['selectedStar'] hipNo = navigationStarsHip[starname] star = Star.from_dataframe(df.loc[hipNo]) apparent = observerLocation.at(t).observe(star).apparent() alt, az, dist = apparent.altaz() return JsonResponse({ 'name': starname, 'hipNo': navigationStarsHip[starname], 'alt': alt.degrees, 'az': az.degrees, 'dist': dist.km }) if (req['type'] == 'GET_TBRG_PLANET'): planets = load('de421.bsp') earth = planets['earth'] ts = load.timescale() dt = datetime.strptime(req['date'], '%Y-%m-%dT%H:%M:%S.%fZ') dt = dt.replace(tzinfo=timezone.utc) t = ts.utc(dt) observerLocation = earth + \ Topos(latitude_degrees=req['lat'], longitude_degrees=req['long']) planet = planets[req['body']] apparent = observerLocation.at(t).observe(planet).apparent() alt, az, dist = apparent.altaz() return JsonResponse({ "alt": alt.degrees, "az": az.degrees, "dist": dist.km })
ts = load.timescale() # Load the given TLE and 'create' a satellite line1 = '1 13337U 98067A 20087.38052801 -.00000452 00000-0 00000+0 0 9995' line2 = '2 13337 51.6460 33.2488 0005270 61.9928 83.3154 15.48919755219337' satellite = EarthSatellite(line1, line2, 'REDACT', ts) print(satellite) #Set the time (not sure if the hrs min sec are right order?) t = ts.utc(2020, 3, 26, 21, 52, 52) geocentric = satellite.at(t) #x,y,z coordinates print(geocentric.position.km) #position above the earth subpoint = geocentric.subpoint() print('Latitude:', subpoint.latitude) print('Longitude:', subpoint.longitude) print('Elevation (m):', int(subpoint.elevation.m)) #tropocentric (from where we are, the Wash Monument) dc = Topos('38.88948 N', '77.03528 W') difference = satellite - dc geometry = difference.at(t) topocentric = difference.at(t) alt, az, distance = topocentric.altaz() print('elevation = ', alt) print('azimuth = ', az) print('distance km = ', distance.km)
planets = load('de421.bsp') # p = ['mercury', 'venus', 'mars', p = []#'jupiter barycenter', 'saturn barycenter'] for i, p_ in enumerate(p): p[i] = planets[p_] earth, mars = planets['earth'], planets['mars'] betelgeuse = skyfield.api.NamedStar('Betelgeuse') p.append(betelgeuse) polaris = skyfield.api.NamedStar('Polaris') p.append(polaris) ts = load.timescale() from skyfield.api import Topos PRINCETON_EARTH = Topos('40.3440 N', '74.6514 W') princeton = earth + PRINCETON_EARTH ax = plt.subplot(111, projection='3d') ax.set_aspect('equal') ax.set_xlim([-1.0,1.0]) ax.set_ylim([-1.0,1.0]) ax.set_zlim([-1.0,1.0]) alt__ = np.repeat([0.0], 20) az__ = np.arange(0.0, 2*np.pi, 2.0/20.0*np.pi) ax.plot(*altaz_to_spherical(alt__, az__)) ax.plot(*altaz_to_spherical(az__, alt__)) ax.plot(*altaz_to_spherical(az__, alt__ + np.pi/2.0))
#!/usr/bin/env python from skyfield.positionlib import ICRF from skyfield.api import load, Topos ts = load.timescale() t = ts.now() observer = Topos(latitude_degrees=52.8344, longitude_degrees=6.3785, elevation_m=10.0) p = ICRF([0.0, 0.0, 0.0], observer_data=observer, t=t) q = p.from_altaz(alt_degrees=30.0, az_degrees=30.0) print(p, q)
def location(self): return self.earth + Topos(self.lat, self.long)
def getSatMWA(line1, line2, line3): ts = load.timescale() satellite = EarthSatellite(line2, line3, line1, ts) mwa = Topos("26.701276778 S", "116.670846137 E", elevation_m=377.827) return satellite, mwa, ts
def compute_visible_passes(UTC_array, obj_id_list, sensor_id_list, ephemeris, tle_dict={}): ''' This function computes the visible passes for a given list of resident space objects (RSOs) from one or more sensors. Output includes the start and stop times of each pass, as well as the time of closest approach (TCA) and time of maximum elevation (TME). Parameters ------ UTC_array : 1D numpy array times to compute visibility conditions stored as skyfield time objects that can be extracted in multiple time systems or representations obj_id_list : list object NORAD IDs (int) sensor_id_list : list sensor IDs (str) ephemeris : skyfield object contains data about sun, moon, and planets loaded from skyfield Returns ------ vis_dict : dictionary contains sorted lists of pass start and stop times for each object and sensor, as well as TCA and TME times, and maximum elevation angle and minimum range to the RSO during the pass ''' # Constants Re = ERAD / 1000. # km # Generate resident space object dictionary rso_dict = define_RSOs(obj_id_list, tle_dict) # Load sensor data # Include options here to load from file, URL, graph database, ... # Load from script sensor_dict = define_sensors() # Remove sensors not in list sensor_remove_list = list(set(sensor_dict.keys()) - set(sensor_id_list)) for sensor_id in sensor_remove_list: sensor_dict.pop(sensor_id, None) # Instantiate a skyfield object for each sensor in list for sensor_id in sensor_dict.keys(): geodetic_latlonht = sensor_dict[sensor_id]['geodetic_latlonht'] lat = geodetic_latlonht[0] lon = geodetic_latlonht[1] elevation_m = geodetic_latlonht[2] * 1000. statTopos = Topos(latitude_degrees=lat, longitude_degrees=lon, elevation_m=elevation_m) sensor_dict[sensor_id]['statTopos'] = statTopos # Retrieve sun and moon positions for full timespan earth = ephemeris['earth'] sun = ephemeris['sun'] moon = ephemeris['moon'] moon_gcrf_array = earth.at(UTC_array).observe(moon).position.km sun_gcrf_array = earth.at(UTC_array).observe(sun).position.km # Initialize output start_list_all = [] stop_list_all = [] TCA_list_all = [] TME_list_all = [] rg_min_list_all = [] el_max_list_all = [] obj_id_list_all = [] sensor_id_list_all = [] # Loop over RSOs for obj_id in rso_dict: rso = rso_dict[obj_id] rso_gcrf_array = rso['satellite'].at(UTC_array).position.km # Retrieve object size and albedo if available/needed radius_km = rcs2radius_meters(rso['rcs_m2']) / 1000. # Loop over sensors for sensor_id in sensor_dict: sensor = sensor_dict[sensor_id] sensor_gcrf_array = sensor['statTopos'].at(UTC_array).position.km # Constraint parameters el_lim = sensor['el_lim'] az_lim = sensor['az_lim'] rg_lim = sensor['rg_lim'] sun_elmask = sensor['sun_elmask'] mapp_lim = sensor['mapp_lim'] moon_angle_lim = sensor['moon_angle_lim'] # Compute topocentric RSO position # For earth satellites, calling observe and apparent is costly # and unnecessary except for meter level accuracy difference = rso['satellite'] - sensor['statTopos'] rso_topo = difference.at(UTC_array) el_array, az_array, rg_array = rso_topo.altaz() # Compute topocentric sun position # Need both sun and sensor positions referenced from solar # system barycenter sensor_ssb = earth + sensor['statTopos'] sun_topo = sensor_ssb.at(UTC_array).observe(sun).apparent() sun_el_array, sun_az_array, sun_rg_array = sun_topo.altaz() # Find indices where az/el/range constraints are met el_inds0 = np.where(el_array.radians > el_lim[0])[0] el_inds1 = np.where(el_array.radians < el_lim[1])[0] az_inds0 = np.where(az_array.radians > az_lim[0])[0] az_inds1 = np.where(az_array.radians < az_lim[1])[0] rg_inds0 = np.where(rg_array.km > rg_lim[0])[0] rg_inds1 = np.where(rg_array.km < rg_lim[1])[0] # Check sun constraint (ensures station is dark if needed) sun_el_inds = np.where(sun_el_array.radians < sun_elmask)[0] # Find all common elements to create candidate visible index list common_el = set(el_inds0).intersection(set(el_inds1)) common_az = set(az_inds0).intersection(set(az_inds1)) common_rg = set(rg_inds0).intersection(set(rg_inds1)) common1 = common_el.intersection(common_az) common2 = common1.intersection(common_rg) common_inds = list(common2.intersection(set(sun_el_inds))) # Initialze visibility array for this sensor and object vis_array = np.zeros(rso_gcrf_array.shape[1], ) vis_array[common_inds] = True # For remaining indices compute angles and visibility conditions for ii in common_inds: rso_gcrf = rso_gcrf_array[:, ii] sensor_gcrf = sensor_gcrf_array[:, ii] sun_gcrf = sun_gcrf_array[:, ii] moon_gcrf = moon_gcrf_array[:, ii] rg_km = rg_array.km[ii] # Compute angles phase_angle, sun_angle, moon_angle = \ compute_angles(rso_gcrf, sun_gcrf, moon_gcrf, sensor_gcrf) # Check for eclipse - if sun angle is less than half cone angle # the sun is behind the earth # First check valid orbit - radius greater than Earth radius r = np.linalg.norm(rso_gcrf) if r < Re: vis_array[ii] = False else: half_cone = asin(Re / r) if sun_angle < half_cone: vis_array[ii] = False # Check too close to moon if moon_angle < moon_angle_lim: vis_array[ii] = False # Check apparent magnitude # Optional input for albedo could be retrieved for each object # from catalog mapp = compute_mapp(phase_angle, rg_km, radius_km) if mapp > mapp_lim: vis_array[ii] = False vis_inds = np.where(vis_array)[0] UTC_vis = UTC_array[vis_inds] rg_vis = rg_array.km[vis_inds] el_vis = el_array.radians[vis_inds] # Compute pass start and stop times start_list, stop_list, TCA_list, TME_list, rg_min_list, el_max_list = \ compute_pass(UTC_vis, rg_vis, el_vis, sensor) # Store output npass = len(start_list) start_list_all.extend(start_list) stop_list_all.extend(stop_list) TCA_list_all.extend(TCA_list) TME_list_all.extend(TME_list) rg_min_list_all.extend(rg_min_list) el_max_list_all.extend(el_max_list) obj_id_list_all.extend([obj_id] * npass) sensor_id_list_all.extend([sensor_id] * npass) # Sort results start_list_JD = [ti.tdb for ti in start_list_all] sort_ind = np.argsort(start_list_JD) sorted_start = [start_list_all[ii] for ii in sort_ind] sorted_stop = [stop_list_all[ii] for ii in sort_ind] sorted_TCA = [TCA_list_all[ii] for ii in sort_ind] sorted_TME = [TME_list_all[ii] for ii in sort_ind] sorted_rg_min = [rg_min_list_all[ii] for ii in sort_ind] sorted_el_max = [el_max_list_all[ii] for ii in sort_ind] sorted_obj_id = [obj_id_list_all[ii] for ii in sort_ind] sorted_sensor_id = [sensor_id_list_all[ii] for ii in sort_ind] # Final output vis_dict = {} vis_dict['start_list'] = sorted_start vis_dict['stop_list'] = sorted_stop vis_dict['TCA_list'] = sorted_TCA vis_dict['TME_list'] = sorted_TME vis_dict['rg_min_list'] = sorted_rg_min vis_dict['el_max_list'] = sorted_el_max vis_dict['obj_id_list'] = sorted_obj_id vis_dict['sensor_id_list'] = sorted_sensor_id return vis_dict
satellite = EarthSatellite(line1, line2) print(satellite.epoch.utc_jpl()) ts = load.timescale() # run the simulation for 1 day durationSim = 1.0 tStart = satellite.epoch tEnd = ts.tt(jd=(tStart.tt + durationSim)) # Get object state vector at time of breakup # Use the time 12.5% into the evaluation period tBreakup = ts.tt(jd=(tStart.tt + ((tEnd.tt - tStart.tt) / 8))) sensor = Topos('0.0 N', '0.0 W') difference = satellite - sensor print(difference) # Start and end times topocentric = difference.at(tBreakup) alt, az, distance = topocentric.altaz() # Simulate a number of pieces that are ejected randomly from the main body nPieces = 4 nTimeSteps = 10 timeStep = 100 ejectionVelocity = 0.4 # km/sec geocentric = satellite.at(tBreakup) r = geocentric.position
# If ISS TLE is more than 7 days old, reload it days = t - satellite.epoch if abs(days) > 7: satellites = load.tle(stations_url, reload=True) satellite = satellites['ISS (ZARYA)'] # Time array at which to calculate the position of ISS # Cadence set to 20 seconds, currently t_steps = np.arange(0, (60 * 60 * 24), 20) time_range = ts.utc(int(year), int(month), int(day), int(hour), int(minute), t_steps) # Lat Lon of Coffs Harbour lat_lon = Topos('-30.2986 N', '153.1094 E') orbit = (satellite - lat_lon).at(time_range) alt, az, _ = orbit.altaz() # Check if sat is above the horizon, return boolean array above_horizon = alt.degrees >= 0 # Indicies of rare times that sats are above the horizon indicies, = above_horizon.nonzero() # Boundary times at which the sat either rises or sets boundaries, = np.diff(above_horizon).nonzero() if above_horizon[0] == True: boundaries = [indicies[0]] + list(boundaries)
t = ts.utc(2020, 3, 26, 21, 52, 43) # March 26th, 2020, at 21:52:43 geocentric = satellite.at(t) print(f'{ geocentric.position.m=}') subpoint = geocentric.subpoint() print(f'{subpoint.latitude.degrees=}') print(f'{subpoint.longitude.degrees=}') print(f'{subpoint.elevation.m=}') same_pos, same_vel = terra( subpoint.latitude.radians, subpoint.longitude.radians, subpoint.elevation.au, geocentric.t.gast, ) same_pos *= AU_M print(f'{same_pos=}') monument = Topos('38.8894541 N', '77.0373601 W') print(f'{monument=}') monument_pos, _ = terra( monument.latitude.radians, monument.longitude.radians, 0, geocentric.t.gast, ) monument_pos *= AU_M print(f'{monument_pos=}') # range = np.linalg.norm(geocentric.position.m - monument_pos) # tilt = angle(geocentric.position.m - monument_pos, monument_pos) north_pole_pos, _ = terra( 90 * DEG2RAD, 135 * DEG2RAD, 0,
def test_positions_skyfield(tmpdir): """ Test positions against those generated by skyfield. """ load = Loader(tmpdir) t = Time('1980-03-25 00:00') location = None # skyfield ephemeris try: planets = load('de421.bsp') ts = load.timescale() except OSError as e: if os.environ.get('CI', False) and 'timed out' in str(e): pytest.xfail('Timed out in CI') else: raise mercury, jupiter, moon = planets['mercury'], planets['jupiter barycenter'], planets['moon'] earth = planets['earth'] skyfield_t = ts.from_astropy(t) if location is not None: earth = earth+Topos(latitude_degrees=location.lat.to_value(u.deg), longitude_degrees=location.lon.to_value(u.deg), elevation_m=location.height.to_value(u.m)) skyfield_mercury = earth.at(skyfield_t).observe(mercury).apparent() skyfield_jupiter = earth.at(skyfield_t).observe(jupiter).apparent() skyfield_moon = earth.at(skyfield_t).observe(moon).apparent() if location is not None: frame = TETE(obstime=t, location=location) else: frame = TETE(obstime=t) ra, dec, dist = skyfield_mercury.radec(epoch='date') skyfield_mercury = SkyCoord(ra.to(u.deg), dec.to(u.deg), distance=dist.to(u.km), frame=frame) ra, dec, dist = skyfield_jupiter.radec(epoch='date') skyfield_jupiter = SkyCoord(ra.to(u.deg), dec.to(u.deg), distance=dist.to(u.km), frame=frame) ra, dec, dist = skyfield_moon.radec(epoch='date') skyfield_moon = SkyCoord(ra.to(u.deg), dec.to(u.deg), distance=dist.to(u.km), frame=frame) # planet positions w.r.t true equator and equinox moon_astropy = get_moon(t, location, ephemeris='de430').transform_to(frame) mercury_astropy = get_body('mercury', t, location, ephemeris='de430').transform_to(frame) jupiter_astropy = get_body('jupiter', t, location, ephemeris='de430').transform_to(frame) assert (moon_astropy.separation(skyfield_moon) < skyfield_angular_separation_tolerance) assert (moon_astropy.separation_3d(skyfield_moon) < skyfield_separation_tolerance) assert (jupiter_astropy.separation(skyfield_jupiter) < skyfield_angular_separation_tolerance) assert (jupiter_astropy.separation_3d(skyfield_jupiter) < skyfield_separation_tolerance) assert (mercury_astropy.separation(skyfield_mercury) < skyfield_angular_separation_tolerance) assert (mercury_astropy.separation_3d(skyfield_mercury) < skyfield_separation_tolerance)
def compute_body_angle(self, body, jsec, lon, lat): t = self.timescale.utc(jsec_to_datetime(jsec).replace(tzinfo=utc)) loc = self.planets["earth"] + Topos(lat, lon) astrometric = loc.at(t).observe(self.planets[body]) alt, az, d = astrometric.apparent().altaz() return az.degrees, alt.degrees
from skyfield.api import load, Topos, Star from skyfield.data import hipparcos, mpc from astropy import units from datetime import datetime from pytz import timezone import drawSvg as draw import numpy as np import math ts = load.timescale() ephem = load('de421.bsp') cet = timezone('CET') sun, moon, earth = ephem['sun'], ephem['moon'], ephem['earth'] amsterdam = Topos('52.3679 N', '4.8984 E') amstercentric = earth + amsterdam t0 = ts.now() t1 = ts.tt_jd(t0.tt + 1) nu = t0.utc_datetime().astimezone(cet).time().strftime('%H:%M') mindist=1.5 from skyfield.constants import GM_SUN_Pitjeva_2005_km3_s2 as GM_SUN with load.open(mpc.COMET_URL,reload=True) as f: comets = mpc.load_comets_dataframe(f) print('Found ',len(comets), ' comets') comets = (comets.sort_values('reference') .groupby('designation', as_index=False).last() .set_index('designation', drop=False)) f = open('cometlist.txt', 'w')
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!')
from skyfield.api import load, Topos, EarthSatellite, Star from almanac2 import seasons, moon_phases, meridian_transits, culminations, twilights, risings_settings ts = load.timescale() ephem = load('de430t.bsp') earth = ephem['earth'] sun = ephem['sun'] moon = ephem['moon'] mars = ephem['mars barycenter'] greenwich = earth + Topos(latitude_degrees=(51, 28, 40), longitude_degrees=(0, 0, -5)) iss_tle = """\ 1 25544U 98067A 18161.85073725 .00003008 00000-0 52601-4 0 9993 2 25544 51.6418 50.3007 0003338 171.6979 280.7366 15.54163173117534 """ ISS = EarthSatellite(*iss_tle.splitlines()) sirius = Star(ra_hours=(6, 45, 8.91728), dec_degrees=(-16, 42, 58.0171)) t0 = ts.utc(2017, 1, 1) t1 = ts.utc(2017, 1, 8) # Equinoxes and Solstices season_times, lons = seasons(earth, ts.utc(2000), ts.utc(2026)) # Moon Phases phase_times, lon_diffs = moon_phases(moon, ts.utc(2018, 1), ts.utc(2018, 2))
def _vec(self): return Topos(latitude_degrees=float(self.latitude), longitude_degrees=float(self.longitude), elevation_m=float(self.elevation))
def galactic_Sun_north_center_SD_directions( measurement_date, sec_of_day, user_longlatdist=geographic_position, prints=False): user_longlatdist = np.array(user_longlatdist) with load.open(hipparcos.URL) as f: df = hipparcos.load_dataframe(f) planets = load('de421.bsp') earth = planets['earth'] user_position = earth + Topos( '{} N'.format(user_longlatdist[0]), '{} E'.format(user_longlatdist[1]) ) #user_longlatdist user_longlatdist[0],user_longlatdist[1] terrestrial_time = format_time_auto_from_days_sec(measurement_date, sec_of_day) ts = load.timescale() # tt_ = ts.tt(terrestrial_time[0], terrestrial_time[1], terrestrial_time[2], terrestrial_time[3], terrestrial_time[4], terrestrial_time[5]) t = ts.utc(terrestrial_time[0], terrestrial_time[1], terrestrial_time[2], terrestrial_time[3], terrestrial_time[4], terrestrial_time[5]) sun = planets['sun'] astrometric_sun = user_position.at(t).observe(sun) alt_sun, az_sun, distance_sun = astrometric_sun.apparent().altaz( ) #astrometric.apparent().altaz() = astrometric_denebola.apparent().altaz() sun_position = pm.aer2ecef(az_sun.degrees, alt_sun.degrees, distance_sun.m, user_longlatdist[0], user_longlatdist[1], user_longlatdist[2]) # Északi Galaktikus Pólus (RA: 12h 51.42m; D: 27° 07.8′, epocha J2000.0) coma_berenices = Star(ra_hours=(12, 51, 25.2), dec_degrees=(27, 7, 48.0)) astrometric_berenice = user_position.at(t).observe(coma_berenices) alt_b, az_b, distance_b = astrometric_berenice.apparent().altaz() berenice_position = pm.aer2ecef(az_b.degrees, alt_b.degrees, distance_b.m, user_longlatdist[0], user_longlatdist[1], user_longlatdist[2]) # Galaktikus Center (RA: 12h 51.42m; D: 27° 07.8′, epocha J2000.0) 17h 45.6m −28.94° galactic_center = Star(ra_hours=(17, 45, 36.0), dec_degrees=(-28, 56, 24.0)) astrometric_center = user_position.at(t).observe(galactic_center) alt_c, az_c, distance_c = astrometric_center.apparent().altaz() center_position = pm.aer2ecef(az_c.degrees, alt_c.degrees, distance_c.m, user_longlatdist[0], user_longlatdist[1], user_longlatdist[2]) nunki = Star.from_dataframe(df.loc[92855]) astrometric_nunki = user_position.at(t).observe(nunki) alt_n, az_n, distance_n = astrometric_nunki.apparent().altaz( ) #astrometric.apparent().altaz() = astrometric_denebola.apparent().altaz() star_pos_n = pm.aer2ecef(az_n.degrees, alt_n.degrees, distance_n.m, user_longlatdist[0], user_longlatdist[1], user_longlatdist[2]) capella = Star.from_dataframe(df.loc[24608]) astrometric_capella = user_position.at(t).observe(capella) alt_ca, az_ca, distance_ca = astrometric_capella.apparent().altaz( ) #astrometric.apparent().altaz() = astrometric_denebola.apparent().altaz() star_pos_ca = pm.aer2ecef(az_ca.degrees, alt_ca.degrees, distance_ca.m, user_longlatdist[0], user_longlatdist[1], user_longlatdist[2]) denebola = Star.from_dataframe(df.loc[57632]) astrometric_denebola = user_position.at(t).observe(denebola) alt_d, az_d, distance_d = astrometric_denebola.apparent().altaz( ) #astrometric.apparent().altaz() = astrometric_denebola.apparent().altaz() star_pos_d = pm.aer2ecef(az_d.degrees, alt_d.degrees, distance_d.m, user_longlatdist[0], user_longlatdist[1], user_longlatdist[2]) sadalmelik = Star.from_dataframe(df.loc[109074]) astrometric_sadalmelik = user_position.at(t).observe(sadalmelik) alt_s, az_s, distance_s = astrometric_sadalmelik.apparent().altaz() star_pos_s = pm.aer2ecef(az_s.degrees, alt_s.degrees, distance_s.m, user_longlatdist[0], user_longlatdist[1], user_longlatdist[2]) if prints: print( np.array(terrestrial_time).astype("int"), ' ', t.utc_strftime( format='%Y-%m-%d %H:%M:%S UTC')) #, ' ', tt_.tt_calendar()) print('Time: ', np.array(terrestrial_time).astype("int")) print('Location: ', '{} N'.format(user_longlatdist[0]), '{} E'.format(user_longlatdist[1])) print('Sun (alt/az): ', alt_sun, az_sun) print('Coma Berenice (alt/az): ', alt_b, az_b) print('Galactic Center (alt/az): ', alt_c, az_c) print('Nunki (alt/az): ', alt_n, az_n) print('Capella (alt/az): ', alt_ca, az_ca) print('Denebola (alt/az): ', alt_d, az_d) print('Sadalmelik (alt/az): ', alt_s, az_s) stars_pos = [ sun_position, berenice_position, center_position, star_pos_n, star_pos_ca, star_pos_d, star_pos_s ] return stars_pos
# Write pid to file pid = str(os.getpid()) file("pidfile", 'w').write(pid) lon = config.siteLon lat = config.siteLat stations_url = 'http://celestrak.com/NORAD/elements/stations.txt' satellites = load.tle(stations_url) satellite = satellites['ISS (ZARYA)'] planets = load('de421.bsp') earth = planets['Earth'] myLocation = Topos(lat, lon) while True: ts = load.timescale() t = ts.now() difference = satellite - myLocation topocentric = difference.at(t) alt, az, distance = topocentric.altaz() print(alt.degrees) print(az.degrees) print(distance) smallAlt = "{0:.2f}".format(alt.degrees) smallAz = "{0:.2f}".format(az.degrees)