PROGRAMA DE CONTROLE DO FOGUETE

ENGENHARIA DE DOMÍNIO

      Apresenta-se a análise e o projeto do sistema de controle do RCX, vê-se a definição dos requisitos, objetivos, definição de atores, uses-case e diagramas de classes.

ÍNDICE:

1.      OBJETIVOS

2.      REQUISITOS

3.      ATORES

4.      USES CASES

5.      DIAGRAMA DE CLASSES

6.      ESCALONAMENTO

7.      CÓDIGO EM NOT QUITE C

 

 

 

 

 

1.      OBJETIVOS:

       O objetivo da missão é levar o foguete Russo de volta ao planeta Terra, saindo do planeta Marte. Além dos percalços já conhecidos, a tripulação deparou-se com mais alguns. Secretamente, o robô matador introduziu um vírus letal na CPU do foguete. Mesmo decolando, sua trajetória foi totalmente modificada. Além do trajeto ficar sinuoso, ele está em rota direta de colisão com asteróides e cometas. Nossa missão é fazer com que o foguete consiga seguir este caminho sinuoso e seja capaz de desviar destes alvos celestiais. Como esta não é uma tarefa fácil, também precisamos criar condições para que o controle da missão possa fazer alguma intervenção quando necessário. Seja para corta algum caminho, já que o combustível, ou corrigir alguma falha no programa de navegação.

 

2. REQUISITOS:

       O foguete Russo será controlado por um programa que terá basicamente três threads. Cada uma executará funções específicas. A principal será a de navegação que conduzirá o foguete por uma linha pintada no chão, representando a sua trajetória. As outras duas threads serão acionada em situações de exceção, para que o foguete desvie de obstáculos ou quando o controle da missão assim o desejar.

Thread de navegação: o foguete anda para frente em linha reta, seguindo uma linha pintada de preto no chão. O foguete pára e é desligado ao encontrar uma faixa larga. O sensor de luz, que aponta para baixo vai realizando a sua leitura. Sempre que o seu valor de retorno ultrapassar um determinado valor, a velocidade e a direção do foguete é alterada. Ele oscilará ora para a esquerda, ora para a direita até ajustar-se na trajetória ou encontrar novamente a linha. Afim de evitar que ele se perca á a última direção será guardada.

Thread de desvio: quando o sensor de toque acusar a presença de algum obstáculo, o foguete pára. A seguir ele dá marcha ré muda de direção e vai em frente por um determinado tempo. Depois disto ele muda de direção novamente e segue em frente até encontrar novamente a linha.

Thread de controle da missão: Sempre que julgar necessário o controle da missão poderá fazer intervenções. Os teclados de seta do serão configurados para que possam fazer o foguete ir em frente, para a esquerda ou para a direita e parar.    

3. ATORES:

       O sensores de luz, de toque, atuadores e o controle da missão.

            

4. USE-CASES:

 

 

USE CASE #1: Seguindo a linha

Objetivo no contexto

O foguete deverá ser capaz de seguir uma linha pintada no chão até encontrar um círculo preto, que representa o planeta Terra.

Escopo

Programa de controle do RCX

Pré-condições

Os demais componente do projeto como drivers, so, protocolos de comunicação deverão estar instalado e suportar as funções exigidas pelo programa aplicativo.

Término com sucesso

O foguete encontra o círculo (Terra), seguindo a linha e para. Também considera-se como sucesso se receber ajuda do controle externo.

Término com falha

Não segue a linha corretamente ou não alcança o destino.

Atores primários

O sensore de luz, atuadores.

Disparo

O foguete é colocado na posição inicial (planeta Marte) e é acionado.

Descrição

Passo

Ação

 

 

1

O foguete é acionado e vai para frente.

2

O programa fica monitorando o sensor de luz. Se encontrou a marca de chegada vai ao passo 6.

3

O foguete anda para frente até o sensor de luz ultrapassar um determinado valor.

4

O foguete oscila para a esquerda ou para a direita, por um certo tempo, até ajustar a trajetória ou encontrar a linha (a última direção é guardada).

5

O foguete retoma a trajetória em linha reta e a execução volta ao passo 2.

6

Os atuadores são desligados.

 

INFORMAÇÕES

Seguindo a linha

Prioridade

É a principal função do robot, mas perde a prioridade em caso de encontrar algum obstáculo ou por alguma chamada do controle da missão.

Performance

