def marvelProbe(params, verbose = False, MC = False):
    '''
    main function for MARVEL probes.
    1) back-propagate probes for params.tback seconds
    2) split probe into N separate probes
    3) apply delta-V of params.DV to each probe in hard-coded directions
    4) forward propagate to entry interface
    5) call mainAD for each probe from entry interface to landing
    '''
    
    # get inertial cartesian state from given planet-relative spherical state
    params.x0, params.vInfvec_N = LLAEHV2RV(params.lat, params.lon,
                                            params.alt, params.efpaWR,
                                            params.hdaWR, params.vmagWR,
                                            params, params.tspan[0])
    params.v0 = Vinf2VN(params.x0, params.vInfvec_N, params, params.tspan[0])
    
    # propagate vehicle backwards in time by params.tback seconds
    yy0 = np.block([params.x0, params.v0])
    
    solBack = solve_ivp(lambda t, y: ODEs.TBP(t, y, params),
                        (params.tback, 0), yy0.flatten(), rtol = params.rtol,
                        atol = params.atol)
    
    xx0vecCenter = solBack.y[:,-1]
    x0vecCenter = xx0vecCenter[:3]
    v0vecCenter = xx0vecCenter[3:]
    
    # split probe into 4 separate probes
    rDir = x0vecCenter / np.linalg.norm(x0vecCenter)
    vDir = v0vecCenter / np.linalg.norm(v0vecCenter)
    hDir = np.cross(rDir, vDir)
    hDir = hDir / np.linalg.norm(hDir)
    
    thDir = np.cross(hDir, rDir)
    thDir = thDir / np.linalg.norm(thDir)
    
    phi = np.radians(0)
    eta = np.radians(0)
    
    aDir = np.cos(phi) * thDir + np.sin(phi) * hDir
    bDir = -aDir
    cDir = np.cos(eta) * hDir - np.sin(eta) * thDir
    dDir = -cDir
    
    v0vecDown = v0vecCenter + params.DVDown * aDir
    v0vecUp = v0vecCenter + params.DVUp * bDir
    
    v0vecLeft = v0vecCenter + params.DVLeft * cDir
    v0vecRight = v0vecCenter + params.DVRight * dDir
    
    
    xx0vecDown = np.hstack([x0vecCenter, v0vecDown])
    xx0vecUp = np.hstack([x0vecCenter, v0vecUp])
    xx0vecLeft = np.hstack([x0vecCenter, v0vecLeft])
    xx0vecRight = np.hstack([x0vecCenter, v0vecRight])
    
    # pdb.set_trace()
    
    # propagate each probe forward until atm interface
    eventEI = lambda t, y: ODEs.above_max_alt(t, y, params)
    eventEI.terminal = True
    
    paramsDown = copy.deepcopy(params)
    solDown = solve_ivp(lambda t, y: ODEs.TBP(t, y, params),
                        (0, 10 * params.tback), xx0vecDown, rtol = params.rtol,
                        atol = params.atol, events = (eventEI))
    paramsDown.x0 = solDown.y[:3,-1]
    paramsDown.v0 = solDown.y[3:,-1]
    paramsDown.inputType = 'inertial vectors'
    
    paramsUp = copy.deepcopy(params)
    solUp = solve_ivp(lambda t, y: ODEs.TBP(t, y, params),
                        (0, 10 * params.tback), xx0vecUp, rtol = params.rtol,
                        atol = params.atol, events = (eventEI))
    paramsUp.x0 = solUp.y[:3,-1]
    paramsUp.v0 = solUp.y[3:,-1]
    paramsUp.inputType = 'inertial vectors'
    
    paramsLeft = copy.deepcopy(params)
    solLeft = solve_ivp(lambda t, y: ODEs.TBP(t, y, params),
                        (0, 10 * params.tback), xx0vecLeft, rtol = params.rtol,
                        atol = params.atol, events = (eventEI))
    paramsLeft.x0 = solLeft.y[:3,-1]
    paramsLeft.v0 = solLeft.y[3:,-1]
    paramsLeft.inputType = 'inertial vectors'
    
    paramsRight = copy.deepcopy(params)
    solRight = solve_ivp(lambda t, y: ODEs.TBP(t, y, params),
                        (0, 10 * params.tback), xx0vecRight, rtol = params.rtol,
                        atol = params.atol, events = (eventEI))
    paramsRight.x0 = solRight.y[:3,-1]
    paramsRight.v0 = solRight.y[3:,-1]
    paramsRight.inputType = 'inertial vectors'
    
    
    # propagate all 4 probes to the surface
    outsDown = Outs()
    outsUp = Outs()
    outsLeft = Outs()
    outsRight = Outs()
    
    outsDown = mainAD(paramsDown, params.tspan, params.events, outsDown,
                      verbose = verbose)
    outsUp = mainAD(paramsUp, params.tspan, params.events, outsUp,
                    verbose = verbose)
    outsLeft = mainAD(paramsLeft, params.tspan, params.events, outsLeft,
                      verbose = verbose)
    outsRight = mainAD(paramsRight, params.tspan, params.events, outsRight,
                       verbose = verbose)
    
    
    # make sure that all probes enter atm at least 1 km away from orbiter
    dista = greatCircleDistDeg(params.lon, params.lat,
                               outsDown.lon0, outsDown.lat0, params)
    distb = greatCircleDistDeg(params.lon, params.lat,
                               outsUp.lon0, outsUp.lat0, params)
    distc = greatCircleDistDeg(params.lon, params.lat,
                               outsLeft.lon0, outsLeft.lat0, params)
    distd = greatCircleDistDeg(params.lon, params.lat,
                               outsRight.lon0, outsRight.lat0, params)
    
    if min(dista, distb, distc, distd) < 1:
        # sys.exit('a probe entered the atmosphere within {0:.3f} km of the'\
        #          ' orbtier'.format(min(dista, distb, distc, distd)))
        print('a probe entered the atmosphere within {0:.3f} km of the'\
                 ' orbtier'.format(min(dista, distb, distc, distd)))
    
    # find minimum distance between two landing locations
    distAB = greatCircleDistDeg(outsDown.lonf, outsDown.latf,
                                outsUp.lonf, outsUp.latf, params)
    distAC = greatCircleDistDeg(outsDown.lonf, outsDown.latf,
                                outsLeft.lonf, outsLeft.latf, params)
    distAD = greatCircleDistDeg(outsDown.lonf, outsDown.latf,
                                outsRight.lonf, outsRight.latf, params)
    distBC = greatCircleDistDeg(outsUp.lonf, outsUp.latf,
                                outsLeft.lonf, outsLeft.latf, params)
    distBD = greatCircleDistDeg(outsUp.lonf, outsUp.latf,
                                outsRight.lonf, outsRight.latf, params)
    distCD = greatCircleDistDeg(outsLeft.lonf, outsLeft.latf,
                                outsRight.lonf, outsRight.latf, params)
    minDist = min(distAB, distAC, distAD, distBC, distBD, distCD)
    maxDist = max(distAB, distAC, distAD, distBC, distBD, distCD)
    
    return outsDown, outsUp, outsLeft, outsRight, (minDist, maxDist)
