def detect_drone_click(self, position): """ Handles drones selection in the simulation. """ click_coords_to_map = (self.environment.width / config.DRAW_SIZE * position[0], self.environment.height / config.DRAW_SIZE * (config.DRAW_SIZE - position[1])) entities_distance = [ euclidean_distance(drone.coords, click_coords_to_map) for drone in self.environment.drones ] clicked_drone = self.environment.drones[np.argmin( entities_distance)] # potentially clicked drone TOLERATED_CLICK_DISTANCE = 40 closest_drone_coords = clicked_drone.coords dron_coords_to_screen = (closest_drone_coords[0] * config.DRAW_SIZE / self.environment.width, config.DRAW_SIZE - (closest_drone_coords[1] * config.DRAW_SIZE / self.environment.width)) if euclidean_distance(dron_coords_to_screen, position) < TOLERATED_CLICK_DISTANCE: # DRONE WAS CLICKED HANDLE NOW self.on_drone_click(clicked_drone)
def relay_selection(self, opt_neighbors): """ arg min score -> geographical approach, take the drone closest to the depot """ best_drone_distance_from_depot = util.euclidean_distance( self.simulator.depot.coords, self.drone.coords) best_drone = None for hpk, drone_istance in opt_neighbors: exp_position = self.__estimated_neighbor_drone_position(hpk) exp_distance = util.euclidean_distance(exp_position, self.simulator.depot.coords) if exp_distance < best_drone_distance_from_depot: best_drone_distance_from_depot = exp_distance best_drone = drone_istance return best_drone
def __move_to_mission(self, time): """ When invoked the drone moves on the map. TODO: Add comments and clean. time -> time_step_duration (how much time between two simulation frame) """ if self.current_waypoint >= len(self.path) - 1: self.current_waypoint = -1 p0 = self.coords if self.come_back_to_mission: # after move p1 = self.last_mission_coords else: p1 = self.path[self.current_waypoint + 1] all_distance = utilities.euclidean_distance(p0, p1) distance = time * self.speed if all_distance == 0 or distance == 0: self.__update_position(p1) return t = distance / all_distance if t >= 1: self.__update_position(p1) elif t <= 0: print("Error move drone, ratio < 0") exit(1) else: self.coords = (((1 - t) * p0[0] + t * p1[0]), ((1 - t) * p0[1] + t * p1[1]))
def run_medium(self, current_ts): to_drop_indices = [] original_self_packets = self.packets[:] self.packets = [] for i in range(len(original_self_packets)): packet, src_drone, dst_drone, to_send_ts = original_self_packets[i] if to_send_ts == current_ts: # time to send this packet to_drop_indices.append(i) if src_drone.identifier != dst_drone.identifier: drones_distance = util.euclidean_distance( src_drone.coords, dst_drone.coords) if drones_distance <= min(src_drone.communication_range, dst_drone.communication_range): if dst_drone.routing_algorithm.channel_success( drones_distance): dst_drone.routing_algorithm.drone_reception( src_drone, packet, current_ts) # reception of a packet original_self_packets = [ original_self_packets[i] for i in range(len(original_self_packets)) if i not in to_drop_indices ] self.packets = original_self_packets + self.packets
def __set_simulation(self): """ the method creates all the uav entities """ self.__set_random_generators() self.path_manager = utilities.PathManager(config.PATH_FROM_JSON, config.JSONS_PATH_PREFIX, self.seed) self.environment = Environment(self.env_width, self.env_height, self) self.depot = Depot(self.depot_coordinates, self.depot_com_range, self) self.drones = [] # drone 0 is the first for i in range(self.n_drones): self.drones.append( Drone(i, self.path_manager.path(i, self), self.depot, self)) self.environment.add_drones(self.drones) self.environment.add_depot(self.depot) # Set the maximum distance between the drones and the depot self.max_dist_drone_depot = utilities.euclidean_distance( self.depot.coords, (self.env_width, self.env_height)) if self.show_plot or config.SAVE_PLOT: self.draw_manager = pp_draw.PathPlanningDrawer(self.environment, self, borders=True)
def relay_selection(self, opt_neighbors): """ This routing is going to select as relay the next drone which is closest to me. :param opt_neighbors: list [(hello_packet, drone_instance), (hello....)] :return: drone_instance of the next relay """ best_drone_distance_from_me = np.inf best_drone = None for hpk, drone_istance in opt_neighbors: time_step_creation = hpk.time_step_creation cur_pos = hpk.cur_pos speed = hpk.speed next_target = hpk.next_target distance_for_me = utilities.euclidean_distance(cur_pos, self.drone.coords) if distance_for_me < best_drone_distance_from_me: best_drone_distance_from_me = distance_for_me best_drone = drone_istance return best_drone
def next_move_to_mission_point(self): """ get the next future position of the drones, according the mission """ current_waypoint = self.current_waypoint if current_waypoint >= len(self.path) - 1: current_waypoint = -1 p0 = self.coords p1 = self.path[current_waypoint + 1] all_distance = utilities.euclidean_distance(p0, p1) distance = self.simulator.time_step_duration * self.speed if all_distance == 0 or distance == 0: return self.path[current_waypoint] t = distance / all_distance if t >= 1: return self.path[current_waypoint] elif t <= 0: print("Error move drone, ratio < 0") exit(1) else: return (((1 - t) * p0[0] + t * p1[0]), ((1 - t) * p0[1] + t * p1[1]))
def __move_to_depot(self, time): """ When invoked the drone moves to the depot. TODO: Add comments and clean. time -> time_step_duration (how much time between two simulation frame) """ p0 = self.coords p1 = self.depot.coords all_distance = utilities.euclidean_distance(p0, p1) distance = time * self.speed if all_distance == 0: self.move_routing = False return t = distance / all_distance if t >= 1: self.coords = p1 # with the next step you would surpass the target elif t <= 0: print("Error routing move drone, ratio < 0") exit(1) else: self.coords = (((1 - t) * p0[0] + t * p1[0]), ((1 - t) * p0[1] + t * p1[1]))
def geo_neighborhood(self, drones, no_error=False): """ returns the list all the Drones that are in self.drone neighbourhood (no matter the distance to depot), in all direction in its transmission range, paired with their distance from self.drone """ closest_drones = [ ] # list of this drone's neighbours and their distance from self.drone: (drone, distance) for other_drone in drones: if self.drone.identifier != other_drone.identifier: # not the same drone drones_distance = util.euclidean_distance( self.drone.coords, other_drone.coords) # distance between two drones if drones_distance <= min(self.drone.communication_range, other_drone.communication_range ): # one feels the other & vv # CHANNEL UNPREDICTABILITY if self.channel_success(drones_distance, no_error=no_error): closest_drones.append((other_drone, drones_distance)) return closest_drones
def will_reach_target(self): """ Returns true if the drone will reach its target or overcome it in this step. """ return self.speed * self.simulator.ts_duration_sec >= euclidean_distance(self.coords, self.next_target())
def routing(self, drones, depot, cur_step): """ do the routing """ self.distance_from_depot = utilities.euclidean_distance( self.depot.coords, self.coords) self.routing_algorithm.routing(depot, drones, cur_step)
def distance_from_depot(self): return utilities.euclidean_distance(self.simulator.depot_coordinates, self.coords)