def test_orbit_inverse_error_kep(self): mjd0 = dpt.jd_to_mjd(2457126.2729) orb_init_list = self._gen_orbits(1000) prop = PropagatorKepler( in_frame='EME', out_frame='EME', ) t = n.array([0.0]) for kep in orb_init_list: state_ref = dpt.kep2cart(kep, m=self.init_data['m'], M_cent=M_earth, radians=False) state = prop.get_orbit( t=t, mjd0=mjd0, a=kep[0], e=kep[1], inc=kep[2], raan=kep[4], aop=kep[3], mu0=dpt.true2mean(kep[5], kep[1], radians=False), m=self.init_data['m'], radians=False, ) state_diff1 = n.abs(state_ref - state[:,0]) nt.assert_array_less(state_diff1[:3], n.full((3,), 1e-5, dtype=state_diff1.dtype)) nt.assert_array_less(state_diff1[3:], n.full((3,), 1e-7, dtype=state_diff1.dtype))
def test_orbit_inverse_error_cart(self): mjd0 = dpt.jd_to_mjd(2457126.2729) orb_init_list = self._gen_orbits(1000) prop = PropagatorKepler( in_frame='TEME', out_frame='TEME', ) t = n.array([0.0]) orbs_done = 0 for kep in orb_init_list: state_ref = dpt.kep2cart(kep, m=self.init_data['m'], M_cent=M_earth, radians=False) state = prop.get_orbit_cart( t=t, mjd0=mjd0, x=state_ref[0], y=state_ref[1], z=state_ref[2], vx=state_ref[3], vy=state_ref[4], vz=state_ref[5], m=self.init_data['m'], ) state_diff1 = n.abs(state_ref - state[:,0]) if n.linalg.norm(state_diff1[:3]) > 1e-5: print(kep) print(orbs_done) nt.assert_array_less(state_diff1[:3], n.full((3,), 1e-5, dtype=state_diff1.dtype)) nt.assert_array_less(state_diff1[3:], n.full((3,), 1e-7, dtype=state_diff1.dtype)) orbs_done += 1
def test_TEME_to_TLE(self): import propagator_sgp4 mjd0 = dpt.jd_to_mjd(2457126.2729) reci = n.array([ -5339.76186573000, 5721.43584226500, 921.276953805000, ], dtype=n.float) veci = n.array([ -4.88969089550000, -3.83304653050000, 3.18013811100000, ], dtype=n.float) state_TEME = n.concatenate((reci, veci), axis=0) mean_elements = tle.TEME_to_TLE(state_TEME, mjd0=mjd0, kepler=False) state = propagator_sgp4.sgp4_propagation(mjd0, mean_elements, B=0, dt=0.0) state_diff = n.abs(state - state_TEME)*1e3 nt.assert_array_less(state_diff[:3], n.full((3,), 1e-2, dtype=state_diff.dtype)) nt.assert_array_less(state_diff[3:], n.full((3,), 1e-5, dtype=state_diff.dtype))
def test_orbit_kep_cart_correspondance(self): mjd0 = dpt.jd_to_mjd(2457126.2729) orb_init_list = self._gen_orbits(100) prop = PropagatorKepler( in_frame='EME', out_frame='EME', ) t = n.linspace(0, 12*3600, num=100, dtype=n.float) for kep in orb_init_list: state_ref = dpt.kep2cart(kep, m=self.init_data['m'], M_cent=M_earth, radians=False) state_kep = prop.get_orbit( t=t, mjd0=mjd0, a=kep[0], e=kep[1], inc=kep[2], raan=kep[4], aop=kep[3], mu0=dpt.true2mean(kep[5], kep[1], radians=False), m=self.init_data['m'], radians=False, ) state_cart = prop.get_orbit_cart( t=t, mjd0=mjd0, x=state_ref[0], y=state_ref[1], z=state_ref[2], vx=state_ref[3], vy=state_ref[4], vz=state_ref[5], m=self.init_data['m'], ) state_diff1 = n.abs(state_kep - state_cart) nt.assert_array_less(state_diff1[:3,:], n.full((3,t.size), 1e-5, dtype=state_diff1.dtype)) nt.assert_array_less(state_diff1[3:,:], n.full((3,t.size), 1e-7, dtype=state_diff1.dtype))
def test_TEME_to_TLE_cases(self): import propagator_sgp4 R_E = 6353.0e3 mjd0 = dpt.jd_to_mjd(2457126.2729) a = R_E*2.0 orb_init_list = [] orb_range = n.array([a, 0.9, 180, 360, 360, 360], dtype=n.float) orb_offset = n.array([R_E*1.1, 0, 0.0, 0.0, 0.0, 0.0], dtype=n.float) test_n = 5000 while len(orb_init_list) < test_n: orb = n.random.rand(6) orb = orb_offset + orb*orb_range if orb[0]*(1.0 - orb[1]) > R_E+200e3: orb_init_list.append(orb) orb_init_list.append(n.array([R_E*1.2, 0, 0.0, 0.0, 0.0, 0.0], dtype=n.float)) orb_init_list.append(n.array([R_E*1.2, 0, 0.0, 0.0, 0.0, 270], dtype=n.float)) orb_init_list.append(n.array([R_E*1.2, 1e-9, 0.0, 0.0, 0.0, 0.0], dtype=n.float)) orb_init_list.append(n.array([R_E*1.2, 0.1, 0.0, 0.0, 0.0, 0.0], dtype=n.float)) orb_init_list.append(n.array([R_E*1.2, 0.1, 75.0, 0.0, 0.0, 0.0], dtype=n.float)) orb_init_list.append(n.array([R_E*1.2, 0.1, 0.0, 120.0, 0.0, 0.0], dtype=n.float)) orb_init_list.append(n.array([R_E*1.2, 0.1, 0.0, 0.0, 35.0, 0.0], dtype=n.float)) orb_init_list.append(n.array([R_E*1.2, 0.1, 75.0, 120.0, 0.0, 0.0], dtype=n.float)) orb_init_list.append(n.array([R_E*1.2, 0.1, 75.0, 0.0, 35.0, 0.0], dtype=n.float)) orb_init_list.append(n.array([R_E*1.2, 0.1, 75.0, 120.0, 35.0, 0.0], dtype=n.float)) fail_inds = [] errs = n.empty((len(orb_init_list),2), dtype=n.float) for ind, kep in enumerate(orb_init_list): M_earth = propagator_sgp4.SGP4.GM*1e9/consts.G state_TEME = dpt.kep2cart(kep, m=0.0, M_cent=M_earth, radians=False)*1e-3 mean_elements = tle.TEME_to_TLE(state_TEME, mjd0=mjd0, kepler=False) state = propagator_sgp4.sgp4_propagation(mjd0, mean_elements, B=0, dt=0.0) state_diff = n.abs(state - state_TEME)*1e3 er_r = n.linalg.norm(state_diff[:3]) er_v = n.linalg.norm(state_diff[3:]) errs[ind,0] = er_r errs[ind,1] = er_v try: self.assertLess(er_r, 10.0) self.assertLess(er_v, 1.0) except AssertionError as err: fail_inds.append(ind) if len(fail_inds) > 0: print('FAIL / TOTAL: {} / {}'.format(len(fail_inds), len(orb_init_list))) self.assertLess(n.median(errs[:,0]), 1e-2) self.assertLess(n.median(errs[:,1]), 1e-4) assert len(fail_inds) < float(test_n)/100.
def TLE_propagation_TEME(line1, line2, jd_ut1, wgs='72'): '''Convert Two-line element to TEME coordinates at a specific Julian date. :param str line1: TLE line 1 :param str line2: TLE line 2 :param float/numpy.ndarray jd_ut1: Julian Date UT1 to propagate TLE to. :param str wgs: The used WGS standard, options are :code:`'72'` or :code:`'84'`. :return: (6,len(jd_ut1)) numpy.ndarray of Cartesian states [SI units] ''' if wgs == '72': from sgp4.earth_gravity import wgs72 as wgs_sys elif wgs == '84': from sgp4.earth_gravity import wgs84 as wgs_sys else: raise Exception('WGS standard "{}" not recognized.'.format(wgs)) satellite = twoline2rv(line1, line2, wgs_sys) if isinstance(jd_ut1, np.ndarray): if len(jd_ut1.shape) > 1: raise Exception( 'Only 1-D date array allowed: jd_ut1.shape = {}'.format( jd_ut1.shape)) else: if isinstance(jd_ut1, float): jd_ut1 = np.array([jd_ut1], dtype=np.float) states = np.empty((6, jd_ut1.size), dtype=np.float) for jdi in range(jd_ut1.size): year, month, day, hour, minute, second, usec = dpt.npdt2date( dpt.mjd2npdt(dpt.jd_to_mjd(jd_ut1[jdi]))) position, velocity = satellite.propagate( year=year, month=month, day=day, hour=hour, minute=minute, second=second + usec * 1e-6, ) state = np.array(position + velocity, dtype=np.float) state *= 1e3 #km to m states[:, jdi] = state return states
def gen_pop(): mass=0.8111E+04 diam=0.8960E+01 m_to_A=128.651 a=7159.5 e=0.0001 i=98.55 raan=248.99 aop=90.72 M=47.37 A=mass/m_to_A # epoch in unix seconds ut0=1241136000.0 # modified julian day epoch mjd0 = dpt.jd_to_mjd(dpt.unix_to_jd(ut0)) print('\n' + 'mjd0: {}'.format(mjd0) + '\n') _params = ['A', 'm', 'd', 'C_D', 'C_R'] pop = Population( name='ENVISAT', extra_columns = _params, space_object_uses = [True]*len(_params), #propagator = PropagatorNeptune, propagator = PropagatorSGP4, propagator_options = { 'out_frame': 'ITRF' }, ) pop.allocate(1) pop['oid'][0] = 1 pop['a'][0] = a pop['e'][0] = e pop['i'][0] = i pop['raan'][0] = raan pop['aop'][0] = aop pop['mu0'][0] = M pop['mjd0'][0] = mjd0 pop['A'][0] = A pop['m'][0] = mass pop['d'][0] = 1.0 pop['C_D'][0] = 2.3 pop['C_R'][0] = 1.0 return pop
def get_orbit(o): #print('{:.2f}, {:.2f}, {:.2f}, {:.2f}, {:.2f}, {:.2f}'.format(*o.tolist())) ecef = prop.get_orbit( t=0.0, a=o[0], e=o[1], inc=o[2], raan=o[4], aop=o[3], mu0=dpt.true2mean(o[5], o[1], radians=False), mjd0=dpt.jd_to_mjd(2457126.2729), C_D=2.3, A=1.0, m=1.0, ) return ecef
def get_orbit_cart(o): cart = dpt.kep2cart(o, m=1.0, M_cent=M_earth, radians=False) #print('{:.2f}, {:.2f}, {:.2f}, {:.2f}, {:.2f}, {:.2f}'.format(*cart.tolist())) ecef = prop.get_orbit_cart( t=0.0, x=cart[0], y=cart[1], z=cart[2], vx=cart[3], vy=cart[4], vz=cart[5], mjd0=dpt.jd_to_mjd(2457126.2729), C_D=2.3, A=1.0, m=1.0, ) return ecef
def _get_MicrosatR_state(mjd): tle_raw = '''1 43947U 19006A 19085.80962006 .00050945 29637-5 93510-4 0 9994 2 43947 96.6379 359.2115 0016283 220.5574 212.4511 16.01198803 9765''' tle_raw = [line.strip() for line in tle_raw.split('\n')] if len(tle_raw) % 2 != 0: raise Exception('Not even number of lines [not TLE compatible]') line1, line2 = tle_raw[0], tle_raw[1] jd0 = tle.tle_jd(line1) mjd0 = dpt.jd_to_mjd(jd0) sat_id = tle.tle_id(line1) state_TEME = tle.TLE_propagation_TEME(line1, line2, dpt.mjd_to_jd(mjd)) return state_TEME, sat_id
def tryActivity(): line1 = '1 43947U 19006A 19069.62495353 .00222140 22344-4 39735-3 0 9995' line2 = '2 43947 96.6263 343.1609 0026772 226.5664 224.4731 16.01032328 7176' mjd0 = dpt.jd_to_mjd(tle.tle_jd(line1)) state, epoch = tle.TLE_to_TEME(line1, line2) x, y, z, vx, vy, vz = state p1 = PropagatorOrekit(solar_activity_strength='STRONG', ) p2 = PropagatorOrekit(solar_activity_strength='WEAK', ) kwargs = dict(m=800., C_R=1., C_D=2.3, A=4.0) t = np.linspace(0, 3 * 24 * 3600.0, num=5000, dtype=np.float64) pv1 = p1.get_orbit_cart(t, x, y, z, vx, vy, vz, mjd0, **kwargs) pv2 = p2.get_orbit_cart(t, x, y, z, vx, vy, vz, mjd0, **kwargs) fig = plt.figure(figsize=(15, 15)) ax = fig.add_subplot(211) ax.plot(t / 3600., np.linalg.norm(pv1[:3, :] - pv2[:3, :], axis=0) * 1e-3) ax.set( xlabel='Time [h]', ylabel='Position difference [km]', title='Strong vs weak solar activity', ) ax = fig.add_subplot(212) ax.plot(t / 3600., np.linalg.norm(pv1[:3, :] * 1e-3, axis=0), label='Weak') ax.plot(t / 3600., np.linalg.norm(pv2[:3, :] * 1e-3, axis=0), label='Strong') ax.set( xlabel='Time [h]', ylabel='Range [km]', ) plt.legend() plt.show()
def get_orbit_TLE(self, t, line1, line2): '''Takes a TLE and propagates it forward in time directly using the SGP4 algorithm. :param float/list/numpy.ndarray t: Time in seconds to propagate relative the initial state epoch. :param str line1: TLE line 1 :param str line2: TLE line 2 ''' jd0 = tle.tle_jd(line1) mjd0 = dpt.jd_to_mjd(jd0) jddates = jd0 + t/(3600.0*24.0) states_TEME = tle.TLE_propagation_TEME(line1, line2, jddates) if self.out_frame == 'TEME': return states_TEME elif self.out_frame == 'ITRF': ecefs = np.empty(states_TEME.shape, dtype=states_TEME.dtype) if self.polar_motion: PM_data = tle.get_Polar_Motion(jddates) for jdi in range(jddates.size): ecefs[:,jdi] = tle.TEME_to_ITRF( states_TEME[:,jdi], jddates[jdi], PM_data[jdi,0], PM_data[jdi,1], ) else: for jdi in range(jddates.size): ecefs[:,jdi] = tle.TEME_to_ITRF( states_TEME[:,jdi], jddates[jdi], 0.0, 0.0, ) return ecefs else: raise Exception('Output frame {} not found'.format(self.out_frame))
def trySteps(): p = PropagatorOrekit() line1 = '1 43947U 19006A 19069.62495353 .00222140 22344-4 39735-3 0 9995' line2 = '2 43947 96.6263 343.1609 0026772 226.5664 224.4731 16.01032328 7176' mjd0 = dpt.jd_to_mjd(tle.tle_jd(line1)) state, epoch = tle.TLE_to_TEME(line1, line2) x, y, z, vx, vy, vz = state kwargs = dict(m=800., C_R=1., C_D=2.3, A=2.0) t_end = 24 * 3600.0 t_vecs = [ np.linspace(0, t_end, num=ind) for ind in [100, 200, 500, 1000, 10000] ] fig = plt.figure(figsize=(15, 15)) ax = fig.add_subplot(111) for t in t_vecs: pv = p.get_orbit_cart(t, x, y, z, vx, vy, vz, mjd0, **kwargs) ax.plot(t / 3600., np.linalg.norm(pv[:3, :] * 1e-3, axis=0), label='{} steps @ {} s step size'.format( len(t), t_end / float(len(t)))) ax.set( xlabel='Time [h]', ylabel='Range [km]', title='Step number difference', ) plt.legend() plt.show()
def simulate_Microsat_R_debris(num, max_dv, radii_range, mass_range, C_D_range, seed, propagator, propagator_options, mjd): tle_raw = '''1 43947U 19006A 19069.62495353 .00222140 22344-4 39735-3 0 9995 2 43947 96.6263 343.1609 0026772 226.5664 224.4731 16.01032328 7176 1 43947U 19006A 19069.68634861 .00217235 21442-4 38851-3 0 9995 2 43947 96.6282 343.2231 0026267 227.5469 217.1086 16.01062873 7183 1 43947U 19006A 19069.81093322 .00066734 37128-5 12017-3 0 9992 2 43947 96.6282 343.3467 0026246 227.0726 215.1493 16.01048534 7204 1 43947U 19006A 19070.54563657 .00111882 69857-5 20248-3 0 9991 2 43947 96.6271 344.0664 0025783 228.7058 125.4384 16.00925959 7318 1 43947U 19006A 19070.80923755 .00013653 19858-5 25403-4 0 9991 2 43947 96.6268 344.3320 0024927 225.1848 207.3499 16.01142181 7364 1 43947U 19006A 19071.12831853 .00154965 11740-4 27719-3 0 9998 2 43947 96.6279 344.6467 0025572 226.6832 243.5148 16.01113233 7412 1 43947U 19006A 19071.80921646 .00118874 76545-5 21379-3 0 9993 2 43947 96.6279 345.3224 0025491 224.0468 208.0149 16.01043615 7523 1 43947U 19006A 19072.44153689 .00037015 24665-5 66863-4 0 9999 2 43947 96.6279 345.9498 0025442 221.6016 252.7257 16.01159223 7620 1 43947U 19006A 19072.74405995 .00022228 21113-5 40609-4 0 9997 2 43947 96.6279 346.2500 0025432 220.3955 196.4626 16.01147542 7675 1 43947U 19006A 19073.12825718 .00008242 19370-5 15873-4 0 9996 2 43947 96.6304 346.6133 0023002 223.0617 246.6563 16.01114545 7738 1 43947U 19006A 19073.44154376 .00035052 24102-5 63784-4 0 9998 2 43947 96.6300 346.9244 0022588 225.2511 249.1037 16.01188227 7782 1 43947U 19006A 19073.80920446 -.00023017 21041-5 -40417-4 0 9994 2 43947 96.6337 347.2908 0022039 223.4278 208.5467 16.01076766 7841 1 43947U 19006A 19074.74408622 .00119327 76982-5 21614-3 0 9994 2 43947 96.6289 348.2321 0022856 222.6623 194.1149 16.01049775 7992 1 43947U 19006A 19075.01672454 .00167822 13470-4 30180-3 0 9994 2 43947 96.6290 348.5015 0022778 221.4659 325.7020 16.01154108 8039 1 43947U 19006A 19075.54702546 .00026769 22010-5 48973-4 0 9993 2 43947 96.6290 349.0278 0022754 219.3583 142.5100 16.01177853 8128 1 43947U 19006A 19075.74902949 .00160298 12418-4 29196-3 0 9995 2 43947 96.6301 349.2308 0021693 223.2409 221.9908 16.00986874 8150 1 43947U 19006A 19075.80608134 .00151204 11245-4 27527-3 0 9991 2 43947 96.6283 349.2862 0021642 222.7701 191.0541 16.01000711 8166 1 43947U 19006A 19075.80608134 .00152613 11422-4 27780-3 0 9994 2 43947 96.6283 349.2862 0021642 222.7701 191.0553 16.01002279 8160 1 43947U 19006A 19076.04950662 .00212767 20643-4 38419-3 0 9990 2 43947 96.6283 349.5277 0021615 221.8443 154.0766 16.01125308 8205 1 43947U 19006A 19076.38314227 .00228397 23614-4 40852-3 0 9999 2 43947 96.6283 349.8588 0021611 220.6464 277.1313 16.01285801 8254 1 43947U 19006A 19076.56965602 .00375665 62286-4 68387-3 0 9990 2 43947 96.6317 350.0396 0020897 222.9971 269.0493 16.01007118 8281 1 43947U 19006A 19076.62489356 .00301460 40170-4 54811-3 0 9991 2 43947 96.6317 350.0945 0020879 222.7479 227.4454 16.01029701 8290 1 43947U 19006A 19076.74888822 .00206456 19517-4 37455-3 0 9990 2 43947 96.6317 350.2206 0020779 222.3519 222.0257 16.01081824 8311 1 43947U 19006A 19076.80334391 .00189842 16753-4 34417-3 0 9997 2 43947 96.6317 350.2747 0020760 222.1378 175.8977 16.01098177 8326 1 43947U 19006A 19077.25548485 .00042586 26475-5 77957-4 0 9991 2 43947 96.6337 350.7139 0018680 228.2848 254.2224 16.01199217 8396 1 43947U 19006A 19077.49923692 .00048049 28483-5 87602-4 0 9993 2 43947 96.6337 350.9559 0018675 227.3154 219.3457 16.01241589 8433 1 43947U 19006A 19077.73867148 .00176479 14671-4 32436-3 0 9999 2 43947 96.6324 351.1992 0019599 225.2817 160.3011 16.00913438 8475 1 43947U 19006A 19078.62402633 .00193781 17362-4 35487-3 0 9996 2 43947 96.6337 352.0814 0019337 224.7610 220.1468 16.00981700 8611 1 43947U 19006A 19079.44446882 .00056887 32197-5 10424-3 0 9994 2 43947 96.6318 352.8859 0017932 222.6020 267.9762 16.01149860 8742 1 43947U 19006A 19079.56114259 .00331197 48376-4 60603-3 0 9996 2 43947 96.6357 353.0133 0018767 223.2624 219.3325 16.01004143 8769 1 43947U 19006A 19079.87121502 .00017670 20377-5 33169-4 0 9996 2 43947 96.6348 353.3097 0018626 221.5456 207.0221 16.01103300 8819 1 43947U 19006A 19080.12837572 .00018161 20446-5 34105-4 0 9991 2 43947 96.6342 353.5628 0017856 223.7454 246.0274 16.01109643 8852 1 43947U 19006A 19080.25184005 .00021666 21015-5 40443-4 0 9990 2 43947 96.6342 353.6854 0017855 223.2528 237.6932 16.01123784 8871 1 43947U 19006A 19080.56838169 .00007182 19289-5 14116-4 0 9996 2 43947 96.6323 353.9969 0018497 223.3308 260.9364 16.01125965 8927 1 43947U 19006A 19080.80934521 -.00010028 19397-5 -17132-4 0 9998 2 43947 96.6323 354.2362 0018496 222.3649 209.7823 16.01086764 8962 1 43947U 19006A 19081.01817130 -.00000602 19026-5 00000+0 0 9994 2 43947 96.6305 354.4520 0018602 217.7557 337.0831 16.00999357 8992 1 43947U 19006A 19081.19970958 .00192780 17239-4 35047-3 0 9995 2 43947 96.6332 354.6387 0017808 222.1497 298.3751 16.01166044 9020 1 43947U 19006A 19081.44288380 .00132357 90623-5 24030-3 0 9997 2 43947 96.6332 354.8802 0017799 221.2143 260.0465 16.01211967 9068 1 43947U 19006A 19081.68209472 .00185493 16056-4 34001-3 0 9993 2 43947 96.6354 355.1161 0017576 220.8387 198.1644 16.01033820 9107 1 43947U 19006A 19081.80977756 .00126608 84347-5 23219-3 0 9995 2 43947 96.6356 355.2444 0017575 222.5408 211.8678 16.01049036 9124 1 43947U 19006A 19082.19785193 .00009851 19489-5 19026-4 0 9997 2 43947 96.6356 355.6299 0017571 221.0666 288.6619 16.01097025 9186 1 43947U 19006A 19082.25710510 .00009887 19472-5 19026-4 0 9996 2 43947 96.6318 355.6880 0017118 220.4674 270.5748 16.01171238 9192 1 43947U 19006A 19082.38407701 .00138221 97199-5 25077-3 0 9994 2 43947 96.6325 355.8124 0017241 219.6702 282.7837 16.01240682 9219 1 43947U 19006A 19082.68646591 .00149753 11067-4 27555-3 0 9993 2 43947 96.6363 356.1139 0016876 222.4115 221.6813 16.01004284 9261 1 43947U 19006A 19082.81114447 .00088395 50732-5 16304-3 0 9995 2 43947 96.6363 356.2377 0016873 221.9425 220.2429 16.01009980 9289 1 43947U 19006A 19083.00642146 .00143972 10375-4 26369-3 0 9992 2 43947 96.6358 356.4314 0016878 221.0757 265.8708 16.01087252 9317 1 43947U 19006A 19083.49288397 -.03265362 32488-2 -61588-2 0 9990 2 43947 96.6406 356.9162 0017256 219.6745 189.3161 16.00630469 9392 1 43947U 19006A 19083.74911125 .00084825 48174-5 15749-3 0 9999 2 43947 96.6345 357.1709 0015989 224.4362 220.2191 16.00930159 9436 1 43947U 19006A 19083.81116759 .00103815 62739-5 19235-3 0 9995 2 43947 96.6324 357.2279 0015947 223.4735 218.5865 16.00945210 9446 1 43947U 19006A 19083.93495759 .00147725 10814-4 27243-3 0 9990 2 43947 96.6324 357.3507 0015945 222.9977 212.0347 16.00998010 9463 1 43947U 19006A 19084.04992207 .00154144 11623-4 28342-3 0 9996 2 43947 96.6354 357.4673 0016254 222.4775 154.7117 16.01036332 9486 1 43947U 19006A 19084.56994306 -.00389064 56746-4 -71643-3 0 9995 2 43947 96.6360 357.9786 0015819 222.1151 270.2904 16.00942425 9569 1 43947U 19006A 19084.68712708 .00107795 66250-5 19877-3 0 9992 2 43947 96.6366 358.0976 0015957 221.7662 225.5779 16.01024149 9583 1 43947U 19006A 19084.74556389 .00097765 57838-5 18034-3 0 9991 2 43947 96.6363 358.1566 0015910 221.6645 202.2537 16.01028963 9598 1 43947U 19006A 19084.98720666 .00152043 11367-4 27860-3 0 9992 2 43947 96.6362 358.3958 0015832 220.6056 155.1371 16.01110841 9636 1 43947U 19006A 19085.19976117 .00022830 21215-5 42802-4 0 9998 2 43947 96.6349 358.6073 0016094 221.4560 298.5857 16.01085713 9665 1 43947U 19006A 19085.49952644 .00052661 30351-5 96803-4 0 9996 2 43947 96.6377 358.9036 0016197 221.8414 224.9544 16.01169686 9718 1 43947U 19006A 19085.56842683 .00054526 31167-5 10000-3 0 9997 2 43947 96.6377 358.9720 0016198 221.5803 262.1287 16.01202917 9722 1 43947U 19006A 19085.80962006 .00050945 29637-5 93510-4 0 9994 2 43947 96.6379 359.2115 0016283 220.5574 212.4511 16.01198803 9765''' mass = 740 tle_raw = [line.strip() for line in tle_raw.split('\n')] if len(tle_raw) % 2 != 0: raise Exception('Not even number of lines [not TLE compatible]') TLEs = zip(tle_raw[0::2], tle_raw[1::2]) event_date = np.datetime64('2019-03-27T05:40') event_mjd = dpt.npdt2mjd(event_date) M_earth = propagator_sgp4.SGP4.GM*1e9/consts.G pop = Population( name='Simulated Microsat R debris', extra_columns = ['A', 'm', 'd', 'C_D', 'C_R'], space_object_uses = [True, True, True, True, True], propagator = propagator, propagator_options = propagator_options, ) pop.allocate(num) tle_mjds = np.empty((len(TLEs),), dtype=np.float64) for line_id, lines in enumerate(TLEs): line1, line2 = lines jd0 = tle.tle_jd(line1) mjd0 = dpt.jd_to_mjd(jd0) tle_mjds[line_id] = mjd0 best_tle = np.argmin(np.abs(tle_mjds - event_mjd)) line1, line2 = TLEs[best_tle] sat_id = tle.tle_id(line1) jd0 = tle.tle_jd(line1) mjd0 = dpt.jd_to_mjd(jd0) state_TEME = tle.TLE_propagation_TEME(line1, line2, dpt.mjd_to_jd(event_mjd)) #first has no pert states = np.repeat(state_TEME, num, axis=1) np.random.seed(seed) kep = dpt.cart2kep(state_TEME, m=mass, M_cent=M_earth, radians=False) pop.objs[0][1] = kep[0]*1e-3 pop.objs[0][2] = kep[1] pop.objs[0][3] = kep[2] pop.objs[0][4] = kep[4] pop.objs[0][5] = kep[3] pop.objs[0][6] = dpt.true2mean(kep[5], kep[1], radians=False) pop.objs[0][0] = float(sat_id) pop.objs[0][7] = mjd0 pop.objs[0][8] = np.pi*1.0**2 pop.objs[0][9] = mass pop.objs[0][10] = 2.0 pop.objs[0][11] = 2.3 pop.objs[0][12] = 1.0 ind = 1 while ind < num: C_D = np.random.rand(1)*(C_D_range[1] - C_D_range[0]) + C_D_range[0] rho = 11e3 while rho > 10e3: r = np.random.rand(1)*(radii_range[1] - radii_range[0]) + radii_range[0] A = np.pi*r**2 m = np.random.rand(1)*(mass_range[1] - mass_range[0]) + mass_range[0] vol = 4.0/3.0*np.pi*r**3 rho = m/vol pert_state = states[:,ind].copy() dv = np.random.rand(1)*max_dv ddir = _rand_sph(1).T pert_state[:3] += ddir[:,0]*dv kep = dpt.cart2kep(pert_state, m=mass, M_cent=M_earth, radians=False) if kep[0]*(1.0 - kep[1]) > 6353.0e3+100e3: pop.objs[ind][1] = kep[0]*1e-3 pop.objs[ind][2] = kep[1] pop.objs[ind][3] = kep[2] pop.objs[ind][4] = kep[4] pop.objs[ind][5] = kep[3] pop.objs[ind][6] = dpt.true2mean(kep[5], kep[1], radians=False) pop.objs[ind][0] = float(sat_id) + num pop.objs[ind][7] = mjd0 pop.objs[ind][8] = A pop.objs[ind][9] = m pop.objs[ind][10] = r*2.0 pop.objs[ind][11] = C_D pop.objs[ind][12] = 1.0 ind += 1 if 'out_frame' in pop.propagator_options: out_f = pop.propagator_options['out_frame'] else: out_f = 'ITRF' pop.propagator_options['out_frame'] = 'TEME' pop = propagate_population(pop, mjd) pop.propagator_options['out_frame'] = out_f return pop
def test_envisat(): import space_object as so mass = 0.8111E+04 diam = 0.8960E+01 m_to_A = 128.651 a = 7159.5 e = 0.0001 i = 98.55 raan = 248.99 aop = 90.72 M = 47.37 A = mass / m_to_A # epoch in unix seconds ut0 = 1241136000.0 # modified julian day epoch mjd0 = dpt.jd_to_mjd(dpt.unix_to_jd(ut0)) print(mjd0) o = so.SpaceObject( a=a, e=e, i=i, raan=raan, aop=aop, mu0=M, C_D=2.3, A=A, m=mass, diam=diam, mjd0=mjd0, #propagator = PropagatorNeptune, propagator=PropagatorSGP4, propagator_options={'out_frame': 'ITRF'}, ) e3d = rlib.eiscat_3d() print("EISCAT Skibotn location x,y,z ECEF (meters)") print(e3d._tx[0].ecef) ski_ecef = e3d._tx[0].ecef print("EISCAT Skibotn location %1.3f %1.3f %1.3f (lat,lon,alt)" % (e3d._tx[0].lat, e3d._tx[0].lon, 0.0)) t_obs = np.linspace(4440, 5280, num=100) + 31.974890 t_obs2 = np.linspace(4440, 5280, num=100) + 31.974890 + 1.0 print("MJD %1.10f %sZ" % (mjd0 + t_obs[0] / 3600.0 / 24.0, ccsds_write.unix2datestr(ut0 + t_obs[0]))) ecef = o.get_state(t_obs) ecef2 = o.get_state(t_obs2) print("ECEF state x,y,z,vx,vy,vz (km and km/s)") print(ecef[:, 0] / 1e3) print( "Time (UTC) Range (km) Vel (km/s) ECEF X (km) ECEF Y (km) ECEF Z (km)" ) for i in range(len(t_obs)): dist = np.linalg.norm(ecef[0:3, i] - ski_ecef) dist2 = np.linalg.norm(ecef2[0:3, i] - ski_ecef) vel = (dist2 - dist) / 1.0 print("%s %1.3f %1.3f %1.3f %1.3f %1.3f" % (ccsds_write.unix2datestr(ut0 + t_obs[i]), dist / 1e3, vel / 1e3, ecef[0, i] / 1e3, ecef[1, i] / 1e3, ecef[2, i] / 1e3))
props = [ p_sgp4, p_nept, p_orekit, ] prop_dat = [ ('-b', 'SGP4'), ('-g', 'NEPTUNE'), ('-k', 'Orekit'), ] ut0 = 1241136000.0 # modified Julian day epoch mjd0 = dpt.jd_to_mjd(dpt.unix_to_jd(ut0)) R_e = 6371.0 m_to_A = 128.651 mass = 0.8111E+04 init_data = { 'a': 7159.5 * 1e3, 'e': 0.0001, 'inc': 98.55, 'raan': 248.99, 'aop': 90.72, 'mu0': 47.37, 'mjd0': mjd0, 'C_D': 2.3, 'C_R': 1.0, 'm': mass,
sim.run_scheduler() sim.status(fout='{}h_to_{}h_scheduler'.format(0, int(SIM_TIME))) if part == 3: sim.set_version(branch_name) sim.load() data_file = './data/microsatR_uhf.h5' with h5py.File(data_file, 'r') as hf: t_obs = hf['t'].value r_obs = hf['r'].value v_obs = hf['v'].value t_obs = (dpt.jd_to_mjd(dpt.unix_to_jd(t_obs)) - mjd)*3600.0*24.0 + 2.0*3600.0 #maybe not gmt t_sort = np.argsort(t_obs) t_obs = t_obs[t_sort] r_obs = r_obs[t_sort] v_obs = v_obs[t_sort] t_select = t_obs < SIM_TIME*3600.0 t_obs = t_obs[t_select] r_obs = r_obs[t_select] v_obs = v_obs[t_select] #create RV_T plots, fig, axs = plt.subplots(2,1,figsize=(12,8),dpi=80) axs[0].hist(sim.population['m'])
) radar.set_scan(scan) sims = [] data_file = './data/microsatR_uhf.h5' with h5py.File(data_file, 'r') as hf: t_obs = hf['t'].value r_obs = hf['r'].value v_obs = hf['v'].value dt = np.datetime64('2019-04-02T12:01') mjd = dpt.npdt2mjd(dt) t_obs = (dpt.jd_to_mjd(dpt.unix_to_jd(t_obs)) - mjd) * 3600.0 * 24.0 + 2.0 * 3600.0 #maybe not gmt t_sort = np.argsort(t_obs) t_obs = t_obs[t_sort] r_obs = r_obs[t_sort] v_obs = v_obs[t_sort] t_select = t_obs < 24.0 * 3600.0 t_obs = t_obs[t_select] r_obs = r_obs[t_select] v_obs = v_obs[t_select] for branch_name in branch_names: fname = sim_root + '/{}_population.h5'.format(branch_name)
def tryTest1(): init_data = { 'a': 7500e3, 'e': 0, 'inc': 90.0, 'raan': 10, 'aop': 10, 'mu0': 40.0, 'mjd0': 57125.7729, 'C_D': 2.3, 'C_R': 1.0, 'm': 8000, 'A': 1.0, } mjd0 = dpt.jd_to_mjd(2457126.2729) orb_init_list = _gen_orbits(100) prop = PropagatorOrekit( in_frame='EME', out_frame='EME', ) t = np.linspace(0, 12 * 3600, num=100, dtype=np.float) for kep in orb_init_list: state_ref = dpt.kep2cart(kep, m=init_data['m'], M_cent=prop.M_earth, radians=False) state_kep = prop.get_orbit( t=t, mjd0=mjd0, a=kep[0], e=kep[1], inc=kep[2], raan=kep[4], aop=kep[3], mu0=dpt.true2mean(kep[5], kep[1], radians=False), C_D=init_data['C_D'], m=init_data['m'], A=init_data['A'], C_R=init_data['C_R'], radians=False, ) state_cart = prop.get_orbit_cart( t=t, mjd0=mjd0, x=state_ref[0], y=state_ref[1], z=state_ref[2], vx=state_ref[3], vy=state_ref[4], vz=state_ref[5], C_D=init_data['C_D'], m=init_data['m'], A=init_data['A'], C_R=init_data['C_R'], ) state_diff1 = np.abs(state_kep - state_cart) try: nt.assert_array_less( state_diff1[:3, :], np.full((3, t.size), 1e-5, dtype=state_diff1.dtype)) nt.assert_array_less( state_diff1[3:, :], np.full((3, t.size), 1e-7, dtype=state_diff1.dtype)) except: fig = plt.figure(figsize=(15, 15)) ax = fig.add_subplot(211) ax.plot(t / 3600.0, np.sqrt(np.sum(state_diff1[:3, :], axis=0)) * 1e-3) ax.set_xlabel('Time [h]') ax.set_ylabel('Position difference [km]') ax.set_title( 'Propagation difference diameter simple vs advanced models') ax = fig.add_subplot(212) ax.plot(t / 3600.0, np.sqrt(np.sum(state_diff1[3:, :], axis=0)) * 1e-3) ax.set_xlabel('Time [h]') fig = plt.figure(figsize=(15, 15)) ax = fig.add_subplot(111, projection='3d') plothelp.draw_earth_grid(ax) ax.plot(state_kep[0, :], state_kep[1, :], state_kep[2, :], "-", alpha=0.5, color="green", label='KEP input') ax.plot(state_cart[0, :], state_cart[1, :], state_cart[2, :], "-", alpha=0.5, color="red", label='CART input') plt.legend() plt.show()
def setUp(self): self.mjd0 = dpt.jd_to_mjd(2457126.2729) # 2015-04-13T18:32:58.560019 self.C_D = 2.3 self.m = 8000 self.A = 1.0 self.prop = propagator_sgp4.PropagatorSGP4()
def test_PropagatorSGP4_cart_kep_cases(self): R_E = 6353.0e3 mjd0 = dpt.jd_to_mjd(2457126.2729) a = R_E*2.0 orb_init_list = [] orb_range = np.array([a, 0.9, 180, 360, 360, 360], dtype=np.float) orb_offset = np.array([R_E*1.1, 0, 0.0, 0.0, 0.0, 0.0], dtype=np.float) test_n = 100 while len(orb_init_list) < test_n: orb = np.random.rand(6) orb = orb_offset + orb*orb_range if orb[0]*(1.0 - orb[1]) > R_E+200e3: orb_init_list.append(orb) orb_init_list.append(np.array([R_E*1.2, 0, 0.0, 0.0, 0.0, 0.0], dtype=np.float)) orb_init_list.append(np.array([R_E*1.2, 0, 0.0, 0.0, 0.0, 270], dtype=np.float)) orb_init_list.append(np.array([R_E*1.2, 1e-9, 0.0, 0.0, 0.0, 0.0], dtype=np.float)) orb_init_list.append(np.array([R_E*1.2, 0.1, 0.0, 0.0, 0.0, 0.0], dtype=np.float)) orb_init_list.append(np.array([R_E*1.2, 0.1, 75.0, 0.0, 0.0, 0.0], dtype=np.float)) orb_init_list.append(np.array([R_E*1.2, 0.1, 0.0, 120.0, 0.0, 0.0], dtype=np.float)) orb_init_list.append(np.array([R_E*1.2, 0.1, 0.0, 0.0, 35.0, 0.0], dtype=np.float)) orb_init_list.append(np.array([R_E*1.2, 0.1, 75.0, 120.0, 0.0, 0.0], dtype=np.float)) orb_init_list.append(np.array([R_E*1.2, 0.1, 75.0, 0.0, 35.0, 0.0], dtype=np.float)) orb_init_list.append(np.array([R_E*1.2, 0.1, 75.0, 120.0, 35.0, 0.0], dtype=np.float)) prop = propagator_sgp4.PropagatorSGP4(polar_motion=False) t = np.linspace(0, 12*3600, num=100, dtype=np.float) M_earth = propagator_sgp4.SGP4.GM*1e9/consts.G for kep in orb_init_list: state_TEME = dpt.kep2cart(kep, m=self.m, M_cent=M_earth, radians=False) ecefs_kep = prop.get_orbit( t=t, mjd0=mjd0, a=kep[0], e=kep[1], inc=kep[2], raan=kep[4], aop=kep[3], mu0=dpt.true2mean(kep[5], kep[1], radians=False), C_D=self.C_D, m=self.m, A=self.A, radians=False, ) ecefs_cart = prop.get_orbit_cart( t=t, mjd0=mjd0, x=state_TEME[0], y=state_TEME[1], z=state_TEME[2], vx=state_TEME[3], vy=state_TEME[4], vz=state_TEME[5], C_D=self.C_D, m=self.m, A=self.A, ) p = ecefs_kep[:3,:]*1e-3 v = ecefs_kep[3:,:]*1e-3 kep_TEME = propagator_sgp4.ecef2teme(t, p, v, mjd0=mjd0)*1e3 p = ecefs_kep[:3,:]*1e-3 v = ecefs_kep[3:,:]*1e-3 cart_TEME = propagator_sgp4.ecef2teme(t, p, v, mjd0=mjd0)*1e3 state_diff1 = np.abs(kep_TEME - cart_TEME) nt.assert_array_less(state_diff1[:3,:], np.full((3,t.size), 1e-5, dtype=state_diff1.dtype)) nt.assert_array_less(state_diff1[3:,:], np.full((3,t.size), 1e-7, dtype=state_diff1.dtype))
def test_PropagatorSGP4_cart_kep_inverse_cases(self): R_E = 6353.0e3 mjd0 = dpt.jd_to_mjd(2457126.2729) a = R_E*2.0 orb_init_list = [] orb_range = np.array([a, 0.9, 180, 360, 360, 360], dtype=np.float) orb_offset = np.array([R_E*1.1, 0, 0.0, 0.0, 0.0, 0.0], dtype=np.float) test_n = 5000 while len(orb_init_list) < test_n: orb = np.random.rand(6) orb = orb_offset + orb*orb_range if orb[0]*(1.0 - orb[1]) > R_E+200e3: orb_init_list.append(orb) orb_init_list.append(np.array([R_E*1.2, 0, 0.0, 0.0, 0.0, 0.0], dtype=np.float)) orb_init_list.append(np.array([R_E*1.2, 0, 0.0, 0.0, 0.0, 270], dtype=np.float)) orb_init_list.append(np.array([R_E*1.2, 1e-9, 0.0, 0.0, 0.0, 0.0], dtype=np.float)) orb_init_list.append(np.array([R_E*1.2, 0.1, 0.0, 0.0, 0.0, 0.0], dtype=np.float)) orb_init_list.append(np.array([R_E*1.2, 0.1, 75.0, 0.0, 0.0, 0.0], dtype=np.float)) orb_init_list.append(np.array([R_E*1.2, 0.1, 0.0, 120.0, 0.0, 0.0], dtype=np.float)) orb_init_list.append(np.array([R_E*1.2, 0.1, 0.0, 0.0, 35.0, 0.0], dtype=np.float)) orb_init_list.append(np.array([R_E*1.2, 0.1, 75.0, 120.0, 0.0, 0.0], dtype=np.float)) orb_init_list.append(np.array([R_E*1.2, 0.1, 75.0, 0.0, 35.0, 0.0], dtype=np.float)) orb_init_list.append(np.array([R_E*1.2, 0.1, 75.0, 120.0, 35.0, 0.0], dtype=np.float)) prop = propagator_sgp4.PropagatorSGP4(polar_motion=False) t = np.array([0], dtype=np.float) M_earth = propagator_sgp4.SGP4.GM*1e9/consts.G fail_inds = [] errs = np.empty((len(orb_init_list),2), dtype=np.float) for ind, kep in enumerate(orb_init_list): state_TEME = dpt.kep2cart(kep, m=self.m, M_cent=M_earth, radians=False) ecefs_kep = self.prop.get_orbit( t=t, mjd0=mjd0, a=kep[0], e=kep[1], inc=kep[2], raan=kep[4], aop=kep[3], mu0=dpt.true2mean(kep[5],kep[1],radians=False), C_D=self.C_D, m=self.m, A=self.A, ) p = ecefs_kep[:3]*1e-3 p.shape=(3,1) v = ecefs_kep[3:]*1e-3 v.shape=(3,1) kep_TEME = propagator_sgp4.ecef2teme(np.array([0.0]), p, v, mjd0=mjd0)*1e3 kep_TEME.shape = (6,) ecefs_cart = self.prop.get_orbit_cart( t=t, mjd0=mjd0, x=kep_TEME[0], y=kep_TEME[1], z=kep_TEME[2], vx=kep_TEME[3], vy=kep_TEME[4], vz=kep_TEME[5], C_D=self.C_D, m=self.m, A=self.A, ) p = ecefs_cart[:3]*1e-3 p.shape=(3,1) v = ecefs_cart[3:]*1e-3 v.shape=(3,1) cart_TEME = propagator_sgp4.ecef2teme(np.array([0.0]), p, v, mjd0=mjd0)*1e3 cart_TEME.shape = (6,) state_diff1 = np.abs(kep_TEME - state_TEME) try: nt.assert_array_less(state_diff1[:3], np.full((3,), 1e-2, dtype=state_diff1.dtype)) nt.assert_array_less(state_diff1[3:], np.full((3,), 1e-5, dtype=state_diff1.dtype)) except AssertionError as err: if ind not in fail_inds: fail_inds.append(ind) state_diff2 = np.abs(cart_TEME - state_TEME) try: nt.assert_array_less(state_diff2[:3], np.full((3,), 1e-2, dtype=state_diff2.dtype)) nt.assert_array_less(state_diff2[3:], np.full((3,), 1e-5, dtype=state_diff2.dtype)) except AssertionError as err: if ind not in fail_inds: fail_inds.append(ind) state_diff = np.abs(cart_TEME - kep_TEME) try: nt.assert_array_less(state_diff[:3], np.full((3,), 1e-2, dtype=state_diff.dtype)) nt.assert_array_less(state_diff[3:], np.full((3,), 1e-5, dtype=state_diff.dtype)) except AssertionError as err: if ind not in fail_inds: fail_inds.append(ind) er_r = np.linalg.norm(state_diff1[:3]) er_v = np.linalg.norm(state_diff1[3:]) errs[ind,0] = er_r errs[ind,1] = er_v if len(fail_inds) > 0: print('FAIL / TOTAL: {} / {}'.format(len(fail_inds), len(orb_init_list))) assert np.median(errs[:,0]) < 1e-2 assert np.median(errs[:,1]) < 1e-4 assert len(fail_inds) < float(test_n)/100.
tle_raw = [line.strip() for line in tle_raw.split('\n')] if len(tle_raw) % 2 != 0: raise Exception('Not even number of lines [not TLE compatible]') TLEs = zip(tle_raw[0::2], tle_raw[1::2]) event_date = np.datetime64('2019-03-27T05:40') event_mjd = dpt.npdt2mjd(event_date) M_earth = propagator_sgp4.SGP4.GM * 1e9 / consts.G tle_mjds = np.empty((len(TLEs), ), dtype=np.float64) for line_id, lines in enumerate(TLEs): line1, line2 = lines jd0 = tle.tle_jd(line1) mjd0 = dpt.jd_to_mjd(jd0) tle_mjds[line_id] = mjd0 best_tle = np.argmin(np.abs(tle_mjds - event_mjd)) line1, line2 = TLEs[best_tle] sat_id = tle.tle_id(line1) jd0 = tle.tle_jd(line1) mjd0 = dpt.jd_to_mjd(jd0) state_TEME = tle.TLE_propagation_TEME(line1, line2, dpt.mjd_to_jd(event_mjd)) kep = dpt.cart2kep(state_TEME, m=mass, M_cent=M_earth, radians=False) print('{}'.format(kep[0, 0])) print('{}'.format(kep[1, 0]))
def tle_snapshot(tle_file, sgp4_propagation=True, propagator = default_propagator, propagator_options = {}): '''Reads a TLE-snapshot file and converts the TLE's to orbits in a TEME frame and creates a population file. The BSTAR parameter is saved in column BSTAR (or :code:`_objs[:,12`). A snapshot generally contains several TLE's for the same object thus will this population also contain duplicate objects. *Numerical propagator assumptions:* To propagate with a numerical propagator one needs to make assumptions. * Density is :math:`5\cdot 10^3 \;\frac{kg}{m^3}`. * Object is a sphere * Drag coefficient is 2.3. :param str/list tle_file: Path to the input TLE snapshot file. Or the TLE-set can be given directly as a list of two lines that can be unpacked in a loop, e.g. :code:`[(tle1_l1, tle1_l2), (tle2_l1, tle2_l2)]`. :param bool sgp4_propagation: If :code:`False` then the population is specifically constructed to be propagated with :class:`propagator_orekit.PropagatorOrekit` and assumptions are made on mass, density and shape of objects. Otherwise the :class:`space_object.SpaceObject` is configured to use SGP4 propagation. :return: TLE snapshot as a population with numerical propagator :rtype: population.Population ''' if isinstance(tle_file, str): tle_raw = [line.rstrip('\n') for line in open(tle_file)] if len(tle_raw) % 2 != 0: raise Exception('Not even number of lines [not TLE compatible]') TLEs = zip(tle_raw[0::2], tle_raw[1::2]) pop_name = tle_file.split('/')[-1] else: TLEs = tle_file pop_name = 'TLE database' M_earth = propagator_sgp4.SGP4.GM*1e9/consts.G if sgp4_propagation: pop = Population( name=pop_name, extra_columns = ['A', 'm', 'd', 'C_D', 'C_R'] + ['line1', 'line2'], dtypes = ['float64']*5 + ['U70', 'U70'], space_object_uses = [True, True, True, True, True] + [True, True], propagator = propagator_sgp4.PropagatorTLE, propagator_options = { 'out_frame': 'ITRF', 'polar_motion': False, }, ) else: pop = Population( name=pop_name, extra_columns = ['A', 'm', 'd', 'C_D', 'C_R'], space_object_uses = [True, True, True, True, True], propagator = propagator, propagator_options = propagator_options, ) pop.allocate(len(TLEs)) for line_id, lines in enumerate(TLEs): line1, line2 = lines sat_id = tle.tle_id(line1) jd0 = tle.tle_jd(line1) mjd0 = dpt.jd_to_mjd(jd0) state_TEME, epoch = tle.TLE_to_TEME(line1,line2) kep = dpt.cart2kep(state_TEME, m=0.0, M_cent=M_earth, radians=False) pop.objs[line_id][1] = kep[0]*1e-3 pop.objs[line_id][2] = kep[1] pop.objs[line_id][3] = kep[2] pop.objs[line_id][4] = kep[4] pop.objs[line_id][5] = kep[3] pop.objs[line_id][6] = dpt.true2mean(kep[5], kep[1], radians=False) pop.objs[line_id][0] = float(sat_id) pop.objs[line_id][7] = mjd0 if sgp4_propagation: for line_id, lines in enumerate(TLEs): line1, line2 = lines pop.objs[line_id][13] = line1[:-1] pop.objs[line_id][14] = line2[:-1] for line_id, lines in enumerate(TLEs): line1, line2 = lines bstar = tle.tle_bstar(line1)/(propagator_sgp4.SGP4.R_EARTH*1000.0) B = bstar*2.0/propagator_sgp4.SGP4.RHO0 if B < 1e-9: rho = 500.0 C_D = 0.0 r = 0.1 A = np.pi*r**2 m = rho*4.0/3.0*np.pi*r**3 else: C_D = 2.3 rho = 5.0 r = (3.0*C_D)/(B*rho) A = np.pi*r**2 m = rho*4.0/3.0*np.pi*r**3 pop.objs[line_id][8] = A pop.objs[line_id][9] = m pop.objs[line_id][10] = r*2.0 pop.objs[line_id][11] = C_D pop.objs[line_id][12] = 1.0 return pop
def Microsat_R_debris(mjd, num, radii_range, mass_range, propagator, propagator_options): tle_raw = Microsat_R_debris_raw_tle tle_raw = [line.strip() for line in tle_raw.split('\n')] if len(tle_raw) % 2 != 0: raise Exception('Not even number of lines [not TLE compatible]') TLEs = zip(tle_raw[0::2], tle_raw[1::2]) M_earth = propagator_sgp4.SGP4.GM*1e9/consts.G pop = Population( name='Microsat R debris', extra_columns = ['A', 'm', 'd', 'C_D', 'C_R'], space_object_uses = [True, True, True, True, True], propagator = propagator, propagator_options = propagator_options, ) pop.allocate(len(TLEs)*num) delete_inds = [] cnt = 0 for ind in range(num): for line_id, lines in enumerate(TLEs): line1, line2 = lines sat_id = tle.tle_id(line1) jd0 = tle.tle_jd(line1) mjd0 = dpt.jd_to_mjd(jd0) state_TEME = tle.TLE_propagation_TEME(line1, line2, dpt.mjd_to_jd(mjd)) kep = dpt.cart2kep(state_TEME, m=0.0, M_cent=M_earth, radians=False) if np.any(np.isnan(kep)): delete_inds.append(cnt) continue pop.objs[cnt][1] = kep[0]*1e-3 pop.objs[cnt][2] = kep[1] pop.objs[cnt][3] = kep[2] pop.objs[cnt][4] = kep[4] pop.objs[cnt][5] = kep[3] pop.objs[cnt][6] = dpt.true2mean(kep[5], kep[1], radians=False) pop.objs[cnt][0] = float(sat_id) pop.objs[cnt][7] = mjd rho = 1.1e4 while rho > 1e4 or rho < 1e2: r = np.random.rand(1)*(radii_range[1] - radii_range[0]) + radii_range[0] A = np.pi*r**2 m = np.random.rand(1)*(mass_range[1] - mass_range[0]) + mass_range[0] vol = 4.0/3.0*np.pi*r**3 rho = m/vol pop.objs[cnt][8] = A pop.objs[cnt][9] = m pop.objs[cnt][10] = r*2.0 pop.objs[cnt][11] = 2.3 pop.objs[cnt][12] = 1.0 cnt += 1 pop.delete(delete_inds) return pop
import numpy as np import scipy.constants as consts import numpy.testing as nt import TLE_tools as tle import dpt_tools as dpt from propagator_orekit import PropagatorOrekit import matplotlib.pyplot as plt mjd0 = dpt.jd_to_mjd(2457126.2729) R_E = 6353.0e3 a = R_E * 2.0 orb_init_list = [] orb_init_list.append( np.array([R_E * 1.2, 0, 0.0, 0.0, 0.0, 0.0], dtype=np.float)) orb_init_list.append( np.array([R_E * 1.2, 0, 0.0, 0.0, 0.0, 270], dtype=np.float)) orb_init_list.append( np.array([R_E * 1.2, 1e-9, 0.0, 0.0, 0.0, 0.0], dtype=np.float)) orb_init_list.append( np.array([R_E * 1.2, 0.1, 0.0, 0.0, 0.0, 0.0], dtype=np.float)) orb_init_list.append( np.array([R_E * 1.2, 0.1, 75.0, 0.0, 0.0, 0.0], dtype=np.float)) orb_init_list.append( np.array([R_E * 1.2, 0.1, 0.0, 120.0, 0.0, 0.0], dtype=np.float)) orb_init_list.append( np.array([R_E * 1.2, 0.1, 0.0, 0.0, 35.0, 0.0], dtype=np.float)) orb_init_list.append( np.array([R_E * 1.2, 0.1, 75.0, 120.0, 0.0, 0.0], dtype=np.float))
def test_OD(root, sub_path): import orbit_determination import TLE_tools as tle import dpt_tools as dpt import radar_library as rlib import propagator_sgp4 #import propagator_orekit #import propagator_neptune import ccsds_write radar = rlib.eiscat_3d(beam='interp', stage=1) radar.set_FOV(max_on_axis=90.0, horizon_elevation=10.0) radar.set_SNR_limits(min_total_SNRdb=10.0, min_pair_SNRdb=1.0) radar.set_TX_bandwith(bw = 1.0e6) #prop = propagator_neptune.PropagatorNeptune() prop = propagator_sgp4.PropagatorSGP4() mass=0.8111E+04 diam=0.8960E+01 m_to_A=128.651 params = dict( A = { 'dist': None, 'val': mass/m_to_A, }, d = { 'dist': None, 'val': diam, }, m = { 'dist': None, 'val': mass, }, C_D = { 'dist': None, 'val': 2.3, }, ) fname = glob.glob(root + sub_path + '*.oem')[0] prior_data, prior_meta = ccsds_write.read_oem(fname) prior_sort = np.argsort(prior_data['date']) prior_data = prior_data[prior_sort][0] prior_mjd = dpt.npdt2mjd(prior_data['date']) prior_jd = dpt.mjd_to_jd(prior_mjd) state0 = np.empty((6,), dtype=np.float64) state0[0] = prior_data['x'] state0[1] = prior_data['y'] state0[2] = prior_data['z'] state0[3] = prior_data['vx'] state0[4] = prior_data['vy'] state0[5] = prior_data['vz'] #state0_ITRF = state0.copy() state0 = tle.ITRF_to_TEME(state0, prior_jd, 0.0, 0.0) #state0_TEME = state0.copy() #state0_ITRF_ref = tle.TEME_to_ITRF(state0_TEME, prior_jd, 0.0, 0.0) #print(state0_ITRF_ref - state0_ITRF) #exit() data_folder = root + sub_path data_h5 = glob.glob(data_folder + '*.h5') data_h5_sort = np.argsort(np.array([int(_h.split('/')[-1].split('-')[1]) for _h in data_h5])).tolist() true_prior_h5 = data_h5[data_h5_sort[0]] true_obs_h5 = data_h5[data_h5_sort[1]] print(true_prior_h5) print(true_obs_h5) with h5py.File(true_prior_h5, 'r') as hf: true_prior = hf['true_state'].value.T*1e3 true_prior_jd = dpt.unix_to_jd(hf['true_time'].value) print('-- True time diff prior [s] --') prior_match_ind = np.argmin(np.abs(true_prior_jd-prior_jd)) jd_diff = prior_jd - true_prior_jd[prior_match_ind] state0_true = true_prior[:,prior_match_ind] state0_true = tle.ITRF_to_TEME(state0_true, true_prior_jd[prior_match_ind], 0.0, 0.0) print(prior_match_ind) print(jd_diff*3600.0*24.0) with h5py.File(true_obs_h5, 'r') as hf: true_obs = hf['true_state'].value.T*1e3 true_obs_jd = dpt.unix_to_jd(hf['true_time'].value) data_tdm = glob.glob(data_folder + '*.tdm') #this next line i wtf, maybe clean up data_tdm_sort = np.argsort(np.array([int(_h.split('/')[-1].split('-')[-1][2]) for _h in data_tdm])).tolist() ccsds_files = [data_tdm[_tdm] for _tdm in data_tdm_sort] print('prior true vs prior mean') print(state0_true - state0) for _fh in ccsds_files: print(_fh) r_obs_v = [] r_sig_v = [] v_obs_v = [] v_sig_v = [] t_obs_v = [] for ccsds_file in ccsds_files: obs_data = ccsds_write.read_ccsds(ccsds_file) sort_obs = np.argsort(obs_data['date']) obs_data = obs_data[sort_obs] jd_obs = dpt.mjd_to_jd(dpt.npdt2mjd(obs_data['date'])) date_obs = obs_data['date'] sort_obs = np.argsort(date_obs) date_obs = date_obs[sort_obs] r_obs = obs_data['range'][sort_obs]*1e3 #to m v_obs = -obs_data['doppler_instantaneous'][sort_obs]*1e3 #to m/s #v_obs = obs_data['doppler_instantaneous'][sort_obs]*1e3 #to m/s r_sig = 2.0*obs_data['range_err'][sort_obs]*1e3 #to m v_sig = 2.0*obs_data['doppler_instantaneous_err'][sort_obs]*1e3 #to m/s #TRUNCATE FOR DEBUG inds = np.linspace(0,len(jd_obs)-1,num=10,dtype=np.int64) jd_obs = jd_obs[inds] r_obs = r_obs[inds] v_obs = v_obs[inds] r_sig = r_sig[inds] v_sig = v_sig[inds] if ccsds_file.split('/')[-1].split('.')[0] == true_obs_h5.split('/')[-1].split('.')[0]: print('-- True time diff obs [s] --') jd_diff = jd_obs - true_obs_jd[inds] print(jd_diff*3600.0*24.0) #r_sig = np.full(r_obs.shape, 100.0, dtype=r_obs.dtype) #v_sig = np.full(v_obs.shape, 10.0, dtype=v_obs.dtype) r_obs_v.append(r_obs) r_sig_v.append(r_sig) v_obs_v.append(v_obs) v_sig_v.append(v_sig) t_obs = (jd_obs - prior_jd)*(3600.0*24.0) #correct for light time approximently lt_correction = r_obs*0.5/scipy.constants.c t_obs -= lt_correction t_obs_v.append(t_obs) print('='*10 + 'Dates' + '='*10) print('{:<8}: {} JD'.format('Prior', prior_jd)) for ind, _jd in enumerate(jd_obs): print('Obs {:<4}: {} JD'.format(ind, _jd)) print('='*10 + 'Observations' + '='*10) print(len(jd_obs)) prior = {} prior['cov'] = np.diag([1e3, 1e3, 1e3, 1e1, 1e1, 1e1])*1.0 prior['mu'] = state0 print('='*10 + 'Prior Mean' + '='*10) print(prior['mu']) print('='*10 + 'Prior Covariance' + '='*10) print(prior['cov']) rx_ecef = [] for rx in radar._rx: rx_ecef.append(rx.ecef) tx_ecef = radar._tx[0].ecef tune = 0 trace = orbit_determination.determine_orbit( num = 2000, r = r_obs_v, sd_r = r_sig_v, v = v_obs_v, sd_v = v_sig_v, grad_dx = [10.0]*3 + [1.0]*3, rx_ecef = rx_ecef, tx_ecef = tx_ecef, t = t_obs_v, mjd0 = prior_mjd, params = params, prior = prior, propagator = prop, step = 'Metropolis', step_opts = { 'scaling': 0.75, }, pymc_opts = { 'tune': tune, 'discard_tuned_samples': True, 'cores': 1, 'chains': 1, 'parallelize': True, }, ) #if comm.rank != 0: # exit() var = ['$X$ [km]', '$Y$ [km]', '$Z$ [km]', '$V_X$ [km/s]', '$V_Y$ [km/s]', '$V_Z$ [km/s]'] fig = plt.figure(figsize=(15,15)) for ind in range(6): ax = fig.add_subplot(231+ind) ax.plot(trace['state'][:,ind]*1e-3) ax.set( xlabel='Iteration', ylabel='{}'.format(var[ind]), ) state1 = np.mean(trace['state'], axis=0) print('='*10 + 'Trace summary' + '='*10) print(pm.summary(trace)) _form = '{:<10}: {}' print('='*10 + 'Prior Mean' + '='*10) for ind in range(6): print(_form.format(var[ind], state0[ind]*1e-3)) print('='*10 + 'Posterior state mean' + '='*10) for ind in range(6): print(_form.format(var[ind], state1[ind]*1e-3)) stated = state1 - state0 print('='*10 + 'State shift' + '='*10) for ind in range(6): print(_form.format(var[ind], stated[ind]*1e-3)) print('='*10 + 'True posterior' + '='*10) for ind in range(6): print(_form.format(var[ind], state0_true[ind]*1e-3)) print('='*10 + 'Posterior error' + '='*10) for ind in range(6): print(_form.format(var[ind],(state1[ind] - state0_true[ind])*1e-3)) print('='*10 + 'Parameter shift' + '='*10) theta0 = {} theta1 = {} for key, val in params.items(): if val['dist'] is not None: theta0[key] = val['mu'] theta1[key] = np.mean(trace[key], axis=0)[0] print('{}: {}'.format(key, theta1[key] - theta0[key])) else: theta0[key] = val['val'] theta1[key] = val['val'] range_v_prior = [] vel_v_prior = [] range_v = [] vel_v = [] range_v_true = [] vel_v_true = [] for rxi in range(len(rx_ecef)): t_obs = t_obs_v[rxi] print('Generating tracklet simulated data RX {}: {} points'.format(rxi, len(t_obs))) states0 = orbit_determination.propagate_state(state0, t_obs, dpt.jd_to_mjd(prior_jd), prop, theta0) states1 = orbit_determination.propagate_state(state1, t_obs, dpt.jd_to_mjd(prior_jd), prop, theta1) states0_true = orbit_determination.propagate_state(state0_true, t_obs, dpt.jd_to_mjd(prior_jd), prop, theta1) range_v_prior += [np.empty((len(t_obs), ), dtype=np.float64)] vel_v_prior += [np.empty((len(t_obs), ), dtype=np.float64)] range_v += [np.empty((len(t_obs), ), dtype=np.float64)] vel_v += [np.empty((len(t_obs), ), dtype=np.float64)] range_v_true += [np.empty((len(t_obs), ), dtype=np.float64)] vel_v_true += [np.empty((len(t_obs), ), dtype=np.float64)] for ind in range(len(t_obs)): range_v_prior[rxi][ind], vel_v_prior[rxi][ind] = orbit_determination.generate_measurements(states0[:,ind], rx_ecef[rxi], tx_ecef) range_v[rxi][ind], vel_v[rxi][ind] = orbit_determination.generate_measurements(states1[:,ind], rx_ecef[rxi], tx_ecef) range_v_true[rxi][ind], vel_v_true[rxi][ind] = orbit_determination.generate_measurements(states0_true[:, ind], rx_ecef[rxi], tx_ecef) prop_states = orbit_determination.propagate_state( state0, np.linspace(0, (np.max(jd_obs) - prior_jd)*(3600.0*24.0), num=1000), dpt.jd_to_mjd(prior_jd), prop, theta1, ) ''' pop = gen_pop() obj = pop.get_object(0) t_obs_pop = t_obs + (dpt.jd_to_mjd(prior_jd) - obj.mjd0)*3600.0*24.0 states0_true2 = obj.get_state(t_obs_pop) print(states0_true2) print(states0_true2 - states0_true) ''' fig = plt.figure(figsize=(15,15)) ax = fig.add_subplot(111, projection='3d') plothelp.draw_earth_grid(ax) for ind, ecef in enumerate(rx_ecef): if ind == 0: ax.plot([ecef[0]], [ecef[1]], [ecef[2]], 'or', label='EISCAT 3D RX') else: ax.plot([ecef[0]], [ecef[1]], [ecef[2]], 'or') ax.plot(states0[0,:], states0[1,:], states0[2,:], 'xb', label = 'Prior', alpha = 0.75) ax.plot(states1[0,:], states1[1,:], states1[2,:], 'xr', label = 'Posterior', alpha = 0.75) ax.plot(prop_states[0,:], prop_states[1,:], prop_states[2,:], '-k', label = 'Prior-propagation', alpha = 0.5) ax.plot(true_prior[0,:], true_prior[1,:], true_prior[2,:], '-b', label = 'Prior-True', alpha = 0.75) ax.plot(true_obs[0,:], true_obs[1,:], true_obs[2,:], '-r', label = 'Posterior-True', alpha = 0.75) ax.legend() for rxi in range(len(rx_ecef)): fig = plt.figure(figsize=(15,15)) t_obs_h = t_obs_v[rxi]/3600.0 ax = fig.add_subplot(221) lns = [] line1 = ax.plot(t_obs_h, (r_obs_v[rxi] - range_v[rxi])*1e-3, '-b', label='Maximum a posteriori: RX{}'.format(rxi)) line0 = ax.plot(t_obs_h, (r_obs_v[rxi] - range_v_true[rxi])*1e-3, '.b', label='True prior: RX{}'.format(rxi)) ax.set( xlabel='Time [h]', ylabel='2-way-Range residuals [km]', ) ax2 = ax.twinx() line2 = ax2.plot(t_obs_h, (r_obs_v[rxi] - range_v_prior[rxi])*1e-3, '-k', label='Maximum a priori: RX{}'.format(rxi)) ax.tick_params(axis='y', labelcolor='b') ax2.tick_params(axis='y', labelcolor='k') lns += line0+line1+line2 labs = [l.get_label() for l in lns] ax.legend(lns, labs, loc=0) ax = fig.add_subplot(222) lns = [] line1 = ax.plot(t_obs_h, (v_obs_v[rxi] - vel_v[rxi])*1e-3, '-b', label='Maximum a posteriori: RX{}'.format(rxi)) line0 = ax.plot(t_obs_h, (v_obs_v[rxi] - vel_v_true[rxi])*1e-3, '.b', label='True prior: RX{}'.format(rxi)) ax.set( xlabel='Time [h]', ylabel='2-way-Velocity residuals [km/s]', ) ax2 = ax.twinx() line2 = ax2.plot(t_obs_h, (v_obs_v[rxi] - vel_v_prior[rxi])*1e-3, '-k', label='Maximum a priori: RX{}'.format(rxi)) ax.tick_params(axis='y', labelcolor='b') ax2.tick_params(axis='y', labelcolor='k') lns += line0+line1+line2 labs = [l.get_label() for l in lns] ax.legend(lns, labs, loc=0) ax = fig.add_subplot(223) ax.errorbar(t_obs_h, r_obs_v[rxi]*1e-3, yerr=r_sig_v[rxi]*1e-3, label='Measurements: RX{}'.format(rxi)) ax.plot(t_obs_h, range_v[rxi]*1e-3, label='Maximum a posteriori: RX{}'.format(rxi)) ax.plot(t_obs_h, range_v_prior[rxi]*1e-3, label='Maximum a priori: RX{}'.format(rxi)) ax.set( xlabel='Time [h]', ylabel='2-way-Range [km]', ) ax.legend() ax = fig.add_subplot(224) ax.errorbar(t_obs_h, v_obs_v[rxi]*1e-3, yerr=v_sig_v[rxi]*1e-3, label='Measurements: RX{}'.format(rxi)) ax.plot(t_obs_h, vel_v[rxi]*1e-3, label='Maximum a posteriori: RX{}'.format(rxi)) ax.plot(t_obs_h, vel_v_prior[rxi]*1e-3, label='Maximum a priori: RX{}'.format(rxi)) ax.set( xlabel='Time [h]', ylabel='2-way-Velocity [km/s]', ) ax.legend() #dpt.posterior(trace['state']*1e-3, var, show=False) plt.show()