João Leitão's Homepage : Research : Hemisson's Robot

Projecto de Vida Artificial (2005/2006): Hemisson's Robot
Faculdade de Ciências da Universidade de Lisboa

Autores:

Downloads: [Código fonte (Java)][Jar][JavaDoc]

Contents

Introdução e contexto

Neste trabalho usamos a robótica e mais especificamente robots hemisson como base de implementação e teste para um conjunto de comportamentos "interessantes" mas cuja base (e.g. regras orientadoras ou codificação) é simples.

No entanto a implementação destes comportamentos em robôs é acompanhada de todo um conjunto de problemas que não são visíveis por exemplo quando se usam ferramentas do género do net-logo ou outras ferramentas de simulação, estes problemas estão tipicamente associados à necessidade das acções do indivíduo que executa o algoritmo (nestecaso um robot hemisson) de tempo real, assim como a existência de delays (atrasos) sempre que é necessário efectuar uma leitura ou enviar instruções para o mesmo. Outros problemas existentes passam pela inexistência de um referencial "universal" (e.g. comum a todos os indivíduos) algo que dificulta bastante a coordenação entre vários robots.

Estes problemas são no entanto a (grande) mais valia que se obtém ao usar a robótica na implementação de comportamentos quando se pretendem que estes possam ser encontrados em alguns seres vivos; é necessário assumirmos que, no mundo real, os processos de obtenção de informação sensorial, avaliação dos mesmos e decisão consomem um certa quantidade de tempo ao individuo (quantidade essa que nem sempre pode ser desprezada).

Este trabalho é, de certa forma, uma primeira abordagem para encontrar mecanismos para conviver e ultrapassar este problema. Para tal decidimos elaborar, implementar e testar um conjunto de comportamentos simples cuja complexidade cresce de forma progressiva.

Apresentamos a metodologia que decidimos aplicar para a implementação destes comportamentos (para robôs hemisson), e sugerimos ainda uma outra metodologia baseada numa framework (desenvolvida em Java) que permita de forma razoavelmente simples a implementação e composição de comportamentos elementares (e.g. construir sequências de comportamentos dependentes de eventos específicos para transitar entre os mesmos) para a obtenção de comportamentos mais elaborados.

Este trabalho foi realizado no contexto da cadeira de Vida Artificial (ano lectivo 2005/2006) inserida na licenciatura em Engenharia Informática da Faculdade de Ciências da Universidade de Lisboa.

[K-Team][Hemisson][Net-Logo][Breve][Vida artificial]

Ambiente de trabalho

Os robôs hemisson que utilizámos encontravam-se equipados com uma placa bluetooth o que permite que o programa que controla o robot possa ser executado num computador que lê os valores dos sensores e emite comandos para o robot através de bluetooth, esta técnica introduz-nos o problema dos delays de comunicação tanto na leitura de valores dos sensores como no envio de ordens para o robot mas permite-nos codificar o comportamento do robot em qualquer linguagem de programação (desde que suporte sockets), e não ter limites no tamanho dos programas que são executados. Ganhamos também poder de processamento e memória, visto que, na maioria dos casos, o processador e a memória existentes num computador serão bastante superiores aos disponíveis no robot.

A linguagem de programação que optámos por utilizar foi a linguagem Java isto porque nos foi disponibilizada um conjunto de classes que facilitam a interacção com robots hemisson recorrendo a bluetooth mas também porque conhecíamos bem a linguagem e o paradigma de programação orientada a objectos nos parece ser útil para o desenvolvimento de comportamentos, que mais tarde, poderemos querer combinar e fazer evoluir.

Utilizámos e recomendamos vivamente a utilização do ambiente de desenvolvimento: Eclipse.

[Imagem: robot hemisson][Imagem: localização sensores][Java][Eclipse]

Trabalho Desenvolvido

Metodologia

Como já referimos implementámos um conjunto de comportamentos crescentemente complexos, sendo que experimentámos implementar variantes dos mesmos comportamentos por forma a testar os resultados obtidos através de diferentes abordagens e técnicas de programação úteis neste caso específico.

Implementámos uma interface genérica que define um comportamento do robot, a que chamámos TarefaRobot, esta classe estende a classe Thread, a ideia é que um comportamento de um robot deve ser um fluxo de execução independente, o que permite entre outras coisas a uma única aplicação java lançar vários comportamentos (iguais ou distintos) sobre um único robot ou sobre vários. A ideia de um comportamento ser uma Thread surge também como forma de demarcar a nossa opinião de que cada comportamento deve ser uma entidade isolada, distinta por exemplo da aplicação que o lança.

A classe TarefaRobot mantêm a referência para a instância de robot que se encontra a executar a tarefa, e fornece métodos para interromper a execução de uma certa tarefa, para além disso esta classe materializa (no seu método run) um ciclo de controle que invoca a função (definida como função abstracta na classe) runOnce, todas as classes que estendem esta classe (e.g. que implementam um comportamento específico) devem implementar este método. A implementação do método runOnce deve, segundo a nossa visão, executar um passo simples do algoritmo que materializa o comportamento, este passo deve começar com uma leitura dos valores dos sensores, algum processamento sobre os valores obtidos e eventualmente mudanças do estado interno da instância que se encontra em execução e finalmente deve enviar uma instrução para o robot para este se deslocar (ou imobilizar), ao longo do processamento recomendamos ainda que, para sinalizar mudanças do estado interno ou outra situação especial, se envie para o robot uma instrução para que este emita um conjunto de beep's, no entanto deve se ter em atenção que cada beep emitido irá custar no mínimo 50 ms à execução do código, o que pode ser bastante prejudicial para alguns algoritmos (ou até mesmo incomportável). Uma implementação simples de uma tarefa (andar continuamente em frente lendo os sensores) pode ser encontrada aqui.

[Exemplo da implementação duma tarefa][classe TarefaRobot]

Tarefas implementadas

Segue-se uma descrição das tarefas implementadas.

Tarefa Segue Linha

A primeira tarefa que implementámos foi a de seguir uma linha (preta num fundo branco). Optámos por esta tarefa por vários motivos nomeadamente o facto de este problema ter uma formulação simples, envolvendo apenas a "monitorização de dois sensores; mas também porque os robots hemisson vêm com um programa de fábrica para realizar esta tarefa, por outro lado apesar da sua aparente simplicidade, a resolução deste problema já envolve alguns requerimentos de reacções dentro de uma "janela temporal de utilidade" (e.g. fazer uma curva antes do robot sair da linha).

Para a resolução do problema de seguir uma linha, decidimos que seria mais simples ter uma noção de distinção entre branco e preto nos valores obtidos dos sensores (apontados para o chão), esta abordagem, apesar de intuitiva, possuí alguns problemas associados, os sensores dos robots são independentes entre si, possuem uma calibração distinta entre si, e os valores obtidos por cada sensor depende de factores externos como por exemplo a luminosidade do ambiente, ou a carga da pilha. Por isso foi necessário criar um mecanismo para calibrar os sensores, esta calibração tem por objectivo determinar um valor limiar (para cada um dos sensores direito e esquerdo) entre as duas cores do ambiente (preto e branco).

Esta calibração realiza um conjunto de medições (em movimento) sobre as duas cores, e recolhe um conjunto de valores. O valor limiar para cada sensor é obtido através da média entre o valor de uma superfície preta mais baixo observado e o valor de uma superfície branca mais baixo observado. A calibração é materializada numa classe (AvaliadorAmbiente) que estende uma classe genérica para realizar calibrações de sensores chamada Avaliador.

