def main(): for size in 10, 1000, 100000: jd = np.linspace(2414992.5, 2471184.50, size) kernel = SPK.open('de421.bsp') ephem = Ephemeris(de421) mars = kernel[0,4] print(size) print('-- old code (2 successive runs):') t0 = time() ephem.position('mars', jd) print(time() - t0) t0 = time() ephem.position('mars', jd) print(time() - t0) print('-- new SPK-powered code (2 successive runs):') t0 = time() mars.compute(jd) print(time() - t0) t0 = time() mars.compute(jd) print(time() - t0) print()
def test_scalar_input(self): import de421 e = Ephemeris(de421) self.check0(*e.compute("earthmoon", 2414994.0)) self.check1(*e.compute("earthmoon", 2415112.5))
def get_earth_to_sun(JD): eph = Ephemeris(de421) AU = 149597870.7 # km/AU barycenter = eph.position('earthmoon', JD) moonvector = eph.position('moon', JD) earth = barycenter - moonvector * eph.earth_share return -1.0 * vector(earth)/AU
def setUp(self): try: import de421 except ImportError: raise SkipTest('the "de421" ephemeris package is not installed') self.eph = Ephemeris(de421) self.jalpha = self.eph.jalpha self.jomega = self.eph.jomega
def test_ephemeris_end_date(self): import de421 e = Ephemeris(de421) x, y, z = e.position("earthmoon", e.jomega) self.assertAlmostEqual(x, -2.81196460e07, delta=1.0) self.assertAlmostEqual(y, 1.32000379e08, delta=1.0) self.assertAlmostEqual(z, 5.72139011e07, delta=1.0)
def setUp(self): try: import de421 except ImportError: raise SkipTest('the "de421" ephemeris package has not been' ' installed with "pip install de421"') self.eph = Ephemeris(de421) self.jalpha = self.eph.jalpha self.jomega = self.eph.jomega
def test_array_input(self): import de421 e = Ephemeris(de421) v = e.compute("earthmoon", np.array([2414994.0, 2415112.5])) v = np.array(v) self.check0(*v[:, 0]) self.check1(*v[:, 1])
def find_residuals(r, rdot, inputJulian, dec_to_check, ra_to_check, timePass): #Verlet Integrator k = 0.01720209895 # Gaussian gravitational consgtant dtau = 0.001 # This is Gaussian Days dt = dtau / k # This is in mean solar days tao = 0.0 deltao = 0.001 r = r2guess rdot = r2Dot r0Verlet = r r1Verlet = r0Verlet + (rdot * deltao) + (0.5*acceleration(r0Verlet, Rho2hat*Rho2)*(deltao**2)) while tao <= timePass*k: r2Update = (2*r1Verlet) - r0Verlet + acceleration(r1Verlet, Rho2hat*Rho2)*(deltao**2) r0Verlet = r1Verlet r1Verlet = r2Update tao += deltao #print r1Verlet #Ephemeris Generation AU = 149597870.7 # km/AU eph = Ephemeris(de421) barycenter = eph.position('earthmoon', inputJulian) moonvector = eph.position('moon', inputJulian) earth = barycenter - moonvector * eph.earth_share R0 = vector(earth)/AU # This is the Sun to Earth center vector in Equatorial system #print R0 R_geocentric = -1.0*R0 #gg = ? rInput = r1Verlet rho = (rInput + R_geocentric) rhohat = norm(rho) declination = arcsin(rhohat.z) RA = arccos(rhohat.x/(cos(declination))) if rhohat.y < 0: RA = 2*math.pi - RA RA_residuals = abs(RA - ra_to_check)/ra_to_check Dec_residuals = abs(declination - dec_to_check)/dec_to_check return RA_residuals, Dec_residuals
def EphemR (JulianDate): #Import Ephem 421 to get vector from Earth to Sun (R) AU = 149597870.7 # km/AU eph = Ephemeris(de421) barycenter = eph.position('earthmoon', JulianDate) moonvector = eph.position('moon', JulianDate) earth = barycenter - moonvector * eph.earth_share R0 = vector(earth)/(AU) #This is the Sun to Earth center vector in Equatorial system R_geocentric = -1.*R0 #Multiply by -1 to get Earth to Sun #gg = #Our geocentric vector #R_topocentric = R_geocentric - gg #Subtract our topocentric vector return R_geocentric
def ephemeris_sun_lunar_ECRF(Julian_date): # import Julian_date # month = 6 # day = 1 # year = 1980 # hour = 12 # minute = 0 # second = 0 # jd = Julian_date.Julian_date(month, day, year, hour, minute, second) # k = ephemeris('moon', jd)#2444391.5 # print('position=',k[0,:]) # print('velocity=', k[1, :]) barycenter_position = ephemeris_position_ICRF('earthmoon', Julian_date) import de405 from jplephem import Ephemeris eph = Ephemeris(de405) Position_sun = ephemeris_position_ICRF('sun', Julian_date) Position_moon_ECRF = ephemeris_position_ICRF('moon', Julian_date) # 本身就是相对地球的 Position_earth = barycenter_position - Position_moon_ECRF * eph.earth_share Position_sun_ECRF = Position_sun - Position_earth return Position_sun_ECRF, Position_moon_ECRF
def planets_pos(self): from jplephem import Ephemeris import de421 from PyKEP import epoch self.eph = Ephemeris(de421) earthpos = [] marspos = [] venuspos = [] for ep in self.sc_state[3]: posSun, __ = self.eph.position_and_velocity('sun', epoch(ep, epoch.epoch_type.MJD2000).jd) positione, __ = self.eph.position_and_velocity('earthmoon', epoch(ep, epoch.epoch_type.MJD2000).jd) positione = self.eq2eclipt(positione - posSun) earthpos.append(positione) positionm, __ = self.eph.position_and_velocity('mars', epoch(ep, epoch.epoch_type.MJD2000).jd) positionm = self.eq2eclipt(positionm - posSun) marspos.append(positionm) positionv, __ = self.eph.position_and_velocity('venus', epoch(ep, epoch.epoch_type.MJD2000).jd) positionv = self.eq2eclipt(positionv - posSun) venuspos.append(positionv) self.earthpos_km = [earthpos[i].reshape((1,3)).tolist()[0] for i in range(len(earthpos))] self.marspos_km = [marspos[i].reshape((1,3)).tolist()[0] for i in range(len(earthpos))] self.venuspos_km = [venuspos[i].reshape((1,3)).tolist()[0] for i in range(len(earthpos))]
def test_ephemeris(): # import Julian_date # month = 6 # day = 1 # year = 1980 # hour = 12 # minute = 0 # second = 0 # jd = Julian_date.Julian_date(month, day, year, hour, minute, second) # k = ephemeris('moon', jd)#2444391.5 # print('position=',k[0,:]) # print('velocity=', k[1, :]) Sun_state = ephemeris('sun', 2444391.5) # 太阳星历 barycenter_statement = ephemeris('earthmoon', 2444391.5) import de405 from jplephem import Ephemeris eph = Ephemeris(de405) Position_sun = Sun_state[0, :] Velocity_sun = Sun_state[1, :] Moon_state = ephemeris('moon', 2444391.5) # 本身就是相对地球的 Position_moon = Moon_state[0, :] Velocity_moon = Moon_state[1, :] Earth_state = barycenter_statement - Moon_state * eph.earth_share Position_earth = Earth_state[0, :] Velocity_earth = Earth_state[1, :] R_sun_earth = Position_sun - Position_earth # 地心ICRF参考系下太阳的位置矢量 V_sun_earth = Velocity_sun - Velocity_earth # 地心ICRF参考系下太阳的速度矢量 print(R_sun_earth, V_sun_earth)
class LegacyTests(_CommonTests, TestCase): def setUp(self): try: import de421 except ImportError: raise SkipTest('the "de421" ephemeris package has not been' ' installed with "pip install de421"') self.eph = Ephemeris(de421) self.jalpha = self.eph.jalpha self.jomega = self.eph.jomega def position(self, name, tdb, tdb2=0.0): return self.eph.position(name, tdb, tdb2) def position_and_velocity(self, name, tdb, tdb2=0.0): return self.eph.position_and_velocity(name, tdb, tdb2) def test_names(self): self.assertEqual(self.eph.names, ( 'earthmoon', 'jupiter', 'librations', 'mars', 'mercury', 'moon', 'neptune', 'nutations', 'pluto', 'saturn', 'sun', 'uranus', 'venus', )) def test_legacy_compute_method(self): pv = self.eph.compute('earthmoon', 2414994.0) self.check0(pv[:3], pv[3:]) pv = self.eph.compute('earthmoon', np.array([2414994.0, 2415112.5])) self.check0(pv[:3, 0], pv[3:, 0]) self.check1(pv[:3, 1], pv[3:, 1]) def test_ephemeris_end_date(self): x, y, z = self.position('earthmoon', self.jomega) self.assertAlmostEqual(x, -94189805.73967789, delta=epsilon_m) self.assertAlmostEqual(y, 1.05103857e+08, delta=1.0) self.assertAlmostEqual(z, 45550861.44383482, delta=epsilon_m)
def planet_elements_and_sv(planet_id, year, month, day, hour, minute, second): global mu mu = 1.327124e11 #calculating julian time j0 = sum(jdcal.gcal2jd(year, month, day)) ut = (hour+minute/60+second/3600)/24 jd = j0+ut #determining state vectors eph = Ephemeris(de421) planet = month_planet_names.planet_name(planet_id) if planet=="earth": barycenter = eph.position_and_velocity('earthmoon', jd) moonvector = eph.position_and_velocity('moon', jd) r = barycenter[0] - eph.earth_share*moonvector[0] v = barycenter[1] - eph.earth_share*moonvector[1] elif planet=="moon": barycenter = eph.position_and_velocity('earthmoon', jd) moonvector = eph.position_and_velocity('moon', jd) r = barycenter[0] - eph.moon_share*moonvector[0] v = barycenter[1] - eph.moon_share*moonvector[1] mu = 3.986e14 else: r, v = eph.position_and_velocity(planet, jd) r = r.flatten() v = v.flatten()/(24*3600) coe = coe_from_sv.coe_from_sv(r, v, mu) return [coe, r, v, jd]
def JPL_Eph_DE405(JD): ''' :param JD: :return: unit: m type: ndarray r_Mercury(ECRF), r_Venus(ECRF), r_Earth(ICRF), r_Mars(ECRF), r_Jupiter(ECRF), r_Saturn(ECRF), r_Uranus(ECRF), \ r_Neptune(ECRF), r_Pluto(ECRF), r_Moon(ECRF), r_Sun(ECRF),r_SunSSB(ICRF) ''' Sun_state = ephemeris('sun', JD) # 太阳星历 barycenter_statement = ephemeris('earthmoon', JD) import de405 from jplephem import Ephemeris eph = Ephemeris(de405) Moon_To_Earth_state = ephemeris('moon', JD) # 本身就是相对地球的 Earth_state = barycenter_statement - Moon_To_Earth_state * eph.earth_share r_Earth = Earth_state[0, :] r_Sun = Sun_state[0, :] - r_Earth Moon_state = Moon_To_Earth_state r_Moon = Moon_state[0, :] Mercury_state = ephemeris('mercury', JD) r_Mercury = Mercury_state[0, :] - r_Earth Venus_state = ephemeris('venus', JD) r_Venus = Venus_state[0, :] - r_Earth Mars_state = ephemeris('mars', JD) r_Mars = Mars_state[0, :] - r_Earth Jupiter_state = ephemeris('jupiter', JD) r_Jupiter = Jupiter_state[0, :] - r_Earth Saturn_state = ephemeris('saturn', JD) r_Saturn = Saturn_state[0, :] - r_Earth Uranus_state = ephemeris('uranus', JD) r_Uranus = Uranus_state[0, :] - r_Earth Neptune_state = ephemeris('neptune', JD) r_Neptune = Neptune_state[0, :] - r_Earth Pluto_state = ephemeris('pluto', JD) r_Pluto = Pluto_state[0, :] - r_Earth r_SunSSB = Sun_state[0, :] #获取的数据是以km为单位,返回值要求为m为单位,需要乘以1e3转化 return r_Mercury*1e3,r_Venus*1e3,r_Earth*1e3,r_Mars*1e3,r_Jupiter*1e3,r_Saturn*1e3,r_Uranus*1e3, \ r_Neptune*1e3,r_Pluto*1e3,r_Moon*1e3,r_Sun*1e3,r_SunSSB*1e3
def ephemeris_position_ICRF(celestial_body, Julian_date): ''' :param celestial_body: earthmoon mercury pluto venus jupiter moon saturn librations neptune sun mars nutations uranus :param Julian_date:儒略日 :return:天体的位置(km),在ICRF下的,以太阳系质心为原点 ''' import de405 from jplephem import Ephemeris eph = Ephemeris(de405) position = eph.position(celestial_body, Julian_date) # 1980.06.01 position = np.transpose(position) position = np.array(position).flatten() return np.array(position)
def main(): for size in 10, 1000, 100000: jd = np.linspace(2414992.5, 2471184.50, size) kernel = SPK.open('de432.bsp') ephem = Ephemeris(de421) mars = kernel[0,4] print(size) print('-- old code (2 successive runs):') t0 = time() ephem.position('mars', jd) print(time() - t0) t0 = time() ephem.position('mars', jd) print(time() - t0) print('-- new SPK-powered code (2 successive runs):') t0 = time() mars.compute(jd) print(time() - t0) t0 = time() mars.compute(jd) print(time() - t0) print()
class LegacyTests(_CommonTests, TestCase): def setUp(self): try: import de421 except ImportError: raise SkipTest('the "de421" ephemeris package has not been' ' installed with "pip install de421"') self.eph = Ephemeris(de421) self.jalpha = self.eph.jalpha self.jomega = self.eph.jomega def position(self, name, tdb, tdb2=0.0): return self.eph.position(name, tdb, tdb2) def position_and_velocity(self, name, tdb, tdb2=0.0): return self.eph.position_and_velocity(name, tdb, tdb2) def test_names(self): self.assertEqual(self.eph.names, ( 'earthmoon', 'jupiter', 'librations', 'mars', 'mercury', 'moon', 'neptune', 'nutations', 'pluto', 'saturn', 'sun', 'uranus', 'venus', )) def test_legacy_compute_method(self): pv = self.eph.compute('earthmoon', 2414994.0) self.check0(pv[:3], pv[3:]) pv = self.eph.compute('earthmoon', np.array([2414994.0, 2415112.5])) self.check0(pv[:3,0], pv[3:,0]) self.check1(pv[:3,1], pv[3:,1]) def test_ephemeris_end_date(self): x, y, z = self.position('earthmoon', self.jomega) self.assertAlmostEqual(x, -94189805.73967789, delta=epsilon_m) self.assertAlmostEqual(y, 1.05103857e+08, delta=1.0) self.assertAlmostEqual(z, 45550861.44383482, delta=epsilon_m)
def ephemeris(celestial_body, Julian_date): ''' :param celestial_body: earthmoon mercury pluto venus jupiter moon saturn librations neptune sun mars nutations uranus :param Julian_date:儒略日 :return:天体的位置(km),速度(km/s) ''' import de405 from jplephem import Ephemeris eph = Ephemeris(de405) position, velocity = eph.position_and_velocity(celestial_body, Julian_date) # 1980.06.01 position = np.transpose(position) position = np.array(position).flatten() velocity = np.transpose(velocity) velocity = np.array(velocity).flatten() velocity = velocity / 86400 state = np.array([position, velocity]) return np.array(state)
def find_residuals(check_index, decs, ras, JDs, r, r_dot): dec_res_total = 0 ra_res_total = 0 total_ra = 0 total_dec = 0 for i in range(len(decs)): #print str(i + 1) + "/" + str(len(decs)) k = 0.01720209895 time_difference = JDs[i] - JDs[check_index] tau = 0.0 d_tau = 0.0001 * is_negative(time_difference) end_tau = time_difference * k mu = 1.0 r_last = r r_now = r_last + r_dot * d_tau + 0.5 * accel(r_last, mu) * (d_tau**2) tau += d_tau while abs(tau) <= abs(end_tau): tau += d_tau temp = verlet_position(r_now, r_last, d_tau, mu) r_last = temp[1] r_now = temp[0] AU = 149597870.7 # km/AU jd = JDs[i] eph = Ephemeris(de421) R_geocentric = get_earth_to_sun(JD) sun_to_asteroid = r_now earth_to_asteroid = norm( R_geocentric + sun_to_asteroid) # Gets unit vector from Earth to Asteroid RA, Dec = location_to_angles(earth_to_asteroid) RA_Residual = abs(ras[i] - RA) Dec_Residual = abs(decs[i] - Dec) ra_res_total += RA_Residual**2 dec_res_total += Dec_Residual**2 tau = 0 d_tau = 0.000001 k = 0.01720209895 mu = 1.0 sigma = sqrt(ra_res_total + dec_res_total) return sigma
def find_residuals(check_index, decs, ras, JDs, r, r_dot): dec = [] ra = [] for i in range(len(decs)): k = 0.01720209895 time_difference = JDs[i] - JDs[check_index] tau = 0.0 d_tau = 0.0001 * neg(time_difference) end_tau = time_difference * k mu = 1.0 r_last = r r_now = r_last + r_dot * d_tau + 0.5 * accel(r_last, mu) * (d_tau ** 2) tau += d_tau while abs(tau) <= abs(end_tau): tau += d_tau temp = verlet_position(r_now, r_last, d_tau, mu) r_last = temp[1] r_now = temp[0] AU = 149597870.7# km/AU jd = JDs[i] eph = Ephemeris(de421) R_geocentric = get_earth_to_sun(jd) sun_to_asteroid = r_now earth_to_asteroid = norm(R_geocentric + sun_to_asteroid) # Gets unit vector from Earth to Asteroid RA, Dec = location_to_angles(earth_to_asteroid) ra.append(RA) dec.append(Dec) tau = 0 d_tau = 0.000001 k = 0.01720209895 mu = 1.0 return ra, dec
def find_endpoints(check_index, decs, ras, JDs, r, r_dot): dec_res_total = 0 ra_res_total = 0 total_ra = 0 total_dec = 0 times = [] times.append(JDs[0]) times.append(JDs[len(JDs) - 1]) new_RAs = [] new_decs = [] for i in range(len(JDs)): k = 0.01720209895 time_difference = JDs[i] - JDs[check_index] tau = time_difference * k f, g = best_f_and_g(tau, r, r_dot) r_now = f * r + g * r_dot AU = 149597870.7 #km/AU jd = JDs[i] eph = Ephemeris(de421) R_geocentric = get_earth_to_sun(JD) sun_to_asteroid = r_now earth_to_asteroid = norm( R_geocentric + sun_to_asteroid) #Gets unit vector from Earth to Asteroid RA, Dec = location_to_angles(earth_to_asteroid) new_RAs.append(RA) new_decs.append(Dec) """ tau = 0 d_tau = 0.000001 k = 0.01720209895 mu = 1.0 """ return new_RAs, new_decs
def find_residuals(check_index, decs, ras, JDs, r, r_dot): dec_res_total = 0 ra_res_total = 0 total_ra = 0 total_dec = 0 for i in range(len(decs)): k = 0.01720209895 time_difference = JDs[i] - JDs[check_index] tau = time_difference * k mu = 1.0 f, g = better_f_and_g(tau, r, r_dot) r_now = f * r + g * r_dot AU = 149597870.7 # km/AU jd = JDs[i] eph = Ephemeris(de421) R_geocentric = get_earth_to_sun(JD) sun_to_asteroid = r_now earth_to_asteroid = norm( R_geocentric + sun_to_asteroid) # Gets unit vector from Earth to Asteroid RA, Dec = location_to_angles(earth_to_asteroid) RA_Residual = abs(ras[i] - RA) Dec_Residual = abs(decs[i] - Dec) ra_res_total += RA_Residual**2 dec_res_total += Dec_Residual**2 tau = 0 d_tau = 0.000001 k = 0.01720209895 mu = 1.0 sigma = sqrt(ra_res_total + dec_res_total) return sigma
class pos(object): def __init__(self): self.trajectory_positions = [] axtl = 23.43929*DEG2RAD # Earth axial tlit # Macierz przejscia z ECI do helio self.mactran = matrix([ [1, 0, 0], [0, cos(axtl), sin(axtl)], [0, -sin(axtl), cos(axtl)] ]) self.day = 86400.0 def positions_lambert(self, l, sol=0, units = 1.0, index = 0): """ Plots a particular solution to a Lambert's problem USAGE: plot_lambert(ax,l, N=60, sol=0, units = 'PyKEP.AU', legend = 'False') * l: PyKEP.lambert_problem object * sol: solution to the Lambert's problem we want to plot (must be in 0..Nmax*2) where Nmax is the maximum number of revolutions for which there exist a solution. * units: the length unit to be used in the plot """ from PyKEP import propagate_lagrangian, AU if sol > l.get_Nmax()*2: raise ValueError("sol must be in 0 .. NMax*2 \n * Nmax is the maximum number of revolutions for which there exist a solution to the Lambert's problem \n * You can compute Nmax calling the get_Nmax() method of the lambert_problem object") #We extract the relevant information from the Lambert's problem r = l.get_r1() v = l.get_v1()[sol] T = l.get_tof() mu = l.get_mu() #We define the integration time ... if T/86400. < 1: N = int(T) #...compute number of points... dt = T / (N-1.) else: N = int(2*T/86400.) #...compute number of points... dt = T / (N-1.) timetuple = [i*dt for i in range(N)] #... and alocate the cartesian components for r x = [0.0]*N y = [0.0]*N z = [0.0]*N #We calculate the spacecraft position at each dt for i in range(N): x[i] = r[0]/units y[i] = r[1]/units z[i] = r[2]/units r,v = propagate_lagrangian(r,v,dt,mu) self.trajectory_positions.append([index, x, y, z, timetuple]) def positions_kepler(self, r,v,t,mu, units = 1, index = 0): """ Plots the result of a keplerian propagation USAGE: plot_kepler(ax,r,v,t,mu, N=60, units = 1, color = 'b', legend = False): * r: initial position (cartesian coordinates) * v: initial velocity (cartesian coordinates) * t: propagation time * mu: gravitational parameter * units: the length unit to be used in the plot """ from PyKEP import propagate_lagrangian #We define the integration time ... if t/86400. < 1: N = int(t) #...compute number of points... dt = t / (N-1.) else: N = int(2*t/86400.) #...compute number of points... dt = t / (N-1.) timetuple = [i*dt for i in range(N)] #... and calcuate the cartesian components for r x = [0.0]*N y = [0.0]*N z = [0.0]*N #We calculate the spacecraft position at each dt for i in range(N): x[i] = r[0]/units y[i] = r[1]/units z[i] = r[2]/units r,v = propagate_lagrangian(r,v,dt,mu) self.trajectory_positions.append([index, x, y, z, timetuple]) def return_sc_positions(self): return self.trajectory_positions def set_launch_epoch(self, mjd2000_epoch): self.Lepoch = mjd2000_epoch def rework_time(self): T = self.trajectory_positions n = len(T) ep = self.Lepoch timespans = [T[i][4][-1]/86400. for i in range(n)] beginings = [ep + sum(timespans[:i]) for i in range(n)] # initialize lists... t = [] x = [] y = [] z = [] # ...and join values, correcting for time for g in range(n): t = t + [beginings[g]+i/86400. for i in T[g][4]] x = x + T[g][1] y = y + T[g][2] z = z + T[g][3] # save spacecraft state self.sc_state = [x, y, z, t] def eq2eclipt(self, xyz): macxyz = matrix(xyz) return self.mactran.dot(macxyz) def planets_pos(self): from jplephem import Ephemeris import de421 from PyKEP import epoch self.eph = Ephemeris(de421) earthpos = [] marspos = [] venuspos = [] for ep in self.sc_state[3]: posSun, __ = self.eph.position_and_velocity('sun', epoch(ep, epoch.epoch_type.MJD2000).jd) positione, __ = self.eph.position_and_velocity('earthmoon', epoch(ep, epoch.epoch_type.MJD2000).jd) positione = self.eq2eclipt(positione - posSun) earthpos.append(positione) positionm, __ = self.eph.position_and_velocity('mars', epoch(ep, epoch.epoch_type.MJD2000).jd) positionm = self.eq2eclipt(positionm - posSun) marspos.append(positionm) positionv, __ = self.eph.position_and_velocity('venus', epoch(ep, epoch.epoch_type.MJD2000).jd) positionv = self.eq2eclipt(positionv - posSun) venuspos.append(positionv) self.earthpos_km = [earthpos[i].reshape((1,3)).tolist()[0] for i in range(len(earthpos))] self.marspos_km = [marspos[i].reshape((1,3)).tolist()[0] for i in range(len(earthpos))] self.venuspos_km = [venuspos[i].reshape((1,3)).tolist()[0] for i in range(len(earthpos))] def distance_to_planets(self): dre = [] drm = [] drv = [] for i in range(len(self.sc_state[3])): ep = self.earthpos_km[i] dist = [ep[0] - self.sc_state[0][i] / 1000., ep[1] - self.sc_state[1][i] / 1000., ep[2] - self.sc_state[2][i] / 1000.] dre.append((sum([g**2 for g in dist]))**.5) mp = self.marspos_km[i] dist = [mp[0] - self.sc_state[0][i] / 1000., mp[1] - self.sc_state[1][i] / 1000., mp[2] - self.sc_state[2][i] / 1000.] drm.append((sum([g**2 for g in dist]))**.5) vp = self.venuspos_km[i] dist = [vp[0] - self.sc_state[0][i] / 1000., vp[1] - self.sc_state[1][i] / 1000., vp[2] - self.sc_state[2][i] / 1000.] drv.append((sum([g**2 for g in dist]))**.5) return dre,drm, drv, self.sc_state[3]
def GenerateJourneyDataPlot(self, DataAxesLeft, DataAxesRight, PlotOptions, firstpass): #generate a vector of dates date_string_vector = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': date_string_vector.append(event.GregorianDate) date_vector = [datetime.datetime.strptime(d,'%m/%d/%Y').date() for d in date_string_vector] #dummy line across the bottom so that neither axes object crashes DataAxesLeft.plot(date_vector, np.zeros_like(date_vector), c='w', lw = 0.1) DataAxesRight.plot(date_vector, np.zeros_like(date_vector), c='w', lw = 0.1) #plot distance from central body if PlotOptions.PlotR: Rvector = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': Rvector.append(math.sqrt(event.SpacecraftState[0]**2 + event.SpacecraftState[1]**2 + event.SpacecraftState[2]**2) / self.LU) if firstpass: unitstring = 'LU' if self.central_body.lower() == 'sun' and math.fabs(self.LU - 149597870.69100001) < 1.0: unitstring = 'AU' labelstring = 'Distance from ' + self.central_body + ' (' + unitstring + ')' DataAxesLeft.plot(date_vector, Rvector, c='k', lw=2, label=labelstring) else: DataAxesLeft.plot(date_vector, Rvector, c='k', lw=2) #plot velocity if PlotOptions.PlotV: Vvector = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': Vvector.append(math.sqrt(event.SpacecraftState[3]**2 + event.SpacecraftState[4]**2 + event.SpacecraftState[5]**2) / self.LU * self.TU) if firstpass: DataAxesLeft.plot(date_vector, Vvector, c='k', lw=2, ls='-.', label='Velocity magnitude (LU/TU)') else: DataAxesLeft.plot(date_vector, Vvector, c='k', lw=2, ls='-.') #plot Thrust if PlotOptions.PlotThrust: Thrustvector = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': Thrustvector.append(math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) * 10.0) if firstpass: DataAxesLeft.plot(date_vector, Thrustvector, c='r', lw=2, ls='-', label='Applied thrust (0.1 N)') else: DataAxesLeft.plot(date_vector, Thrustvector, c='r', lw=2, ls='-') #plot Isp if PlotOptions.PlotIsp: Ispvector = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': Ispvector.append(event.Isp / 1000.0) if firstpass: DataAxesLeft.plot(date_vector, Ispvector, c='c', lw=2, ls='-', label='Isp (1000 s)') else: DataAxesLeft.plot(date_vector, Ispvector, c='c', lw=2, ls='-') #plot mass flow rate if PlotOptions.PlotMdot: Mdotvector = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': Mdotvector.append(event.MassFlowRate * 1.0e6) if firstpass: DataAxesLeft.plot(date_vector, Mdotvector, c='brown', lw=2, ls='-', label='Mass flow rate (mg/s)') else: DataAxesLeft.plot(date_vector, Mdotvector, c='brown', lw=2, ls='-') #plot Efficiency if PlotOptions.PlotEfficiency: Efficiencyvector = [] for event in self.missionevents: if event.EventType == 'SFthrust' or event.EventType == 'FBLTthrust' or event.EventType == "PSBIthrust": Efficiencyvector.append(event.AvailableThrust * event.Isp * 9.80665 / (2000 * event.ActivePower)) elif event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': Efficiencyvector.append(0.0) if firstpass: DataAxesLeft.plot(date_vector, Efficiencyvector, c='DarkGreen', lw=2, ls='-', label='Propulsion system efficiency') else: DataAxesLeft.plot(date_vector, Efficiencyvector, c='DarkGreen', lw=2, ls='-') #plot Throttle if PlotOptions.PlotThrottle: Throttlevector = [] for event in self.missionevents: if event.EventType == 'SFthrust' or event.EventType == 'FBLTthrust' or event.EventType == "PSBIthrust": Throttlevector.append(math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) / (event.AvailableThrust * self.thruster_duty_cycle)) elif event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': Throttlevector.append(0.0) if firstpass: DataAxesLeft.plot(date_vector, Throttlevector, c='r', lw=2, ls='--', label='Throttle') else: DataAxesLeft.plot(date_vector, Throttlevector, c='r', lw=2, ls='--') #plot power if PlotOptions.PlotPower: Powervector = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': if event.AvailablePower > 0.0: Powervector.append(event.AvailablePower) else: Powervector.append(0.0) if firstpass: DataAxesLeft.plot(date_vector, Powervector, c='Navy', lw=2, ls='-', label='Power produced by spacecraft (kW)') else: DataAxesLeft.plot(date_vector, Powervector, c='Navy', lw=2, ls='-') #plot gamma if PlotOptions.PlotGamma: gammavector = [] for event in self.missionevents: if event.EventType == 'SFthrust' or event.EventType == 'FBLTthrust' or event.EventType == "PSBIthrust": gammavector.append(math.atan2(event.Thrust[1], event.Thrust[0]) * 180.0 / math.pi) elif event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': gammavector.append(0.0) if firstpass: DataAxesRight.plot(date_vector, gammavector, c='DarkGreen', lw=2, ls='--', label=r'$\gamma$ (radians)') else: DataAxesRight.plot(date_vector, gammavector, c='DarkGreen', lw=2, ls='--') #plot delta if PlotOptions.PlotDelta: deltavector = [] for event in self.missionevents: if event.EventType == 'SFthrust' or event.EventType == 'FBLTthrust' or event.EventType == "PSBIthrust": AppliedThrust = math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) deltavector.append(math.asin(event.Thrust[2] / AppliedThrust) * 180.0 / math.pi) elif event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': deltavector.append(0.0) if firstpass: DataAxesRight.plot(date_vector, deltavector, c='LightGreen', lw=2, ls='--', label=r'$\delta$ (radians)') else: DataAxesRight.plot(date_vector, deltavector, c='LightGreen', lw=2, ls='--') #plot central body to thrust vector angle if PlotOptions.PlotCB_thrust_angle: CBthrustvector = [] for event in self.missionevents: if event.EventType == 'SFthrust' or event.EventType == 'FBLTthrust' or event.EventType == "PSBIthrust": r = math.sqrt(event.SpacecraftState[0]**2 + event.SpacecraftState[1]**2 + event.SpacecraftState[2]**2) AppliedThrust = math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) rdotT = event.SpacecraftState[0]*event.Thrust[0] + event.SpacecraftState[1]*event.Thrust[1] + event.SpacecraftState[2]*event.Thrust[2] CBthrustvector.append( math.acos( rdotT / (r * AppliedThrust) ) * 180.0 / math.pi) elif event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': CBthrustvector.append(0.0) if firstpass: DataAxesRight.plot(date_vector, CBthrustvector, c='Salmon', lw=2, ls='--', label='CB-thrust angle (radians)') else: DataAxesRight.plot(date_vector, CBthrustvector, c='Salmon', lw=2, ls='--') #plot mass if PlotOptions.PlotMass: mass = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': mass.append(event.Mass * 1.0e-3) if firstpass: DataAxesLeft.plot(date_vector, mass, c='DarkGrey', lw=2, ls='-', label='Mass (1000 kg)') else: DataAxesLeft.plot(date_vector, mass, c='DarkGrey', lw=2, ls='-') #plot number of active thrusters if PlotOptions.PlotNumberOfEngines: numberofengines = [] for event in self.missionevents: if event.EventType == 'SFthrust' or event.EventType == 'FBLTthrust' or event.EventType == "PSBIthrust": numberofengines.append(event.Number_of_Active_Engines) elif event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': numberofengines.append(0) if firstpass: DataAxesLeft.plot(date_vector, numberofengines, c='Orange', lw=2, ls='-', label='Number of active thrusters') else: DataAxesLeft.plot(date_vector, numberofengines, c='Orange', lw=2, ls='-') #plot power actively used by the thrusters if PlotOptions.PlotActivePower: activepowervector = [] for event in self.missionevents: if event.EventType == 'SFthrust' or event.EventType == 'FBLTthrust' or event.EventType == "PSBIthrust": activepowervector.append(event.ActivePower) elif event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': activepowervector.append(0.0) if firstpass: DataAxesLeft.plot(date_vector, activepowervector, c='Navy', lw=2, ls='--', label='Power used by the propulsion system (kW)') else: DataAxesLeft.plot(date_vector, activepowervector, c='Navy', lw=2, ls='--') #plot waste heat from the propulsion system if PlotOptions.PlotWasteHeat: WasteHeatvector = [] for event in self.missionevents: if event.EventType == 'SFthrust' or event.EventType == 'FBLTthrust' or event.EventType == "PSBIthrust": WasteHeatvector.append( (1 - event.AvailableThrust * event.Isp * 9.80665 / (2000 * event.ActivePower)) * event.ActivePower ) elif event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': WasteHeatvector.append(0.0) if firstpass: DataAxesLeft.plot(date_vector, WasteHeatvector, c='Crimson', lw=2, ls='--', label='Waste heat from propulsion system (kW)') else: DataAxesLeft.plot(date_vector, WasteHeatvector, c='Crimson', lw=2, ls='--') #plot Earth distance in LU and SPE angle if PlotOptions.PlotEarthDistance or PlotOptions.PlotSunEarthSpacecraftAngle: if self.central_body.lower() != 'sun': print 'getting Earth distance and Sun-Spacecraft-Earth angle is only supported if the central body is the sun' else: import de423 from jplephem import Ephemeris eph = Ephemeris(de423) EarthDistanceVector = [] SunEarthSpacecraftAngle = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': #get the position of the central body relative to the solar system barycenter cb_relative_to_solar_system_barycenter_in_ICRC = eph.position(self.central_body.lower(), event.JulianDate) #get the position of the Earth relative to the central body embarycenter_in_ICRC = eph.position('earthmoon', event.JulianDate) moonvector_in_ICRC = eph.position('moon', event.JulianDate) Earth_relative_to_solar_system_barycenter_in_ICRC = embarycenter_in_ICRC - moonvector_in_ICRC * eph.earth_share Earth_relative_to_cb_in_ICRC = Earth_relative_to_solar_system_barycenter_in_ICRC + cb_relative_to_solar_system_barycenter_in_ICRC #rotate the spacecraft state relative to the central body into the ICRF frame spacecraft_state_relative_to_central_body_in_ICRF = AstroFunctions.rotate_from_ecliptic_to_equatorial3(np.array(event.SpacecraftState[0:3])) #get the vector from the Earth to the Spacecraft Earth_Spacecraft_Vector = spacecraft_state_relative_to_central_body_in_ICRF - np.transpose(Earth_relative_to_cb_in_ICRC)[0] #return the magnitude of the Earth-centered position vector EarthDistanceVector.append(np.linalg.norm(Earth_Spacecraft_Vector) / self.LU) #if applicable, compute sun-spacecraft-Earth angle if PlotOptions.PlotSunEarthSpacecraftAngle: cosAngle = np.dot(-Earth_Spacecraft_Vector, -spacecraft_state_relative_to_central_body_in_ICRF)/np.linalg.norm(spacecraft_state_relative_to_central_body_in_ICRF)/np.linalg.norm(Earth_Spacecraft_Vector) SunEarthSpacecraftAngle.append(np.arccos(cosAngle) * 180.0/math.pi) if PlotOptions.PlotEarthDistance: if firstpass: unitstring = 'LU' if self.central_body.lower() == 'sun' and math.fabs(self.LU - 149597870.69100001) < 1.0: unitstring = 'AU' labelstring = 'Distance from Earth (' + unitstring + ')' DataAxesLeft.plot(date_vector, EarthDistanceVector, c='g', lw=2, label=labelstring) else: DataAxesLeft.plot(date_vector, EarthDistanceVector, c='g', lw=2) if PlotOptions.PlotSunEarthSpacecraftAngle: if firstpass: DataAxesRight.plot(date_vector, SunEarthSpacecraftAngle, c='orangered', lw=2, ls = '-.', label='Sun-Spacecraft-Earth Angle') else: DataAxesRight.plot(date_vector, SunEarthSpacecraftAngle, c='orangered', lw=2, ls = '-.')
def WriteDateReport(self, PlotOptions, reportfile): #write header reportfile.write('JD, MM-DD-YYYY, Event duration (days), Event type, Event location') if PlotOptions.IncludeStateVectorInReport: reportfile.write(',x (km), y (km), z (km), xdot (km/s), ydot (km/s), zdot (km/s)') if PlotOptions.PlotR: unitstring = 'LU' if 'sun' in self.central_body.lower() and math.fabs(self.LU - 149597870.69100001) < 1.0: unitstring = 'AU' reportfile.write(', Distance from ' + self.central_body + ' (' + unitstring + ')') if PlotOptions.PlotV: reportfile.write(', Velocity magnitude (LU/TU)') if PlotOptions.PlotThrust: reportfile.write(', Applied thrust (N)') if PlotOptions.PlotIsp: reportfile.write(', Isp (s)') if PlotOptions.PlotMdot: reportfile.write(', Mass flow rate (kg/s)') if PlotOptions.PlotEfficiency: reportfile.write(', Propulsion system efficiency') if PlotOptions.PlotThrottle: reportfile.write(', Control magnitude') if PlotOptions.PlotPower: reportfile.write(', Power produced by spacecraft (kW)') if PlotOptions.PlotGamma: reportfile.write(', in-plane control angle (degrees)') if PlotOptions.PlotDelta: reportfile.write(', out-of-plane control angle (degrees)') if PlotOptions.PlotArray_Thrust_Angle: reportfile.write(', Array to thrust angle (degrees)') if PlotOptions.PlotMass: reportfile.write(', Mass (kg)') if PlotOptions.PlotNumberOfEngines: reportfile.write(', Number of active thrusters') if PlotOptions.PlotActivePower: reportfile.write(', Power used by the propulsion system (kW)') if PlotOptions.PlotWasteHeat: reportfile.write(', Waste heat from propulsion system (kW)') if PlotOptions.PlotEarthDistance: unitstring = 'LU' if 'sun' in self.central_body.lower() and math.fabs(self.LU - 149597870.69100001) < 1.0: unitstring = 'AU' reportfile.write(', Distance from Earth (' + unitstring + ')') if PlotOptions.PlotSunSpacecraftEarthAngle: reportfile.write(', Sun-Spacecraft-Earth Angle') if PlotOptions.PlotSpacecraftViewingAngle: reportfile.write(', Latitude of Earth-Spacecraft Vector') if PlotOptions.PlotThrottleLevel: reportfile.write(', Throttle level') if PlotOptions.PlotSunBoresightAngle: reportfile.write(', Sun-Boresight Angle') reportfile.write('\n') #load stuff if necessary if PlotOptions.PlotEarthDistance or PlotOptions.PlotSunSpacecraftEarthAngle or PlotOptions.PlotSpacecraftViewingAngle: if not 'sun' in self.central_body.lower(): print('getting Earth distance and Sun-Spacecraft-Earth angle is only supported if the central body is the sun') else: import de423 from jplephem import Ephemeris self.eph = Ephemeris(de423) if PlotOptions.PlotThrottleLevel: #instantiate a throttle table object thruster_throttle_table = ThrottleTable.ThrottleTable(PlotOptions.throttletablefile) self.high_Mdot_set, self.low_Mdot_set = thruster_throttle_table.create_non_dominated_sets() #now print the report for event in self.missionevents: reportfile.write(str(event.JulianDate)) reportfile.write(', ' + event.GregorianDate) reportfile.write(', ' + str(event.TimestepLength)) reportfile.write(', ' + event.EventType) reportfile.write(', ' + event.Location) if PlotOptions.IncludeStateVectorInReport: for state in event.SpacecraftState: reportfile.write(', ' + str(state)) if PlotOptions.PlotR: reportfile.write(', ' + str(math.sqrt(event.SpacecraftState[0]**2 + event.SpacecraftState[1]**2 + event.SpacecraftState[2]**2) / self.LU)) if PlotOptions.PlotV: reportfile.write(', ' + str(math.sqrt(event.SpacecraftState[3]**2 + event.SpacecraftState[4]**2 + event.SpacecraftState[5]**2) / self.LU * self.TU)) if PlotOptions.PlotThrust: if event.EventType not in ['match_point','upwr_flyby','pwr_flyby','LT_rndzvs','LT_spiral']: reportfile.write(', ' + str(math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2))) elif event.EventType == 'LT_spiral': reportfile.write(', ' + str(event.AvailableThrust * self.thruster_duty_cycle)) else: reportfile.write(', 0.0') if PlotOptions.PlotIsp: reportfile.write(', ' + str(event.Isp)) if PlotOptions.PlotMdot: reportfile.write(', ' + str(event.MassFlowRate)) if PlotOptions.PlotEfficiency: if event.EventType in ['SFthrust', 'SSFthrust','FBLTSthrust','FBLTthrust','PSBIthrust','PSFBthrust','LT_spiral']: reportfile.write(', ' + str(event.AvailableThrust * event.Isp * 9.80665 / (2000 * event.ActivePower))) else: reportfile.write(', 0.0') if PlotOptions.PlotThrottle: if event.EventType in ['SFthrust', 'SSFthrust','FBLTSthrust','FBLTthrust','PSBIthrust','PSFBthrust']: reportfile.write(', ' + str(math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) / (event.AvailableThrust * self.thruster_duty_cycle))) elif event.EventType == 'LT_spiral': reportfile.write(', ' + str(1.0)) elif event.EventType not in ['match_point','upwr_flyby','pwr_flyby','LT_rndzvs']: reportfile.write(', ' + str(0.0)) if PlotOptions.PlotPower: if event.EventType not in ['match_point','upwr_flyby','pwr_flyby','LT_rndzvs']: if (event.AvailablePower > 0.0): reportfile.write(', ' + str(event.AvailablePower)) else: reportfile.write(', ' + str(0.0)) else: reportfile.write(', ' + str(0.0)) if PlotOptions.PlotGamma: if event.EventType in ['SFthrust', 'SSFthrust','FBLTSthrust','FBLTthrust','PSBIthrust','PSFBthrust','LT_spiral']: reportfile.write(', ' + str(math.atan2(event.Thrust[1], event.Thrust[0]) * 180.0 / math.pi)) else: reportfile.write(', ' + str(0.0)) if PlotOptions.PlotDelta: if event.EventType in ['SFthrust', 'SSFthrust','FBLTSthrust','FBLTthrust','PSBIthrust','PSFBthrust','LT_spiral']: AppliedThrust = math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) reportfile.write(', ' + str(math.asin(event.Thrust[2] / AppliedThrust) * 180.0 / math.pi)) else: reportfile.write(', ' + str(0.0)) if PlotOptions.PlotArray_Thrust_Angle: if event.EventType in ['SFthrust', 'SSFthrust','FBLTSthrust','FBLTthrust','PSBIthrust','PSFBthrust','LT_spiral']: r = math.sqrt(event.SpacecraftState[0]**2 + event.SpacecraftState[1]**2 + event.SpacecraftState[2]**2) AppliedThrust = math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) rdotT = event.SpacecraftState[0]*event.Thrust[0] + event.SpacecraftState[1]*event.Thrust[1] + event.SpacecraftState[2]*event.Thrust[2] reportfile.write(', ' + str(math.acos( rdotT / (r * AppliedThrust) ) * 180.0 / math.pi)) else: reportfile.write(', ' + str(0.0)) if PlotOptions.PlotMass: reportfile.write(', ' + str(event.Mass)) if PlotOptions.PlotNumberOfEngines: if event.EventType in ['SFthrust', 'SSFthrust','FBLTSthrust','FBLTthrust','PSBIthrust','PSFBthrust','LT_spiral']: reportfile.write(', ' + str(event.Number_of_Active_Engines)) else: reportfile.write(', ' + str(0)) if PlotOptions.PlotActivePower: if event.EventType in ['SFthrust', 'SSFthrust','FBLTSthrust','FBLTthrust','PSBIthrust','PSFBthrust','LT_spiral']: reportfile.write(', ' + str(event.ActivePower)) else: reportfile.write(', ' + str(0.0)) if PlotOptions.PlotWasteHeat: if event.EventType in ['SFthrust', 'SSFthrust','FBLTSthrust','FBLTthrust','PSBIthrust','PSFBthrust','LT_spiral']: reportfile.write(', ' + str((1.0 - event.AvailableThrust * event.Isp * 9.80665 / (2000.0 * event.ActivePower)) * event.ActivePower)) else: reportfile.write(', ' + str(0.0)) if PlotOptions.PlotEarthDistance or PlotOptions.PlotSunSpacecraftEarthAngle or PlotOptions.PlotSpacecraftViewingAngle: if not 'sun' in self.central_body.lower(): print('getting Earth distance and Sun-Spacecraft-Earth angle is only supported if the central body is the sun') else: #get the position of the central body relative to the solar system barycenter cb_relative_to_solar_system_barycenter_in_ICRF = self.eph.position('sun', event.JulianDate) #get the position of the Earth relative to the central body embarycenter_in_ICRF = self.eph.position('earthmoon', event.JulianDate) moonvector_in_ICRF = self.eph.position('moon', event.JulianDate) Earth_relative_to_solar_system_barycenter_in_ICRF = embarycenter_in_ICRF - moonvector_in_ICRF * self.eph.earth_share Earth_relative_to_cb_in_ICRF = Earth_relative_to_solar_system_barycenter_in_ICRF + cb_relative_to_solar_system_barycenter_in_ICRF #rotate the spacecraft state relative to the central body into the ICRF frame spacecraft_state_relative_to_central_body_in_ICRF = AstroFunctions.rotate_from_ecliptic_to_equatorial3(np.array(event.SpacecraftState[0:3])) #get the vector from the Earth to the Spacecraft Earth_Spacecraft_Vector = spacecraft_state_relative_to_central_body_in_ICRF - np.transpose(Earth_relative_to_cb_in_ICRF)[0] #return the magnitude of the Earth-centered position vector EarthDistance = np.linalg.norm(Earth_Spacecraft_Vector) / self.LU if PlotOptions.PlotEarthDistance: reportfile.write(', ' + str(EarthDistance)) if PlotOptions.PlotSunSpacecraftEarthAngle: cosAngle = np.dot(-Earth_Spacecraft_Vector, -spacecraft_state_relative_to_central_body_in_ICRF)/np.linalg.norm(spacecraft_state_relative_to_central_body_in_ICRF)/np.linalg.norm(Earth_Spacecraft_Vector) reportfile.write(', ' + str(np.arccos(cosAngle) * 180.0/math.pi)) if PlotOptions.PlotSpacecraftViewingAngle: tanAngle = Earth_Spacecraft_Vector[2]/math.sqrt(Earth_Spacecraft_Vector[0]*Earth_Spacecraft_Vector[0]+Earth_Spacecraft_Vector[1]*Earth_Spacecraft_Vector[1]) reportfile.write(', ' + str(np.arctan(tanAngle) * 180.0/math.pi)) if PlotOptions.PlotThrottleLevel: if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', 'PSBIthrust','PSFBthrust', 'end_spiral']: if PlotOptions.throttlesetmode == 0: reportfile.write(', ' + str(int(self.high_Mdot_set.find_nearest_throttle_setting_1D(event.ActivePower / event.Number_of_Active_Engines).TL.strip('TL')))) elif PlotOptions.throttlesetmode == 1: reportfile.write(', ' + str(int(self.low_Mdot_set.find_nearest_throttle_setting_1D(event.ActivePower / event.Number_of_Active_Engines).TL.strip('TL')))) elif PlotOptions.throttlesetmode == 2: print('2D throttle matching not currently implemented') else: reportfile.write(', ' + str(0.0)) #plot sun-boresight angle if PlotOptions.PlotSunBoresightAngle: if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', "PSBIthrust",'PSFBthrust']: r = math.sqrt(event.SpacecraftState[0]**2 + event.SpacecraftState[1]**2 + event.SpacecraftState[2]**2) AppliedThrust = math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) rdotT = event.SpacecraftState[0]*event.Thrust[0] + event.SpacecraftState[1]*event.Thrust[1] + event.SpacecraftState[2]*event.Thrust[2] reportfile.write(', ' + str(math.acos( rdotT / (r * AppliedThrust) ) * 180.0 / math.pi)) else: reportfile.write(', ' + str(0.0)) reportfile.write('\n')
mu = 1.0 r_dot /= k r_now = r_last + r_dot * d_tau + 0.5 * accel(r_last, mu) * (d_tau ** 2) tau += d_tau while abs(tau) <= abs(end_tau): tau += d_tau temp = verlet_position(r_now, r_last, d_tau, mu) r_last = temp[1] r_now = temp[0] return r_now AU = 149597870.7 # km/AU epsilon = 23.43687 # obliquity of the Ecliptic eph = Ephemeris(de421) def location_to_angles(location): dec = asin(location.z) #print dec ra = acos(location.x/cos(dec)) if location.y < 0: ra = 2 * pi - ra return degrees(ra), degrees(dec) def get_ra_dec(r, julian_date): barycenter = eph.position('earthmoon', julian_date) moonvector = eph.position('moon', julian_date) earth = barycenter - moonvector * eph.earth_share R0 = vector(earth)/AU # This is the Sun to Earth center vector in Equatorial system
class Journey(object): def __init__(self, parent): self.parent = parent self.missionevents = [] self.journey_name = "AJourney" self.journey_number = 0 self.central_body = "Sun" self.central_body_radius = 4.379e+6 self.mu = 132712440017.99 self.LU = 1.49597870691e+8 self.TU = 5022642.890912973 self.boundary_states = [] self.flyby_periapse_states = [[0.0]*6] self.thruster_duty_cycle = 1.0 self.journey_post_arrival_deltav = 0.0 self.journey_post_arrival_propellant_used = 0.0 self.journey_initial_mass_increment = 0.0 self.journey_final_mass_increment = 0.0 #default values for entry things self.journey_entryinterface_velocity_with_respect_to_rotating_atmosphere = 0.0 self.journey_entry_landing_interface_point = [0.0]*6 self.entry_latitude = 0.0 self.entry_longitude = 0.0 self.entry_sun_angle = 0.0 self.journey_arrival_spacecraft_sun_Earth_angle = 180.0 self.state_frame = '' self.alpha0 = 0.0 self.delta0 = 0.0 def PlotJourney(self, JourneyAxes, PlotOptions, CustomLabels = None): #plot each mission event BeforeMatchPoint = True if PlotOptions.ShowMissionEvents: for event in self.missionevents: #do we have a custom label? if CustomLabels != None: for label in CustomLabels: #this is a list of lists, [eventNumber, labelstring] if label[0] == event.EventNumber: BeforeMatchPoint = event.PlotEvent(JourneyAxes, self.LU, self.TU, self.mu, PlotOptions, BeforeMatchPoint, label[1]) else: BeforeMatchPoint = event.PlotEvent(JourneyAxes, self.LU, self.TU, self.mu, PlotOptions, BeforeMatchPoint) else: BeforeMatchPoint = event.PlotEvent(JourneyAxes, self.LU, self.TU, self.mu, PlotOptions, BeforeMatchPoint) def PlotJourneyBoundaryOrbits(self, JourneyAxes, PlotOptions): from scipy.integrate import ode for boundaryStateIndex in range(0, len(self.boundary_states)): if not ((boundaryStateIndex == 0 and self.missionevents[0].Location == 'free point') \ or (boundaryStateIndex == (len(self.boundary_states) - 1) and self.missionevents[-1].Location == 'free point')) \ or PlotOptions.ShowFreePointBoundaryOrbits: boundarystate = self.boundary_states[boundaryStateIndex] BoundaryStateScaled = np.array(boundarystate) / self.LU BoundaryStateScaled[3:6] *= self.TU r = np.linalg.norm(BoundaryStateScaled[0:3]) v = np.linalg.norm(BoundaryStateScaled[3:6]) if r == 0.0: continue a = r / (2.0 - r*v*v) if a > 0.0: T = 2*math.pi*math.sqrt(a**3) else: T = 2*math.pi*self.LU / self.TU StateIntegrateObject = ode(EOM.EOM_inertial_2body, jac=EOM.EOM_jacobian_intertial_2body).set_integrator('dop853', atol=1.0e-8, rtol=1.0e-8) StateIntegrateObject.set_initial_value(BoundaryStateScaled).set_f_params(1.0).set_jac_params(1.0) dt = T / 10000 StateHistory = [] epoch = (self.missionevents[0].JulianDate - 2451544.5) * 86400.0 while StateIntegrateObject.successful() and StateIntegrateObject.t < T * 1.01: epoch += dt * self.TU stateArray = StateIntegrateObject.integrate(StateIntegrateObject.t + dt) state = [stateArray[0] * self.LU, stateArray[1] * self.LU, stateArray[2] * self.LU, epoch] StateHistory.append(state) X = [] Y = [] Z = [] for StateLine in StateHistory: if PlotOptions.PlotCentralBody != 'Journey central body': import spiceypy journey_central_body = self.central_body if journey_central_body in ['Mars','Jupiter','Uranus','Neptune','Pluto']: journey_central_body = journey_central_body + ' Barycenter' if journey_central_body != PlotOptions.PlotCentralBody: body_state, LT = spiceypy.spkezr(journey_central_body, StateLine[-1], 'J2000', "None", PlotOptions.PlotCentralBody) X.append(StateLine[0] + body_state[0]) Y.append(StateLine[1] + body_state[1]) Z.append(StateLine[2] + body_state[2]) else: X.append(StateLine[0]) Y.append(StateLine[1]) Z.append(StateLine[2]) else: X.append(StateLine[0]) Y.append(StateLine[1]) Z.append(StateLine[2]) JourneyAxes.plot(X, Y, Z, lw=1, c='0.75') def PlotJourneyCentralBodyOrbits(self, JourneyAxes, PlotOptions): if PlotOptions.PlotCentralBody != 'Journey central body': import spiceypy journey_central_body = self.central_body if journey_central_body in ['Mars','Jupiter','Uranus','Neptune','Pluto']: journey_central_body = journey_central_body + ' Barycenter' if journey_central_body != PlotOptions.PlotCentralBody: body_state, LT = spiceypy.spkezr(journey_central_body, (self.missionevents[0].JulianDate - 2451545.0) * 86400.0, 'J2000', "None", PlotOptions.PlotCentralBody) r = np.linalg.norm(body_state[0:3]) v = np.linalg.norm(body_state[3:6]) mu = {'Mercury': 22031.780000, 'Venus': 324858.592000, 'Earth': 398600.435436, 'Mars': 42828.375214, 'Jupiter Barycenter': 126712764.800000, 'Saturn Barycenter': 37940585.200000, 'Uranus Barycenter': 5794548.600000, 'Neptune Barycenter': 6836527.100580, 'Pluto Barycenter': 977.000000, 'Sun': 132712440041.939400, 'Moon': 4902.800066, 'Earth-Moon Barycenter': 403503.235502} elements = spiceypy.oscltx(body_state, (self.missionevents[0].JulianDate - 2451545.0) * 86400.0, mu[PlotOptions.PlotCentralBody]) a = elements[-2] #a = r / (2.0 - r*v*v) if a > 0.0: T = 2*math.pi *math.sqrt(a**3 / mu[PlotOptions.PlotCentralBody]) else: T = 2*math.pi * self.TU t0 = (self.missionevents[0].JulianDate - 2451545.0) * 86400.0 tf = t0 + T X = [] Y = [] Z = [] for epoch in np.linspace(t0, tf, num=100): body_state, LT = spiceypy.spkezr(journey_central_body, epoch, 'J2000', "None", PlotOptions.PlotCentralBody) X.append(body_state[0]) Y.append(body_state[1]) Z.append(body_state[2]) JourneyAxes.plot(X, Y, Z, lw=1, c='0.75') def UpdateLabelPosition(self, Figure, Axes): for event in self.missionevents: event.UpdateLabelPosition(Figure, Axes) def PlotPhaseBoundariesOnDataPlot(self, DataAxes, PlotOptions, firstpass, Ybounds): #create vertical lines at important events date_string_vector = [] boundarylegendflag = True burnlegendflag = True for event in self.missionevents: if event.EventType in ['upwr_flyby', 'pwr_flyby', 'LT_rndzvs', 'rendezvous', 'intercept', 'insertion', 'match-vinf', 'launch', 'departure', "begin_spiral", "end_spiral"]: event_epoch = datetime.datetime.strptime(event.GregorianDate,'%m/%d/%Y').date() if firstpass and boundarylegendflag: DataAxes.plot([event_epoch]*2, Ybounds, c='k', marker='+', ls = '-.', lw=3)#, label='Phase boundary') boundarylegendflag = False else: DataAxes.plot([event_epoch]*2, Ybounds, c='k', marker='+', ls = '-.', lw=3) if event.EventType == 'chem_burn': event_epoch = datetime.datetime.strptime(event.GregorianDate,'%m/%d/%Y').date() if firstpass and burnlegendflag: DataAxes.plot([event_epoch]*2, Ybounds, c='r', marker='+', ls = '-.', lw=3, label='Deep-Space Maneuver') burnlegendflag = False else: DataAxes.plot([event_epoch]*2, Ybounds, c='r', marker='+', ls = '-.', lw=3) def GenerateJourneyDataPlot(self, DataAxesLeft, DataAxesRight, PlotOptions, firstpass): import math import astropy #generate a vector of dates date_string_vector = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby' and event.EventType != 'LT_rndzvs': date_string_vector.append(event.GregorianDate) date_vector = [datetime.datetime.strptime(d,'%m/%d/%Y').date() for d in date_string_vector] #dummy line across the bottom so that neither axes object crashes DataAxesLeft.plot(date_vector, np.zeros_like(date_vector), c='w', lw = 0.1) DataAxesRight.plot(date_vector, np.zeros_like(date_vector), c='w', lw = 0.1) #plot distance from central body if PlotOptions.PlotR: Rvector = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby' and event.EventType != 'LT_rndzvs': Rvector.append(math.sqrt(event.SpacecraftState[0]**2 + event.SpacecraftState[1]**2 + event.SpacecraftState[2]**2) / self.LU) if firstpass: unitstring = 'LU' if 'sun' in self.central_body.lower() and math.fabs(self.LU - 149597870.69100001) < 1.0: unitstring = 'AU' labelstring = 'Distance from ' + self.central_body + ' (' + unitstring + ')' DataAxesLeft.plot(date_vector, Rvector, c='k', lw=2, label=labelstring) else: DataAxesLeft.plot(date_vector, Rvector, c='k', lw=2) #plot velocity if PlotOptions.PlotV: Vvector = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby' and event.EventType != 'LT_rndzvs': Vvector.append(math.sqrt(event.SpacecraftState[3]**2 + event.SpacecraftState[4]**2 + event.SpacecraftState[5]**2) / self.LU * self.TU) if firstpass: DataAxesLeft.plot(date_vector, Vvector, c='k', lw=2, ls='-.', label='Velocity magnitude (LU/TU)') else: DataAxesLeft.plot(date_vector, Vvector, c='k', lw=2, ls='-.') #plot Thrust if PlotOptions.PlotThrust: Thrustvector = [] shortDateVector = [] for event in self.missionevents: epoch = astropy.time.Time(event.JulianDate, format='jd', scale='tdb') if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', 'PSBIthrust', 'PSFBthrust']: Thrustvector.append(math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) * 10.0) shortDateVector.append((epoch - event.TimestepLength / 2).datetime) Thrustvector.append(math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) * 10.0) shortDateVector.append((epoch + event.TimestepLength / 2).datetime) elif event.EventType == 'LT_spiral': Thrustvector.append(event.AvailableThrust * self.thruster_duty_cycle*10.0) shortDateVector.append((epoch - event.TimestepLength / 2).datetime) Thrustvector.append(event.AvailableThrust * self.thruster_duty_cycle*10.0) shortDateVector.append((epoch + event.TimestepLength / 2).datetime) elif event.EventType != 'match_point': Thrustvector.append(0.0) shortDateVector.append((epoch - event.TimestepLength / 2).datetime) Thrustvector.append(0.0) shortDateVector.append((epoch + event.TimestepLength / 2).datetime) if firstpass: DataAxesLeft.plot(shortDateVector, Thrustvector, c='r', lw=2, ls='--', label='Applied thrust (0.1 N)') else: DataAxesLeft.plot(shortDateVector, Thrustvector, c='r', lw=2, ls='--') #plot Isp if PlotOptions.PlotIsp: Ispvector = [] shortDateVector = [] for event in self.missionevents: epoch = astropy.time.Time(event.JulianDate, format='jd', scale='tdb') if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', 'PSBIthrust', 'PSFBthrust', 'LT_spiral']: Ispvector.append(event.Isp / 1000.0) shortDateVector.append((epoch - event.TimestepLength / 2).datetime) Ispvector.append(event.Isp / 1000.0) shortDateVector.append((epoch + event.TimestepLength / 2).datetime) elif event.EventType != 'match_point': Ispvector.append(0.0) shortDateVector.append((epoch - event.TimestepLength / 2).datetime) Ispvector.append(0.0) shortDateVector.append((epoch + event.TimestepLength / 2).datetime) if firstpass: DataAxesLeft.plot(shortDateVector, Ispvector, 'dodgerblue', lw=4, ls='-.', label='Isp (1000 s)') else: DataAxesLeft.plot(shortDateVector, Ispvector, 'dodgerblue', lw=4, ls='-.') #plot mass flow rate if PlotOptions.PlotMdot: Mdotvector = [] shortDateVector = [] for event in self.missionevents: epoch = astropy.time.Time(event.JulianDate, format='jd', scale='tdb') if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', 'PSBIthrust', 'PSFBthrust', 'LT_spiral']: Mdotvector.append(event.MassFlowRate * 1.0e6) shortDateVector.append((epoch - event.TimestepLength / 2).datetime) Mdotvector.append(event.MassFlowRate * 1.0e6) shortDateVector.append((epoch + event.TimestepLength / 2).datetime) elif event.EventType != 'match_point': Mdotvector.append(0.0) shortDateVector.append((epoch - event.TimestepLength / 2).datetime) Mdotvector.append(0.0) shortDateVector.append((epoch + event.TimestepLength / 2).datetime) if firstpass: DataAxesLeft.plot(shortDateVector, Mdotvector, c='brown', lw=2, ls='-', label='Mass flow rate (mg/s)') else: DataAxesLeft.plot(shortDateVector, Mdotvector, c='brown', lw=2, ls='-') #plot Efficiency if PlotOptions.PlotEfficiency: Efficiencyvector = [] shortDateVector = [] for event in self.missionevents: epoch = astropy.time.Time(event.JulianDate, format='jd', scale='tdb') if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', 'PSBIthrust', 'PSFBthrust', 'LT_spiral']: Efficiencyvector.append(event.AvailableThrust * event.Isp * 9.80665 / (2000 * event.ActivePower)) shortDateVector.append((epoch - event.TimestepLength / 2).datetime) Efficiencyvector.append(event.AvailableThrust * event.Isp * 9.80665 / (2000 * event.ActivePower)) shortDateVector.append((epoch + event.TimestepLength / 2).datetime) elif event.EventType != 'match_point': Efficiencyvector.append(0.0) shortDateVector.append((epoch - event.TimestepLength / 2).datetime) Efficiencyvector.append(0.0) shortDateVector.append((epoch + event.TimestepLength / 2).datetime) if firstpass: DataAxesLeft.plot(shortDateVector, Efficiencyvector, c='DarkGreen', lw=2, ls='-', label='Propulsion system efficiency') else: DataAxesLeft.plot(shortDateVector, Efficiencyvector, c='DarkGreen', lw=2, ls='-') #plot control magnitude if PlotOptions.PlotThrottle: Throttlevector = [] shortDateVector = [] for event in self.missionevents: epoch = astropy.time.Time(event.JulianDate, format='jd', scale='tdb') if event.EventType in ['SFthrust', 'SSFthrust', 'PSBIthrust']: Throttlevector.append(math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) / (event.AvailableThrust)) shortDateVector.append((epoch - event.TimestepLength / 2).datetime) Throttlevector.append(math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) / (event.AvailableThrust)) shortDateVector.append((epoch + event.TimestepLength / 2).datetime) elif event.EventType in ['FBLTthrust','FBLTSthrust','PSFBthrust']: Throttlevector.append(event.DVmagorThrottle) shortDateVector.append((epoch - event.TimestepLength / 2).datetime) Throttlevector.append(event.DVmagorThrottle) shortDateVector.append((epoch + event.TimestepLength / 2).datetime) elif event.EventType == 'LT_spiral': Throttlevector.append(1.0) shortDateVector.append((epoch - event.TimestepLength / 2).datetime) Throttlevector.append(1.0) shortDateVector.append((epoch + event.TimestepLength / 2).datetime) elif event.EventType != 'match_point': Throttlevector.append(0.0) shortDateVector.append((epoch - event.TimestepLength / 2).datetime) Throttlevector.append(0.0) shortDateVector.append((epoch + event.TimestepLength / 2).datetime) if firstpass: DataAxesLeft.plot(shortDateVector, Throttlevector, c='r', lw=2, ls='--', label='Control magnitude') else: DataAxesLeft.plot(shortDateVector, Throttlevector, c='r', lw=2, ls='--') #plot power if PlotOptions.PlotPower: Powervector = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby' and event.EventType != 'LT_rndzvs': if event.AvailablePower > 0.0: Powervector.append(event.AvailablePower) else: Powervector.append(0.0) if firstpass: DataAxesLeft.plot(date_vector, Powervector, c='Navy', lw=2, ls='-.', label='Power available for propulsion (kW)') else: DataAxesLeft.plot(date_vector, Powervector, c='Navy', lw=2, ls='-.') #plot gamma if PlotOptions.PlotGamma: gammavector = [] shortDateVector = [] for event in self.missionevents: if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', 'PSBIthrust', 'PSFBthrust', 'LT_spiral']: gammavector.append(math.atan2(event.Thrust[1], event.Thrust[0]) * 180.0 / math.pi) shortDateVector.append(datetime.datetime.strptime(event.GregorianDate,'%m/%d/%Y').date()) if firstpass: DataAxesRight.plot(shortDateVector, gammavector, c='DarkGreen', lw=2, ls='--', label=r'$\gamma$ (degrees)') else: DataAxesRight.plot(shortDateVector, gammavector, c='DarkGreen', lw=2, ls='--') #plot delta if PlotOptions.PlotDelta: deltavector = [] shortDateVector = [] for event in self.missionevents: if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', 'PSBIthrust', 'PSFBthrust', 'LT_spiral']: AppliedThrust = math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) deltavector.append(math.asin(event.Thrust[2] / AppliedThrust) * 180.0 / math.pi) shortDateVector.append(datetime.datetime.strptime(event.GregorianDate,'%m/%d/%Y').date()) if firstpass: DataAxesRight.plot(shortDateVector, deltavector, c='LightGreen', lw=2, ls='--', label=r'$\delta$ (degrees)') else: DataAxesRight.plot(shortDateVector, deltavector, c='LightGreen', lw=2, ls='--') #plot central body to thrust vector angle if PlotOptions.PlotArray_Thrust_Angle: CBthrustvector = [] shortDateVector = [] for event in self.missionevents: if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', 'PSBIthrust', 'PSFBthrust', 'LT_spiral']: r = math.sqrt(event.SpacecraftState[0]**2 + event.SpacecraftState[1]**2 + event.SpacecraftState[2]**2) AppliedThrust = math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) rdotT = event.SpacecraftState[0]*event.Thrust[0] + event.SpacecraftState[1]*event.Thrust[1] + event.SpacecraftState[2]*event.Thrust[2] CBthrustvector.append( 90.0 - math.acos( rdotT / (r * AppliedThrust) ) * 180.0 / math.pi) shortDateVector.append(datetime.datetime.strptime(event.GregorianDate,'%m/%d/%Y').date()) if firstpass: DataAxesRight.plot(shortDateVector, CBthrustvector, c='Salmon', marker='o', ls='None', label='Array to thrust angle (degrees)') else: DataAxesRight.plot(shortDateVector, CBthrustvector, c='Salmon', marker='o', ls='None') #plot mass if PlotOptions.PlotMass: mass = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby' and event.EventType != 'LT_rndzvs': mass.append(event.Mass * 1.0e-3) if firstpass: DataAxesLeft.plot(date_vector, mass, c='DarkGrey', lw=2, ls='-', label='Mass (1000 kg)') else: DataAxesLeft.plot(date_vector, mass, c='DarkGrey', lw=2, ls='-') #plot number of active thrusters if PlotOptions.PlotNumberOfEngines: numberofengines = [] shortDateVector = [] for event in self.missionevents: if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', 'PSBIthrust', 'PSFBthrust', 'LT_spiral']: numberofengines.append(event.ActivePower) shortDateVector.append(datetime.datetime.strptime(event.GregorianDate,'%m/%d/%Y').date()) if firstpass: DataAxesLeft.plot(shortDateVector, numberofengines, 'k*', mew=2, markersize=7, label='Number of active thrusters') else: DataAxesLeft.plot(shortDateVector, numberofengines, 'k*', mew=2, markersize=7) #plot power actively used by the thrusters if PlotOptions.PlotActivePower: activepowervector = [] shortDateVector = [] for event in self.missionevents: if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', 'PSBIthrust', 'PSFBthrust', 'LT_spiral']: activepowervector.append(event.ActivePower) shortDateVector.append(datetime.datetime.strptime(event.GregorianDate,'%m/%d/%Y').date()) if firstpass: DataAxesLeft.plot(shortDateVector, activepowervector, c='Navy', lw=2, ls='-', label='Power used by the propulsion system (kW)') else: DataAxesLeft.plot(shortDateVector, activepowervector, c='Navy', lw=2, ls='-') #plot waste heat from the propulsion system if PlotOptions.PlotWasteHeat: WasteHeatvector = [] shortDateVector = [] for event in self.missionevents: if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', 'PSBIthrust', 'PSFBthrust', 'LT_spiral']: WasteHeatvector.append( (1 - event.AvailableThrust * event.Isp * 9.80665 / (2000 * event.ActivePower)) * event.ActivePower ) shortDateVector.append(datetime.datetime.strptime(event.GregorianDate,'%m/%d/%Y').date()) if firstpass: DataAxesLeft.plot(shortDateVector, WasteHeatvector, c='Crimson', lw=2, ls='--', label='Waste heat from propulsion system (kW)') else: DataAxesLeft.plot(shortDateVector, WasteHeatvector, c='Crimson', lw=2, ls='--') #plot Earth distance in LU and SPE angle if PlotOptions.PlotEarthDistance or PlotOptions.PlotSunSpacecraftEarthAngle or PlotOptions.PlotSpacecraftViewingAngle: if not 'sun' in self.central_body.lower(): print('getting Earth distance and Sun-Spacecraft-Earth angle is only supported if the central body is the sun') else: import de423 from jplephem import Ephemeris eph = Ephemeris(de423) EarthDistanceVector = [] SunSpacecraftEarthAngle = [] SpacecraftViewingAngle = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby' and event.EventType != 'LT_rndzvs': #get the position of the central body relative to the solar system barycenter cb_relative_to_solar_system_barycenter_in_ICRF = eph.position('sun', event.JulianDate) #get the position of the Earth relative to the central body embarycenter_in_ICRF = eph.position('earthmoon', event.JulianDate) moonvector_in_ICRF = eph.position('moon', event.JulianDate) Earth_relative_to_solar_system_barycenter_in_ICRF = embarycenter_in_ICRF - moonvector_in_ICRF * eph.earth_share Earth_relative_to_cb_in_ICRF = Earth_relative_to_solar_system_barycenter_in_ICRF + cb_relative_to_solar_system_barycenter_in_ICRF #rotate the spacecraft state relative to the central body into the ICRF frame spacecraft_state_relative_to_central_body_in_ICRF = AstroFunctions.rotate_from_ecliptic_to_equatorial3(np.array(event.SpacecraftState[0:3])) #get the vector from the Earth to the Spacecraft Earth_Spacecraft_Vector = spacecraft_state_relative_to_central_body_in_ICRF - np.transpose(Earth_relative_to_cb_in_ICRF)[0] #return the magnitude of the Earth-centered position vector EarthDistanceVector.append(np.linalg.norm(Earth_Spacecraft_Vector) / self.LU) #if applicable, compute sun-spacecraft-Earth angle if PlotOptions.PlotSunSpacecraftEarthAngle: cosAngle = np.dot(-Earth_Spacecraft_Vector, -spacecraft_state_relative_to_central_body_in_ICRF)/np.linalg.norm(spacecraft_state_relative_to_central_body_in_ICRF)/np.linalg.norm(Earth_Spacecraft_Vector) SunSpacecraftEarthAngle.append(np.arccos(cosAngle) * 180.0/math.pi) if PlotOptions.PlotSpacecraftViewingAngle: tanAngle = Earth_Spacecraft_Vector[2]/math.sqrt(Earth_Spacecraft_Vector[0]*Earth_Spacecraft_Vector[0]+Earth_Spacecraft_Vector[1]*Earth_Spacecraft_Vector[1]) SpacecraftViewingAngle.append(np.arctan(tanAngle) * 180.0/math.pi) if PlotOptions.PlotEarthDistance: if firstpass: unitstring = 'LU' if 'sun' in self.central_body.lower() and math.fabs(self.LU - 149597870.69100001) < 1.0: unitstring = 'AU' labelstring = 'Distance from Earth (' + unitstring + ')' DataAxesLeft.plot(date_vector, EarthDistanceVector, c='g', lw=2, label=labelstring) else: DataAxesLeft.plot(date_vector, EarthDistanceVector, c='g', lw=2) if PlotOptions.PlotSunSpacecraftEarthAngle: if firstpass: DataAxesRight.plot(date_vector, SunSpacecraftEarthAngle, c='orangered', lw=2, ls = '-.', label='Sun-Spacecraft-Earth Angle') else: DataAxesRight.plot(date_vector, SunSpacecraftEarthAngle, c='orangered', lw=2, ls = '-.') if PlotOptions.PlotSpacecraftViewingAngle: if firstpass: DataAxesRight.plot(date_vector, SpacecraftViewingAngle, c='orangered', lw=2, ls = '-.', label='Latitude of Earth-Spacecraft Vector') else: DataAxesRight.plot(date_vector, SpacecraftViewingAngle, c='orangered', lw=2, ls = '-.') #plot throttle level if PlotOptions.PlotThrottleLevel: ThrottleLevelVector = [] shortDateVector = [] for event in self.missionevents: if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', 'PSBIthrust', 'PSFBthrust', 'LT_spiral']: ThrottleLevelVector.append(event.ThrottleLevel) shortDateVector.append(datetime.datetime.strptime(event.GregorianDate,'%m/%d/%Y').date()) if firstpass: DataAxesLeft.scatter(shortDateVector, ThrottleLevelVector, c='midnightblue', marker='h' , label='Throttle level') else: DataAxesLeft.scatter(shortDateVector, ThrottleLevelVector, c='midnightblue', marker='h' ) #plot sun-boresight angle if PlotOptions.PlotSunBoresightAngle: SunBoresightAngle = [] for event in self.missionevents: if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', 'PSFBthrust', "PSBIthrust"]: r = math.sqrt(event.SpacecraftState[0]**2 + event.SpacecraftState[1]**2 + event.SpacecraftState[2]**2) AppliedThrust = math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) rdotT = -event.SpacecraftState[0]*event.Thrust[0] - event.SpacecraftState[1]*event.Thrust[1] - event.SpacecraftState[2]*event.Thrust[2] SunBoresightAngle.append(math.acos( rdotT / (r * AppliedThrust) ) * 180.0 / math.pi) elif event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby' and event.EventType != 'LT_rndzvs': SunBoresightAngle.append(0.0) if firstpass: DataAxesRight.plot(date_vector, SunBoresightAngle, c='purple', marker='o', ls='None', label='Sun-to-Boresight angle (degrees)') else: DataAxesRight.plot(date_vector, SunBoresightAngle, c='purple', marker='o', ls='None') #DataAxesLeft.set_ylim(bottom=-0.7) #DataAxesRight.set_ylim(bottom=-0.7) #DataAxesLeft.set_ylim([-0.2,2.5]) #DataAxesLeft.set_ylim([-0.2,2.5]) def WriteDateReport(self, PlotOptions, reportfile): #write header reportfile.write('JD, MM-DD-YYYY, Event duration (days), Event type, Event location') if PlotOptions.IncludeStateVectorInReport: reportfile.write(',x (km), y (km), z (km), xdot (km/s), ydot (km/s), zdot (km/s)') if PlotOptions.PlotR: unitstring = 'LU' if 'sun' in self.central_body.lower() and math.fabs(self.LU - 149597870.69100001) < 1.0: unitstring = 'AU' reportfile.write(', Distance from ' + self.central_body + ' (' + unitstring + ')') if PlotOptions.PlotV: reportfile.write(', Velocity magnitude (LU/TU)') if PlotOptions.PlotThrust: reportfile.write(', Applied thrust (N)') if PlotOptions.PlotIsp: reportfile.write(', Isp (s)') if PlotOptions.PlotMdot: reportfile.write(', Mass flow rate (kg/s)') if PlotOptions.PlotEfficiency: reportfile.write(', Propulsion system efficiency') if PlotOptions.PlotThrottle: reportfile.write(', Control magnitude') if PlotOptions.PlotPower: reportfile.write(', Power produced by spacecraft (kW)') if PlotOptions.PlotGamma: reportfile.write(', in-plane control angle (degrees)') if PlotOptions.PlotDelta: reportfile.write(', out-of-plane control angle (degrees)') if PlotOptions.PlotArray_Thrust_Angle: reportfile.write(', Array to thrust angle (degrees)') if PlotOptions.PlotMass: reportfile.write(', Mass (kg)') if PlotOptions.PlotNumberOfEngines: reportfile.write(', Number of active thrusters') if PlotOptions.PlotActivePower: reportfile.write(', Power used by the propulsion system (kW)') if PlotOptions.PlotWasteHeat: reportfile.write(', Waste heat from propulsion system (kW)') if PlotOptions.PlotEarthDistance: unitstring = 'LU' if 'sun' in self.central_body.lower() and math.fabs(self.LU - 149597870.69100001) < 1.0: unitstring = 'AU' reportfile.write(', Distance from Earth (' + unitstring + ')') if PlotOptions.PlotSunSpacecraftEarthAngle: reportfile.write(', Sun-Spacecraft-Earth Angle') if PlotOptions.PlotSpacecraftViewingAngle: reportfile.write(', Latitude of Earth-Spacecraft Vector') if PlotOptions.PlotThrottleLevel: reportfile.write(', Throttle level') if PlotOptions.PlotSunBoresightAngle: reportfile.write(', Sun-Boresight Angle') reportfile.write('\n') #load stuff if necessary if PlotOptions.PlotEarthDistance or PlotOptions.PlotSunSpacecraftEarthAngle or PlotOptions.PlotSpacecraftViewingAngle: if not 'sun' in self.central_body.lower(): print('getting Earth distance and Sun-Spacecraft-Earth angle is only supported if the central body is the sun') else: import de423 from jplephem import Ephemeris self.eph = Ephemeris(de423) if PlotOptions.PlotThrottleLevel: #instantiate a throttle table object thruster_throttle_table = ThrottleTable.ThrottleTable(PlotOptions.throttletablefile) self.high_Mdot_set, self.low_Mdot_set = thruster_throttle_table.create_non_dominated_sets() #now print the report for event in self.missionevents: reportfile.write(str(event.JulianDate)) reportfile.write(', ' + event.GregorianDate) reportfile.write(', ' + str(event.TimestepLength)) reportfile.write(', ' + event.EventType) reportfile.write(', ' + event.Location) if PlotOptions.IncludeStateVectorInReport: for state in event.SpacecraftState: reportfile.write(', ' + str(state)) if PlotOptions.PlotR: reportfile.write(', ' + str(math.sqrt(event.SpacecraftState[0]**2 + event.SpacecraftState[1]**2 + event.SpacecraftState[2]**2) / self.LU)) if PlotOptions.PlotV: reportfile.write(', ' + str(math.sqrt(event.SpacecraftState[3]**2 + event.SpacecraftState[4]**2 + event.SpacecraftState[5]**2) / self.LU * self.TU)) if PlotOptions.PlotThrust: if event.EventType not in ['match_point','upwr_flyby','pwr_flyby','LT_rndzvs','LT_spiral']: reportfile.write(', ' + str(math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2))) elif event.EventType == 'LT_spiral': reportfile.write(', ' + str(event.AvailableThrust * self.thruster_duty_cycle)) else: reportfile.write(', 0.0') if PlotOptions.PlotIsp: reportfile.write(', ' + str(event.Isp)) if PlotOptions.PlotMdot: reportfile.write(', ' + str(event.MassFlowRate)) if PlotOptions.PlotEfficiency: if event.EventType in ['SFthrust', 'SSFthrust','FBLTSthrust','FBLTthrust','PSBIthrust','PSFBthrust','LT_spiral']: reportfile.write(', ' + str(event.AvailableThrust * event.Isp * 9.80665 / (2000 * event.ActivePower))) else: reportfile.write(', 0.0') if PlotOptions.PlotThrottle: if event.EventType in ['SFthrust', 'SSFthrust','FBLTSthrust','FBLTthrust','PSBIthrust','PSFBthrust']: reportfile.write(', ' + str(math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) / (event.AvailableThrust * self.thruster_duty_cycle))) elif event.EventType == 'LT_spiral': reportfile.write(', ' + str(1.0)) elif event.EventType not in ['match_point','upwr_flyby','pwr_flyby','LT_rndzvs']: reportfile.write(', ' + str(0.0)) if PlotOptions.PlotPower: if event.EventType not in ['match_point','upwr_flyby','pwr_flyby','LT_rndzvs']: if (event.AvailablePower > 0.0): reportfile.write(', ' + str(event.AvailablePower)) else: reportfile.write(', ' + str(0.0)) else: reportfile.write(', ' + str(0.0)) if PlotOptions.PlotGamma: if event.EventType in ['SFthrust', 'SSFthrust','FBLTSthrust','FBLTthrust','PSBIthrust','PSFBthrust','LT_spiral']: reportfile.write(', ' + str(math.atan2(event.Thrust[1], event.Thrust[0]) * 180.0 / math.pi)) else: reportfile.write(', ' + str(0.0)) if PlotOptions.PlotDelta: if event.EventType in ['SFthrust', 'SSFthrust','FBLTSthrust','FBLTthrust','PSBIthrust','PSFBthrust','LT_spiral']: AppliedThrust = math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) reportfile.write(', ' + str(math.asin(event.Thrust[2] / AppliedThrust) * 180.0 / math.pi)) else: reportfile.write(', ' + str(0.0)) if PlotOptions.PlotArray_Thrust_Angle: if event.EventType in ['SFthrust', 'SSFthrust','FBLTSthrust','FBLTthrust','PSBIthrust','PSFBthrust','LT_spiral']: r = math.sqrt(event.SpacecraftState[0]**2 + event.SpacecraftState[1]**2 + event.SpacecraftState[2]**2) AppliedThrust = math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) rdotT = event.SpacecraftState[0]*event.Thrust[0] + event.SpacecraftState[1]*event.Thrust[1] + event.SpacecraftState[2]*event.Thrust[2] reportfile.write(', ' + str(math.acos( rdotT / (r * AppliedThrust) ) * 180.0 / math.pi)) else: reportfile.write(', ' + str(0.0)) if PlotOptions.PlotMass: reportfile.write(', ' + str(event.Mass)) if PlotOptions.PlotNumberOfEngines: if event.EventType in ['SFthrust', 'SSFthrust','FBLTSthrust','FBLTthrust','PSBIthrust','PSFBthrust','LT_spiral']: reportfile.write(', ' + str(event.Number_of_Active_Engines)) else: reportfile.write(', ' + str(0)) if PlotOptions.PlotActivePower: if event.EventType in ['SFthrust', 'SSFthrust','FBLTSthrust','FBLTthrust','PSBIthrust','PSFBthrust','LT_spiral']: reportfile.write(', ' + str(event.ActivePower)) else: reportfile.write(', ' + str(0.0)) if PlotOptions.PlotWasteHeat: if event.EventType in ['SFthrust', 'SSFthrust','FBLTSthrust','FBLTthrust','PSBIthrust','PSFBthrust','LT_spiral']: reportfile.write(', ' + str((1.0 - event.AvailableThrust * event.Isp * 9.80665 / (2000.0 * event.ActivePower)) * event.ActivePower)) else: reportfile.write(', ' + str(0.0)) if PlotOptions.PlotEarthDistance or PlotOptions.PlotSunSpacecraftEarthAngle or PlotOptions.PlotSpacecraftViewingAngle: if not 'sun' in self.central_body.lower(): print('getting Earth distance and Sun-Spacecraft-Earth angle is only supported if the central body is the sun') else: #get the position of the central body relative to the solar system barycenter cb_relative_to_solar_system_barycenter_in_ICRF = self.eph.position('sun', event.JulianDate) #get the position of the Earth relative to the central body embarycenter_in_ICRF = self.eph.position('earthmoon', event.JulianDate) moonvector_in_ICRF = self.eph.position('moon', event.JulianDate) Earth_relative_to_solar_system_barycenter_in_ICRF = embarycenter_in_ICRF - moonvector_in_ICRF * self.eph.earth_share Earth_relative_to_cb_in_ICRF = Earth_relative_to_solar_system_barycenter_in_ICRF + cb_relative_to_solar_system_barycenter_in_ICRF #rotate the spacecraft state relative to the central body into the ICRF frame spacecraft_state_relative_to_central_body_in_ICRF = AstroFunctions.rotate_from_ecliptic_to_equatorial3(np.array(event.SpacecraftState[0:3])) #get the vector from the Earth to the Spacecraft Earth_Spacecraft_Vector = spacecraft_state_relative_to_central_body_in_ICRF - np.transpose(Earth_relative_to_cb_in_ICRF)[0] #return the magnitude of the Earth-centered position vector EarthDistance = np.linalg.norm(Earth_Spacecraft_Vector) / self.LU if PlotOptions.PlotEarthDistance: reportfile.write(', ' + str(EarthDistance)) if PlotOptions.PlotSunSpacecraftEarthAngle: cosAngle = np.dot(-Earth_Spacecraft_Vector, -spacecraft_state_relative_to_central_body_in_ICRF)/np.linalg.norm(spacecraft_state_relative_to_central_body_in_ICRF)/np.linalg.norm(Earth_Spacecraft_Vector) reportfile.write(', ' + str(np.arccos(cosAngle) * 180.0/math.pi)) if PlotOptions.PlotSpacecraftViewingAngle: tanAngle = Earth_Spacecraft_Vector[2]/math.sqrt(Earth_Spacecraft_Vector[0]*Earth_Spacecraft_Vector[0]+Earth_Spacecraft_Vector[1]*Earth_Spacecraft_Vector[1]) reportfile.write(', ' + str(np.arctan(tanAngle) * 180.0/math.pi)) if PlotOptions.PlotThrottleLevel: if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', 'PSBIthrust','PSFBthrust', 'end_spiral']: if PlotOptions.throttlesetmode == 0: reportfile.write(', ' + str(int(self.high_Mdot_set.find_nearest_throttle_setting_1D(event.ActivePower / event.Number_of_Active_Engines).TL.strip('TL')))) elif PlotOptions.throttlesetmode == 1: reportfile.write(', ' + str(int(self.low_Mdot_set.find_nearest_throttle_setting_1D(event.ActivePower / event.Number_of_Active_Engines).TL.strip('TL')))) elif PlotOptions.throttlesetmode == 2: print('2D throttle matching not currently implemented') else: reportfile.write(', ' + str(0.0)) #plot sun-boresight angle if PlotOptions.PlotSunBoresightAngle: if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', "PSBIthrust",'PSFBthrust']: r = math.sqrt(event.SpacecraftState[0]**2 + event.SpacecraftState[1]**2 + event.SpacecraftState[2]**2) AppliedThrust = math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) rdotT = event.SpacecraftState[0]*event.Thrust[0] + event.SpacecraftState[1]*event.Thrust[1] + event.SpacecraftState[2]*event.Thrust[2] reportfile.write(', ' + str(math.acos( rdotT / (r * AppliedThrust) ) * 180.0 / math.pi)) else: reportfile.write(', ' + str(0.0)) reportfile.write('\n') def AutoTableJourney(self, TableFile, PlotOptions, skipNext): for event in self.missionevents: skipNext = event.AutoTableLine(TableFile, PlotOptions, skipNext) return skipNext def getManeuver(self, phaseIndex = 0, maneuverIndex = 0): #function to get the nth DSM/TCM in a phase #if that maneuver does not exist, return None #Step 1: search through the journey to find the right phase. We do this by counting the number of boundary events until we get to the end of the journey or the phase that we want #since phase boundaries are always upwr_flyby or pwr_flyby, this isn't too hard! phaseCount = 0 maneuverCount = 0 for event in self.missionevents: if event.EventType in ['pwr_flyby','upwr_flyby']: phaseCount += 1 maneuverCount = 0 if event.EventType == 'chem_burn': if maneuverCount == maneuverIndex: #this is the maneuver that we want, so return it return event #if we didn't just return, increment the maneuver count maneuverCount += 1 #if we got this far then the event that the user asked for does not exist, so return "none" return None def getPeriapseDistance(self, scale = None): r_min = 1.0e+10 if scale == None: scale = self.LU for event in self.missionevents: r = (event.SpacecraftState[0]**2 + event.SpacecraftState[1]**2 + event.SpacecraftState[2]**2 ) ** 0.5 if r < r_min: r_min = r return r_min / scale
def GenerateJourneyDataPlot(self, DataAxesLeft, DataAxesRight, PlotOptions, firstpass): import math import astropy #generate a vector of dates date_string_vector = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby' and event.EventType != 'LT_rndzvs': date_string_vector.append(event.GregorianDate) date_vector = [datetime.datetime.strptime(d,'%m/%d/%Y').date() for d in date_string_vector] #dummy line across the bottom so that neither axes object crashes DataAxesLeft.plot(date_vector, np.zeros_like(date_vector), c='w', lw = 0.1) DataAxesRight.plot(date_vector, np.zeros_like(date_vector), c='w', lw = 0.1) #plot distance from central body if PlotOptions.PlotR: Rvector = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby' and event.EventType != 'LT_rndzvs': Rvector.append(math.sqrt(event.SpacecraftState[0]**2 + event.SpacecraftState[1]**2 + event.SpacecraftState[2]**2) / self.LU) if firstpass: unitstring = 'LU' if 'sun' in self.central_body.lower() and math.fabs(self.LU - 149597870.69100001) < 1.0: unitstring = 'AU' labelstring = 'Distance from ' + self.central_body + ' (' + unitstring + ')' DataAxesLeft.plot(date_vector, Rvector, c='k', lw=2, label=labelstring) else: DataAxesLeft.plot(date_vector, Rvector, c='k', lw=2) #plot velocity if PlotOptions.PlotV: Vvector = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby' and event.EventType != 'LT_rndzvs': Vvector.append(math.sqrt(event.SpacecraftState[3]**2 + event.SpacecraftState[4]**2 + event.SpacecraftState[5]**2) / self.LU * self.TU) if firstpass: DataAxesLeft.plot(date_vector, Vvector, c='k', lw=2, ls='-.', label='Velocity magnitude (LU/TU)') else: DataAxesLeft.plot(date_vector, Vvector, c='k', lw=2, ls='-.') #plot Thrust if PlotOptions.PlotThrust: Thrustvector = [] shortDateVector = [] for event in self.missionevents: epoch = astropy.time.Time(event.JulianDate, format='jd', scale='tdb') if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', 'PSBIthrust', 'PSFBthrust']: Thrustvector.append(math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) * 10.0) shortDateVector.append((epoch - event.TimestepLength / 2).datetime) Thrustvector.append(math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) * 10.0) shortDateVector.append((epoch + event.TimestepLength / 2).datetime) elif event.EventType == 'LT_spiral': Thrustvector.append(event.AvailableThrust * self.thruster_duty_cycle*10.0) shortDateVector.append((epoch - event.TimestepLength / 2).datetime) Thrustvector.append(event.AvailableThrust * self.thruster_duty_cycle*10.0) shortDateVector.append((epoch + event.TimestepLength / 2).datetime) elif event.EventType != 'match_point': Thrustvector.append(0.0) shortDateVector.append((epoch - event.TimestepLength / 2).datetime) Thrustvector.append(0.0) shortDateVector.append((epoch + event.TimestepLength / 2).datetime) if firstpass: DataAxesLeft.plot(shortDateVector, Thrustvector, c='r', lw=2, ls='--', label='Applied thrust (0.1 N)') else: DataAxesLeft.plot(shortDateVector, Thrustvector, c='r', lw=2, ls='--') #plot Isp if PlotOptions.PlotIsp: Ispvector = [] shortDateVector = [] for event in self.missionevents: epoch = astropy.time.Time(event.JulianDate, format='jd', scale='tdb') if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', 'PSBIthrust', 'PSFBthrust', 'LT_spiral']: Ispvector.append(event.Isp / 1000.0) shortDateVector.append((epoch - event.TimestepLength / 2).datetime) Ispvector.append(event.Isp / 1000.0) shortDateVector.append((epoch + event.TimestepLength / 2).datetime) elif event.EventType != 'match_point': Ispvector.append(0.0) shortDateVector.append((epoch - event.TimestepLength / 2).datetime) Ispvector.append(0.0) shortDateVector.append((epoch + event.TimestepLength / 2).datetime) if firstpass: DataAxesLeft.plot(shortDateVector, Ispvector, 'dodgerblue', lw=4, ls='-.', label='Isp (1000 s)') else: DataAxesLeft.plot(shortDateVector, Ispvector, 'dodgerblue', lw=4, ls='-.') #plot mass flow rate if PlotOptions.PlotMdot: Mdotvector = [] shortDateVector = [] for event in self.missionevents: epoch = astropy.time.Time(event.JulianDate, format='jd', scale='tdb') if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', 'PSBIthrust', 'PSFBthrust', 'LT_spiral']: Mdotvector.append(event.MassFlowRate * 1.0e6) shortDateVector.append((epoch - event.TimestepLength / 2).datetime) Mdotvector.append(event.MassFlowRate * 1.0e6) shortDateVector.append((epoch + event.TimestepLength / 2).datetime) elif event.EventType != 'match_point': Mdotvector.append(0.0) shortDateVector.append((epoch - event.TimestepLength / 2).datetime) Mdotvector.append(0.0) shortDateVector.append((epoch + event.TimestepLength / 2).datetime) if firstpass: DataAxesLeft.plot(shortDateVector, Mdotvector, c='brown', lw=2, ls='-', label='Mass flow rate (mg/s)') else: DataAxesLeft.plot(shortDateVector, Mdotvector, c='brown', lw=2, ls='-') #plot Efficiency if PlotOptions.PlotEfficiency: Efficiencyvector = [] shortDateVector = [] for event in self.missionevents: epoch = astropy.time.Time(event.JulianDate, format='jd', scale='tdb') if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', 'PSBIthrust', 'PSFBthrust', 'LT_spiral']: Efficiencyvector.append(event.AvailableThrust * event.Isp * 9.80665 / (2000 * event.ActivePower)) shortDateVector.append((epoch - event.TimestepLength / 2).datetime) Efficiencyvector.append(event.AvailableThrust * event.Isp * 9.80665 / (2000 * event.ActivePower)) shortDateVector.append((epoch + event.TimestepLength / 2).datetime) elif event.EventType != 'match_point': Efficiencyvector.append(0.0) shortDateVector.append((epoch - event.TimestepLength / 2).datetime) Efficiencyvector.append(0.0) shortDateVector.append((epoch + event.TimestepLength / 2).datetime) if firstpass: DataAxesLeft.plot(shortDateVector, Efficiencyvector, c='DarkGreen', lw=2, ls='-', label='Propulsion system efficiency') else: DataAxesLeft.plot(shortDateVector, Efficiencyvector, c='DarkGreen', lw=2, ls='-') #plot control magnitude if PlotOptions.PlotThrottle: Throttlevector = [] shortDateVector = [] for event in self.missionevents: epoch = astropy.time.Time(event.JulianDate, format='jd', scale='tdb') if event.EventType in ['SFthrust', 'SSFthrust', 'PSBIthrust']: Throttlevector.append(math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) / (event.AvailableThrust)) shortDateVector.append((epoch - event.TimestepLength / 2).datetime) Throttlevector.append(math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) / (event.AvailableThrust)) shortDateVector.append((epoch + event.TimestepLength / 2).datetime) elif event.EventType in ['FBLTthrust','FBLTSthrust','PSFBthrust']: Throttlevector.append(event.DVmagorThrottle) shortDateVector.append((epoch - event.TimestepLength / 2).datetime) Throttlevector.append(event.DVmagorThrottle) shortDateVector.append((epoch + event.TimestepLength / 2).datetime) elif event.EventType == 'LT_spiral': Throttlevector.append(1.0) shortDateVector.append((epoch - event.TimestepLength / 2).datetime) Throttlevector.append(1.0) shortDateVector.append((epoch + event.TimestepLength / 2).datetime) elif event.EventType != 'match_point': Throttlevector.append(0.0) shortDateVector.append((epoch - event.TimestepLength / 2).datetime) Throttlevector.append(0.0) shortDateVector.append((epoch + event.TimestepLength / 2).datetime) if firstpass: DataAxesLeft.plot(shortDateVector, Throttlevector, c='r', lw=2, ls='--', label='Control magnitude') else: DataAxesLeft.plot(shortDateVector, Throttlevector, c='r', lw=2, ls='--') #plot power if PlotOptions.PlotPower: Powervector = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby' and event.EventType != 'LT_rndzvs': if event.AvailablePower > 0.0: Powervector.append(event.AvailablePower) else: Powervector.append(0.0) if firstpass: DataAxesLeft.plot(date_vector, Powervector, c='Navy', lw=2, ls='-.', label='Power available for propulsion (kW)') else: DataAxesLeft.plot(date_vector, Powervector, c='Navy', lw=2, ls='-.') #plot gamma if PlotOptions.PlotGamma: gammavector = [] shortDateVector = [] for event in self.missionevents: if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', 'PSBIthrust', 'PSFBthrust', 'LT_spiral']: gammavector.append(math.atan2(event.Thrust[1], event.Thrust[0]) * 180.0 / math.pi) shortDateVector.append(datetime.datetime.strptime(event.GregorianDate,'%m/%d/%Y').date()) if firstpass: DataAxesRight.plot(shortDateVector, gammavector, c='DarkGreen', lw=2, ls='--', label=r'$\gamma$ (degrees)') else: DataAxesRight.plot(shortDateVector, gammavector, c='DarkGreen', lw=2, ls='--') #plot delta if PlotOptions.PlotDelta: deltavector = [] shortDateVector = [] for event in self.missionevents: if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', 'PSBIthrust', 'PSFBthrust', 'LT_spiral']: AppliedThrust = math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) deltavector.append(math.asin(event.Thrust[2] / AppliedThrust) * 180.0 / math.pi) shortDateVector.append(datetime.datetime.strptime(event.GregorianDate,'%m/%d/%Y').date()) if firstpass: DataAxesRight.plot(shortDateVector, deltavector, c='LightGreen', lw=2, ls='--', label=r'$\delta$ (degrees)') else: DataAxesRight.plot(shortDateVector, deltavector, c='LightGreen', lw=2, ls='--') #plot central body to thrust vector angle if PlotOptions.PlotArray_Thrust_Angle: CBthrustvector = [] shortDateVector = [] for event in self.missionevents: if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', 'PSBIthrust', 'PSFBthrust', 'LT_spiral']: r = math.sqrt(event.SpacecraftState[0]**2 + event.SpacecraftState[1]**2 + event.SpacecraftState[2]**2) AppliedThrust = math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) rdotT = event.SpacecraftState[0]*event.Thrust[0] + event.SpacecraftState[1]*event.Thrust[1] + event.SpacecraftState[2]*event.Thrust[2] CBthrustvector.append( 90.0 - math.acos( rdotT / (r * AppliedThrust) ) * 180.0 / math.pi) shortDateVector.append(datetime.datetime.strptime(event.GregorianDate,'%m/%d/%Y').date()) if firstpass: DataAxesRight.plot(shortDateVector, CBthrustvector, c='Salmon', marker='o', ls='None', label='Array to thrust angle (degrees)') else: DataAxesRight.plot(shortDateVector, CBthrustvector, c='Salmon', marker='o', ls='None') #plot mass if PlotOptions.PlotMass: mass = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby' and event.EventType != 'LT_rndzvs': mass.append(event.Mass * 1.0e-3) if firstpass: DataAxesLeft.plot(date_vector, mass, c='DarkGrey', lw=2, ls='-', label='Mass (1000 kg)') else: DataAxesLeft.plot(date_vector, mass, c='DarkGrey', lw=2, ls='-') #plot number of active thrusters if PlotOptions.PlotNumberOfEngines: numberofengines = [] shortDateVector = [] for event in self.missionevents: if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', 'PSBIthrust', 'PSFBthrust', 'LT_spiral']: numberofengines.append(event.ActivePower) shortDateVector.append(datetime.datetime.strptime(event.GregorianDate,'%m/%d/%Y').date()) if firstpass: DataAxesLeft.plot(shortDateVector, numberofengines, 'k*', mew=2, markersize=7, label='Number of active thrusters') else: DataAxesLeft.plot(shortDateVector, numberofengines, 'k*', mew=2, markersize=7) #plot power actively used by the thrusters if PlotOptions.PlotActivePower: activepowervector = [] shortDateVector = [] for event in self.missionevents: if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', 'PSBIthrust', 'PSFBthrust', 'LT_spiral']: activepowervector.append(event.ActivePower) shortDateVector.append(datetime.datetime.strptime(event.GregorianDate,'%m/%d/%Y').date()) if firstpass: DataAxesLeft.plot(shortDateVector, activepowervector, c='Navy', lw=2, ls='-', label='Power used by the propulsion system (kW)') else: DataAxesLeft.plot(shortDateVector, activepowervector, c='Navy', lw=2, ls='-') #plot waste heat from the propulsion system if PlotOptions.PlotWasteHeat: WasteHeatvector = [] shortDateVector = [] for event in self.missionevents: if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', 'PSBIthrust', 'PSFBthrust', 'LT_spiral']: WasteHeatvector.append( (1 - event.AvailableThrust * event.Isp * 9.80665 / (2000 * event.ActivePower)) * event.ActivePower ) shortDateVector.append(datetime.datetime.strptime(event.GregorianDate,'%m/%d/%Y').date()) if firstpass: DataAxesLeft.plot(shortDateVector, WasteHeatvector, c='Crimson', lw=2, ls='--', label='Waste heat from propulsion system (kW)') else: DataAxesLeft.plot(shortDateVector, WasteHeatvector, c='Crimson', lw=2, ls='--') #plot Earth distance in LU and SPE angle if PlotOptions.PlotEarthDistance or PlotOptions.PlotSunSpacecraftEarthAngle or PlotOptions.PlotSpacecraftViewingAngle: if not 'sun' in self.central_body.lower(): print('getting Earth distance and Sun-Spacecraft-Earth angle is only supported if the central body is the sun') else: import de423 from jplephem import Ephemeris eph = Ephemeris(de423) EarthDistanceVector = [] SunSpacecraftEarthAngle = [] SpacecraftViewingAngle = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby' and event.EventType != 'LT_rndzvs': #get the position of the central body relative to the solar system barycenter cb_relative_to_solar_system_barycenter_in_ICRF = eph.position('sun', event.JulianDate) #get the position of the Earth relative to the central body embarycenter_in_ICRF = eph.position('earthmoon', event.JulianDate) moonvector_in_ICRF = eph.position('moon', event.JulianDate) Earth_relative_to_solar_system_barycenter_in_ICRF = embarycenter_in_ICRF - moonvector_in_ICRF * eph.earth_share Earth_relative_to_cb_in_ICRF = Earth_relative_to_solar_system_barycenter_in_ICRF + cb_relative_to_solar_system_barycenter_in_ICRF #rotate the spacecraft state relative to the central body into the ICRF frame spacecraft_state_relative_to_central_body_in_ICRF = AstroFunctions.rotate_from_ecliptic_to_equatorial3(np.array(event.SpacecraftState[0:3])) #get the vector from the Earth to the Spacecraft Earth_Spacecraft_Vector = spacecraft_state_relative_to_central_body_in_ICRF - np.transpose(Earth_relative_to_cb_in_ICRF)[0] #return the magnitude of the Earth-centered position vector EarthDistanceVector.append(np.linalg.norm(Earth_Spacecraft_Vector) / self.LU) #if applicable, compute sun-spacecraft-Earth angle if PlotOptions.PlotSunSpacecraftEarthAngle: cosAngle = np.dot(-Earth_Spacecraft_Vector, -spacecraft_state_relative_to_central_body_in_ICRF)/np.linalg.norm(spacecraft_state_relative_to_central_body_in_ICRF)/np.linalg.norm(Earth_Spacecraft_Vector) SunSpacecraftEarthAngle.append(np.arccos(cosAngle) * 180.0/math.pi) if PlotOptions.PlotSpacecraftViewingAngle: tanAngle = Earth_Spacecraft_Vector[2]/math.sqrt(Earth_Spacecraft_Vector[0]*Earth_Spacecraft_Vector[0]+Earth_Spacecraft_Vector[1]*Earth_Spacecraft_Vector[1]) SpacecraftViewingAngle.append(np.arctan(tanAngle) * 180.0/math.pi) if PlotOptions.PlotEarthDistance: if firstpass: unitstring = 'LU' if 'sun' in self.central_body.lower() and math.fabs(self.LU - 149597870.69100001) < 1.0: unitstring = 'AU' labelstring = 'Distance from Earth (' + unitstring + ')' DataAxesLeft.plot(date_vector, EarthDistanceVector, c='g', lw=2, label=labelstring) else: DataAxesLeft.plot(date_vector, EarthDistanceVector, c='g', lw=2) if PlotOptions.PlotSunSpacecraftEarthAngle: if firstpass: DataAxesRight.plot(date_vector, SunSpacecraftEarthAngle, c='orangered', lw=2, ls = '-.', label='Sun-Spacecraft-Earth Angle') else: DataAxesRight.plot(date_vector, SunSpacecraftEarthAngle, c='orangered', lw=2, ls = '-.') if PlotOptions.PlotSpacecraftViewingAngle: if firstpass: DataAxesRight.plot(date_vector, SpacecraftViewingAngle, c='orangered', lw=2, ls = '-.', label='Latitude of Earth-Spacecraft Vector') else: DataAxesRight.plot(date_vector, SpacecraftViewingAngle, c='orangered', lw=2, ls = '-.') #plot throttle level if PlotOptions.PlotThrottleLevel: ThrottleLevelVector = [] shortDateVector = [] for event in self.missionevents: if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', 'PSBIthrust', 'PSFBthrust', 'LT_spiral']: ThrottleLevelVector.append(event.ThrottleLevel) shortDateVector.append(datetime.datetime.strptime(event.GregorianDate,'%m/%d/%Y').date()) if firstpass: DataAxesLeft.scatter(shortDateVector, ThrottleLevelVector, c='midnightblue', marker='h' , label='Throttle level') else: DataAxesLeft.scatter(shortDateVector, ThrottleLevelVector, c='midnightblue', marker='h' ) #plot sun-boresight angle if PlotOptions.PlotSunBoresightAngle: SunBoresightAngle = [] for event in self.missionevents: if event.EventType in ['SFthrust', 'SSFthrust', 'FBLTSthrust', 'FBLTthrust', 'PSFBthrust', "PSBIthrust"]: r = math.sqrt(event.SpacecraftState[0]**2 + event.SpacecraftState[1]**2 + event.SpacecraftState[2]**2) AppliedThrust = math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) rdotT = -event.SpacecraftState[0]*event.Thrust[0] - event.SpacecraftState[1]*event.Thrust[1] - event.SpacecraftState[2]*event.Thrust[2] SunBoresightAngle.append(math.acos( rdotT / (r * AppliedThrust) ) * 180.0 / math.pi) elif event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby' and event.EventType != 'LT_rndzvs': SunBoresightAngle.append(0.0) if firstpass: DataAxesRight.plot(date_vector, SunBoresightAngle, c='purple', marker='o', ls='None', label='Sun-to-Boresight angle (degrees)') else: DataAxesRight.plot(date_vector, SunBoresightAngle, c='purple', marker='o', ls='None')
class Tests(TestCase): def setUp(self): import de421 self.e = Ephemeris(de421) def check0(self, xyz, xyzdot=None): eq = partial(self.assertAlmostEqual, delta=1.0) x, y, z = xyz eq(x, 39705023.28) eq(y, 131195345.65) eq(z, 56898495.41) if xyzdot is None: return dx, dy, dz = xyzdot eq(dx, -2524248.19) eq(dy, 619970.11) eq(dz, 268928.26) def check1(self, xyz, xyzdot=None): eq = partial(self.assertAlmostEqual, delta=1.0) x, y, z = xyz eq(x, -144692624.00) eq(y, -32707965.14) eq(z, -14207167.26) if xyzdot is None: return dx, dy, dz = xyzdot eq(dx, 587334.38) eq(dy, -2297419.36) eq(dz, -996628.74) def test_names(self): self.assertEqual(self.e.names, ( 'earthmoon', 'jupiter', 'librations', 'mars', 'mercury', 'moon', 'neptune', 'nutations', 'pluto', 'saturn', 'sun', 'uranus', 'venus', )) def test_scalar_tdb(self): self.check0(self.e.position('earthmoon', 2414994.0)) self.check1(self.e.position('earthmoon', 2415112.5)) def test_scalar_tdb2(self): self.check0(self.e.position('earthmoon', 2414990.0, 4.0)) self.check1(self.e.position('earthmoon', 2415110.0, 2.5)) def test_scalar_tdb_keyword(self): self.check0(self.e.position('earthmoon', tdb=2414994.0)) self.check1(self.e.position('earthmoon', tdb=2415112.5)) def test_scalar_tdb2_keyword(self): self.check0(self.e.position('earthmoon', tdb=2414990.0, tdb2=4.0)) self.check1(self.e.position('earthmoon', tdb=2415110.0, tdb2=2.5)) def check_2d_result(self, name, tdb, tdb2): p = self.e.position(name, tdb + tdb2) self.check0(p[:,0]) self.check1(p[:,1]) p = self.e.position(name, tdb, tdb2) self.check0(p[:,0]) self.check1(p[:,1]) p, v = self.e.position_and_velocity(name, tdb + tdb2) self.check0(p[:,0], v[:,0]) self.check1(p[:,1], v[:,1]) p, v = self.e.position_and_velocity(name, tdb, tdb2) self.check0(p[:,0], v[:,0]) self.check1(p[:,1], v[:,1]) def test_array_tdb(self): tdb = np.array([2414994.0, 2415112.5]) tdb2 = 0.0 self.check_2d_result('earthmoon', tdb, tdb2) def test_array_tdb_scalar_tdb2(self): tdb = np.array([2414991.5, 2415110.0]) tdb2 = 2.5 self.check_2d_result('earthmoon', tdb, tdb2) def test_scalar_tdb_array_tdb2(self): tdb = 2414990.0 d = 2415112.5 - tdb tdb2 = np.array([4.0, d]) self.check_2d_result('earthmoon', tdb, tdb2) def test_array_tdb_array_tdb2(self): tdb = np.array([2414990.0, 2415110.0]) tdb2 = np.array([4.0, 2.5]) self.check_2d_result('earthmoon', tdb, tdb2) def test_legacy_compute_method(self): pv = self.e.compute('earthmoon', 2414994.0) self.check0(pv[:3], pv[3:]) pv = self.e.compute('earthmoon', np.array([2414994.0, 2415112.5])) self.check0(pv[:3,0], pv[3:,0]) self.check1(pv[:3,1], pv[3:,1]) def test_ephemeris_end_date(self): x, y, z = self.e.position('earthmoon', self.e.jomega) self.assertAlmostEqual(x, -94189805.73967789, delta=1.0) self.assertAlmostEqual(y, 1.05103857e+08, delta=1.0) self.assertAlmostEqual(z, 45550861.44383482, delta=1.0) def test_too_early_date(self): tdb = self.e.jalpha - 0.01 self.assertRaises(DateError, self.e.position, 'earthmoon', tdb) def test_too_late_date(self): tdb = self.e.jomega + 16.01 self.assertRaises(DateError, self.e.position, 'earthmoon', tdb)
def GenerateJourneyDataPlot(self, DataAxesLeft, DataAxesRight, PlotOptions, firstpass): #generate a vector of dates date_string_vector = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': date_string_vector.append(event.GregorianDate) date_vector = [ datetime.datetime.strptime(d, '%m/%d/%Y').date() for d in date_string_vector ] #dummy line across the bottom so that neither axes object crashes DataAxesLeft.plot(date_vector, np.zeros_like(date_vector), c='w', lw=0.1) DataAxesRight.plot(date_vector, np.zeros_like(date_vector), c='w', lw=0.1) #plot distance from central body if PlotOptions.PlotR: Rvector = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': Rvector.append( math.sqrt(event.SpacecraftState[0]**2 + event.SpacecraftState[1]**2 + event.SpacecraftState[2]**2) / self.LU) if firstpass: unitstring = 'LU' if self.central_body.lower( ) == 'sun' and math.fabs(self.LU - 149597870.69100001) < 1.0: unitstring = 'AU' labelstring = 'Distance from ' + self.central_body + ' (' + unitstring + ')' DataAxesLeft.plot(date_vector, Rvector, c='k', lw=2, label=labelstring) else: DataAxesLeft.plot(date_vector, Rvector, c='k', lw=2) #plot velocity if PlotOptions.PlotV: Vvector = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': Vvector.append( math.sqrt(event.SpacecraftState[3]**2 + event.SpacecraftState[4]**2 + event.SpacecraftState[5]**2) / self.LU * self.TU) if firstpass: DataAxesLeft.plot(date_vector, Vvector, c='k', lw=2, ls='-.', label='Velocity magnitude (LU/TU)') else: DataAxesLeft.plot(date_vector, Vvector, c='k', lw=2, ls='-.') #plot Thrust if PlotOptions.PlotThrust: Thrustvector = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': Thrustvector.append( math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) * 10.0) if firstpass: DataAxesLeft.plot(date_vector, Thrustvector, c='r', lw=2, ls='-', label='Applied thrust (0.1 N)') else: DataAxesLeft.plot(date_vector, Thrustvector, c='r', lw=2, ls='-') #plot Isp if PlotOptions.PlotIsp: Ispvector = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': Ispvector.append(event.Isp / 1000.0) if firstpass: DataAxesLeft.plot(date_vector, Ispvector, c='c', lw=2, ls='-', label='Isp (1000 s)') else: DataAxesLeft.plot(date_vector, Ispvector, c='c', lw=2, ls='-') #plot mass flow rate if PlotOptions.PlotMdot: Mdotvector = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': Mdotvector.append(event.MassFlowRate * 1.0e6) if firstpass: DataAxesLeft.plot(date_vector, Mdotvector, c='brown', lw=2, ls='-', label='Mass flow rate (mg/s)') else: DataAxesLeft.plot(date_vector, Mdotvector, c='brown', lw=2, ls='-') #plot Efficiency if PlotOptions.PlotEfficiency: Efficiencyvector = [] for event in self.missionevents: if event.EventType == 'SFthrust' or event.EventType == 'FBLTthrust' or event.EventType == "PSBIthrust": Efficiencyvector.append(event.AvailableThrust * event.Isp * 9.80665 / (2000 * event.ActivePower)) elif event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': Efficiencyvector.append(0.0) if firstpass: DataAxesLeft.plot(date_vector, Efficiencyvector, c='DarkGreen', lw=2, ls='-', label='Propulsion system efficiency') else: DataAxesLeft.plot(date_vector, Efficiencyvector, c='DarkGreen', lw=2, ls='-') #plot Throttle if PlotOptions.PlotThrottle: Throttlevector = [] for event in self.missionevents: if event.EventType == 'SFthrust' or event.EventType == 'FBLTthrust' or event.EventType == "PSBIthrust": Throttlevector.append( math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) / (event.AvailableThrust * self.thruster_duty_cycle)) elif event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': Throttlevector.append(0.0) if firstpass: DataAxesLeft.plot(date_vector, Throttlevector, c='r', lw=2, ls='--', label='Throttle') else: DataAxesLeft.plot(date_vector, Throttlevector, c='r', lw=2, ls='--') #plot power if PlotOptions.PlotPower: Powervector = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': if event.AvailablePower > 0.0: Powervector.append(event.AvailablePower) else: Powervector.append(0.0) if firstpass: DataAxesLeft.plot(date_vector, Powervector, c='Navy', lw=2, ls='-', label='Power produced by spacecraft (kW)') else: DataAxesLeft.plot(date_vector, Powervector, c='Navy', lw=2, ls='-') #plot gamma if PlotOptions.PlotGamma: gammavector = [] for event in self.missionevents: if event.EventType == 'SFthrust' or event.EventType == 'FBLTthrust' or event.EventType == "PSBIthrust": gammavector.append( math.atan2(event.Thrust[1], event.Thrust[0]) * 180.0 / math.pi) elif event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': gammavector.append(0.0) if firstpass: DataAxesRight.plot(date_vector, gammavector, c='DarkGreen', lw=2, ls='--', label=r'$\gamma$ (radians)') else: DataAxesRight.plot(date_vector, gammavector, c='DarkGreen', lw=2, ls='--') #plot delta if PlotOptions.PlotDelta: deltavector = [] for event in self.missionevents: if event.EventType == 'SFthrust' or event.EventType == 'FBLTthrust' or event.EventType == "PSBIthrust": AppliedThrust = math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) deltavector.append( math.asin(event.Thrust[2] / AppliedThrust) * 180.0 / math.pi) elif event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': deltavector.append(0.0) if firstpass: DataAxesRight.plot(date_vector, deltavector, c='LightGreen', lw=2, ls='--', label=r'$\delta$ (radians)') else: DataAxesRight.plot(date_vector, deltavector, c='LightGreen', lw=2, ls='--') #plot central body to thrust vector angle if PlotOptions.PlotCB_thrust_angle: CBthrustvector = [] for event in self.missionevents: if event.EventType == 'SFthrust' or event.EventType == 'FBLTthrust' or event.EventType == "PSBIthrust": r = math.sqrt(event.SpacecraftState[0]**2 + event.SpacecraftState[1]**2 + event.SpacecraftState[2]**2) AppliedThrust = math.sqrt(event.Thrust[0]**2 + event.Thrust[1]**2 + event.Thrust[2]**2) rdotT = event.SpacecraftState[0] * event.Thrust[ 0] + event.SpacecraftState[1] * event.Thrust[ 1] + event.SpacecraftState[2] * event.Thrust[2] CBthrustvector.append( math.acos(rdotT / (r * AppliedThrust)) * 180.0 / math.pi) elif event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': CBthrustvector.append(0.0) if firstpass: DataAxesRight.plot(date_vector, CBthrustvector, c='Salmon', lw=2, ls='--', label='CB-thrust angle (radians)') else: DataAxesRight.plot(date_vector, CBthrustvector, c='Salmon', lw=2, ls='--') #plot mass if PlotOptions.PlotMass: mass = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': mass.append(event.Mass * 1.0e-3) if firstpass: DataAxesLeft.plot(date_vector, mass, c='DarkGrey', lw=2, ls='-', label='Mass (1000 kg)') else: DataAxesLeft.plot(date_vector, mass, c='DarkGrey', lw=2, ls='-') #plot number of active thrusters if PlotOptions.PlotNumberOfEngines: numberofengines = [] for event in self.missionevents: if event.EventType == 'SFthrust' or event.EventType == 'FBLTthrust' or event.EventType == "PSBIthrust": numberofengines.append(event.Number_of_Active_Engines) elif event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': numberofengines.append(0) if firstpass: DataAxesLeft.plot(date_vector, numberofengines, c='Orange', lw=2, ls='-', label='Number of active thrusters') else: DataAxesLeft.plot(date_vector, numberofengines, c='Orange', lw=2, ls='-') #plot power actively used by the thrusters if PlotOptions.PlotActivePower: activepowervector = [] for event in self.missionevents: if event.EventType == 'SFthrust' or event.EventType == 'FBLTthrust' or event.EventType == "PSBIthrust": activepowervector.append(event.ActivePower) elif event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': activepowervector.append(0.0) if firstpass: DataAxesLeft.plot( date_vector, activepowervector, c='Navy', lw=2, ls='--', label='Power used by the propulsion system (kW)') else: DataAxesLeft.plot(date_vector, activepowervector, c='Navy', lw=2, ls='--') #plot waste heat from the propulsion system if PlotOptions.PlotWasteHeat: WasteHeatvector = [] for event in self.missionevents: if event.EventType == 'SFthrust' or event.EventType == 'FBLTthrust' or event.EventType == "PSBIthrust": WasteHeatvector.append( (1 - event.AvailableThrust * event.Isp * 9.80665 / (2000 * event.ActivePower)) * event.ActivePower) elif event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': WasteHeatvector.append(0.0) if firstpass: DataAxesLeft.plot( date_vector, WasteHeatvector, c='Crimson', lw=2, ls='--', label='Waste heat from propulsion system (kW)') else: DataAxesLeft.plot(date_vector, WasteHeatvector, c='Crimson', lw=2, ls='--') #plot Earth distance in LU and SPE angle if PlotOptions.PlotEarthDistance or PlotOptions.PlotSunEarthSpacecraftAngle: if self.central_body.lower() != 'sun': print 'getting Earth distance and Sun-Spacecraft-Earth angle is only supported if the central body is the sun' else: import de423 from jplephem import Ephemeris eph = Ephemeris(de423) EarthDistanceVector = [] SunEarthSpacecraftAngle = [] for event in self.missionevents: if event.EventType != 'match_point' and event.EventType != 'upwr_flyby' and event.EventType != 'pwr_flyby': #get the position of the central body relative to the solar system barycenter cb_relative_to_solar_system_barycenter_in_ICRC = eph.position( self.central_body.lower(), event.JulianDate) #get the position of the Earth relative to the central body embarycenter_in_ICRC = eph.position( 'earthmoon', event.JulianDate) moonvector_in_ICRC = eph.position( 'moon', event.JulianDate) Earth_relative_to_solar_system_barycenter_in_ICRC = embarycenter_in_ICRC - moonvector_in_ICRC * eph.earth_share Earth_relative_to_cb_in_ICRC = Earth_relative_to_solar_system_barycenter_in_ICRC + cb_relative_to_solar_system_barycenter_in_ICRC #rotate the spacecraft state relative to the central body into the ICRF frame spacecraft_state_relative_to_central_body_in_ICRF = AstroFunctions.rotate_from_ecliptic_to_equatorial3( np.array(event.SpacecraftState[0:3])) #get the vector from the Earth to the Spacecraft Earth_Spacecraft_Vector = spacecraft_state_relative_to_central_body_in_ICRF - np.transpose( Earth_relative_to_cb_in_ICRC)[0] #return the magnitude of the Earth-centered position vector EarthDistanceVector.append( np.linalg.norm(Earth_Spacecraft_Vector) / self.LU) #if applicable, compute sun-spacecraft-Earth angle if PlotOptions.PlotSunEarthSpacecraftAngle: cosAngle = np.dot( -Earth_Spacecraft_Vector, -spacecraft_state_relative_to_central_body_in_ICRF ) / np.linalg.norm( spacecraft_state_relative_to_central_body_in_ICRF ) / np.linalg.norm(Earth_Spacecraft_Vector) SunEarthSpacecraftAngle.append( np.arccos(cosAngle) * 180.0 / math.pi) if PlotOptions.PlotEarthDistance: if firstpass: unitstring = 'LU' if self.central_body.lower() == 'sun' and math.fabs( self.LU - 149597870.69100001) < 1.0: unitstring = 'AU' labelstring = 'Distance from Earth (' + unitstring + ')' DataAxesLeft.plot(date_vector, EarthDistanceVector, c='g', lw=2, label=labelstring) else: DataAxesLeft.plot(date_vector, EarthDistanceVector, c='g', lw=2) if PlotOptions.PlotSunEarthSpacecraftAngle: if firstpass: DataAxesRight.plot(date_vector, SunEarthSpacecraftAngle, c='orangered', lw=2, ls='-.', label='Sun-Spacecraft-Earth Angle') else: DataAxesRight.plot(date_vector, SunEarthSpacecraftAngle, c='orangered', lw=2, ls='-.')
def setUp(self): import de421 self.e = Ephemeris(de421)
def find_residuals(check_index, decs, ras, JDs, r, r_dot): dec_res_total = 0 ra_res_total = 0 total_ra = 0 total_dec = 0 date = "2018-7-16 01:52" for i in range(len(decs)): #print str(i + 1) + "/" + str(len(decs)) k = 0.01720209895 time_difference = JDs[i] - JDs[check_index] tau = 0 d_tau = 0.001 * is_negative(time_difference) end_tau = time_difference * k #TEMP INTEGRATOR THINGY HERE (THE NEW ONE BRO) sim = rebound.Simulation() date = "2018-7-16 01:52" #TEST INFO# #SUN sim.add(m=1.0) #ASTEROID sim.add(m=0.0, x=r.x, y=r.y, z=r.z, vx=r_dot.x, vy=r_dot.y, vz=r_dot.z) #EARTH sim.add(m=1.0 / 330000.0, x=4.189675889417898E-01, y=-8.496104448760934E-01, z=-3.683119473905782E-01, vx=1.539665060981763E-02 / k, vy=6.454046892673179E-03 / k, vz=2.797224517462366E-03 / k) #sim.add('Earth') #JUPITER sim.add(m=1.0 / 1000.0, x=-3.213494013743870E+00, y=-4.009890793133180E+00, z=-1.640521133996669E+00, vx=5.974697377415830E-03 / k, vy=-3.756443410778172E-03 / k, vz=-1.755593829452442E-03 / k) #sim.add('Jupiter') #SATURN sim.add(m=1.0 / 3300.0, x=1.084878715668408E+00, y=-9.231862109791130E+00, z=-3.860012135382278E+00, vx=5.246951399009119E-03 / k, vy=6.191309101028240E-04, vz=3.018304002418789E-05 / k) #sim.add('Saturn') sim.move_to_com() ps = sim.particles sim.integrate(end_tau) r_now = vector(ps[1].x, ps[1].y, ps[1].z) AU = 149597870.7 # km/AU jd = JDs[i] eph = Ephemeris(de421) R_geocentric = get_earth_to_sun(JD) sun_to_asteroid = r_now earth_to_asteroid = norm( R_geocentric + sun_to_asteroid) # Gets unit vector from Earth to Asteroid RA, Dec = location_to_angles(earth_to_asteroid) RA_Residual = abs(ras[i] - RA) Dec_Residual = abs(decs[i] - Dec) ra_res_total += RA_Residual**2 dec_res_total += Dec_Residual**2 tau = 0 d_tau = 0.000001 k = 0.01720209895 mu = 1.0 sigma = sqrt(ra_res_total + dec_res_total) return sigma
def pertubation(t, orbit_element): ''' :param Orbit_Elements: 轨道六根数,单位为弧度 :param t: 时间 :return: 微分方程右边的表达式 ''' ''' d_earth_nonsphericfigure:地球非球型摄动影响 ''' t_start_jd = 2458454.0 R_earth = 6378 #km mu = 398600 #km^3/s^(-2) J2 = -1.08264 * 10**(-3) semi_major_axis = orbit_element[0] Eccentricity = orbit_element[1] Inclination = orbit_element[2] RAAN = orbit_element[3] Perigee = orbit_element[4] True_Anomaly = orbit_element[5] p = semi_major_axis**(1 - Eccentricity**2) n = sqrt(mu / (semi_major_axis)**3) d_RAAN_earth_nonsphericfigure = (-2 / 3) * ( R_earth / p)**2 * n * J2 * cos(Inclination) d_Perigee_earth_nonsphericfigure = -3 / 4 * (R_earth / p)**2 * n * J2 * ( 1 - 5 * (cos(Inclination)**2)) d_semi_major_axis_earth_nonsphericfigure = 0 d_Eccentricity_earth_nonsphericfigure = 0 d_Inclination_earth_nonsphericfigure = 0 d_Mean_anomaly_earth_nonsphericfigure = 0 ''' d_lunar_solar日,月引力摄动 ''' Sun_state = ephemeris('sun', t_start_jd + t / 3600 / 24) #太阳星历 barycenter_statement = ephemeris('earthmoon', t_start_jd + t / 3600 / 24) import de405 from jplephem import Ephemeris eph = Ephemeris(de405) Position_sun = Sun_state[0, :] Velocity_sun = Sun_state[1, :] Moon_state = ephemeris('moon', t_start_jd + t / 3600 / 24) #本身就是相对地球的 Position_moon = Moon_state[0, :] Velocity_moon = Moon_state[1, :] Earth_state = barycenter_statement - Moon_state * eph.earth_share Position_earth = Earth_state[0, :] Velocity_earth = Earth_state[1, :] # 太阳引力摄动 G = 6.67259 * 1e-11 #N·m²/kg² M_sun = 1.9885 * 1e30 #kg R_sun_earth = Position_sun - Position_earth #地心ICRF参考系下太阳的位置矢量 V_sun_earth = Velocity_sun - Velocity_earth #地心ICRF参考系下太阳的速度矢量 r_sun = np.sqrt(R_sun_earth[0]**2 + R_sun_earth[1]**2 + R_sun_earth[2]**2) K_sun = G * M_sun / (r_sun**3) #r_sun为日地距 #计算太阳在地心ICRF坐标系下的轨道根数 import RV_To_Orbit_Elements mu_sun_earth = 398600 + G * M_sun / (1e9) # km^3/s^2 Sun_Orbit_Elements_ECRF = RV_To_Orbit_Elements.rv_to_orbit_element( R_sun_earth, V_sun_earth, mu_sun_earth) Inclination_sun = Sun_Orbit_Elements_ECRF[2] RAAN_sun = Sun_Orbit_Elements_ECRF[3] Perigee_sun = Sun_Orbit_Elements_ECRF[4] True_anomaly_sun = Sun_Orbit_Elements_ECRF[5] u_sun = True_anomaly_sun + Perigee_sun #计算系数 A_sun = cos(RAAN - RAAN_sun) * cos(u_sun) + sin(RAAN - RAAN_sun) * sin( u_sun) * cos(Inclination_sun) B1_sun = cos(Inclination) B2_sun = B1_sun * (-sin(RAAN - RAAN_sun) * cos(u_sun) + sin(u_sun) * cos(Inclination_sun) * cos(RAAN - RAAN_sun)) B_sun = B2_sun + sin(Inclination) * sin(Inclination_sun) * sin(u_sun) C1_sun = sin(Inclination) C2_sun = C1_sun * (sin(RAAN - RAAN_sun) * cos(u_sun) - sin(u_sun) * cos(Inclination_sun) * cos(RAAN - RAAN_sun)) C_sun = C2_sun + cos(Inclination) * sin(Inclination_sun) * sin(u_sun) d_semi_major_axis_solar = 0 d_Eccentricity_solar = -(15 * K_sun / 2 / n) * Eccentricity * sqrt( 1 - Eccentricity**2) * (A_sun * B_sun * cos(2 * Perigee) - (1 / 2) * (A_sun**2 - B_sun**2) * sin(2 * Perigee)) d_Inclination_solar=3*K_sun*C_sun/4/n/sqrt(1-Eccentricity**2)*(A_sun*(2+3*Eccentricity**2+\ 5*Eccentricity**2*cos(2*Perigee))+5*(B_sun*Eccentricity**2)*sin(2*Perigee)) d_RAAN_solar = 3*K_sun*C_sun/4/n/sqrt(1-Eccentricity**2)/sin(Inclination)*(B_sun*(2+3*Eccentricity**2+\ 5*Eccentricity**2*cos(2*Perigee))+5*A_sun*Eccentricity**2*sin(2*Perigee)) d_Perigee_solar = 3*K_sun/2/n*sqrt(1-Eccentricity**2)*((5*A_sun*B_sun*sin(Perigee*2)+\ 1/2*(A_sun**2-B_sun**2)*cos(2*Perigee))-1+3/2*(A_sun**2+B_sun**2))\ +5*semi_major_axis/2/Eccentricity/r_sun*(1-5/4*(A_sun**2-B_sun**2))*(A_sun*cos(Perigee)\ +B_sun*sin(Perigee))-cos(Inclination)*d_RAAN_solar d_Mean_anomaly_solar = 0 # 月球引力摄动 M_moon = 7.349 * 1e22 #kg R_moon_earth = Position_moon #地心ICRF参考系下太阳的位置矢量 V_moon_earth = Velocity_moon #地心ICRF参考系下太阳的速度矢量 r_moon = np.sqrt(R_moon_earth.dot(R_moon_earth)) K_moon = G * M_moon / (r_moon**3) #r_moon为月地距 mu_moon_earth = 398600 + G * M_moon / (1e9) #计算月球在地心ICRF坐标系下的轨道根数 Moon_Orbit_Elements_ECRF = RV_To_Orbit_Elements.rv_to_orbit_element( R_moon_earth, V_moon_earth, mu_moon_earth) Inclination_moon = Moon_Orbit_Elements_ECRF[2] RAAN_moon = Moon_Orbit_Elements_ECRF[3] Perigee_moon = Moon_Orbit_Elements_ECRF[4] True_anomaly_moon = Moon_Orbit_Elements_ECRF[5] u_moon = True_anomaly_moon + Perigee_moon #计算系数 A_moon = cos(RAAN - RAAN_moon) * cos(u_moon) + sin(RAAN - RAAN_moon) * sin( u_moon) * cos(Inclination_moon) B1_moon = cos(Inclination) B2_moon = B1_moon * (-sin(RAAN - RAAN_moon) * cos(u_moon) + sin(u_moon) * cos(Inclination_moon) * cos(RAAN - RAAN_moon)) B_moon = B2_moon + sin(Inclination) * sin(Inclination_moon) * sin(u_moon) C1_moon = sin(Inclination) C2_moon = C1_moon * (sin(RAAN - RAAN_moon) * cos(u_moon) - sin(u_moon) * cos(Inclination_moon) * cos(RAAN - RAAN_moon)) C_moon = C2_moon + cos(Inclination) * sin(Inclination_moon) * sin(u_moon) d_semi_major_axis_lunar = 0 d_Eccentricity_lunar=-(15*K_moon/2/n)*Eccentricity*sqrt(1-Eccentricity**2)*\ (A_moon*B_moon*cos(2*Perigee)-(1/2)*(A_moon**2-B_moon**2)*sin(2*Perigee)) d_Inclination_lunar=3*K_moon*C_moon/4/n/sqrt(1-Eccentricity**2)*(A_moon*(2+3*Eccentricity**2+\ 5*Eccentricity**2*cos(2*Perigee))+5*B_moon*Eccentricity**2*sin(2*Perigee)) d_RAAN_lunar = 3*K_moon*C_moon/4/n/sqrt(1-Eccentricity**2)/sin(Inclination)*(B_moon*(2+3*Eccentricity**2+\ 5*Eccentricity**2*cos(2*Perigee))+5*A_moon*Eccentricity**2*sin(2*Perigee)) d_Perigee_lunar = 3*K_moon/2/n*sqrt(1-Eccentricity**2)*((5*A_moon*B_moon*sin(Perigee*2)+\ 1/2*(A_moon**2-B_moon**2)*cos(2*Perigee))-1+3/2*(A_moon**2+B_moon**2))\ +5*semi_major_axis/2/Eccentricity/r_moon*(1-5/4*(A_moon**2-B_moon**2))*(A_moon*cos(Perigee)\ +B_moon*sin(Perigee))-cos(Inclination)*d_RAAN_lunar d_Mean_anomaly_lunar = 0 d_semi_major_axis = d_semi_major_axis_earth_nonsphericfigure + d_semi_major_axis_lunar + d_semi_major_axis_solar d_Eccentricity = d_Eccentricity_earth_nonsphericfigure + d_Eccentricity_lunar + d_Eccentricity_solar d_Inclination = d_Inclination_earth_nonsphericfigure + d_Inclination_solar + d_Inclination_lunar d_RAAN = d_RAAN_earth_nonsphericfigure + d_Inclination_lunar + d_RAAN_solar d_Perigee = d_Perigee_earth_nonsphericfigure + d_Perigee_lunar + d_Perigee_solar d_Mean_anomaly = n semi_major_axis_earth_nonsphericfigure = 1 semi_major_axis_lunar_solar = 0 Eccentricity_earth_nonsphericfigure = 1 Eccentricity_lunar_solar = 0 Inclination_earth_nonsphericfigure = 1 Inclination_solar_solar = 0 RAAN_earth_nonsphericfigure = 1 RAAN_lunar_solar = 0 Perigee_earth_nonsphericfigure = 1 Perigee_lunar_solar = 0 return np.array([ d_semi_major_axis, d_Eccentricity, d_Inclination, d_RAAN, d_Perigee, d_Mean_anomaly ])
RA_measured = array([[20, 56, 08.762], [20, 59, 20.410], [21, 8, 43.156]]) Dec_measured = array([[16, 29, 32.52], [18, 14, 10.95], [22, 28, 36.27]]) t1 = JD[0] t2 = JD[1] t3 = JD[2] list_test = [JD[0], JD[2]] tau2 = 0 tau1 = k * (t1 - t2) tau3 = k * (t3 - t2) R = [] for i in JD: eph = Ephemeris(de421) barycenter = eph.position('earthmoon', i) moonvector = eph.position('moon', i) earth = barycenter - moonvector * eph.earth_share R0 = vector( earth ) / AU # This is the Sun to Earth center vector in Equatorial system R_geocentric = -1. * R0 R.append(array(R_geocentric)) print 'R_geocentric', R print def RAconverter(hrs, minutes, seconds): return (hrs / 24. + minutes / (24. * 60) + seconds / (24. * 3600)) * 360.
# import os from skyfield.api import * years = range(-9999, 9999, 10) north_pole = earth.topos('90 N', '0 W') print(north_pole) x, y, z = north_pole.gcrs(utc=(years, 1, 1)).position.km print(x,y,z) plot(x, y) exit() # from skyfield.api import * import de421 from jplephem import Ephemeris eph = Ephemeris(de421) # x, y, z = eph.position('saturn', 2456656.501) # x, y, z = eph.position('mars', 2456658.500000000); # x, y, z = eph.position('mercury', 2414992.5); x,y,z = eph.position('mercury', 2456876) - eph.position('jupiter', 2456876) print x,y,z for t in range (2456876,2456876+1000): mx,my,mz = eph.position('mercury', t) jx,jy,jz = eph.position('jupiter', t) eq = -0.0145987218963993*(jx-mx)-0.430326550289791*(jy-my)+0.902555226805917*(jz-mz) print "ALPHA",t,eq exit()