Projeto

Geral

Perfil

Ações

Atividade #1101

Fechada

Refatoração da inteligência

Adicionado por Lucas Germano mais de 5 anos atrás. Atualizado mais de 5 anos atrás.

Situação:
Fechada
Prioridade:
Normal
Atribuído para:
Início:
18/05/2019
Data prevista:

Descrição

Time: Rebeca, Erick e Nicolas

As tarefas desse time são para fazer a inteligência orientada a objeto, que é o modulo central no nosso projeto Phoenix. A inteligência receberá os dados da visão antiga e mandará para a comunicação, por meio de "proxys" construidos pelos outros dois times.

Observações:
Não acessar uma tactic inválida
Acessar a visão por referência


Arquivos

arrayball.png (69,9 KB) arrayball.png Gabriel Borges da Conceição, 07/06/2019 21:11 h
arrayrobot.png (76,2 KB) arrayrobot.png Gabriel Borges da Conceição, 07/06/2019 21:11 h
Ações #1

Atualizado por Rebeca Reismais de 5 anos

Primeiramente, criamos todos os getters e setters de todas as classes, que no labview são chamados de read and write methods. Para isso, bastou clicar com o botão direito em cada classe e selecionar "Create Data Member Access". Quando a janelinha abrir, não esquecer de selecionar as opções que falam de "read and write", vi estática, property node e "no folder" (para que seja público).

Depois começamos a trabalhar numa estrutura para o STP. Criamos uma TestSkill, que nada mais é do que um goTo para o centro do campo; uma TestTactic, que é uma máquina de estados com apenas 1 estado (já que só contém essa skill); uma TestRole,que é uma sequência de tactics, no caso apenas a TestTactic.

Algumas mudanças feitas:

  • Não existe mais a classe SkillStateMachine que estava no UML, pois percebemos que não havia essa necessidade, já que a tactic nada mais é do que uma única máquina de estados, tendo um método para executá-la.
  • A classe TacticBook, bem como a SkillBook e a Rolebook, tinham como atributos um array das tactics, das skills, ou das roles, respectivamente. Apagamos o array e adicionamos a referência para as classes filhas como atributos da respectiva classe pai. Assim, elas ficam disponíveis no cluster da classe pai, e fica mais fácil de acessar os filhos com um unbundle (ou property node), em vez de iterar no array sem saber a posição em que se encontra a tática / skill / role que queremos.
  • Um detalhe: para o caso das roles, a princípio seria importante que fosse mantido o array, já que a role executa as tactics de maneira ordenada. Tentamos manter o array e ir atualizando o index para cada iteração da role pegar a respectiva tactic naquele index do array, mas então esbarramos com um problema: para acessar o método daquela tactic atual, é preciso adicionar a vi correspondente a esse método na vi principal da TestRole. Dessa maneira seria preciso utilizar um case, e para cada tactic chamamos o seu método correspondente (o que executa a sua máquina de estados). Como não tinha como fugir do case, optamos por fazer sem o array mesmo, e agora o case é pra, de acordo com o index, escolher a tactic e executar seu método.
  • No caso da tactic, outra mudança foi que cada classe filha vai ter como atributo um enum chamado States, que contém todos os estados daquela tática específica.
  • O padrão de organização então ficou assim: cada classe do tipo Book contém atributos que são referências para suas classes filhas. E cada classe, como por exemplo Tactic, contém como atributo uma referência para o "book" de um nível abaixo, no caso o SkillBook. De forma equivalente, então: Role contém um atributo TacticBook, e assim por diante.
  • Criamos um template para a máquina de estados que vai ser usada em todas as tactics. O template está localizado na pasta mais geral do projeto, e tem o nome de StateMachineExample. Ele deve ser copiado e utilizado como padrão para criar as próximas tactics.

