def start_race(self):
        """
        Start the race (evaluation) for the current racer.
        """
        LOG.info(
            "[virtual event manager] Starting race for racer %s", self._current_racer.racerAlias
        )
        # update the car on current model if does not use f1 or tron type of shell
        if const.F1 not in self._body_shell_type.lower():
            self._model_updater.update_model_color(
                self._current_car_model_state.model_name, self._current_racer.carConfig.carColor
            )
        # send request
        if self._is_save_mp4_enabled:
            self._subscribe_to_save_mp4(
                VirtualEventVideoEditSrvRequest(
                    display_name=self._current_racer.racerAlias,
                    racecar_color=self._current_racer.carConfig.carColor,
                )
            )

        # Update CameraManager by adding cameras into the current namespace. By doing so
        # a single follow car camera will follow the current active racecar.
        self._camera_manager.add(
            self._main_cameras[VIRTUAL_EVENT], self._current_car_model_state.model_name
        )
        self._camera_manager.add(self._sub_camera, self._current_car_model_state.model_name)

        configure_environment_randomizer()
        # strip index for park position
        self._park_position_idx = get_racecar_idx(self._current_car_model_state.model_name)
        # set the park position in track and do evaluation
        # Before each evaluation episode (single lap for non-continuous race and complete race for
        # continuous race), a new copy of park_positions needs to be loaded into track_data because
        # a park position will be pop from park_positions when a racer car need to be parked.
        # unpause the physics in current world
        self._model_updater.unpause_physics()
        LOG.info("[virtual event manager] Unpaused physics in current world.")
        if (
            self._prev_model_name is not None
            and self._prev_model_name != self._current_car_model_state.model_name
        ):
            # disable the links on the prev car
            # we are doing it here because we don't want the car to float around
            # after the link is disabled
            prev_car_model_state = ModelState()
            prev_car_model_state.model_name = self._prev_model_name
        LOG.info("[virtual event manager] Unpaused model for current car.")
        if self._is_continuous:
            self._track_data.park_positions = [self._park_positions[self._park_position_idx]]
            self._current_graph_manager.evaluate(EnvironmentSteps(1))
        else:
            for _ in range(self._number_of_trials):
                self._track_data.park_positions = [self._park_positions[self._park_position_idx]]
                self._current_graph_manager.evaluate(EnvironmentSteps(1))
Ejemplo n.º 2
0
    def start_race(self):
        """
            Start the race (evaluation) for the current racer.
        """
        LOG.info("[virtual event manager] Starting race for racer %s",
                 self._current_racer.racerAlias)
        # send request
        if self._is_save_mp4_enabled:
            # racecar_color is not used for virtual event image editing, so simply pass default "Black"
            self._subscribe_to_save_mp4(
                VirtualEventVideoEditSrvRequest(
                    display_name=self._current_racer.racerAlias,
                    racecar_color=DEFAULT_COLOR))

        configure_environment_randomizer()
        self._model_updater.unpause_physics()
        LOG.info("[virtual event manager] Unpaused physics in current world.")

        if self._is_continuous:
            self._evaluate()
        else:
            self._evaluate()
            for _ in range(self._number_of_trials - 1):
                self._current_graph_manager.evaluate(EnvironmentSteps(1))