event1 = lambda t, y: ODEs.below_min_alt(t, y, params)
event1.terminal = True
event2 = lambda t, y: ODEs.above_max_alt(t, y, params)
event2.terminal = True
event2.direction = 1
events = (event1, event2)
params.events = events

### INTEGRATION TOLERANCE
params.rtol = 1e-11
params.atol = 1e-11

outsCenter = Outs()

outsCenter = mainAD(params, params.tspan, params.events, outsCenter)


# =============================================================================
# Set up dispersion parameters
# =============================================================================
# Number of Monte Carlo trials
Nmc = 15

# Ballistic coefficient, U[0.95%, 1.05%]
BCMean = params.BC
BCLB = 0.95 * params.BC
BCRng = 0.1 * params.BC

# DV, U[90%, 110%]
DVMean = DVnom
Exemple #3
0
for i_trial in range(Nmc):
    # generate input realizations
    params.efpaWR = norm.rvs(size=1, loc=efpanom, scale=efpa_sig)[0]
    params.vmagWR = norm.rvs(size=1, loc=vmagnom, scale=vmag_sig)[0]
    params.CD = uniform.rvs(size=1, loc=CD_LB, scale=2 * (CD_UB - CDnom))[0]
    params.m = uniform.rvs(size=1, loc=m_LB, scale=2 * (m_UB - mnom))[0]
    params.BC = params.m / (params.CD * Anom)

    # get atmosphere table for this trial
    params.atmdat = np.array([h, densAll[:, i_trial]])
    params.atmdat = params.atmdat[:, params.atmdat[0, :].argsort()]

    # run sim
    print('\nTrial {}'.format(i_trial + 1))
    outs = Outs()
    outsList.append(mainAD(params, tspan, events, outs))
    paramsList.append(getQoIParams(params))

    # every 50 trials, save all results to a file
    if not i_trial % 50:

        ## Save results to a file
        np.savez(outname,
                 paramsList=paramsList,
                 outsList=outsList,
                 CD_LB=CD_LB,
                 CD_UB=CD_UB,
                 m_LB=m_LB,
                 m_UB=m_UB,
                 efpanom=efpanom,
                 efpa_sig=efpa_sig,
Exemple #4
0
params.hmax = params.p.halt + 1e-7 + 10

event1 = lambda t, y: ODEs.below_min_alt(t, y, params)
event1.terminal = True

event2 = lambda t, y: ODEs.above_max_alt(t, y, params)
event2.terminal = True

events = (event1, event2)

### SINGLE RUN
params.efpaWR = -6
params.BC = 50

outs = Outs()
outs = mainAD(params, tspan, events, outs)
print(outs.fpaf)
print(outs.engf)

### PLOTS
alt = np.linalg.norm(outs.rvec_N, axis=0) - params.p.rad  #/1e3
vmag = np.linalg.norm(outs.vvec_N, axis=0)

fig = plt.figure(1)
ax = fig.add_subplot(111)
ax.plot(vmag, alt)
ax.set_xlabel('Inertial velocity, km/s')
ax.set_ylabel('Altitude, km')
ax.grid()

fig = plt.figure(2)
event1 = lambda t, y: ODEs.below_min_alt(t, y, params)
event1.terminal = True

event2 = lambda t, y: ODEs.above_max_alt(t, y, params)
event2.terminal = True

events = (event1, event2)

### SINGLE RUN
params.efpaWR = -12
params.BC = 130

### SIMULATE ORBITER
outsOrbiter = Outs()
outsOrbiter = mainAD(params, tspan, events, outsOrbiter)
print('\nORBITER:')
print('Final energy: {:.3f} km^2/s^2'.format(outsOrbiter.engf))
print('Apoapsis altitude: {:.3f} km'.format(outsOrbiter.haf))
print('Bank angle set to {:.1f} deg\n'.format(params.bank))

### SIMULATE PROBE
params.LD = 0
params.BC = 35
outsProbe = Outs()
outsProbe = mainAD(params, tspan, events, outsProbe)
print('\nPROBE:')
print('Final energy: {:.3f} km^2/s^2'.format(outsProbe.engf))
print('Apoapsis altitude: {:.3f} km'.format(outsProbe.haf))

# =============================================================================