예제 #1
0
    def __init__(self, projectile, debris):
        self.projectile = projectile
        self.debris = debris

        self.debris.orbit = functions.orbit_impulse(
            debris.orbit, functions.velocity_change(projectile, debris))

        print(self.debris.orbit.r_p - 6371 * u.km)
예제 #2
0
    def give_impulse(self):

        self.orbit = functions.orbit_impulse(self.orbit, [100, 0, 0])
예제 #3
0
def heatmap_debris_net():
    earth_radius = 6371 * u.km
    #Create an orbit object, which a debris is.
    r = [-6045, -3490, 0]
    v = [-3457, 6618, 0]
    rtest, vtest = functions.get_random_ellipse_orbit()
    ss_orig = Orbit.from_vectors(Earth, r * u.km, v * u.m / u.s)

    #Generate a piece of debris to test on
    debris_orig = Classes.debris(0, 0, [0, 0], "Images/debris.png",
                                 [0, 705 * 10**3, 1])

    debris_orig.orbit = ss_orig

    original_periapsis = ((debris_orig.orbit.r_p - earth_radius).value)

    myData = []

    ylabels = []
    xlabels = []

    #The weight here is in grams
    for weight in range(10, 100, 2):

        print(weight)

        dataLine = []

        ylabels.append(weight)

        #We test velocities in the range of -1.5 -> 10 km/s
        for velocity in range(-5000, 5000, 100):
            xlabels.append(velocity)

            #Create a net
            pos = functions.orbit_to_position(debris_orig.orbit)

            #We want to hit it straight on, so we take the inverse direction
            vector = functions.get_vector_orbit(debris_orig.orbit) * (-1)

            #Normalize vector so we can multiply by the velocity
            vector = vector / (np.sqrt(vector[0]**2 + vector[1]**2))
            vector *= (velocity * u.m / u.s)

            net = Classes.projectile(1,
                                     pos[0],
                                     pos[1],
                                     vector, [0, 0, 0, 0, 0],
                                     mass=weight * u.g)
            vectorx, vectory = functions.velocity_change(net, debris_orig)

            #Set the vector into an array. We make sure they have the same units.
            vector_change = [vectorx.value,
                             vectory.to(vectorx.unit).value, 0] * vectorx.unit

            #Apply impulse
            new_orbit = functions.orbit_impulse(debris_orig.orbit,
                                                vector_change)

            #Save distance
            dataLine.append((new_orbit.r_p - earth_radius).value)

        myData.append(dataLine)

    ax = sns.heatmap(
        myData,
        linewidth=0,
        cmap="RdYlGn_r",
        cbar_kws={'label': 'Distance to periapsis minus radius of earth [km]'})

    xticks = ax.get_xticks()

    xlabels2 = ax.get_xticklabels()

    for i, value in enumerate(xticks):
        #divide by 1000 to get in km
        xlabels2[i] = str(round(float(xlabels[int(value)] / 1000), 1))
    ax.set_xticklabels(xlabels2)

    yticks = ax.get_yticks()

    ylabels2 = ax.get_yticklabels()

    for i, value in enumerate(yticks):
        ylabels2[i] = str(round(float(ylabels[int(value)]), 1))
    ax.set_yticklabels(ylabels2)

    ax.set_xlabel("Velocity of projectile [km/s]")
    ax.set_ylabel("Weight of projectile [g]")

    for tick in ax.get_xticklabels():
        tick.set_rotation(45)

    for tick in ax.get_yticklabels():
        tick.set_rotation(0)

    plt2.show()

    True
예제 #4
0
def min_distance(ss_orig):
    #We find the angle to the debris

    pos = functions.orbit_to_position(ss_orig)
    first_angle = functions.vec_to_angle_2d(pos[0], pos[1])

    #Reset best periapsis:
    best_periapsis = 10000000 * u.km

    #We try different angles but always with the same magnitude
    #The angle is relative to the orbit.
    #This means that 0 degrees is a head on collision
    #90 degrees is a collision so that it will line up towards earth
    #180 degrees is a collision from behind, which is hard to accomplish.

    #We apply gradient descent to this.
    #for angle in range(-180,180,1):

    #	orbit_vector = functions.get_vector_orbit(ss_orig)
    #	new_angle = functions.vec_to_angle_2d(orbit_vector[0].value,orbit_vector[1].value)
    #	new_angle = new_angle -180 + angle

    #	#The angle is normalized, meaning it will have the same length no matter what.
    #	x,y = functions.angle_to_vec_2d(new_angle)

    #	ss = functions.orbit_impulse(ss_orig,[x*10,y*10,0])

    #	#The periapsis tells us the closest point to earth.
    #	periapsis_radius = ss.r_p

    #	if periapsis_radius < best_periapsis:
    #		best_periapsis = periapsis_radius
    #		best_x = x
    #		best_y = y
    #		best_angle = angle
    #	#If this is within the karman line, the debris will be destroyed
    #	#print(periapsis_radius - earth_radius* u.km)

    current_periapsis = 10000000 * u.km
    last_periapsis = 1 * u.km
    angle = -179
    change = 40
    swapped_last = False
    direction = 1
    #While the change is larger than 1 meter

    iterations = 0

    while abs(last_periapsis - current_periapsis) > 1 * u.m:
        iterations += 1
        angle += change * direction

        last_periapsis = current_periapsis
        orbit_vector = functions.get_vector_orbit(ss_orig)
        new_angle = functions.vec_to_angle_2d(orbit_vector[0].value,
                                              orbit_vector[1].value)
        new_angle = new_angle - 180 + angle

        #The angle is normalized, meaning it will have the same length no matter what.
        x, y = functions.angle_to_vec_2d(new_angle)
        ss = functions.orbit_impulse(ss_orig, [x * 10, y * 10, 0])

        #The periapsis tells us the closest point to earth.
        current_periapsis = ss.r_p

        #The bad case
        if current_periapsis > last_periapsis:
            #We move in the other direction
            direction *= -1

            #If we did not change direction last time, we half the distance.
            if not swapped_last:
                change /= 2
            last_periapsis = 0 * u.km
            swapped_last = True
        else:
            swapped_last = False

    print("Iterations:")
    print(iterations)
    return current_periapsis, angle