def rollout_worker(graph_manager, num_workers, rollout_idx, task_parameters,
                   s3_writer):
    """
    wait for first checkpoint then perform rollouts using the model
    """
    if not graph_manager.data_store:
        raise AttributeError("None type for data_store object")

    data_store = graph_manager.data_store

    checkpoint_dir = task_parameters.checkpoint_restore_path
    wait_for_checkpoint(checkpoint_dir, data_store)
    wait_for_trainer_ready(checkpoint_dir, data_store)
    # Make the clients that will allow us to pause and unpause the physics
    rospy.wait_for_service('/gazebo/pause_physics')
    rospy.wait_for_service('/gazebo/unpause_physics')
    rospy.wait_for_service('/racecar/save_mp4/subscribe_to_save_mp4')
    rospy.wait_for_service('/racecar/save_mp4/unsubscribe_from_save_mp4')
    pause_physics = ServiceProxyWrapper('/gazebo/pause_physics', Empty)
    unpause_physics = ServiceProxyWrapper('/gazebo/unpause_physics', Empty)
    subscribe_to_save_mp4 = ServiceProxyWrapper(
        '/racecar/save_mp4/subscribe_to_save_mp4', Empty)
    unsubscribe_from_save_mp4 = ServiceProxyWrapper(
        '/racecar/save_mp4/unsubscribe_from_save_mp4', Empty)
    graph_manager.create_graph(task_parameters=task_parameters,
                               stop_physics=pause_physics,
                               start_physics=unpause_physics,
                               empty_service_call=EmptyRequest)

    chkpt_state_reader = CheckpointStateReader(checkpoint_dir,
                                               checkpoint_state_optional=False)
    last_checkpoint = chkpt_state_reader.get_latest().num

    # this worker should play a fraction of the total playing steps per rollout
    episode_steps_per_rollout = graph_manager.agent_params.algorithm.num_consecutive_playing_steps.num_steps
    act_steps = int(episode_steps_per_rollout / num_workers)
    if rollout_idx < episode_steps_per_rollout % num_workers:
        act_steps += 1
    act_steps = EnvironmentEpisodes(act_steps)

    configure_environment_randomizer()

    for _ in range(
        (graph_manager.improve_steps / act_steps.num_steps).num_steps):
        # Collect profiler information only IS_PROFILER_ON is true
        with utils.Profiler(s3_bucket=PROFILER_S3_BUCKET,
                            s3_prefix=PROFILER_S3_PREFIX,
                            output_local_path=ROLLOUT_WORKER_PROFILER_PATH,
                            enable_profiling=IS_PROFILER_ON):
            graph_manager.phase = RunPhase.TRAIN
            exit_if_trainer_done(checkpoint_dir, s3_writer, rollout_idx)
            unpause_physics(EmptyRequest())
            graph_manager.reset_internal_state(True)
            graph_manager.act(act_steps,
                              wait_for_full_episodes=graph_manager.
                              agent_params.algorithm.act_for_full_episodes)
            graph_manager.reset_internal_state(True)
            time.sleep(1)
            pause_physics(EmptyRequest())

            graph_manager.phase = RunPhase.UNDEFINED
            new_checkpoint = -1
            if graph_manager.agent_params.algorithm.distributed_coach_synchronization_type\
                    == DistributedCoachSynchronizationType.SYNC:
                unpause_physics(EmptyRequest())
                is_save_mp4_enabled = rospy.get_param(
                    'MP4_S3_BUCKET', None) and rollout_idx == 0
                if is_save_mp4_enabled:
                    subscribe_to_save_mp4(EmptyRequest())
                if rollout_idx == 0:
                    for _ in range(MIN_EVAL_TRIALS):
                        graph_manager.evaluate(EnvironmentSteps(1))

                while new_checkpoint < last_checkpoint + 1:
                    exit_if_trainer_done(checkpoint_dir, s3_writer,
                                         rollout_idx)
                    if rollout_idx == 0:
                        graph_manager.evaluate(EnvironmentSteps(1))
                    new_checkpoint = data_store.get_chkpoint_num('agent')
                if is_save_mp4_enabled:
                    unsubscribe_from_save_mp4(EmptyRequest())
                s3_writer.upload_to_s3()

                pause_physics(EmptyRequest())
                data_store.load_from_store(
                    expected_checkpoint_number=last_checkpoint + 1)
                graph_manager.restore_checkpoint()

            if graph_manager.agent_params.algorithm.distributed_coach_synchronization_type\
                    == DistributedCoachSynchronizationType.ASYNC:
                if new_checkpoint > last_checkpoint:
                    graph_manager.restore_checkpoint()

            last_checkpoint = new_checkpoint
