def reward(self, state, collision):
        """
        Вычисление награды агента, находящегося в состоянии state.
        Эту функцию можно (и иногда нужно!) менять, чтобы обучить вашу сеть именно тем вещам, которые вы от неё хотите
        :param state: текущее состояние агента
        :param collision: произошло ли столкновение со стеной на прошлом шаге
        :return reward: награду агента (возможно, отрицательную)
        """
        a = np.sin(angle(-state.position, state.heading))
        heading_score = self.HEADING_REWARD * np.tanh(-2 * a)  
        idle_penalty = 0 if abs(state.velocity) > self.MIN_SPEED else -self.IDLENESS_PENALTY
        speeding_penalty = 0 if abs(state.velocity) < self.MAX_SPEED else -self.SPEEDING_PENALTY * abs(state.velocity)
        collision_penalty = - max(abs(state.velocity), 0.1) * int(collision) * self.COLLISION_PENALTY

        dist = np.infty
        sectors = len(self.map)
        for j in range(sectors):
                inner_wall = self.map[j - 1][0], self.map[j][0]
                outer_wall = self.map[j - 1][1], self.map[j][1]

                intersect = intersect_ray_with_segment((state.position, state.heading), inner_wall)
                intersect = abs(intersect - state.position) if intersect is not None else np.infty
                if intersect < dist:
                    dist = intersect

                intersect = intersect_ray_with_segment((state.position, state.heading), outer_wall)
                intersect = abs(intersect - state.position) if intersect is not None else np.infty
                if intersect < dist:
                    dist = intersect
        dist_penalty = 0 if collision else - max(abs(state.velocity), 1) * self.COLLISION_PENALTY * np.exp(-dist)
        return heading_score + collision_penalty \
               + idle_penalty + speeding_penalty + dist_penalty
示例#2
0
    def visualize(self, scale, step):
        """
        Рисует картинку. Этот и все "приватные" (начинающиеся с _) методы необязательны для разбора.
        """
        for i, agent in enumerate(self.agents):
            state = self.agent_states[agent]
            collisions = self.collisions[agent]
            surface = self._agent_surfaces[i]
            rays_lengths = self.vision_for(agent)[-agent.rays:]
            self._agent_images[i] = [self._draw_ladar(rays_lengths, state, scale),
                                     self._get_agent_image(surface, state, scale)]

        if len(self.agents) == 1:
            a = self.agents[0]
            draw_text("Step: %i" % step, self._info_surface, scale, self.size,
                      text_color=white, bg_color=black, tlpoint=(self._info_surface.get_width() - 100, self._info_surface.get_height() - 30))
            draw_text("Reward: %.3f" % a.reward_history[-1], self._info_surface, scale, self.size,
                      text_color=white, bg_color=black)
            steer, acc = a.chosen_actions_history[-1]
            state = self.agent_states[a]
            draw_text("Action: steer.: %.2f, accel: %.2f" % (steer, acc), self._info_surface, scale,
                      self.size, text_color=white, bg_color=black, tlpoint=(self._info_surface.get_width()/2-200, self._info_surface.get_height()/2-50))
            draw_text("Inputs: |v|=%.2f, sin(angle): %.2f" % (
                abs(state.velocity), np.sin(angle(-state.position, state.heading))),
                      self._info_surface, scale,
                      self.size, text_color=white, bg_color=black, tlpoint=(self._info_surface.get_width()/2-200, self._info_surface.get_height()/2))
            draw_text("Circle: %.2f, collisions: %i" % (self.circles[a]/2/pi, collisions), self._info_surface, scale,
                      self.size, text_color=white, bg_color=black,
                      tlpoint=(self._info_surface.get_width() / 2 - 200, self._info_surface.get_height() / 2 + 50))
