Aqui estão disponíveis algumas fotos do robô e os gráficos que criamos para entender melhor os sensores.
No gráfico a seguir fizemos uma aproximação linear e cúbica do comportamento do sensor a medida que distanciamos um objeto dele.
Os gráficos a seguir são referentes a medições de um objeto a várias distâncias utilizando-se o sensor óptico. Percebe-se que algumas leituras do sensor LDR contém muito ruído, mas não é o suficiente para estragar a média de valores, no caso de 500 amotragens. Além disso, percebe-se também que os valores lidos aproximam-se dos valores plotados na curva anterior.
Os gráficos a seguir são referentes a medições com o sensor óptico a 3mm do bloco. Percebe-se que a influência da luz é grande nas amostragens, gerando ruídos. No caso do motor, pode-se perceber a sua influência nos resultados, porém não gera ruídos como a variação de luz.
Os histogramas a seguir referem-se a dez medições feitas com cada um dos cubos. O sensor foi capaz de identificar cada cor corretamente todas as vezes.
Para o gráfico a seguir realizamos 10 medidas para cada bloco em cada distância para encontrarmos o valor médio para cada bloco no espaço de quatro dimensões. Feito isso, calculamos a distância euclidiana entre todos os blocos e escolhemos a menor delas. Definimos que a distância ideal entre o bloco e o sensor é a que proporciona a maior distância euclidiana entre os valores medidos para os blocos.
Conforme visto nesse gráfico a melhor distância para se manter entre o sensor e o bloco é 1.6cm.
II.
Normalizing Exercises - página 85
1 - Utilizando a porta analógica 4 com o seguinte programa:
void main() { while (1) { printf("sensor 4=%d\n", analog(4)); sleep(0.1); } }
Os valores determinados para a leituras máxima e mínima do sensor LDR são: Leitura máxima =248 Leitura mínima = 3
2 - A função normalize funcionou como o esperado convertendo os valores, a faixa de variação de valores foi de 0 a 100.
3 - O caso de output menor que zero ocorre quando o sensor mede um valor menor que o valor definido por MIN_LIGHT. O caso de output maior que 100 ocorre quandoqunado o sensor mede uma valor maior que o valor definido por MAX_LIGHT.
III.
Utilizando a porta analógica quatro o programa usado para imprimir continuamente o valor da tensão medida no display da Hand-Board é:
void main() { while (1) { printf("%d\n", analog(4)); msleep(100L); } }
IV.
Utilizando a porta 3 para o novo sensor. As leituras máxima e mínima de tensão para este novo sensor LDR são: Leitura máxima = 253 Leitura mínima = 3 A função normalize novamente foi precisa e exibiu valores na faixa de 0 a 100.
O funcionamento do programa é o seguinte, utilizando a tecla start em zero a porta 3 é lida, utilizando a tecla stop em zero a porta 4 é lidao, simplesmente aperte stop para start para mostrar o sensor 4 e stop para mostrar o sensor 3. O programa faza impressão na tela do valor de tensão corrente medido e do valor retornado pela função normalize.
void main() { while(1) { while (!start_button()) { printf("porta tres: real=%d normalizado=%d \n", analog(3), normalize(analog(3))); msleep(100L); } while (!stop_button()) { printf("porta quatro: real=%d normalizado=%d \n", analog(4), normalize(analog(4))); msleep(100L); } } } int normalize (int light) { int MAX_LIGHT = 3; int MIN_LIGHT = 248; int output = 100 - ((light - MAX_LIGHT) * 100) / (MIN_LIGHT - MAX_LIGHT); if (output < 0) output = 0; if (output > 100) output = 100; return output; }
Sensor History Exercises - página 306
1-
tempo = (1/frequencia) * tamanho_vetor; frequencia = 7.8125Hz tamanho_vetor = 50; tempo = (1/7.8125) * 50 = 6.4 segundos
2 - Um seguidor de parede funciona de modo semelhante a um seguidor de linha exemplifucado na figura 6.64. As mudanças consistem em o sensor estar apontado para a parede sendo agora o limiar da parede o valor calculado, e as funções de esperar na linha e fora da linha são substituídas por uma função de distância da parede. Quando o robô está se distanciando da parede ele vira em direção a ela e quando se aproxima além do limiar se distancia da parede. Funciona apenas quando a parte direita do robô (onde o sensor está instalado) está de voltada para a parede. O código do programa é:
int wall[50]; int WALL_THRESHOLD; void main() { start_process(compute_and_display()); wall_follow(); } void wall_follow() { while (1) { waddle_left(); waituntil_on_the_wall(); waddle_right(); waituntil_off_the_wall(); } } void waituntil_on_the_wall() { while (wall_sensor() < WALL_THRESHOLD); } void waituntil_off_the_wall() { while (wall_sensor() > WALL_THRESHOLD); } int wall_sensor() { return current_value((int)wall); } void waddle_left() { fd(3); off(0); } void waddle_right() { fd(0); off(3); } void compute_and_display() { install_sensor_history(wall, 0, 3); while (1) { WALL_THRESHOLD= sensor_average((int)wall); printf("thresh %d wall %d\n", WALL_THRESHOLD, current_value((int)wall)); msleep(50L); } }
3 - Os valores máximo e mínimo do buffer são lidos com as funções sensor_max e sensor_min, quando estes valores são iguais significa que o robô não se moveu pelo menos pelo intervalo de tempo determinado pelo buffer. A função que imprime na tela se o robô está emperrado supondo as inicializações já feitas é:
void stuck_robot() { while(1) { if (sensor_max(int(line)) == sensor_min(int(line))) printf("the robot is stucked"); mSleep(100L); } }
4 - Para a monitoração de sensores digitais funções como definição da precisão (define o número de bits a serem usados na conversão analógica digital) e transmissão além da média do desvio padrão das amostras. Imlementação:
int set_precision_ad(int precision) { return precision; } float desvio_padrao(int array_ptr) { float variancia = 0; float media = sensor_average((int)array_ptr); for (int i = 0; i < 50; i++) variancia = (arrayptr[i] - media) * (arrayptr[i] - media) + variancia; variancia = variancia/50; return sqrt(variancia); }
5 - Um exemplo é a medição de nível em um tanque, o sensor teria de medir os valores máximo e mínimo para garantir que o nível estaja sempre dentro de uma faixa. O sensor também pode medir a taxa de variação do nível para fazer uma predição informando ao controlador a tedência a ser seguida pelo nível. A rotina de taxa de variação (derivada) recupera o último valor medido subtrai pelo penúltimo e divide pelo intervalo de amostragem (período), é definida em assembler como: subrotine_derivate:
xgdx bsr get_last_datum push bsr get_prev_datum subd div periodo rts
6 - A identificação se o robô esta emperrado pode ser feita através do histórico de medição do estado dos motores, por exemplo caso apenas um motor steja ligado e os outroa desligados o robô estaria girando em torno do seu próprio eixo.
Devido nossa experiência a montagem deste robô foi mais rápida que o antigo. Refizemos a caixa de engrenagem que agora conta com 3 reduções de 8 para 40, o que nos dá um total de redução de 125 em cada engrenagem. Como podemos ver na figura abaixo.
Utilizamos a mesma caixa do trabalho anterior para colocar a HandyBoard, mas reduzimos a largura do robô, podemos ver isso na figura abaixo. Note que fixamos os sensores na parte de baixo do robô presos com cola quente a uma peça de lego. Os LEDs para o identificador de cor ficam ligados ao output digital da handyboard e os três sensores (os dois para andar na linha e o para identificar a cor ficam ligados na entrada analógica.
Reunimos e construímos a caixa de engrenagens do robô. Ela é constituída de 3 reduções 40:8, totalizando uma redução de 125:1 por motor.
Reunimos novamente para a montagem dos sensores. Descobrimos que 2 sensores CdS estavam queimados, pois o LED não emitia luz infravermelha. Verificamos isso usando câmeras de celular para verificar se o sensor ligado emitia luz. Compramos 2 novos sensores e fizemos a montagem deles sem acrescentar resistores, pois o monitor havia dito que os resistores não eram necessários. No entanto, os sensores também queimaram e concluímos que era necessário a montagem com resistores.
Compramos mais dois sensores CdS e resistores de 330 ohms. Montamos os sensores com os resistores. Terminamos também a estrutura do robô. Ele está pronto mecanicamente.
Os sensores CdS, apesar de emitirem o infravermelho, não retornavam valores válidos. Descobrimos que os fios terra e VCC estavam trocados e remontamos os mesmos. Terminamos a implementação do código para calibragem, testes e medições e a tarefa de andar sobre a linha preta. O robô está seguindo a linha preta perfeitamente.
Descobrimos um novo problema: os sensores CdS não estão funcionando bem para identificação de cores. Pesquisamos a respeito do assunto e descobrimos uma nova maneira de identificar cores. Essa maneira consiste em iluminar o objeto a ser identificado com cores diferentes, durante determinado período de tempo e tomar amostragens da quantidade de luz refletida pelo objeto. Com esses dados é possível calcular o desvio da cor do objeto a partir de cores pré-definidas, permitindo identificar a sua cor.
Compramos 4 LEDs de alto brilho das cores azul, verde, vermelho e branco. Fizemos a montagem do sensor para identificação de cores, utilizando um sensor LDR e os 4 LEDs.
Termimos a construção do código para identificação de cores. O robô está conseguindo identificar cores muito bem, pois podemos, inclusive, variar a distância dos blocos em relação ao sensor e a luz ambiente (até certo ponto).
Toda a parte a ser apresentada do trabalho está pronta. A seguir os vídeos com os resultados:
Ainda faltam alguns testes a serem feitos para a documentação e alguns exercícios. Tivemos problemas principalmente com relação a identificação de cores, mas hoje tudo foi resolvido. Faltando apenas acabamentos para deixar o trabalho esteticamente mais bonito.
Remontamos o sensor de identificação de cores, melhorando seu acabamento e o acabamento do robô de maneira geral.
Terminamos os exercícios, os testes e a documentação a ser apresentada. Os resultados dos testes corresponderam ao que era esperado, confirmando que a montagem do robô está correta.