def abstrips_solve_from_task(sas_task, temp_dir=TEMP_DIR, clean=False, debug=False, hierarchy=[], **kwargs): # Like partial order planning in terms of precondition order # TODO: add achieve subgoal actions # TODO: most generic would be a heuristic on each state if not hierarchy: return solve_from_task(sas_task, temp_dir=temp_dir, clean=clean, debug=debug, **kwargs) start_time = time() plan, cost = None, INF with Verbose(debug): print('\n' + 50*'-' + '\n') last_plan = [] for level in range(len(hierarchy)+1): local_sas_task = deepcopy(sas_task) prune_hierarchy_pre_eff(local_sas_task, hierarchy[level:]) # TODO: break if no pruned add_subgoals(local_sas_task, last_plan) write_sas_task(local_sas_task, temp_dir) plan, cost = parse_solution(run_search(temp_dir, debug=True, **kwargs)) if (level == len(hierarchy)) or (plan is None): # TODO: fall back on standard search break last_plan = [name_from_action(action, args) for action, args in plan] if clean: safe_rm_dir(temp_dir) print('Total runtime:', time() - start_time) return plan, cost
def abstrips_solve_from_task_sequential(sas_task, temp_dir=TEMP_DIR, clean=False, debug=False, hierarchy=[], subgoal_horizon=1, **kwargs): # TODO: version that plans for each goal individually # TODO: can reduce to goal serialization if binary flag for each subgoal if not hierarchy: return solve_from_task(sas_task, temp_dir=temp_dir, clean=clean, debug=debug, **kwargs) start_time = time() plan, cost = None, INF with Verbose(debug): last_plan = None for level in range(len(hierarchy) + 1): local_sas_task = deepcopy(sas_task) prune_hierarchy_pre_eff(local_sas_task, hierarchy[level:]) # TODO: break if no pruned # The goal itself is effectively a subgoal # Handle this subgoal horizon subgoal_plan = [local_sas_task.goal.pairs[:]] # TODO: do I want to consider the "subgoal action" as a real action? if last_plan is not None: subgoal_var = add_subgoals(local_sas_task, last_plan) subgoal_plan = [[(subgoal_var, val)] for val in range(1, local_sas_task.variables.ranges[subgoal_var], subgoal_horizon)] + subgoal_plan hierarchy_horizon = min(hierarchy[level-1].horizon, len(subgoal_plan)) subgoal_plan = subgoal_plan[:hierarchy_horizon] plan, cost = plan_subgoals(local_sas_task, subgoal_plan, temp_dir, **kwargs) if (level == len(hierarchy)) or (plan is None): # TODO: fall back on normal # TODO: search in space of subgoals break last_plan = [name_from_action(action, args) for action, args in plan] if clean: safe_rm_dir(temp_dir) print('Total runtime:', time() - start_time) # TODO: record which level of abstraction each operator is at when returning # TODO: return instantiated actions here rather than names (including pruned pre/eff) return plan, cost
def start_task(): pid = os.getpid() current_wd = os.getcwd() trial_wd = os.path.join(current_wd, TEMP_DIRECTORY, '{}/'.format(pid)) safe_rm_dir(trial_wd) ensure_dir(trial_wd) os.chdir(trial_wd) return current_wd, trial_wd
def write_pddl(domain_pddl, problem_pddl): # TODO: already in downward.py safe_rm_dir(TEMP_DIR) # Ensures not using old plan ensure_dir(TEMP_DIR) domain_path = TEMP_DIR + DOMAIN_INPUT problem_path = TEMP_DIR + PROBLEM_INPUT write(domain_path, domain_pddl) write(problem_path, problem_pddl) return domain_path, problem_path
def display_plan(tamp_problem, plan, display=True, time_step=0.01, sec_per_step=0.002): from examples.continuous_tamp.viewer import ContinuousTMPViewer from examples.discrete_tamp.viewer import COLORS example_name = os.path.basename(os.path.dirname(__file__)) directory = os.path.join(VISUALIZATIONS_DIR, example_name + '/') safe_rm_dir(directory) ensure_dir(directory) colors = dict(zip(sorted(tamp_problem.initial.block_poses.keys()), COLORS)) viewer = ContinuousTMPViewer(SUCTION_HEIGHT, tamp_problem.regions, title='Continuous TAMP') state = tamp_problem.initial print() print(state) duration = compute_duration(plan) real_time = None if sec_per_step is None else (duration * sec_per_step / time_step) print('Duration: {} | Step size: {} | Real time: {}'.format( duration, time_step, real_time)) draw_state(viewer, state, colors) if display: user_input('Start?') if plan is not None: #for action in plan: # i = action.start # print(action) # for j, state in enumerate(apply_action(state, action)): # print(i, j, state) # draw_state(viewer, state, colors) # viewer.save(os.path.join(directory, '{}_{}'.format(i, j))) # if display: # if sec_per_step is None: # user_input('Continue?') # else: # time.sleep(sec_per_step) for t in inclusive_range(0, duration, time_step): for action in plan: if action.start <= t <= get_end(action): update_state(state, action, t - action.start) print('t={} | {}'.format(t, state)) draw_state(viewer, state, colors) viewer.save(os.path.join(directory, 't={}'.format(t))) if display: if sec_per_step is None: user_input('Continue?') else: time.sleep(sec_per_step) if display: user_input('Finish?')
def serialized_solve_from_task(sas_task, temp_dir=TEMP_DIR, clean=False, debug=False, hierarchy=[], **kwargs): # TODO: specify goal grouping / group by predicate & objects # TODO: version that solves for all subgoals at once start_time = time() with Verbose(debug): print('\n' + 50*'-' + '\n') subgoal_plan = [sas_task.goal.pairs[:i+1] for i in range(len(sas_task.goal.pairs))] plan, cost = plan_subgoals(sas_task, subgoal_plan, temp_dir, **kwargs) if clean: safe_rm_dir(temp_dir) print('Total runtime:', time() - start_time) return plan, cost
def solve_from_pddl(domain_pddl, problem_pddl, temp_dir=TEMP_DIR, clean=False, debug=False, **kwargs): # TODO: combine with solve_from_task start_time = time() with Verbose(debug): write_pddl(domain_pddl, problem_pddl, temp_dir) #run_translate(temp_dir, verbose) translate_and_write_pddl(domain_pddl, problem_pddl, temp_dir, debug) solution = run_search(temp_dir, debug=debug, **kwargs) if clean: safe_rm_dir(temp_dir) print('Total runtime:', time() - start_time) return parse_solution(solution)
def solve_from_task(task, temp_dir=TEMP_DIR, clean=False, debug=False, **kwargs): start_time = time() with Verbose(debug): translate_and_write_task(task, temp_dir) solution = run_search(temp_dir, debug=True, **kwargs) if clean: safe_rm_dir(temp_dir) print('Total runtime:', time() - start_time) return parse_solution(solution)
def solve_from_task(sas_task, temp_dir=TEMP_DIR, clean=False, debug=False, hierarchy=[], **kwargs): # TODO: can solve using another planner and then still translate using FastDownward # Can apply plan constraints (skeleton constraints) here as well start_time = time() with Verbose(debug): print('\n' + 50*'-' + '\n') write_sas_task(sas_task, temp_dir) solution = run_search(temp_dir, debug=True, **kwargs) if clean: safe_rm_dir(temp_dir) print('Total runtime:', time() - start_time) #for axiom in sas_task.axioms: # # TODO: return the set of axioms here as well # var, value = axiom.effect # print(sas_task.variables.value_names[var]) # axiom.dump() return parse_solution(solution)
def solve_from_pddl(domain_pddl, problem_pddl, temp_dir=TEMP_DIR, clean=False, debug=False, **search_kwargs): # TODO: combine with solve_from_task #return solve_tfd(domain_pddl, problem_pddl) start_time = time() with Verbose(debug): write_pddl(domain_pddl, problem_pddl, temp_dir) #run_translate(temp_dir, verbose) translate_and_write_pddl(domain_pddl, problem_pddl, temp_dir, debug) solution = run_search(temp_dir, debug=debug, **search_kwargs) if clean: safe_rm_dir(temp_dir) print('Total runtime: {:.3f}'.format(elapsed_time(start_time))) return solution
def run_trials(trials, data_path=None, num_cores=False, **kwargs): # https://stackoverflow.com/questions/15314189/python-multiprocessing-pool-hangs-at-join # https://stackoverflow.com/questions/39884898/large-amount-of-multiprocessing-process-causing-deadlock # TODO: multiprocessing still seems to hang on one thread before starting assert (get_python_version() == 3) results = [] if not trials: return results start_time = time.time() serial = (num_cores is False) # None is the max number failures = 0 scored = 0 try: for result in map_general(run_trial, trials, serial, num_cores=num_cores, **kwargs): num_trials = len(results) + failures print( '{}\nTrials: {} | Successes: {} | Failures: {} | Scored: {} | Time: {:.3f}' .format(SEPARATOR, num_trials, len(results), failures, scored, elapsed_time(start_time))) print('Result:', str_from_object(result)) if result is None: failures += 1 print('Error! Trial resulted in an exception') continue scored += int(result.get('score', None) is not None) results.append(result) write_results(data_path, results) # except BaseException as e: # traceback.print_exc() # e finally: print(SEPARATOR) safe_rm_dir(TEMP_DIRECTORY) write_results(data_path, results) print('Hours: {:.3f}'.format(elapsed_time(start_time) / HOURS_TO_SECS)) # TODO: make a generator version of this return results
def main(): parser = argparse.ArgumentParser() parser.add_argument('-p', '--prefix', default=None, help='The prefix of trials') parser.add_argument('-l', '--lower', default=0, help='The minimum number of trials') parser.add_argument('-u', '--upper', default=INF, help='The minimum number of trials') # TODO: select the training policy # TODO: date range args = parser.parse_args() #data_path = os.path.dirname(__file__) all_dirname = os.path.join(DATA_DIR, '{}_all/'.format(args.prefix)) selected_trials = [] all_data = [] for trial_dirname in sorted(os.listdir(DATA_DIR)): if (args.prefix is not None) and not trial_dirname.startswith(args.prefix): continue trial_directory = os.path.join(DATA_DIR, trial_dirname) if not os.path.isdir(trial_directory) or ( trial_directory == all_dirname[:-1]): # TODO: sloppy continue for trial_filename in sorted(os.listdir(trial_directory)): if trial_filename.startswith(TRIAL_PREFIX): trial_path = os.path.join(trial_directory, trial_filename) data = list(read_data(trial_path)) if (len(data) < args.lower) or (args.upper < len(data)): continue print('\n{}'.format( os.path.join(DATA_DIR, trial_dirname, trial_filename))) # TODO: record the type of failure num_scored = sum(result[SCORE] is not None for result in data) print('Trials: {} | Scored: {}'.format(len(data), num_scored)) category_frequencies = { category: Counter(field for result in data if result.get(category, {}) for field in result.get(category, {})) for category in CATEGORIES } category_frequencies.update({ category: Counter(result[category] for result in data if category in result) for category in SPECIAL_CATEGORIES }) #if list(category_frequencies.get('policy', {})) != [TRAINING]: # continue for category in CATEGORIES + SPECIAL_CATEGORIES: frequencies = category_frequencies.get(category, {}) if frequencies: print('{} ({}): {}'.format(category, len(frequencies), sorted(frequencies.keys()))) category_values = get_category_values(data, include_score=False) context_values = category_values[FEATURE] for name in sorted(DISCRETE_FEATURES): if name in context_values: print('{}: {}'.format(name, Counter(context_values[name]))) selected_trials.append(trial_path) all_data.extend(data) # TODO: print num of successful trials #if len(data) < MIN_TRIALS: # response = user_input('Remove {}?'.format(trial_path)) # safe_remove(trial_path) # Get most recent of each skill if not os.listdir(trial_directory): print('Removed {}'.format(trial_directory)) safe_rm_dir(trial_directory) print() print(len(all_data)) ensure_dir(all_dirname) #write_results(os.path.join(all_dirname, TRIAL_PREFIX), all_data) #write_json(path, all_data) print(' '.join(selected_trials))
def complete_task(sim_world, current_wd, trial_wd): # TODO: the pybullet windows aren't fully closing on OSX sim_world.stop() os.chdir(current_wd) safe_rm_dir(trial_wd)
def main(): parser = create_parser() args = parser.parse_args() print(args) # https://stackoverflow.com/questions/15314189/python-multiprocessing-pool-hangs-at-join # https://stackoverflow.com/questions/39884898/large-amount-of-multiprocessing-process-causing-deadlock # TODO: alternatively don't destroy the world num_cores = max(1, cpu_count() - SPARE_CORES) json_path = os.path.abspath( os.path.join(EXPERIMENTS_DIRECTORY, '{}.json'.format(get_date()))) #memory_per_core = float(MAX_RAM) / num_cores # gigabytes #set_soft_limit(resource.RLIMIT_AS, int(BYTES_PER_GIGABYTE * memory_per_core)) # bytes #set_soft_limit(resource.RLIMIT_CPU, 2*MAX_TIME) # seconds # RLIMIT_MEMLOCK, RLIMIT_STACK, RLIMIT_DATA print('Results:', json_path) print('Num Cores:', num_cores) #print('Memory per Core: {:.2f}'.format(memory_per_core)) print('Tasks: {} | {}'.format(len(TASK_NAMES), TASK_NAMES)) print('Policies: {} | {}'.format(len(POLICIES), POLICIES)) print('Num Trials:', N_TRIALS) num_experiments = len(TASK_NAMES) * len(POLICIES) * N_TRIALS print('Num Experiments:', num_experiments) max_parallel = math.ceil(float(num_experiments) / num_cores) print('Estimated duration: {:.2f} hours'.format( MEAN_TIME_PER_TRIAL * max_parallel / HOURS_TO_SECS)) user_input('Begin?') print(SEPARATOR) print('Creating problems') start_time = time.time() problems = create_problems(args) experiments = [ { 'problem': copy.deepcopy(problem), 'policy': policy } #, 'args': args} for problem in problems for policy in POLICIES ] print('Created {} problems and {} experiments in {:.3f} seconds'.format( len(problems), len(experiments), elapsed_time(start_time))) print(SEPARATOR) ensure_dir(EXPERIMENTS_DIRECTORY) safe_rm_dir(TEMP_DIRECTORY) ensure_dir(TEMP_DIRECTORY) start_time = time.time() results = [] try: for result in map_parallel(run_experiment, experiments, num_cores=num_cores): results.append(result) print('{}\nExperiments: {} / {} | Time: {:.3f}'.format( SEPARATOR, len(results), len(experiments), elapsed_time(start_time))) print('Experiment:', str_from_object(result['experiment'])) print('Outcome:', str_from_object(result['outcome'])) write_json(json_path, results) #except BaseException as e: # traceback.print_exc() # e finally: if results: write_json(json_path, results) print(SEPARATOR) print('Saved:', json_path) print('Results:', len(results)) print('Duration / experiment: {:.3f}'.format( num_cores * elapsed_time(start_time) / len(experiments))) print('Duration: {:.2f} hours'.format( elapsed_time(start_time) / HOURS_TO_SECS)) safe_rm_dir(TEMP_DIRECTORY) # TODO: dump results automatically? return results
def run_experiment(experiment): problem = experiment['problem'] task_name = problem['task'].name if SERIALIZE_TASK else problem['task'] trial = problem['trial'] policy = experiment['policy'] set_memory_limits() if not VERBOSE: sys.stdout = open(os.devnull, 'w') stdout = sys.stdout if not SERIAL: current_wd = os.getcwd() # trial_wd = os.path.join(current_wd, TEMP_DIRECTORY, '{}/'.format(os.getpid())) trial_wd = os.path.join( current_wd, TEMP_DIRECTORY, 't={}_n={}_{}/'.format(task_name, trial, name_from_policy(policy))) safe_rm_dir(trial_wd) ensure_dir(trial_wd) os.chdir(trial_wd) parser = create_parser() args = parser.parse_args() task_fn_from_name = {fn.__name__: fn for fn in TASKS_FNS} task_fn = task_fn_from_name[task_name] world = World(use_gui=SERIAL) if SERIALIZE_TASK: task_fn(world, fixed=args.fixed) task = problem['task'] world.task = task task.world = world else: # TODO: assumes task_fn is deterministic wrt task task_fn(world, fixed=args.fixed) problem['saver'].restore() world._update_initial() problem['task'] = task_name # for serialization del problem['saver'] random.seed(hash((0, task_name, trial, time.time()))) numpy.random.seed(hash((1, task_name, trial, time.time())) % (2**32)) #seed1, seed2 = problem['seeds'] # No point unless you maintain the same random state per generator #set_random_seed(seed1) #set_random_seed(seed2) #random.setstate(state1) #numpy.random.set_state(state2) reset_globals() real_state = create_state(world) #start_time = time.time() #if has_gui(): # wait_for_user() observation_fn = lambda belief: observe_pybullet(world) transition_fn = lambda belief, commands: iterate_commands( real_state, commands, time_step=0) outcome = dict(ERROR_OUTCOME) try: with timeout(MAX_TIME + TIME_BUFFER): outcome = run_policy(task, args, observation_fn, transition_fn, max_time=MAX_TIME, **policy) outcome['error'] = False except KeyboardInterrupt: raise KeyboardInterrupt() except: traceback.print_exc() #outcome = {'error': True} world.destroy() if not SERIAL: os.chdir(current_wd) safe_rm_dir(trial_wd) if not VERBOSE: sys.stdout.close() sys.stdout = stdout result = { 'experiment': experiment, 'outcome': outcome, } return result