====== SAS - Seek and Shoot ====== {{:cursos:introrobotica:2011-2:grupo10:logo_sas.png|}} ====Introdução==== O primeiro trabalho prático requeria a construção de um robô móvel com um sistema de controle cinemático implementado. Para sua construção foi fornecido um kit de peças Lego, 2 motores elétricos e sensores break-beam. Para testar o controle cinemático, era preciso que o robô realizasse duas tarefas. Na primeira, precisaria realizar três quadrados (de lado 30cm) consecutivos e na segunda, três círculos (de raio de 30cm) consecutivos. As trajetórias deveriam ser marcadas em uma superfície. ====Montagem==== Para montar o robô inicialmente nos baseamos na estrutura proposta por Fred J. Martin. No entanto essa se tornou inviável quanto a disposição dos sensores e rodas. Experimentamos várias idéias visando aperfeiçoar a estrutura quanto à estabilidade, firmeza e velocidade. Pudemos perceber que as mais simples alterações em relação à qualquer um dos fatores implicavam em mudanças em toda a estrutura do robô. Na versão apresentada conseguimos um boa relação entre estabilidade e velocidade, porém, a estrutura não ficou firme como esperado. Dessa forma, pretendemos nos próximos trabalhos melhorar sua firmeza sem comprometer os demais aspectos. {{:cursos:introrobotica:2011-2:grupo10:robo_frente.jpg?727|}} Para realizar a odometria utilizamos shaft-encoders, construídos a partir de dois sensores //break-beam//, montados como na imagem abaixo. {{:cursos:introrobotica:2011-2:grupo10:eixo.jpg?350|}} No primeiro projeto realizado pelo grupo os sensores foram instalados no eixo da roda com o objetivo de captar apenas as reais rotações da roda. Esta montagem se mostrou pouco eficiente pois os sensores captavam poucas rotações devido as reduções e o resultado da velocidade de rotação do motor não era preciso o suficiente para aplicação de controle de maneira eficiente. Portanto o Shaft-Encoder foi instalado diretamente no eixo do motor para que o sensor conseguisse uma maior resolução na captura de dados. Dessa forma conseguimos obter um maior número de pulsos gerados, o que propiciou melhores condições para a realização do controle de movimentação do robô. Para demarcar o trajeto percorrido pelo robô foi modificada uma caneta hidrocor, a qual foi colada sob uma peça lego do repositório de peças extras. Em prol de minimizar desvios no traçado da rotação do robô, esta estrutura foi afixada de forma que a ponta da caneta ficou disposta no centro dos eixos. A montagem desse módulo é ilustrada pela figura abaixo. {{:cursos:introrobotica:2011-2:grupo10:robo_cima.jpg?400|}} ====Implementação==== Com os sensores instalados o próximo desafio era obter a relação entre o número de counts e a distância percorrida em centímetros. Como cada pulso corresponde à uma borda de descida ou subida, cada furo da roda lego utilizada (figura acima) corresponde à dois counts. Dado o raio da roda r=2,1cm, e o perímetro p=13,1943cm, e que a redução do eixo é de 1:24, temos que a cada 12 counts (um giro do motor), o robô se desloca p/24=0.5497cm. ===Controle=== Para fazer o controle do robô estabelecemos como objetivo a velocidade das rodas. Caso, a velocidade de uma das rodas estivesse acima ou abaixo do esperado, a potência do seu motor correspondente era diminuída ou aumentada respectivamente. ==Execução do Quadrado== No caso do desenho do quadrado, o objetivo era manter as duas velocidades constantes e de mesmo módulo sempre. No primeiro gráfico observamos o número de counts de cada motor na execução do percurso, bem como a diferença entre eles. Em seguida contrastamos a potência aplicada em cada motor. {{:cursos:introrobotica:2011-2:grupo10:graf_quad_1.png?757|}}{{:cursos:introrobotica:2011-2:grupo10:graf_quad_2.png?757|}}{{:cursos:introrobotica:2011-2:grupo10:graf_quad_3.png?757|}} A partir da análise dos gráficos acima, podemos evidenciar o erro entre as rodas durante a execução da tarefa e a sua redução à zero ao fim da mesma. Observamos também que o erro de rotação ia se acumulando, levando o robô à não coincidir o traçado dos três quadrados. Mesmo assim o resultado obtido foi muito bom, dado que utilizamos apenas dois sensores break-beam. ===Execução do Círculo=== Porém, no caso do círculo, o objetivo era manter uma diferença constante entre as velocidades das duas rodas, traçando assim uma curva. Essa diferença proporcional varia de acordo com a dimensão requerida do círculo e é dada pela razão dos raios das trajetórias a serem percorridas por cada roda. Como a distância entre as rodas é de 15cm, e a caneta é colocada no centro do eixo, p = r1/r2 = (37.5/22.5) = 1.66, onde r1 e r2 são os raios das trajetórias da roda interna e externa, respectivamente, à circunferência tracejada. Os gráficos abaixo ilustram a diferença de potência aplicada nos motores e a relação entre as velocidades das rodas. {{:cursos:introrobotica:2011-2:grupo10:graf_circ_1.png?757|}} {{:cursos:introrobotica:2011-2:grupo10:graf_circ_2.png?757|}} ====Exercícios Propostos==== ===Exercício 1=== Para a realização do exercício foi montado uma estrutura composta de um motor, uma roda e um shaft-encoder (através de um sensor //break-beam//). {{:cursos:introrobotica:2011-2:grupo10:exe_eixo.jpg?727|}} Com a constante derivativa D=.25 valendo ¼ de P (P=1.00), observamos uma maior demora para a estabilização, dada a ocorrência de vários overshoots de pequena amplitude, como ilustrado pelos gráficos abaixo. {{:cursos:introrobotica:2011-2:grupo10:grafico.png?727|}} {{:cursos:introrobotica:2011-2:grupo10:grafico2.png?727|}} Quando definimos D=1.00 e P=2.00 inicialmente observamos uma maior amplitude dos overshoots, mas uma estabilização mais rápida. {{:cursos:introrobotica:2011-2:grupo10:grafico5.png?727|}} {{:cursos:introrobotica:2011-2:grupo10:grafico6.png?727|}} Ao utilizar D=0.5 e P=1.00 a estabilização foi rápida e suave, como representado nas figuras abaixo. {{:cursos:introrobotica:2011-2:grupo10:grafico3.png?727|}} {{:cursos:introrobotica:2011-2:grupo10:grafico4.png?727|}} ===Exercício 4=== A principal dificuldade encontrada em manter o robô em uma trajetória retilínea na calibração dos parâmetros do motor (o tempo de reação dos motores e constantes de ganho propocional e derivativo). Outro fator decisivo foi a produção de pulsos para aumentar a resolução e precisão na atuação. Inicialmente os sensores foram instalados no eixo da roda com o objetivo de captar apenas as reais rotações da roda. Esta montagem se revelou ineficiente já que os sensores captavam poucas rotações devido as reduções e o resultado da velocidade de rotação do motor não era preciso o suficiente para aplicação de controle de maneira eficiente. Portanto o Shaft-Encoder foi instalado diretamente no eixo do motor para que o sensor conseguisse uma maior resolução na captura de dados. Dessa forma conseguimos obter um maior número de pulsos gerados, o que propiciou melhores condições para a realização do controle de movimentação do robô. ====Conclusão==== Neste trabalho foi construído um robô móvel dotado de um controle cinemático utilizando os modelos de controle proporcional-derivativo (PD). Descrevemos os passos da montagem e as dificuldades encontradas bem como os resultados da execução das tarefas. ====Código Fonte==== #include sencdr5.icb #include sencdr6.icb #define counts_30cm 623 #define counts_circle37 4950 #define angle_90 237 #define angle_10 26 int main(){ int v0 = 60; int v1 = 50; int D, P, tmp0, D1, P1, tmp1, i, function; printf("\n\nEscolha a funcao no knob"); function = 0; while(!stop_button()){ while(!start_button()){ if(knob() < 128){ if(function != 1){ printf("\n\nFuncao selecionada: Quadrado"); function = 1; } } else { if(function != 2){ printf("\n\nFuncao selecionada: Circulo"); function = 2; } } } switch(function){ case 1: squares(3); break; case 2: circle(3); break; } off(0);off(1); } return 0; } void turn_10(){ int P,v0,v1; v0 = 50; v1 = 50; encoder5_counts = 0; encoder6_counts = 0; while(1){ P = (encoder5_counts - encoder6_counts); if(P<0) { v0 -= 1; v1 += 1; } if(P>0) { v0 += 1; v1 -= 1; } motor(1, (int)v1); motor(0, -(int)v0); if(stop_button())break; printf("\n\nc0: %d c1: %d", encoder6_counts, encoder5_counts); if(encoder5_counts > angle_10 || encoder6_counts > angle_10) break; msleep(50L); } } /** Desenha o numero de quadrados passado como parametros.*/ void squares(int n){ int i; for(i=0; i0) { v0 += 1; v1 -= 1; } motor(1, (int)v1); motor(0, -(int)v0); if(stop_button())break; if(encoder5_counts > angle_90 || encoder6_counts > angle_90) break; msleep(50L); } } /** Anda em linha reta pela distancia passada como parametro, em counts */ void goAhead(int distance){ int P,v0,v1; int goal, i; v0 = 50; v1 = 50; encoder5_counts = 0; encoder6_counts = 0; goal = 0; while(!goal){ P = (encoder5_counts - encoder6_counts); if(P<5) { v0 -= 1; v1 += 1; } if(P>5) { v0 += 1; v1 -= 1; } motor(1, (int)v1); motor(0, (int)v0); if(stop_button())break; //Checa se a distancia foi atingida. for(i=0; i< 6; i++){ if(encoder5_counts > distance || encoder6_counts > distance){ goal = 1; break; } msleep(50L); } } } /** Desenha o numero de circulos de 30cm de raio passado como parametro. */ void circle(int n){ int v0,v1, acum, i; v0 = 0; v1 = 0; for(i=0; i 6){ v0 -= 1; } if(encoder6_counts < 6){ v0 += 1; } if(encoder5_counts > 10){ v1 -= 1; } if(encoder5_counts < 10){ v1 += 1; } motor(1, (int)v1); motor(0, (int)v0); if(stop_button())break; acum += encoder5_counts; encoder5_counts = 0; encoder6_counts = 0; msleep(100L); } } } ====Referências==== MARTIN, Fred G.Robotic Explorations: An Introduction to Engineering Through Design. Prentice Hall; ISBN: 0-130-89568-7.