Outra discussão que surgiu no final: estamos utilizando, em todas vis que criamos, um feedback node para pegar o estado da última iteração, bem como atualizando o estado atual em variáveis que possam existir (por exemplo, o index da tactic que está sendo utilizada no momento é atualizado toda vez que vamos trocar de tactic, e essa variável pode ser utilizada como forma de debugar o código). Outra opção seria não utilizar o feedback node e confiar nos valores que recebemos do game, mas aí ao final da execução completa do código teríamos que sobrescrever os valores de todos os atributos possíveis no game para os valores atuais. Isso seria uma solução mais trabalhosa talvez, pois teria que existir uma vi grande que seria copiar todos os atributos de todas as classes para o game da próxima iteração.

Ações #2

Atualizado por Rebeca Reismais de 5 anos

Hoje implementamos os 3 métodos principais e colocamos essas VIs no projeto da Phoenix, seguindo o fluxo de dados: Choose Play, Pick Robots e Execute Play. Lembrando que todos esses métodos são divididos em partes, pois temos que escolher separadamente a Offensive Play, Defensive Play e Keeper Play. Como só há até o momento uma Play teste, uma role teste, uma tactic teste e uma skill teste, a implementação foi um pouco mais "simples" nesse sentido, pois ainda vamos ter que criar VIs futuramente que vão definir as condições para escolher a play atual e a forma como os robôs são atribuídos a cada role também.

Algumas modificações importantes feitas:

  • Devido a algumas dificuldades de implementação e muita discussão, alguns atributos do Game mudaram. Antes a ideia era que teríamos a referência para a play defensiva, ofensiva e keeper. Mas quando tentamos atribuir a play escolhida para a referência dela no game, o fio quebrava pois eram de tipos diferentes (a referência é do tipo play, e a play escolhida era de uma classe filha criada). Por serem classes distintas, mesmo com a herança, não era possível ligar. A solução para isso foi trocarmos essas 3 referências por 3 enums, um para cada tipo de play (ofensiva/defensiva/keeper). Daí, a escolha da play é determinada nesse enum, e na hora de executá-la basta criar um case com esse enum (pois de qualquer forma cada play tem possivelmente métodos diferentes que vão ser chamados ali dentro).
  • Antes tínhamos definido que cada role tem uma id de robô como atributo. Isso foi mantido, mas percebemos que o contrário seria vantajoso para a implementação. Por isso, agora também mapeamos cada robô na sua role que está sendo executada. Ou seja, a classe robô tem um enum role, e no pick robots é preciso atualizar tanto o id do robô dentro da role como também a role dentro do robô.
  • Criamos a classe Utilities que vai guardar alguns métodos importantes e úteis para todo o código. Existe uma referência para essa classe no Game. Um método útil criado, por exemplo, foi o findRobotByID, que recebe uma id e retorna a referência para o robô correspondente.

Vai haver uma aulinha essa semana para os outros membros aprenderem como criar novas skills, tactics, plays ou roles no código, qual o passo a passo que precisam seguir, pois são muitos detalhes e locais no código que precisam ser atualizados toda vez que uma nova classe for criada. É importante entender como as classes se relacionam também, antes de começar a implementar qualquer coisa.

Obs- Não podemos esquecer de atualizar o diagrama para a arquitetura atual, pois foram feitas muitas modificações desde a primeira versão.

Ações #3

Atualizado por Gabriel Borges da Conceiçãomais de 5 anos

Foi feito o merge das branches relativas à comunicação, visão e inteligência.
Todos os erros já foram consertados e o código dessa junção se encontra na branch mergeIntelVisionCom.

OBS: as branches dev, newVision e newCommunication permanecem intactas.

Peço que abram o código da branch mergeIntelVisionCom e confiram se está realmente tudo certo.

Ações #4

Atualizado por Nicolas Oliveiramais de 5 anos

Foi gerado apenas uma opção de skill, tactic, play até agora. Farei um segunda opção, a princípio Halt. Que será utilizada para ensinar os outros membros essa implementação.

Ações #5

Atualizado por Gabriel Borges da Conceiçãomais de 5 anos

Após a reunião do dia 06/06/2019, alguns pontos foram levantados e listados:

