quarta-feira, 26 de janeiro de 2011

Robô bípede com arduino


Se preferir assista no youtube.

Assistindo vídeos no Youtube encontrei muitos robôs feitos com servomotores. Alguns mais simples outros muito sofisticados como o BIOLOID e o I-SOBOT que, são  produzidos por empresas e vendidos por  preços que giram em torno dos US$1500, passando facilmente disto dependendo do modelo e dos assessórios. Os modelos comerciais aparentam ser bastante flexível principalmente o BIOLOID que pode assumir diversas formas dependendo da criatividade do dono. Dos aparentemente caseiros, este me chamou a atenção. A estrutura física do que eu construí foi baseada no robô deste video.


A estrutura física foi o que deu mais trabalho. Basicamente a peça é desenhada  impressa e colada numa chapa fina de alumínio, cortada e dobrada. Os servos foram fixados com parafusos. As partes articuladas usam parafuso, porca e contra porca para manter a folga.








 O código, que foi feito apenas para ver o "bicho" funcionando, é mostrado abaixo. Ele  faz o robô andar para frente, retorna à direita, anda novamente para frente e anda para traz. A idéia básica para fazé-lo andar para frente é mandar o mesmo sinal para servos paralelos em cada perna. Por exemplo: servo 1 da perna um e servo 1 da perna 2 recebendo o mesmo sinal simultaneamente.

O manual da shield incluindo a biblioteca pode ser visto neste site.

Estou pretendendo acrescentar mais servos e alguns sensores. Se tudo der certo eu posto os resultados.
Vou tentar também fazer um passo-a-passo para auxiliar alguém que queira montar  o robô.

int pe1 = 14; // motor 1 da perna esquerda ( de baixo para cima)  
 int pd1 = 15; // motor 1 da perna direita ( de baixo para cima)  
 int pe2 = 13; // motor 2 da perna esquerda ( de baixo para cima)  
 int pd2 = 12; // motor 2 da perna direita ( de baixo para cima)  
 int i = 1500;  
 int a = 1500;  
 #include <ServoShield.h>  // inclui a biblioteca ServoShield que deve ser baixada e adicionada a pasta libraries do arduino  
 ServoShield servos;  //Cria um objeto ServoShield  
 void setup()  
 {  
  servos.start();   
  for (int servo = 0; servo < 16; servo++)//inicializa todos os servos  
  {  
   servos.setbounds(servo, 500, 2500); //seta a faixa de pulso maximo e minimo  
   servos.setposition(servo, 1500);  // todos os servos na posição central  
  }  
  delay(2000);  
 }  
 void loop() // laco pricipal  
 {  
  for(int a = 0; a < 7; a ++) //frente  
  {  
 inclina_esq();  
 pd_frente();  
 inclina_dir();  
 pe_frente();  
  }  
  descansar();  
 for(int a = 0; a < 10; a ++) //roda a direita  
  {  
 inclina_esq();  
 pd_frente();  
 desenclina_esq();  
 pe_frente();  
  }  
 for(int a = 0; a < 7; a ++) //frente  
  {  
 inclina_esq();  
 pd_frente();  
 inclina_dir();  
 pe_frente();  
  }  
  descansar();  
 for(int a = 0; a < 7; a ++) //re  
  {  
 inclina_esq();  
 pe_frente();  
 inclina_dir();  
 pd_frente();  
  }  
  descansar();  
 } // fim do laco pricipal  
 void inclina_esq() // inclina para esquerda  
 {  
 for(; i <= 1730; i++)    
 {  
  servos.setposition(pe1, i);  
  servos.setposition(pd1, i);  
  delay(1);  
 }  
 }  
 void desenclina_esq()  
 {  
 for(; i >= 1500; i--)   
 {  
  servos.setposition(pe1, i);  
  servos.setposition(pd1, i);  
  delay(1);  
 }  
 }  
 void inclina_dir()  // inclina para direita  
 {  
 for(; i >= 1270; i--)   
 {  
  servos.setposition(pe1, i);  
  servos.setposition(pd1, i);  
  delay(1);  
 }  
 }  
 void pd_frente() // pe direito a frente   
 {  
  int aux = a + 700;  
  if (aux > 1900)  
  aux = 1900;  
  for(; a <= aux ; a++)    
 {  
  servos.setposition(pe2, a);  
  servos.setposition(pd2, a);  
  delay(1);  
 }  
 }  
 void pe_frente() // pe esquerdo a frente  
 {  
  int aux = a - 700;  
  if (aux < 1100)  
  aux = 1100;  
  for(; a >= aux; a--)   
 {  
  servos.setposition(pe2, a);  
  servos.setposition(pd2, a);  
  delay(1);  
 }  
 }  
 void descansar() // coloca suavemente todos os servor na posicao central 1500  
 {   
  int pos;  
  int cnt = 0;  
  int aux[16]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};  
  while(cnt != 16)  
  {  
  for (int servo = 0; servo < 16; servo++)  
  {  
  pos = servos.getposition(servo); // pos recebe a posicao atual do servo   
  if(pos > 1500)  
   pos--;  
  else if(pos < 1500)  
   pos++;  
  else if(aux[servo] != 1)  
  {  
  aux[servo] = 1;  
  cnt ++;  
  }  
  servos.setposition(servo, pos);  
  }  
  delay(1); // determina o qual lento é o movimento de retorno a posicao inicial  
 }  
  i = pos;  
  a = pos;  
 }