示例#1
0
def main(cie, log_dir, attempts):
    config_ = env_as_yaml('experiment_manager_parameters')
    logger.info('parameters:\n\n%s' % config_)
    config = cast(MyConfig, ipce_to_object(config_, {}, expect_type=MyConfig))

    # first open all fifos
    agent_ci = ComponentInterface(config.agent_in, config.agent_out,
                                  expect_protocol=protocol_agent, nickname="agent")
    agents = [agent_ci]
    sim_ci = ComponentInterface(config.sim_in, config.sim_out,
                                expect_protocol=protocol_simulator, nickname="simulator")
    sm_ci = ComponentInterface(config.sm_in, config.sm_out,
                               expect_protocol=protocol_scenario_maker, nickname="scenario_maker")

    # then check compatibility
    # so that everything fails gracefully in case of error
    timeout_initialization = 20
    agent_ci._get_node_protocol(timeout=timeout_initialization)
    sm_ci._get_node_protocol(timeout=timeout_initialization)
    sim_ci._get_node_protocol(timeout=timeout_initialization)

    check_compatibility_between_agent_and_sim(agent_ci, sim_ci)

    attempt_i = 0
    per_episode = {}
    stats = {}
    try:

        nfailures = 0

        sim_ci.write('seed', config.seed)
        agent_ci.write('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", 5):
                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')
                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:\n%s' % 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)))
示例#2
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.')