def config_sats(self): """ Function that configures the satellites into a SatrecArray object :return: SatrecArray object """ # Loop through the TLE data to create a SatrecArray with several individual space objects satellites = [] # SatrecArray to store all space objects if self.linespertle == 2: m = 0 else: m = 1 for i in range(0, len(self.tledata), self.linespertle): line1 = self.tledata[i + m] line2 = self.tledata[i + (m + 1)] # Check to see if the Elset Classification is 'U' indicating that it is an # unclassified object, that is, a space debris if self.tledata[i + m].split()[1][-1] == 'U': satellites.append(Satrec.twoline2rv(line1, line2)) sats = SatrecArray(satellites) return sats
def load_gp_from_celestrak(*, catalog_number=None, international_designator=None, name=None): """Load general perturbations orbital data from Celestrak. Returns ------- Satrec Orbital data from specified object. Notes ----- This uses the OMM XML format from Celestrak as described in [1]_. References ---------- .. [1] Kelso, T.S. "A New Way to Obtain GP Data (aka TLEs)" https://celestrak.com/NORAD/documentation/gp-data-formats.php """ # Assemble query, raise an error if malformed url = _generate_url(catalog_number, international_designator, name) # Make API call, raise an error if data is malformed fields = _make_query(url) # Initialize and return Satrec object sat = Satrec() omm.initialize(sat, fields) return sat
def propagation_engine(line1, line2, time_list): """Tests the interpolation accuracy for a given TLE.""" # Init satellite object from the TLE sat = Satrec.twoline2rv(line1, line2) # ****** Generate the pos, vel vectors for each time instant ****** # Run the propagation and init pos and vel vectors in TEME e, r_list, v_list = sat.sgp4_array(time_list.jd1, time_list.jd2) # Load the time, pos, vel info into astropy objects (shallow copied) vel_list = CartesianDifferential(v_list, unit=u.km / u.s, xyz_axis=1) pos_list = CartesianRepresentation( r_list, unit=u.km, xyz_axis=1 ).with_differentials(vel_list) # trajectory in astropy traj_astropy = SkyCoord( pos_list, obstime=time_list, frame=TEME.name, representation_type="cartesian", differential_type="cartesian", ) # Init trajectory in Trajectory object trajectory = Trajectory(traj_astropy) return {"traj": trajectory, "sat": sat}
def write_PV_to_file_test(tle_obj_vec: list[dict], filepath:str="sats-TLE-example.json") -> None: import json import datetime from sgp4.api import Satrec, jday json_posveldata = {} # all TLEs (w/ diff epochs) will be propagated to current time. now = datetime.datetime.now() jd, fr = jday (now.year, now.month, now.day, now.hour, now.minute, now.seconds,0) for item in tle_obj_vec: sat_name = item["NORAD_CAT_ID"] sat = Satrec.twoline2rv(item["TLE_LINE1"], item["TLE_LINE2"]) e, r, v = sat.sgp4(jd, fr) r = [poskm * 1000 for poskm in r] v = [velkms * 1000 for velkms in v] json_posveldata[sat_name] = [r, v ] # # tle_json_data = {item["NORAD_CAT_ID"]: Satrec.twoline2rv(item["TLE_LINE1"], item["TLE_LINE2"]) # for item in tle_obj_vec } with open(filepath, "w") as file: json.dump(json_posveldata, file, indent=6) print(f"PV File written successfully at {filepath}.")
def get_TLE_parameters(line1, line2, gravity_model = 'WGS84'): grav_ind = getattr(sgp4.api, gravity_model.upper()) satellite = Satrec.twoline2rv(line1, line2, grav_ind) ret = {} for key in ['bstar', 'satnum', 'jdsatepochF', 'jdsatepoch']: ret[key] = getattr(satellite, key) return ret
def test_omm_export(): line0, line1, line2 = VANGUARD_TLE.splitlines() sat = Satrec.twoline2rv(line1, line2) fields = export_omm(sat, 'VANGUARD 1') assertEqual(fields, { 'ARG_OF_PERICENTER': 162.2516, 'BSTAR': -2.2483e-05, 'CENTER_NAME': 'EARTH', 'CLASSIFICATION_TYPE': 'U', 'ECCENTRICITY': 0.1845686, 'ELEMENT_SET_NO': 999, 'EPHEMERIS_TYPE': 0, 'EPOCH': '2020-10-13T04:52:48.472320', 'INCLINATION': 34.2443, 'MEAN_ANOMALY': 205.2356, 'MEAN_ELEMENT_THEORY': 'SGP4', 'MEAN_MOTION': 10.84869164, 'MEAN_MOTION_DDOT': 0.0, 'MEAN_MOTION_DOT': -1.6e-07, 'NORAD_CAT_ID': 5, 'OBJECT_ID': '1958-002B', 'OBJECT_NAME': 'VANGUARD 1', 'RA_OF_ASC_NODE': 225.5254, 'REF_FRAME': 'TEME', 'REV_AT_EPOCH': 21814, 'TIME_SYSTEM': 'UTC', })
def get_mean_elements(self, line1, line2, radians=False): '''Extract the mean elements in SI units (a [m], e [1], inc [deg], raan [deg], aop [deg], mu [deg]), B-parameter (not bstar) and epoch from a two line element pair. ''' xpdotp = 1440.0/(2.0*np.pi) # 229.1831180523293 satrec = Satrec.twoline2rv(line1, line2, self.grav_ind) B = satrec.bstar/(self.grav_model.radiusearthkm*1e3)*2/self.rho0 epoch = Time(satrec.jdsatepoch + satrec.jdsatepochF, format='jd', scale='utc') mean_elements = np.zeros((6,), dtype=np.float64) n0 = satrec.no_kozai*xpdotp/(86400.0/(2*np.pi)) mean_elements[0] = (np.sqrt(self.grav_model.mu)/n0)**(2.0/3.0)*1e3 mean_elements[1] = satrec.ecco mean_elements[2] = satrec.inclo mean_elements[3] = satrec.nodeo mean_elements[4] = satrec.argpo mean_elements[5] = satrec.mo if not radians: mean_elements[2:] = np.degrees(mean_elements[2:]) return mean_elements, B, epoch
def rv2tle(satno, tnew, r0, v0, drmin=1e-1, dvmin=1e-3, niter=100): # New epoch epochyr, epochdoy = datetime_to_epoch(tnew) # Dummy tle tle = TwoLineElement.from_parameters(satno, epochyr, epochdoy, 90.0, 0.0, 0.0001, 0.0, 0.0, 14.0, 5e-5) # Start loop rnew, vnew = r0, v0 converged = False for i in range(niter): # Convert state vector into new TLE newtle = classical_elements(rnew, vnew, epochyr, epochdoy, tle) # Propagate with SGP4 sat = Satrec.twoline2rv(newtle.line1, newtle.line2) e, rtmp, vtmp = sat.sgp4(sat.jdsatepoch, sat.jdsatepochF) rsgp4, vsgp4 = np.asarray(rtmp), np.asarray(vtmp) # Vector difference and magnitudes dr, dv = r0 - rsgp4, v0 - vsgp4 drm, dvm = np.linalg.norm(dr), np.linalg.norm(dv) # Exit check if (np.abs(drm) < drmin) and (np.abs(dvm) < dvmin): converged = True break # Update state vector rnew = rnew + dr vnew = vnew + dv return newtle, converged
def test_intldesg_with_7_characters(): sat = Satrec.twoline2rv( '1 39444U 13066AE 20110.89708219 .00000236 00000-0' ' 35029-4 0 9992', '2 39444 97.5597 114.3769 0059573 102.0933 258.6965 ' '14.82098949344697', ) assertEqual(sat.intldesg, '13066AE')
def test_satnum_leading_spaces(): # https://github.com/brandon-rhodes/python-sgp4/issues/81 # https://github.com/brandon-rhodes/python-sgp4/issues/90 l1 = '1 4859U 21001A 21007.63955392 .00000000 00000+0 00000+0 0 9990' l2 = '2 4859 000.0000 000.0000 0000000 000.0000 000.0000 01.00000000 09' sat = Satrec.twoline2rv(l1, l2) assertEqual(sat.satnum, 4859) assertEqual(sat.classification, 'U') assertEqual(sat.intldesg, '21001A')
def sgp4Predict(s, t, jd, fr): satellite = Satrec.twoline2rv(s, t) jd += 0.5 # get the position and velocity vectors in TEME frame e, r, v = satellite.sgp4(jd, fr) # Conversion from TEME to ITRS r, v = sgp4lib.TEME_to_ITRF(jd + fr, np.asarray(r), np.asarray(v) * 86400) v = v / 86400 return r * 1000, v * 1000
def get_predictor_from_tle_lines(tle_lines): db = MemoryTLESource() sgp4_sat = Satrec.twoline2rv(tle_lines[0], tle_lines[1]) db.add_tle( sgp4_sat.satnum, tuple(tle_lines), datetime_from_jday(sgp4_sat.jdsatepoch, sgp4_sat.jdsatepochF), ) predictor = TLEPredictor(sgp4_sat.satnum, db) return predictor
def test_whether_array_logic_writes_nan_values_to_correct_row(): # https://github.com/brandon-rhodes/python-sgp4/issues/87 l1 = "1 44160U 19006AX 20162.79712247 +.00816806 +19088-3 +34711-2 0 9997" l2 = "2 44160 095.2472 272.0808 0216413 032.6694 328.7739 15.58006382062511" sat = Satrec.twoline2rv(l1, l2) jd0 = np.array([2459054.5, 2459055.5]) jd1 = np.array([0.79712247, 0.79712247]) e, r, v = sat.sgp4_array(jd0, jd1) assert list(e) == [6, 1] assert np.isnan(r).tolist() == [[False, False, False], [True, True, True]] assert np.isnan(v).tolist() == [[False, False, False], [True, True, True]]
def TLE_to_RV(TLE, time_delta, current_time): satellite = Satrec.twoline2rv(TLE.split('\n')[0], TLE.split('\n')[1]) jd, fr = getThis_JD_FR(current_time, time_delta) e, r, v = satellite.sgp4(jd, fr) newVector = False if e == 0: newVector = [r[0], r[1], r[2], v[0], v[1], v[2]] else: # print("Error code is - ",e) pass return newVector
def __init__(self, name, line1, line2, whichconst=WGS84): self.name = name.strip() self.line1 = line1.strip() self.line2 = line2.strip() self.whichconst = whichconst self.satellite = Satrec.twoline2rv(self.line1, self.line2, self.whichconst) self.trace = { 'start_datetime': None, 'data': [], }
def test_all_three_gravity_models_with_sgp4init(): # Gravity models specified with sgp4init() should also change the # positions generated. sat = Satrec() args = sgp4init_args(VANGUARD_ATTRS) sat.sgp4init(WGS72OLD, 'i', VANGUARD_ATTRS['satnum'], VANGUARD_EPOCH, *args) assert_wgs72old(sat) sat.sgp4init(WGS72, 'i', VANGUARD_ATTRS['satnum'], VANGUARD_EPOCH, *args) assert_wgs72(sat) sat.sgp4init(WGS84, 'i', VANGUARD_ATTRS['satnum'], VANGUARD_EPOCH, *args) assert_wgs84(sat)
def propagate(self, tnew, drmin=1e-1, dvmin=1e-3, niter=100): # New epoch epochyr, epochdoy = datetime_to_epoch(tnew) jd, fr = jday(tnew.year, tnew.month, tnew.day, tnew.hour, tnew.minute, tnew.second + tnew.microsecond / 1000000) # Compute reference state vector sat = Satrec.twoline2rv(self.line1, self.line2) e, r, v = sat.sgp4(jd, fr) r0, v0 = np.asarray(r), np.asarray(v) # Start loop rnew, vnew = r0, v0 converged = False for i in range(niter): # Convert state vector into new TLE newtle = classical_elements(rnew, vnew, epochyr, epochdoy, self) # Propagate with SGP4 sat = Satrec.twoline2rv(newtle.line1, newtle.line2) e, rtmp, vtmp = sat.sgp4(sat.jdsatepoch, sat.jdsatepochF) rsgp4, vsgp4 = np.asarray(rtmp), np.asarray(vtmp) # Vector difference and magnitudes dr, dv = r0 - rsgp4, v0 - vsgp4 drm, dvm = np.linalg.norm(dr), np.linalg.norm(dv) # Exit check if (np.abs(drm) < drmin) and (np.abs(dvm) < dvmin): converged = True break # Update state vector rnew = rnew + dr vnew = vnew + dv return newtle, converged
def test_tle_export(): """Check `export_tle()` round-trip using all the TLEs in the test file. This iterates through the satellites in "SGP4-VER.TLE", generates `Satrec` objects and exports the TLEs. These exported TLEs are then compared to the original TLE, closing the loop (or the round-trip). """ data = get_data(__name__, 'SGP4-VER.TLE') tle_lines = iter(data.decode('ascii').splitlines()) # Skip these lines, known errors # Resulting TLEs are equivalent (same values in the Satrec object), but they are not the same # 25954: BSTAR = 0 results in a negative exp, not positive # 29141: BSTAR = 0.13519 results in a negative exp, not positive # 33333: Checksum error as expected on both lines # 33334: Checksum error as expected on line 1 # 33335: Checksum error as expected on line 1 expected_errs_line1 = set([25954, 29141, 33333, 33334, 33335]) expected_errs_line2 = set([33333, 33335]) if accelerated: # Non-standard: omits the ephemeris type integer. expected_errs_line1.add(11801) for line1 in tle_lines: if not line1.startswith('1'): continue line2 = next(tle_lines) # trim lines to normal TLE string size line1 = line1[:69] line2 = line2[:69] satrec = Satrec.twoline2rv(line1, line2) satrec_old = io.twoline2rv(line1, line2, wgs72) # Generate TLE from satrec out_line1, out_line2 = export_tle(satrec) out_line1_old, out_line2_old = export_tle(satrec_old) if satrec.satnum not in expected_errs_line1: assertEqual(out_line1, line1) assertEqual(out_line1_old, line1) if satrec.satnum not in expected_errs_line2: assertEqual(out_line2, line2) assertEqual(out_line2_old, line2)
def el2rv(inc, raan, ecc, argp, mean_anomaly, mean_motion, epoch): """ Converts mean orbital elements to state vector """ time_tle = epoch.jd - 2433281.5 sat = Satrec() sat.sgp4init( WGS84, "i", 0, time_tle, 0.0, 0.0, 0.0, ecc, argp, inc, mean_anomaly, mean_motion, raan, ) errorCode, rTEME, vTEME = sat.sgp4(epoch.jd1, epoch.jd2) if errorCode != 0: raise RuntimeError(SGP4_ERRORS[errorCode]) pTEME = coord.CartesianRepresentation(rTEME * u.km) vTEME = coord.CartesianDifferential(vTEME * u.km / u.s) svTEME = TEME(pTEME.with_differentials(vTEME), obstime=epoch) svITRS = svTEME.transform_to(coord.ITRS(obstime=epoch)) orb = Orbit.from_coords(Earth, svITRS) return orb.r, orb.v
def _sat_eci_sgp4_nonaccelerated(tles, observers, mjds): from sgp4.api import Satrec, SGP4_ERRORS out_dts = [np.dtype(('float64', 3))] it = np.nditer( [tles, observers, mjds] + [None] * 2, flags=['external_loop', 'buffered', 'delay_bufalloc', 'refs_ok'], op_flags=[['readonly']] * 3 + [['readwrite', 'allocate']] * 2, op_dtypes=['object', 'object', 'float64'] + out_dts + out_dts) it.reset() for itup in it: tle = itup[0] mjd = itup[2] size = mjd.shape[0] # TODO code path for api.accelerated == True for i in range(size): line1, line2 = tle[i].tle_strings()[1:] sat = Satrec.twoline2rv(line1, line2) _f, _i = np.modf(mjd[i]) err_code, pos, vel = sat.sgp4(_i + 2400000.5, _f) if err_code: raise ValueError('Satellite propagation error', err_code, '({})'.format(SGP4_ERRORS[err_code])) eci_pos_x, eci_pos_y, eci_pos_z = pos eci_vel_x, eci_vel_y, eci_vel_z = vel itup[3][i][0] = eci_pos_x itup[3][i][1] = eci_pos_y itup[3][i][2] = eci_pos_z itup[4][i][0] = eci_vel_x itup[4][i][1] = eci_vel_y itup[4][i][2] = eci_vel_z eci_pos = it.operands[3] eci_vel = it.operands[4] return eci_pos, eci_vel
def pass_countries(tle): print(tle) tle = tle.split('\n') sat = Satrec.twoline2rv(tle[1], tle[2]) jd, fr = jday(2019, 12, 9, 12, 0, 0) e, r, v = sat.sgp4(2458827, 0.362605) start_time = datetime.datetime.now() jds, frs = [], [] times = [] for i in range(60 * 60 * 6): time = start_time + datetime.timedelta(seconds=i) times.append(time) jd, fr = jday(time.year, time.month, time.day, time.hour, time.minute, time.second) jds.append(jd) frs.append(fr) jds = np.array(jds) frs = np.array(frs) e, r, v = sat.sgp4_array(jds, frs) R = 6371 lats, lons = [], [] last_country_id = -1 pass_country = [] for i, p in enumerate(r): x, y, z = p[0], p[1], p[2] lat = np.degrees(np.arctan(z / (x * x + y * y))) lon = np.degrees(np.arctan2(y, x)) country_id = pos2idx(lat, lon) if country_id != last_country_id: pass_country.append({ 'country': country_id, 'start_time': times[i].strftime('%Y-%m-%d %H:%M:%S'), 'end_time': '' }) last_country_id = country_id for i in range(len(pass_country) - 1): pass_country[i]['end_time'] = pass_country[i + 1]['start_time'] pass_country = list( filter(lambda x: x['country'] != -1, pass_country[1:-2])) for i in range(len(pass_country)): pass_country[i]['country'] = name[pass_country[i]['country']] pass_country[i]['sat'] = tle[0] return pass_country
def TLE_to_spacePoint(tle, timeDiff, now): satellite = Satrec.twoline2rv(tle.split('\n')[0], tle.split('\n')[1]) jd, fr = getThis_JD_FR(now, timeDiff) e, r, v = satellite.sgp4(jd, fr) newVector = False if (e != 0): print("Bad error accured :( ") else: newVectorObj = { "Ri": r[0], "Rj": r[1], "Rk": r[2], "Vi": v[0], "Vj": v[1], "Vk": v[2] } newVector = [r[0], r[1], r[2], v[0], v[1], v[2]] return newVector
def test_december_32(): # ISS [Orbit 606], whose date is 2019 plus 366.82137887 days. # The core SGP4 routines handled this fine, but my hamfisted # attempt to provide a Python datetime for "convenience" ran # into an overflow. a = '1 25544U 98067A 19366.82137887 .00016717 00000-0 10270-3 0 9129' b = '2 25544 51.6392 96.6358 0005156 88.7140 271.4601 15.49497216 6061' correct_epoch = dt.datetime(2020, 1, 1, 19, 42, 47, 134368) # Legacy API. sat = io.twoline2rv(a, b, wgs72) assertEqual(sat.epoch, correct_epoch) correct_epoch = correct_epoch.replace(tzinfo=conveniences.UTC) # Modern API. sat = Satrec.twoline2rv(a, b) assertEqual(conveniences.sat_epoch_datetime(sat), correct_epoch)
def test_setters(): sat = Satrec() sat.classification = 'S' assert sat.classification == 'S' sat.intldesg = 'Russian' assert sat.intldesg == 'Russian' sat.ephtype = 23 assert sat.ephtype == 23 sat.elnum = 123 assert sat.elnum == 123 sat.revnum = 1234 assert sat.revnum == 1234
def __init__(self, line1, line2, name=None, ts=None): if ts is None: ts = self.ts if ts is None: ts = EarthSatellite.ts = _build_builtin_timescale() self.name = None if name is None else name.strip() satrec = Satrec.twoline2rv(line1, line2) self.model = satrec two_digit_year = satrec.epochyr if two_digit_year < 57: year = two_digit_year + 2000 else: year = two_digit_year + 1900 self.epoch = ts.utc(year, 1, satrec.epochdays) self._setup(satrec)
def get_sat(tle_string): ''' Construct a satellite instance (`sgp4.io.Satellite`) from TLE string. Parameters ---------- tle_string : str Two-line elements (TLE) as 3-line string Returns ------- satname : str Name (identifier) of satellite satellite : `sgp4.io.Satellite` instance Satellite object filled from TLE Notes ----- TLE string must be of the form: .. code-block:: none ISS (ZARYA) 1 25544U 98067A 13165.59097222 .00004759 00000-0 88814-4 0 47 2 25544 51.6478 121.2152 0011003 68.5125 263.9959 15.50783143834295 ''' try: from sgp4.api import Satrec, WGS72 except ImportError: raise ImportError( 'The "sgp4" package (version 2+) is necessary to use this ' 'function.') tle_string_list = tle_string.split('\n') satname = tle_string_list[0] if satname[0:2] == '0 ': # remove leading 0 if present satname = satname[2:] satellite = Satrec.twoline2rv(*tle_string_list[1:3], WGS72) return satname, satellite
def __init__(self, line1, line2, name=None, ts=None): ts = ts or _ts self.name = None if name is None else name.strip() sat = Satrec.twoline2rv(line1, line2) self.model = sat # TODO: just use the Julian dates instead two_digit_year = sat.epochyr if two_digit_year < 57: year = two_digit_year + 2000 else: year = two_digit_year + 1900 self.epoch = ts.utc(year, 1, sat.epochdays) self.target = -100000 - self.model.satnum self.target_name = 'Satellite{0} {1}'.format( self.model.satnum, ' ' + repr(self.name) if self.name else '', )
def load(line1=None, line2=None, line3=None): if line1 == None or line2 == None or line3 == None: print("A LINE IS EMPTY ASSUMING ISS, THIS ISN'T NORMAL") line1 = "ISS (ZARYA)" line2 = "1 25544U 98067A 20164.65373352 .00000382 00000-0 14906-4 0 9994" line3 = "2 25544 51.6454 10.9046 0002538 44.6307 63.7290 15.49438511231317" satellite = Satrec.twoline2rv(line2, line3) yr = satellite.epochyr a = days2mdhms(satellite.epochyr, satellite.epochdays) yr = int("20" + str(yr)) now = datetime.datetime.now() last_r = datetime.datetime(yr, a[0], a[1], a[2]) delta = datetime.timedelta(days=14) max_datetime = delta + last_r if now > max_datetime: print("running ./tle.sh") error_code = os.system("./tle.sh") if error_code: print("something went wrong, check internet") exit() sat = ephem.readtle(line1, line2, line3) return sat
def _sat_eci_sgp4_accelerated(tles, observers, mjds): ''' Note, on a single core, this version is not really faster than the non-accelerated version. Probably the overhead of the python iteration can mostly be neglected. ''' from sgp4.api import Satrec, SGP4_ERRORS unique_tles = np.unique(tles) tles, observers, mjds = np.broadcast_arrays(tles, observers, mjds) eci_pos = np.empty(tles.shape + (3, ), dtype=np.float64) eci_vel = np.empty(tles.shape + (3, ), dtype=np.float64) for u_tle in unique_tles: # doesn't work, as array doesn't know tle_strings method # mask = u_tle == tles mask = np.array([u_tle == t for t in tles.flat], dtype=np.bool).reshape(tles.shape) mjd = mjds[mask] line1, line2 = u_tle.tle_strings()[1:] sat = Satrec.twoline2rv(line1, line2) _f, _i = np.modf(mjd) err_code, pos, vel = sat.sgp4_array(_i + 2400000.5, _f) if np.any(err_code): raise ValueError('Satellite propagation error', err_code, '({})'.format(SGP4_ERRORS[err_code])) eci_pos[mask] = pos eci_vel[mask] = vel return eci_pos, eci_vel
def get_satrec(satnum, epoch, ecco, argpo, inclo, mo, no_kozai, nodeo, bstar, ndot, nddot=0.0): time_ref = -631238400.0 # Time("1949-12-31T00:00:00", format="isot", scale="utc").unix satrec = Satrec() satrec.sgp4init( WGS72, # gravity model 'i', # 'a' = old AFSPC mode, 'i' = improved mode satnum, # satnum: Satellite number (epoch - time_ref) / (24.0 * 3600.0), # epoch: days since 1949 December 31 00:00 UT bstar, # bstar: drag coefficient (/earth radii) ndot, # ndot: ballistic coefficient (revs/day) nddot, # nddot: second derivative of mean motion (revs/day^3) ecco, # ecco: eccentricity argpo * np.pi / 180.0, # argpo: argument of perigee (radians) inclo * np.pi / 180.0, # inclo: inclination (radians) mo * np.pi / 180.0, # mo: mean anomaly (radians) no_kozai * 2.0 * np.pi / (24.0 * 60.0), # no_kozai: mean motion (radians/minute) nodeo * np.pi / 180.0, # nodeo: right ascension of ascending node (radians) ) satrec.classification = 'U' satrec.intldesg = "OrbDet" return satrec