====== 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.