Conteúdo sugerido

Normalmente, os programas dos robôs que criamos não podem ser feitos de forma seqüencial e direta. O mesmo programa pode ser responsável por ler sinais de sensores, controlar vários motores, perceber obstáculos, tomar decisões relacionadas aos estados dos sensores, etc.

Para criarmos programas capazes de tratar todas essas questões, podemos lançar mão de várias técnicas de programação que são chamados de Design patterns.

Existem muitos desses padrões de desenvolvimento, criados para lidar com uma infinidade de problemas como inteligência artificial, processamento de alta performance e concorrência de processos, problemas de tempo real, problemas de relacionamento entre máquinas e tarefas, etc.

Um padrão de desenvolvimento muito simples e que usamos muito em nossos robôs é a Máquina de Estados Finitos.

Sua concepção parte da seguinte premissa:
Um dispositivo que possui um conjunto finito de estados e aceita um finito numero de entradas, pode produzir um finito numero de diferentes saídas. Este dispositivo deve ter uma memória que possa armazenar a seqüência de entradas recebidas, de forma que a saída seja dependente destas entradas.
No nosso caso vamos criar um exemplo imaginando assim:

Um robô  precisa se deslocar pelas ruas de uma cidade procurando uma caixa, se encontrar ele deverá levar a caixa a um lugar pré-determinado.

Uma variável Global chamada estadoatual é quem indica o estado que está ocorrendo. Antes de criá-la nós definimos quais estados existem para o nosso sistema (se é finito agente pode definir!).

typedef enum {
E_INICIANDO = 0, E_PROCURANDO, E_TRANSPORTANDO
} Estados;

Para o compilador essa linha cria uma seqüência de palavras-chave relacionadas a números inteiros (E_PROCURANDO = 1, E_TRANSPORTANDO = 2) mas pra gente basta saber que é nossa seqência de estados.

Declaramos então nossa variável:

static Estados estadoAtual = E_INICIANDO;

Nossa máquina de estados principal é um loop com um switch case:

loop() {
   // se o robo estiver indo contra alguma das três leis da robótica, ele se desliga
   if (infrigindoLei())
      exit();
   
   switch (estadoAtual) {
      case E_INICIANDO:
         iniciaSensores();
         iniciaAtuadores();
         posicionaPartida();

         if (pronto) {
            estadoatual = E_PROCURANDO;
         }
      break;
      
      case E_PROCURANDO:
         andeAteProximaEsquina();

         if (encontrouCaixa()) {
            carregueCaixa();	
            estadoatual = E_TRANSPORTANDO;
         }
      break;

      case E_TRANSPORTANDO:
         andeAtePontoDeEntrega();

         if (chegouNoPontoDeEngtrega()) {
            descarregueCaixa();
            missaoCumprida();
            exit();	
         }
      break;
   }
}


Conteúdo criado na rede antiga por Henrique Foresti


Atividades recentes