def test_tracker_creates_a_stats_entry(): def simple_print(message): print(message) tracker = PerformanceTracker(algorithm_name) tracker.count("printCount", lambda: simple_print("count 0")) all_stats = tracker.get_stats() number_of_stats = len(all_stats) assert number_of_stats == 2, "Cannot create a single stat entry for counting"
def test_tracker_adds_stat_for_time(): def waiting(time_to_wait): time.sleep(time_to_wait) tracker = PerformanceTracker(algorithm_name) tracker.time("wait", lambda: waiting(1)) all_stats = tracker.get_stats() number_of_stats = len(all_stats) assert number_of_stats == 2, "Cannot create a single stat entry for timing"
def test_tracker_counts_how_many_times_function_is_called(): def empty_func(): pass number_of_times_to_call_function = 5 tracker = PerformanceTracker(algorithm_name) for i in range(number_of_times_to_call_function): tracker.count("functionCallCount", empty_func) all_stats = tracker.get_stats() assert all_stats[ "functionCallCount"] is number_of_times_to_call_function, "Cannot correctly count the number of times a function is called"
def test_tracker_times_how_long_a_function_takes_to_run(): def waiting(waiting_time): time.sleep(waiting_time) time_to_wait = 2 tracker = PerformanceTracker(algorithm_name) tracker.time("wait", lambda: waiting(time_to_wait)) all_stats = tracker.get_stats() time_taken = all_stats["wait"] threshold = 0.1 assert (time_taken < (time_to_wait + threshold)) and ( time_taken > (time_to_wait - threshold) ), "Cannot accurately time function within a certain threshold"
def test_tracker_creates_multiple_stats_entry(): def simple_print(message): print(message) tracker = PerformanceTracker(algorithm_name) tracker.count("printCount1", lambda: simple_print("count 1")) tracker.count("printCount2", lambda: simple_print("count 2")) tracker.count("printCount3", lambda: simple_print("count 3")) tracker.count("printCount4", lambda: simple_print("count 4")) tracker.count("printCount5", lambda: simple_print("count 5")) all_stats = tracker.get_stats() number_of_stats = len(all_stats) assert number_of_stats == 6, "Cannot create multiple stats entry for counting"
def test_tracker_times_multiple_instances_of_same_key(): def waiting(waiting_time): time.sleep(waiting_time) time_to_wait = 1 expected_time = 2 tracker = PerformanceTracker(algorithm_name) for i in range(expected_time): tracker.time("wait", lambda: waiting(time_to_wait)) all_stats = tracker.get_stats() time_taken = all_stats["wait"] threshold = 0.1 assert (time_taken < (expected_time + threshold)) and ( time_taken > (expected_time - threshold)), "Cannot accurately add times of multiple function calls"
def test_tracker_can_track_the_max_length_of_a_list(): tracker = PerformanceTracker(algorithm_name) list_name = "test_list" test_list = [] size_of_list = 5 elements_to_remove = 3 for i in range(size_of_list): test_list.append(0) tracker.record_max(list_name, len(test_list)) for j in range(elements_to_remove): test_list.pop() stats = tracker.get_stats() list_size = stats[list_name] assert list_size == size_of_list, "Cannot correctly record size of list at its larger size"
def test_print_stats_for_tracker(): def waiting(waiting_time): time.sleep(waiting_time) def empty_func(): pass time_to_wait = 2 tracker = PerformanceTracker(algorithm_name) tracker.time("wait", lambda: waiting(time_to_wait)) for i in range(10): tracker.count("empty", lambda: empty_func()) tracker.print_stats()
def __init__(self, map_details): """my_map - list of lists specifying obstacle positions starts - [(x1, y1), (x2, y2), ...] list of start locations goals - [(x1, y1), (x2, y2), ...] list of goal locations """ self.my_map = map_details.map_instance self.starts = map_details.starting_loc self.goals = map_details.goal_loc self.num_of_agents = len(map_details.goal_loc) self.num_of_agents = len(self.goals) self.open_list = [] self.visited = set() self.visited_loc_Big_f = set() self.stat_tracker = PerformanceTracker("EPEA") self.stat_tracker.set_map_name(map_details.name) self.stat_tracker.set_results_file_name(map_details.result_file_name) self.osf = self.stat_tracker.time("osf time", lambda: OSF(self.my_map, self.goals))
def __init__(self, map_details): """my_map - list of lists specifying obstacle positions starts - [(x1, y1), (x2, y2), ...] list of start locations goals - [(x1, y1), (x2, y2), ...] list of goal locations """ self.my_map = map_details.map_instance self.starts = map_details.starting_loc self.goals = map_details.goal_loc self.num_of_agents = len(map_details.goal_loc) self.stat_tracker = PerformanceTracker("ICTS") self.stat_tracker.set_map_name(map_details.name) self.stat_tracker.set_results_file_name(map_details.result_file_name) self.open_list = [] # compute heuristics for the low-level search self.heuristics = [] self.stat_tracker.time("heuristic_time", lambda: self.calculate_heuristics()) self.ict = self.stat_tracker.time("time", lambda: self.create_ict()) self.upper_bound = self.calculate_upper_bound_cost()
def test_tracker_can_write_file(): def empty_func(): pass tracker = PerformanceTracker(algorithm_name) for i in range(10): tracker.count("empty", lambda: empty_func()) tracker.write_stats_to_file(file_name_1) assert os.path.exists( file_name_1), "Cannot create file for performance tracker" os.remove(file_name_1)
def test_tracker_can_write_single_entry_to_file(): def empty_func(): pass tracker = PerformanceTracker(algorithm_name) expected_result = "{\"algorithm\": \"ICTS\", \"empty\": 10, \"map_name\": \"test_map\"}\n" for i in range(10): tracker.count("empty", lambda: empty_func()) tracker.set_map_name("test_map") tracker.write_stats_to_file(file_name_2) stats_file = open(file_name_2, "r") file_contents = "" if stats_file.mode == "r": file_contents = stats_file.read() assert file_contents == expected_result, "Cannot write single performance tracker entry to file" stats_file.close() os.remove(file_name_2)
def test_tracker_can_track_the_size_of_list(): tracker = PerformanceTracker(algorithm_name) list_name = "test_list" test_list = [] size_of_list = 5 tracker.add_list_to_record(list_name, test_list) for i in range(size_of_list): test_list.append(0) tracker.update_all_list_lengths() stats = tracker.get_stats() list_size = stats[list_name] assert list_size == len( test_list ), "Cannot correctly record size of list upon call to record the length of the list"
class EPEASolver(object): """A high-level EPEA* search.""" def __init__(self, map_details): """my_map - list of lists specifying obstacle positions starts - [(x1, y1), (x2, y2), ...] list of start locations goals - [(x1, y1), (x2, y2), ...] list of goal locations """ self.my_map = map_details.map_instance self.starts = map_details.starting_loc self.goals = map_details.goal_loc self.num_of_agents = len(map_details.goal_loc) self.num_of_agents = len(self.goals) self.open_list = [] self.visited = set() self.visited_loc_Big_f = set() self.stat_tracker = PerformanceTracker("EPEA") self.stat_tracker.set_map_name(map_details.name) self.stat_tracker.set_results_file_name(map_details.result_file_name) self.osf = self.stat_tracker.time("osf time", lambda: OSF(self.my_map, self.goals)) def find_solution(self): """ Finds paths for all agents from their start locations to their goal locations """ print("\nFinding EPEA* Solution...") result = self.stat_tracker.time("time", lambda: self.epea_star()) self.stat_tracker.write_stats_to_file( self.stat_tracker.get_results_file_name()) return result def epea_star(self): osf = self.osf open_list = self.open_list start_locs = tuple(self.starts) goals = tuple(self.goals) visited_locs = self.visited num_agents = len(start_locs) mycounter = 0 # counter used to break ties in the priority queue g = 0 h = osf.list_of_locations_to_heuristic(start_locs) start_node = { 'agent_locs': start_locs, 'g': 0, 'h': h, 'small_f': g + h, 'big_F': g + h, 'parent': False } priority_tuple = (g + h, -g, h, mycounter) heappush(open_list, (priority_tuple, start_node)) mycounter += 1 start_time = timer.time() nodes_expanded = 0 while (len(open_list) != 0): self.print_sanity_track(start_time, nodes_expanded) priority_tuple, current_node = heappop(open_list) if current_node['agent_locs'] == goals: return self.find_paths(current_node, goals) new_child_nodes, next_big_F = self.stat_tracker.count( "expanded nodes", lambda: osf.get_children_and_next_F(current_node)) for child in new_child_nodes: child_node = self.get_child_node(child, current_node, osf) if child not in visited_locs: visited_locs.add(child) priority_tuple = (child_node['big_F'], child_node['h'], -child_node['g'], mycounter) heappush(open_list, (priority_tuple, child_node)) self.stat_tracker.record_max('max_open_list_length', len(open_list)) mycounter += 1 if math.isinf(next_big_F): visited_locs.add(current_node['agent_locs']) else: current_node['big_F'] = next_big_F priority_tuple = (current_node['big_F'], current_node['h'], -current_node['g'], mycounter) heappush(open_list, (priority_tuple, current_node)) self.stat_tracker.record_max('max_open_list_length', len(open_list)) mycounter += 1 nodes_expanded += 1 return [] def find_paths(self, node, goals): path = [goals] while (node['parent']): path.append(node['parent']['agent_locs']) node = node['parent'] path.reverse() path = [list(t) for t in path] path = list(list(i) for i in zip(*path)) return path def print_sanity_track(self, start_time, num_expanded): elapsed = "{:.5f}".format(round(timer.time() - start_time, 5)) print("\r[ Time elapsed: " + elapsed + "s | Nodes expanded: " + str(num_expanded), end=" ]", flush=True) def get_child_node(self, child, parent, osf): h = osf.list_of_locations_to_heuristic(child) num_agents_not_at_goal = 0 for i, loc in enumerate(child): if self.goals[i] != loc: num_agents_not_at_goal += 1 g = parent['g'] + num_agents_not_at_goal small_f = g + h big_F = small_f new_node = { 'agent_locs': child, 'g': g, 'h': h, 'small_f': small_f, 'big_F': big_F, 'parent': parent } return new_node
def test_tracker_can_write_multiple_entries_to_file(): def empty_func(): pass tracker1 = PerformanceTracker(algorithm_name) tracker2 = PerformanceTracker(algorithm_name) expected_result = '{"algorithm": "ICTS", "empty": 10, "map_name": "test_map"}\n{"algorithm": "ICTS", "empty": 5, "map_name": "test_2_map"}\n' for i in range(10): tracker1.count("empty", lambda: empty_func()) for i in range(5): tracker2.count("empty", lambda: empty_func()) tracker1.set_map_name("test_map") tracker2.set_map_name("test_2_map") tracker1.write_stats_to_file(file_name_3) tracker2.write_stats_to_file(file_name_3) stats_file = open(file_name_3, "r") file_contents = "" if stats_file.mode == "r": file_contents = stats_file.read() assert file_contents == expected_result, "Cannot write multiple performance tracker entry to file, each entry being on a different line" stats_file.close() os.remove(file_name_3)
import mdd import map_utils as util from performance_tracker import PerformanceTracker dummy_tracker = PerformanceTracker("test") def test_simple_construction(my_map, starts, goals): agent = 0 depth = 7 # Arbitrary depth new_mdd = mdd.MDD(my_map, 0, starts[agent], goals[agent], depth, False) assert new_mdd.agent == 0, "test_simple_construction Failed: Agent is improperly set" assert new_mdd.depth == depth, "test_simple_construction Failed: Depth is improperly set" assert new_mdd.start == starts[ agent], "test_simple_construction Failed: Start is improperly set" assert new_mdd.goal == goals[ agent], "test_simple_construction Failed: Goal is improperly set" print("test_simple_construction Passed") def test_depth_d_bfs_tree(my_map, starts, goals): agent = 0 depth = 4 new_mdd = mdd.MDD(my_map, 0, starts[agent], goals[agent], depth) bfs_tree_dict = new_mdd.get_depth_d_bfs_tree(my_map, starts[agent], depth) bfs_tree = bfs_tree_dict['tree'] for node in bfs_tree.keys(): for val in bfs_tree[node]: loc, t = val assert not my_map[loc[0]][loc[ 1]], "test_depth_d_bfs_tree Failed: BFS explores invalid cells"
class ICTSSolver(object): """A high-level ICTS search.""" def __init__(self, map_details): """my_map - list of lists specifying obstacle positions starts - [(x1, y1), (x2, y2), ...] list of start locations goals - [(x1, y1), (x2, y2), ...] list of goal locations """ self.my_map = map_details.map_instance self.starts = map_details.starting_loc self.goals = map_details.goal_loc self.num_of_agents = len(map_details.goal_loc) self.stat_tracker = PerformanceTracker("ICTS") self.stat_tracker.set_map_name(map_details.name) self.stat_tracker.set_results_file_name(map_details.result_file_name) self.open_list = [] # compute heuristics for the low-level search self.heuristics = [] self.stat_tracker.time("heuristic_time", lambda: self.calculate_heuristics()) self.ict = self.stat_tracker.time("time", lambda: self.create_ict()) self.upper_bound = self.calculate_upper_bound_cost() def calculate_heuristics(self): h = [dict() for g in range(len(self.goals))] for x, row in enumerate(self.my_map): for y, col in enumerate(row): if not col: for g, goal in enumerate(self.goals): h[g][(x, y)] = self.manhattan_distance((x, y), goal) self.heuristics = h def true_distance_bfs(self, my_map, goal): h = dict() q = collections.deque() indiv_ops = [(1, 0), (-1, 0), (0, 1), (0, -1), (0, 0)] q.append((goal, 0)) visited = set() visited.add(goal) while q: (x, y), this_h = q.popleft() h[(x, y)] = this_h children = [] for op in indiv_ops: new_child = (x + op[0], y + op[1]) if not my_map[new_child[0]][ new_child[1]] and new_child not in visited: visited.add(new_child) children.append((new_child, this_h + 1)) if children: q.extend(children) return h def manhattan_distance(self, my_loc, goal): return abs(my_loc[0] - goal[0]) + abs(my_loc[1] - goal[1]) def find_solution(self): """ Finds paths for all agents from their start locations to their goal locations """ print("\nFinding ICTS Solution...") ######### Fill in the ICTS Algorithm here ######### result = self.stat_tracker.time("time", lambda: self.bfs()) if result == -1: self.stat_tracker.stats['time'] = -1 return [] self.stat_tracker.write_stats_to_file( self.stat_tracker.get_results_file_name()) return result ################################################### def calculate_upper_bound_cost(self): number_of_open_spaces = find_number_of_open_spaces(self.my_map) upper_bound = (self.num_of_agents**2) * number_of_open_spaces return upper_bound def bfs(self): ict = self.ict open_list = ict.get_open_list() mdd_cache = {} start_time = timer.time() nodes_expanded = 0 while (len(open_list) != 0): current_node = ict.get_next_node_to_expand() node_cost = current_node.get_cost() if timer.time() - start_time > 60: return -1 self.print_sanity_track(start_time, nodes_expanded) if not self.node_has_exceeded_upper_bound(current_node, self.upper_bound): solution_paths = self.find_paths_for_agents_for_given_cost( node_cost, mdd_cache) if (self.solution_exists(solution_paths)): return solution_paths else: self.stat_tracker.count('expanded nodes', lambda: ict.expand_next_node()) self.stat_tracker.record_max('max_open_list_length', len(open_list)) nodes_expanded += 1 ict.pop_next_node_to_expand() return [] def node_has_exceeded_upper_bound(self, node, upper_bound): agent_costs = node.get_cost() summed_agent_costs = sum(agent_costs) return summed_agent_costs > upper_bound def solution_exists(self, paths): return paths != None def find_paths_for_agents_for_given_cost(self, agent_path_costs, mdd_cache): mdds = [] for i in range(len(agent_path_costs)): agent_depth_key = (i, agent_path_costs[i]) if agent_depth_key not in mdd_cache: agent_prev_depth_key = (i, agent_path_costs[i] - 1) t1 = timer.time() if agent_prev_depth_key in mdd_cache: new_mdd = MDD(self.my_map, i, self.starts[i], self.goals[i], agent_path_costs[i], last_mdd=mdd_cache[agent_prev_depth_key]) else: new_mdd = MDD(self.my_map, i, self.starts[i], self.goals[i], agent_path_costs[i]) t2 = timer.time() mdd_cache[agent_depth_key] = new_mdd else: # Already cached new_mdd = mdd_cache[agent_depth_key] mdds.append(new_mdd) t1 = timer.time() solution_path = find_solution_in_joint_mdd(mdds, self.stat_tracker) t2 = timer.time() return solution_path def create_ict(self): initial_estimate = self.find_cost_of_initial_estimate_for_root() if not initial_estimate: return None ict = IncreasingCostTree(self.my_map, self.starts, self.goals, initial_estimate) return ict def find_cost_of_initial_estimate_for_root(self): optimal_paths = self.find_most_optimal_paths() optimal_costs = [] for i in range(len(optimal_paths)): if not optimal_paths[i]: return [] optimal_costs.append(max(len(optimal_paths[i]) - 1, 0)) return optimal_costs def find_most_optimal_paths(self): optimal_paths = [] for agent in range(self.num_of_agents): optimal_paths.append( a_star(self.my_map, self.starts[agent], self.goals[agent], self.heuristics[agent], agent, [])) return optimal_paths def print_sanity_track(self, start_time, num_expanded): elapsed = "{:.5f}".format(round(timer.time() - start_time, 5)) print("\r[ Time elapsed: " + elapsed + "s | Nodes expanded: " + str(num_expanded), end=" ]", flush=True)
from posture_tracker import PostureTracker from performance_tracker import PerformanceTracker calibration_time = 2 check_periodicity = 10 positive_reinforcement_periodicity = 300 display_feed = False face_model_filepath = 'models/face_model.xml' storage_filename = 'historical_performance.json' performance_tracker = PerformanceTracker(storage_filename) posture_tracker = PostureTracker(face_model_filepath, calibration_time, check_periodicity, positive_reinforcement_periodicity, display_feed, performance_tracker) print("\nTracker calibrating...") posture_tracker.calibrate() print("\nTracker calibrated!") print("\nTracking posture...") posture_tracker.track()