-
Notifications
You must be signed in to change notification settings - Fork 7
conceitos o que e um coach
Um coach é um módulo especial no NeonFC. O coach
é tratado no sistema como uma entidade.
Um coach é instanciado no objeto match (ver def start
). Durante a sua inicialização, ele verifica pela chave match.coach_name
para instanciar a classe certa. Para isso, é necessario adicionar a relação chave/valor na variável AVAILABLE_COACHES
, dentro de entities/coach/__init__.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 normalmente usamos para fazer isso: estático, cada estratégia é passada sempre para o mesmo robô; dinâmico, o coach escolhe qual estratégia cada robô seguirá, baseado na função das suas posições; ou ainda o coach playbook, do qual mais informações podem ser encontradas aqui.
Uma instância de Coach
precisa ter apenas dois métodos:
-
__init__
(construtor): No método construtor, deverá ser passada a referência damatch
. Aqui, você poderá instanciar as estratégias contidas no seu coach, assim como objetos auxiliares para a tomada de decisão. -
decide
: Esse método deverá atribuir para cada robô uma nova estratégia. É importante que após a execução desse método cada robô tenha uma estratégia válida, caso contrário o NeonFC irá quebrar.
Nesse exmplo, usamos as estratégias da LARC 2020 de forma que, sempre os robôs de id 0, 1 e 2 recebem 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 é necessário além de uma simples iteração, sabemos através da criação da lista match.robots
que ela sempre será ordenada. Então a atribuição funcionará sempre.
Esse exemplo é o coach utilizado pela equipe Project Neon na LARC 2020.
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 criação através do Playbook.