O Robot deverá seguir a linha, corrigindo a rota sempre que necessário. Deve percebendo mudanças na trajetória e ir a ajustando.

Freqüência

Sempre. Pode ser interrompido ocasionalmente, quando o foguete deparar com algum obstáculo ou o controle da missão assim desejar.

Formas de comunicação com os atores

O programa se comunicará com o hardware do RCX através da abstração de rede. Enviará e receberá bytes que deverão ser interpretados.

Relação com outros componentes do projeto

Algumas funções deverão ser implementadas pelo SO para que o programa possa acessar os recursos como sensores, aturadores, timers e comunicação com o IR. São elas:

SetSensor(sensor, tipo_sensor)

SetVelocidade(atuadores,velocidade) "SetPower"

OnPraFrente(atuadores) "OnFwd"

Off(Atuadores)

ClearTime(valor)

SetPraFrente(atuadores) "Fwd"

SetPraTras(atuadores) "Rev"

   

USE CASE #2: Desviando de obstáculos

Objetivo no contexto

O foguete deverá ser capaz de desviar, de forma autônoma, de obstáculos que se interponham pelo caminho.

Escopo

Programa de controle do RCX

Pré-condições

Os demais componente do projeto como drivers, so, protocolos de comunicação deverão estar instalado e suportar as funções exigidas pelo programa aplicativo.

Término com sucesso

O foguete, após tocar no objeto, deverá ser capaz de contorná-lo e prosseguir seu caminho. Poderá ser auxiliado pelo controle da missão.

Término com falha

O foguete fica preso ao obstáculo.

Atores primários

Sensor de toque, atuadores.

Disparo

Os sensores detectam a presença de algum obstáculo.

Descrição

Passo

Ação

 

1

Ao chocar-se com um obstáculo esta thread é ativada.

2

O foguete para.

3

O foguete retorna para trás por um perído de tempo

4

O foguete muda de direção, conforme a direção guardada.

5

O foguete avança por um período de tempo para frente.

6

O foguete muda novamente a direção até encontrar a trajetória.

 

7

O controle é devolvido a thread que controla a trajetória.

 

INFORMAÇÕES

Desviando de obstáculos

Prioridade

 Somente é acionado com a presença de obstáculos, tem prioridade sobre a função que segue a linha. Pode ser interrompida pelo controle da missão.

Performance

Tempo necessário para desviar e retornar a trajetória.

Freqüência

Sempre que os sensores forem ativados.

Formas de comunicação com os atores

O programa se comunicará com o hardware do RCX através da abstração de rede. Enviará e receberá bytes que deverão ser interpretados.

Relação com outros componentes do projeto

Algumas funções deverão ser implementadas pelo compilador para que o programa possa acessar os recursos como sensores, aturadores, timers e comunicação com o IR. São elas:

SetSensor(sensor, tipo_sensor)

SetVelocidade(atuadores,velocidade) "SetPower"

OnPraFrente(atuadores) "OnFwd"

Off(Atuadores)

ClearTime(valor)

SetPraFrente(atuadores) "Fwd"

SetPraTras(atuadores) "Rev" OnPraTras(atuadores) "OnRev ou OnFor"

Timer (valor) "Timer"

 

USE CASE #3: Controle da Missão

Objetivo no contexto

O foguete deverá ser capaz de imediatamente interromper o que está fazendo e seguir os comandos do controle da missão, Após a intervensão o robot deve voltar ao seu comportamento normal.

Escopo

Programa de controle do RCX, Infra-vermelho,SO,iPAQ

Pré-condições

Os demais componente do projeto como driver infra-vermelho, so, protocolos de comunicação deverão estar aptos e suportar as funções exigidas pelo programa aplicativo.

Término com sucesso

O foguete, após receber o comando, deverá ser capaz de executá-lo e retornar a thread principal(seguir o caminho).

Término com falha

O foguete não obedecerá o comando ou não retornará adequadamente à thread principal.

Atores primários

Dispositivo de comunicação por infra-vermelho.

Disparo

Os sensores recebem o comando do controle da missão.

Descrição

Passo

Ação

 

1

 Parar imediatamente os atuadores

2

 Executar o camando enviado pelo CM

3

 O controle é devolvido a thread principal

 

INFORMAÇÕES

Desviando de obstáculos

Prioridade

 Somente é acionado quando uma interrupçãp gerada pelo controle da missão é detectada

Performance

