Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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.')
Ejemplo n.º 6
0
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.')
Ejemplo n.º 7
0
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)))