예제 #1
0
def test_teme_loopback():
    from_coo = TEME(1 * u.AU, 2 * u.AU, 3 * u.AU, obstime='2001-01-01')
    to_frame = TEME(obstime='2001-06-30')

    explicit_coo = from_coo.transform_to(ICRS()).transform_to(to_frame)
    implicit_coo = from_coo.transform_to(to_frame)

    # Confirm that the explicit transformation changes the coordinate
    assert not allclose(
        explicit_coo.cartesian.xyz, from_coo.cartesian.xyz, rtol=1e-10)

    # Confirm that the loopback matches the explicit transformation
    assert_allclose(explicit_coo.cartesian.xyz,
                    implicit_coo.cartesian.xyz,
                    rtol=1e-10)
예제 #2
0
def convert(t,
            states,
            in_frame,
            out_frame,
            logger=None,
            profiler=None,
            **kwargs):
    '''Perform predefined coordinate transformations. Always returns a copy of the array.
    '''

    if logger is not None:
        logger.info(
            f'frames:convert: in_frame={in_frame}, out_frame={out_frame}')
    if profiler is not None:
        profiler.start(f'frames:convert:{in_frame}->{out_frame}')

    in_frame = in_frame.upper()
    out_frame = out_frame.upper()

    if in_frame == out_frame:
        return states.copy()

    if in_frame == 'TEME':
        astropy_states = _convert_to_astropy(states, TEME, obstime=t)
    elif in_frame in ['ITRS', 'ITRF']:  #Reference System VS Reference Frame
        astropy_states = _convert_to_astropy(states, ITRS, obstime=t)
    elif in_frame in ['ICRS', 'ICRF']:
        astropy_states = _convert_to_astropy(states, ICRS)
    elif in_frame in ['GCRS', 'GCRF']:
        astropy_states = _convert_to_astropy(states, GCRS, obstime=t)
    else:
        raise ValueError(
            f'In frame "{in_frame}" not recognized, please perform manual transformation'
        )

    if out_frame in ['ITRS', 'ITRF']:
        out_states = astropy_states.transform_to(ITRS(obstime=t))
    elif out_frame == 'TEME':
        out_states = astropy_states.transform_to(TEME(obstime=t))
    elif out_frame in ['ICRS', 'ICRF']:
        out_states = astropy_states.transform_to(ICRS())
    elif out_frame in ['GCRS', 'GCRF']:
        out_states = astropy_states.transform_to(GCRS(obstime=t))
    else:
        raise ValueError(
            f'Out frame "{out_frame}" not recognized, please perform manual transformation'
        )

    rets = states.copy()
    rets[:3, ...] = out_states.cartesian.xyz.to(units.m).value
    rets[3:, ...] = out_states.velocity.d_xyz.to(units.m / units.s).value

    if logger is not None:
        logger.info('frames:convert:completed')
    if profiler is not None:
        profiler.stop(f'frames:convert:{in_frame}->{out_frame}')

    return rets
예제 #3
0
    def gen_trajectory(self, tle, interval, **kwargs):
        """
        Generates the trajectory (time and coordinate information) for the given
        interval with the internal stepsize.
        Parameters
        ----------
        tle : TLE
            Two-Line-Element initial orbit information (TEME mean orbital elements)
        interval : TimeInterval
            Time interval for which the ephemeris will be generated
        kwargs
            No keywords defined
        Returns
        -------
        Trajectory
            The output trajectory (in `GCRS`)
        """

        # ****** Generate the pos, vel vectors for each time instant ******

        # generate the output timelist
        time_list = self._generate_time_list(interval)

        # Run the propagation and init pos and vel vectors in TEME
        e, r_list, v_list = tle.satrec.sgp4_array(time_list.jd1, time_list.jd2)

        # Load the time, pos, vel info into astropy objects (shallow copied)
        rv_list_teme = CartesianRepresentation(
            r_list, unit=u.km, xyz_axis=1
        ).with_differentials(CartesianDifferential(v_list, unit=u.km / u.s, xyz_axis=1))

        rv_list_gcrs = TEME(
            rv_list_teme,
            obstime=time_list,
            representation_type="cartesian",
            differential_type="cartesian",
        ).transform_to(GCRS(obstime=time_list))

        # trajectory in astropy
        traj_astropy = SkyCoord(
            rv_list_gcrs,
            obstime=time_list,
            frame="gcrs",
            representation_type="cartesian",
            differential_type="cartesian",
        )

        # Init trajectory in Trajectory object
        trajectory = Trajectory(traj_astropy)

        return trajectory