def tournament_worker(graph_manager, number_of_trials, task_parameters,
                      s3_writers, is_continuous, park_positions):
    """ Tournament worker function

    Arguments:
        graph_manager(MultiAgentGraphManager): Graph manager of multiagent graph manager
        number_of_trials(int): Number of trails you want to run the evaluation
        task_parameters(TaskParameters): Information of the checkpoint, gpu/cpu,
            framework etc of rlcoach
        s3_writers(S3Writer): Information to upload to the S3 bucket all the simtrace and mp4
        is_continuous(bool): The termination condition for the car
        park_positions(list of tuple): list of (x, y) for cars to park at
    """
    # Collect profiler information only IS_PROFILER_ON is true
    with utils.Profiler(s3_bucket=PROFILER_S3_BUCKET,
                        s3_prefix=PROFILER_S3_PREFIX,
                        output_local_path=ROLLOUT_WORKER_PROFILER_PATH,
                        enable_profiling=IS_PROFILER_ON):
        checkpoint_dirs = list()
        agent_names = list()
        subscribe_to_save_mp4_topic, unsubscribe_from_save_mp4_topic = list(
        ), list()
        subscribe_to_save_mp4, unsubscribe_from_save_mp4 = list(), list()
        for agent_param in graph_manager.agents_params:
            _checkpoint_dir = task_parameters.checkpoint_restore_path if len(graph_manager.agents_params) == 1 \
                else os.path.join(task_parameters.checkpoint_restore_path, agent_param.name)
            agent_names.append(agent_param.name)
            checkpoint_dirs.append(_checkpoint_dir)
            racecar_name = 'racecar' if len(agent_param.name.split("_")) == 1 \
                                     else "racecar_{}".format(agent_param.name.split("_")[1])
            subscribe_to_save_mp4_topic.append(
                "/{}/save_mp4/subscribe_to_save_mp4".format(racecar_name))
            unsubscribe_from_save_mp4_topic.append(
                "/{}/save_mp4/unsubscribe_from_save_mp4".format(racecar_name))
        wait_for_checkpoints(checkpoint_dirs, graph_manager.data_store)
        modify_checkpoint_variables(checkpoint_dirs, agent_names)

        # Make the clients that will allow us to pause and unpause the physics
        rospy.wait_for_service('/gazebo/pause_physics')
        rospy.wait_for_service('/gazebo/unpause_physics')
        pause_physics = ServiceProxyWrapper('/gazebo/pause_physics', Empty)
        unpause_physics = ServiceProxyWrapper('/gazebo/unpause_physics', Empty)

        for mp4_sub, mp4_unsub in zip(subscribe_to_save_mp4_topic,
                                      unsubscribe_from_save_mp4_topic):
            rospy.wait_for_service(mp4_sub)
            rospy.wait_for_service(mp4_unsub)
        for mp4_sub, mp4_unsub in zip(subscribe_to_save_mp4_topic,
                                      unsubscribe_from_save_mp4_topic):
            subscribe_to_save_mp4.append(ServiceProxyWrapper(mp4_sub, Empty))
            unsubscribe_from_save_mp4.append(
                ServiceProxyWrapper(mp4_unsub, Empty))

        graph_manager.create_graph(task_parameters=task_parameters,
                                   stop_physics=pause_physics,
                                   start_physics=unpause_physics,
                                   empty_service_call=EmptyRequest)
        logger.info(
            "Graph manager successfully created the graph: Unpausing physics")
        unpause_physics(EmptyRequest())

        is_save_mp4_enabled = rospy.get_param('MP4_S3_BUCKET', None)
        if is_save_mp4_enabled:
            for subscribe_mp4 in subscribe_to_save_mp4:
                subscribe_mp4(EmptyRequest())

        configure_environment_randomizer()
        track_data = TrackData.get_instance()

        # Before each evaluation episode (single lap for non-continuous race and complete race for
        # continuous race), a new copy of park_positions needs to be loaded into track_data because
        # a park position will be pop from park_positions when a racer car need to be parked.
        if is_continuous:
            track_data.park_positions = park_positions
            graph_manager.evaluate(EnvironmentSteps(1))
        else:
            for _ in range(number_of_trials):
                track_data.park_positions = park_positions
                graph_manager.evaluate(EnvironmentSteps(1))
        if is_save_mp4_enabled:
            for unsubscribe_mp4 in unsubscribe_from_save_mp4:
                unsubscribe_mp4(EmptyRequest())
        for s3_writer in s3_writers:
            s3_writer.upload_to_s3()
        time.sleep(1)
        pause_physics(EmptyRequest())
