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)
def give_impulse(self): self.orbit = functions.orbit_impulse(self.orbit, [100, 0, 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
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
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)