def trajectory(masses, x, v, host, sat, target, sun, time, tol, itol = 100): theta_target = np.arctan2(x[:, target, 1], x[:,target,0]) theta_host = np.arctan2(x[:, host, 1], x[:,host,0]) theta_target = np.where(theta_target < 0, theta_target + 2*np.pi, theta_target) theta_host = np.where(theta_host < 0, theta_host + 2*np.pi, theta_host) r_target = nt.norm(x[:, target], ax = 1) r_host = nt.norm(x[:, host], ax = 1) launch_window = [] t_cept = [] for i in range(len(time)): r1 = r_host[i] t1 = theta_host[i] check = colinear(t1, theta_target, tol) # Check future values possibles = np.argwhere(check[i:] != 0) + i # Values where planets align through sun. for possible in possibles: r2 = r_target[possible] a = (r1 + r2)/2 p = kepler3(masses[sun], masses[sat], a) t_future = time[i] + p/2 i_future = np.argmin(np.abs(time-t_future)) if i_future <= len(time) and np.abs(i_future - possible) < itol: if nt.norm(x[i_future, host] - x[possible, host], ax = 1) < tol: #i_future == possible print('Found possible launch window at t =', time[i]) launch_window.append(time[i]) t_cept.append(time[i_future]) return launch_window, t_cept
def keplercheck(): #compare two areas one where close to aphelion, one where close to perihelion #INPUTS: positions_vect, velocities_vect, time_vect.. a = vars.a m_star = vars.m_star m = vars.m P = ot.kepler3(m_star, m, a) t = np.load('saved/saved_orbits/time_verif.npy') x = np.load('saved/saved_orbits/pos_verif.npy') v = np.load('saved/saved_orbits/vel_verif.npy') dA = np.zeros(len(x[0]))#, len(x[0][0])]) dt = t[1]-t[0] #print(dt) for n in range(int(len(x[0])) - 1): vel = v[2:, n + 1, :].transpose() #9999, 8, 2 pos = x[2:, n + 1, :].transpose() print('Planet %i:' %(n)) dist = nt.norm(pos) apoapsis = np.argmax(dist) periapsis = np.argmin(dist) buel_api = nt.norm(pos[:,apoapsis+1] - pos[:,apoapsis-1]) area_api = dist[apoapsis]*buel_api/2 area_api_v2 = 1/2*dist[apoapsis]**2*nt.angle_between(pos[:,apoapsis], pos[:,apoapsis+1]) buel_peri = nt.norm(pos[:,periapsis+1] - pos[:,periapsis-1]) area_peri = dist[periapsis]*buel_peri/2 area_peri_v2 = 1/2*dist[periapsis]**2*nt.angle_between(pos[:,periapsis], pos[:,periapsis+1]) print('Apoapsis - Periapsis =', area_api - area_peri) #larger numerical erros in v2 due to small angles i think print('Apoapsis / Periapsis =', area_api / area_peri) #larger numerical erros in v2 due to small angles i think print('Distance traveled apoapsis:', buel_api) print('Distance traveled periapsis:', buel_peri) print('Mean speed apoapsis:', buel_api/(2*dt)) print('Mean speed periapsis:', buel_peri/(2*dt)) plt.plot(t[2:], dist) print('') plt.show() #Keplers third law, comparison between versions P_k3 = np.sqrt(a**3) indeks = np.argmin(P_k3/P) comparison = P_k3/P/(P_k3[indeks]/P[indeks]) print(comparison) print(max(comparison-1)/max(comparison)*100,'%') print(apoapsis[0]) #measure area perihelion for i in num: rad = dist[i][apoapsis[i]] dx = nt.norm(x[i][apoapsis[i]+1]- x[i][apoapsis[i]]) dA[i] = rad*dx/2 print(dA[0]) for i in num: rad = dist[i][periapsis[i]] dx = abs(dist[i][periapsis[i]+1]- dist[i][periapsis[i]]) dA[i] = rad*dx/2 print(dA[0])#measure area, dA =
def get_dev(t_orient, optx, optv, x_sat, v_sat, nums, topt): # Find deviation from optimal orbit with optimal position optx, optimal velocity optv devx = np.zeros((nums-1)) devv = np.copy(devx) dv = np.zeros((nums-1, 2)) vec_between = np.copy(dv) for ii in range(nums-1): arg1 = np.argmin(np.abs(topt - t_orient[ii])) arg2 = np.argmin(np.abs(topt - t_orient[ii + 1])) devx[ii] = nt.norm(x_sat[ii]-optx[arg1]) devv[ii] = nt.norm(v_sat[ii]-optv[arg1]) dv[ii] = -v_sat[ii] + optv[arg1] vec_between[ii] = nt.unit_vector(-x_sat[ii] + optx[arg1]) return devx, devv, dv, vec_between
def Part9_Ex5(): c = 299792458 #METER/SEKUND G = 6.67e-11 #konstanti mass = 3.459198972171e23 #KILOGRAM planet_radius = 2678881.4788 #METER t1 = 14.6189759mostly ts1_t1 = 14.5934565 ts2_t1 = 14.5898827 t2 = 10247.9021048 #sek ts1_t2 = 10247.8821483 ts2_t2 = 10247.8863525 pos1_t1 = np.array([5396873, -4194131]) #METER pos2_t1 = np.array([6770895, -933788]) #METER pos1_t2 = np.array([-6586081, 1827708]) #METER pos2_t2 = np.array([-6617567, -1710199]) #METER radius1 = nt.norm(pos1_t1) radius2 = nt.norm(pos2_t1) radius = radius1/2 + radius2/2 vel = np.sqrt(G*mass/radius) #METER PER SEC print('r1', radius1) print('r2', radius2) print('vel', vel) beta = np.array([np.arctan2(pos1_t1[1], pos1_t1[0]) + 2*np.pi, np.arctan2(pos2_t1[1], pos2_t1[0]) + 2*np.pi, \ np.arctan2(pos1_t2[1], pos1_t2[0]), np.arctan2(pos2_t2[1], pos2_t2[0]) + 2*np.pi]) print('angle ships',beta) t = np.array([t1, t1, t2, t2]) t_sat = np.array([ts1_t1, ts2_t1, ts1_t2, ts2_t2]) distance = c * (t - t_sat) #calculated NOT using relativity t_sat_rel = np.sqrt(1-2*mass*G/c**2/planet_radius)/np.sqrt(1-2*mass*G/c**2/radius)/np.sqrt(1-vel**2/c**2)*t_sat print('KONST WELL', np.sqrt(1-2*mass*G/c**2/planet_radius)/np.sqrt(1-2*mass*G/c**2/radius)) print('KONST SPEC', 1/np.sqrt(1-vel**2/c**2)) distance = c * (t - t_sat_rel) #calculated using relativity #print(distance) alpha = np.arccos((radius**2 + planet_radius**2 - distance**2)/(2*radius*planet_radius)) print('angle diff',alpha) angles = alpha*np.array([-1,-1,1,1]) - beta*np.array([-1,-1,-1,-1]) print('ANGLES phone', angles) angle1 = angles[0]/2 + angles[1]/2 angle2 = angles[2]/2 + angles[3]/2 print(angle1, 'or', angle1*180/np.pi - 180) print(angle2, 'or', angle2*180/np.pi - 180) position1 = np.array([planet_radius * np.cos(angle1), planet_radius * np.sin(angle1)]) print(position1) position2 = np.array([planet_radius * np.cos(angle2), planet_radius * np.sin(angle2)]) print(position2) print(nt.norm(position2 - position1), 'meters difference')
def n_body_sat(xp, mass, time, dv, sx0, sv0, sm, opt_vel = None, opt_orb = None, t_opt = 0, opt = False, numboosts = 1000): def acc(r_sat, r): r_between = r_sat - r rr1 = nt.norm(r_between, ax = 1) acc = 0 for mm, rr, rb in zip(mass, rr1, r_between): acc1 = -vars.G*mm/rr**3*rb acc += acc1 return acc x_sat = np.zeros((len(time), 2)) v_sat = np.zeros((len(time), 2)) x_sat[0] = sx0 v_sat[0] = sv0 nextboost = np.argmin(np.abs(time-t_opt)) for k in range(len(time) -1): dt = time[k+1] - time[k] acc1 = acc(x_sat[k], xp[k]) x_sat[k+1] = x_sat[k] + v_sat[k]*dt + 0.5*acc1*dt**2 acc2 = acc(x_sat[k+1], xp[k+1]) if opt and time[k] > t_opt and k == nextboost: v_diff = opt_vel[k + 1] - v_sat[k] if nt.norm(v_diff) < 10: dv[k] = dv[k] + v_diff v_sat[k+1] = v_sat[k] + 0.5*(acc1 + acc2)*dt + dv[k] nextboost += int(len(time)/numboosts) else: v_sat[k+1] = v_sat[k] + 0.5*(acc1 + acc2)*dt + dv[k] return x_sat, v_sat, dv
def acc(r_sat, r): r_between = r_sat - r rr1 = nt.norm(r_between, ax = 1) acc = 0 for mm, rr, rb in zip(mass, rr1, r_between): acc1 = -vars.G*mm/rr**3*rb acc += acc1 return acc
def find_orbits(): # Third part of orbital simulation, in a centre of mass reference frames with more planets mask = np.arange(len(m)) # Selected planets mass = np.append(m_star, m[mask]) period = ot.kepler3(m_star, m, a)[0] orbits = 21 stepsperorbit = 10000 t1 = orbits*period steps = orbits*stepsperorbit time = np.linspace(0, t1, steps) body_x0 = np.array([[0],[0]]) # Sun x0 body_v0 = np.array([[0],[0]]) # Sun v0 _x0 = np.concatenate((body_x0, np.array([x0[mask], y0[mask]])), axis=1) _v0 = np.concatenate((body_v0, np.array([vx0[mask], vy0[mask]])), axis=1) _x0 = _x0.transpose(); _v0 = _v0.transpose() #xx, vv, cm, vcm = ot.n_body_setup(mass, time, steps, _x0, _v0, ref_frame = 'cm') # Find orbits for n-body system (much more fun) #for i in range(len(mass)): # plt.plot(xx[0,i], xx[1,i]) # Find two-body system for just star and planet 3 mask = [0, 3] mass2 = np.array([m_star, vars.m[2]]) period = ot.kepler3(m_star, vars.m, vars.a)[0] orbits = 31 stepsperorbit = 10000 t1 = orbits*period steps = orbits*stepsperorbit time = np.linspace(0, t1, steps) x02 = _x0[mask] v02 = _v0[mask] x2, v2, cm, vcm = ot.n_body_setup(mass2, time, steps, x02, v02, ref_frame = 'cm') # N body system, centre of mass two body :/ x2 = x2.transpose(); v2 = v2.transpose() r = nt.norm(x2[:, 0] - x2[:, 1], ax = 1) v = nt.norm(v2[:, 0] - v2[:, 1], ax = 1) total_energy = ot.energy_cm(m_star, vars.m[2], v, r) # Find total energy in cm system avg_en = np.sum(total_energy)/len(total_energy) # Deviation print('Average energy:', np.sum(total_energy)/len(total_energy)) print('Maximum deviation:', np.abs(np.min(total_energy)-np.max(total_energy))) for i in range(2): plt.plot(x2[:, i, 0], x2[:, i, 1], '--k', linewidth = 0.8) plt.title('Centre of Mass Reference Frame') plt.xlabel('x [AU]', size = 12); plt.ylabel('y [AU]', size = 12) plt.axis('equal') plt.show()
def find_launch_sequence(maxiter = 5): intercept = cept - t_launch_indx host = 1 time2 = full_time[t_launch_indx:] planet_x = xx[t_launch_indx:] planet_v = vv[t_launch_indx:] dvv = dv[t_launch_indx:] x0_sat = planet_x[0, host] + vars.radius[0]*1000/vars.AU_tall*nt.unit_vector(planet_v[0, host]) v0_sat = planet_v[0, host] xv = ot.vis_viva(mass[0], nt.norm(x0_sat), semimajor[-1]) deviation = np.pi/2-nt.angle_between(v0_sat, x0_sat) dvv[0] = nt.rotate(dvv[0], deviation) v00_sat = xv*nt.rotate(nt.unit_vector(v0_sat), deviation) acc_optimal = lambda r, t: ot.gravity(mass[0], m_sat, r)/m_sat opt_orb, opt_vel = ot.orbit(x0_sat, v00_sat, acc_optimal, time2) opt_vel = opt_vel.transpose() opt_orb = opt_orb.transpose() '' x_sat, v_sat, dv_used = ot.n_body_sat(planet_x, mass, time2, dvv, x0_sat, v0_sat, m_sat) print(v_sat) print('Closest approach:', min(nt.norm(planet_x[:, 2] - x_sat, ax = 1))) opt_dev = nt.norm(x_sat - opt_orb.transpose(), ax = 1) boost_thresh = ot.grav_influence(mass[0], mass[1], x_sat, 1) dist_to_host = nt.norm(planet_x[:, 1] - x_sat, ax = 1) boost_time = np.where(dist_to_host > boost_thresh)[0][0] print('Time of boost:', time2[boost_time]) x_sat, v_sat, dv_used = ot.n_body_sat(planet_x, mass, time2, dvv, x0_sat, v0_sat, m_sat, opt_vel, opt_orb, time2[boost_time], True) print('Closest approach:',min(nt.norm(planet_x[:, 2] - x_sat, ax = 1))) print('Optimal closest approach:', ot.grav_influence(mass[0], mass[2], x_sat)[intercept]) closest = np.argmin(nt.norm(planet_x[:,2]- x_sat, ax=1)) print('total dv:', np.sum(nt.norm(dv_used))) dv_used[closest-3000:] = dv_used[closest-3000:]*0 x_sat, v_sat, dv_used = ot.n_body_sat(planet_x, mass, time2, dv_used, x0_sat, v0_sat, m_sat, opt_vel, opt_orb, time2[boost_time], False) print('Closest approach:',min(nt.norm(planet_x[:, 2] - x_sat, ax = 1))) print('total dv:', np.sum(nt.norm(dv_used))) closest = np.argmin(nt.norm(planet_x[:,2]- x_sat, ax=1)) return x_sat, v_sat, dvv, opt_orb, closest, dv_used
def find_orbital_params(x_sat, x_planet, time, v_sat=0): r = nt.norm(x_planet - x_sat, ax=1) api = np.max(r) peri = np.min(r) a = (api + peri) / 2 print('Periapsis:', peri) print('Apoapsis:', api) print('Semimajor:', a) dt = time[1] - time[0] rad_unit_vec = (x_planet - x_sat) / nt.norm(x_planet - x_sat) #print(tan_unit_vec) b = np.sqrt(np.min(r) * np.max(r)) P = time[-1] - time[0] e = np.sqrt(1 - (b / a)**2) print('Period:', P) print('Period, Kepler 3:', ot.kepler3(vars.m[1], 0 * 60000 / vars.solar_mass, (api + peri) / 2)) print('Eccentricity:', e) print('Semiminor:', b) print('dt:', dt) print('\n')
def best_fit(self, ref, image): ''' Tries to find best fit for projection centred around angle phi. Assumes ref is a reference array corresponding to a 2 pi panorama of night sky. Assumes image is a part of that panorama, of same dimension as ref Returns best angle, found using least squares approach, in degrees :'( ''' width = image.shape[1] rads_per_pixel = self.fov_phi/width ref = np.concatenate((ref, ref[:, :width]), axis = 1) best = np.sum(nt.norm(ref[:, :width] - image)**2) best_col = 0 for col in range(ref.shape[1]- width): section = ref[:, col: col + width] distance = np.sum(nt.norm(section - image)**2) # Least squares if distance < best: best = distance best_col = col return np.degrees((best_col + width/2)*rads_per_pixel)
def circularize(m_senter, m_sat, x, v, desired_r): ''' m_senter is mass of center body in two body system m_sat is mass of body orbiting central body in an elliptical orbit x is the position of the orbiting body v is the velocity of the orbiting body desired_r is the radius of the desired circular orbit tol is the allowed deviation from the circular radius. ''' v_desired = vis_viva(m_senter, desired_r, desired_r) delta_v = 0 #foob dv = np.zeros(x.shape) apoapsis = np.argmax(nt.norm(x, ax = 1)) dv[apoapsis] = 0 #baz
def create_light_curve(pos, rp, rs): #position, time, radius planet, radius sun # Creates light curves for our planet x = pos[0] y = pos[1] area_planet = np.pi*rp**2 area = np.zeros(len(x)) n = np.linspace(0,len(x)-1, len(x), dtype=int) for x, y, n in zip(x, y, n): if y < 0: area[n] = 0 elif abs(x) >= rs+rp: area[n] = 0 elif abs(x) <= rs-rp: area[n] = area_planet elif nt.norm([x,rp]) > rs: if x < 0: #innenfor venstre c = np.sqrt(rs**2-((rs**2-rp**2+x**2)/(2*x))**2) #c = y i kryssningspunkt mellom sirklene areal = c*np.sqrt(rp**2-c**2) + rp**2*np.arcsin(c/rp) \ + c*np.sqrt(rs**2-c**2) + rs**2*np.arcsin(c/rs) + 2*c*x area[n] = areal else: #innenfor høyre c = np.sqrt(rs**2-((rs**2-rp**2+x**2)/(2*x))**2) #c = y i kryssningspunkt mellom sirklene areal = c*np.sqrt(rp**2-c**2) + rp**2*np.arcsin(c/rp) \ + c*np.sqrt(rs**2-c**2) + rs**2*np.arcsin(c/rs) - 2*c*x area[n] = areal else: #utenfor venstre if x < 0: c = np.sqrt(rs**2-((rs**2-rp**2+x**2)/(2*x))**2) #c = y i kryssningspunkt mellom sirklene areal_inv = +c*np.sqrt(rp**2-c**2) + rp**2*np.arcsin(c/rp) \ - c*np.sqrt(rs**2-c**2) - rs**2*np.arcsin(c/<<<<<<< HEADrs) - 2*c*x area[n] = area_planet - areal_inv else: #utenfor høyre c = np.sqrt(rs**2-((rs**2-rp**2+x**2)/(2*x))**2) #c = y i kryssningspunkt mellom sirklene areal_inv = c*np.sqrt(rp**2-c**2) + rp**2*np.arcsin(c/rp) \ - c*np.sqrt(rs**2-c**2) - rs**2*np.arcsin(c/rs) + 2*c*x area[n] = area_planet - areal_inv return area
def c2p_vel(pos_cart, vel_cart): #x, y, v_x, v_y polar = np.zeros(pos_cart.shape) polar[0] = (pos_cart[0]*vel_cart[0] + pos_cart[1]*vel_cart[1])/nt.norm(pos_cart) #numtools polar[1] = (pos_cart[0]*vel_cart[1] - vel_cart[0]*pos_cart[1])/(pos_cart[0]**2 + pos_cart[1]**2) return polar
def system_gravity(m1, m2, x): x = x.transpose() return (-vars.G*m1*m2/nt.norm(x)**3*x).transpose()
def launch_sat(): m_star = vars.m_star m_planets = vars.m a = vars.a radius = vars.radius * 1000 / vars.AU_tall # Planet radii given in AUs m_sat = vars.satellite / vars.solar_mass x0 = np.array([[x0, y0] for x0, y0 in zip(vars.x0, vars.y0)]) v0 = np.array([[vx0, vy0] for vx0, vy0 in zip(vars.vx0, vars.vy0)]) x0 = np.concatenate((np.zeros((1, 2)), x0)) # Set sun initial conditions v0 = np.concatenate((np.zeros((1, 2)), v0)) mass = np.append(m_star, m_planets) host = 1 target = 2 t0 = 0 t1 = 0.6 period = ot.kepler3(m_star, m_planets, a)[0] orbits = t1 / period stepsperorbit = 10000 steps = stepsperorbit * orbits print('Steps:', steps) time = np.linspace(t0, t1, steps) x, v = ot.patched_conic_orbits(time, mass, x0, v0) tol = 5e-5 t_launch_est, t_cept = find_launch_time(time, tol, x, v, mass, m_sat, target, host) t_launch = t_launch_est[0] t_intercept = t_cept[0] launch_indx = np.argmin(np.abs(t_launch - time)) intercept_indx = np.argmin((np.abs(t_intercept - time))) print('Launch window selected at t =', t_launch) t2 = time[launch_indx] time2 = np.linspace(t2, t1, steps) x0_sat = x[launch_indx, host] v0_sat = v[launch_indx, host] semimajor = (nt.norm(x0_sat) + nt.norm(x[intercept_indx, target])) / 2 x, v = ot.patched_conic_orbits(time2, mass, x[launch_indx], v[launch_indx]) # Find planetary orbits dv = np.zeros((len(time2), 2)) launch_indx = 0 intercept_indx = np.argmin(np.abs(t_intercept - time2)) dv_opt = ot.vis_viva(mass[0], nt.norm(x0_sat), semimajor) deviation = np.pi / 2 - nt.angle_between( v0_sat, x0_sat) # Angular deviation for Hohmann transfer print('Angular deviation for optimal orbit', deviation) v0_opt = dv_opt * nt.rotate(nt.unit_vector(v0_sat), deviation) acc = lambda r, t: ot.gravity(m_sat, m_star, r) / m_sat opt_orb, opt_vel = ot.orbit(x0_sat, v0_opt, acc, time2) # Optimal transfer orbit opt_orb = opt_orb.transpose() opt_vel = opt_vel.transpose() dvv = np.zeros((len(time2), 2)) v_escape = ot.vis_viva(m_planets[0], radius[0], 1e20) # Escape velocity print('Escape velocity', v_escape) dvv[0] = v_escape * nt.unit_vector(v0_sat) - v0_sat x0_sat = x0_sat + nt.unit_vector(v0_sat) * radius[0] x_sat, v_sat, dv_used = ot.n_body_sat(x, mass, time2, dvv, x0_sat, v0_sat, m_sat) print('Closest approach:', min(nt.norm(x[:, 2] - x_sat, ax=1))) opt_dev = nt.norm(x_sat - opt_orb, ax=1) boost_thresh = ot.grav_influence(m_star, m_planets[0], x_sat, 1) dist_to_host = nt.norm(x[:, 1] - x_sat, ax=1) print('Safe to boost for dist to host:', dist_to_host[0]) boost_time = np.where(dist_to_host > boost_thresh)[0][0] print('Time of boost:', time2[boost_time]) x_sat, v_sat, dv_used = ot.n_body_sat(x, mass, time2, dvv, x0_sat, v0_sat, m_sat, opt_vel, opt_orb, 0, True) closest = np.argmin(nt.norm(x[:, 2] - x_sat, ax=1)) print('Closest approach:', min(nt.norm(x[:, 2] - x_sat, ax=1))) print('Time of closest approach:', time2[closest]) print('Predicted time of intercept:', t_intercept) print('Total dv required:', np.sum(np.abs(dv_used))) plt.plot(x_sat[:, 0], x_sat[:, 1], '--k', opt_orb[:, 0], opt_orb[:, 1], '-.k', linewidth=0.8) plt.plot(x[:, 2, 0], x[:, 2, 1], 'k', x[:, 1, 0], x[:, 1, 1], 'b', linewidth=0.8) plt.xlabel('x [AU]', size=12) plt.ylabel('y [AU]', size=12) plt.legend([ 'Satellite Orbit', 'Optimal Orbit', 'Target Planet Orbit', 'Home Planet Orbit' ], frameon=False) plt.scatter(x0_sat[0], x0_sat[1], c='k') plt.scatter(x[intercept_indx, 2, 0], x[intercept_indx, 2, 1], c='k') plt.scatter(x_sat[intercept_indx, 0], x_sat[intercept_indx, 1], c='k') plt.scatter(x_sat[closest, 0], x_sat[closest, 1], c='k') plt.scatter(x[closest, 2, 0], x[closest, 2, 1], c='k') plt.axis('equal') plt.show()
tcount += dt if tcount > t_boost and not_launched: dt = dt/1000 print(dt) xx[0] = np.copy(xx[2]) + vars.radius[0]*1000/vars.AU_tall*nt.unit_vector(vv[2]) vv[0] = np.copy(vv[2]) + nt.unit_vector(vv[2])*dv_boost not_launched = False print('LAUNCHED!') elif not_launched: xx[0] = np.copy(xx[2]) + vars.radius[0]*1000/vars.AU_tall*nt.unit_vector([vv[2]]) vv[0] = np.copy(vv[2]) small = nt.norm(xx[0]- xx[3]) if small < closest: closest = small print('Closest Approach: ', closest) if count % 1 == 0: for xd, yd , planet in zip(x[:,0], x[:,1], fullmugg.planets): #pg.draw.circle(surf, (0,0,0), (int(0 + center) , int(0 + center)), 3) xd = xd - cm[0] - xx[indx, 0]*frameno yd = yd - cm[1] - xx[indx, 1]*frameno if planet.name == 'Matsat': col = (100, 190, 100) else: col = (0, 0, 0)
def c2p_pos(cart): #x, y polar = np.zeros(cart.shape) polar[0] = nt.norm(cart) #numtools polar[1] = np.arctan2(cart[1], cart[0]) return polar
dv3[0] = -v0_sat + vv[0,2] - ot.vis_viva(mass[2], nt.norm(x0_sat-xx[0,2]), nt.norm(x0_sat-xx[0,2]))*dir2 xss, v_sat, dv_used = ot.n_body_sat(xx, mass, time3, dv3, x0_sat, v0_sat, m_sat) plt.plot(xss[:,0] - xx[:, 2,0], xss[:,1]-xx[:, 2, 1], c = 'k') ''' intercept = cept - t_launch_indx host = 1 time2 = full_time[t_launch_indx:] planet_x = xx[t_launch_indx:] planet_v = vv[t_launch_indx:] dvv = dv[t_launch_indx:] x0_sat = planet_x[0, host] + vars.radius[0]*1000/vars.AU_tall*nt.unit_vector(planet_v[0, host]) v0_sat = planet_v[0, host] xv = ot.vis_viva(mass[0], nt.norm(x0_sat), semimajor[-1]) deviation = np.pi/2-nt.angle_between(v0_sat, x0_sat) dvv[0] = nt.rotate(dvv[0], deviation) v00_sat = xv*nt.rotate(nt.unit_vector(v0_sat), deviation) acc_optimal = lambda r, t: ot.gravity(mass[0], m_sat, r)/m_sat opt_orb, opt_vel = ot.orbit(x0_sat, v00_sat, acc_optimal, time2) opt_vel = opt_vel.transpose() opt_orb = opt_orb.transpose() plt.plot(opt_orb[:intercept,0], opt_orb[0:intercept,1], '--k') for i in range(1, 3): plt.plot(xx[:, i, 0], xx[:, i, 1], 'k', linewidth = 0.6) plt.axis('equal')
def grav_influence(m_star, m_planet, r_to_star, k = 10): return nt.norm(r_to_star, ax = 1)*np.sqrt(m_planet/(k*m_star))
def landing(pos, vel, boost_angle, boost, plot = False): #Where pos and vel is given relative to the planet, not relative to the sun #plt.figure() period = vars.period[1]*24*60*60 radius = vars.radius_normal_unit[1] print('RADIUS[1]', radius) A = vars.area_lander #cross sectional area A_parachute = 25 M_planet = vars.m_normal_unit[1] m = vars.mass_lander G = vars.G_SI polar_vec = np.array([0,1]) dt = 0.1 t = 0 count = 0 boost_time = 1000 parachute_time = 1001 angle1 = 0 boost_velocity = 0 time_force = np.linspace(0, 30000, 300001) force = np.zeros(300001) print('forceShapes', time_force.shape, force.shape) boosted = False parachuted = False angle_less = False #theta is not really theta, but the tangent given in meters print('NORM', nt.norm(pos)) while abs(boost_angle) > np.pi: if boost_angle > 0: boost_angle = boost_angle - 2*np.pi elif boost_angle < 0: boost_angle = boost_angle + 2*np.pi while nt.norm(pos) > radius: #while count < 240000: wel = p2c_vel(c2p_pos(pos), 2*np.pi/period * polar_vec) vel_drag = vel - wel rho = part6.density(nt.norm(pos)) acc = -1/2*rho*A*nt.norm(vel_drag)*vel_drag/m - (M_planet*G/(nt.norm(pos)**2))*nt.unit_vector(pos) vel = vel + acc*dt pos = pos + vel*dt t += dt force[count] = nt.norm(acc*m) count += 1 if np.arctan2(pos[1],pos[0]) >= boost_angle and angle_less: #a check that should trigger when the desired angle is reached, and not before this #without the 'and angle_less' it would not work because angles are stupid 0->2pi->0 if not boosted: if plot: plt.scatter(pos[0]/1000, pos[1]/1000, c = 'b') print('boosted at angle', np.arctan2(pos[1],pos[0])) print('boost angle is ', boost_angle) boosted = True boost_time = t print('boost_time', boost_time) angle1 = np.arctan2(pos[1],pos[0]) boost_velocity = -vel*(1-boost) vel = vel*boost elif np.arctan2(pos[1],pos[0]) <= boost_angle: angle_less = True if nt.norm(vel_drag) < 30 and not parachuted: #parachute will be launched when the drag velocity is below 30m/s #could have included a check to see if the new force will be above #some threshold, though this should not happen at 30m/s parachute_time = t parachuted = True print('paratime', parachute_time) A = A_parachute acc = -1/2*rho*A*nt.norm(vel_drag)*vel_drag/m - (M_planet*G/(nt.norm(pos)**2))*nt.unit_vector(pos) F = m*acc force[count] = nt.norm(acc*m) print('Force', nt.norm(F), 'N') if count % int(50) == 0 and plot: plt.scatter(pos[0]/1000, pos[1]/1000, 1, 'r') angle2 = np.arctan2(pos[1],pos[0]) if plot: print('time', t) plt.scatter(pos[0]/1000, pos[1]/1000, c = 'b') print('DRAG: You reached the surface with a velocity of %.3f m/s after %.2f seconds' %(nt.norm(vel_drag), (t-boost_time))) vel_drag_radial = nt.norm(vel_drag*nt.unit_vector(-pos)) vel_drag_tangential = nt.norm(vel_drag*nt.rotate(nt.unit_vector(-pos), np.pi/2)) print('DRAG: Radial velocity was %.3f m/s and tangential velocity was %.3f m/s' %(vel_drag_radial, vel_drag_tangential)) print('Angle', angle2-angle1) plt.axis('equal') plt.xlabel('X-position [km]') plt.ylabel('Y-position [km]') pi_vec = np.linspace(0, 2*np.pi, 1000) for theta in pi_vec: circle = p2c_pos(np.array([radius, theta])) #circle2 = circle * 1.27 plt.scatter(circle[0]/1000, circle[1]/1000, 0.1, 'k') #plt.scatter(circle2[0], circle2[1], 0.1, 'k') plt.show() #plt.plot(time_force, force, '-k') #plt.xlabel('Time [s]') #plt.ylabel('Force [N]') #plt.show() print('BOOST TIME ', boost_time) return angle2, angle2-angle1, parachute_time, boost_time, boost_velocity, t
def gravity(m1, m2, x): return -vars.G*m1*m2/nt.norm(x)**3*x
measured_position = p4.position_from_objects(indx, solar_system.analyse_distances(), x) measured_velocity = p4.velocity_from_stars(solar_system.measure_doppler_shifts()) solar_system.take_picture() find_orient = Image.open('find_orient.png') find_orient2 = np.array(find_orient) measured_angle = p4.find_angle(np.array(find_orient2)) solar_system.manual_orientation(measured_angle, measured_velocity, measured_position) x = x.transpose(); v = v.transpose() topt = time[launch_indx] t2 = time[launched_indx] time2 = np.linspace(t2, t1, 150000) # New time vector, for optimal orbit from launch to end, high res x0_sat = x[launch_indx, host] v0_sat = v[launch_indx, host] semimajor = (nt.norm(x0_sat) + nt.norm(x[intercept_indx, target]))/2 #x, v = ot.patched_conic_orbits(time2, mass, x[launched_indx], v[launched_indx]) #np.save('saved/saved_params/xx_sol4.npy', x) #np.save('saved/saved_params/vv_sol4.npy', v) x = np.load('saved/saved_params/xx_sol4.npy') v = np.load('saved/saved_params/vv_sol4.npy') dv = np.zeros((len(time2), 2)) launch_indx = 0 launched_indx = 0 intercept_indx = np.argmin(np.abs(t_intercept-time2)) dv_opt = ot.vis_viva(mass[0], nt.norm(x0_sat), semimajor) deviation = np.pi/2 - nt.angle_between(v0_sat, x0_sat) v0_opt = dv_opt*nt.rotate(nt.unit_vector(v0_sat), deviation)