You are here

Atividade 3

Usando o Mapa

 

    Uma vantagem em se criar um mapa do ambiente é que o tank pode tomar boas decisões mesmo sem a ajuda do radar, economizando energia. Nesta atividade, será abordado o uso do mapa para guiar o tank em direção aos carregadores de energia e saúde, quando estiver com baixos níveis destes. A produção usada para controlar o comportamento do tank, nesta atividade, será a mesma produção mapping-bot.soar, usada anteriormente, acrescida de algumas modificações. Os passos seguintes demonstram as modificações necessárias que foram feitas para implementar o uso do mapa pelo tank.

1º Passo: detecção dos objetos

    Antes de realizar o procedimento de busca (seek) dos carregadores de energia e saúde, será necessário detectar a posição dos mesmos. Conforme navega pelo seu ambiente, o tank vai criando um mapa do mesmo. Ao passar sobre um desses objetos, Energy Charger ou Health Charger, (ou ao detectá-los pelo radar) o tank atualiza suas posições no mapa. Essas posições, em relação às células do mapa, serão usadas para ajudar o tank a navegar em direção a esses objetos. As estruturas de dados ^d-energy e ^d-health serão usadas para armazenar as informações sobre a detecção (^pheromone) e a decisão de buscar (^seek) os carregadores de energia e saúde. As regras da figura abaixo criam tais estruturas de dados na memória de trabalho:

    As regras responsáveis pela detecção dos carregadores de energia e saúde também estão ilustradas na figura acima. Essas regras detectam a presença dos carregadores quando o tank passa sobre algum deles (^io.input-link.energyrecharger yes e ^io.input-link.healthrecharger yes), alterando o valor dos atributos, das variáveis, relacionados a eles (<de> ^pheromone *yes* e <dh> ^pheromone *yes*). Todas as regras mencionadas, acima, disparam no super-estado inicial criado (^name tanksoar). As figuras abaixo exibem os resultados obtidos:

Energy Charger  detectado:

Health Charger detectado:

    Os textos "ENERGY DETECTED" e "HEALTH DETECTED" indicam que os carregadores de energia e de saúde foram detectados pelo tank, ao passar sobre eles. Tendo detectado esses objetos, agora o tank já pode decidir buscar os carregadores de energia e de saúde quanto seus níveis de energia e/ou saúde estiverem baixos.

2º Passo: proposição dos operadores

    A proposição dos operadores responsáveis pela busca dos carregadores de energia e saúde requer, primeiramente, que sejam detectadas as condições de baixo nível de energia e/ou saúde. As regras na figura abaixo são responsáveis por tal detecção. Essas regras também disparam no super-estado inicial (^name tanksoar). São verificados os níveis atuais de energia (^io.input-link.energy <= 200) e/ou saúde (^io.input-link.health <= 200) e, caso sejam baixos, serão configurados os atributos responsáveis pela busca dos carregadores de energia (^d-energy.seek *yes*) e/ou saúde (^d-health.seek *yes*).

    As regras da próxima figura propõe os operadores responsáveis pela busca dos carregadores (<o> ^name seek-energy e <o> ^name seek-health). Essas regras disparam quando as condições para busca (^d-energy.seek *yes* e ^d-health.seek *yes*) dos carregadores são atendidas. Os operadores de busca serão propostos com alta preferência de seleção (<s> ^operator <o> + =, >). A proposição desses operadores criará um novo sub-estado que será responsável pela proposição de novos operadores para realizar a busca "inteligente" dos carregadores.

    As figuras abaixo exibem os resultados obtidos:

Proposição do operador seek-energy:

Proposição do operador seek-health:

    Os textos, das figuras, indicam que foram detectados baixos níveis de energia ("LOW ENERGY") e saúde ("LOW HEALTH"), sendo propostos os operadores (seek-energy e seek-health) responsáveis pela busca dos carregadores de energia ("SEEK ENERGY") e de saúde ("SEEK HEALTH").

3º Passo: estratégia de busca

    A estratégia escolhida para realizar a busca dos carregadores de energia e de saúde consiste em marcar as células visitadas pelo tank, durante sua movimentação, após o tank ter passado sobre o carregador (de energia ou saúde). O controle da marcação das células é efetuado pelo valor do atributos ^d-energy.pheromone e ^d-health.pheromone. Inicialmente, tais atributos possuem o valor *no*; quando os carregadores são detectados, seus valores mudam para *yes*. Na condição de baixo nível de energia e/ou saúde, e tendo sido detectados os carregadores de energia e/ou saúde, os operadores de busca dos carregadores serão propostos, e, os valores dos atributos retornam para *no*. Ou seja, enquanto buscando pelo carregador (de energia ou saúde), interrompe-se a marcação das células visitadas pelo tank. A figura a seguir exibe as regras responsáveis pela marcação das células:

    Primeiramente, todas as células do mapa criado (^map <m>) terão um novo atributo (^e-pherom e ^h-pherom) configurado com o valor *no*. Em seguida, após os carregadores terem sido detectados (<de> ^pheromone *yes* e <dh> ^pheromone *yes*), as células por onde o tank move-se (<sq> ^x {<xt> <x>} ^y {<yt> <y>}) serão marcadas (<sq> ^e-pherom *yes* e <sq> ^h-pherom *yes*). Tendo marcado as células por onde o tank passa, ou seja, de posse do trajeto do tank de sua posição inicial até o carregador (de energia ou saúde), o próximo passo é seguir esse trajeto. As próximas figuras exibem os operadores responsáveis por esse procedimento:

Operador move:

Operador turn: (semelhante para turn-to-health)

    De acordo com as figuras acima, serão propostos dois operadores (move e turn) para direcionar o tank até os carregadores de energia e/ou saúde, seguindo o trajeto marcado até os mesmos. A preferência será pela seleção do operador move. Ou seja, o tank terá a tendência de se mover em linha reta (isso poderá ser problemático, conforme discutido logo a seguir). Quando não for possível seguir em linha reta, o tank girará na direção das células marcadas com "feromônio" (^e-squares <qs>). Foram escritas várias regras do tipo turn para cobrir todas as situações (direções) possíveis que o tank pode assumir durante sua busca pelo caminho que leva até os carregadores. Houve a necessidade de se incluir mais um operador turn para girar o tank quando não for possível seguir em linha reta e nem houver células adjacentes marcadas para onde o tank possa girar. Ou seja, nessa situação, o tank se moverá de volta pelo mesmo caminho que seguiu anteriormente. A próxima figura exibe as regras responsáveis por gravar as direções (células adjacentes marcadas com feromônio) que o tank deve seguir ou girar:

    Finalizando, após percorrer o caminho que leva até os carregadores, os atributos ^d-energy.seek e ^d-health.seek são configurados, novamente, com o valor *no* e os atributos ^d-energy.pheromone e ^d-health.pheromone são configurados com o valor *yes*. Ou seja, o tank deixa o modo seek e volta a marcar as células por onde passa, conforme as regras da figura abaixo. Após encontrar os carregadores de energia e/ou saúde, as células anteriormente marcadas (<sq> ^e-pherom *yes* e <sq> ^h-pherom *yes*) serão desmarcadas (<sq> ^e-pherom *no*) para que um novo trajeto possa ser traçado da posição atual do tank até os carregadores. A figura também exibe uma regra (seek*elaborate*radar-off) que desliga o radar enquanto o tank está no modo de busca dos carregadores.

Resultados

    A estratégia adotada possui um inconveniente: pode ocorrer do tank ficar preso num trajeto circular enquanto tenta encontrar o caminho de volta até os carregadores. Isso ocorre porque o tank sempre terá a preferência de seguir em linha reta ao invés de girar para um direção adjacente que contenha feromônio. Caso seja retirada essa preferência, ou seja, se o tank não tiver preferências por girar ou seguir em linha reta, ocorre do tank realizar uma busca "cega" pelo caminho de volta até o carregador: o tank passa ao lado do carregador e gira ao invés de se mover em linha reta até o mesmo.

    Esse problema pode ser evitado se o tank sempre se mantiver próximo dos carregadores de energia e saúde (^io.input-link.energy <= 750 e ^io.input-link.health <= 750). Ou seja, dessa forma será menos provável que o tank tenha tempo de executar um trajeto muito longo, cheio de curvas. Assim, há uma maior chance do tank não percorrer caminhos fechados e, portanto, conseguir fazer o caminho de volta até os carregadores. Esse problema poderia ser evitado se o tank tivesse uma preferência maior por selecionar células (direções) que ele tenha visitado com menor frequência. Ou seja, criando-se um atributo ^visited 0, em cada célula do mapa, e incrementando-o cada vez que o tank passasse por uma célula, seria possível criar regras de elaboração de operadores para dar uma preferência maior em girar para direções menos visitadas do que seguir em linha reta por células muito visitadas. Porém, não foi possível realizar essa tarefa devido a um incoveniente não contornado: ao tentar incrementar o valor desse novo atributo (^visited), a regra responsável por isso dispara várias vezes, suspendendo a execução do agente.

    Outro inconveniente dessa estratégia é que ela não funciona corretamente com mais de um tank no jogo. A proposição de alguns outros operadores (chase, retreat, wander) normalmente causa algum tipo de impasse ou outros problemas que fazem com que os tanks sejam re-instanciados em posições aleatórias. Ou seja, se um tank estiver tentando seguir seu caminho de volta até o carregador e for, repentinamente, levado para uma posição qualquer, pode ocorrer do tank não conseguir encontrar seu caminho e ficar girando em círculos. Poderia-se criar uma nova regra para move o tank, aleatoriamente, pelo terreno do jogo até que o tank encontrasse novamente uma célula adjacente marcada. Essa solução não foi adotada porque esse problema não está sendo gerado pela estratégia adotada, e sim, por outras regras usadas pelo tank. Seria interessante tentar re-escrever algumas dessas regras para sanar esses inconvenientes.

    Não foi tratada a situação do tank estar se movendo até os carregadores enquanto outro tank o está perseguindo. Essa situação pode ser tratada detectando (sensor RWaves) o sinal de radar de outro tank adversário que esteja atingindo o tank. Assim, nessa situação, o operador seek não seria mais proposto e poderia-se propor o operador retreat até a ameaça passar. Teria-se que localizar, novamente, as células marcadas para, só então, retomar o operador seek para levar o tank até os carregadores. O código deste projeto encontra-se disponível a seguir:

  Using the Map.rar

 

 

Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer