segunda-feira, 5 de agosto de 2013

Qual o ângulo que o robô vai virar?

Esta postagem refere-se a uma dificuldade surgida no projeto a partir de dados reais de trabalho: precisamos saber qual é o tempo para colocar no delay e, qual o ângulo correspondente deste delay. Em resumo, precisamos que o robô vire num ângulo pré-determinado. Isso afeta as manobras não só no sumô mas no resgate também.
Primeiro precisamos de algumas informações:

1- Como o robô vira?
Para responder a esta questão temos 2 situações distintas- se o robô vira um lado de cada vez (acionamento apenas de um lado do motor) ou se vira os dois lados ao mesmo tempo (um lado para frente e o outro de ré). Se ele vira uma lado de cada vez a curva sairia mais aberta, conforme a figura 1, senão, os dois lados ao mesmo tempo, o robô viraria no próprio eixo, conforme a figura 2 e, portanto, a medida (x) seria diferente.

Figura 1 - Robô virando acionando apenas um lado
Figura 2- Robô virando acionando os dois lados
A partir desta afirmações podemos concluir que, se o robô virar com apenas um motor, a curva descreverá uma circunferência igual a 2 vezes a distância de largura do robô (largura = raio), enquanto, acionando os dois motores, a distância será igual a largura do robô (largura = diâmetro). 

2- Qual a velocidade do robô?
Velocidade é o espaço percorrido em função do tempo gasto para percorrer o trajeto, portanto pode-se determinar a velocidade do robô fazendo-o percorrer um espaço de 1 metro e medindo o tempo, em segundos, com um cronometro, obtendo o valor da velocidade em metros por segundo (m/s), unidade do Sistema Internacional.

3- O ângulo desejado.

A partir destas informações em fazendo o uso da equação que mede o comprimento da circunferência -  c = \pi d = 2 r\ \pi, (fonte:wikipedia) e regra de três simples, conseguimos determinar o delay a ser inserido no robô para que ele vire no ângulo desejado. 

Para tanto vamos estudar 2 casos:
Caso 1- Robô virando de um lado apenas
Dados:
Velocidade: 0,102 m/s
Ângulo: 60º
Largura do robô: 20 cm

Convertendo velocidade de m/s em cm/s: 
0,102 x 100=10,2cm/s

Comprimento da circunferência: 
20 x 2 x 3,14 = 125,6 cm.

Ou seja, para dar uma volta completa na circunferência (360º), o robô terá de percorrer 125,6 cm, entra a regra de 3 para determinar, qual distância ele precisa percorrer para o ângulo desejado (60º):
ângulo (º)           Distância (cm)
360                     125,6
60                          x

x = (125,6 x 60)/360
x = 20,93 cm

Desta forma o robô deve percorrer 20,93cm para fazer uma curva de 60º. Basta então, dividir o a distância pela velocidade para obter o tempo e, multiplicar por mil para obter em milissegundos. Desta forma temos:
delay = (20,93/10,2) x 1000
delay = 2,052*1000
delay = 2052 ms

Ou seja, no programa deste robô, para fazer ele virar num ângulo de 60°, basta colocar um delay de 2052 ms.

Caso 2 - Robô que vira os lados
 Dados:
Velocidade: 0,102 m/s
Ângulo: 60º
Largura do robô: 20 cm

Convertendo velocidade de m/s em cm/s: 
0,102 x 100=10,2cm/s

Comprimento da circunferência: (lembrando que aqui o valor de diâmetro é igual a largura do robô)
20  x 3,14 = 62,8 cm.

Ou seja, para dar uma volta completa na circunferência (360º), o robô terá de percorrer 125,6 cm, entra a regra de 3 para determinar, qual distância ele precisa percorrer para o ângulo desejado (60º):
ângulo (º)           Distância (cm)
360                     62,8
60                          x

x = (62,8 x 60)/360
x = 10,46 cm

Desta forma o robô deve percorrer 10,46cm para fazer uma curva de 60º. Basta então, dividir o a distância pela velocidade para obter o tempo e, multiplicar por mil para obter em milissegundos. Desta forma temos:
delay = (10,46/10,2) x 1000
delay = 1,026 *1000
delay = 1026 ms

Ou seja, no programa deste robô, para fazer ele virar num ângulo de 60°, basta colocar um delay de 1026 ms.

