Relatório TP-3

Introdução

Este trabalho possui 3 partes. Implementar um código de WaveFront, em que se passa um mapa para o robô e ele deve definir uma rota, de um ponto inicial a um final.

A implementação de uma função startup e a construção do sensor necessário. Pois quando uma luz acende na mesa, abaixo do robô, ele deve funcionar durante 60 segundos.

E a montagem de uma catapulta capaz de se armar automaticamente e que consiga arremessar um projétil ao outro lado do campo.

Construção da Catapulta

Nossa catapulta foi implementada como um estilingue. Para a sua construção foi utilizado um motor adicional, mas para que ele consiga “puxar” o elástico foi feita uma grande redução.

O motor gira uma alavanca e ela puxa o elástico pelas duas extremidades, ou seja, a cada 180° girados pela alavanca.

Para a agregação da catapulta ao robô não foram feitas grandes alterações em sua estrutura. Além do posicionamento da catapulta, foram modificados:

  • A posição dos sensores para a luz polarizada, para que não fosse escondido pela catapulta.
  • A base da HandBoard para diminuir o espaço utilizado a fim de caber a catapulta.
  • A substituição da roda pivô, por um roll-on pois o peso em cima da roda devido à catapulta se tornou muito grande e a roda começou a arrastar.

Redução

Foram feitas 4 reduções de 40/8.

WaveFront

#define ESQUERDA 1
#define FRENTE 0
#define DIREITA -1
 
#define LESTE 0
#define NORTE 90
#define OESTE 180
#define SUL 270
 
#define X_DIM 10
#define Y_DIM 10
 
#define MAX 255
 
/* Mapa contendo os obstaculos do ambiente */
int map[X_DIM][Y_DIM];
 
/* Pose = posicao (x y) + orientacao */
int pose_atual[3];    // posicao (x,y) atual + orientacao (N / S / L / O)
int pose_inicial[3];  // posicao inicial
int pose_desejada[3]; // posicao final desejada (ignorar a orientacao)
 
/* Variaveis extras*/
int fifo[100][2];
int indice = 0;
int indice2 = 0;
void push(int x, int y, int valor) {
    if (x >= 0 && x < X_DIM && y >=0 && y < Y_DIM && map[x][y] == 0) {
        //printf("fifo[%d] <= [%d %d]\n", indice, x, y);
        map[x][y] = valor;
        fifo[indice][0] = x;
        fifo[indice][1] = y;
        indice++;
    }
}
 
void pop(int *x, int *y) {
    *x = fifo[indice2][0];
    *y = fifo[indice2][1];
    indice2++;
    //printf("fifo[%d] => [%d %d]\n", indice2, *x, *y);
}
 
 
/* Esta funcao deve calcular o mapa de distancias usando o algoritmo
 * wavefront.
 * A variavel map deve conter as distancias entre o ponto final e inicial
 * ao final da sua execucao
 */
void calculaWaveFront() {
    int x,y;
    int i,j;
    int stop = 0;
 
    for (i = 0; i < X_DIM; i++) {
        map[i][0] = MAX;
        map[i][Y_DIM - 1] = MAX;
    }
    for (j = 0; j < Y_DIM; j++) {
        map[0][j] = MAX;
        map[X_DIM- 1][j] = MAX;
    }
 
    push(pose_desejada[0], pose_desejada[1], 1);
    x = pose_desejada[0], y = pose_desejada[1];
    while (!stop) {
        pop(&x , &y);
        push(x, y - 1, map[x][y] + 1);
        push(x, y + 1, map[x][y] + 1);
        push(x + 1, y, map[x][y] + 1);
        push(x - 1, y, map[x][y] + 1);   
        if (x == pose_inicial[0] && y == pose_inicial[1])
          stop = 1;
    }
 
    for (j = 0; j < Y_DIM; j++)
      for (i = 0; i < X_DIM; i++)
        if (map[i][j] == 0) map[i][j] = MAX;   
}
 
/* Esta funcao deve retornar a direcao que o robo deve seguir para sair
 * do quadrante atual para chegar ate o proximo quadrante, obedecendo
 * o mapa criado pelo algoritmo wavefront
 */
int calculaDirecao() {
    int x, y, xa, ya, xl, yl, xr, yr;
 
    x = pose_atual[0];
    y = pose_atual[1];
    xa = x;    xl = x;
    xr = x;    ya = y;
    yl = y;    yr = y;
 
    if (pose_atual[2] == LESTE) {
        xa = x + 1;
        yl = y + 1;
        yr = y - 1;
    }
    if (pose_atual[2] == NORTE) {
        ya = y + 1;
        xl = x - 1;
        xr = x + 1;
    }
    if (pose_atual[2] == OESTE) {
        xa = x - 1;
        yl = y - 1;
        yr = y + 1;
    }
    if (pose_atual[2] == SUL) {
        ya = y - 1;
        xl = x + 1;
        xr = x - 1;
    }
    if (map[xa][ya] < map[x][y])
      return FRENTE;
    if (map[xl][yl] < map[x][y])
      return ESQUERDA;
    if (map[xr][yr] < map[x][y])
      return DIREITA;
}
 
/* Imprime o mapa na tela. util para realizar a depuracao (so funciona no PC).
 */
void printMap() {
    int i, j;
    for (j = 0; j < Y_DIM; j++) {
        for (i = 0; i < X_DIM; i++) {
            printf("%3d ", map[i][j]);       
        }
        printf("\n");
    }
}
 
/* Le um valor do knob variando de 0 at intervalo*/
int getKnob(char texto[], int intervalo) {
    int valor;
    while (!start_button()) {
        valor = (intervalo * knob()) / 255;
        printf("%s %d\n", texto, valor);
        msleep(100L);
    }
    while (start_button());
    return valor;
}
 
void escolhePosicao() {
    int posicao;
    pose_inicial[0] = getKnob("X inicial: ", X_DIM);
    pose_inicial[1] = getKnob("Y inicial: ", Y_DIM);
 
    pose_atual[0] = pose_inicial[0];
    pose_atual[1] = pose_inicial[1];
 
    pose_desejada[0] = getKnob("X desejado: ",X_DIM);
    pose_desejada[1] = getKnob("Y desejado: ",Y_DIM);
}
 
void escolheMapa() {
    int x, y;
    int n, i;
    n = getKnob("Numero de obstaculos: ", 20);
    for (i = 0; i < n; i++) {
        x = getKnob("X obstaculo: ",X_DIM);
        y = getKnob("Y obstaculo: ",Y_DIM);
        map[x][y] = MAX;
    }
}

StartUp

Sensor

Um LDR foi colocado em um peça Lego, que foi presa na parte inferior do robô.

Função

Enquanto espera pela luz de partida

<code c> while(STARTUP_SENSOR > STARTUP_LIMIAR){

                  sleep(0.1);
                  printf("wating for start light! %d\n", STARTUP_SENSOR);
              }                
              printf("go\n");
              stopstartup();
              _pid_startup = start_process(startup());

<\code>

Depois que a luz é ativada:

<code c> void startup(){

  sleep(60.0);
  stopmenu();
  _pid_menu = start_process(menu());

} <\code>

cursos/introrobotica/2011-2/grupo07/relatorio_tp-3.txt · Última modificação: 2011/11/18 08:09 por fctakahashi