예제 #1
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
예제 #2
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
예제 #3
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()
예제 #4
0
        for i in range(n):
            acc = lambda r: ot.system_acceleration(masses, r, i, n)
            x[i] = xx[i] + vv[i]*dt + 0.5*acc(xx)*dt**2
        for i in range(n):
            acc = lambda r: ot.system_acceleration(masses, r, i, n)
            v[i] = vv[i] + 0.5*(acc(xx)+ acc(x))*dt

        cm = ot.center_of_mass(masses, x)
        xx = x
        vv = v

        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)

예제 #5
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
예제 #6
0
    phase1 = np.linspace(0, t1, steps)
    phase2 = np.linspace(t_launch - launch_duration, t2 - (t2-t_launch)/steps2, steps2)
    phase3 = np.linspace(t2, t3, steps)
    full_time = np.concatenate((phase1, phase2, phase3))

    xx, vv = sol.find_two_body_orbits(full_time, mass, x0, v0)
    #np.save('saved/saved_params/xx_sol2.npy', xx)
    #np.save('saved/saved_params/vv_sol2.npy', vv)

    #xx = np.load('saved/saved_params/xx_sol2.npy')
    #vv = np.load('saved/saved_params/vv_sol2.npy')

    dv = np.zeros((len(full_time), 2))
    t_launch_indx = len(phase1)
    cept = np.argmin(np.abs(full_time - t_cept[-1]))
    dv[t_launch_indx] = dw[-1]*nt.unit_vector(vv[t_launch_indx, 1])
    print('Go for launch')
    tol2 = 1e-3
    dw, tw, t_cept, semimajor = ot.trajectory(m_t, xx, vv, 1, -1, 2, 0, full_time, False, tol2)

    import launch
    launch.test(testing = True)
    xx = xx.transpose()
    vv = vv.transpose()

    xx = xx.transpose()
    vv = vv.transpose()
    print(xx.shape)
    print(dw[-1], tw, t_cept[-1])
    print('Initial launch index:', t_launch_indx)
    t_launch_indx = np.argmin(abs(full_time - tw[-1]))