예제 #4
0
def el2rv(inc, raan, ecc, argp, mean_anomaly, mean_motion, epoch):
    """
    Converts mean orbital elements to state vector
    """

    time_tle = epoch.jd - 2433281.5
    sat = Satrec()
    sat.sgp4init(
        WGS84,
        "i",
        0,
        time_tle,
        0.0,
        0.0,
        0.0,
        ecc,
        argp,
        inc,
        mean_anomaly,
        mean_motion,
        raan,
    )

    errorCode, rTEME, vTEME = sat.sgp4(epoch.jd1, epoch.jd2)
    if errorCode != 0:
        raise RuntimeError(SGP4_ERRORS[errorCode])

    pTEME = coord.CartesianRepresentation(rTEME * u.km)
    vTEME = coord.CartesianDifferential(vTEME * u.km / u.s)
    svTEME = TEME(pTEME.with_differentials(vTEME), obstime=epoch)

    svITRS = svTEME.transform_to(coord.ITRS(obstime=epoch))

    orb = Orbit.from_coords(Earth, svITRS)

    return orb.r, orb.v
예제 #5
0
def test_itrs_to_teme():
    """Check the coordinate transform accuracy."""
    # test_frame = "TEME"
    allowable_pos_diff = 300 * u.mm
    allowable_vel_diff = 0.23 * u.mm / u.s

    rv_teme = rv_itrs_true.transform_to(TEME(obstime=time))

    r_diff = pos_err(rv_teme, rv_teme_true)
    v_diff = vel_err(rv_teme, rv_teme_true)

    # print(f"r {rv_teme.name} diff      :  {r_diff}")
    # print(f"v {rv_teme.name} diff      :  {v_diff}")

    assert r_diff < allowable_pos_diff
    assert v_diff < allowable_vel_diff
예제 #6
0
def test_teme_itrf():
    """
    Test case transform from TEME to ITRF.

    Test case derives from example on appendix C of Vallado, Crawford, Hujsak & Kelso (2006).
    See https://celestrak.com/publications/AIAA/2006-6753/AIAA-2006-6753-Rev2.pdf
    """
    v_itrf = CartesianDifferential(-3.225636520,
                                   -2.872451450,
                                   5.531924446,
                                   unit=u.km / u.s)
    p_itrf = CartesianRepresentation(-1033.479383,
                                     7901.2952740,
                                     6380.35659580,
                                     unit=u.km,
                                     differentials={'s': v_itrf})
    t = Time("2004-04-06T07:51:28.386")

    teme = ITRS(p_itrf, obstime=t).transform_to(TEME(obstime=t))
    v_teme = CartesianDifferential(-4.746131487,
                                   0.785818041,
                                   5.531931288,
                                   unit=u.km / u.s)
    p_teme = CartesianRepresentation(5094.18016210,
                                     6127.64465050,
                                     6380.34453270,
                                     unit=u.km,
                                     differentials={'s': v_teme})

    assert_allclose(teme.cartesian.without_differentials().xyz,
                    p_teme.without_differentials().xyz,
                    atol=30 * u.cm)

    assert_allclose(teme.cartesian.differentials['s'].d_xyz,
                    p_teme.differentials['s'].d_xyz,
                    atol=1.0 * u.cm / u.s)

    # test round trip
    itrf = teme.transform_to(ITRS(obstime=t))
    assert_allclose(itrf.cartesian.without_differentials().xyz,
                    p_itrf.without_differentials().xyz,
                    atol=100 * u.cm)
    assert_allclose(itrf.cartesian.differentials['s'].d_xyz,
                    p_itrf.differentials['s'].d_xyz,
                    atol=1 * u.cm / u.s)
예제 #7
0
def test_itrs_roundtrip():
    """Check whether transforming to a coord and then
    transforming back yields the same output."""
    # test_frame = "ITRS"
    allowable_pos_diff = 1.5e-6 * u.mm
    allowable_vel_diff = 2.8e-6 * u.mm / u.s

    rv_teme = rv_itrs_true.transform_to(TEME(obstime=time))
    rv_itrs_from_teme = rv_teme.transform_to(ITRS(obstime=time))

    r_diff = pos_err(rv_itrs_from_teme, rv_itrs_true)
    v_diff = vel_err(rv_itrs_from_teme, rv_itrs_true)

    # print(f"r {rv_itrs_true.name} diff      :  {r_diff}")
    # print(f"v {rv_itrs_true.name} diff      :  {v_diff}")

    assert r_diff < allowable_pos_diff
    assert v_diff < allowable_vel_diff
