def cartesian2keplerian(epoch, state, frame='ecliptic', mu=cnst.GM): """Uses spiceypy to convert heliocentric cartesian states to Keplerian orbital elements. Parameters: ----------- epoch ... epoch of orbital elements [JD] state ... cartesian state (x,y,z,vx,vy,vz) frame ... coordinate frame of Cartesian states: 'ecliptic', 'icrf' mu ... gravitational parameter Returns: -------- kep ... orbital elements array a = pericenter distance e = eccentricity i = inclination (deg) w = argument of pericenter (deg) node = longitude of the ascending node (deg) M = mean anomaly at epoch (deg) T0 = epoch mu = gravitational parameter External dependencies: ---------------------- spiceypy (imported as sp) numpy (imported as np) """ # Output for spiceypy.oscelt: # q = pericenter distance # e = eccentricity # i = inclination (deg) # node = longitude of the ascending node (deg) # w = argument of pericenter (deg) # M = mean anomaly at epoch (deg) # T0 = epoch # mu = gravitational parameter estate = frameCheck(state, frame) oscelt = sp.oscelt(array(estate), epoch, mu) kep = [] # semimajor axis a from q kep.append(oscelt[0] / (1 - oscelt[1])) # eccentricity kep.append(oscelt[1]) # inclination kep.append(rad2deg(oscelt[2])) # w: argument of pericenter kep.append(rad2deg(oscelt[4])) # node kep.append(rad2deg(oscelt[3])) # mean anomaly kep.append(rad2deg(oscelt[5])) return kep, epoch
def conic_elements(self): """Compute the conic elements of the orbiter at the current time. Uses SPICE. """ time = self.trv[0] rv_km = self.trv[1:] / 1000.0 # convert to km, km/sec elements = spice.oscelt(rv_km, time, self.conic_mu * 1e-9) elements[0] *= 1000.0 # convert perifocal distance to meters return elements
def cartesian2keplerian(epoch, state, mu=0.01720209895**2): """Uses spiceypy to convert Cartesian states to Keplerian orbital elements Parameters: ----------- epoch ... epoch of orbital elements [JD] state ... Cartesian state (x,y,z,vx,vy,vz) mu ... Gravitational parameter Returns: -------- kep ... orbital elements array a = pericenter distance e = eccentricity i = inclination (deg) w = argument of pericenter (deg) node = longitude of the ascending node (deg) M = mean anomaly at epoch (deg) T0 = epoch mu = gravitational parameter External dependencies: ---------------------- spiceypy (imported as sp) numpy (imported as np) """ # Output for spiceypy.oscelt: # q = pericenter distance # e = eccentricity # i = inclination (deg) # node = longitude of the ascending node (deg) # w = argument of pericenter (deg) # M = mean anomaly at epoch (deg) # T0 = epoch # mu = gravitational parameter oscelt = sp.oscelt(state, epoch, mu) kep = [] # semimajor axis a from q kep.append(oscelt[0] / (1 - oscelt[1])) # eccentricity kep.append(oscelt[1]) # inclination kep.append(np.rad2deg(oscelt[2])) # w: argument of pericenter kep.append(np.rad2deg(oscelt[4])) # node kep.append(np.rad2deg(oscelt[3])) # mean anomaly kep.append(np.rad2deg(oscelt[5])) return kep, epoch, mu
def comet(et,p,v): state = [p[0],p[1],p[2],v[0],v[1],v[2]] # km, km/s elts = spice.oscelt(state,et,mu) # compute osculating Keplerian parameters from a state vector RP,ECC,INC,LNODE,ARGP,M0,T0,MU = elts a = np.abs(RP/(1-ECC)) n = np.sqrt(MU/(a*a*a)) # rad/s TP = T0 - M0/n #fixme: need a case distinction for the sign of this correction? RP = RP/au INC = rad2deg(INC) LNODE = rad2deg(LNODE) ARGP = rad2deg(ARGP) TP = float(spice.timout(TP,"JULIAND.######## ::TDB")) #fixme return RP,ECC,ARGP,LNODE,INC,TP
def oscelt(self, date, frame="ECLIPJ2000", mu=None): """Concic osculating orbital elements. Returns the orbit from oscelt in the SPICE toolkit. The results are unreliable for eccentricities very close to 1.0, specific angular momentum near zero, and inclinations near 0 or 180 degrees. See the SPICE toolkit for notes. Parameters ---------- date : string, float, astropy Time, datetime Processed via `util.date2time`. frame : string The name of a SPICE reference frame. mu : float, optional `G M` of the primary body, or `None` to use the Sun. Returns ------- orbit : dict Orbital parameters as a dictionary. """ import astropy.units as u from mskpy.ephem import GM_sun from mskpy.util import jd2time et = core.date2et(date) state, lt = spice.spkez(self.naifid, et, frame, "NONE", 10) if mu is None: mu = GM_sun.to('km3 / s2').value o = spice.oscelt(state, et, mu) orbit = {} orbit['q'] = (o[0] * u.km).to(u.au) orbit['e'] = o[1] orbit['i'] = (o[2] * u.rad).to(u.deg) orbit['node'] = (o[3] * u.rad).to(u.deg) orbit['peri'] = (o[4] * u.rad).to(u.deg) orbit['n'] = (o[5] * u.rad).to(u.deg) / u.s orbit['t'] = jd2time(float(core.et2jd(o[6]))) return orbit
method='CG') opt2 = sc.optimize.minimize(dist1, [node, omega, opt1.x[0], opt1.x[1]], args=(elts_ast, Gm), method='CG') print(opt2.x) new_mean = toMean(opt2.x[3], e) new_elts_ast = np.array( [a, e, inc, opt2.x[0], opt2.x[1], new_mean, et, Gm]) new_pos_ast = convertAst(sp.conics(new_elts_ast, 0)) new_earth_pos = convertEarth( sp.spkezr('EARTH', opt2.x[2], 'J2000', 'LT+S', 'SUN')) distance = np.linalg.norm(new_earth_pos[0:3] - new_pos_ast[0:3]) #print(distance) if distance > r_earth: new_elts_ast = sp.oscelt(correction(new_earth_pos - new_pos_ast), T0, Gm) final_data = [ C_Time_earth, new_elts_ast[0] * 6.6846e-9, new_elts_ast[1], new_elts_ast[2], new_elts_ast[3], new_elts_ast[4], new_elts_ast[5] ] with open('new_earth_impactors.csv', 'a', newline='') as file: writer = csv.writer(file) writer.writerow(final_data) #print(new_elts_ast[0]*) # with open('new_earth_impactors.csv','w' ,newline ='' ) as file: # writer= csv.writer(file) # writer.writerow
# Compute the state vector and the corresponding orbital elements of 67P as # seen from the Sun # Create an ET (2004 day 1 is the minimum date-time in the corresponding SPICE # spk kernel) sample_et = spiceypy.utc2et('2004-001T00:00:00') # Compute the state vector of 67P ... COMET_67P_STATE, _ = spiceypy.spkgeo(targ=1000012, \ et=sample_et, \ ref='ECLIPJ2000', \ obs=10) # ... and the corresponding orbital elements COMET_67P_ORB_ELEM = spiceypy.oscelt(state=COMET_67P_STATE, \ et=sample_et, \ mu=GM_SUN) #%% # Now we want to determine when 67P enters the SOI of Jupiter. As a starting # date we set the 1st January 1961 and compute everything back in time datetime_stamp = datetime.datetime(year=2017, month=1, day=1) # Our computation will be performed within a while condition (to check whether # 67P entered the SOI or not); thus we need to set an initial value for the # while condition. Here: a very large distance between 67P and Jupiter comet_jup_dist = 10.0**10 # While condition: Compute the following coding part as long as 67P did not # enter Jupiter's SOI
def __load_stereo_kernals__(self): """ Function to load in the STEREO specific kernals """ # Load in the necessary Spice kernels kernals_dict = self.__get_kernal_files__() # Load in the predicted ephemeris, and collect all ephem files. # >> Initialise record of maximum dates covered by the ephemeris self.__PredMaxdates__ = { 'sta': Time(0.0, format='jd'), 'stb': Time(0.0, format='jd') } # >> Initialise the conic to cover the predicted ephemeris outside covered range self.__PredConic__ = {'sta': None, 'stb': None} self.__mu__ = 1.32712440018 self.__AllPredictedEphem__ = [] for craft in ['sta', 'stb']: # Load in the predicted ephemeris files key = craft + "_ephem_filelist" with open(kernals_dict[key]) as f: all_ephem_files = f.read().splitlines() for ephem_file in all_ephem_files: full_ephem_path = os.path.join(kernals_dict['data_root'], ephem_file) if os.path.exists(full_ephem_path): spice.furnsh(full_ephem_path) self.__AllPredictedEphem__.append(full_ephem_path) # Extract the orbital parameters for conic extrapolation on predicted ephemeris dates_min, dates_max, craft_ids = self.__get_spice_range__( full_ephem_path) if dates_max > self.__PredMaxdates__[craft]: self.__PredMaxdates__[craft] = dates_max state = self.get_coord(dates_max, craft, system='HAE') et = spice.utc2et(dates_max.isot) elts = spice.oscelt(state, et, self.__mu__) self.__PredConic__[craft] = elts else: print("Error: File not found - {}".format( full_ephem_path)) # Load in the definitive ephemeris, and collect all ephem files. # >> Initialise record of maximum dates covered by the ephemeris self.__DefMaxdates__ = { 'sta': Time(0.0, format='jd'), 'stb': Time(0.0, format='jd') } # >> Initialise the conic to cover the predicted ephemeris outside covered range self.__DefConic__ = {'sta': None, 'stb': None} self.__AllDefEphem__ = [] for craft in ['sta', 'stb']: # Load in the predicted ephemeris files key = craft + "_def_ephem_filelist" with open(kernals_dict[key]) as f: all_ephem_files = f.read().splitlines() for ephem_file in all_ephem_files: full_ephem_path = os.path.join(kernals_dict['data_root'], ephem_file) if os.path.exists(full_ephem_path): spice.furnsh(full_ephem_path) self.__AllDefEphem__.append(full_ephem_path) # Extract the orbital parameters for conic extrapolation on definitive ephemers dates_min, dates_max, sid = self.__get_spice_range__( full_ephem_path) if dates_max > self.__DefMaxdates__[craft]: self.__DefMaxdates__[craft] = dates_max state = self.get_coord(dates_max, craft, system='HAE') et = spice.utc2et(dates_max.isot) elts = spice.oscelt(state, et, self.__mu__) self.__DefConic__[craft] = elts else: print("Error: File not found - {}".format( full_ephem_path)) # TODO: Load in Attitude kernals if want to use CMAT stuff? return
indexIni = int(sys.argv[2]) indexFin = int(sys.argv[3]) print "\nSearching orbital elements from %lf to %lf\n" % (indexIni, indexFin) time, x, y, z, vx, vy, vz = loadtxt(sys.argv[1], unpack=True) x = x * ULG / 100 / 1000 y = y * ULG / 100 / 1000 z = z * ULG / 100 / 1000 peri = zeros(len(time)) ecc = zeros(len(time)) inclination = zeros(len(time)) for i in range(len(time)): #print time[i], x[i], y[i], z[i], vx[i], vy[i], vz[i] elements = sp.oscelt([x[i], y[i], z[i], vx[i], vy[i], vz[i]], time[i], mu) #print elements[0],elements[1],elements[2],elements[3],elements[4],elements[5],elements[6],elements[7] peri[i] = elements[0] ecc[i] = elements[1] inclination[i] = elements[2] filter = logical_and(time >= indexIni, time <= indexFin) print filter, peri[filter] * 1000 * 100 / ULG print peri * 1000 * 100 / ULG print mean( peri[filter]) * 1000 * 100 / ULG, mean(ecc), mean(inclination) * 180.0 / pi