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)
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 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()
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 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 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 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 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 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 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 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 = [] 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 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)): 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
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
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 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')
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 ])
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 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='-.')