예제 #8
0
    def propagate(tle, time):
        """
        Computes the coordinates at the target `time` using the source `TLE` mean
        orbital elements.

        Parameters
        ----------
        tle : TLE
            Mean orbital elements (Two-Line-Element)
        time : Time
            Target time for propagation

        Returns
        -------
        coords : SkyCoord
            Coordinates at target time (in `GCRS`)

        Raises
        ------
        SGP4GeneralError
            Errors in SGP4 propagation
        SGP4SatDecayedError
            Satellite coordinates at required coordinates are below decay altitude.
        """
        # compute coords at time
        e, r, v = tle.satrec.sgp4(time.utc.jd1, time.utc.jd2)

        # check error code
        SGP4Propagator.__handle_err_code(e)

        v_teme = CartesianDifferential(np.asarray(v), unit=u.km / u.s)
        r_teme = CartesianRepresentation(np.asarray(r), unit=u.km)
        rv_gcrs = TEME(r_teme.with_differentials(v_teme), obstime=time).transform_to(
            GCRS(obstime=time)
        )

        return SkyCoord(
            rv_gcrs, representation_type="cartesian", differential_type="cartesian"
        )
예제 #9
0
def test_teme_to_tirs_no_vel():
    """Check whether coord transform without velocity is possible."""
    rv_teme_no_vel = TEME(r_teme_true,
                          obstime=time,
                          representation_type="cartesian")
    rv_teme_no_vel.transform_to(TIRS(obstime=time))
예제 #10
0
    [-1033.47503120, 7901.30558560, 6380.34453270], unit=u.km)
rv_tirs_true = TIRS(
    r_tirs_true.with_differentials(v_tirs_true),
    obstime=time,
    representation_type="cartesian",
    differential_type="cartesian",
)

# Vallado IAU 2000 - Table 3-6 TEME
v_teme_true = CartesianDifferential(
    [-4.7461314870, 0.7858180410, 5.5319312880], unit=u.km / u.s)
r_teme_true = CartesianRepresentation(
    [5094.18016210, 6127.64465950, 6380.34453270], unit=u.km)
rv_teme_true = TEME(
    r_teme_true.with_differentials(v_teme_true),
    obstime=time,
    representation_type="cartesian",
    differential_type="cartesian",
)


def _init_orbit_mars():
    """Initialises the test orbit in a Martian orbit."""
    obstime = Time("2020-01-10T11:30:00.0003", scale="tdb")

    v_mars = CartesianDifferential(
        [3.057934230169251e-01, -3.068219328642159e00, -1.397389382391015e00],
        unit=u.km / u.s,
    )
    r_mars = CartesianRepresentation(
        [1.786125452441044e03, -1.191541086863880e03, 3.003639539248147e03],
        unit=u.km)
예제 #11
0
        0.0,
        0.0,
        ecc,
        argp,
        inc,
        m_ano,
        m_mot,
        raan,
    )
    errorCode, rTEME, vTEME = sat.sgp4(epoch.jd1, epoch.jd2)
    if errorCode != 0:
        raise RuntimeError(SGP4_ERRORS[errorCode])

    # Convert state vector from TEME (True Equator Mean Equinox) to ITRS
    pTEME = coord.CartesianRepresentation(rTEME * u.km)
    vTEME = coord.CartesianDifferential(vTEME * u.km / u.s)
    svTEME = TEME(pTEME.with_differentials(vTEME), obstime=iss.epoch)
    svITRS = svTEME.transform_to(coord.ITRS(obstime=iss.epoch))
    sv = Orbit.from_coords(Earth, svITRS)

    # Display results
    print("State vector [rv2el]")
    print(f"     r = {sv.r}")
    print(f"     v = {sv.v}")
    print()

    print("State vector differences [poliastro - rv2el]")
    print(f"    dr = {iss.r - sv.r}")
    print(f"    dv = {iss.v - sv.v}")
    print()
예제 #12
0
t = lines[6]
url = re.findall(url_regex, lines[8])[0][0]

satellite = Satrec.twoline2rv(s, t)

# Epoch March 26th, 2020, at 21:52:56
t = Time('2020-03-26T21:52:56.0', format='isot', scale='utc')
error_code, teme_p, teme_v = satellite.sgp4(t.jd1, t.jd2)  # in km and km/s

if error_code != 0:
	raise RuntimeError(SGP4_ERRORS[error_code])

# Convert SGP4 TEME to Astropy native TEME
teme_p = CartesianRepresentation(teme_p*u.km)
teme_v = CartesianDifferential(teme_v*u.km/u.s)
teme = TEME(teme_p.with_differentials(teme_v), obstime=t)

'''
itrs = teme.transform_to(ITRS(obstime=t))  
location = itrs.earth_location  
print(location.geodetic)
'''

# Lat/Lon/Alt of the Washington Monumnet
monumentLat = 38.889484
monumentLon = -77.035278
monumnetAlt = 169			# meters

# get the locations into similar coordinate system objects
#satellilteEarthLocation = ?.from_geocentric(xSat,ySat,zSat)
monumentEarthLocation = EarthLocation.from_geodetic(monumentLon,monumentLat,monumnetAlt)