SOAR: Tutorial 3
Objetivo
Desenvolver as atividades propostas no tutorial 3 do SOAR. Nessa parte do tutorial, o objetivo é lidar com problemas mais complexos, cujas soluções exigem a decomposição de uma meta em metas intermediárias (subgoals). Para isso, deverá ser utilizado o pequeno jogo TankSoar, desenvolvido pelo grupo do Soar para ilustrar situações mais complexas. O nosso agente no TankSoar possuirá agora um grande número de possíveis ações e comportamentos, e o Soar deverá ser capaz de elaborar uma estratégia que coordene essas ações no tempo. Isso exigirá o uso do mecanismo de impasses e a criação de sub-estados, que iremos exercitar durante a aula.
Relatório das Atividades
Atividade 1
Foi executado o programa TankSoar cuja tela principal é mostrada na Fig. 1.1.
|
Fig. 1.1 - Tela principal do programa TankSoar. |
O ambiente do jogo pode conter os seguintes tipos de objetos:
- Obstacles
São representados como árvores e nunca se movem e não podem ser destruídos. Nenhuma parte do campo de jogo fica inacessível apenas pelo posicionamento de obstáculos. Isso pode acontecer, eventualmente, pelo bloqueio por outro tank. - Healthcharger
Há apenas um carregador de saúde em cada mapa de jogo. O recarregador de saúde nunca se move. A cada fase de decisão em que um tank fica sobre o recarregador de saúde, seu nível é acrescido de 150 unidades, subtraídos os danos causados por colisões com alguma coisa. - Energycharger
Há apenas um carregador de energia (bateria) em cada mapa de jogo. O recarregador de energia nunca se move. A cada fase de decisão em que um tank fica sobre o recarregador de saúde, seu nível é acrescido de 250 unidades, subtraídos os valores gastos com o uso do radar ou dos escudos. - Packs of missiles
Pacotes de mísseis são espalhados pelo mapa de jogo, em localização e com periodicidade selecionados aleatoriamente. Não são atingidos por mísseis passando por cima dos quadrados que ocupem. Podem ser obtidos por um tanque que se mova para o quadrado que ocupe, desaparecendo e incrementando de 7 mísseis o suprimento do tanque. - Tanks
Tanks são controlados por agentes Soar. Fazem coisas divertidas como disparar mísseis e se mover pelo mapa do jogo como descrito nos ítens anteriores.
Cada tanque possui recursos, sensores primários e sensores secundários, e pode executar algumas ações.
Recursos:
- Health
Um tank nasce com o valor máximo de 1.000 unidades de saúde e morre quando esse valor atinge zero. Quando um tank morre, ele é ressuscitado em um quadrado vazio selecionado aleatoriamente, com seus recursos reiniciados com os valores máximos. Se atingido por um míssel com os escudos desativados perderá 400 unidades. A cada rodada que o tank passar sobre um recarregador de saúde terá 150 unidades acrescentados. - Energy
Um tank nasce com o valor máximo de 1.000 unidades de energia. Esse valor é decrementado quando o tank usa o radar, proporcionalmente ao alcance configurado, ou quando usa os escudos (20 unidades por rodada). Se atingido por um míssel com os escudos ativados perderá 250 unidades. A cada rodada que o tank passar sobre um recarregador de energia terá 150 unidades acrescentados. Se o valor de energia atingir zero, o tank não poderá usar o radar ou oes escudos até que recarregue (ou morra e ressuscite). - Missiles
Um tank nasce com 15 mísseis. Quando um tank obtém um pacote de mísseis seu suprimento é incrementado de 7 unidades. Esse suprimento é decrementado de 1 unidade sempre que um míssel for disparado.
Sensores primários:
- Blocked
Indica se os quadrados imediatamente adjacentes ao ocupado pelo tank estão bloqueados ou não (valores yes ou no). Um quadrado pode estar bloqueado por um obstáculo ou por outro tank mas o sensor não permite distinguir entre eles. O sensor é atualizado no link de entrada mesmo que o tank não se mova ou que os valores não se alterem. - Incoming
Indica se há um míssel se aproximando do tank a qualquer distância a menos que o míssel esteja do outro lado de um obstáculo ou outro tank. O sensor não indica mísseis do próprio tank. - Radar
O radar de um tanque funciona quando é ligado e há energia suficiente para alimentá-lo. Este sensor deteta objetos à frente do tanque em uma coluna com três quadrados de largura. O alcance do radar é a distância d configurada ou o número de quadrados entre o tanque e o objeto de bloqueio mais próximo (ou seja, um tanque ou obstáculo) em frente a ela, o que for menor. Os objetos visíveis no radar são aqueles que estão a uma distância de d quadrados ou menos, diretamente em frente, diretamente em frente e um quadrado para a esquerda e diretamente em frente e um quadrado à direita do tanque. O Radar também deteta todos os objetos diretamente à direita ou à esquerda do tanque. Além disso, se a distância efetiva é maior do que d, ou seja, o radar está sendo bloqueado por um objeto, o(s) objeto(s) d + 1 quadrados em frente deste tanque também são visíveis no radar. Vários objetos no mesmo quadrado são visíveis se o quadrado é visível. As informações retornadas sobre objetos visíveis são o seu tipo e onde eles foram vistos (por exemplo, um obstáculo cinco quadrados em frente à esquerda). Se um objeto é um tanque, então sua cor também é dada. - Rwaves
O sensor de ondas de radar deteta se o radar de outro tanque está detetando o tanque a partir das quatro direções (à frente, atrás, à esquerda e à direita). - Smell
O sensor de cheiro deteta o tanque mais próximo e fornece informações sobre o quão perto o tanque está e qual é a sua cor. Se existirem dois ou mais tanques igualmente próximos, então um deles é escolhido de forma aleatória. A distância é o número de células em x e y entre os dois tanques (distância de Manhattan). O sensor de cheiro penetra obstáculos, de modo que o tanque "sentido" pode não ser o que está mais próximo. Se não houver outros tanques, ambos o valor de distância e de cor serão "nenhum". - Sound
O sensor de som detecta o tanque mais próximo que se movia durante a última decisão, enquanto que o tanque está actualmente 7 ou menos quadrados de distância. Se dois ou mais tanques moveu durante a última decisão e são igualmente perto, então o sensor escolhe um ao acaso. Se o tanque está dentro de 7 quadrados de distância, mas não se moveu durante a última decisão, não fará ruído e não será captado por esse sensor. A informação retornada sobre o tanque mais próximo é a direção para seguir em frente pelo caminho mais curto em direção ao tanque detetado. Se houver mais do que uma direção possível, então o sensor escolhe uma aleatoriamente. Se nenhum tanque se movia dentro de 7 quadrados de distância, o sensor de som terá o valor "silêncio".
Sensores secundários:
- Clock
O relógio é iniciado em 1 e é incrementado de um a cada fase de decisão. É um contador global para todos os tanques e, assim, se um tanque é criado depois que os outros já estavam se movendo por um tempo, o valor inicial não será 1. - Direction
A direção para qual o tanque está voltado: norte, sul, leste ou oeste. Muda quando o tanque gira. - Energy
Indica o nível de energia atual. Se igual a zero o tanque não poderá usar o radar ou os escudos. - Energy recharger
Se o tanque estiver sobre o carregador de energia seu valor será "sim"; caso contrário será "não". - Health
Indica o nível de saúde atual. Se igual a zero o tanque "morre" e será "ressuscitado" em um quadrado selecionado aleatoriamente. - Health recharger
Se o tanque estiver sobre um carregador de saúde seu valor será "sim"; caso contrário, será "não". - Missiles
Indica o número de mísseis que o tanque atualmente possui. - My-color
Indica a cor do tanque. - Radar-distance
Indica a distância efetiva do radar na última vez que esse foi usado. É a distância que radar alcançou antes de atingir um obstáculo. Se não havia obstáculo esse valor coincide com o valor de configuração. - Radar-setting
É o alcance configurado para o radar por meio do comando de saída radar-power. - Radar-status
Indica se o radar está ligado ou não. - Random
Fornece um número real aleatório entre 0 e 1. Muda a cada fase de decisão. - Ressurrected
Sempre que o tanque morre e ressuscita seu valor é "sim". - Shield-status
Indica se os escudos estão ligados ou não. - X
Indica o valor da cordenada no eixo X. Varia de 1 (lado esquerdo) a 14 (lado direito). - Y
Indica o valor da coordenada no eixo Y. Varia de 1 (lado superior) a 14 (lado inferior).
Ações:
- Move
Um tanque pode se mover para a frente, para trás, para a esquerda ou para a direita. A ação mover é mutuamente exclusiva com a ação girar. Se um tanque tenta se mover, mas é bloqueado, permanece onde está e perde 100 unidades de saúde. Um tanque também pode se mover em nenhuma direção, o que indica uma ação de espera. - Rotate
Um tanque pode girar para a esquerda ou direita. A ação girar é mutuamente exclusiva com a ação mover. A rotação nunca falhará (assumindo que o tanque não está nem morto nem tenta se mover simultaneamente). - Fire
Um tanque pode disparar um míssil por decisão. O disparo pode ser executado em conjunto com qualquer outra ação. O míssil é disparado para a frente na direção para a qual o tanque está voltado. Disparando um míssil diminui o suprimento de mísseis do tanque por um, e falhará se o tanque não possuir mísseis. - Radar
Um tanque pode ligar ou desligar o seu radar. Ligar o radar falhará se o tanque não possuir energia suficiente para alimentá-lo. Essa falha será refletida no ajuste do sensor radar-distance para o nível mais alto possível. - Radar Range
Um tanque pode alterar o alcance do seu radar usando o comando radar-power. O valor pode ser de 1 a 14. Quanto maior alcance ajustado para o radar, mais energia é usada. - Shields
Um tanque pode ligar ou desligar os seus escudos, e isso pode ser feito em conjunto com qualquer outra ação. Ligar os escudos consome 20 unidades de energia por decisão. E irá falhar se o tanque não possuir energia suficiente. O fracasso será refletido no valor "desligado" para o sensor shield-status.
O programa TankSoar foi executado com dois agentes controlados pelas regras simple-bot. As telas do programa e do SoarDebugger para cada agente, ao final da execução, são mostradas nas Fig. 1.2, Fig. 1.3 e Fig. 1.4, respectivamente.
|
Fig. 1.2 - Tela do programa TankSoar ao final da execução com dois agentes controlados pelas regras simple-bot. |
|
Fig. 1.3 - Tela do SoarDebugger para a agente vermelho, ao final da execução do programa TankSoar com dois agentes controlados pelas regras simple-bot. |
|
Fig. 1.4 - Tela do SoarDebugger para a agente azul, ao final da execução do programa TankSoar com dois agentes controlados pelas regras simple-bot. |
Atividade 2
O Tutorial 3 descreve o desenvolvimento de um agente para o TankSoar, partindo de uma versão simples (wander) à qual são adicionados comportamentos mais complexos (deteção melhorada de som – simple-sound-bot; criação de mapa – mapping-bot).
O wander tank vagueia pela área do jogo procurando por objetos, usando os sensores para evitar obstáculos e detetar outros objetos.
Em seguida o agente é melhorado com a inclusão de uma hieraquia de operadores, onde os operadores de nível mais alto representam objetivos e contém operadores em nível mais baixo que representam os objetivos intermediários (tarefas que combinadas permitem atingir os objetivos).
Além da organização do obetivo wander em seus objetivos intermediários (move e turn), são acrescentados outros obejtivos (chase, attack e retreat). A hieraquia de operadores é mostrada na Fig. 2.1.
|
Fig. 2.1 - Hieraquia de operadores. |
A evolução continua com a melhoria do recurso de deteção de sons e com a capacidade de construir um mapa do ambiente.
As Fig. 2.2 e 2.3 mostram as telas do jogo e do debugger para a execução de um agente com as regras mapping-bot.
|
Fig. 2.2 - Tela do jogo com o agente mapping-bot. |
|
Fig. 2.3 - Tela do debugger com o agente mapping-bot, mostrando a estrutura do mapa contendo um pacote de mísseis (S44) e o recarregador de energia (S45). |
Atividade 3
Um programa Soar foi desenvolvido para permitir que o tanque além de suas atividades normais, utilize o mapa do ambiente para se dirigir aos carregadores de energia e saúde, quando estiverem com baixa energia ou baixa saúde.
A proposta de solução é criar um operador de alto nível, move-to-target, selecionado quando o tank estiver com baixa energia ou baixa saúde, quando houver o recarregador correspondente mapeado, e que não esteja sob ataque, detetando o som de outro tanque ou detetando um míssel vindo em sua direção. O operador move-to-taget deve conter suboperadores para mover e girar (move e turn) de acordo com a posição relativa ao recarregador mapeado.
A primeira abordagem para determinar a posição relativa foi computar a diferença entre a posição absoluta do recarregador mapeada e a posição absoluta do tanque, de forma a permitir a sua associação às ações move e turn e as direções correspondentes. Mas não foi possível obter uma implementação funcional que executasse as operações aritméticas necessárias.
A abordagem adotada foi a criação de uma estrutura auxiliar que permitisse o mapeamento da posição relativa dos recarregadores em relação ao tank e a direção relativa dependente da orientação do tank a cada momento (Fig. 3.1 e Fig. 3.2). Assim, regras de elaboração no top-state atualizam as direções relativas a cada movimento do tank (Fig. 3.3). Esses valores orientarão a proposição dos operadores de baixo nível, move e turn, de forma a que o tank se movimente na direção dos recarregadores, priorizando o de energia (Fig. 3.4). Também foi necessária a inibição do operador wander quando o operador move-to-target for ativado (Fig. 3.5)
O problema encontrado foi a solução dos conflitos entre as diversas proposições de movimento. Dentro do tempo disponível para execução da atividade não foi possível convergir para uma solução 100 % funcional.
O projeto está disponível através do link move-to-target-bot.zip.
|
Fig. 3.1 - Definição de variáveis no top-state para indicar nível baixo de energia ou saúde. |
|
|
Fig. 3.2 - Definição da estutura auxiliar para mapeamento de posição relativa dos carregadores em relação a posição do tank. |
|
Fig. 3.3 - Elaboração para a direção relativa de um recarregador em relação a posição do tanque. |
|
Fig. 3.4 - Tela do Visual Soar mostrando o operador move-to-target e seus operadores de baixo nível move e turn. |
|
Fig. 3.5 - Inibição do operador wander nas condições de ativação do operador move-to-target. |
|
Fig. 3.6 - Tela do jogo no momento em que ocorre um impasse. |
|
Fig. 3.7 - Tela do debugger mostrando a elaboração para a direção relativa dos recarregadores, a ativação do operador move-to-target para energia, a ativação do operador de baixo nível move e o impasse state no-change. |