Skip to content

Commit

Permalink
Merge pull request #16 from LBBassani/pathplanning
Browse files Browse the repository at this point in the history
Pathplanning
  • Loading branch information
LBBassani authored Oct 23, 2019
2 parents 66beee5 + 8084a4c commit e55221c
Show file tree
Hide file tree
Showing 30 changed files with 565 additions and 84 deletions.
29 changes: 25 additions & 4 deletions new_scripts/Agente.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@
"""
from sklearn.linear_model import LinearRegression
from .Geometria import Ponto
from .Campo import Campo
import math as m

class Agente(object):

def __init__(self, ponto = Ponto()):
self.__ponto = ponto
self.__theta = 0
self.__posicoesAntigas = list()

@property
Expand All @@ -21,30 +24,48 @@ def ponto(self):

@ponto.setter
def ponto(self, value):
self._changePosition()
self.__changePosition()
self.__ponto = value
c = Campo()
c.occupy(c.transform2Grid((value.x, value.y)), self)

@property
def posicao(self):
return self.ponto.posicao

@posicao.setter
def posicao(self, value):
self._changePosition()
self.__changePosition()
self.ponto.posicao = value
c = Campo()
c.occupy(c.transform2Grid(value), self)

@property
def x(self):
return self.ponto.x

@property
def y(self):
return self.ponto.y

@property
def theta(self):
return self.__theta

@theta.setter
def theta(self, value):
self.__theta = value

@property
def posicoesAntigas(self):
return self.__posicoesAntigas.copy()

def _changePosition(self):
if(len(self.__posicoesAntigas) >= 5):
def __changePosition(self):
if len(self.__posicoesAntigas) >= 5:
self.__posicoesAntigas.pop(0)
self.__posicoesAntigas.append(Ponto(self.ponto.x, self.ponto.y))
c = Campo()
c.release(c.transform2Grid(self.posicao))

def predicaoAdaptativa(self):
pass
9 changes: 6 additions & 3 deletions new_scripts/Aliado.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

class Aliado(Jogador):

def __init__(self, idJ, ponto = Ponto(), comportamento = COMPORTAMENTOS.DEFESA):
Jogador.__init__(id = idJ, ponto = ponto)
def __init__(self, idJ, ponto = Ponto(), comportamento = None):
Jogador.__init__(self, idJ = idJ, ponto = ponto)
self.comportamento = comportamento

""" Nome da função : comportamento (getter)
Expand Down Expand Up @@ -52,4 +52,7 @@ def comportamento(self, comportamento):
Retorno : Boolean : Sempre False
"""
def isInimigo(self):
return False
return False

def definirObjetivo(self, mundo):
return self.__comportamento.definirObjetivo(self, mundo)
8 changes: 6 additions & 2 deletions new_scripts/Ball.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@
"""
from .Agente import Agente
from .Geometria import Ponto
from .Patterns.Singleton import Singleton

class Ball(Agente):
class Ball(Agente, Singleton):

def __init__(self, ponto = Ponto()):
def __init__(self, *args, **keyargs):
pass

def inicializa(self, ponto = Ponto()):
Agente.__init__(self, ponto)
39 changes: 39 additions & 0 deletions new_scripts/Campo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
""" Nome do módulo : Campo
Ano de criação : 2019/10
Descrição do módulo : Modelar o campo do jogo
Versão : 1.0
Pré-requisitos : WeightedGridGraph
Pattern.Singleton
Membros : Lorena B Bassani
"""
from .Patterns.Singleton import Singleton
from .PathPlanning.Graph import WeightedGridGraph


class Campo(WeightedGridGraph, Singleton):

def __init__(self, *args, **keyargs):
pass

def inicializa(self, celulasX, celulasY, dimX = 150, dimY = 130):
if not hasattr(self, "grade"):
WeightedGridGraph.__init__(self, celulasX, celulasY)
self.__h = (dimX/(celulasX - 1), dimY/(celulasY - 1))

@property
def tamanhoCelula(self):
return self.__h