O algoritmo desenhado para resolver este problema é bastante simples e pode ser esquematizado como uma máquina de estados com apenas um estado; o algoritmo é baseado na repetição de um mesmo passo em ciclo. Em cada iteração do ciclo de controle avaliamos os valores obtidos dos sensores apontados para o chão de seguida tomamos uma decisão com base no "estado" destes sensores:

  • Ambos os sensores numa superfície negra: Avançar em frente.
  • Apenas o sensor esquerdo numa superfície negra: Curvar ligeiramente à esquerda.
  • Apenas o sensor direito numa superfície negra: Curvar ligeiramente à direita.
  • Ambos os sensores numa superfície branca: depende do estado dos sensores na iteração anterior:
    • ambos os sensores estavam numa superfície negra: Voltar atrás.
    • apenas o sensor esquerdo estava numa superfície negra: Curvar fortemente à esquerda.
    • apenas o sensor direito estava numa superfície negra: Curvar fortemente à direita.
    • ambos os sensores estavam numa superfície negra: Vaguear aleatoriamente pelo mundo.

Supondo que o processamento de cada iteração do algoritmo poderia ser demorado demais, o podia introduzir um atraso grande demais para o envio de novos comandos com velocidades para os motores do robot hemisson (o que poderia levar a perder a linha), para resolvermos este problema decidimos que no final de cada iteração apenas executávamos o movimento decidido pelo algoritmo durante 500 ms findos os quais enviávamos ao robot uma nova instrução para que este imobilizasse o seu movimento. Isto leva a que o robot se encontre parado durante toda a execução da iteração. Descobrimos que este funcionamento permitia que o robot conseguisse seguir algumas pistas - tipicamente com curvas muito apertadas - que não eram exequíveis sem este comportamento de paragem.