Tempo necessário para execução do comando recebido

Freqüência

Sempre que o controle da missão enviar um comando.

Formas de comunicação com os atores

 O programa se comunicará com o hardware do RCX através da abstração do dispositivo de infra-vermelho. Enviará e receberá bytes que deverão ser interpretados.

Relação com outros componentes do projeto

 Algumas funções deverão ser implementadas pelo SO para que o programa possa acessar os recursos como sensores, aturadores, timers e comunicação com o infra-vermelho. São elas:

SetSensor(sensor, tipo_sensor)

SetVelocidade(atuadores,velocidade) "SetPower"

OnPraFrente(atuadores) "OnFwd"

Off(Atuadores)

ClearTime(valor)

SetPraFrente(atuadores) "Fwd"

SetPraTras(atuadores) "Rev" OnPraTras(atuadores) "OnRev ou OnFor"

Timer (valor) "Timer"

Connect(infra-vermelhor);

receive(infra-vermelho);

send(infravermelho);

CloseConnection(infra-vermelho);

 

5. DIAGRAMA DE CLASSES:

 

6. ESCALONAMENTO:

Não é necessário um algoritmo de escalonameto, pois o tempo de cada tarefa é conhecido antes da execução.

Haverá a processo principal que executará uma rotina com tempo pré-determinado. Essa rotina coletará valores
dos sensores e executará, se necessário, subrotinas com tempo de execução conhecido.

As subrotinas, depois de executadas, devolverão o controle ao processo principal.

 

7. CÓDIGO EM NOT QUITE C

 

#define EYE SENSOR_1

#define LEFT      OUT_C

#define RIGHT     OUT_A

#define BUMPER SENSOR_2  // bump

 

 

#define NORMAL_SPEED 6

#define TURN_SPEED 2

#define DELAY     20

 

#define CUTOFF    55

#define STOP      48

 

 

int direction, time, eye;

 

#define INITIAL_TIME 2

// timing

#define BUMP_BACK_TIME  60  // 0.6 seconds  bump

#define BUMP_SPIN_TIME  20  // 0.2 seconds  bump

 

task main()

{

      SetSensor(EYE, SENSOR_LIGHT);

     

      direction = 1;

      time = INITIAL_TIME;

      start follow;

      stop avoid_Obstacle;

      stop external_Control;

      while (eye < STOP)

      {

         if (Message() != 0)

       {

           stop follow;

           stop avoid_Obstacle;

           start external_Control;

           Wait (50);

           start follow;

       }

         if (BUMPER==0)

       {

           stop follow;

           start avoid_Obstacle;

       }

      }

      stop follow;     

      Off(RIGHT+LEFT);

      PlaySound(5);

}

 

 

task follow()

{

      SetPower(LEFT+RIGHT, NORMAL_SPEED);

      OnFwd(LEFT+RIGHT);

      while(true)

      {

            eye = EYE;

            if (eye <= CUTOFF) continue;

 

            ClearTimer(0);

            if (direction == 1)

            {

                  SetPower(LEFT+RIGHT, TURN_SPEED);

                  Fwd(RIGHT);

                  Rev(LEFT);

            }

            else

            {

                  SetPower(LEFT+RIGHT, TURN_SPEED);

                  Fwd(LEFT);

                  Rev(RIGHT);

            }

                 

            while(true)

            {

                  if (EYE < CUTOFF)

                  {

                        time = INITIAL_TIME;

                        break;

                  }

                       

                  if (Timer(0) > time)

                  {

                        direction *= -1;

                        time *= 2;

                        break;

                  }

            }

                 

            SetPower(RIGHT+LEFT, NORMAL_SPEED);

            Fwd(RIGHT+LEFT);

      }

}

 

 

task avoid_Obstacle()

{          

       // back up a bit      

               OnRev(LEFT+RIGHT);

               Wait(BUMP_BACK_TIME);

           

               // spin a bit

               Fwd(LEFT);

               Wait(BUMP_SPIN_TIME);

           

               // resume

               Fwd(RIGHT);

               Wait(BUMP_SPIN_TIME);

       start follow;         

}

 

task external_Control()

{

         if (Message() == 1) {OnFwd(OUT_A+OUT_C);}

         if (Message() == 2) {OnRev(OUT_A+OUT_C);}

         if (Message() == 3) {Off(OUT_A+OUT_C);}

         ClearMessage();

}

 

 

