Skip to content

conceitos o que e um coach

jpkleal edited this page Mar 20, 2023 · 2 revisions

Um coach é um módulo especial no NeonFC. Coach é tratado no sistema como uma entidade.

Um coach é instanciado no objeto match (ver def start). Durante a sua inicializacao ele verifica pela chave match.coach_name para instanciar a classe certa. Para isso e necessario adicionar a relacao chave/valor na variavel AVAILABLE_COACHES, dentro de match.py.

O coach é executado durante toda iteração do loop principal, no update do match. Ele é encarregado por escolher qual comportamento (estratégia) cada um dos robôs da equipe vai seguir. Existem 3 maneiras que normamente usamos para fezer isso: estático, cada estratégia é passada sempre para o mesmo robô; dinâmico, o coach escolhe qual robô seguirá, qual estratéia baseado na função das suas posições; ou ainnda o coach playbook, mais informações podem ser encontradas aqui.

Uma instancia de Coach precisa ter apenas dois metodos:

  • __init__ (construtor): no metodo construtor devera ser passado a referência da match. Aqui você podera instanciar as estratégias contidas no seu coach, assim como objetos auxiliares para a tomada de decisao.

  • decide: esse metodo devera atribuir para cada robot uma nova estratégia. É importante que após a execucao desse metodo cada robo tenha uma estratégia valida, caso contrario o NeonFC irá quebrar.

Exemplo 1: Atribuidor simples

Nesse exmplo, usamos as estratégias da Larc2020 de forma que, sempre os robos de id 0,1 e 2 receberam as estratégias Goalkeeper, Attacker e Midfielder consecutivamente.

import algorithms
import strategy
import math
from commons.math import angular_speed, speed, rotate_via_numpy, unit_vector

class Coach(object):
    def __init__(self, match):
        self.match = match
        self.constraints = [
            strategy.larc2020.GoalKeeper(self.match),
            strategy.larc2020.Attacker(self.match),
            strategy.larc2020.MidFielder(self.match)
        ]
    
    def decide (self):
        robots = [r.robot_id for r in self.match.robots]
        for robot_id in robots:
            self.match.robots[robot_id].strategy = self.constraints[robot_id]

Nesse caso, nada é necessario alem de uma simples iteração, sabemos através da criação da lista match.robots que ela sempre sera ordenada. Então a atribuição funcionara sempre.

Exemplo 2: larc2020.py

Esse exemplo é o coach utilizado pela equipe Project Neon na LARC 2020. Ele tambem pode ser encontrado nesse link.

import algorithms
import strategy
import math
from commons.math import angular_speed, speed, rotate_via_numpy, unit_vector

class Coach(object):
    def __init__(self, match):
        self.match = match
        self.constraints = [
            #estratégia - função eleitora - prioridade
            (strategy.larc2020.GoalKeeper(self.match), self.elect_goalkeeper, 0),
            (strategy.larc2020.Attacker(self.match), self.elect_attacker, 0),
            (strategy.larc2020.MidFielder(self.match), self.elect_midfielder, 0)
        ]
    
    def decide (self):
        robots = [r.robot_id for r in self.match.robots]
        for strategy, fit_fuction, priority in self.constraints:
            elected = -1
            best_fit = -99999
            for robot_id in robots:
                robot_fit = fit_fuction(self.match.robots[robot_id])
                if (robot_fit > best_fit):
                    best_fit = robot_fit
                    elected = robot_id
            if self.match.robots[elected].strategy is None:
                self.match.robots[elected].strategy = strategy
            elif self.match.robots[elected].strategy.name != strategy.name:
                self.match.robots[elected].strategy = strategy
                self.match.robots[elected].start()
            robots.remove(elected)
    
    def elect_attacker(self, robot):
        dist_to_ball = math.sqrt(
            (robot.x - self.match.ball.x)**2 + (robot.y - self.match.ball.y)**2
        )
        return 1000 - dist_to_ball

    def elect_goalkeeper(self, robot):
        dist_to_goal = math.sqrt(
            (robot.x - 0)**2 + (robot.y - 0.65)**2
        )
        return 1000 - dist_to_goal

    def elect_midfielder(self, robot):
        return 1

Assim que estiver familiarizado com a funçao do objeto coach você pode experimentar a criacao atraves do Playbook

Clone this wiki locally