示例#3
0
    def evaluate_agent(self, agent, Physics, steps=1000, visual=True, **physics_pars):
        """
        Прогонка цикла мира для конкретного агента (см. пример использования в комментариях после if _name__ == "__main__")
        :param agent: SimpleCarAgent
        :param steps: количество итераций цикла
        :param visual: рисовать картинку или нет
        :return: среднее значение награды агента за шаг
        """
        agent.evaluate_mode = True
        self.set_agents([agent])
        rewards = []
        if visual:
            scale, screen = self._prepare_visualization()
        for step in range(steps):
            self.obs = generate_obstacles(8, self.radii, self.angles, step)
            self.physics = Physics(self.map, self.obs, **physics_pars)
            #plot_obstacles(self.map, self.obs, screen)
            vision = self.vision_for(agent)
            action = agent.choose_action(vision)
            next_agent_state, collision = self.physics.move(
                self.agent_states[agent], action
            )
            if collision:
                self.collisions[agent] += 1
            self.circles[agent] += angle(self.agent_states[agent].position, next_agent_state.position)
            self.agent_states[agent] = next_agent_state
            rewards.append(self.reward(next_agent_state, collision))
            agent.receive_feedback(rewards[-1])
            if visual:
                self.visualize(scale, step)
                if self._update_display() == pygame.QUIT:
                    break
                #sleep(0.05)

        return self.circles[agent], self.collisions[agent]  # np.mean(rewards)
    def evaluate_agent(self, agent, steps=1000, visual=True):
        """
        Прогонка цикла мира для конкретного агента (см. пример использования в комментариях после if __name__ == "__main__")
        :param agent: SimpleCarAgent
        :param steps: количество итераций цикла
        :param visual: рисовать картинку или нет
        :return: среднее значение награды агента за шаг
        """
        agent.evaluate_mode = True
        self.set_agents([agent])
        rewards = []
        if visual:
            scale = self._prepare_visualization()
        self.steps = steps
        for step in range(steps):
            self.step = step
            vision = self.vision_for(agent)
            action = agent.choose_action(vision)
            next_agent_state, collision = self.physics.move(
                self.agent_states[agent], action
            )
            self.circles[agent] += angle(self.agent_states[agent].position, next_agent_state.position) / (2*pi)
            self.agent_states[agent] = next_agent_state
            rewards.append(self.eval_reward(next_agent_state, collision))
            agent.receive_feedback(rewards[-1])
            if visual:
                self.visualize(scale)
                if self._update_display() == pygame.QUIT:
                    break
                sleep(0.05)

        return np.mean(rewards)
    def eval_reward(self, state, collision):
        """
        Награда "по умолчанию", используется в режиме evaluate
        Удобно, чтобы не приходилось отменять свои изменения в функции reward для оценки результата
        """
        a = -np.sin(angle(-state.position, state.heading))
        heading_reward = 1 if a > 0.1 else a if a > 0 else 0
        heading_penalty = a if a <= 0 else 0
        idle_penalty = 0 if abs(state.velocity) > self.MIN_SPEED else -self.IDLENESS_PENALTY
        speeding_penalty = 0 if abs(state.velocity) < self.MAX_SPEED else -self.SPEEDING_PENALTY * abs(state.velocity)
        collision_penalty = - max(abs(state.velocity), 0.1) * int(collision) * self.COLLISION_PENALTY

        return heading_reward * self.HEADING_REWARD + heading_penalty * self.WRONG_HEADING_PENALTY + collision_penalty \
            + idle_penalty + speeding_penalty
示例#6
0
    def vision_for(self, agent):
        """
        Строит видение мира для каждого агента
        :param agent: машинка, из которой мы смотрим
        :return: список из модуля скорости машинки, направленного угла между направлением машинки
        и направлением на центр и `agent.rays` до ближайших стен трека (запустите картинку, и станет совсем понятно)
        """
        state = self.agent_states[agent]
        vision = [abs(state.velocity), np.sin(angle(-state.position, state.heading))]
        extras = len(vision)

        delta = pi / (agent.rays - 1)
        start = rotate(state.heading, - pi / 2)

        sectors = len(self.map)
        for i in range(agent.rays):
            # define ray direction
            ray = rotate(start, i * delta)

            # define ray's intersections with walls
            vision.append(np.infty)
            for j in range(sectors):
                inner_wall = self.map[j - 1][0], self.map[j][0]
                outer_wall = self.map[j - 1][1], self.map[j][1]

                intersect = intersect_ray_with_segment((state.position, ray), inner_wall)
                intersect = abs(intersect - state.position) if intersect is not None else np.infty
                if intersect < vision[-1]:
                    vision[-1] = intersect

                intersect = intersect_ray_with_segment((state.position, ray), outer_wall)
                intersect = abs(intersect - state.position) if intersect is not None else np.infty
                if intersect < vision[-1]:
                    vision[-1] = intersect
            for obstacle in self.obs:
                for j in range(len(obstacle)):
                    obstacle_wall = obstacle[j - 1], obstacle[j]
                    intersect = intersect_ray_with_segment((state.position, ray), obstacle_wall)
                    intersect = abs(intersect - state.position) if intersect is not None else np.infty
                    if intersect < vision[-1]:
                        vision[-1] = intersect


            assert vision[-1] < np.infty, \
                "Something went wrong: {}, {}".format(str(state), str(agent.chosen_actions_history[-1]))
        assert len(vision) == agent.rays + extras, \
            "Something went wrong: {}, {}".format(str(state), str(agent.chosen_actions_history[-1]))
        return vision