def transform2Cart(self, cel):
# TODO : Ver Se as grades possuem as mesmas características de crescimento de coordenadas
i, j = WeightedGridGraph.transform2Cart(self, cel)
return (i*self.__h[0], j*self.__h[1])

def transform2Grid(self, cel):
# TODO : Redefinir trasnformação
x, y = cel
return WeightedGridGraph.transform2Grid(self, (x//self.__h[0], y//self.__h[1]))

def cost(self, start, goal):
# TODO : Redefinir custo para variar com a proximidade a um obstáculo
return WeightedGridGraph.cost(self, start, goal)
33 changes: 32 additions & 1 deletion new_scripts/ComportamentosJogadores/ComportamentoAtacante.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,41 @@
Descrição do módulo : Comportamento de Atacante para Jogadores
Versão : 1.0
Pré-requisitos : IComportamento
Geometria
Mundo, Arena, Lado
Jogador
Ball
math
Membros : Lorena Bassani
"""
from .IComportamento import IComportamento
from ..Geometria import Ponto
from ..Mundo import Mundo, Arena, Lado
from ..Jogador import Jogador
from ..Ball import Ball
import math as m

class ComportamentoAtacante(IComportamento):
def __init__(self):
IComportamento.__init__(self)
IComportamento.__init__(self)

def definirObjetivo(self, jogador : Jogador, mundo : Mundo):
ball = mundo.ball
if ball.ponto.distancia(jogador.ponto) > 30:
x, y = ball.posicao
# Se posicionar antes da bola
if mundo.lado == Lado.DIREITO:
x += 3.35
else:
x -= 3.35
# Se a bola estiver acima do meio de campo, se posicionar acima dela
if y < Arena.marcacoes["Meio"].y:
y -= 3.35
else:
y += 3.35
return Ponto(x, y)
elif ball.ponto.distancia(jogador.ponto) > 5:
return ball.ponto
else:
resp = Arena.golEsquerdo["Meio"] if mundo.lado == Lado.ESQUERDO else Arena.golDireito["Meio"]
return resp
15 changes: 14 additions & 1 deletion new_scripts/ComportamentosJogadores/ComportamentoDefesa.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,23 @@
Descrição do módulo : Comportamento de Defesa para Jogadores
Versão : 1.0
Pré-requisitos : IComportamento
Geometria
Mundo, Arena, Lado
Jogador
Ball
math
Membros : Lorena Bassani
"""
from .IComportamento import IComportamento
from ..Geometria import Ponto
from ..Mundo import Mundo, Arena, Lado
from ..Jogador import Jogador
from ..Ball import Ball
import math as m

class ComportamentoDefesa(IComportamento):
def __init__(self):
IComportamento.__init__(self)
IComportamento.__init__(self)

def definirObjetivo(self, jogador, mundo):
pass
55 changes: 53 additions & 2 deletions new_scripts/ComportamentosJogadores/ComportamentoGoleiro.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,63 @@
""" Nome do módulo : ComportamentoGoleiro
Ano de criação : 2019/10
Descrição do módulo : Comportamento de Goleiro para Jogadores
Versão : 1.0
Versão : 2.0
Pré-requisitos : IComportamento
Geometria
Mundo, Arena, Lado
Ball
Jogador
math
Membros : Lorena Bassani
"""
from .IComportamento import IComportamento
from ..Geometria import Ponto
from ..Mundo import Mundo, Arena, Lado
from ..Ball import Ball
from ..Jogador import Jogador
import math as m

class ComportamentoGoleiro(IComportamento):
def __init__(self):
IComportamento.__init__(self)
IComportamento.__init__(self)

def definirObjetivo(self, jogador : Jogador, mundo : Mundo):
""" Ideia da implementação :
Posicionar o robô de forma que ele impessa a trajetória da bola
Como : Calcular o angulo de abertura entre a bola e o gol
Posicionar o robô onde o "triangulo" tenha base de 7,5 (tamanho do robô)
"""
resp = Ponto()
ball = mundo.ball
bx, _ = ball.posicao
bt = ball.theta
""" a² = b² + c² - 2bc*cos α
a² - b² - c² = -2bc* cos α
(b² + c² - a²)/2bc = cos α
α = acos(((b² + c² - a²)/2bc))
Onde :
a <- lado oposto (tamanho do gol)
b e c <- lados adjascentes (distancia da bola até um dos limites do gol)
α <- angulo desejado
"""
gol = Arena.golDireito if mundo.lado == Lado.DIREITO else Arena.golEsquerdo
a = Arena.metricas["Gol"][1]
b = ball.ponto.distancia(gol["Superior"])
c = ball.ponto.distancia(gol["Inferior"])
alpha = (b**2 + c**2 - a**2)/2*b*c
if alpha > 1:
alpha = 1.0
elif alpha < -1:
alpha = -1.0
alpha = m.acos(alpha)

dx = 3.75/m.tan(alpha) if m.tan(alpha) != 0 else 0 # 3.75 é metade da largura do robô de 7.5x7.5
resp.x = bx + dx if mundo.lado == Lado.DIREITO else bx - dx

theta = m.fabs(bt - jogador.theta)
resp.y = (resp.x/m.tan(theta))

resp.y = 100 if resp.y > 100 else 30 if resp.y < 30 else resp.y
resp.posicao = (10, 65) if mundo.lado == Lado.ESQUERDO and resp.x > 37.5 else (150, 65) if mundo.lado == Lado.DIREITO and resp.x < 112.5 else resp.posicao

return resp
36 changes: 36 additions & 0 deletions new_scripts/ComportamentosJogadores/ComportamentoLissajous.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
""" Nome do módulo : ComportamentoLissajous
Ano de criação : 2019/10
Descrição do módulo : Modela um comportamento que descreve uma curva de Lissajous
Versão : 1.0
Pré-requisitos : IComportamento
Geometria
math
Membros : Lorena B Bassani
"""
from .IComportamento import IComportamento
from ..Geometria import Ponto
from ..Mundo import Mundo, Arena, Lado
from ..Jogador import Jogador
from ..Ball import Ball
import math as m

class ComportamentoLissajous(IComportamento):
__PI = 3.14159
def __init__(self, A = 30, B = 100, a = 3, b = 4, sig = (__PI/2)):
IComportamento.__init__(self)
self.A = A
self.B = B
self.a = a
self.b = b
self.sigma = sig
self.__t = 0

def definirObjetivo(self, jogador, Mundo):
""" Na matemática, a curva de Lissajous (figura de Lissajous ou curva de Bowditch)
é o gráfico produzido por um sistema de equações paramétricas que descreve um complexo movimento harmônico.
x = A*sen(at + sig), y = B*sen(bt)
"""
x = self.A*m.sin(self.a*self.__t + self.sigma)
y = self.B*m.sin(self.b*self.__t)
self.__t += 1
return Ponto(x, y)
5 changes: 4 additions & 1 deletion new_scripts/ComportamentosJogadores/Factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from .ComportamentoGoleiro import ComportamentoGoleiro
from .ComportamentoDefesa import ComportamentoDefesa
from .ComportamentoAtacante import ComportamentoAtacante
from .ComportamentoLissajous import ComportamentoLissajous

class Factory(object):

Expand All @@ -28,5 +29,7 @@ def create(comportamento):
return ComportamentoGoleiro()
elif comportamento == COMPORTAMENTOS.ATACANTE:
return ComportamentoAtacante()
elif comportamento == COMPORTAMENTOS.DEFESA:
return ComportamentoDefesa()
else:
return ComportamentoDefesa()
return ComportamentoLissajous()
3 changes: 2 additions & 1 deletion new_scripts/ComportamentosJogadores/IComportamento.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@
Membros : Lorena Bassani
"""
class IComportamento(object):
pass
def definirObjetivo(self, jogador, mundo):
raise NotImplementedError
Loading

0 comments on commit e55221c

Please sign in to comment.