lunes, 14 de noviembre de 2011

Robot Patrulla


Autor
Patricio Bello Villalobos

Competencia 
Gestión en TI.
Nivel 1: Usa sistemas informáticos finales y ofrece soluciones a problemas de los usuarios, mediante la integración básica de distintos elementos de hardware y software.

Descripción de la actividad: 
Se les pide que programen un robot patrullero, que sea capaz de recorrer una ruta
establecida alrededor de una casa que está vigilando, de manera que cada vez que que
escucha un ruido fuera de lo normal, aumenta su nivel de alerta y además pierde energía
pues se contacta con la central de seguridad. Cuando el nivel de alerta alcanza un limite
establecido, el robot entra en modo guardián, acercándose más a la casa, y comienza a girar
en su propio eje para repeler a los ladrones.
En cualquier momento, el robot puede quedarse sin energía; si esto sucede, apaga sus
funciones motores y queda en modo ataque, asechando a enemigos descuidados.
En términos prácticos, ya que no se cuenta con un robot guardián y una casa para realizar una
prueba real, con ayuda de su robot NXT, deben simular esta actividad:
● Se mostrará en pantalla en todo momento: la cantidad de veces que ha detectado
ruidos hasta ese momento, el nivel de alerta del robot, y la energía restante para
su funcionamiento.
○ Los ruidos anormales se detectarán con el sensor de ruido (micrófono) del
robot. Todo ruido que sobrepase un umbral de “40” (superior o igual a una
palmada) será contabilizado.
○ El nivel de alerta será un acumulador que inicia en 0 y que, cada vez que se
registre un ruido, sumará un valor al azar entre 20 y 50.
○ La energía del robot será un acumulador inverso, de manera que empieza
con un valor de 500, y cada vez que se registre ruido, este decrecerá en un
numero al azar entre 50 y 60.
● El robot pasará por 3 modos, cada uno dependiente de los valores de estado del robot:
○ Modo patrulla: Este es el modo inicial de operación del robot. Sigue una
ruta simulada alrededor de la casa, usando una línea negra en forma de
óvalo.
■ El robot siempre debe avanzar en la misma dirección por la ruta.
■ Cada vez que se registre un ruido fuera de lo habitual en el recinto, el
robot debe detenerse, tocar un sonido similar a una sirena y refrescar
en pantalla los valores de cada estado del robot, en el siguiente
formato:
Intentos de robo: 0
Nivel de alerta: 0
Energía restante: 500
Luego, el robot reanuda su patrullaje. Para realizar esto, se utilizarán
los conocimientos utilizados anteriormente en clases y el comando:
● TextOut(x,y, "palabra") ; que imprime la cadena de
caracteres ‘palabra’, dentro de la pantalla del ladrillo NXT, en las
coordenadas (x,y) de la pantalla.
○ Modo guardián: se pasa a este modo cuando el nivel de alerta supera 100.
En este modo sucede lo siguiente:
■ el robot ingresa hacia el centro del ovalo (tener la precaución de no
chocar la casa).
■ comienza a girar sobre su eje a potencia media.
○ Modo ataque: se pasa a este modo cuando la energía restante del robot
es menor o igual a “0” (cero). En este modo sucede lo siguiente:
■ el movimiento del robot se detiene completamente.
■ si el robot detecta algo a menos de 10 cm de la dirección en la que está
mirando, se lanzará en avance con potencia 100% por un segundo y
luego retrocederá por un segundo (a la misma potencia).
■ Este es el modo final, por lo que el programa nunca termina al menos
que Ud. lo detenga manualmente.
● Recuerden que en todos los modos de operación del robot, se debe mostrar por
pantalla la cantidad de veces que ha detectado ruidos hasta ese momento, el nivel
de alerta del robot, y la energía restante para su funcionamiento.

Solución:

Este nuevo trabajo tuvo una mayor complicación que los anteriores, puesto que tuvimos que cambiar el modo de programación que estábamos acostumbrados a realizar, además de la complejidad del programa que nos dio el profesor para trabajar.
El primer problema al cual nos vimos enfrentados fue una nueva forma de hacer la programación la cual consistía en hacerlo en subrutinas, por ende esto nos complicó mucho dado que no estábamos acostumbrados a esto, para lograr darle una solución a este gran problema seguimos adelante tratando de hacer todo ordenado y paso a paso, revisando nuestras guías y nuestros apuntes de clases.
Un segundo problema que se nos presentó fue que nosotros colocamos un sonido muy largo de alerta, lo que causaba que el robot se escuchara así mismo y  por ende marcara que estaban robando, la solución a este problema fue acortar el tono para que de este modo el robot no tuviese problemas.
El tercer y último obstáculo fue que teníamos un problema con los random que daban la información sobre los intentos de robo, energía restante y nivel de alerta, el impedimento fue que no nos daban los resultados dentro de  los valores que nos habían asignado, la solución fue revisar los random y asignarle nuevos valores que concordaran con los que nos entregaron en la guía.
Y a pesar de todos los problemas que se nos presentaron en el desarrollo de este trabajo, logramos terminarlo a tiempo y de manera satisfactoria.
Pseudocódigo:
Nivel de alerta =0
Energia restante = 500
Intentos de robo =0
Modo patrulla
  Mientras (el nivel de alerta sea menor que 100)
     {
         mostrar texto
         {  Mostrar en la pantalla nivel de alerta
            mostrar en la pantalla energia restante
            mostrar en la pantalla intentos de robo
           }
       Si el (sensor de luz detecta blanco)
          {
           Girar levemente hacia el circulo negro
           }
       Sino
          {
            Avanzar
           }
       Si (el sensor de sonido detecta un ruido)
          { Detener el robot
            Tocar la sirena
              {
                reproducir un sonido
                }
           Sumar uno a los intentos de robo
           Restar a energia restante un valor al azar entre 50 y 60
           Sumar a nivel de alerta un valor al azar entre 20 y 50   
           }
   }
Modo Guardian
Cuando (el nivel de alerta supere 100 y la energia restante sea positiva entrar modo guardian)
    {
          Mostrar texto
        { Mostrar en la pantalla nivel de alerta
          Mostrar en la pantalla energia restante
          Mostrar en la pantalla intentos de robo
         }
     Si (el nivel de alerta es mayor que 100)
       { Entrar en el circulo
        Girar sobre su eje a potencia media
        }
     Si (el sensor de sonido detecta un ruido)
        { Sumar uno a los intentos de robo
          Restar a energia restante un valor al azar entre 50 y 60
          Sumar a nivel de alerta un valor al azar entre 20 y 50
          }
   }
Modo Ataque
Cuando (la energia restante es menor o igual que 0)
     {
         Si (El robot detecta algo enfrente suyo a menos de 10 cm)
              {Embestirlo durante un segundo a maxima potencia
               Retroceder a maxima potencia durante un segundo
               }
      }
  Código:
// Este programa hace que el robot se transforme en patrullero encargado de
// vigilar una casa, por medio de ruidos que aumentan el nivel de alerta y a la
// misma vez los intentos de robos, también pierde energía por cada intento
// de robo. Se divide en 3 modos que tienen condiciones para cada uno, que marca
// el inicio y final de cada uno. El primer modo se llama patrulla este consiste
// en rodear la casa en forma de ovalo y al escuchar un ruido aumenta el nivel
// de alerta, al sobrepasar los 100 pasa al siguiente modo llamado guardián
// que ingresa al ovalo y gira sobre su eje hasta que el nivel de energía sea
// 0 esto lo hace porque está relacionado con los intentos de robos cada vez que
// ocurre uno, la energía disminuye. El tercer modo y último es el modo ataque
// para que ocurra el nivel de energía tiene que ser igual o menor que 0
// y hace que el robot esté detenido, si detecta algo en una
// distancia determinada, se lanzará ( embistiendo) con su mayor potencia por
// un segundo y retrocede en las mismas condiciones que avanza ( potencia igual
// a 100 y por 1 segundo), esto ocurre sin un fin, la única forma de terminar
// es haciéndolo manualmente.
//                Grupo AXIS 64
//           - Patricio Bello
//           - Marcelo Carrasco
//           - Felipe Lagos
//           - Esteban Muñoz
//Inicializacion de las variables
int nivel_alerta=0; // El nivel de alerta es importante para cambiar entre los 3 modosint energia_res=500;// Energía que le queda al robot por cada intento de robo disminuyeint intentos_robos=0;// Cada sonido escuchado mediante el sensor de sonido es un
                             // intento de robo.
#define UMBRAL 40//  Rango de luz para considerar que es blanco#define UMBRAL_SONIDO 60 // Necesario para el sensor de sonido detecte los ruidos que
                                           // entra en los intentos de robo. 
#define MIC // Es necesario para que funcione el sensor de sonido al activar el micrófono.#define DISTANCIA 10       // la cantidad medida en cm esto hace que si detecta algo en esa
                                              // cantidad haga la instrucción pedida.
