134 lines
4.7 KiB
Python
134 lines
4.7 KiB
Python
"""Export orbit data to a Two-Line-Element representation.
|
|
|
|
Contributed by Egemen Imre https://github.com/egemenimre
|
|
|
|
"""
|
|
from math import pi
|
|
from sgp4.io import compute_checksum
|
|
from sgp4.conveniences import sat_epoch_datetime
|
|
|
|
# Define constants
|
|
_deg2rad = pi / 180.0 # 0.0174532925199433
|
|
_xpdotp = 1440.0 / (2.0 * pi) # 229.1831180523293
|
|
|
|
def export_tle(satrec):
|
|
"""Generate the TLE for a given `Satrec` object; returns two strings."""
|
|
|
|
# --------------------- Start generating line 1 ---------------------
|
|
|
|
# Build the list by appending successive items
|
|
pieces = ['1 ', satrec.satnum_str]
|
|
append = pieces.append
|
|
|
|
# Add classification code (use "U" if empty)
|
|
classification = getattr(satrec, 'classification', 'U')
|
|
append(classification.strip() or 'U')
|
|
append(' ')
|
|
|
|
# Add int'l designator and pad to 8 chars
|
|
intldesg = getattr(satrec, 'intldesg', '')
|
|
append('{0:8} '.format(intldesg))
|
|
|
|
# Add epoch year and days in YYDDD.DDDDDDDD format
|
|
epochyr = satrec.epochyr
|
|
# Undo non-standard 4-digit year for old satrec objects
|
|
epochyr %= 100
|
|
append(str(epochyr).zfill(2) + "{:012.8f}".format(satrec.epochdays) + " ")
|
|
|
|
# Add First Time Derivative of the Mean Motion (don't use "+")
|
|
append("{0: 8.8f}".format(satrec.ndot * (_xpdotp * 1440.0)).replace("0", "", 1) + " ")
|
|
|
|
# Add Second Time Derivative of Mean Motion
|
|
append(_abbreviate_rate(satrec.nddot * _xpdotp * 20736000.0, '-0'))
|
|
|
|
# Add BSTAR
|
|
append(_abbreviate_rate(satrec.bstar * 10.0, '+0'))
|
|
|
|
# Add Ephemeris Type and Element Number
|
|
ephtype = getattr(satrec, 'ephtype', 0)
|
|
elnum = getattr(satrec, 'elnum', 0)
|
|
append('{0} {1:4}'.format(ephtype, elnum))
|
|
|
|
# Join all the parts and add the Checksum
|
|
line1 = ''.join(pieces)
|
|
line1 += str(compute_checksum(line1))
|
|
|
|
# --------------------- Start generating line 2 ---------------------
|
|
|
|
# Reset the str array
|
|
pieces = ['2 ', satrec.satnum_str]
|
|
append = pieces.append
|
|
|
|
# Add the inclination (deg)
|
|
if not 0 <= satrec.inclo <= pi:
|
|
raise ValueError("Inclination must be between 0 and pi, got %r", satrec.inclo)
|
|
append(' {0:8.4f} '.format(satrec.inclo / _deg2rad))
|
|
|
|
# Add the RAAN (deg)
|
|
if not 0 <= satrec.nodeo <= 2 * pi:
|
|
raise ValueError("RAAN must be between 0 and 2 pi, got %r", satrec.nodeo)
|
|
append("{0:8.4f}".format(satrec.nodeo / _deg2rad).rjust(8, " ") + " ")
|
|
|
|
# Add the eccentricity (delete the leading zero an decimal point)
|
|
append("{0:8.7f}".format(satrec.ecco).replace("0.", "") + " ")
|
|
|
|
# Add the Argument of Perigee (deg)
|
|
if not 0 <= satrec.argpo <= 2 * pi:
|
|
raise ValueError("Argument of Perigee must be between 0 and 2 pi, got %r", satrec.argpo)
|
|
append("{0:8.4f}".format(satrec.argpo / _deg2rad).rjust(8, " ") + " ")
|
|
|
|
# Add the Mean Anomaly (deg)
|
|
if not 0 <= satrec.mo <= 2 * pi:
|
|
raise ValueError("Mean Anomaly must be between 0 and 2 pi, got %r", satrec.mo)
|
|
append("{0:8.4f}".format(satrec.mo / _deg2rad).rjust(8, " ") + " ")
|
|
|
|
# Add the Mean Motion (revs/day)
|
|
append("{0:11.8f}".format(satrec.no_kozai * _xpdotp).rjust(8, " "))
|
|
|
|
# Add the rev number at epoch
|
|
append(str(satrec.revnum).rjust(5))
|
|
|
|
# Join all the parts and add the Checksum
|
|
line2 = ''.join(pieces)
|
|
line2 += str(compute_checksum(line2))
|
|
|
|
return line1, line2
|
|
|
|
def _abbreviate_rate(value, zero_exponent_string):
|
|
return (
|
|
'{0: 4.4e} '.format(value)
|
|
.replace('.', '')
|
|
.replace('e+00', zero_exponent_string)
|
|
.replace('e-0', '-')
|
|
.replace('e+0', '+')
|
|
)
|
|
|
|
def export_omm(satrec, object_name):
|
|
launch_year = int(satrec.intldesg[:2])
|
|
launch_year += 1900 + (launch_year < 57) * 100
|
|
object_id = '{0}-{1}'.format(launch_year, satrec.intldesg[2:])
|
|
|
|
return {
|
|
"OBJECT_NAME": object_name,
|
|
"OBJECT_ID": object_id,
|
|
"CENTER_NAME": "EARTH",
|
|
"REF_FRAME": "TEME",
|
|
"TIME_SYSTEM": "UTC",
|
|
"MEAN_ELEMENT_THEORY": "SGP4",
|
|
"EPOCH": sat_epoch_datetime(satrec).strftime('%Y-%m-%dT%H:%M:%S.%f'),
|
|
"MEAN_MOTION": satrec.no_kozai * _xpdotp,
|
|
"ECCENTRICITY": satrec.ecco,
|
|
"INCLINATION": satrec.inclo / _deg2rad,
|
|
"RA_OF_ASC_NODE": satrec.nodeo / _deg2rad,
|
|
"ARG_OF_PERICENTER": satrec.argpo / _deg2rad,
|
|
"MEAN_ANOMALY": satrec.mo / _deg2rad,
|
|
"EPHEMERIS_TYPE": satrec.ephtype,
|
|
"CLASSIFICATION_TYPE": satrec.classification,
|
|
"NORAD_CAT_ID": satrec.satnum,
|
|
"ELEMENT_SET_NO": satrec.elnum,
|
|
"REV_AT_EPOCH": satrec.revnum,
|
|
"BSTAR": satrec.bstar,
|
|
"MEAN_MOTION_DOT": satrec.ndot * (_xpdotp * 1440.0),
|
|
"MEAN_MOTION_DDOT": satrec.nddot * (_xpdotp * 1440.0 * 1440),
|
|
}
|