Comparando os delays podemos concluir que um robô que aciona os dois lados para virar é mais rápido e que, em algumas situações, um ou outro sistema de curva, pode ser mais adequado. 



terça-feira, 23 de julho de 2013

Problema solucionado: leitura de sensores IR e ultrassom para robôs de sumô

Quando iniciamos a preparação para a OBR de 2013 notamos um problema toda vez que acionávamos os sensores de infravermelho digital junto com o sensor de ultrassom: o robô simplesmente ignorava a leitura de linha e travava o movimento. Para tanto usamos a versão 2.0 do Simulino (santo simulino) e criamos um ambiente de teste, onde os 2 ldr´s da simulação funcionam como sensores IR digitais e o sensor de ultrassom como ele mesmo. Em vez de usarmos os motores, usamos led´s para facilitar a visualização do que está acontecendo, sendo que, o robô deveria reagir conforme fluxograma abaixo:
Para tanto seguimos a seguinte programação:
int emissor=10;
int receptor=9;
long cm1,duracao;

int sensor_d = 6; //conectar ao pino digital 
int sensor_e = 7; //conectar ao pino digital

int diff1;
int diff2;

void setup(){
  pinMode (emissor, OUTPUT);
  pinMode (receptor, INPUT);
  pinMode (13, OUTPUT);
  pinMode (12, OUTPUT);
Serial.begin (9600);
}
void loop(){
  //leitura dos sensores de IR
  int linha_d = direita(); //armazena o valor de leitura na viarável linha_d
  int linha_e = esquerda();//armazena o valor de leitura na variável linha_e
  sonar();

Serial.print (linha_d);
Serial.print (", ");
Serial.print (linha_e);
Serial.print (", ");
Serial.println (cm1);

  //se a leitura das linhas corresponder a branco, executa esta função
  if (linha_d<800 || linha_e<800){
    if (cm1<30){
  digitalWrite (13, HIGH); //acende o led no pino 13
  digitalWrite (12, LOW); //desliga o led pino 0
    }
    if (cm1>30){
    digitalWrite (13, LOW); //desliga o led no pino 13
    digitalWrite (12, HIGH); //liga o led pino 0
    }
  }
  if (linha_d>=800||linha_e>=800){
    digitalWrite (13, HIGH); //acende o led no pino 13
    digitalWrite (12, LOW); //desliga o led pino 0
    delay (10);
    digitalWrite (13, LOW); //desliga o led no pino 13
    digitalWrite (12, HIGH); //liga o led pino 0
    delay (10);
  }

}

int sonar(){
   digitalWrite (emissor, LOW);
  delayMicroseconds (2); 
  digitalWrite (emissor, HIGH);
  delayMicroseconds (2); 
  digitalWrite (emissor, LOW);
  duracao=pulseIn(receptor,HIGH);
  cm1=microsecondstocentimeters(duracao);
}

long microsecondstocentimeters(long microseconds){
  return microseconds/29/2;
}

int direita(){
pinMode( sensor_d, INPUT );
int leitura_d=digitalRead(sensor_d);
if (leitura_d==HIGH){
  diff1=700;
}
else{
  diff1=900;
}
 return diff1;
}

int esquerda(){
  pinMode( sensor_e, INPUT );
  int leitura_e=digitalRead(sensor_e);
  if (leitura_e==HIGH){
  diff2=700;
}
else{
  diff2=900;
}
  return diff2;
}

Após rodar esta programação, o robô simulou o mesmo erro que observamos nos nossos treinos, onde o robô passa direto pela linha independente de encontrar a linha preta ou não (900 no virtual terminal), acendendo a luz amarela direta. 


