Example #1
0
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
Example #2
0
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()
Example #3
0
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()
Example #4
0
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
Example #5
0
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
Example #6
0
    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)
Example #7
0
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_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)
Example #9
0
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)
Example #10
0
    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')
Example #11
0
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
Example #12
0
    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 = '-.')
Example #13
0
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.
Example #14
0
    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='-.')
Example #15
0
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()

for t in range(1,3660):
    t0 = 2456658.500000000+t/10.
    x, y, z = eph.position('mercury', t0);
    print t0,z[0],"\n"
Example #16
0
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)