예제 #7
0
def launch(time_vector, planet_position, planet_velocity, t0, theta = 1/2*np.pi, testing = False):
    #print('angle = ', theta)
    #print('angle = ', theta * 180/np.pi)
    radius = vars.radius_normal_unit[0]
    planet_mass = vars.m_normal_unit[0]
    grav_const = vars.gravitational_constant
    satellite_mass = vars.satellite
    period = vars.period[0] #unit is 24h
    force_box = np.load('saved/engine/force_box.npy')
    fuel_consumed_box_per_sec = np.load('saved/engine/fuel_consumed_box_per_sec.npy')
    part_consumed_box = fuel_consumed_box_per_sec/vars.molecule_mass
    position = radius
    DDt = time_vector[1]- time_vector[0]
    indd = int(t0/DDt)
    home_planet_position = planet_position[:,1] - planet_position[:,0]
    home_planet_velocity = planet_velocity[:,1] - planet_velocity[:,0]

    x_interp = nt.interp_xin(time_vector, home_planet_position)
    v_interp = nt.interp_xin(time_vector, home_planet_velocity)
    planet_position_t0 = np.array([x_interp[0](t0), x_interp[1](t0)])
    planet_velocity_t0 = np.array([v_interp[0](t0), v_interp[1](t0)])

    #print(planet_position_t0)
    #planet_position_t0 = np.array([home_planet_position[0,indd], home_planet_position[1,indd]])
    #planet_velocity_t0 = np.array([home_planet_velocity[0,indd], home_planet_velocity[1,indd]])
    #print(planet_position_t0)

    force = 35000e3 #input? kraft for hele raketten
    fuel_mass = 3000e3-satellite_mass #input? total fuelmasse for raketten
    boxes = force/force_box #antall bokser regnes utifra ønsket kraft
    fuel_consumption = boxes * fuel_consumed_box_per_sec #drivstofforbruk regnes ut for samlet motor
    mass = satellite_mass + fuel_mass
    initial_mass = mass
    initial_fuel_mass = fuel_mass
    #print('PARTICLES PER BOX PER SEC', part_consumed_box)
    #print('FUEL CONSUMED PER SEC', fuel_consumption)
    #print('BOXES', boxes)
    dt = 0.01
    t = t0*vars.year
    escape_velocity = (2*grav_const*planet_mass/position)**0.5
    velocity = 0; count = 0; has_fuel = 1
    tangential_velocity = 2*np.pi*radius/(period*24*60*60)
    while (velocity**2 + tangential_velocity**2)**(1/2) < escape_velocity: #1Dimensional
        acceleration = force/mass*has_fuel - grav_const*planet_mass/(position**2)
        velocity = velocity + acceleration*dt
        position = position + velocity*dt
        mass = mass - fuel_consumption*dt
        fuel_mass = fuel_mass - fuel_consumption*dt
        escape_velocity = (2*grav_const*planet_mass/position)**0.5
        if fuel_mass < 0:
            has_fuel = 0
            print('NO ORBIT')
            break
        t = t + dt
        count += 1
        '''
    print('\n\n')
    print('Velocity in planet reference frame', velocity)
    print('Duration', t)
    print('Fuel percentage', fuel_mass / initial_fuel_mass*100)
    print('Initial Fuel', initial_fuel_mass)
    print('Fuel', fuel_mass)
    print('height', position-radius)
    print('\n\n')
    '''
    tangential_velocity = tangential_velocity/vars.AU_tall*vars.year
    position = position/vars.AU_tall
    velocity = velocity/vars.AU_tall*vars.year
    t_AU = t/vars.year
    planet_position_t1 = np.array([x_interp[0](t_AU), x_interp[1](t_AU)])
    planet_velocity_t1 = np.array([v_interp[0](t_AU), v_interp[1](t_AU)])
    unitvector = nt.unit_vector(planet_position_t1)
    position_before_rotation = position * unitvector + nt.rotate(unitvector, np.pi/2) * (t_AU - t0) * tangential_velocity #radiallyish outwards from sun/cm
    velocity_before_rotation = velocity * unitvector + nt.rotate(unitvector, np.pi/2) * tangential_velocity
    position_after_rotation = nt.rotate(position_before_rotation, theta) #returns array with [x, y]
    velocity_after_rotation = nt.rotate(velocity_before_rotation, theta)
    final_position = planet_position_t1 + position_after_rotation
    final_velocity = planet_velocity_t1 + velocity_after_rotation
    phi = nt.angle_between(planet_velocity_t1, velocity_after_rotation)
    print('PHI', phi)
    print('THETA', theta)
    print('Duration:', t-t0*vars.year)
    if testing == True:
        vars.solar_system.engine_settings(force_box, boxes, part_consumed_box, initial_fuel_mass, \
        t-t0*vars.year, planet_position_t0 + nt.rotate(vars.radius_AU[0]*unitvector, theta), t0)
        vars.solar_system.mass_needed_launch(final_position, test = False)

    launch_pos = planet_position_t0 + nt.rotate(vars.radius_AU[0]*unitvector, theta)
    #new_mass, dvv = boost(force, fuel_consumption, mass, satellite_mass, 1000000, 0.00001)
    #print('DELTA V', dvv*vars.year/vars.AU_tall)
    #print('MASS', new_mass)
    return t_AU, final_position, final_velocity, mass/vars.solmasse, fuel_mass/vars.solmasse, phi, launch_pos
예제 #8
0
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)

acc = lambda r, t: ot.gravity(m_sat, m_star, r)/m_sat
t_optvec = np.linspace(topt, t2, 1000)
#a, b = ot.orbit(x0_sat, v0_opt, acc, t_optvec) # This only makes sure that the optimal orbit and the launch with mcast actually align.
#a = a.transpose(); b = b.transpose()
#opt_orb, opt_vel = ot.orbit(a[-1], b[-1], acc, time2) # Calculate optimal orbit
#np.save('saved/saved_params/xopt1.npy', opt_orb)
#np.save('saved/saved_params/vopt1.npy', opt_vel)
opt_orb = np.load('saved/saved_params/xopt1.npy')
opt_vel = np.load('saved/saved_params/vopt1.npy')
opt_orb = opt_orb.transpose()
opt_vel = opt_vel.transpose()


min_dist_res() # Minimum resolution distance