1) Ordenar array de robôs de acordo com o grupo a que pertencem (offensive, defensive ou keeper). As primeiras coordenadas do vetor seriam relativas a offensive e as últimas relativas a defensive. O keeper é separado. Teria que existir um método que ordenasse esses robôs.

2) Dividir o vetor de robôs de Ally em 3 (offensive, defensive ou keeper) e já passar assim para a arquitetura STP.

3)Criar path planning e navigation após "execute play".

4)Lembrar de reencapsular tudo após um método chamado.

5)Lembrar de clonar todas as VIs de skills que sejam usadas por diferentes robôs.

6)Criar atritubuto nas Roles que representa a quantidade de tactis que ela executará.

7)Criar gerenciador de Tactis para que se saiba em determinado instante quais roles já terminaram uma tactic, quais ainda estão executando para poder andar ordenadamente.

8)Nas plays conjuntas como "Halt" e "Timeout" etc, fazer tudo em apenas 1 dos 3 whiles da intel. A sugestão foi que se fizesse na do goleiro.

9)Resetar todos os parâmetros de uma play quando ela for para de ser executada. A sugestão foi que se passasse a respectiva "constant play".

10)Sempre criar os métodos "Data Member Access" de acesso aos atributos para que se possa ler/escrever nos atributos com property node. Sempre deixar a opção "No folder" ao criar o método de acesso.

Não necessariamente tudo que está aqui deve ser feito. Mas foi colocado tudo que pensamos durante a reunião para que pudéssemos pensar/discutir a implementação

Atualizado por Gabriel Borges da Conceiçãomais de 5 anos

Consegui resolver o problema de vetores de classes filhas:
![](arrayball.png)
![](arrayrobot.png)

Baseado nisso, fiz uma nova estruturação da arquitetura baseado em vetor de roles na play. Pois dessa forma não vamos fugir da real arquitetura e fica muito mais genérico.

Tudo que fiz está na branch "TestArch" na VI "Test".

A VI das fotos acima é a "ArrayOfChildClasses" e está solta na pasta.

Peço que olhem e dêem feedback pois isso é importante para o avanço daqui pra frente

Ações #7

Atualizado por Rebeca Reismais de 5 anos

Sobre o item "dividir o vetor ally em 3" já foi feita essa implementação, com um detalhe que agora mudamos a ordenação dos robos: a primeira posiçao é o goalie, as do meio sao offensive e as ultimas sao defensive. Na ordem, fica: Goalie, Offensive (pinned), Offensive, Defensive, Defensive (pinned).

Ações #8

Atualizado por Rebeca Reismais de 5 anos

Foi feita a ordenação dos robos seguindo a ordem especificada acima. Agora, com esse array já ordenado, o nosso vetor de ally é dividido em 3: keeper team, offensive team e defensive team. Daí, de acordo com o numero de offensive e defensive robots que a play necessita, nós construímos esses 3 times seguindo a ordem do array de robos, e isso fica bem simples dado q eles já estao organizados.

Criei os atributos pinned offensive e pinned defensive no game, que sao arrays de robos. Falta agora criar um control para alterar isso no painel principal da phoenix, e também um while para setar os valores de todos esses controls que vao existir na tela principal.

Ações #9

Atualizado por Rebeca Reismais de 5 anos

Consertei algun erros que existiam na parte de dividir o ally em 3. Um detalhe que mudou é que antes a role recebia a id do robo que a executaria, agora preencho nela a referencia do robo direto. Podemos apagar esse atributo id que nao vai ser mais necessário. Por causa dessa mudança, na vi da testRole mudei também um detalhe: ela recebia como entrada um parametro robot in. Agora, a referencia do robo já está na role, nao precisa dessa entrada.

Estou tendo dificuldades agora para incluir o rrt e a navigation no código atual. Fiquei na dúvida se eles sao métodos do game mesmo ou do robo. Por enquanto acredito que sejam do game. Estou na parte de transformar o game no IA State para conseguir executar nosso rrt antigo, mas nao sei se isso é a melhor forma de se fazer.

Ações #10

Atualizado por Rebeca Reismais de 5 anos

