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
Exemple #3
0
    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))
Exemple #5
0
    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.
Exemple #6
0
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
Exemple #7
0
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
Exemple #8
0
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
Exemple #9
0
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
Exemple #10
0
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
Exemple #11
0
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()
Exemple #12
0
    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))
Exemple #13
0
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()
Exemple #14
0
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
Exemple #15
0
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))
Exemple #16
0
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,
Exemple #17
0
    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'])
Exemple #18
0
)
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)
Exemple #19
0
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.
Exemple #23
0
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]))
Exemple #24
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
Exemple #25
0
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))
Exemple #27
0
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()