示例#7
0
    def reward(self, state, collision):
        """
        Вычисление награды агента, находящегося в состоянии state.
        Эту функцию можно (и иногда нужно!) менять, чтобы обучить вашу сеть именно тем вещам, которые вы от неё хотите
        :param state: текущее состояние агента
        :param collision: произошло ли столкновение со стеной на прошлом шаге
        :return reward: награду агента (возможно, отрицательную)
        """
        a = np.sin(angle(-state.position, state.heading))
        heading_reward = 1 if a < 0.1 else a if a < 0 else 0
        heading_penalty = -a if a >= 0 else 0
        idle_penalty = 0 if abs(state.velocity) > self.MIN_SPEED else -self.IDLENESS_PENALTY
        speeding_penalty = 0 if abs(state.velocity) < self.MAX_SPEED else -self.SPEEDING_PENALTY * abs(state.velocity)
        collision_penalty = - max(abs(state.velocity), 0.1) * int(collision) * self.COLLISION_PENALTY

        return heading_reward * self.HEADING_REWARD + heading_penalty * self.WRONG_HEADING_PENALTY + collision_penalty \
               + idle_penalty + speeding_penalty
示例#8
0
 def transition(self):
     """
     Логика основного цикла:
      подсчёт для каждого агента видения агентом мира,
      выбор действия агентом,
      смена состояния
      и обработка реакции мира на выбранное действие
     """
     for a in self.agents:
         vision = self.vision_for(a)
         action = a.choose_action(vision)
         next_agent_state, collision = self.physics.move(
             self.agent_states[a], action
         )
         self.circles[a] += angle(self.agent_states[a].position, next_agent_state.position)
         self.agent_states[a] = next_agent_state
         a.receive_feedback(self.reward(next_agent_state, collision))
示例#9
0
    def eval_reward(self, state, collision):
        """
        Награда "по умолчанию", используется в режиме evaluate
        Удобно, чтобы не приходилось отменять свои изменения в функции reward для оценки результата
        """
        a = -np.sin(angle(-state.position, state.heading))
        heading_reward = 1 if a > 0.1 else a if a > 0 else 0
        heading_penalty = a if a <= 0 else 0
        idle_penalty = 0 if abs(
            state.velocity) > self.MIN_SPEED else -self.IDLENESS_PENALTY
        speeding_penalty = 0 if abs(
            state.velocity) < self.MAX_SPEED else -self.SPEEDING_PENALTY * abs(
                state.velocity)
        collision_penalty = -max(abs(state.velocity),
                                 0.1) * int(collision) * self.COLLISION_PENALTY

        return heading_reward * self.HEADING_REWARD + heading_penalty * self.WRONG_HEADING_PENALTY + collision_penalty \
               + idle_penalty + speeding_penalty
示例#10
0
    def vision_for(self, agent, state=None):
        """
        Строит видение мира для каждого агента
        :param agent: машинка, из которой мы смотрим
        :return: список из модуля скорости машинки, направленного угла между направлением машинки
        и направлением на центр и `agent.rays` до ближайших стен трека (запустите картинку, и станет совсем понятно)
        :state: Force the position of the agent, otherwise the current position is used
        """
        if state is None:
            state = self.agent_states[agent]
        vision = [abs(state.velocity), np.sin(angle(-state.position, state.heading))]
        extras = len(vision)

        delta = pi / (agent.rays - 1)
        start = rotate(state.heading, - pi / 2)

        sectors = len(self.map)
        for i in range(agent.rays):
            # define ray direction
            ray = rotate(start, i * delta)

            # define ray's intersections with walls
            vision.append(np.infty)
            for j in range(sectors):
                inner_wall = self.map[j - 1][0], self.map[j][0]
                outer_wall = self.map[j - 1][1], self.map[j][1]

                intersect = intersect_ray_with_segment((state.position, ray), inner_wall)
                intersect = abs(intersect - state.position) if intersect is not None else np.infty
                if intersect < vision[-1]:
                    vision[-1] = intersect

                intersect = intersect_ray_with_segment((state.position, ray), outer_wall)
                intersect = abs(intersect - state.position) if intersect is not None else np.infty
                if intersect < vision[-1]:
                    vision[-1] = intersect

            assert vision[-1] < np.infty, \
                "Something went wrong: {}, {}".format(str(state), str(agent.chosen_actions_history[-1]))
        assert len(vision) == agent.rays + extras, \
            "Something went wrong: {}, {}".format(str(state), str(agent.chosen_actions_history[-1]))
        return vision
 def transition(self):
     """
     Логика основного цикла:
      подсчёт для каждого агента видения агентом мира,
      выбор действия агентом,
      смена состояния
      и обработка реакции мира на выбранное действие
     """
     for a in self.agents:
         vision = self.vision_for(a)
         action = a.choose_action(vision)
         next_agent_state, collision = self.physics.move(
             self.agent_states[a], action)
         self.circles[a] += angle(self.agent_states[a].position,
                                  next_agent_state.position) / (2 * pi)
         self.agent_states[a] = next_agent_state
         a.receive_feedback(self.reward(next_agent_state, collision),
                            train_every=self._train_every,
                            epochs=self._epochs,
                            eta=self._eta)