Para corrigir alteramos os seguintes trechos:
...
void loop(){
  //leitura dos sensores de IR
  int linha_d = direita(); //armazena o valor de leitura na viarável linha_d
  int linha_e = esquerda();//armazena o valor de leitura na variável linha_e
 ...
Retirando a leitura do sonar e colocando-a de forma a agilizar a leitura dos sensores, fazendo com que a leitura do ultrassom só seja feita se o robô está sobre a linha branca, conforme abaixo:
 ...
  //se a leitura das linhas corresponder a branco, executa esta função
  if (linha_d<800 || linha_e<800){
  sonar();
...   
Além disso, na função sonar mudamos o valor do tempo em HIGH de 2 microssegundos para 10 microssegundos evitando erros de leitura:
...
int sonar(){
   digitalWrite (emissor, LOW);
  delayMicroseconds (2); 
  digitalWrite (emissor, HIGH);
  delayMicroseconds (10); 
  digitalWrite (emissor, LOW);
  duracao=pulseIn(receptor,HIGH);
  cm1=microsecondstocentimeters(duracao);
}
...

O resultado final pode ser visto no vídeo abaixo,com a pequena alteração de colocar um led vermelho para identificar quando está sobre a a linha preta, um led amarelo para representar sobre a linha branca sem nenhum objeto à frente e, o led verde representando sobre a linha branca com objeto a menos de 30 cm:


Ainda assim, você pode notar que os led´s piscam alternadamente, mostrando que há interferência, causada pela leitura dos sensores. Isso pode provocar movimentos involuntários do robô interferindo no planejamento inicial. Para eliminar o problema criamos uma função que interpreta o sinal dos sensores:
...
//função que transforma a leitura dos sensores em uma variável, eliminando erros:
if (linha_d<800||linha_e<800){
  estado = 100;
}
if (linha_d>=800||linha_e>=800){
  estado = 300;
}
...
Essa  função retorna o valor de 100 para branco e 300 para preto, eliminando o defeito anterior. Se baseia no princípio de Máquina de Estados Finitos que pode ser assim definido:
" é um modelo matemático usado para representar programas de computadores ou circuitos lógicos. O conceito é concebido como uma máquina abstrata que deve estar em um de seus finitos estados. A máquina está em apenas um estado por vez, este estado é chamado de estado atual. Um estado armazena informações sobre o passado, isto é, ele reflete as mudanças desde a entrada num estado, no início do sistema, até o momento presente. Uma transição indica uma mudança de estado e é descrita por uma condição que precisa ser realizada para que a transição ocorra. Uma ação é a descrição de uma atividade que deve ser realizada num determinado momento."

Desta forma, conforme o vídeo abaixo, o problema foi finalmente corrigido:

sexta-feira, 19 de julho de 2013

Locais do Torneio Juvenil de Robótica 2013

Conforme cronograma recebido hoje segue datas e locais para a realização do Torneio Juvenil de Robótica. Peço aos alunos que vão levar convidados que me enviem os dados urgente para cadastrarmos os visitantes previamente no site do torneio.
Abaixo o trecho com data e local:
Para as equipes de crianças, jovens e adultos, todos com idade de 12 anos ou mais, inscritos nos desafios Sumô, Cabo de Guerra, Viagem ao Centro da Terra, Resgate de Alto Risco, Labirinto de Linhas, Dança e Registro Multimidiático, o evento ocorrerá nos dias 17 e 18 de agosto, das 8 horas às 18 horas, na Universidade Paulista _UNIP_ campus Cidade Universitária, próximo do Instituto de Matemática e Estatística da Universidade de São Paulo, conforme indicado no site do Torneio Juvenil de Robótica.

Mapa:

Lembrando que temos alguns lugares na van mas eu preciso de confirmação se alguém vai. Ainda não temos a van para o segundo dia do evento por isso, priorizaremos o sumô e cabo de guerra.

quarta-feira, 26 de junho de 2013

Sistema de radar usando Arduino e Ultrassom

09/09/2013 - Teste do radar
Após os testes teóricos realizamos os testes práticos. O primeiro teste consistiu no sensor de ultrassom fixo e o servo motor marcando a posição. O led verde acende quando o objeto está a menos de 20 cm e a posição do servo aumenta de 10 em 10º sem delay entre os ângulos.
A fonte de alimentação do servo foi ligada separado para evitar interferência (ruído).
No segundo teste instalamos o sensor de ultrassom sobre o servo motor (deu um trabalhão pois o suporte reciclado está com problemas) e continuamos usando o mesmo aumento e a mesma distância. Resultado extremamente positivo, com o led acendendo quando o sonar encontra o objeto.
Próximo teste será no chassi com busca do objeto e ataque.

30/08/2013
Continuando o sistema de desenvolvimento de um radar para nossos robôs usando um servo de posição e um sensor de ultrassom, desenvolvemos um programa baseado nos testes anteriores usando apenas o if como base de decisão.
Primeiro determinamos 2 variáveis que trarão as informações do servo-motor:
...
int posicao;
int m;
...
(m) corresponde a posição que o motor vai ficar (servo.write) e (posicao) a leitura de posição atual do motor. Em segundo lugar determinamos como o servo vai aumentar a posição através do comando:
...
if (m<180){
   m+=10;
   radar.write (m);
   Serial.println ("Procurando alvo");
   delay(10);
  }
...
Ou seja, o servo aumentará de 10 em 10 graus seu ângulo até 170 graus. Por que não 180? Porque o modelo que usamos no simulador do proteus (simulino) vai só até 180. O servo que usamos vai até 225º e portanto poderemos até aumentar estes valores na prática.
Depois inserimos a variável que irá "zerar" o motor se nada for encontrado no radar:
...
 if (m==180){
  radar.write (0);
  Serial.println ("Zerando a posicao");
  m=0;
  delay (500);
  }
Essa foi a mais díficil pois estávamos usando (m==0) e não (m=0) o que fazia com que o motor voltasse mas não zerasse. Opcionalmente pode-se usar:
...
 if (m==180){
  m=0;
  radar.write (m);
  Serial.println ("Zerando a posicao");
  delay (500);
  }
...
Os (delay) utilizados foram apenas para que pudéssemos visualizar na gravação da simulação o que ocorria pois a velocidade de processamento e do (Serial.print) não deixava claro o que estava acontecendo. No programa no final desta atualização removeremos.
Depois inserimos as variáveis de controle baseados na leitura do ultrassom:
...
if (cm1>20){
....// comandos para movimentação e zerar servo anteriores
}
  if (cm1<=20){
//comandos para atacar alvo
   Serial.println ("Atacar alvo");
   delay (1000);
 }
...
Novamente colocamos o (delay) para facilitar a visualização na gravação no proteus.
Finalmente inserimos o comando de leitura do sensor de ultrassom (sonar) e criamos uma função para leitura do sensor logo após o (void loop) para assim limitar o movimento do servo se baseando na distância do alvo, conforme o programa abaixo:
_________________________________________________________________________________
//Programa Pequenos Cientistas para sistema de radar
#include <Servo.h>//biblioteca do servo motor
//Variáveis do sensor de ultrasssom
int emissor=11;// trigger pinos do sensor de ultrassom
int receptor=10; //echo pinos do sensor de ultrassom
long cm1,duracao;
//Variáveis do servo-motor
Servo radar;
int posicao;
int m;

void setup(){
  //aciona os pinos do sensor de ultrassom
  pinMode (emissor, OUTPUT);
  pinMode (receptor, INPUT);
  //pino do servo-motor
  radar.attach (9);
  Serial.begin (9600);
}//fim do void setup

void loop(){
  //leitura do sensor de ultrassom
  sonar();
  //leitura da posição do servo
  posicao=radar.read();
  //imprime as leituras
  Serial.print (cm1);
  Serial.print (", ");
  Serial.print (posicao);
  Serial.print (", ");
  Serial.println (m);
  //Se o objeto estiver a mais de 20 cm
 if (cm1>20){
  if (m<180){
   m+=10;
   radar.write (m);
   Serial.println ("Procurando alvo");
   delay(10);
  }//fim do if para movimentar o servo
  if (m==180){
  radar.write (0);
  Serial.println ("Zerando a posicao");
  m=0;
  delay (500);
  }// fim do if para zerar o servo
 }// fim do if de distância do alvo
 //Se o objeto estiver a menos de 20 cm
  if (cm1<=20){
    //comandos de ataque
   Serial.println ("Atacar alvo");
   delay (1000);
 }//fim do if atacar alvo
}//fim do void loop
//Função de leitura do sensor de ultrassom
long sonar(){
  digitalWrite (emissor, LOW);
  delayMicroseconds (2);
  digitalWrite (emissor, HIGH);
  delayMicroseconds (10);
  digitalWrite (emissor, LOW);
  duracao=pulseIn(receptor,HIGH);
  cm1=microsecondstocentimeters(duracao);
  return cm1;
}
//Converte microssegundos em centímetros - velocidade do som = 1cm/29ms
long microsecondstocentimeters(long microseconds){
  return microseconds/29/2;
}
_________________________________________________________________________________
Vídeo de teste:
O primeiro número é a leitura do ultrassom, o segundo a leitura da variável (posicao) - servo.read, e o terceiro número é a leitura da variável (m) que controla a posição do servo. No teste primeiro deixamos o servo buscar até o final e retornar a zero, aí simulamos um objeto e, depois, esse objeto sai da frente do sensor de ultrassom, retornando a busca normal pelo objeto.


19/07/2013
Fonte para consulta (slide share):
http://www.slideshare.net/Miojex360/rob-seguidor-de-linha

20/06/2013 - Início do Projeto
Objetivo: desenvolver um sistema de sensor de ultrassom que localize um objeto, sem mover o chassi e, depois, o chassi se move em direção ao objeto.

Materiais:
Servo de posição HB
Sensor de ultrassom HC-SR04
Arduino Uno
Protoboard para testes
Fios wire macho macho
Chassi de teste : robô Osíris

Planejamento dos testes
1- Teste do servo motor usando o comando for (0 a 180º)
2- Teste de programa usando o sonar e o servo-motor: o servo deve se mover parando quando encontrar o objeto.
3- Teste de programa simulando o motor: o servo deve se mover até encontrar o objeto. Após encontrar o objeto luzes se acenderão simulando os motores do robô e, depois, o servo deve se posicionar em 90º, acionando um outro conjunto de luzes.
4- Teste final: o sonar será instalado no chassi Osíris e será realizado os testes de simulação de combate contra o robô Artemis.

Fase 1- Teste de uso do servo motor
Objetivo: determinar um programa de controle do servo-motor
Neste caso usamos o comando for e as instruções contidas no modelo de programa da pasta "Examples" do Arduino.
Resultado - O motor funcionou, movendo-se de 1 em 1º.
Vídeo abaixo:

 Teste 2- Montagem do radar
Neste teste fizemos 9 programas diferentes sendo que, usamos o comando for, comandos if e outros para ver se conseguíamos fazer o servo localizar o objeto e parar de se mover. O teste 1, 3 e 9 foram os únicos que chegaram próximos disso, conforme vídeos abaixo:
Teste 1

Teste 3

Teste 9

Chegamos a conclusão que o melhor programa era o do "Teste 1" e, portanto trabalharíamos em aprimorá-lo para conseguir chegar ao objetivo desta etapa. Abaixo segue imagem com o fluxograma utilizado, e os links para o programa já na linguagem do Arduino.

Teste 11 - Neste teste usamos o comando if para fazer a função dos comandos que estavam distribuídos ao longo do sketch do programa 1, deixando mais próximo do fluxograma de programa que julgamos ideal, atingindo nosso objetivo nesta etapa que era do radar se mover até encontrar o objeto. Caso o objeto saísse da frente ele voltava a rotina de busca e localização. Como padrão usamos a distância de 30 cm que era a distância ideal da mesa de teste.

Somos notícias: Jornal Foco - Diretoria de Ensino de Jundiaí

Segue reportagem na edição de Junho/2013 do Jornal Foco da Diretoria de Ensino de Jundiaí:

sábado, 8 de junho de 2013

Reportagem na TV TEM: Cultura é Currículo

02/07/2013 Saiu no Jornal de Campo limpo Paulista
http://www.encontracampolimpopaulista.com.br/noticias/estudantes-de-campo-limpo-paulista-visitam-museu/

08/06/2013
Nosso orientador deu entrevista hoje, 8 de junho, no Tem Notícias da Rede Globo de Sorocaba e Jundiaí sobre o projeto "Cultura é Currículo", representando a EE Elza Facca M. Bonilha na excursão ao Museu da Energia em Jundiaí. Este trabalho pretende se transformar numa "Feira de Ciências" no molde do Grande Desafio da Unicamp, em novembro na escola, projeto que vamos apresentar nossos robôs e s resultados obtidos ao longo do ano, como forma de atrair a atenção da comunidade, patrocinadores e alunos para o ensino de Ciências Naturais.
Reportagem:

sexta-feira, 7 de junho de 2013

Feiras Científicas 2013

Feiras Científicas:

Todas estas feiras usam como padrão o artigo da FEBRACE por isso, e por ser gratuitas, podemos preparar um artigo e nos inscrever em todas elas:
http://feiraciencias.wix.com/dntalentos


http://www.expocit.com.br/
EXPOCIT