#define SENSOR_LUZ            SENSOR_2

#define ESQUERDA    OUT_C

#define DIREITA         OUT_A

#define ADIANTE (OUT_REV)

#define REVERSO (OUT_FWD)

#define VELOCIDADE_NORMAL 10

#define VELOCIDADE_REDUZIDA 1

// TEMPOS EM 1/10 S

#define TEMPO_PAUSA (1)

#define TEMPO_EXTRA (1)

#define TEMPO_SEGUINDO (5)

#define TEMPO_IDEAL (3)

// ÂNGULO SÃO TEMPOS DE RETORNO

#define ANGULO_INCIAL (3)

#define ANGULO_PASSO (2)

// NIVEIS DE LUZ EM PERCENTAGEM

#define PONTO_INCIAL       (43)

#define LIMITE_BORDA        (24)

int direcao, angulo_volta, sensor_luz, relogio;

task main()

{

    SetSensor(SENSOR_LUZ, SENSOR_LIGHT);

 

    direcao = 1;

    angulo_volta = ANGULO_INCIAL;

    sensor_luz = SENSOR_LUZ;

    while (true) {

        procurar();  //até encontrar a linha

        seguir();  // até perder novamente a linha

    }

}

// fica parado por uns instantes

void fica_parado()

{

    Off(ESQUERDA+DIREITA);

        // Espera medida em centésimos de seg

#if TEMPO_PAUSA > 0

   Wait(TEMPO_PAUSA * 10);

#endif

}

void esperando_a_linha(const int &timeout)

{

    ClearTimer(0);

    relogio = 0;

    while (sensor_luz >= PONTO_INCIAL && relogio < timeout) {

        sensor_luz = SENSOR_LUZ;

        relogio = Timer(0);

    }

}

 

// procurar a linha até o sensor de luz a enchergar

sub procurar()

{

    int tempo_volta;

   

    SetPower(ESQUERDA + DIREITA, VELOCIDADE_REDUZIDA);

        // tentando ir de um lado ao outro

    tempo_volta = angulo_volta;

    while (true) {

        if (direcao == 1) {

            SetDirection(DIREITA, ADIANTE);

            SetDirection(ESQUERDA, REVERSO);

        } else {

            SetDirection(ESQUERDA, ADIANTE);

            SetDirection(DIREITA, REVERSO);

        }

        On(ESQUERDA + DIREITA);

        esperando_a_linha(tempo_volta);

        if (sensor_luz < PONTO_INCIAL) {

            return;

        }

            // voltando para trás

        SetDirection(ESQUERDA + DIREITA, REVERSO);

        On(ESQUERDA + DIREITA);

        esperando_a_linha(angulo_volta);

        fica_parado();

        if (sensor_luz < PONTO_INCIAL) {

            return;

        }

            // não esta achando desta maneira, tentar de outra.

 

        direcao *= -1;

        tempo_volta = angulo_volta; // voltando ao ponto de parada

        angulo_volta += ANGULO_PASSO;

        tempo_volta += angulo_volta;

    }

}

// Achou a linha e segue atá perder.

sub seguir()

{

    int successo;

 

    successo = 0;

    SetPower(ESQUERDA + DIREITA, VELOCIDADE_NORMAL);

    SetDirection(ESQUERDA + DIREITA, ADIANTE);

    while (true) {

            // mudando a direção até encontrar a linha

        if (direcao == 1) {

            Off(ESQUERDA);

            On(DIREITA);

        } else {    

            Off(DIREITA);

            On(ESQUERDA);

        }

        esperando_a_linha(TEMPO_SEGUINDO);

        if (sensor_luz >= PONTO_INCIAL) {

            return;

        }

        if (sensor_luz < LIMITE_BORDA) {

                // abortar

            Off(ESQUERDA + DIREITA);

            StopAllTasks();

                // para toda as tarefas

        }

            // encontrou a linha

        if (relogio < TEMPO_IDEAL) {

            successo++;

        } else {

            successo = 0;

        }

        if (successo > 3) {

                // encontrou alinha

            angulo_volta = ANGULO_INCIAL;

        }

            // ESPERANDO UM TEMPO EXTRA E MUDANDO A DIREÇÃO

            // espera medida em centésimo de seg

        Wait(TEMPO_EXTRA * 10);

        direcao *= -1;

            // sensor fora da linha

        sensor_luz = SENSOR_LUZ;

    }

}