domingo, 18 de septiembre de 2016

ROBOT MINERO RESCATISTA

Autor:


Rafael Fuentealba

Competencia:

Creatividad e Innovación (Nivel 1)

Asignatura:

Programación de Robot














Palabras claves:

Programación NXC, Robot Lego, Robot Minero, Arreglos, Archivos.


Descripción de la Actividad:

La actividad consiste en la misión que deberá completar un robot previamente programado para emular el rescate en una mina, en donde se encuentran atrapados el presidente (caja blanca) junto a otros 4 civiles (cajas negras). Ya que es primordial que el presidente permanezca sano y salvo, es de suma importancia que este sea la primera víctima en ser rescatada. Esta situación debe ser resuelta en un tiempo límite de dos minutos, después de lo cual, si el robot no ha rescatado al presidente el simulacro finalizará. Si se termina la tarea anterior, el robot deberá continuar avanzando por la mina rescatando civiles y llevándolos hacia una zona segura. Para esto contará con un tiempo de tres minutos. Dicho esto, se entiende que la misión completa dura 5 minutos.
El ganador del concurso será aquel equipo que consiga rescatar al presidente y la mayor cantidad de civiles posibles dentro del tiempo mencionado.



Estrategia de Trabajo:

En un aspecto más técnico, el robot logró funcionar gracias a códigos añadidos a este, los cuales se fueron trabajando por computadora y con conocimientos adquiridos previamente en clases.

Para contextualizar la actividad comenzaremos por decir que se trata de emular el rescate de personas en una mina derrumbada. Entre estas personas civiles se encuentra el presidente, quien debe ser la primera víctima en ser rescatada y llevada a una zona de seguridad. Después de esto el robot debe continuar rescatando al resto de las víctimas.

Estructura del juego:
1. Se comienza a avanzar desde una línea negra marcada en la pista.
2. El circuito consta de distintos caminos formando un circuito.
3. Sobre el final de cada camino se encuentra una caja que puede ser de color blanco o negro.

Reglas:
1. Para completar la misión se tiene un tiempo de 5 minutos.
2. Sobre la pista habrá una caja de color blanco que corresponde al presidente. Este sujeto debe ser rescatado primero ante todas las otras víctimas, para la cual contará con un tiempo de 2 minutos. Si logra ser salvado a tiempo se dará un puntaje de 500 puntos y el robot podrá continuar rescatando personajes, en caso contrario, el simulacro se da por finalizado.
3. Se hallarán 4 cajas negras las cuales corresponden al resto de los civiles. Estas cajas deben ser movidas en un lapso de 3 minutos y posible tiempo extra, vale decir, desde que se rescata al presidente hasta cumplido 5 minutos del simulacro. Por cada civil se dará 50 puntos.
4. El ayudante (quien controla al robot) puede avisar al robot mediante un sonido (aplauso, grito, etcétera) el camino a optar para encontrar al presidente en el tiempo señalado, sin embargo, ante cada eventual acción de este tipo se descontará 20 puntos.
5. El juego se da por finalizado:
    - Si no se rescata al presidente antes de los 2 minutos.
    - Si el robot rescata a todas las víctimas antes de los 5 minutos.
    - Si el tiempo transcurrido es 5 minutos.

El robot construido consta de un sensor de luz ubicada bajo la estructura para poder detectar el color negro de los caminos de la pista.
Se utiliza otro sensor de luz en el frente del robot para detectar el color del objeto que se pueda encontrar en el recorrido. A la vez, se utiliza un sensor de tacto que permite reconocer que existe tal objeto en el camino, esto a la señal de un choque o impacto.
Se utiliza un sensor de sonido para que el robot pueda percibir señales audibles que le indicarán el camino a seguir para encontrar al presidente.
Para mostrar el puntaje obtenido se utiliza el visor ubicado sobre la estructura del robot.

Materiales:
Para lograr al resultado final se utilizaron materiales que fueron sumamente importantes dentro de la actividad, siendo así:

1. Robot construido en la clase de laboratorio N°1, dentro de lo que incluye:
- 2 sensores de luz.
- Sensor de sonido.
- Sensor de tacto.
2. Computador (o notebook) con el programa Bricx Commander y drivers.
3.  Cable de datos USB del robot.
4.  Cargador de batería (Pilas AA opcionales).


Solución:


Para dar solución al problema he diseñado el siguiente pseudocódigo:


