Tuesday, October 25, 2011

Robot UMR com sensor de ultrasom

Tenho feito alguns experimentos com o UMR (Unidade Móvel Robótica) que adquirí no mercado livre.
Um de meus objetivos está sendo fazer o robot andar aleatóriamente em uma sala fechada tentando não ficar preso nem bater nos vários objetos como cadeiras, bancadas, mesas e pessoas ocasionalmente.
Um resultado pode ser observado neste vídeo no youtube. Estiveram pesquisando junto comigo o Prof. Adiel e o aluno Alex, ambos da USS.
O UMR é controlado por uma placa Arduíno, com 2 servos para acionamento e um servo de 180 graus para mover o sensor ultrassom.

O código que utilizado para este experimento (rodado no Arduíno IDE, Linux) é:


#include
#include //Inclue a biblioteca Servos
#define NBR_SVR 3 // Numero de Servos ligados. Maximo de 48 arduino MEGA, 12 para outros ar#define FIRST_SERVO_PIN 8
#define SVR_SON 0 // Servo dotendo  sonar
#define SVR_ESQ 1 // Servo esquerdo
#define SVR_DIR 2 // Servo direito
#define ANTIHOR 1000
#define HORARIO 2000
#define PARADO 70
#define SON_ESQ 0
#define SON_FRT 90
#define SON_DIR 180
#define DISTPAD 40
#define DISTLAT 25
#define CICLE_FWD 3
#define HEARTBEAT 10
#define MAXLOOK 5

// enums
enum SonSvr{Esq,VireEsq,Frt,VireFrt,Dir,VireDir};
enum Estado{Parar, Parado, Mover, Movendo};

//iniciando a função e passando os pinos
Ultrasonic ultrasonic(12,13);
Servo Servos[NBR_SVR] ;
long distanciaF, distanciaE, distanciaD;
long hbCounter = 0;
int sonsvrCount=0;
int estadoCount=0;
unsigned char leituraEdisponivel = 0, leituraFdisponivel = 1, leituraDdisponivel = 0;
unsigned char presoCount = 0;
SonSvr sonsvr;
Estado estado;

void setup() {
  Servos[SVR_SON].attach(8,880,2400);
  Servos[SVR_ESQ].attach(9,880,2400);
  Servos[SVR_DIR].attach(10,880,2400);
  Servos[SVR_ESQ].write(PARADO); //enviando um ângulo de 70 graus o servo para
  Servos[SVR_DIR].write(PARADO);
  estado = Parado;
  Servos[SVR_SON].write(SON_FRT);
  sonsvr = VireEsq;
  // delay inicial
  delay(5000);
  distanciaF = ultrasonic.Ranging(CM);
}

void loop() {
  
  // incrementa contador de heartbeat
  hbCounter++;
  if(hbCounter > 3*MAXLOOK*HEARTBEAT) hbCounter = 0;
  // delay do HEARTBEAT
  delay(HEARTBEAT);
  
  if(sonsvr == VireEsq) {
    Servos[SVR_SON].write(SON_ESQ);
    sonsvr = Esq;
    sonsvrCount=0;
  } else if(sonsvr == VireFrt) {
    Servos[SVR_SON].write(SON_FRT);
    sonsvr = Frt;
    sonsvrCount=0;
  } else if(sonsvr == VireDir) {
    Servos[SVR_SON].write(SON_DIR);
    sonsvr = Dir;
    sonsvrCount=0;
  }
  sonsvrCount++;
  if(sonsvrCount>=MAXLOOK*HEARTBEAT) {
    // sonar em posicao de leitura
    if(sonsvr == Esq) {
      distanciaE = ultrasonic.Ranging(CM);
      if(distanciaE) leituraEdisponivel = 1;
      else leituraEdisponivel = 0;
      sonsvr = VireDir;
    } else if(sonsvr == Frt) {
      distanciaF = ultrasonic.Ranging(CM);
      if(distanciaF) leituraFdisponivel = 1;
      else leituraFdisponivel = 0;
      sonsvr = VireEsq;
    } else if(sonsvr == Dir) {
      distanciaD = ultrasonic.Ranging(CM);
      if(distanciaD) leituraDdisponivel = 1;
      else leituraDdisponivel = 0;
      sonsvr = VireFrt;
    }
    sonsvrCount=0;
  }

  // tomada de decisao de movimento
  estadoCount++;
  if(estado == Parar)
  {
    estadoCount=0;
    parar();
    estado = Parado;
  }
  if(estado == Parado) {
    if(estadoCount >= 2*HEARTBEAT) {
      estado = Mover;
    }
  }
  if(estado == Mover) {
    estadoCount = 0;
    estado = Movendo;
  }
  if(estado == Movendo)
  {
    if(estadoCount >= 8*HEARTBEAT) {
      estado = Parar;
    }
    if (distanciaF <= DISTPAD || distanciaE <= DISTLAT || distanciaD <= DISTLAT)
    {
      parar();
      leituraFdisponivel=0;
    
      //  preciso mudar de direcao!
      if(distanciaD >= DISTPAD && leituraDdisponivel)
      {
        // girar a direita
        direitaRT();
        leituraDdisponivel = 0;
      } else if(distanciaE > DISTPAD && leituraEdisponivel) {
          // girar a esquerda
          esquerdaRT();
          leituraEdisponivel = 0;
      } else {
        presoCount++;
      }
      if(presoCount>6) {
        // ficou preso
        presoCount = 0;
        irAtras();
      }
    }
    else
    {
      // pode ir para frente ...
      irFrente();
    }
  }
}

