def find_finished_pedestrians(self): """ Finds all pedestrians that have reached the goal in this time step. If there is a cap on the number of pedestrians allowed to exit, we randomly sample that number of pedestrians and leave the rest in the exit. If any pedestrians are unable to exit, we set the exit to inaccessible. The pedestrians that leave are processed and removed from the scene :return: None """ for goal in self.exit_list: in_goal = np.logical_and(self.position_array >= goal.begin, self.position_array <= goal.end) in_g = np.logical_and(in_goal[:, 0], in_goal[:, 1]) done = np.logical_and(in_g, self.active_entries) index_list = np.where(done)[0] if goal.cap: surplus = max(0, len(index_list) - goal.cap) ft.debug("Surplus %d" % surplus) if surplus: index_list = np.random.choice(index_list, goal.cap, replace=False) goal.accessible = False else: goal.accessible = True for index in index_list: finished_pedestrian = self.index_map[index] goal.log_pedestrian(finished_pedestrian, self.time) self.remove_pedestrian(finished_pedestrian)
def create_new_pedestrians(self): """ Creates new pedestrians according to the entrance data. New indices are computed for these pedestrians and if necessary, the arrays are increased. :return: None """ for entrance in self.entrance_list: new_number = entrance.get_new_number_of_pedestrians(self.time) max_tries = 100 * new_number tries = 0 # when this becomes large, chances are the entrance can produce no valid new position. while new_number > 0: tries += 1 new_position = entrance.get_spawn_location() if not self.is_accessible(new_position): if tries > max_tries: raise RuntimeError("Can't find new spawn locations for %s. Check the scene" % entrance) continue free_indices = np.where(self.active_entries == False)[0] # Not faster with np.not if len(free_indices): new_index = free_indices[0] else: new_index = self.active_entries.shape[0] self._expand_arrays() ft.debug("Indices full. doubling array size to %d" % (2 * new_index)) new_max_speed = self.max_speed_interval.random() self.max_speed_array[new_index] = new_max_speed new_pedestrian = Pedestrian(self, self.total_pedestrians, self.exit_list, new_position, new_index) self.total_pedestrians += 1 self.active_entries[new_index] = True self.pedestrian_list.append(new_pedestrian) self.index_map[new_index] = new_pedestrian [func(new_pedestrian) for func in self.on_pedestrian_init_functions] new_number -= 1
def start_drawing(self, event): ft.debug(self.object_status.get()) self.draw_status = SceneCreator.DrawStatus.drawing self.draw_start = (event.x, event.y) self.window.bind('<Motion>', self.motion) self.window.bind('<Button-1>', self.stop_drawing) ft.debug("Started drawing. Start location of obstacle: %s" % str(self.draw_start))
def __init__(self): self.window = tkinter.Tk() self.window.title("Scene creator") self.size = (800, 800) self.window.bind('<Button-1>', self.start_drawing) self.window.bind('<Button-2>', self.remove_last_obstacle) self.canvas = tkinter.Canvas(self.window) self.canvas.pack(fill=tkinter.BOTH, expand=1) self.draw_status = SceneCreator.DrawStatus.idle self.object_status = SceneCreator.ObjectStatus.obstacle self.menu = tkinter.Menu(self.window) self.menu.add_command(label='Save scene', command=self.ask_save) self.menu.add_command(label='Quit', command=self.window.destroy) self.object_status = tkinter.IntVar() self.menu.add_radiobutton(label='Obstacles', variable=self.object_status, value=0) self.menu.add_radiobutton(label='Exits', variable=self.object_status, value=1) self.menu.add_radiobutton(label='Entrances', variable=self.object_status, value=2) self.window.config(menu=self.menu) ft.debug("Started creating scenes.") self.obstacle_list = [] self.exit_list = [] self.entrance_list = [] self.new_object_holder = 0 self.draw_start = self.draw_end = None
def stop_drawing(self, event): ft.debug("stopped drawing") self.window.unbind('<Motion>') self.draw_status = SceneCreator.DrawStatus.idle self.draw_end = (event.x, event.y) ft.debug("End of obstacle: %s" % str(self.draw_end)) new_obstacle = self.create_new_obstacle() self.draw_start = self.draw_end = None self.window.bind('<Button-1>', self.start_drawing) self.draw_obstacle(new_obstacle)
def update(self, new_field): """ Preferred way of updating a field. :param new_field: np.array (must be same size) to update the Scalar field with :return: """ if not self.array.shape == new_field.shape: ft.debug((self.name, self.array.shape, new_field.shape)) assert self.array.shape == new_field.shape self.array = new_field.copy() self.time_step += 1
def update(self, new_field): """ Preferred way of updating the array from this field. :param new_field: np.array (must be same size) to update the Scalar field with :return: """ if not self.array.shape == new_field.shape: ft.debug((self.name, self.array.shape, new_field.shape)) assert self.array.shape == new_field.shape self.array = new_field self.time_step += 1
def draw_obstacle(self, obstacle): draw_coords = self.convert_relative_coordinate(obstacle.start) + self.convert_relative_coordinate(obstacle.end) ft.debug("Drawing obstacle on %s" % str(draw_coords)) enum = SceneCreator.ObjectStatus(self.object_status.get()) if enum == SceneCreator.ObjectStatus.obstacle: color = 'gray' elif enum == SceneCreator.ObjectStatus.exit: color = 'red' elif enum == SceneCreator.ObjectStatus.entrance: color = 'green' else: raise ValueError("Bug in enums ObjectStatus") self.canvas.create_rectangle(draw_coords, fill=color)
def __init__(self, begin, size): ft.debug("Creating new obstacle with start %s and size %s" % (str(begin), str(size))) self.start = begin self.size = size self.end = (begin[0] + size[0], begin[1] + size[1])