def tournament_worker(graph_manager, number_of_trials, task_parameters,
                      s3_writers, is_continuous):
    """ Tournament worker function

    Arguments:
        graph_manager {[MultiAgentGraphManager]} -- [Graph manager of multiagent graph manager]
        number_of_trials {[int]} -- [Number of trails you want to run the evaluation]
        task_parameters {[TaskParameters]} -- [Information of the checkpoint, gpu/cpu, framework etc of rlcoach]
        s3_writers {[S3Writer]} -- [Information to upload to the S3 bucket all the simtrace and mp4]
        is_continuous {bool} -- [The termination condition for the car]
    """
    checkpoint_dirs = list()
    agent_names = list()
    subscribe_to_save_mp4_topic, unsubscribe_from_save_mp4_topic = list(
    ), list()
    subscribe_to_save_mp4, unsubscribe_from_save_mp4 = list(), list()
    for agent_param in graph_manager.agents_params:
        _checkpoint_dir = task_parameters.checkpoint_restore_path if len(graph_manager.agents_params) == 1 \
            else os.path.join(task_parameters.checkpoint_restore_path, agent_param.name)
        agent_names.append(agent_param.name)
        checkpoint_dirs.append(_checkpoint_dir)
        racecar_name = 'racecar' if len(agent_param.name.split("_")) == 1 \
            else "racecar_{}".format(agent_param.name.split("_")[1])
        subscribe_to_save_mp4_topic.append(
            "/{}/save_mp4/subscribe_to_save_mp4".format(racecar_name))
        unsubscribe_from_save_mp4_topic.append(
            "/{}/save_mp4/unsubscribe_from_save_mp4".format(racecar_name))
    wait_for_checkpoints(checkpoint_dirs, graph_manager.data_store)
    modify_checkpoint_variables(checkpoint_dirs, agent_names)

    # Make the clients that will allow us to pause and unpause the physics
    rospy.wait_for_service('/gazebo/pause_physics')
    rospy.wait_for_service('/gazebo/unpause_physics')
    pause_physics = ServiceProxyWrapper('/gazebo/pause_physics', Empty)
    unpause_physics = ServiceProxyWrapper('/gazebo/unpause_physics', Empty)

    for mp4_sub, mp4_unsub in zip(subscribe_to_save_mp4_topic,
                                  unsubscribe_from_save_mp4_topic):
        rospy.wait_for_service(mp4_sub)
        rospy.wait_for_service(mp4_unsub)
    for mp4_sub, mp4_unsub in zip(subscribe_to_save_mp4_topic,
                                  unsubscribe_from_save_mp4_topic):
        subscribe_to_save_mp4.append(ServiceProxyWrapper(mp4_sub, Empty))
        unsubscribe_from_save_mp4.append(ServiceProxyWrapper(mp4_unsub, Empty))

    graph_manager.create_graph(task_parameters=task_parameters,
                               stop_physics=pause_physics,
                               start_physics=unpause_physics,
                               empty_service_call=EmptyRequest)
    unpause_physics(EmptyRequest())

    is_save_mp4_enabled = rospy.get_param('MP4_S3_BUCKET', None)
    if is_save_mp4_enabled:
        for subscribe_mp4 in subscribe_to_save_mp4:
            subscribe_mp4(EmptyRequest())

    configure_environment_randomizer()

    if is_continuous:
        graph_manager.evaluate(EnvironmentSteps(1))
    else:
        for _ in range(number_of_trials):
            graph_manager.evaluate(EnvironmentSteps(1))
    if is_save_mp4_enabled:
        for unsubscribe_mp4 in unsubscribe_from_save_mp4:
            unsubscribe_mp4(EmptyRequest())
    for s3_writer in s3_writers:
        s3_writer.upload_to_s3()
    time.sleep(1)
    pause_physics(EmptyRequest())