void irFrente() {
    Servos[SVR_ESQ].writeMicroseconds (ANTIHOR); // antihorario
    Servos[SVR_DIR].writeMicroseconds (HORARIO); // horario
    
}

void irAtras() {
    Servos[SVR_DIR].writeMicroseconds (ANTIHOR); // antihorario
    Servos[SVR_ESQ].writeMicroseconds (HORARIO); // horario
    
}

void parar()
{
  Servos[SVR_ESQ].write(PARADO); //enviando um ângulo de 70 graus o servo para
  Servos[SVR_DIR].write(PARADO);
  estado = Parado;
}

void esquerdaRT()
{
    Servos[SVR_ESQ].writeMicroseconds(HORARIO); // horario
    Servos[SVR_DIR].writeMicroseconds(HORARIO); // horario
}
void direitaRT()
{
    Servos[SVR_ESQ].writeMicroseconds (ANTIHOR); // antihorario
    Servos[SVR_DIR].writeMicroseconds (ANTIHOR); // antihorario
}

void irDireita()
{
    Servos[SVR_ESQ].writeMicroseconds(ANTIHOR); // horario
    Servos[SVR_DIR].write(PARADO);
}

void irEsquerda()
{
    Servos[SVR_DIR].writeMicroseconds(HORARIO); // horario
    Servos[SVR_ESQ].write(PARADO);
}
 

Friday, December 31, 2010

Etc.: Carta eletrônica de agradecimento que enviei ao Presidente Lula

Exmo. Sr. Presidente Lula,
Neste final de seu governo não posso me furtar ao mínimo de manifestar minha gratidão. Cada uma das minhas expectativas quando votei no senhor foram amplamente atendidas e superadas. Eu sonhava em ter no senhor um presidente capaz de diminuir um pouco que fosse a enorme diferença na distribuição de riquezas existente entre as classes ricas e probres do Brasil. Só isso já teria feito meu voto valer a pena. Mas, muito além do que eu esperava ser possível, nesses últimos 8 anos ví gradativamente meu orgulho de ser brasileiro aumentar, sonhando com a possibilidade de nos tornarmos um país justo com seus cidadãos, e inspirador e amigo de todos os povos do mundo. Quero destacar suas ações para a integração sul-americana, bem como o estreitamento dos nossos laços com os países da África. Vibrei com cada instante da política externa brasileira durante seu governo: finalmente mostramos o rosto e o coração do Brasil! Acredite que estou emocionado ao encerrar com a única sentença que me ocorre nese momento: Muito obrigado, presidente e equipe.

Wednesday, July 14, 2010

3pi pololu robot 3rd experiment

This time we decided to check the precision we can obtain measuring distances with the Pololu 3pi.
There is a function called encoders_get_counts_m1 in the AVR Library available on 3pi stuff. The function returns the counts of motor 1, and declares that the value of the distance from the start point is near 3 mm/count. So, we coded 3pi to follow a (straight) line, stopping after what should be 10 cm forward and wait for button B pressure, and so on, until the end of the line.
We measured each stop with a rule, and got the values (in centimeters):
7.8 - 8.5 - 8.5 - 7.9 - 7.9 - 9.2 - 7.6 - 7.5.
The bigger difference is 9.2 - 7.5 = 1.7 cm. This points to a possible error of aprox. 18.4% on the measurement. But it is not conclusive yet. We must check if there are no external influences, as the pressure of the button, that can be changing the results.





Monday, July 5, 2010

3pi pololu robot 2nd experiment

Next (see before 3pi pololu robot 1st experiment) we decided to make 3pi follow a given path from point A to point B.
We inserted an array of directions into the C code. Each time 3pi find a diversion it consumes a direction from the array and applies it.



This research activity is part of Grupo de Tecnologia e Desenvolvimento de Sistemas Computacionais.