sub texto()   
{
TextOut(0,40,"Int. de robos"); // Muestra en pantalla en palabras intentos de robosNumOut (85,40,intentos_robos);// Indica la cantidad ( numero)  de intentos de robos. TextOut(0,60,"Nv de alerta " ); // En pantalla se ve con palabras Nv de alertaNumOut (80,60,nivel_alerta);// Muestra el valor de la variable nivel_alertaTextOut(0,50,"Energia res");  //muestra en pantalla “energía restante”NumOut (80,50,energia_res);  //Muestra el valor de la variable energia_res
}
sub modo_guardian()
{
  OnRev(OUT_C, 75);// Las 2 instrucciones permite que se de una vuelta para
  
OnFwd(OUT_A, 75);//  posicionar su entrada al ovalo
  
Wait(250);  OnFwd(OUT_AC, 50); // Va hacia adelante por 1 segundo y un poco mas
  
Wait(1800);
  
Off(OUT_AC);// Apaga los motores por medio segundo
  
Wait(500);

while (nivel_alerta > 100 && energia_res > 0) // Mientras las 2 condiciones se cumplan.
       {
       
if(Sensor(IN_2) > UMBRAL_SONIDO) // Si el sensor de sonido detecta un ruido mayor
                                                                        // que el umbral de sonido
       {
       ++
intentos_robos; // Sumar uno a intentos de robos
       
energia_res-=(Random (11)+50); // Resta a energia res un valor entre 50 y 60
       
nivel_alerta+=(Random(31)+20); // Suma a nivel de alerta un valor entre 20 y 50
       }
       texto();  // Muestra el sub modo texto
       OnRev(OUT_C, 50); //  Estas 2 instrucciones hace que gire sobre su eje
       
OnFwd(OUT_A, 50);
 }
       Off(OUT_AC); // Apagar motores
}

sub modo_ataque()
{
while(true)  
  {
            texto();                                               // Muestra el texto
       
Off(OUT_AC);                        // Apagar motores
     
 if (SensorUS(IN_1) < DISTANCIA) // El sensor funciona si se detecta algo entre la distancia
                                                            // especificada antes
       {++
intentos_robos;                 // Sigue la suma en los intentos de robos.
       
nivel_alerta+=(Random(31)+20); // el nivel de alerta suma valores entre 20 y 50
       
OnFwd(OUT_AC, 100);  // Ir hacia adelante embistiendo por 1 segundo
       
Wait(1000);
       
OnRev(OUT_AC, 100); //  Retroceder por 1 segundo
       
Wait(1000);
       
Off(OUT_AC);  // Apagar motores
       }  // Cierre del if
       }  // Cierre del while
       } // Cierre modo ataque
sub sirena()
{
PlayTone (1000,100); // Tonos de la sirenaWait (250);PlayTone (2000,200);Wait (250);
}
sub modo_patrulla()
{
 
while (nivel_alerta<100) // Mientras el nivel de alerta es menor que 100
 {
  texto(); // Muestra el sub modo texto
 
 if (Sensor(IN_3) > UMBRAL) / Si el  sensor de luz detecta un rango mayor que el umbral
  {
       
OnRev(OUT_C, 75);// Al detectar el color blanco se dobla hacia el circulo negro
       
Wait(25);
       }
 
 else
  {
       
OnFwd(OUT_C, 75); // Si no va hacia adelante
       
OnFwd(OUT_A, 80);
       }
  if(Sensor(IN_2) > UMBRAL_SONIDO) // Si el sensor de sonido es mayor que el //umbral_sonido
  {
       
Off (OUT_AC); // Se apaga los motores por 2 segundos
       
Wait (2000);
       sirena(); // Hace lo que está dentro del sub modo sirena donde reproduce un tono
       ++
intentos_robos;// Esto hace que cada vez que detecte un sonido se le sume uno
                                   // al intento de robo
       
energia_res-=(Random (11)+ 50);// Se resta un valor entre 50 y 60 a energia restante
       
nivel_alerta+=(Random(31)+20); // Se suma un valor entre 20 y 50 a nivel de alerta
            // Cierra if
}      //  Cierra while
 }   // Cierra el modo patrulla
task main ()
{
  SetSensorLight(IN_3); // Encender Sensor de Luz
  SetSensorSound(IN_2);// Encender Sensor de Sonido
  SetSensorLowspeed (IN_1);// Encender Sensor de Ultrasonido
  modo_patrulla(); // Llamado del modo patrulla
  modo_guardian(); // Al terminar el modo anterior, se activa este modo
  modo_ataque(); // Luego de terminar el modo guardian pasa a este ultimo
}

Conclusiones
1.     Se pueden agrupar grandes cantidades de instrucciones en sub-rutinas, lo que facilita enormemente la lectura del código y la detección de errores.
2.     Es muy recomendable buscar una condición especial para cada While que se use, ya que así se podrá dar paso a instrucciones fuera de él, solo en el caso de que necesitemos un ciclo infinito del cual el robot no debe salir debemos usar la condición “true”.
3.     Para conservar datos y que funciones para todos los procesos es necesario crear variables e inicializarlas fuera de las sub-rutinas, así tendrán un uso global en el código y no solo en una sub-rutina.
4.     Todas las rutinas que se usen dentro de otras rutinas deben estar ya previamente establecidas  a la rutina que la está usando, de no ser así ocurrirá un error de declaración.
Para establecer valores Random correctamente entre dos números, se deben escribir en forma de suma dos números que al sumarse indican el límite máximo siendo el segundo de ellos el limite inferior, ej x=(Random(31)+20);. 

Reflexión: 
En esta actividad vimos como la utiliacion de una programación puede automatizar casi por completo un robot, dandole múltiples funciones que puede ejecutar, realizando tareas para simplificar la vida de los usuarios.

No hay comentarios:

Publicar un comentario