Ejemplo n.º 6
0
def evaluation_worker(graph_manager, number_of_trials, task_parameters,
                      simtrace_video_s3_writers, is_continuous, park_positions,
                      race_type, pause_physics, unpause_physics):
    """ Evaluation worker function

    Arguments:
        graph_manager(MultiAgentGraphManager): Graph manager of multiagent graph manager
        number_of_trials(int): Number of trails you want to run the evaluation
        task_parameters(TaskParameters): Information of the checkpoint, gpu/cpu,
            framework etc of rlcoach
        simtrace_video_s3_writers(list): Information to upload to the S3 bucket all the simtrace and mp4
        is_continuous(bool): The termination condition for the car
        park_positions(list of tuple): list of (x, y) for cars to park at
        race_type (str): race type
    """
    # Collect profiler information only IS_PROFILER_ON is true
    with utils.Profiler(s3_bucket=PROFILER_S3_BUCKET,
                        s3_prefix=PROFILER_S3_PREFIX,
                        output_local_path=ROLLOUT_WORKER_PROFILER_PATH,
                        enable_profiling=IS_PROFILER_ON):
        subscribe_to_save_mp4_topic, unsubscribe_from_save_mp4_topic = list(
        ), list()
        subscribe_to_save_mp4, unsubscribe_from_save_mp4 = list(), list()
        for agent_param in graph_manager.agents_params:
            racecar_name = 'racecar' if len(agent_param.name.split("_")) == 1 \
                                     else "racecar_{}".format(agent_param.name.split("_")[1])
            subscribe_to_save_mp4_topic.append(
                "/{}/save_mp4/subscribe_to_save_mp4".format(racecar_name))
            unsubscribe_from_save_mp4_topic.append(
                "/{}/save_mp4/unsubscribe_from_save_mp4".format(racecar_name))
        graph_manager.data_store.wait_for_checkpoints()
        graph_manager.data_store.modify_checkpoint_variables()

        # wait for the required cancel services to become available
        if race_type != RaceType.F1.value:
            # TODO: Since we are not running Grand Prix in RoboMaker,
            # we are opting out from waiting for RoboMaker's cancel job service
            # in case of Grand Prix execution.
            # Otherwise, SimApp will hang as service will never come alive.
            #
            # If we don't depend on RoboMaker anymore in the future,
            # we need to remove below line, or do a better job to figure out
            # whether we are running on RoboMaker or not to decide whether
            # we should wait for below service or not.
            rospy.wait_for_service('/robomaker/job/cancel')

        # Make the clients that will allow us to pause and unpause the physics
        rospy.wait_for_service('/gazebo/pause_physics_dr')
        rospy.wait_for_service('/gazebo/unpause_physics_dr')
        pause_physics = ServiceProxyWrapper('/gazebo/pause_physics_dr', Empty)
        unpause_physics = ServiceProxyWrapper('/gazebo/unpause_physics_dr',
                                              Empty)

        for mp4_sub, mp4_unsub in zip(subscribe_to_save_mp4_topic,
                                      unsubscribe_from_save_mp4_topic):
            rospy.wait_for_service(mp4_sub)
            rospy.wait_for_service(mp4_unsub)
        for mp4_sub, mp4_unsub in zip(subscribe_to_save_mp4_topic,
                                      unsubscribe_from_save_mp4_topic):
            subscribe_to_save_mp4.append(ServiceProxyWrapper(mp4_sub, Empty))
            unsubscribe_from_save_mp4.append(
                Thread(target=ServiceProxyWrapper(mp4_unsub, Empty),
                       args=(EmptyRequest(), )))

        graph_manager.create_graph(task_parameters=task_parameters,
                                   stop_physics=pause_physics,
                                   start_physics=unpause_physics,
                                   empty_service_call=EmptyRequest)
        logger.info(
            "Graph manager successfully created the graph: Unpausing physics")
        unpause_physics(EmptyRequest())

        is_save_mp4_enabled = rospy.get_param('MP4_S3_BUCKET', None)
        if is_save_mp4_enabled:
            for subscribe_mp4 in subscribe_to_save_mp4:
                subscribe_mp4(EmptyRequest())

        configure_environment_randomizer()
        track_data = TrackData.get_instance()

        # Before each evaluation episode (single lap for non-continuous race and complete race for
        # continuous race), a new copy of park_positions needs to be loaded into track_data because
        # a park position will be pop from park_positions when a racer car need to be parked.
        if is_continuous:
            track_data.park_positions = park_positions
            graph_manager.evaluate(EnvironmentSteps(1))
        else:
            for _ in range(number_of_trials):
                track_data.park_positions = park_positions
                graph_manager.evaluate(EnvironmentSteps(1))
        if is_save_mp4_enabled:
            for unsubscribe_mp4 in unsubscribe_from_save_mp4:
                unsubscribe_mp4.start()
            for unsubscribe_mp4 in unsubscribe_from_save_mp4:
                unsubscribe_mp4.join()
        # upload simtrace and mp4 into s3 bucket
        for s3_writer in simtrace_video_s3_writers:
            s3_writer.persist(utils.get_s3_kms_extra_args())
        time.sleep(1)
        pause_physics(EmptyRequest())

    if race_type != RaceType.F1.value:
        # Close the down the job
        utils.cancel_simulation_job()
