def gen_trajectory(self, tle, interval): """ 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 Returns ------- Trajectory The output trajectory (in `GCRS`) """ # generate number of steps (forced to rounded up int) no_of_steps = np.ceil((interval.duration / self.stepsize).decompose()) # make sure there are enough elements for interpolation if no_of_steps < Trajectory.reqd_min_elements(): no_of_steps = Trajectory.reqd_min_elements() # time list time_list = interval.start + self.stepsize * np.arange(0, no_of_steps) time_list.format = "isot" # ****** Generate the pos, vel vectors for each time instant ****** # Run the propagation and init pos and vel vectors in TEME e, r_list, v_list = 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
def gen_trajectory(self, tle, interval): """ 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 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
def test_itrs_to_teme(): """Check the coordinate transform accuracy.""" # test_frame = "TEME" allowable_pos_diff = 300 * u.mm allowable_vel_diff = 0.21 * 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 {test_frame} diff : {r_diff}") # print(f"v {test_frame} diff : {v_diff}") assert approx(r_diff.value, abs=allowable_pos_diff.value) == 0.0 assert approx(v_diff.value, abs=allowable_vel_diff.value) == 0.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.2e-9 * 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 {test_frame} diff : {r_diff}") # print(f"v {test_frame} diff : {v_diff}") assert approx(r_diff.value, abs=allowable_pos_diff.value) == 0.0 assert approx(v_diff.value, abs=allowable_vel_diff.value) == 0.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", )
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))
[-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 pos_err(rv_test, rv_true): """ Computes positional error between two vectors defined in a frame. Parameters ---------- rv_test : State with position vector under test rv_true : State with true position vector Returns -------