[Ver vídeo (versão do algoritmo sem paragens)][classe SegueLinha][classe Avaliador][classe AvaliadorAmbiente][

Tarefa Segue Linha (algoritmo sem paragens)

Todo o código e comportamento desta tarefa é igual ao da tarefa SegueLinha com a excepção de que nesta tarefa não executamos o movimento no final de cada iteração durante um período limitado e não realizamos, por isso, qualquer paragem.

A vantagem desta modificação é de que o comportamento do robot fica mais rápido. No entanto descobrimos que com alguns percursos específicos o robot acaba por perder a linha preta de vista, especialmente em curvas muito apertadas.

Aqui fica uma técnica que pode ser interessante a aplicar quando a computação executada em cada iteração do ciclo de controle do robot é demorada demais, usar paragens ao longo do ciclo de execução para permitir um controle mais "fino" do comportamento do mesmo.

[Ver vídeo][classe SegueLinhaFast]

Tarefa Passear

Seguindo os mesmos motivos que nos levaram à implementação do comportamento de seguir uma linha, decidi-mos de seguida implementar o comportamento de passear num "mundo" evitando obstáculos. Chamámos a tarefa que materializa este comportamento Passear. Esta tarefa já envolve a monitorização de um conjunto maior de sensores (seis, sendo que não se monitorizam os dois sensores que estão direccionados para o chão e o sensor que aponta para a parte de trás do robot).

Optámos por, neste comportamento, fazer com que o robot se desloque sempre para a frente até que encontre um obstáculo, este comportamento leva a que a porção do "mundo" que é explorada não seja muito grande no entanto parece ser um comportamento intuitivo para implementar.

Como em todos os algoritmos que criámos este é bastante simples, sendo composto por um ciclo de controle, em cada iteração deste ciclo começamos por obter os valores dos sensores do robot, de seguida observamos em que direcções (e.g. quais os sensores) é que localizamos algum obstáculo, esta operação é realizada comparando o valor obtido de cada sensor com um valor definido como uma constante (a constante obstaculoLimiar definida por nós com o valor 20 - este valor foi obtido por tentativa e erro), como já referimos anteriormente, os valores de limiar devem ser calculados de forma independente para cada sensor, no entanto optámos - essencialmente devido à falta de tempo - em não implementarmos um novo avaliador de ambiente para este problema.

Finalmente quando obtemos a lista das direcções onde identificamos um obstáculo, seleccionamos uma direcção para onde nos vamos deslocar, no caso de não se detectar nenhum obstáculo deslocamo-nos (por defeito) para a frente, se não seleccionamos a direcção correspondente ao sensor do qual obtivemos o menor valor na leitura inicial, a ideia aqui é deslocarmo-nos para o espaço "mais aberto", a forma como tomamos esta decisão também não é ideal, visto que os sensores possuem calibrações independentes, os valores dos vários sensores não deveriam ser comparados directamente entre si, sem ser pré-processados com informação proveniente de um processo de calibração inicial (e.g. o avaliador de ambiente que não implementámos).

Quando definimos a direcção para onde nos pretendemos deslocar, efectuamos (se necessário) uma rotação com o robot sobre si mesmo para orienta-lo nessa direcção, esta rotação é conseguida com o auxilio da classe Direccao, é de notar que esta classe não oferece garantias de que o robot fique perfeitamente alinhado na direcção pretendida, isto porque também esta classe usa constantes definidas por tentativa e erro, em vez de, valores obtidos através de um processo prévio de calibração, no entanto esta classe fornece uma aproximação válida e um serviço de mais alto nível que é bastante útil.

Finalmente para terminar a iteração do ciclo de controle é enviado ao robot uma instrução para se deslocar em frente. Como uma nota, este algoritmo consegue evitar algumas situações de "bloqueio" que o algoritmo de origem dos robots hemisson não consegue evitar.

[Ver vídeo][classe PassearFugir][classe Direccao]

Tarefa Passear (algoritmo alternativo - mais agressivo)

Como referimos, no algoritmo anterior existe o problema da percentagem de "mundo" coberta pelo robot ser relativamente pequena, este problema deve-se em parte ao facto de o robot se deslocar sempre para a frente até que encontre um obstáculo. Tentamos solucionar esta questão com um algoritmo alternativo ao anterior a que chamámos passearFast.

Outro motivo que nos levou a desenhar este algoritmo é o facto de termos notado que o o algoritmo que vêm com os robots hemisson para evitar obstáculos e o algoritmo que criamos originalmente (Tarefa Passear) ser bastante diferente deste algoritmo, tentámos nesta versão alternativa criar um comportamento mais parecido com o algoritmo dos robots hemisson, pelo que este algoritmo é bastante diferente do algoritmo anterior.

Começamos, como sempre, as iterações do ciclo de controle com a leitura dos sensores do robot. Neste algoritmo apenas monitorizamos quatro sensores, os sensores à frente do lado direito e esquerdo e os sensores dos lados esquerdo e direito. Usamos mais uma vez constantes para definir o valor limiar dos sensores a partir do qual se considera que este está a detectar um obstáculo (os problemas desta abordagem já foram explicados no algoritmo anterior.

Atribuímos aqui um valor de base à velocidade que será comunicada a cada um dos motores, e aumentamos esta velocidade por cada sensor do lado desse motor que detecte um obstáculo. No caso de os sensores de cada lado do robot detectarem o mesmo numero de obstáculos, para evitar que o robot fique preso num movimento contra uma parede, enviamos uma instrução para que este se desloque para trás e de seguida para efectuar um deslocamento aleatório.

Doutra forma, no caso de qualquer um dos sensores ter detectado um obstáculo usamos a velocidade calculada no passo inicial, no caso de nenhum sensor ter detectado qualquer obstáculo, então introduzimos uma mudança aleatória sobre os valores de base dos motores, a intenção desta mudança aleatória é a de evitar fazer deslocamentos em frente e portanto cobrir uma maior área de exploração.

Devido ao facto deste algoritmo produzir muitos movimentos curvos, descobrimos, enquanto o testávamos que era bastante simples o robot bloquear-se em alguns ângulos contra superfícies de forma que apesar deste calcular velocidades distintas para os motores já não conseguia sair da posição em que estava, para resolver esta situação quando é detectado um obstáculo, as velocidades calculadas são comparadas com as velocidade calculadas na iteração anterior, se se passarem um número (definido como a constante limiarRepeticao) de iterações em que se calculam sempre os mesmos valores para os dois motores, então podemos assumir que nos encontramos numa situação de bloqueio, e para tentar escapar desta o que fazemos é inverter as velocidade calculas (gerando um movimento curvo para trás).

Verificamos que a utilização de valores aleatórios, apesar de interessante e de permitirem obter um comportamento mais interessante, trás nos alguns problemas, como por exemplo o ser mais fácil chocar contra obstáculos ou bloquear o robot em obstáculos específicos.

[Ver vídeo][classe PassearFugirAgressivo][classe PassearFugir][classe Direccao]

Tarefa Passear (algoritmo alternativo com paragens)

Como forma de tentarmos minimizar o problema de "choques" com obstáculos que foram verificados no algoritmo anterior, e os problemas de bloqueio, tentámos aplicar nesse comportamento a técnica de paragens (e.g. efectuar todo o processamento com o robot parado, e efectuar os movimentos no final das iterações por um tempo limitado exactamente como fizemos na nossa primeira tentativa de seguir uma linha).

Não efectuamos qualquer outra alteração ao comportamento e acabámos por observar que os resultados obtidos com esta nova abordagem foram os mesmos do algoritmo anterior, excepto claro que o movimento do robot passou a ser muito mais lento.

[classe PassearFugirAgressivoTurnos][classe PassearFugirAgressivo]

Tarefa Detectar Movimento

O passo seguinte foi o de arranjarmos uma solução que permita a um robot hemisson detectar (com os seus sensores apenas) a presença de um outro robot. Este passo é essencial para se poderem desenvolver comportamentos colaborativos entre vários robots e é um bloco fundamental por exemplo no contexto da disciplina de vida artificial (em que a interacção entre vários elementos é objecto de estudo).

Apesar da importância deste "comportamento", a forma de o obter (com os recursos limitados de que dispomos) não é imediata, os sensores dos robots hemisson permitem-nos detectar obstáculos, mas daí a perceber que o obstáculo é uma parede ou outro robot não é simples, a noção de cor por exemplo "não existe" com sensores deste tipo.

A solução que apresentamos não é óptima no entanto foi a única que encontramos, basicamente a forma como iremos distinguir entre um obstáculo que é uma parede (ou um objecto inanimado) e um outro robot é o facto de que outro robot terá movimento. Assim no fundo distinguimos entre objectos com e sem movimento (um dos problemas desta solução é que um robot que esteja parado não será identificado como um robot), para isto usamos um algoritmo relativamente simples.

  • O robot passeia no mundo até detectar um obstáculo num dos seus sensores (esta detecção é feita da mesma forma que explicámos na tarefa Passear)
  • Ao detectar o obstáculo o robot pára o seu movimento
  • Nas N iterações seguintes o robot irá verificar se o obstáculo se deslocou (nesse caso será lido um valor no sensor que está a apontar para o obstáculo que terá uma diferença em relação ao valor original maior que um certo intervalo de tolerância):
    • Se durante as N tentativas for detectado movimento, então o comportamento termina a sua execução e considera que aquele obstáculo é um robot
    • Se ao fim das N tentativas não for detectado qualquer movimento, então assume-se que o obstáculo era de facto um obstáculo, e o robot afasta-se deste e continua até encontrar um novo obstáculo.

Este comportamento foi implementado numa tarefa a que chamámos Detectar, esta implementação, tal como aconteceu nas últimas usa valores constantes que foram obtidos por tentativa e erro, e apesar do nome da classe (DetectarRobot), qualquer movimento como por exemplo uma mão a passar janto de um dos sensores do robot, será considerado como tendo detectado um robot.

[classe DetectarRobot]

Tarefa Passear com detecção de movimento

Visto que tínhamos um comportamento para passear e desviar de obstáculos, e outro comportamento para detectar robots (ou aliás, objectos com movimentos), decidimos combinar os dois comportamentos, visto que não temos uma forma "automática" para efectuar a combinação de duas tarefas implementámos um novo comportamento em que usámos código dos dois comportamentos definidos anteriormente, sendo eles o passear e detectar. Chamámos ao comportamento resultante Passear com Detecao, o interesse de termos realizado esta tarefa é o de mostrar que é importante arranjar um mecanismo que permita a combinação de um ou mais comportamentos já definidos, para evitar o esforço de recombinar e adaptar código apenas para combinar comportamentos já definidos.

[Ver vídeo][classe PassearFugirDetect]

Tarefa Encaminhar-se para um objectivo

Decidimos elaborar mais o comportamento de detecção, fornecendo ao robot a capacidade de distinguir entre dois tipos de movimentos distintos, o movimento estacionário (e.g. sem sair do mesmo local) e um movimento "normal" em que o objecto se desloca efectivamente.

Para implementar esta distinção usámos o código que elaboramos para a tarefa anterior, e em vez de terminarmos a execução do comportamento quando determinamos que um objecto se encontra em movimento, aquilo que fazemos é interromper a execução do comportamento (e.g. usando a função da classe Thread: sleep()) e repetindo (ao fim de um certo tempo) o processo de detecção. Isto vai permitir que quando um objecto se encontra em deslocamento "normal" apenas irá interromper a execução do comportamento temporariamente até este se afastar do raio de detecção dos sensores dos robot.

Num espaço em que exista um robot que apenas possui um movimento de rotação sobre si mesmo (vamos chamar a este robot "beacon") e um outro robot que executa o comportamento de passear (ou simplesmente o algoritmo que vem de fábrica nos robots hemisson), um robot que execute o comportamento que definimos aqui irá passear no mundo até encontrar o beacon e parar junto de este (este comportamento pode ser chamado de "homing"), mesmo que se cruze com outro robot que apresente um comportamento de passear, o robot que execute este comportamento irá avalia-lo como sendo um robot e após este afastar-se irá prosseguir na sua "procura" pelo beacon.

Outro efeito interessante deste comportamento é que se o robot já estiver parado junto ao beacon e este mudar de posição (e.g. porque nós o movemos para uma nova localização do mundo), o robot passado algum tempo irá descobrir que o beacon desapareceu e voltará a iniciar a sua procura no mundo por este.

Devido a alguns problemas com as ligações bluetooth, o nosso teste final deste comportamento envolvia apenas três robots, um era controlado pela nossa consola e efectuava um movimento continuo de rotação sobre si mesmo, outro estava a executar o programa de passeio (e desvio) que se vem de fábrica nos robots hemisson e finalmente um robot executava este comportamento.

[Ver vídeos][classe PassearFurgirDetect]

Consola

Para facilitar o desenvolvimento de comportamentos e testar o resultado de algumas instruções, decidimos criar uma consola que facilitasse a execução destes comandos.

Esta consola a que chamamos HemissonConsole, é na realidade uma aplicação java que estabelece uma ligação (através de bluetooth) com um robot hemisson, e envia comandos para esse robot de acordo com as instruções que recebe da linha de comandos (tem portanto um interpretador de comandos), para além disso integramos nesta consola mecanismos para lançar tarefas de controle sobre o robot.

Um nova versão desta consola encontra-se já em desenvolvimento, esta nova versão pretende essencialmente permitir que se controlem vários robots hemisson a partir de uma mesma consola.

Segue-se o output do comando help executado na consola, que mostra uma lista dos comandos disponíveis na mesma.

Consola para controle de robots Hemisson

Comandos disponíveis

Help: mostra esta mensagem
infmove Esq Dir: Efectua o movimento com os valores Esq e Dir nos motores esquerdo e direito, e desactiva a consola
move Esq Dir: Efectua o movimento com os valores Esq e Dir nos motores durante 1 segundo
read: Mostra os valores obtidos pelos sensores de distancia (Sonar)
readl: Mostra os valores obtidos pelos sensores de luz (Light)
rt Direccao: Permite efectuar um movimento de rotação

Direccao pode tomar valores: esquerda, direita, trás execute Tarefa: Lança uma Thread que executa uma certa operação Tarefa pode tomar os seguintes valores:
passear - Tarefa para passear num mundo desviando se de obstáculos
linha - Tarefa para seguir uma linha preta num chão com paragens (branco) envolve calibração de sensores
linhaFast - Tarefa para seguir uma linha preta num chão sem paragens (branco) envolve calibração de sensores
detect - Tarefa para passear detectar outro robot (objecto em movimento) num espaço
passearFast - Tarefa para passear num mundo desviando se de obstáculos (algoritmo mais agressivo)
passearTurnos - Tarefa para passear num mundo desviando se de obstáculos (algoritmo mais agressivo com pausas)
passearDetect - Tarefa para passear num mundo desviando se de obstáculos e parar quando detecta um robot
passearDetectBeacon - Tarefa anterior que só para se estiver perante um beacon (robot em rotação)
Stop: coloca valores zero em ambos os motores do robot

[classe HemissonConsole][classe AdvancedHemissonConsole (trabalho incompleto)]

Trabalho Futuro

Existe muito espaço para melhoramentos neste trabalho, a nossa recomendação seria a de em primeiro lugar resolver os muitos problemas que, ainda, existem na comunicação recorrendo a bluetooth, durante a realização deste trabalho esta foi a maior dificuldade sentida.

As sugestões que implementamos para cada um dos comportamentos que abordámos são apenas isso: sugestões. Outras formas de abordar os problemas existem e devem ser experimentadas e implementadas, preferencialmente seguindo uma metodologia padrão, por forma a poder comparar mais facilmente as implementações.

Parece-nos essencial que se desenvolva um mecanismo para combinação de comportamentos já definidos, por forma a elaborar - sem grande esforço - novos comportamentos a partir de comportamentos já implementados, a nossa sugestão passa pela criação em java de uma framework de composição se comportamentos, esta framework deve primariamente definir um conjunto de componentes genéricos que podem fazer parta da implementação de um comportamento para um robot hemisson, como por exemplo a definição genérica de comportamento (que nós materializámos na classe abstracta tarefa), mas também a definição de um mecanismo de avaliação de condições (e.g. valores dos sensores) genérica.

Esta framework deve suportar no mínimo dois mecanismos de combinação de comportamentos, um mecanismo "linear" em que existem transições entre vários comportamentos de acordo com regras e condições da execução do comportamento, sendo que este tipo de combinação pode ser esquematizado por uma máquina de estados com vários estados em que cada um destes representa um comportamento base.

O outro mecanismo de composição que esta framework deve suportar é um mecanismo "paralelo", ou seja, um mecanismo que permita executar paralelamente um conjunto de comportamentos, em que cada um destes tem acesso aos dados dos sensores e gera um "resultado" ou seja valores para os motores do robot. Os valores gerados por todas estas tarefas seriam então compostos de acordo com regras que poderiam levar em conta prioridades das várias tarefas em execução ou outra medida qualquer relativa de peso, e gerar os valores finais de velocidade para os motores que seriam então comunicados ao robot controlado. Este mecanismo deve evidentemente suportar a adição e remoção em tempo de execução de comportamentos à lista de comportamentos paralelos em execução.

Durante a realização deste trabalho ponderámos implementar um protótipo muito simples do mecanismo de combinação linear, no entanto não tivemos tempo para concluir este objectivo, no entanto poderão ainda ser encontradas algumas classes que foram criadas com esse objectivo.

Conclusões

Neste trabalho apresentamos um conjunto de soluções possíveis para a implementação de um conjunto relativamente simples de comportamentos para robots hemisson.

Apresentamos ainda uma sugestão de uma metodologia para a implementação destes comportamentos, fornecemos ainda algumas ferramentas (classes genéricas e uma consola de controle) para auxiliar alguém que pretenda implementar um comportamento para estes robots.

Finalmente sugerimos algum trabalho que pode ser feito, dentro deste contexto, no futuro e sugerimos a especificação de uma framework que seria bastante útil para a produção, desenho e composição de comportamentos mais complexos e elaborados para robots hemisson, esta framework, apesar de originalmente ter sido especificada para robots hemisson, pode sem grande esforço ser estendida para controlar outro tipo de robots em tempo real. As hipóteses são infinitas.