示例#12
0
    def reward(self, state, collision):
        """
        Вычисление награды агента, находящегося в состоянии state.
        Эту функцию можно (и иногда нужно!) менять, чтобы обучить вашу сеть именно тем вещам, которые вы от неё хотите
        :param state: текущее состояние агента
        :param collision: произошло ли столкновение со стеной на прошлом шаге
        :return reward: награду агента (возможно, отрицательную)
        """
        a = np.sin(angle(-state.position, state.heading))
        heading_reward = 1 if a > 0.1 else a if a > 0 else 0
        heading_penalty = a if a <= 0 else 0
        idle_penalty = 0 if abs(
            state.velocity) > self.MIN_SPEED else -self.IDLENESS_PENALTY
        speeding_penalty = 0 if abs(
            state.velocity) < self.MAX_SPEED else -self.SPEEDING_PENALTY * abs(
                state.velocity)
        collision_penalty = -max(abs(state.velocity),
                                 0.1) * int(collision) * self.COLLISION_PENALTY

        return heading_reward * self.HEADING_REWARD + heading_penalty * self.WRONG_HEADING_PENALTY + collision_penalty \
               + idle_penalty + speeding_penalty
示例#13
0
    def evaluate_agent(self,
                       agent,
                       Physics,
                       steps=1000,
                       visual=True,
                       **physics_pars):
        """
        Прогонка цикла мира для конкретного агента (см. пример использования в комментариях после if _name__ == "__main__")
        :param agent: SimpleCarAgent
        :param steps: количество итераций цикла
        :param visual: рисовать картинку или нет
        :return: среднее значение награды агента за шаг
        """
        agent.evaluate_mode = True
        self.set_agents([agent])
        rewards = []
        if visual:
            scale, screen = self._prepare_visualization()
        for step in range(steps):
            self.obs = generate_obstacles(8, self.radii, self.angles, step)
            self.physics = Physics(self.map, self.obs, **physics_pars)
            #plot_obstacles(self.map, self.obs, screen)
            vision = self.vision_for(agent)
            action = agent.choose_action(vision)
            next_agent_state, collision = self.physics.move(
                self.agent_states[agent], action)
            if collision:
                self.collisions[agent] += 1
            self.circles[agent] += angle(self.agent_states[agent].position,
                                         next_agent_state.position)
            self.agent_states[agent] = next_agent_state
            rewards.append(self.reward(next_agent_state, collision))
            agent.receive_feedback(rewards[-1])
            if visual:
                self.visualize(scale, step)
                if self._update_display() == pygame.QUIT:
                    break
                #sleep(0.05)

        return self.circles[agent], self.collisions[agent]  # np.mean(rewards)
