예제 #1
0
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
예제 #2
0
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 =
예제 #3
0
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
예제 #4
0
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')
예제 #5
0
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
예제 #6
0
 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
예제 #7
0
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()
예제 #8
0
    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
예제 #9
0
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')
예제 #10
0
 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)
예제 #11
0
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
예제 #12
0
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
예제 #13
0
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
예제 #14
0
def system_gravity(m1, m2, x):
    x = x.transpose()
    return (-vars.G*m1*m2/nt.norm(x)**3*x).transpose()
예제 #15
0
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()
예제 #16
0
        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)
예제 #17
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
예제 #18
0
    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')
예제 #19
0
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))
예제 #20
0
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
예제 #21
0
def gravity(m1, m2, x):
    return -vars.G*m1*m2/nt.norm(x)**3*x
예제 #22
0
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)