def set_options_from_args(self, args: List[str]): """ Reads the configuration from command line arguments. raises: UserError: Wrong configuration, user's mistake. Exception: all other exceptions """ cls = type(self) prog = cls.get_prog_name() params = DecentParams() self.define_program_options(params) try: usage = cls.get_usage() if usage: usage = usage.replace('%prog', prog) desc = cls.get_program_description() epilog = cls.get_epilog() self.options = \ params.get_dpr_from_args(prog=prog, args=args, usage=usage, description=desc, epilog=epilog) except UserError: raise except Exception as e: msg = 'Could not interpret:\n' msg += ' args = %s\n' % args msg += 'according to params spec:\n' msg += indent(str(params), '| ') + '\n' msg += 'Error is:\n' msg += indent(traceback.format_exc(), '> ') raise Exception(msg) # XXX class
def set_options_from_dict(self, config: Dict[str, Any]): """ Reads the configuration from a dictionary. raises: UserError: Wrong configuration, user's mistake. Exception: all other exceptions """ params = DecentParams() self.define_program_options(params) try: self.options = params.get_dpr_from_dict(config) except DecentParamsUserError as e: raise QuickAppException(str(e)) except Exception as e: msg = 'Could not interpret:\n' msg += indent(pformat(config), '| ') msg += 'according to params spec:\n' msg += indent(str(params), '| ') + '\n' msg += 'Error is:\n' # if isinstance(e, DecentParamsUserError): # msg += indent(str(e), '> ') # else: msg += indent(traceback.format_exc(), '> ') raise QuickAppException(msg) # XXX class
def get_object_tree( po: PlacedObject, levels: int = 100, spatial_relations: bool = False, attributes: bool = False, ) -> str: ss = [] ss.append("%s" % type(po).__name__) d = po.params_to_json_dict() d.pop("children", None) d.pop("spatial_relations", None) if attributes: if d: ds = yaml.safe_dump( d, encoding="utf-8", indent=4, allow_unicode=True, default_flow_style=False, ) if isinstance(ds, bytes): ds = ds.decode("utf-8") ss.append("\n" + indent(ds, " ")) if po.children and levels >= 1: ss.append("") N = len(po.children) for i, (child_name, child) in enumerate(po.children.items()): if i != N - 1: prefix1 = "├ %s ┐ " % child_name prefix2 = "│ %s │ " % (" " * len(child_name)) else: prefix1 = "└ %s ┐ " % child_name prefix2 = " %s │ " % (" " * len(child_name)) c = get_object_tree( child, attributes=attributes, spatial_relations=spatial_relations, levels=levels - 1, ) sc = indent(c, prefix2, prefix1) n = max(len(_) for _ in sc.split("\n")) sc += "\n" + prefix2[:-2] + "└" + "─" * (n - len(prefix2) + 3) ss.append(sc) if spatial_relations: if po.spatial_relations and levels >= 1: ss.append("") for r_name, rel in po.spatial_relations.items(): ss.append( '- from "%s" to "%s" %s ' % (url_from_fqn(rel.a), url_from_fqn(rel.b), rel.transform)) return "\n".join(ss)
def wrap_config_reader2(f, cls, data: dict, *args, **kwargs): """Decorator for a function that takes a (clsname, dict)""" # def f2(x, *args, **kwargs): if not isinstance(data, dict): msg = "Expected dict" raise ZValueError(msg, data=data) def write(d: dict): assert isinstance(d, dict) # noinspection PyBroadException try: return json.dumps(d, indent=4) except: # try: # return safe_yaml_dump(d, default_flow_style=False).encode('utf-8') # except: return str(d) data2 = dict(**data) try: res = f(cls, data2, *args, **kwargs) except KeyError as e: msg = "Could not interpret the configuration data using %s:%s()" % ( cls.__name__, f.__name__, ) msg += '\nMissing configuration "%s". Specified: %s' % (e.args, list(data)) msg += "\n\n" + indent(write(data), " > ") + "\n" raise InvalidConfiguration(msg) from e except InvalidConfiguration as e: msg = "Could not interpret the configuration data using %s:%s()" % ( cls.__name__, f.__name__, ) msg += "\n\n" + indent(write(data), " > ") + "\n" raise InvalidConfiguration(msg) from e except BaseException as e: msg = "Could not interpret the configuration data using %s:%s()" % ( cls.__name__, f.__name__, ) msg += "\n\n" + indent(write(data), " > ") + "\n" # raise_wrapped(InvalidConfiguration, e, msg, compact=False) raise InvalidConfiguration(msg) from e # # if data2: # msg = "Unused fields %s " % list(data2) # msg += "\n\n" + indent(write(data), " > ") # raise InvalidConfiguration(msg) return res
def main(): # Set in the docker-compose env section config_ = env_as_yaml('middleware_parameters') logger.info('parameters:\n\n%s' % config_) config = cast(MyConfig, object_from_ipce(config_, MyConfig)) # first open all fifos logger.info("Opening the sim CI") sim_ci = ComponentInterface(config.sim_in, config.sim_out, expect_protocol=protocol_simulator, nickname="simulator", timeout=config.timeout_regular) logger.info("Pipes connected to simulator") logger.info("Opening the agent CI") agent_ci = ComponentInterface(config.agent_in, config.agent_out, expect_protocol=protocol_agent, nickname="agent", timeout=config.timeout_regular) logger.info("Pipes connected to agent") agents = [agent_ci] # We enable CC of the pipes for debugging if logger.level < logging.DEBUG: logfile = "/fifos/agentlog" logfile2 = "/fifos/simlog" ff = open(logfile, "wb") ff2 = open(logfile, "wb") agent_ci.cc(ff) sim_ci.cc(ff2) logger.info(f"opened {logfile} as agent cc") logger.info(f"opened {logfile2} as sim cc") # then check compatibility # so that everything fails gracefully in case of error logger.info("Checking sim protocol compatibility...") sim_ci._get_node_protocol(timeout=config.timeout_initialization) logger.info( "Sim protocol compatible, checking agent protocol compatibility...") agent_ci._get_node_protocol(timeout=config.timeout_initialization) logger.info("Acquired nodes protocols") check_compatibility_between_agent_and_sim(agent_ci, sim_ci) logger.info("Compatibility verified.") attempt_i = 0 ep = 0 try: nfailures = 0 logger.info("Sending seed to sim") sim_ci.write_topic_and_expect_zero('seed', config.seed) logger.info("Sending seed to agent") agent_ci.write_topic_and_expect_zero('seed', config.seed) logger.info("Received feedback from peer containers") # TODO we should have a proper handling of invalid map name map_name = os.environ.get('MAP_NAME', 'loop_empty') yaml_string: str = _get_map_yaml(map_name) yaml_data = yaml.load(yaml_string, Loader=yaml.SafeLoader) placed_obj = construct_map(yaml_data) pose = sample_good_starting_pose(placed_obj, only_straight=True) vel = geometry.se2_from_linear_angular([0, 0], 0) logger.info(f"Got good starting pose at: {pose}") robot1_config = RobotConfiguration(pose=pose, velocity=vel) robot1 = ScenarioRobotSpec(description="Development agent", playable=True, configuration=robot1_config, motion=None) scenario1 = Scenario("scenario1", environment=yaml_string, robots={"agent1": robot1}) unique_episode = EpisodeSpec("episode1", scenario1) episodes = [unique_episode] # Since we dont have a scenario maker, we will loop the episode (for now) while episodes: if nfailures >= config.max_failures: msg = 'Too many failures: %s' % nfailures raise Exception(msg) # XXX episode_spec = episodes[0] episode_name = episode_spec.episode_name ep += 1 episode_name = f'episode_{ep}' logger.info(f'Starting {episode_name}') # dn_final = os.path.join(log_dir, episode_name) # if os.path.exists(dn_final): # shutil.rmtree(dn_final) # dn = os.path.join(attempts, episode_name + '.attempt%s' % attempt_i) # if os.path.exists(dn): # shutil.rmtree(dn) # if not os.path.exists(dn): # os.makedirs(dn) # fn = os.path.join(dn, 'log.gs2.cbor') # fn_tmp = fn + '.tmp' # fw = open(fn_tmp, 'wb') # agent_ci.cc(fw) # sim_ci.cc(fw) logger.info('Now running episode') num_playable = len([ _ for _ in episode_spec.scenario.robots.values() if _.playable ]) if num_playable != len(agents): msg = f'The scenario requires {num_playable} robots, but I only know {len(agents)} agents.' raise Exception(msg) # XXX try: length_s = run_episode( sim_ci, agents, episode_name=episode_name, scenario=episode_spec.scenario, episode_length_s=config.episode_length_s, physics_dt=config.physics_dt) logger.info('Finished episode %s' % episode_name) except: msg = 'Anomalous error from run_episode():\n%s' % traceback.format_exc( ) logger.error(msg) raise # finally: # fw.close() # os.rename(fn_tmp, fn) # output = os.path.join(dn, 'visualization') # logger.info('Now creating visualization and analyzing statistics.') # logger.warning('This might take a LONG time.') # # with notice_thread("Visualization", 2): # evaluated = read_and_draw(fn, dn) # logger.info('Finally visualization is done.') # stats = {} # for k, evr in evaluated.items(): # assert isinstance(evr, RuleEvaluationResult) # for m, em in evr.metrics.items(): # assert isinstance(em, EvaluatedMetric) # assert isinstance(m, tuple) # if m: # M = "/".join(m) # else: # M = k # stats[M] = float(em.total) # per_episode[episode_name] = stats if length_s >= config.min_episode_length_s: logger.info('%1.f s are enough' % length_s) # episodes.pop(0) #@ We dont pop the episode, run in loop # out_video = os.path.join(dn, 'camera.mp4') # with notice_thread("Make video", 2): # make_video1(fn, out_video) # os.rename(dn, dn_final) else: logger.error('episode too short with %1.f s < %.1f s' % (length_s, config.min_episode_length_s)) nfailures += 1 attempt_i += 1 except dc.InvalidSubmission: raise except BaseException as e: msg = 'Anomalous error while running episodes:' msg += '\n\n' + indent(traceback.format_exc(), ' > ') logger.error(msg) raise dc.InvalidEvaluator(msg) from e finally: agent_ci.close() sim_ci.close() logger.info('Simulation done.')
def main(): # Set in the docker-compose env section config_ = env_as_yaml('middleware_parameters') logger.info('parameters:\n\n%s' % config_) config = cast(MyConfig, object_from_ipce(config_, MyConfig)) # first open all fifos logger.info("Opening the sim CI") sim_ci = ComponentInterface(config.sim_in, config.sim_out, expect_protocol=protocol_simulator, nickname="simulator", timeout=config.timeout_regular) #logfile = "/fifos3/simlog" #ff = open(logfile,"wb") #sim_ci.cc(ff) #logger.info(f"opened {logfile} as cc") logger.info("Opening the agent CI") #agent_ci = ComponentInterface(config.agent_in, config.agent_out, # expect_protocol=protocol_agent, nickname="agent", # timeout=config.timeout_regular) #agents = [agent_ci] # sm_ci = ComponentInterface(config.sm_in, config.sm_out, # expect_protocol=protocol_scenario_maker, nickname="scenario_maker", # timeout=config.timeout_regular) # then check compatibility # so that everything fails gracefully in case of error # sm_ci._get_node_protocol(timeout=config.timeout_initialization) logger.info("Checking sim protocol compatibility") sim_ci._get_node_protocol(timeout=config.timeout_initialization) logger.info(">Verified sim_ci compatibility, pipes are connected !") logger.info("Checking agent protocol compatibility") agent_ci._get_node_protocol(timeout=config.timeout_initialization) logger.info("Acquired node protocol") check_compatibility_between_agent_and_sim(agent_ci, sim_ci) logger.info("Compatibility verified.") attempt_i = 0 # per_episode = {} # stats = {} quit_loop = False ep = 0 try: nfailures = 0 logger.info("Sending seed to sim") sim_ci.write_topic_and_expect_zero('seed', config.seed) logger.info("Sending seed to agent") agent_ci.write_topic_and_expect_zero('seed', config.seed) logger.info("Received feedback from peer containers") # TODO this should be in docker-compose or yaml map_name = "loop_empty" robot1_config = RobotConfiguration(pose=0.0, velocity=0.0) robot1 = ScenarioRobotSpec(description="Development agent", playable=True, configuration=robot1_config) environment1 = _get_map_yaml(map_name) scenario1 = Scenario("scenario1", environment=environment1, robots={"agent1": robot1}) unique_episode = EpisodeSpec("episode1", scenario1) # episodes = get_episodes(sm_ci, episodes_per_scenario=config.episodes_per_scenario, # seed=config.seed) episodes = [unique_episode] # while episodes: while episodes: if nfailures >= config.max_failures: msg = 'Too many failures: %s' % nfailures raise Exception(msg) # XXX episode_spec = episodes[0] episode_name = episode_spec.episode_name ep += 1 episode_name = f'episode_{ep}' logger.info('Starting episode 1') #dn_final = os.path.join(log_dir, episode_name) #if os.path.exists(dn_final): # shutil.rmtree(dn_final) #dn = os.path.join(attempts, episode_name + '.attempt%s' % attempt_i) #if os.path.exists(dn): # shutil.rmtree(dn) #if not os.path.exists(dn): # os.makedirs(dn) #fn = os.path.join(dn, 'log.gs2.cbor') #fn_tmp = fn + '.tmp' #fw = open(fn_tmp, 'wb') #agent_ci.cc(fw) #sim_ci.cc(fw) logger.info('Now running episode') num_playable = len([ _ for _ in episode_spec.scenario.robots.values() if _.playable ]) if num_playable != len(agents): msg = f'The scenario requires {num_playable} robots, but I only know {len(agents)} agents.' raise Exception(msg) # XXX try: length_s = run_episode( sim_ci, agents, episode_name=episode_name, scenario=episode_spec.scenario, episode_length_s=config.episode_length_s, physics_dt=config.physics_dt) logger.info('Finished episode %s' % episode_name) except: msg = 'Anomalous error from run_episode():\n%s' % traceback.format_exc( ) logger.error(msg) raise finally: fw.close() os.rename(fn_tmp, fn) # output = os.path.join(dn, 'visualization') # logger.info('Now creating visualization and analyzing statistics.') # logger.warning('This might take a LONG time.') # # with notice_thread("Visualization", 2): # evaluated = read_and_draw(fn, dn) # logger.info('Finally visualization is done.') # stats = {} # for k, evr in evaluated.items(): # assert isinstance(evr, RuleEvaluationResult) # for m, em in evr.metrics.items(): # assert isinstance(em, EvaluatedMetric) # assert isinstance(m, tuple) # if m: # M = "/".join(m) # else: # M = k # stats[M] = float(em.total) # per_episode[episode_name] = stats if length_s >= config.min_episode_length_s: logger.info('%1.f s are enough' % length_s) # episodes.pop(0) #@ We dont pop the episode, run in loop # out_video = os.path.join(dn, 'camera.mp4') # with notice_thread("Make video", 2): # make_video1(fn, out_video) os.rename(dn, dn_final) else: logger.error('episode too short with %1.f s < %.1f s' % (length_s, config.min_episode_length_s)) nfailures += 1 attempt_i += 1 except dc.InvalidSubmission: raise except BaseException as e: msg = 'Anomalous error while running episodes:' msg += '\n\n' + indent(traceback.format_exc(), ' > ') logger.error(msg) raise dc.InvalidEvaluator(msg) from e finally: agent_ci.close() sim_ci.close() logger.info('Simulation done.')
def main(cie, log_dir, attempts): config_ = env_as_yaml('experiment_manager_parameters') logger.info('parameters:\n\n%s' % config_) config = cast(MyConfig, object_from_ipce(config_, MyConfig)) # first open all fifos agent_ci = ComponentInterface(config.agent_in, config.agent_out, expect_protocol=protocol_agent, nickname="agent", timeout=config.timeout_regular) agents = [agent_ci] sim_ci = ComponentInterface(config.sim_in, config.sim_out, expect_protocol=protocol_simulator, nickname="simulator", timeout=config.timeout_regular) sm_ci = ComponentInterface(config.sm_in, config.sm_out, expect_protocol=protocol_scenario_maker, nickname="scenario_maker", timeout=config.timeout_regular) # then check compatibility # so that everything fails gracefully in case of error sm_ci._get_node_protocol(timeout=config.timeout_initialization) sim_ci._get_node_protocol(timeout=config.timeout_initialization) agent_ci._get_node_protocol(timeout=config.timeout_initialization) check_compatibility_between_agent_and_sim(agent_ci, sim_ci) attempt_i = 0 per_episode = {} stats = {} try: nfailures = 0 sim_ci.write_topic_and_expect_zero('seed', config.seed) agent_ci.write_topic_and_expect_zero('seed', config.seed) episodes = get_episodes( sm_ci, episodes_per_scenario=config.episodes_per_scenario, seed=config.seed) while episodes: if nfailures >= config.max_failures: msg = 'Too many failures: %s' % nfailures raise Exception(msg) # XXX episode_spec = episodes[0] episode_name = episode_spec.episode_name logger.info('Starting episode %s' % episode_name) dn_final = os.path.join(log_dir, episode_name) if os.path.exists(dn_final): shutil.rmtree(dn_final) dn = os.path.join(attempts, episode_name + '.attempt%s' % attempt_i) if os.path.exists(dn): shutil.rmtree(dn) if not os.path.exists(dn): os.makedirs(dn) fn = os.path.join(dn, 'log.gs2.cbor') fn_tmp = fn + '.tmp' fw = open(fn_tmp, 'wb') agent_ci.cc(fw) sim_ci.cc(fw) logger.info('Now running episode') num_playable = len([ _ for _ in episode_spec.scenario.robots.values() if _.playable ]) if num_playable != len(agents): msg = f'The scenario requires {num_playable} robots, but I only know {len(agents)} agents.' raise Exception(msg) # XXX try: length_s = run_episode( sim_ci, agents, episode_name=episode_name, scenario=episode_spec.scenario, episode_length_s=config.episode_length_s, physics_dt=config.physics_dt) logger.info('Finished episode %s' % episode_name) except: msg = 'Anomalous error from run_episode():\n%s' % traceback.format_exc( ) logger.error(msg) raise finally: fw.close() os.rename(fn_tmp, fn) # output = os.path.join(dn, 'visualization') logger.info('Now creating visualization and analyzing statistics.') logger.warning('This might take a LONG time.') with notice_thread("Visualization", 2): evaluated = read_and_draw(fn, dn) logger.info('Finally visualization is done.') stats = {} for k, evr in evaluated.items(): assert isinstance(evr, RuleEvaluationResult) for m, em in evr.metrics.items(): assert isinstance(em, EvaluatedMetric) assert isinstance(m, tuple) if m: M = "/".join(m) else: M = k stats[M] = float(em.total) per_episode[episode_name] = stats if length_s >= config.min_episode_length_s: logger.info('%1.f s are enough' % length_s) episodes.pop(0) out_video = os.path.join(dn, 'camera.mp4') with notice_thread("Make video", 2): make_video1(fn, out_video) os.rename(dn, dn_final) else: logger.error('episode too short with %1.f s < %.1f s' % (length_s, config.min_episode_length_s)) nfailures += 1 attempt_i += 1 except dc.InvalidSubmission: raise except BaseException as e: msg = 'Anomalous error while running episodes:' msg += '\n\n' + indent(traceback.format_exc(), ' > ') logger.error(msg) raise dc.InvalidEvaluator(msg) from e finally: agent_ci.close() sim_ci.close() logger.info('Simulation done.') cie.set_score('per-episodes', per_episode) for k in list(stats): values = [_[k] for _ in per_episode.values()] cie.set_score('%s_mean' % k, float(np.mean(values))) cie.set_score('%s_median' % k, float(np.median(values))) cie.set_score('%s_min' % k, float(np.min(values))) cie.set_score('%s_max' % k, float(np.max(values)))