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
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,
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)) # =============================================================================