subrutina linea
Si sensor tacto= “activado”{
            Suma 1 a contador primera sección
            Suma 1 a contador separador de sección
            Se apagan motores
            Retroceder con motor A
            Apagar motores
                                   
Si sensor luz=  “negro”
            Avanza con motor B
                                   
De lo contrario, si sensor luz =  “blanco”{
            Avanza motor A con más potencia que motor B
            Avanzar motor B con menos potencia que motor A
                       
Finaliza primera sección
Ingresa a la segunda sección

subrutina laberinto

Avanzan motores A y B
Si sensor ultrasonido= “CERCA”
            Se detienen motores
            Gira a la derecha 90º
                                                          
            Si sensor ultrasonido= “CERCA”
                        Se detienen motores
                        Gira 180º
                                                          
De lo contrario
            Avanzar

Si sensor luz= “negro”
            Se detienen motores    
            Suma 1 a contador segunda sección

subrutina circulos
Avanzar
Apagar motores
Girar a la izquierda para comenzar a detectar círculos negros
Apagar motores
Mientras choques en sección 3 sea menor 3 y tiempo menor a 26 segundos:
            Avanzar 
            Si sensor tacto = “activado”
                        Suma 1 a contador de choques sección 3
                        Apagar motores
                        Retroceder
                        Girar a la derecha
            Si sensor de luz = “Negro”
                        Suma 1 a contador de círculos negros
                        Apagar motores
                        Giro de 90 º
                        Avanzar
                        Giro aleatorio entre 90º y 270º
                        Calcular diferencia de tiempo
                                   
subrutina  puntaje
Apagar motores
Si puntajef es >= 0
            calcular puntos totales obtenidos

De lo contrario, si puntaje es negativo:
            puntaje final será 0

Mostrar por pantalla los puntos acumulados
Mostrar por pantalla los puntos descontados
Mostrar por pantalla los puntos finales
Emitir un tono por 10 segundos mientras se muestran los resultados antes mencionados
           
Inicia tarea task
Se activa sensor de tacto
Se activa sensor de luz
Se activa sensor de ultrasonido
Mientras contador separador de sección=0:
            Llamar a subrutina línea
Mientras contador separador de sección=1:
            Llamar a subrutina laberinto
Mientras contador separador de sección=2:
            Llamar a subrutina círculos
            Llamar a subrutina puntaje

Fin de tarea task


El código fuente es el siguiente:



#define UMBRAL 35

#define DECIBEL 50

mutex avanzar;
int choque[4]; //inicializa arreglo
int i= 0; //contador que indica el índice de arreglo
int contobjetos= 0; //cantidad total de objetos
int contcivil= 0; //cantidad de civiles
int contsonido= 0; //contador de señales audibles
int presi= 0; //contador presidente
int pTotales= 0; //almacena puntaje total

sub traspasaArchivo() {
    byte punteroArchivo;
    string cadena;
    byte bytesEscritos;
    CreateFile("Puntaje.txt",600, punteroArchivo);
    WriteLnString(punteroArchivo,"ESTADÍSTICAS DE JUEGO", bytesEscritos);
    WriteLnString(punteroArchivo,"                  ", bytesEscritos);
    cadena= "Presidente:  " + NumToStr(choque[0]) + "  " + NumToStr(choque[0]*500) + " " + "puntos.";
    WriteLnString(punteroArchivo,cadena,bytesEscritos);
    cadena= "Cìviles:     " + NumToStr(choque[1]) + "  " + NumToStr(choque[1]*50) + " " + "puntos.";
    WriteLnString(punteroArchivo,cadena,bytesEscritos);
    cadena= "Descuentos:  " + NumToStr(choque[2]) + "  " + NumToStr(choque[2]*20) + " " + "puntos.";
    WriteLnString(punteroArchivo,cadena,bytesEscritos);
    WriteLnString(punteroArchivo,"       -------------        ",bytesEscritos);
    cadena= "Ptje Total:                  " + NumToStr(choque[3]) + " " + "puntos.-";
    WriteLnString(punteroArchivo,cadena,bytesEscritos);
    CloseFile(punteroArchivo);
}


task chocaobjeto(){
    while(true){
if(Sensor(IN_4)==1){
         if(Sensor(IN_2)>UMBRAL){
                Acquire(avanzar);
                presi++;
                contobjetos++;
                choque[0] = presi;
                NumOut(60,60,choque[0]);
                OnFwd(OUT_AB,50);
                Wait(500);
                OnFwd(OUT_A,50);
                OnRev(OUT_B,50);
                Wait(600);
                Release(avanzar);
                TextOut(5,60,"Presidente");
                Wait(4000);
                NumOut(70,60,presi*500);
                Wait(4000);
            }
            else{
                Acquire(avanzar);
                contcivil++;
                contobjetos++;
                choque[1]= contcivil;
                OnFwd(OUT_AB,50);
                Wait(600);
                OnFwd(OUT_A,50);
                OnRev(OUT_B,50);
                Wait(600);
                Release(avanzar);
                TextOut(5,45,"Civiles");
                Wait(4000);
                NumOut(70,45,contcivil*50);
                Wait(4000);
            }
        }
    }
}


task sonido(){
    while(true){
        if(Sensor(IN_3)>=DECIBEL){
            Acquire(avanzar);
            OnFwd(OUT_A,65);
            OnRev(OUT_B,40);
            Wait(500);
            contsonido++; //suma 1 a contador de señales audibles
            choque[2] = contsonido;
            pTotales = ((presi*500)+(contcivil*50)-(contsonido*20));
            choque[3] = pTotales;
            Release(avanzar);
            TextOut(5,30,"Descuentos");
            Wait(4000);
            NumOut(70,30,contsonido*20);
            Wait(4000);
        }
    }
}

task tiempo(){
    long time= CurrentTick();
        while(true){
            if((CurrentTick() - time == 120000) && presi==0){ //Si tiempo es 2 min y el indice 0 no tiene nada(no se rescató al presidente)
                TextOut(0,20,"---------------------");
                Wait(4000);
                Off(OUT_AB);
                Wait(8000);
                TextOut(5,5,"Ptje Final");
                Wait(8000);
                NumOut(70,5,(presi*500)+(contcivil*50)-(contsonido*20));
                Wait(8000);
                StopAllTasks(); //Se detendrán todas las tareas
            }
            if((CurrentTick() - time <=300000) && contobjetos == 5){
                TextOut(0,20,"---------------------");
                Wait(4000);
                TextOut(5,5,"Ptje Final");
                Wait(8000);
                NumOut(70,5,(presi*500)+(contcivil*50)-(contsonido*20));
                Wait(8000);
                StopAllTasks(); //Se detendrán todas las tareas
            }
            if((CurrentTick() - time == 300000) && contobjetos <> 5){ //Si el tiempo transcurrido es 5 min
                TextOut(0,20,"---------------------");
                Wait(4000);
                TextOut(5,5,"Ptje Final");
                Wait(8000);
                NumOut(70,5,(presi*500)+(contcivil*50)-(contsonido*20));
                Wait(8000);
                StopAllTasks(); //Se detendrán todas las tareas
            }
        }
}

task lineanegra(){
    while(true){
        if(Sensor(IN_1)<UMBRAL){
            Acquire(avanzar);
            OnFwd(OUT_B,50);
            OnFwd(OUT_A,10);
            Release(avanzar);
        }
        else{
            Acquire(avanzar);
            OnFwd(OUT_A,60);
            OnRev(OUT_B,55);
            Release(avanzar);
        }
    }
}

task main(){
Precedes(tiempo,lineanegra,chocaobjeto,sonido);
SetSensorLight(IN_1);
SetSensorLight(IN_2);
SetSensorSound(IN_3);
SetSensorTouch(IN_4);
traspasaArchivo();
}


Primero se definen todas las variables que utilizaremos en el programa. Luego definimos una subrutina que nos será útil para crear un archivo al cual le pasaremos los datos recolectados del juego.

Posteriormente se definen las tareas:
La primera nos servirá para detectar si hemos chocado algún objeto y además saber de que color este mismo, luego de lo cual será desplazado fuera de la pista.
La segunda tarea la utilizaremos para percibir señales audibles y así pode realizar alguna acción (giro) que claramente también será un dato a guardar en el archivo.
La tercera nos servirá para controlar el tiempo de juego, que tiene como máximo una ejecución dentro de 5 minutos, después de lo cual el robot se detiene.
La cuarta tarea la utilizaremos para ir recorriendo los caminos dentro de la pista, permitirá encontrar los objetos que se encuentran dentro de ella.
Por último tenemos la tarea principal main en donde se setean todos los sensores a usar en el juego, además de iniciar todas las tareas y subrutinas ya mencionadas.



Vídeo de la Actividad:





Reflexión:

Esta actividad permitió incorporar todos los conocimientos adquiridos durante el desarrollo del curso de Programación de Robot, ya que utiliza contenido básico como los tipos de datos, sentencias básicas, uso de sensores; hasta contenido más avanzado como arreglos y archivos. 

Otro de los objetivos importantes que se desarrolló fue la creatividad, esto quiere decir, el darse cuenta de que los robots poseen muchas habilidades que ciertamente hacen más sencilla la vida del hombre; sin poner en riesgo esta misma. A lo anterior es posible añadir que la actividad incorpora la creatividad como un fenómeno de desarrollo tecnológico, puesto que implementa la construcción de ideas estructuradas que en estricto rigor configuran  un producto mucho más entretenido, con diseño y funciones más atractivas.


No hay comentarios:

Publicar un comentario