-
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. 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 damatch
. 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.
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.
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