Ejemplo n.º 7
0
def rollout_worker(graph_manager, num_workers, rollout_idx, task_parameters,
                   simtrace_video_s3_writers):
    """
    wait for first checkpoint then perform rollouts using the model
    """
    if not graph_manager.data_store:
        raise AttributeError("None type for data_store object")

    data_store = graph_manager.data_store

    #TODO change agent to specific agent name for multip agent case
    checkpoint_dir = os.path.join(task_parameters.checkpoint_restore_path,
                                  "agent")
    graph_manager.data_store.wait_for_checkpoints()
    graph_manager.data_store.wait_for_trainer_ready()
    # Make the clients that will allow us to pause and unpause the physics
    rospy.wait_for_service('/gazebo/pause_physics_dr')
    rospy.wait_for_service('/gazebo/unpause_physics_dr')
    rospy.wait_for_service('/racecar/save_mp4/subscribe_to_save_mp4')
    rospy.wait_for_service('/racecar/save_mp4/unsubscribe_from_save_mp4')
    pause_physics = ServiceProxyWrapper('/gazebo/pause_physics_dr', Empty)
    unpause_physics = ServiceProxyWrapper('/gazebo/unpause_physics_dr', Empty)
    subscribe_to_save_mp4 = ServiceProxyWrapper(
        '/racecar/save_mp4/subscribe_to_save_mp4', Empty)
    unsubscribe_from_save_mp4 = ServiceProxyWrapper(
        '/racecar/save_mp4/unsubscribe_from_save_mp4', Empty)
    graph_manager.create_graph(task_parameters=task_parameters,
                               stop_physics=pause_physics,
                               start_physics=unpause_physics,
                               empty_service_call=EmptyRequest)

    chkpt_state_reader = CheckpointStateReader(checkpoint_dir,
                                               checkpoint_state_optional=False)
    last_checkpoint = chkpt_state_reader.get_latest().num

    # this worker should play a fraction of the total playing steps per rollout
    episode_steps_per_rollout = graph_manager.agent_params.algorithm.num_consecutive_playing_steps.num_steps
    act_steps = int(episode_steps_per_rollout / num_workers)
    if rollout_idx < episode_steps_per_rollout % num_workers:
        act_steps += 1
    act_steps = EnvironmentEpisodes(act_steps)

    configure_environment_randomizer()

    for _ in range(
        (graph_manager.improve_steps / act_steps.num_steps).num_steps):
        # Collect profiler information only IS_PROFILER_ON is true
        with utils.Profiler(s3_bucket=PROFILER_S3_BUCKET,
                            s3_prefix=PROFILER_S3_PREFIX,
                            output_local_path=ROLLOUT_WORKER_PROFILER_PATH,
                            enable_profiling=IS_PROFILER_ON):
            graph_manager.phase = RunPhase.TRAIN
            exit_if_trainer_done(checkpoint_dir, simtrace_video_s3_writers,
                                 rollout_idx)
            unpause_physics(EmptyRequest())
            graph_manager.reset_internal_state(True)
            graph_manager.act(act_steps,
                              wait_for_full_episodes=graph_manager.
                              agent_params.algorithm.act_for_full_episodes)
            graph_manager.reset_internal_state(True)
            time.sleep(1)
            pause_physics(EmptyRequest())

            graph_manager.phase = RunPhase.UNDEFINED
            new_checkpoint = -1
            if graph_manager.agent_params.algorithm.distributed_coach_synchronization_type\
                    == DistributedCoachSynchronizationType.SYNC:
                unpause_physics(EmptyRequest())
                is_save_mp4_enabled = rospy.get_param(
                    'MP4_S3_BUCKET', None) and rollout_idx == 0
                if is_save_mp4_enabled:
                    subscribe_to_save_mp4(EmptyRequest())
                if rollout_idx == 0:
                    for _ in range(int(rospy.get_param('MIN_EVAL_TRIALS',
                                                       '5'))):
                        graph_manager.evaluate(EnvironmentSteps(1))

                while new_checkpoint < last_checkpoint + 1:
                    exit_if_trainer_done(checkpoint_dir,
                                         simtrace_video_s3_writers,
                                         rollout_idx)
                    if rollout_idx == 0:
                        print(
                            "Additional evaluation. New Checkpoint: {}, Last Checkpoint: {}"
                            .format(new_checkpoint, last_checkpoint))
                        graph_manager.evaluate(EnvironmentSteps(1))
                    else:
                        time.sleep(5)
                    new_checkpoint = data_store.get_coach_checkpoint_number(
                        'agent')
                if is_save_mp4_enabled:
                    unsubscribe_from_save_mp4(EmptyRequest())
                logger.info(
                    "Completed iteration tasks. Writing results to S3.")
                # upload simtrace and mp4 into s3 bucket
                for s3_writer in simtrace_video_s3_writers:
                    s3_writer.persist(utils.get_s3_kms_extra_args())
                pause_physics(EmptyRequest())
                logger.info(
                    "Preparing to load checkpoint {}".format(last_checkpoint +
                                                             1))
                data_store.load_from_store(
                    expected_checkpoint_number=last_checkpoint + 1)
                graph_manager.restore_checkpoint()

            if graph_manager.agent_params.algorithm.distributed_coach_synchronization_type\
                    == DistributedCoachSynchronizationType.ASYNC:
                if new_checkpoint > last_checkpoint:
                    graph_manager.restore_checkpoint()

            last_checkpoint = new_checkpoint

    logger.info("Exited main loop. Done.")