def case1_synthesis(formula, ts_file): _, dfa_0, dfa_inf, bdd = twtl.translate(formula, kind='both', norm=True) logging.debug('alphabet: {}'.format(dfa_inf.props)) for u, v, d in dfa_inf.g.edges_iter(data=True): logging.debug('({}, {}): {}'.format(u, v, d)) dfa_inf.visualize(draw='matplotlib') plt.show() logging.debug('\nEnd of translate\n\n') logging.info('The bound of formula "%s" is (%d, %d)!', formula, *bdd) logging.info('Translated formula "%s" to normal DFA of size (%d, %d)!', formula, *dfa_0.size()) logging.info('Translated formula "%s" to infinity DFA of size (%d, %d)!', formula, *dfa_inf.size()) logging.debug('\n\nStart policy computation\n') ts = Ts.load(ts_file) ets = expand_duration_ts(ts) for name, dfa in [('normal', dfa_0), ('infinity', dfa_inf)]: logging.info('Constructing product automaton with %s DFA!', name) pa = ts_times_fsa(ets, dfa) logging.info('Product automaton size is: (%d, %d)', *pa.size()) if name == 'infinity': for u in pa.g.nodes_iter(): logging.debug('{} -> {}'.format(u, pa.g.neighbors(u))) pa.visualize(draw='matplotlib') plt.show() # compute optimal path in PA and then project onto the TS policy, output, tau = compute_control_policy(pa, dfa, dfa.kind) logging.info('Max deadline: %s', tau) if policy is not None: logging.info('Generated output word is: %s', [tuple(o) for o in output]) policy = [x for x in policy if x not in ets.state_map] out = StringIO.StringIO() for u, v in zip(policy[:-1], policy[1:]): print >> out, u, '->', ts.g[u][v][0]['duration'], '->', print >> out, policy[-1], logging.info('Generated control policy is: %s', out.getvalue()) out.close() logging.info('Relaxation is: %s', twtl.temporal_relaxation(output, formula=formula)) else: logging.info('No control policy found!')
def case2_verification(formula, ts_file): _, dfa_inf, bdd = twtl.translate(formula, kind=DFAType.Infinity, norm=True) logging.info('The bound of formula "%s" is (%d, %d)!', formula, *bdd) logging.info('Translated formula "%s" to infinity DFA of size (%d, %d)!', formula, *dfa_inf.size()) ts = Ts.load(ts_file) ts.g.add_edges_from(ts.g.edges(), weight=1) for u, v in ts.g.edges_iter(): print u, '->', v result = verify(ts, dfa_inf) logging.info('The result of the verification procedure is %s!', result)
def postprocessing(logfilename, ts_filename, outdir, lts_index, rrg_iterations, lts_iterations, local_traj_iterations, generate=()): '''Parses log file and generate statistics and figures.''' if not os.path.isdir(outdir): os.makedirs(outdir) with open(logfilename, 'r') as logfile: # first process general data data = dict() line = '' for line in logfile: prefix, line_data = line.split('--') if prefix.lower().rfind('info') >= 0: data.update(eval(line_data)) if line_data.lower().find('start global planning') >= 0: break print 'general data:', len(data) # second process data on global planner rrg_data = [] iteration_data = None for line in logfile: prefix, line_data = line.split('--') if prefix.lower().rfind('info') >= 0: if line_data.lower().rfind('found solution') >= 0: rrg_data.append(iteration_data) break if line_data.lower().find('iteration') >= 0: if iteration_data is not None: rrg_data.append(iteration_data) iteration_data = dict() iteration_data.update(eval(line_data)) print 'rrg data:', len(rrg_data) rrg_stat_data = eval(line_data) for line in logfile: prefix, line_data = line.split('--') if prefix.lower().rfind('info') >= 0: if line_data.lower().find('end global planning') >= 0: break rrg_stat_data.update(eval(line_data)) print 'rrg_stat_data', len(rrg_stat_data) assert rrg_stat_data['Iterations'] == len(rrg_data) # third process data on local planner rrt_stat_data = dict() for line in logfile: prefix, line_data = line.split('--') if prefix.lower().rfind('info') >= 0: if line_data.lower().find('initialize local planner') >= 0: break rrt_stat_data.update(eval(line_data)) print 'rrt_stat_data:', len(rrt_stat_data) rrt_data = [] execution_data = dict() for line in logfile: prefix, line_data = line.split('--') if prefix.lower().rfind('info') >= 0: if line_data.lower().find( 'local online planning finished') >= 0: rrt_data.append(execution_data) break # NOTE: second condition is for compatibility with Cozmo logs if (line_data.lower().find('start local planning step') >= 0 or line_data.lower().find('plan start time') >= 0): rrt_data.append(execution_data) execution_data = dict() execution_data.update(eval(line_data)) print 'rrt data:', len(rrt_data) # save useful information with open(os.path.join(outdir, 'general_data.txt'), 'w') as f: for key in [ 'Robot initial configuration', 'Robot step size', 'Global specification', 'Buchi size', 'Local specification' ]: print >> f, key, ':', data[key] for key in [ 'Iterations', 'global planning runtime', 'Size of TS', 'Size of PA' ]: print >> f, key, ':', rrg_stat_data[key] pre, suff = rrg_stat_data['global policy'] print >> f, 'Global policy size :', (len(pre), len(suff)) # key = 'Computing potential function runtime' # print>>f, key, ':', rrt_stat_data[key] # get workspace wspace, style = data['Workspace'] wspace.boundary.style = style ewspace, style = data['Expanded workspace'] ewspace.boundary.style = style # get robot robot_name = data['Robot name'] initConf = data['Robot initial configuration'] stepsize = data['Robot step size'] robot = eval(data['Robot constructor']) robot.diameter = data['Robot diameter'] robot.localObst = data['Local obstacle label'] # create simulation object sim = Simulate2D(wspace, robot, ewspace) sim.config['output-dir'] = outdir # add regions to workspace for key, value in data.iteritems(): if isinstance(key, tuple) and key[0] == "Global region": r, style = value # add styles to region addStyle(r, style=style) # add region to workspace sim.workspace.addRegion(r) # create expanded region er = expandRegion(r, robot.diameter / 2) # add style to the expanded region addStyle(er, style=style) # add expanded region to the expanded workspace sim.expandedWorkspace.addRegion(er) # get local requests and obstacles localSpec = data['Local specification'] requests = [] obstacles = [] for key, value in data.iteritems(): if isinstance(key, tuple) and key[0] == "Local region": r, style, path, is_request = value # add styles to region addStyle(r, style=style) # add path if path: r.path = it.cycle(path) r.original_path = path[:] # add to requests or obstacles lists if is_request: name = next(iter(r.symbols)) requests.append(Request(r, name, localSpec[name])) else: obstacles.append(r) # get robot sensor robot.sensor = eval(data['Robot sensor constructor']) # create RRG planner and load transition system, and global policy sim.offline = RRGPlanner(robot, None, 1) prefix, suffix = rrg_stat_data['global policy'] sim.solution = (prefix, suffix[1:]) print 'Global policy size:', len(prefix), len(suffix) if any(option in generate for option in ('workspace', 'expanded workspace', 'global solution')): # set larger font for saving figures for r in sim.workspace.regions | sim.expandedWorkspace.regions: r.fontsize_orig = r.textStyle.get('fontsize', 12) r.textStyle['fontsize'] = 24 # display workspace if 'workspace' in generate: sim.display(save='workspace.png') # display expanded workspace if 'expanded workspace' in generate: sim.display(expanded=True, save='eworkspace.png') # display solution for off-line problem if 'global solution' in generate: ts = sim.offline.ts sim.offline.ts = Ts.load(ts_filename) sim.display(expanded=True, solution=prefix + suffix[1:], save='global_solution.png') sim.offline.ts = ts # restore original fontsize for r in sim.workspace.regions: r.textStyle['fontsize'] = r.fontsize_orig del r.fontsize_orig # display both workspaces if 'both workspaces' in generate: sim.display(expanded='both') # show construction of rrg sim.offline.ts.init[initConf] = 1 if 'RRG construction' in generate: sim.config['global-ts-color'] = { 'node_color': 'blue', 'edge_color': 'black' } sim.config['video-interval'] = 500 sim.config['video-file'] = 'rrg_construction.mp4' sim.save_rrg_process(rrg_data) # reset to default colors sim.defaultConfiguration(reset=['global-ts-color']) if 'RRG iterations' in generate: sim.config['global-ts-color'] = { 'node_color': 'blue', 'edge_color': 'black' } rrg_iterations = [ i + (i == -1) * (len(rrg_data) + 1) for i in rrg_iterations ] sim.save_rrg_iterations(rrg_data, rrg_iterations) # reset to default colors sim.defaultConfiguration(reset=['global-ts-color']) # set to global and to save animation sim.offline.ts = Ts.load(ts_filename) print 'TS size', sim.offline.ts.size() if 'offline plan' in generate: sim.config['video-interval'] = 30 sim.config['sim-step'] = 0.02 sim.config['video-file'] = 'global_plan.mp4' sim.simulate(loops=1, offline=True) sim.play(output='video', show=False) sim.save() # get online trajectory sim.offline.ts = Ts.load(ts_filename) trajectory = [d['new configuration'] for d in rrt_data] local_plans = [d['local plan'] for d in rrt_data] + [[]] potential = [d['potential'] for d in rrt_data] + [0] requests = [d['requests'] for d in rrt_data] + [[]] print len(trajectory), len(local_plans) if 'trajectory' in generate: # set larger font for saving figures for r in sim.workspace.regions | sim.expandedWorkspace.regions: r.fontsize_orig = r.textStyle.get('fontsize', 12) r.textStyle['fontsize'] = 24 sim.config['trajectory-min-transparency'] = 0.2 # fading sim.config['trajectory-history-length'] = len( trajectory) # full history sim.config['global-policy-color'] = 'orange' sim.online = LocalPlanner(None, sim.offline.ts, robot, localSpec) sim.online.trajectory = trajectory sim.online.robot.sensor.requests = [] sim.display(expanded=True, solution=prefix + suffix[1:], show_robot=False, localinfo=('trajectory', ), save='trajectory.png') sim.defaultConfiguration(reset=[ 'trajectory-min-transparency', 'trajectory-history-length', 'global-policy-color' ]) # restore original fontsize for r in sim.workspace.regions: r.textStyle['fontsize'] = r.fontsize_orig del r.fontsize_orig # local plan visualization sim.online = LocalPlanner(None, sim.offline.ts, robot, localSpec) sim.online.trajectory = trajectory if 'online plan' in generate: sim.config['video-interval'] = 30 sim.config['sim-step'] = 0.01 sim.config['video-file'] = 'local_plan.mp4' sim.simulate(offline=False) sim.play(output='video', show=False, localinfo={ 'trajectory': trajectory, 'plans': local_plans, 'potential': potential, 'requests': requests }) sim.save() if 'online trajectory iterations' in generate: sim.config['sim-step'] = 0.05 sim.config['trajectory-min-transparency'] = 1.0 # no fading sim.config['trajectory-history-length'] = 100000 # entire history sim.config['image-file-template'] = 'local_trajectory_{frame:04d}.png' sim.config['global-policy-color'] = 'orange' # simulate and save sim.simulate(offline=False) sim.play(output='plots', show=False, localinfo={ 'trajectory': trajectory, 'plans': local_plans, 'potential': potential, 'requests': requests }) sim.save(output='plots', frames=local_traj_iterations) # set initial values sim.defaultConfiguration(reset=[ 'trajectory-min-transparency', 'trajectory-history-length', 'image-file-template', 'global-policy-color' ]) msize = np.mean([d['tree size'] for d in rrt_data if d['tree size'] > 0]) print 'Mean size:', msize for k, d in enumerate(rrt_data): if d['tree size'] > 0: print(k, d['tree size']) if any(option in generate for option in ('LTS iterations', 'LTS construction')): idx = lts_index print rrt_data[idx]['tree size'] print 'current state:', rrt_data[idx - 1]['new configuration'] lts_data = sorted([ v for k, v in rrt_data[idx].items() if str(k).startswith('lts iteration') ], key=lambda x: x[0]) # print lts_data sim.online.lts = Ts(directed=True, multi=False) sim.online.lts.init[rrt_data[idx - 1]['new configuration']] = 1 # reset and fast-forward requests' locations for r in sim.robot.sensor.all_requests: aux = it.cycle(r.region.original_path) for _ in range(idx - 1): r.region.translate(next(aux)) sim.robot.sensor.requests = [ r for r in sim.robot.sensor.all_requests if r in rrt_data[idx]['requests'] ] if 'LTS construction' in generate: sim.config['video-interval'] = 500 sim.config['video-file'] = 'lts_construction.mp4' sim.save_lts_process(lts_data, endframe_hold=20) if 'LTS iterations' in generate: lts_iterations = [ i + (i == -1) * len(lts_data) for i in lts_iterations ] sim.save_lts_iterations(lts_data, lts_iterations) if 'LTS statistics' in generate: metrics = [('tree size', True), ('local planning runtime', False), ('local planning execution', False)] rrt_data = rrt_data[1:] # NOTE: This is for compatibility with the Cozmo logs if 'local planning execution' not in rrt_data[0]: for d in rrt_data: duration = (d['plan stop time'] - d['plan start time']) * 1000 d['local planning execution'] = duration data = [len(d['requests']) for d in rrt_data] serviced = sum(n1 - n2 for n1, n2 in it.izip(data, data[1:]) if n1 > n2) with open(os.path.join(outdir, 'local_performance_stats.txt'), 'w') as f: print >> f, 'no trials:', len(rrt_data) print >> f, 'no requests serviced', serviced ops = [np.mean, np.min, np.max, np.std] for key, positive in metrics: if positive: print >> f, key, [ op([ trial[key] for trial in rrt_data if trial[key] > 0 ]) for op in ops ] else: print >> f, key, [ op([trial[key] for trial in rrt_data]) for op in ops ]
def main(): Rho = namedtuple('Rho', ['lower', 'upper']) rhos = [Rho(lower=0.98, upper=1.04), Rho(lower=0.98, upper=1.04)] # # Case Study 1 # with Timer('IJRR 2013 Case-Study 1'): # r1 = Ts.load('./robot_1.yaml') # r2 = Ts.load('./robot_2.yaml') # ts_tuple = (r1, r2) # formula = ('[]<>gather && [](r1gather -> X(!r1gather U r1upload)) ' # '&& [](r2gather -> X(!r2gather U r2upload))') # opt_prop = set(['gather']) # logger.info('Formula: %s', formula) # logger.info('opt_prop: %s', opt_prop) # prefix_length, prefixes, suffix_cycle_cost, suffix_cycles = \ # lomap.multi_agent_optimal_run(ts_tuple, formula, opt_prop) # logger.info('Cost: %d', suffix_cycle_cost) # logger.info('Prefix length: %d', prefix_length) # # Find the controls that will produce this run # control_prefixes = [] # control_suffix_cycles = [] # for i in range(0, len(ts_tuple)): # ts = ts_tuple[i] # control_prefixes.append(ts.controls_from_run(prefixes[i])) # control_suffix_cycles.append(ts.controls_from_run(suffix_cycles[i])) # logger.info('%s run prefix: %s', ts.name, prefixes[i]) # logger.info('%s control perfix: %s', ts.name, control_prefixes[i]) # logger.info('%s suffix cycle: %s', ts.name, suffix_cycles[i]) # logger.info('%s control suffix cycle: %s', ts.name, # control_suffix_cycles[i]) # # logger.info('<><><> <><><> <><><>') # Case Study 2 with Timer('IJRR 2013 Case-Study 2'): r1 = Ts.load('./robot_1.yaml') r2 = Ts.load('./robot_2.yaml') ts_tuple = (r1, r2) formula = ('[]<>gather && [](gather->(r1gather && r2gather)) ' '&& [](r1gather -> X(!r1gather U r1upload)) ' '&& [](r2gather -> X(!r2gather U r2upload))') opt_prop = set(['r1gather','r2gather']) logger.info('Formula: %s', formula) logger.info('opt_prop: %s', opt_prop) prefix_length, prefixes, suffix_cycle_cost, suffix_cycles = \ lomap.robust_multi_agent_optimal_run(ts_tuple, rhos, formula, opt_prop) logger.info('Cost: %d', suffix_cycle_cost) logger.info('Prefix length: %d', prefix_length) # Find the controls that will produce this run control_prefixes = [] control_suffix_cycles = [] for i in range(0, len(ts_tuple)): ts = ts_tuple[i] control_prefixes.append(ts.controls_from_run(prefixes[i])) control_suffix_cycles.append(ts.controls_from_run(suffix_cycles[i])) logger.info('%s run prefix: %s', ts.name, prefixes[i]) logger.info('%s control perfix: %s', ts.name, control_prefixes[i]) logger.info('%s suffix cycle: %s', ts.name, suffix_cycles[i]) logger.info('%s control suffix cycle: %s', ts.name, control_suffix_cycles[i]) logger.info('<><><> <><><> <><><>') # Case Study 3 with Timer('IJRR 2013 Case-Study 3'): r1 = Ts.load('./robot_1.yaml') r2 = Ts.load('./robot_2.yaml') ts_tuple = (r1, r2) formula = ('[]<>gather && [](gather->(r1gather && r2gather)) ' '&& [](r1gather -> X(!r1gather U r1upload)) ' '&& [](r2gather -> X(!r2gather U r2upload)) ' '&& [](!(r1gather1 && r2gather1) && !(r1gather2 && r2gather2)' '&& !(r1gather3 && r2gather3) && !(r1gather4 && r2gather4))') opt_prop = set(['r1gather','r2gather']) logger.info('Formula: %s', formula) logger.info('opt_prop: %s', opt_prop) prefix_length, prefixes, suffix_cycle_cost, suffix_cycles = \ lomap.robust_multi_agent_optimal_run(ts_tuple, rhos, formula, opt_prop) logger.info('Cost: %d', suffix_cycle_cost) logger.info('Prefix length: %d', prefix_length) # Find the controls that will produce this run control_prefixes = [] control_suffix_cycles = [] for i in range(0, len(ts_tuple)): ts = ts_tuple[i] control_prefixes.append(ts.controls_from_run(prefixes[i])) control_suffix_cycles.append(ts.controls_from_run(suffix_cycles[i])) logger.info('%s run prefix: %s', ts.name, prefixes[i]) logger.info('%s control perfix: %s', ts.name, control_prefixes[i]) logger.info('%s suffix cycle: %s', ts.name, suffix_cycles[i]) logger.info('%s control suffix cycle: %s', ts.name, control_suffix_cycles[i]) logger.info('<><><> <><><> <><><>') # Case Study 4 with Timer('IJRR 2013 Case-Study 4'): r1 = Ts.load('./robot_1.yaml') r2 = Ts.load('./robot_2.yaml') ts_tuple = (r1, r2) formula = ('[]<>gather && [](gather->(r1gather4 && r2gather2)) ' '&& [](r1gather -> X(!r1gather U r1upload)) ' '&& [](r2gather -> X(!r2gather U r2upload))') opt_prop = set(['r1gather4','r2gather2']) logger.info('Formula: %s', formula) logger.info('opt_prop: %s', opt_prop) prefix_length, prefixes, suffix_cycle_cost, suffix_cycles = \ lomap.multi_agent_optimal_run(ts_tuple, formula, opt_prop) logger.info('Cost: %d', suffix_cycle_cost) logger.info('Prefix length: %d', prefix_length) # Find the controls that will produce this run control_prefixes = [] control_suffix_cycles = [] for i in range(0, len(ts_tuple)): ts = ts_tuple[i] control_prefixes.append(ts.controls_from_run(prefixes[i])) control_suffix_cycles.append(ts.controls_from_run(suffix_cycles[i])) logger.info('%s run prefix: %s', ts.name, prefixes[i]) logger.info('%s control perfix: %s', ts.name, control_prefixes[i]) logger.info('%s suffix cycle: %s', ts.name, suffix_cycles[i]) logger.info('%s control suffix cycle: %s', ts.name, control_suffix_cycles[i]) logger.info('<><><> <><><> <><><>') # Case Study 4 w/ sync with Timer('IJRR 2013 Case-Study 4 (w/ sync)'): r1 = Ts.load('./robot_1.yaml') r2 = Ts.load('./robot_2.yaml') ts_tuple = (r1, r2) formula = ('[]<>gather && [](gather->(r1gather4 && r2gather2)) ' '&& [](r1gather -> X(!r1gather U r1upload)) ' '&& [](r2gather -> X(!r2gather U r2upload))') opt_prop = set(['r1gather4','r2gather2']) logger.info('Formula: %s', formula) logger.info('opt_prop: %s', opt_prop) prefix_length, prefixes, suffix_cycle_cost, suffix_cycles = \ lomap.robust_multi_agent_optimal_run(ts_tuple, rhos, formula, opt_prop) logger.info('Cost: %d', suffix_cycle_cost) logger.info('Prefix length: %d', prefix_length) # Find the controls that will produce this run control_prefixes = [] control_suffix_cycles = [] for i in range(0, len(ts_tuple)): ts = ts_tuple[i] control_prefixes.append(ts.controls_from_run(prefixes[i])) control_suffix_cycles.append(ts.controls_from_run(suffix_cycles[i])) logger.info('%s run prefix: %s', ts.name, prefixes[i]) logger.info('%s control perfix: %s', ts.name, control_prefixes[i]) logger.info('%s suffix cycle: %s', ts.name, suffix_cycles[i]) logger.info('%s control suffix cycle: %s', ts.name, control_suffix_cycles[i])