示例#14
0
    def visualize(self, scale):
        """
        Рисует картинку. Этот и все "приватные" (начинающиеся с _) методы необязательны для разбора.
        """
        for i, agent in enumerate(self.agents):
            state = self.agent_states[agent]
            surface = self._agent_surfaces[i]
            rays_lengths = self.vision_for(agent)[-agent.rays:]
            self._agent_images[i] = [
                self._draw_ladar(rays_lengths, state, scale),
                self._get_agent_image(surface, state, scale)
            ]

        if len(self.agents) == 1:
            a = self.agents[0]
            draw_text("Reward: %.3f" % a.reward_history[-1],
                      self._info_surface,
                      scale,
                      self.size,
                      text_color=white,
                      bg_color=black)
            steer, acc = a.chosen_actions_history[-1]
            state = self.agent_states[a]
            draw_text("Action: steer.: %.2f, accel: %.2f" % (steer, acc),
                      self._info_surface,
                      scale,
                      self.size,
                      text_color=white,
                      bg_color=black,
                      tlpoint=(self._info_surface.get_width() - 500, 10))
            draw_text("Inputs: |v|=%.2f, sin(angle): %.2f, circle: %.2f" %
                      (abs(state.velocity),
                       np.sin(angle(-state.position,
                                    state.heading)), self.circles[a]),
                      self._info_surface,
                      scale,
                      self.size,
                      text_color=white,
                      bg_color=black,
                      tlpoint=(self._info_surface.get_width() - 500, 50))
    def reward(self, previous_state, state, collision, previous_vision, vision):
        """
        Вычисление награды агента, находящегося в состоянии state.
        Эту функцию можно (и иногда нужно!) менять, чтобы обучить вашу сеть именно тем вещам, которые вы от неё хотите
        :param state: текущее состояние агента
        :param collision: произошло ли столкновение со стеной на прошлом шаге
        :return reward: награду агента (возможно, отрицательную)
        """
        a = -np.sin(angle(-state.position, state.heading))
        heading_reward = 1 if a > 0.1 else a if a > 0 else 0
        heading_penalty = a if a <= 0 else 0
        idle_penalty = 0 if abs(state.velocity) > self.MIN_SPEED else -self.IDLENESS_PENALTY
        speeding_penalty = 0 if abs(state.velocity) < self.MAX_SPEED else -self.SPEEDING_PENALTY * abs(state.velocity)
        collision_penalty = - max(abs(state.velocity), 0.1) * int(collision) * self.COLLISION_PENALTY
        along_longest_ray_reward = 0
        towards_longest_ray_reward = 0

        # мы должны двигаться вдоль самого длинного луча (самый длинный луч должен быть по середине)
        # возможно он уже посередине?        
        rays = np.array(vision[2:])
        maxIndex = np.argmax(rays)
        raysNum = rays.size
        centerRayIndex = raysNum // 2

        previous_rays = np.array(previous_vision[2:])
        previous_maxIndex = np.argmax(previous_rays)
        if maxIndex == centerRayIndex &  previous_maxIndex == centerRayIndex:
            along_longest_ray_reward = 1
        else:
            if (abs(centerRayIndex - maxIndex) < abs(centerRayIndex - previous_maxIndex)):
                towards_longest_ray_reward = 1


        # награда за движение вдоль длинного луча только если движение в правильном направлении
        # награда за движение в сторону длинного луча только если движение в правильном направлении
        return heading_reward * self.HEADING_REWARD + heading_penalty * self.WRONG_HEADING_PENALTY + collision_penalty \
                + idle_penalty + speeding_penalty \
                + heading_reward * along_longest_ray_reward * self.ALONG_LONGEST_RAY_REWARD  \
                + heading_reward * towards_longest_ray_reward  * self.TOWARDS_LONGEST_RAY_REWARD \
                + 0.5
示例#16
0
 def transition(self):
     """
     Логика основного цикла:
      подсчёт для каждого агента видения агентом мира,
      выбор действия агентом,
      смена состояния
      и обработка реакции мира на выбранное действие
     """
     rewards = []
     for a in self.agents:
         vision = self.vision_for(a)
         action = a.choose_action(vision)
         next_agent_state, collision = self.physics.move(
             self.agent_states[a], action)
         self.circles[a] += angle(self.agent_states[a].position,
                                  next_agent_state.position) / (2 * pi)
         self.agent_states[a] = next_agent_state
         reward = self.reward(vision, next_agent_state, collision,
                              a.print_logs)
         rewards += [reward]
         a.receive_feedback(reward)
     return rewards
示例#17
0
 def transition(self):
     """
     Логика основного цикла:
      подсчёт для каждого агента видения агентом мира,
      выбор действия агентом,
      смена состояния
      и обработка реакции мира на выбранное действие
     """
     for a in self.agents:
         vision = self.vision_for(a) # s_t
         action = a.choose_action(vision) # a_t
         next_agent_state, collision = self.physics.move(
             self.agent_states[a], action
         )
         self.circles[a] += angle(self.agent_states[a].position, next_agent_state.position) / (2*pi)
         self.agent_states[a] = next_agent_state
         reward = self.reward(next_agent_state, collision) # r_t
         if collision:
             self.learner.update_final_qvalue(vision, action, reward)
             raise EpisodeFinished()
         else:
             next_vision = self.vision_for(a, next_agent_state)
             self.learner.update_qvalue(vision, action, reward, a, next_vision)