lunes, 10 de octubre de 2011

Laboratorio N°4 Robot Patrulla.

Autor: Manuel Vidal Jaque 
Competencia: Desarrollo de Software (Nivel 1): Desarrolla soluciones de software aplicando procesos de análisis, diseño y prueba a problemas simples; centrados en la programación, los datos y las Interfaces Humano/Computador (IHM).
Palabras Clave: Programación, NXC, robótica, Lego



Descripción de la Actividad


En este presente artículo quiero compartir con ustedes mi experiencia en el laboratorio nº 4 de programación de robot. En esta actividad junto a mis compañeros de grupo tuvimos que implementar un programa en NXC para que nuestro robot lego actuara como un robot guardián el cual debía ser de pasar por 3 modos. El “Modo Patrulla” en el cual recorría una ruta establecida alrededor de una “casa” que se supone vigilaba, además cuando escuchaba un ruido aumentaba su medidor de alerta y perdía energía, cuando el robot llegaba a un nivel de alerta establecido entraba en el “Modo Guardián” en este modo se acercaba a la “casa” y comenzaba a girar, final mente cuando el robot se quedaba sin energía pasaba al “Modo Ataque” en este modo arremetía a todo lo que se acercase a él.


Solución
Primero, escribimos el pseudocódigo que diera solución al problema:

Pseudocódigo Robot Patrulla
Int color negro
Int color blanco
Int ruido
Int alerta=0
Int Energía = 500

Tarea Modo Patrulla
Mientras (alerta>100)
{
Si (sensor_de_luz detecta el color Negro)
 Avanzar con ambos motores;
Si (sensor_de_luz detecta el color blanco)
Reducir la velocidad del motor izquierdo;
Si (sensor_de_Sonido < ruido)
{
Detener ambos motores;
Tocar sirena;
Sumar a nivel de alerta valor al azar entre 20 y 50;
Restar a Energía valor al azar entre 50 y 60;
Llamar sub rutina pantalla;
}
}
Tarea Modo Guardián
Si (alerta<100)
{
Girar a la izquierda;
Avanzar ambos motores;
Si (sensor_proximidad >= 14cm)
              {
              Parar ambos motores;
Avanzar motor izquierdo;
Retroceder motor derecho;
Llamar Sub Rutina Sonido;
}
}
Tarea Modo Ataque
Mientras (Energía >=0)
{
       Apagar ambos motores;
       Si (sensor_proximidad >= 10cm)
              {
              Avanzar con ambos motores, con potencia 100;
              Durante 1 segundo;
              Retroceder con ambos motores, con potencia 100;
              Durante 1 segundo;
              Llamar Sub Rutina Sonido;
}
}
Sub Rutina Sonido
{
Si (sensor_de_Sonido < ruido)
{
Sumar a nivel de alerta valor al azar entre 20 y 50;
Restar a Energía valor al azar entre 50 y 60;
Llamar sub rutina pantalla;
}
}
Sub Rutina pantalla
{
Refrescar pantalla;
Mostrar nivel alerta;
Mostrar  intentos de robo;
Mostrar Energía;
}
Tarea Principal
{
Encender sensor_de_luz;
Encender sensor_de_sonido;
Encender  sensor_proximidad;
Ordenar tareas (Modo Patrulla,  Modo Guardián,  Modo ataque)
}



Uno problema fue entender la real utilidad de las subrutinas y aplicarlas correctamente. Al principio creíamos que podíamos separar el funcionamiento total del robot en tres subrutinas como nos fue sugerido en clases, lo que fracasó para nosotros. Tuvimos que replantear innumerables veces nuestro entendimiento de aquella función. Finalmente aplicamos como subrutinas a ‘funciones’ que se repetían en distintas partes del código o mejor dicho, en diferentes “instancias” o “tareas”, y que la función principal era poder repetir un mismo código sin tener que escribir más de una vez lo mismo, y no usarlo para “diferenciar” tareas. Por lo tanto, nos vimos obligados a usar subtareas y subrutinas.


El codigo fuente de nuestro robot finalmente fue este:

//Programacion de Robots
//Grupo WPE_PRO
//Manuel Vidal, Sebastian Muñoz y Pablo Hernandez P.
//LABORATORIO No.4 ROBOT PATRULLA
//CONSTANTES
#define UMBRAL 70                             
//Para sensor sonido
#define NEGRO 50                               
//Para sensor luz
#define NEAR 10                                  
//Para sensor lowspeed
#define __NOTETIME   35                  
//Para subrutina music
#define __WAITTIME   12                  
//Para subrutina music

//VARIABLES
int energia=500;                                  //valores iniciales
int alerta=0;
int robos=0;

//SUBRUTINAS

sub music()                                       //subrutina de melodia
{                                                
//por herramienta
  PlayTone(1397,4*__NOTETIME);                    //BRICK PIANO.
  Wait(4*__WAITTIME);
  PlayTone(5274,4*__NOTETIME);
  Wait(4*__WAITTIME);
  PlayTone(1397,4*__NOTETIME);
  Wait(4*__WAITTIME);
  PlayTone(4699,4*__NOTETIME);
  Wait(4*__WAITTIME);
  PlayTone(1397,4*__NOTETIME);
  Wait(4*__WAITTIME);
  PlayTone(5274,4*__NOTETIME);
  Wait(4*__WAITTIME);
}

sub sound()                              //subrutina de detección de sonido
{
  Off(OUT_AC);
  music();                          //intro subrutina de alarma dentro de otra subrutina
  Wait(1000);
  alerta=alerta+Random(31)+20;      //incremento aleatorio de alerta
  energia=energia-Random(11)-50;    //decremento aleatorio de energia
  robos++;                          //incremento de robos fijo +1
  ClearScreen();
  TextOut(6,10,"Robo" );            //DISPLAY LCD, formato: TEXTO/NUMERO
  NumOut(51,10, robos);
  TextOut(7,30, "Alerta" );
  NumOut(50,30, alerta);

  TextOut(7,50, "Energia" );
  NumOut(50,50, energia);
}

sub ataque()                           //subrutina de ataque
{
  while(energia<=0)
   {
    Off(OUT_AC);
    if (SensorUS(IN_4)<NEAR)           //si sensor lowspeed detecta objeto a 10 cms
     {
      OnFwd(OUT_AC,100);
      Wait(1000);
      OnRev(OUT_AC,100);
      Wait(1000);
     }
   }
}

sub guardian()                          //subrutina guardian
{
    while(alerta >= 100 && energia >= 0)   //si alerta es mayor o igual a 100 y energia es mayor o igual a 0
    {
     OnFwd(OUT_A,50);                        //girar a velocidad media
     OnRev(OUT_C,50);
     if(SENSOR_3 > UMBRAL)
     {                                      //intro subrutina de deteccion sonido
      sound();
     }
    }
}
sub antguardian()                        //subrutina anteior a guardian, para posicionamiento dentro de circunferencia
{                                        //gira hacia dentro de la circunferencia y avanza, se detiene y pasa a prox sub.
    OnFwd(OUT_A,60);
    OnRev(OUT_C,60);
    Wait(390);
    OnFwd(OUT_AC,75);
    Wait(800);
    Off(OUT_AC);
}
//SUBTAREAS
task Submain()                           //tarea SUBMAIN. De aqui sale el modo patrulla y
{                                        //las condiciones para que los demas modos se ejecuten.
     while(true)
      {
       if(SENSOR_3 > UMBRAL)             //Para deteccion de sonido
        {
         sound();
        }
       if (SENSOR_2 > NEGRO && alerta < 100)          //SEGUIR LINEA NEGRA
        {
         OnFwd(OUT_C,20);
         OnFwd(OUT_A,70);
        }
       if (SENSOR_2 < NEGRO && alerta < 100)          //SEGUIR LINEA NEGRA2
        {
         OnFwd(OUT_AC,70);
        }
       if (alerta >=100)                               //si alerta es igual o mayor que 100, pasar a
        {
         antguardian();                                //posicionamiento pre modo guardian, y pasar a
         guardian();                                   //modo GUARDIAN
        }
       if (energia <= 0)                               //si energia es menor o igual a 0, pasar a
        {
         ataque();                                     //modo ATAQUE
        }
      }
}
//TAREA PRINCIPAL
task main()                                           //tarea principal, activaciones de sensores.
{
  SetSensorLight(IN_2);
  SetSensorSound(IN_3);
  SetSensorLowspeed(IN_4);
  Precedes(Submain);                                  //tarea principal precede a tarea secundaria
}



En el siguiente vídeo pueden apreciar la actividad que realice



Reflexión
Esta actividad fue muy entretenida y a la vez pude aprender mucho sobre como programar las sub rutinas, primeramente haciendo un análisis lógico y redactando una primera solución atreves del pseudocódigo.

Te invito a que compartas tus comentarios o consultas





No hay comentarios:

Publicar un comentario