Fizemos diversas modificações hoje:

  • Mudamos o painel principal da phoenix para ficar mais organizado e bonito visualmente. Agora tem abas para nao poluir muito, e cada uma tem um objetivo específico. Exemplo, uma aba só para parametros, uma aba para o filtro da camera, etc. Podemos criar novas abas a medida que for surgindo necessidade.
  • Nessa aba de setar parametros já existe um array Offensive pinned e um defensive pinned, para colocar os ids do robo que deseja fixar.
  • No painel principal tem um botão Test, feito para rodar a play de teste, tactic de teste e skill de teste. Quando criar uma play nova, basta setar sua play ali para testá-la.
  • Obs- o while grande "decode information" está muito desorganizado e horrível visualmente, com comentários e setas por cima de blocos e fios. Uma bagunça e difícil de entender, alguém precisa arrumar isso dps!
  • Mudança importante: antes, a classe Play tinha um atributo number of robots. Mas aí cada play filha nao tem esse atributo visível, e teríamos que usar o Init dela pra setar o numero de robos de cada classe filha. Pra nao ter que ficar chamando o Init toda vez e setando esse valor, a solução que achamos que seria melhor foi que cada play filha criada terá seu próprio atributo number of robots, e temos que setar esse valor e deixar como default pra nao precisar mexer mais nisso. A classe pai play nao tem mais esse atributo.
  • Para testar alguma vi: se quiser só ler dela, desabilite a escrita! aí ela nao vai escrever no Game um resultado errado e é possível debugar aquela vi específica, vendo com o probe os resultados finais dela sem que eles sobrescrevam o game! Para isso, clique com o botão direito no bloco "Data value Reference Read / write element " e selecione read only.
Ações #11

Atualizado por Rebeca Reismais de 5 anos

Fizemos uma mudança importante que melhorou bastante! Antes o fps estava muito baixo, e também o grsim com um bug muito estranho. Quando a gente clicava no grsim, a comunicação entre ele e a phoenix funcionava. Quando clicava na phoenix, parava de comunicar. Daí colocamos um wait em todos os whiles do código, (sigam o mesmo padrão para os próximos!), para colocar um teto máximo de fps neles. Alguns whiles estavam muito rápidos antes, mais de 2000, daí mudamos o teto para 240 para todos, e com isso a comunicação entre o grsim e a phoenix ficou estável e sem aquele bug. Agora, a luz verde da comunicação está sempre acesa!

Ações #12

Atualizado por Rebeca Reismais de 5 anos

Criar outro método na utilities que seja deleteRobotByIndex, porque aí se usarmos o findRobotById antes dele, podemos aproveitar a saída desse método (o index) e usar na entrada do outro. Isso economiza um loop que seria feito para deletar o robo, que agora pode ser feito em o(1) aproveitando o resultado do loop que foi feito antes.

Ações #13

Atualizado por Rebeca Reismais de 5 anos

Atenção: o número de roles existentes na play deve ser igual ao number of robots daquela play! Caso vc queria que aquela play tenha duas roles iguais, por exemplo, precisa duplicar aquele atributo (a role específica) na sua play.

Ações #14

Atualizado por Rebeca Reismais de 5 anos

Na vi pickDefensiveTeam/pickOfensiveTeam temos que criar bloquinhos para escolher a ordem dos robos nesses times, de acordo com a play. Por exemplo, na pickDefensiveTeam, caso tenha duelist a ordem é duelist, barreira1, barreira2 (sendo barreira1 com y > y da barreira2). Caso nao tenha duelist, o critério para ordenar é apenas o y, sendo do maior pro menor y. No caso do offensive Team, podemos ordenar pela proximidade com a bola, sendo o primeiro robo do time o mais próximo da bola e os seguintes menos próximos (striker 1 e 2).

Ações #15

Atualizado por Gabriel Borges da Conceiçãomais de 5 anos

  • Situação alterado de Em andamento para Fechada

Tarefa encerrada, faltando apenas a nova implementação do passe.

Ações

Exportar para Atom PDF