예제 #5
0
def heatmap_orbit(ss_orig, xticks, yticks):
    ss_orig = ss_orig.propagate(0.001 * u.s)
    earth_radius = 6371  #km

    best_i = 0
    best_j = 0
    best_angle = 0
    best_periapsis = 100000 * u.km

    superiour_periapsis = best_periapsis
    best_ss = ss_orig

    op = OrbitPlotter()

    #Plot original orbit
    #op.plot(ss,label = "Original orbit")
    #plt.show()

    period = ss_orig.state.period

    myData = []

    top_line = []

    original_distance = ss_orig.r_p.value - earth_radius

    top_line.append(ss_orig.r_p)

    angle_myData = []

    for time in time_range(period, yticks):
        row = []

        ss_prop = ss_orig.propagate(time)

        #We find the angle to the debris

        pos = functions.orbit_to_position(ss_prop)
        first_angle = functions.vec_to_angle_2d(pos[0], pos[1])

        angle_myData.append(first_angle)

        #Reset best periapsis:
        best_periapsis = 10000000 * u.km

        #We try different angles but always with the same magnitude
        #The angle is relative to the orbit.
        #This means that 0 degrees is a head on collision
        #90 degrees is a collision so that it will line up towards earth
        #180 degrees is a collision from behind, which is hard to accomplish.
        xlabels = []
        for angle in range(-180, 180, int(360 / yticks)):
            xlabels.append(angle)

            orbit_vector = functions.get_vector_orbit(ss_prop)

            new_angle = functions.vec_to_angle_2d(orbit_vector[0].value,
                                                  orbit_vector[1].value)

            new_angle = new_angle - 180 + angle

            #The angle is normalized, meaning it will have the same length no matter what.
            x, y = functions.angle_to_vec_2d(new_angle)

            ss = functions.orbit_impulse(ss_prop,
                                         [x * 10, y * 10, 0] * u.m / u.s)

            #The periapsis tells us the closest point to earth.
            periapsis_radius = ss.r_p

            #We insert the radius
            row.append(periapsis_radius.value - earth_radius)

            if periapsis_radius < best_periapsis:
                best_periapsis = periapsis_radius
                best_x = x
                best_y = y
                best_angle = angle
            #If this is within the karman line, the debris will be destroyed
            #print(periapsis_radius - earth_radius* u.km)

        print()
        x = best_x
        y = best_y
        print(x)
        print(y)
        print(best_angle)

        ss = functions.orbit_impulse(ss_prop, [x * 10, y * 10, 0] * u.m / u.s)

        #The periapsis tells us the closest point to earth.
        periapsis_radius = ss.r_p

        if periapsis_radius < superiour_periapsis:
            superiour_periapsis = periapsis_radius
            best_ss = ss

        #If this is within the karman line, the debris will be destroyed
        print(periapsis_radius - earth_radius * u.km)

        #Plot the best result
        label = "angle: {}, length: {:4.4f}".format(
            best_angle, periapsis_radius - earth_radius * u.km)
        op.plot(ss, label=label)

        #Save the row into the data.
        myData.append(row)

    op2 = OrbitPlotter()

    pos = functions.orbit_to_position(best_ss)
    first_angle = functions.vec_to_angle_2d(pos[0], pos[1])
    print(first_angle)
    print(best_ss.r_p.value - earth_radius)

    op2.plot(ss_orig, label="original")
    op2.plot(best_ss, label="Best outcome")

    plt.show()

    #Sort myData:
    new_data = [x for _, x in sorted(zip(angle_myData, myData))]

    ylabels = sorted(angle_myData)

    ax = sns.heatmap(
        new_data,
        linewidth=0,
        cmap="RdYlGn_r",
        center=original_distance,
        cbar_kws={'label': 'Distance to periapsis minus radius of earth [km]'})

    xticks = ax.get_xticks()

    xlabels2 = ax.get_xticklabels()

    for i, value in enumerate(xticks):
        xlabels2[i] = str(round(float(xlabels[int(value)]), 1))
    ax.set_xticklabels(xlabels2)

    yticks = ax.get_yticks()

    ylabels2 = ax.get_yticklabels()

    for i, value in enumerate(yticks):
        ylabels2[i] = str(round(float(ylabels[int(value)]), 1))
    ax.set_yticklabels(ylabels2)

    ax.set_xlabel("Angle of impact [Degrees]")
    ax.set_ylabel("Angle of debris [Degrees]")

    for tick in ax.get_xticklabels():
        tick.set_rotation(45)

    for tick in ax.get_yticklabels():
        tick.set_rotation(0)

    plt2.show()

    myFile = open('saved_values.csv', 'w')

    with myFile:
        writer = csv.writer(myFile)
        writer.writerows(myData)