def rise_set_yydoy(df_tle: pd.DataFrame, yydoy: str, dir_tle: str, logger: logging.Logger) -> pd.DataFrame: """ rise_set_yydoy calculates the rise/set times for GNSS PRNs """ cFuncName = colored(os.path.basename(__file__), 'yellow') + ' - ' + colored(sys._getframe().f_code.co_name, 'green') # get the datetime that corresponds to yydoy date_yydoy = datetime.strptime(yydoy, '%y%j') logger.info('{func:s}: calculating rise / set times for {date:s} ({yy:s}/{doy:s})'.format(date=colored(date_yydoy.strftime('%d-%m-%Y'), 'green'), yy=yydoy[:2], doy=yydoy[2:], func=cFuncName)) # load a time scale and set RMA as Topo # loader = sf.Loader(dir_tle, expire=True) # loads the needed data files into the tle dir ts = sf.load.timescale() RMA = sf.Topos('50.8438 N', '4.3928 E') logger.info('{func:s}: Earth station RMA = {topo!s}'.format(topo=colored(RMA, 'green'), func=cFuncName)) t0 = ts.utc(int(date_yydoy.strftime('%Y')), int(date_yydoy.strftime('%m')), int(date_yydoy.strftime('%d'))) date_tomorrow = date_yydoy + timedelta(days=1) t1 = ts.utc(int(date_tomorrow.strftime('%Y')), int(date_tomorrow.strftime('%m')), int(date_tomorrow.strftime('%d'))) # go over the PRN / NORADs that have TLE corresponding to the requested date for row, prn in enumerate(df_tle['PRN']): logger.info('{func:s}: for NORAD {norad:s} ({prn:s})'.format(norad=colored(df_tle['NORAD'][row], 'green'), prn=colored(prn, 'green'), func=cFuncName)) # create a EarthSatellites from the TLE lines for this PRN gnss_sv = EarthSatellite(df_tle['TLE1'][row], df_tle['TLE2'][row]) logger.info('{func:s}: created earth satellites {sat!s}'.format(sat=colored(gnss_sv, 'green'), func=cFuncName)) t, events = gnss_sv.find_events(RMA, t0, t1, altitude_degrees=5.0) for ti, event in zip(t, events): name = ('rise above 5d', 'culminate', 'set below 5d')[event] logger.info('{func:s}: {jpl!s} -- {name!s}'.format(jpl=ti.utc_jpl(), name=name, func=cFuncName))
def test_iss_against_horizons(): ts = api.load.timescale() s = EarthSatellite(*iss_tle0.splitlines()) hp = array([ [2.633404251158200E-5, 1.015087620439817E-5, 3.544778677556393E-5], [-2.136440257814821E-5, -2.084170814514480E-5, -3.415494123796893E-5], ]).T hv = array([ [-1.751248694205384E-3, 4.065407557020968E-3, 1.363540232307603E-4], [2.143876266215405E-3, -3.752167957502106E-3, 9.484159290242074E-4], ]).T two_meters = 2.0 / AU_M three_km_per_hour = 3.0 * 24.0 / AU_KM t = ts.tdb(2018, 7, 4) p = s.at(t) assert abs(p.position.au - hp[:, 0]).max() < two_meters assert abs(p.velocity.au_per_d - hv[:, 0]).max() < three_km_per_hour t = ts.tdb(2018, 7, [4, 5]) p = s.at(t) assert abs(p.position.au - hp).max() < two_meters assert abs(p.velocity.au_per_d - hv).max() < three_km_per_hour
def test_iss_against_horizons(): ts = api.load.timescale() s = EarthSatellite(*iss_tle0.splitlines()) hp = array([ [2.633404251158200E-5, 1.015087620439817E-5, 3.544778677556393E-5], [-2.136440257814821E-5, -2.084170814514480E-5, -3.415494123796893E-5], ]).T hv = array([ [-1.751248694205384E-3, 4.065407557020968E-3, 1.363540232307603E-4], [2.143876266215405E-3, -3.752167957502106E-3, 9.484159290242074E-4], ]).T two_meters = 2.0 / AU_M three_km_per_hour = 3.0 * 24.0 / AU_KM t = ts.tdb(2018, 7, 4) p = s.at(t) assert (abs(p.position.au - hp[:,0]) < two_meters).all() assert (abs(p.velocity.au_per_d - hv[:,0]) < three_km_per_hour).all() t = ts.tdb(2018, 7, [4, 5]) p = s.at(t) assert (abs(p.position.au - hp) < two_meters).all() assert (abs(p.velocity.au_per_d - hv) < three_km_per_hour).all()
def compare(line1_1, line1_2, line2_1, line2_2, timestamp_min, timestamps, td): ts = load.timescale() satrec1 = Satrec.twoline2rv(line1_1, line1_2) satrec2 = Satrec.twoline2rv(line2_1, line2_2) satellite1 = EarthSatellite.from_satrec(satrec1, ts) satellite2 = EarthSatellite.from_satrec(satrec2, ts) residual = 0 number_of_measurements = 0 for s in range(len(timestamps)): number_of_measurements += len(timestamps[s]) for t0 in range(len(timestamps[s])): time_step = timestamps[s][t0] timestamp1 = timestamp_min + time_step + td[s] observing_time = Time(timestamp1, format="unix", scale="utc") t = ts.from_astropy(observing_time) R1 = satellite1.at(t).position.km R2 = satellite2.at(t).position.km distance = ((R1[0] - R2[0])**2 + (R1[1] - R2[1])**2 + (R1[2] - R2[2])**2)**0.5 residual += distance return residual / number_of_measurements
def compute_orbit_track(tle_data, p_start_date, p_end_date, p_step): # calculate time interval in minutes from inputs date_time_1 = mission_timer_to_datetime(p_start_date) date_time_2 = mission_timer_to_datetime(p_end_date) running_date = date_time_1 ts = load.timescale() satellite = EarthSatellite(tle_data["line_1"], tle_data["line_2"], "Satellite", ts) result = [] while running_date < date_time_2: running_date = running_date + timedelta(0, p_step) time_data = datetime_to_mission_timer(running_date) time_instant = ts.utc( time_data["year"], time_data["month"], time_data["day"], time_data["hour"], time_data["min"], time_data["sec"], ) geocentric = satellite.at(time_instant) subpoint = geocentric.subpoint() data = { "timestamp": running_date, "lat": float(subpoint.latitude.degrees), "lng": float(subpoint.longitude.degrees), "alt": float(subpoint.elevation.km), } result.append(data) return result
def __init__(self, lat, lon, norad_id=None, horizon=10.0): self.eph = skyfield_load("de421.bsp") self.timescale = skyfield_load.timescale() self.horizon = horizon tle = get_tle(norad_id) self.observer = Topos(latitude_degrees=lat, longitude_degrees=lon) self.satellite = EarthSatellite(tle[1], tle[2], tle[0], self.timescale)
def test_appendix_c_satellite(): lines = appendix_c_example.splitlines() ts = api.load.timescale() sat = EarthSatellite(lines[1], lines[2], lines[0], ts) t = ts.tt_jd(sat.epoch.whole + 3.0, sat.epoch.tt_fraction) # First, a crucial sanity check (which is, technically, a test of # the `sgp4` package and not of Skyfield): are the right coordinates # being produced by our Python SGP4 propagator for this satellite? rTEME, vTEME, error = sat._position_and_velocity_TEME_km(t) # TODO: This used to be accurate to within 1e-8 but lost precision # with the move to SGP4 2.0. Is the difference an underlying change # in the algorithm and its results? Or something else? epsilon = 1e-4 assert abs(-9060.47373569 - rTEME[0]) < epsilon assert abs(4658.70952502 - rTEME[1]) < epsilon assert abs(813.68673153 - rTEME[2]) < epsilon # TODO: Similar to the above, this used to be 1e-9. Then the Time # object started storing UTC as seconds, and it got worse. epsilon = 5e-8 assert abs(-2.232832783 - vTEME[0]) < epsilon assert abs(-4.110453490 - vTEME[1]) < epsilon assert abs(-3.157345433 - vTEME[2]) < epsilon
def sat_position(satname, dbid=0, ref="eci"): """ Satellite position in eci and lat,lon """ ## get sat since_last_update = (time.time() - os.stat("celestrak.txt").st_ctime) / 3600.00 ## if file is greater then 8 hrs. Get new tle file if since_last_update > 3600 * 8.0: _, name = get_sat_data() if "no_file" in name: return "error in celestrak file" dbid = save_sat_data() satname, line1, line2 = get_sat_tle(satname, dbid) ts = load.timescale(builtin=True) satellite = EarthSatellite(line1, line2, satname, ts) satellite_model = satellite.at(ts.now()) position = satellite_model.position.km if ref == 'ecef': position = satellite_model.itrf_xyz().km ## get the subpoint subpoint = satellite_model.subpoint() lat = subpoint.latitude.degrees lon = subpoint.longitude.degrees return (position.tolist(), lat, lon)
def getEpoch(self): """Get epoch from TLEs""" self.ts = load.timescale() self.satellite = EarthSatellite(self.line1, self.line2, self.line0, self.ts) print("TLE epoch: {}".format(self.satellite.epoch.utc_jpl()))
def get_orbital_data(tle_data, time_data, label="Satellite"): ts = load.timescale() satellite = EarthSatellite(tle_data["line_1"], tle_data["line_2"], label, ts) time_instant = ts.utc( time_data["year"], time_data["month"], time_data["day"], time_data["hour"], time_data["min"], time_data["sec"], ) geocentric = satellite.at(time_instant) subpoint = geocentric.subpoint() elements = osculating_elements_of(geocentric) result = { "description": str(satellite), "lat": float(subpoint.latitude.degrees), "lng": float(subpoint.longitude.degrees), "alt": float(subpoint.elevation.km), "sunlit": satellite.at(time_instant).is_sunlit(JPL_EPH), "gcrs_vector": geocentric.position.km, "elements": elements } return result
def test_appendix_c_satellite(): ts = api.load.timescale() lines = appendix_c_example.splitlines() sat = EarthSatellite(lines[1], lines[2], lines[0], ts) jd_epoch = sat.model.jdsatepoch + sat.model.jdsatepochF three_days_later = jd_epoch + 3.0 offset = ts.tt(jd=three_days_later)._utc_float() - three_days_later t = ts.tt(jd=three_days_later - offset) # First, a crucial sanity check (which is, technically, a test of # the `sgp4` package and not of Skyfield): are the right coordinates # being produced by our Python SGP4 propagator for this satellite? rTEME, vTEME, error = sat._position_and_velocity_TEME_km(t) # TODO: This used to be accurate to within 1e-8 but lost precision # with the move to SGP4 2.0. Is the difference an underlying change # in the algorithm and its results? Or something else? epsilon = 1e-4 assert abs(-9060.47373569 - rTEME[0]) < epsilon assert abs(4658.70952502 - rTEME[1]) < epsilon assert abs(813.68673153 - rTEME[2]) < epsilon # TODO: Similar to the above, this used to be 1e-9. epsilon = 1e-8 assert abs(-2.232832783 - vTEME[0]) < epsilon assert abs(-4.110453490 - vTEME[1]) < epsilon assert abs(-3.157345433 - vTEME[2]) < epsilon
def find_sat(target_pos, flyover_time): with open("stations.txt", "r") as tles: lines = tles.readlines() sats = [] candidate_sat = None norm = 1e99 ts = load.timescale() # Load sat names for i in range(0, len(lines), 3): name = lines[i].strip() sats.append(name) try: satellite = EarthSatellite(lines[i + 1], lines[i + 2], lines[i], ts) position = satellite.at(ts.utc(flyover_time)).position.km diff = position - target_pos curr_norm = np.linalg.norm(diff) if curr_norm < norm: candidate_sat = satellite norm = curr_norm except NotImplementedError: pass return candidate_sat
def generatePlot(): print('Generating Plot') df = pandas.read_csv('../Data/tempCSV.csv') objectID = df.values[1][0][2:7] L1 = df.values[1][0] L2 = df.values[2][0] load = Loader( '~/Documents/fishing/SkyData') # avoids multiple copies of large files ts = load.timescale() data = load('de421.bsp') earth = data['earth'] ts = load.timescale() minutes = np.arange(60. * 24) # seven days time = ts.utc(today.year, today.month, today.day, 0, minutes) # start June 1, 2018 ISS = EarthSatellite(L1, L2) subpoint = ISS.at(time).subpoint() lon = subpoint.longitude.degrees lat = subpoint.latitude.degrees breaks = np.where(np.abs(lon[1:] - lon[:-1]) > 30) #don't plot wrap-around lon, lat = lon[:-1], lat[:-1] lon[breaks] = np.nan my_tweet = 'Ground Track of NORAD ID #' + str( objectID) + ' for the next 24 hours' fig1, ax1 = plt.subplots() earth = mpimg.imread('../Figures/earth.tif') earth = mpimg.imread(earthImg) ax1.imshow(earth) ax1.plot(10800 * (lon / 360 + .5), 5400 * (lat / 180 + 0.5)) plt.axis('off') imgFile = "../Figures/latestGroundTrack.png" plt.savefig(imgFile, dpi=300, bbox_inches='tight', pad_inches=0) fig2, ax2 = plt.subplots() ax2.plot(lon / 360 + .5, lat / 180 - .5) print(lat[0]) if (math.isnan(lat[0])): exitFlag = False else: exitFlag = True return exitFlag, my_tweet
def __init__(self, name, l1, l2): self.name = name self.l1 = l1 self.l2 = l2 self.ts = load.timescale() self.sat = EarthSatellite(self.l1, self.l2, self.name, self.ts) self.no = SatData.no SatData.no += 1
def test_is_another_satellite_behind_earth(): # See if the method works with a pure geometric difference. ts = api.load.timescale() t = ts.utc(2018, 7, 3, 0, range(0, 60, 10)) s = EarthSatellite(line1, line2) # The "other satellite" is fictitious: the ISS offset by one day. s2 = EarthSatellite(line1.replace('184.80969102', '185.80969102'), line2) expected = [True, True, True, True, True, True] p = (s - s2).at(t) assert list(p.is_behind_earth()) == expected
def getSatXY(line1, line2, line3, time, mwa, ts): sat = EarthSatellite(line2, line3, line1, ts) sat.at(time) difference = sat - mwa topocentric = difference.at(time) ra, dec, distance = topocentric.radec() ra, dec = np.degrees(ra.radians), np.degrees(dec.radians) px, py = wcs.all_world2pix([[ra, dec]], 1)[0] return px, py, distance
def getSatXY(line1, line2, line3, UT, mwa, ts): """ determines if the satellite is within fov and if so returns the x y pixel location of the satellite Paramters --------- line1 : line1 of tle line2 : line2 of tle line3 : line3 of tle UT : UTC time mwa : skyfield observer object ts : skyfield time object Returns ------- px : x location of satellite py : y location of satellite number_of_pixels : search cone radius visible : visible? (bool) """ visible = False number_of_pixels = 0 sat = EarthSatellite(line2, line3, line1, ts) # propogate satellite to utc time = ts.utc(UT.year, UT.month, UT.day, UT.hour, UT.minute, UT.second) sat.at(time) difference = sat - mwa topocentric = difference.at(time) # determine angular and pixel space location of satellite ra, dec, distance = topocentric.radec() ra, dec = np.degrees(ra.radians), np.degrees(dec.radians) px, py = wcs.all_world2pix([[ra, dec]], 1)[0] ## check if satellite within image if 0 < px < imgSize and 0 < py < imgSize: if np.sqrt((px - (imgSize / 2))**2 + (py - (imgSize / 2))**2) < imgSize / 3: LOS_range = distance.m if LOS_range < 2000000: visible = True radius = np.degrees( 70000 / LOS_range ) # 25 km offset cone in orbit (can be made smaller) s=rxtheta number_of_pixels = radius / pixel_scale return px, py, number_of_pixels, visible
def test_is_sunlit(): # Yes, a positionlib method; but it made sense to test it here. ts = api.load.timescale() t = ts.utc(2018, 7, 3, 0, range(0, 60, 10)) s = EarthSatellite(*iss_tle0.splitlines()) eph = load('de421.bsp') expected = [True, False, False, False, True, True] assert list(s.at(t).is_sunlit(eph)) == expected # What if we observe from a topos rather than the geocenter? topos = api.Topos('40.8939 N', '83.8917 W') assert list((s - topos).at(t).is_sunlit(eph)) == expected
def sat_pos(self): # Create timescale ts = load.timescale() # Satellite satellite = EarthSatellite(self.TLE[0],self.TLE[1],self.name,ts) # Find t t = ts.utc(self.date[0],self.date[1],self.date[2],self.date[3],self.date[4],self.date[5]) geocentric = satellite.at(t) # Generate Longitude and Latitude of satellite y = geocentric.subpoint().latitude x = geocentric.subpoint().longitude return x,y
def locate(tle, observer_location, time=load.timescale().now(), verbose=False): try: if isinstance(observer_location, ObserverLocation): line0, line1, line2 = tle[0].strip().split('\n') satellite = EarthSatellite(line1, line2, name=line0) location = satellite - Topos((observer_location.location())[0], (observer_location.location())[1]) app = location.at(time) flag = True for val in app.position.km: if math.isnan(val): flag = False break if flag: temperature = observer_location.temperature() pressure = observer_location.pressure() return line0.strip() + " : " + line1[2:7], app.altaz( temperature_C=temperature, pressure_mbar=pressure) else: raise ValueError( "Expected <ObserverLocation> as observer_location") except ValueError as val_err: if verbose: print(val_err) return None
def test_updatePositions_9(qtbot): app = SatelliteWindow(app=Test()) qtbot.addWidget(app) tle = ["TIANGONG 1", "1 37820U 11053A 14314.79851609 .00064249 00000-0 44961-3 0 5637", "2 37820 42.7687 147.7173 0010686 283.6368 148.1694 15.73279710179072"] app.satellite = EarthSatellite(*tle[1:3], name=tle[0]) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') app.plotSatPosEarth, = plt.plot([1, 0], [1, 0]) app.plotSatPosHorizon, = plt.plot([1, 0], [1, 0]) app.plotSatPosSphere1, = ax.plot([1], [1], [1]) app.plotSatPosSphere2, = ax.plot([1], [1], [1]) now = app.app.mount.obsSite.ts.now() observe = app.satellite.at(now) subpoint = observe.subpoint() difference = app.satellite - app.app.mount.obsSite.location altaz = difference.at(now).altaz() with mock.patch.object(app.plotSatPosSphere1, 'set_data_3d'): with mock.patch.object(app.plotSatPosSphere2, 'set_data_3d'): with mock.patch.object(app.plotSatPosEarth, 'set_data'): with mock.patch.object(app.plotSatPosHorizon, 'set_data'): suc = app.updatePositions(observe=observe, subpoint=subpoint, altaz=altaz) assert suc
def readTLE(tleFilename): # Open TLE filename tleFile = open(tleFilename, 'r') print("Opened TLE file: ", tleFilename) # Read TLEs into catalog catalog = [] line0 = None line1 = None line2 = None for line in tleFile: if line[0] == '0': line0 = line elif line[0] == '1': line1 = line elif line[0] == '2': line2 = line else: # Error - TLE lines start with 0, 1 or 2 print("Error: line does not start with 0, 1 or 2: ", line) if line1 and line2: # Check if object number is same in both line 1 and 2 if line1[1:6] == line2[1:6]: catalog.append(EarthSatellite(line1, line2)) line1 = None line2 = None else: print("Error: Satnumber in line 1 not equal to line 2", line1, line2) print("Read ", len(catalog), "TLEs into catalog") return catalog
def getSatXY(line1, line2, line3, time_vector): """ propogate tle elements to epoch and determine the x,y position using wcs object """ sat = EarthSatellite(line2, line3) sat.at(time_vector) difference = sat - mwa topocentric = difference.at(time_vector) ra, dec, distance = topocentric.radec() ra = np.degrees(ra.radians) dec = np.degrees(dec.radians) pix_coords = wcs.all_world2pix(np.array([ra, dec]).T, 1) px, py = pix_coords.T return px, py
def __init__(self, s_list, t_list, J_t, fr): self.sat = Satrec() self.orbit = Earth_model.orbit() self.earth = Earth_model.Earth() self.satellite = self.sat.twoline2rv(s_list, t_list) e, self.r_sat, self.v_sat = self.satellite.sgp4(J_t, fr) self.coordinates_to_earth = EarthSatellite(s_list, t_list) self.first = 0
def loadSatfromTLE(self, tle): ''' :param tle: TLE EXAMPLE tle = """ GOCE 1 34602U 09013A 13314.96046236 .14220718 20669-5 50412-4 0 930 2 34602 096.5717 344.5256 0009826 296.2811 064.0942 16.58673376272979 """ :return: ''' lines = tle.strip().splitlines() self.satellites = EarthSatellite(lines[1], lines[2], lines[0]) return
def getSatXY(line1, line2, line3, UT, mwa, ts): """ determines of the satellite is within fov and if so returns t he x y pixel location of the satellite Paramters --------- line1 : line1 of tle line2 : line2 of tle line3 : line3 of tle UT : UTC time mwa : skyfield observer object ts : skyfield time object Returns ------- px : x location of satellite py : y location of satellite number_of_pixels : search cone radius visible : visible? (bool) """ visible = False number_of_pixels = 0 sat = EarthSatellite(line2, line3, line1, ts) # propogate satellite to utc #time = ts.utc(UT.year, UT.month, UT.day, UT.hour, UT.minute, UT.second) time = UT sat.at(time) difference = sat - mwa topocentric = difference.at(time) # determine angular and pixel space location of satellite ra, dec, distance = topocentric.radec() ra, dec = np.degrees(ra.radians), np.degrees(dec.radians) #print(ra) #px, py = wcs.all_world2pix([ra, dec]], 1)[0] pix_coords = wcs.all_world2pix(np.array([ra, dec]).T, 1) px, py = pix_coords.T ## check if satellite within image imgSize = 1400 pixel_scale = 0.0833333333333333 return px, py
def skyfield_ephem(load_path=None, parallax_correction=False, utc=None): '''Returns skyfield objects used for doing solar planning and conversion. Optional keywords: load_path: Directory location where the bsp files are stored. Defaults to current working directory if None. parallax_corection: Download the latest NuSTAR TLE file and apply the parallax correction based on NuSTAR's position in its orbit. Defaults to "False". If "True" then uses the nustar_pysolar.io TLE methods to parse the closest TLE entry in the NuSTAR database. If you set parallax_correction=True then Returns: observer, sun, ts The first two are Skyfield objects. "observer" is either geocentric or the NuSTAR location based on the TLE. "ts" is the Skyfield time object. ''' # Initialize Skyfield ephemeris tools. from skyfield.api import EarthSatellite, Loader from astropy.time import Time # Not actually used? So just comment out, and so no sunpy v1 issue # import sunpy.sun if load_path is None: load_path = './' load = Loader(load_path) else: load = Loader(load_path) ts = load.timescale() planets = load('de436.bsp') earth = planets['Earth'] sun = planets['Sun'] if parallax_correction is False: observer = earth else: assert ( not utc is None), "Must set UTC when using parallax correction!" import nustar_pysolar.io as io tlefile = io.download_tle(outdir=load_path) mindt, line1, line2 = io.get_epoch_tle(utc, tlefile) nustar = EarthSatellite(line1, line2) observer = earth + nustar ts = load.timescale() return observer, sun, ts
def find_satelite(x, y, z, tmt, ts): with open("stations.txt") as active: sat_name = active.readline() while sat_name: line1 = active.readline() line2 = active.readline() #print(sat_name,line1,line2) satellite = EarthSatellite(line1, line2, sat_name, ts) geocentric = satellite.at(tmt) sat_pos = geocentric.position.km if (sat_pos[0] == x and sat_pos[1] == y and sat_pos[2] == z): return satellite sat_name = active.readline().rstrip()
def test_is_behind_earth(): # Like the previous test: a satellite-focused positionlib method. # Just for fun, we ask whether the Sun is behind the earth, so this # measures the same celestial circumstance as the previous test. ts = api.load.timescale() t = ts.utc(2018, 7, 3, 0, range(0, 60, 10)) s = EarthSatellite(*iss_tle0.splitlines()) eph = load('de421.bsp') expected = [False, True, True, True, False, False] p = (eph['earth'] + s).at(t).observe(eph['sun']).apparent() assert list(p.is_behind_earth()) == expected
def test_receiveSatelliteAndShow_2(qtbot): app = SatelliteWindow(app=Test()) qtbot.addWidget(app) tle = ["TIANGONG 1", "1 37820U 11053A 14314.79851609 .00064249 00000-0 44961-3 0 5637", "2 37820 42.7687 147.7173 0010686 283.6368 148.1694 15.73279710179072"] satellite = EarthSatellite(*tle[1:3], name=tle[0]) suc = app.receiveSatelliteAndShow(satellite=satellite) assert suc
def get_adcs_vectors(time_data, tle_data): sun = JPL_EPH['sun'] earth = JPL_EPH['earth'] ts = load.timescale() label="Satellite" satellite = EarthSatellite(tle_data["line_1"], tle_data["line_2"], label, ts) time_instant = ts.utc( time_data["year"], time_data["month"], time_data["day"], time_data["hour"], time_data["min"], time_data["sec"], ) tru_pos = earth + satellite sun_vector1 = tru_pos.at(time_instant).observe(sun).apparent().position.km sun_vector2 = satellite.at(time_instant).position.km # sun_vector = satellite.at(time_instant).observe(earth).apparent() # print(tru_pos.at(time_instant).position.km) # print(earth.at(time_instant).position.km) return [sun_vector1 - sun_vector2]
def test_appendix_c_satellite(): lines = appendix_c_example.splitlines() sat = EarthSatellite(lines[1], lines[2], lines[0]) ts = api.load.timescale() jd_epoch = sat.model.jdsatepoch three_days_later = jd_epoch + 3.0 offset = ts.tt(jd=three_days_later)._utc_float() - three_days_later t = ts.tt(jd=three_days_later - offset) # First, a crucial sanity check (which is, technically, a test of # the `sgp4` package and not of Skyfield): are the right coordinates # being produced by our Python SGP4 propagator for this satellite? rTEME, vTEME, error = sat._position_and_velocity_TEME_km(t) assert abs(-9060.47373569 - rTEME[0]) < 1e-8 assert abs(4658.70952502 - rTEME[1]) < 1e-8 assert abs(813.68673153 - rTEME[2]) < 1e-8 assert abs(-2.232832783 - vTEME[0]) < 1e-9 assert abs(-4.110453490 - vTEME[1]) < 1e-9 assert abs(-3.157345433 - vTEME[2]) < 1e-9