domingo, 9 de octubre de 2011

Juego Dribbler

Autor: Felipe Andres Lagos Morapasten
Competencia: Desarrollo de Software (Nivel 1)
Palabras Clave: Proyecto de Robot,NXC, Arreglos,Tareas.

Descripción de la Actividad

Quiero compartirles con ustedes la realización de un video juego llamado Dribbler, correspondiente al proyecto número 1 del Curso de Robótica, que se tuvo que programar en lenguaje NXC.
El juego que debe ejecutar el robot consiste en encontrar zonas de puntaje que están en la pista sin chocar con los obstáculo que presenta al momento de impacta el juego se termina, cuenta con una especie de ayuda que consiste en una señal auditiva que hace cambiar el rumbo, sentido que lleva el robot. 

Solución
Lo inicial de cada actividad es el pseudocódigo que nos dará la idea principal de la actividad, que luego se lleva, traspasa al código fuente NXC.

Umbral Sonido=80 
Umbral=40 
suma=0 
contadorp=0 
potencia=20 
i=0 
puntos[100] 
tiempo = 0
mutex bandera
mutex música

Tarea música()
{Mientras (Siempre)
{Adquirir recurso (música)
Tocar música
Liberar recurso (música) } // Cierre del Mientras
} // Cierre de la tarea música

Tarea avance ()
{ Registrar tiempo anterior
Mientras (Siempre)
{Adquirir recurso (bandera);
Avanzar con el valor de Potencia
Liberar recurso (bandera);

Si (Sensor de luz detecta negro)
{Registrar tiempo de demora al encontrar el punto negro
Tocar un Sonido indicando la detección de punto

Si(el tiempo de demora es mayor o igual a 10)
{tiempo=10 }

Calcular el puntaje obtenido y guardarlo en el arreglo, puntos[]
contadorp++
suma=suma+puntos[i]

Si (la potencia >=100)
{Potencia=100}
sino
{Potencia=potencia+10 }

Adquirir recurso (bandera);
Girar sobre su eje en un ángulo aleatorio
Liberar recurso (bandera);
} // Cierre del Si
} // Cierre Mientras
}// Cierre Tarea Avance

Tarea peligro ()
{Mientras (Siempre)
{Si (Detecta un sonido sobre el Umbral de sonido)
{Adquirir recurso (bandera);
Girar en un ángulo leve
Liberar recurso (bandera);} //Cierre Si
} // Cierre Mientras
}// Cierre Tarea Peligro

Tarea final ()
{Mientras (Siempre)
{Si (Detecta pared)
{Mientras (contadorp<=15)
{Mostrar en pantalla los puntajes obtenidos y la suma total
contadorp++
} // Cierre del Mientras

Adquirir recurso (bandera);
apagar motores
Liberar recurso (bandera);
detener todas las tareas
}// Cierre del Si
} // Cierre Mientras
}// Cierre Tarea final.

Tarea Principal ()
{Hacer correr todas las tareas
Encender Sensores de Luz, Tacto y Sonido
} 
El Código fuente del proyecto es el que sigue:
#define Umbral_Sonido 80 // Usado para que el sensor de Sonido detecte el aplauso
#define Umbral 40 // Declarado para ser usada como un punto negro por el Sensor de Luz
int suma=0; // Variable que representa el total del puntaje
int contadorp=0;// Variable usada que cuenta la cantidad de veces que detecta los puntos negros.
int potencia=20; // Potencia inicial que arranca el robot en la actividad.
long actual = 0; // Usado para registrar el tiempo hasta encontrar un punto negro
long anterior = 0; // Usado para registrar el tiempo desde el comienzo.
int i=0; // Marca la posición número 1 para el arreglo
int puntos[100]; // Arreglo que guarda el valor de los puntajes obtenidos al detectar un punto negro.
int giro=0; // Variable usada para realizar un giro en 180° al momento de detectar una señal auditiva
int tiempo = 0;// Variable usada para marcar lo que demoro en buscar un punto negro, lo que determina el puntaje obtenido(( actual - anterior)/1000)
int pos=0; // Usado para que al momento de Mostrar en pantalla avance lo guardado en el arreglo.
int altura=30; // Usado como coordenada Y en la muestra de la pantalla del ladrillo.

mutex bandera; // Con esto nos aseguramos que al mover de los motores no ocurra que resultados inesperados al tratar de funcionar
mutex musiquita; // Usado para la musica de fondo y el sonido de obtener puntaje.

task musica() // Tarea de la música de Fondo.
{
while(true) // Mientras sea verdadero
{ Acquire(musiquita); // Indica que el control en este caso de la musica la tiene esta tarea.
PlayTone (700,100); // Los 4 Playtone confeccionar la música de fondo gracias a sus diferentes frecuencias y tiempos.
Wait (200);
PlayTone (1000,100);
Wait (200);
PlayTone (1500,100);
Wait (200);
PlayTone (1200,100);
Wait (200);
Release(musiquita); // Esto quiere decir que libera el uso del sonido para que otra tarea la use.
} // Cierre del While
} // Cierre de la tarea musica

task avance()
{
anterior=CurrentTick(); // En esta variable guarda el tiempo desde el inicio del programa
while(true) // Mientras sea verdadero
{ Acquire(bandera); // Usado para que los motores tenga el control para avanzar
OnFwd(OUT_AC,potencia); // Avanzar con una potencia determinada en este caso 20.
Release(bandera); //Indica que los recursos del avance esten libres, lo puedan usar otra tarea.

if(Sensor(IN_3) <= Umbral) // Si el Sensor de Luz detecta un punto negro.
{
actual=CurrentTick(); // Guarda el tiempo que demoro en detectar un punto.
PlayTone (1000,100); // Los 2 Playtone marcan el hallazgo de un punto negro
Wait (250);
PlayTone (2000,200);
Wait (250);
tiempo=(actual-anterior)/1000; // La variable tiempo se guarda el tiempo exacto en segundo que demoro desde el inicio al encontrar un punto.
if(tiempo>=10) // Si el tiempo es mayor o igual a 10
{tiempo=10;} // El tiempo será 10 lo que en la ecuación de los puntos lo igual a 0 el puntaje.

puntos[i]= 50 - 5*tiempo; // Arreglo que determina el puntaje obtenido en relación al tiempo obtenido.
contadorp++; // Para contar el numero de veces que detecta un punto.
suma=suma+puntos[i]; // Marca el resultado total del puntaje que se obtienen
i++; // Usado para que se guarden valores una posición más allá de la inicial en el arreglo

if(potencia>=100) // Si la potencia es igual o mayor que 100
{potencia=100;} // La potencia es igual a 100.

else // Sino
{ potencia=potencia+10;}// La Potencia aumenta en 10

// Cierre Potencia

Acquire(bandera); // Lo mismo que en el inicio de la tarea en el uso de motores, ahora tienen el control.
OnFwd(OUT_A,75); // Las dos instrucciones usadas para que realice un giro aleatorio
OnRev(OUT_C,75); // para cambiar el rumbo que se lleva
giro=Random(400)+200;
Wait(giro);
Release(bandera); // Marca el final del uso del recurso del motor,
} // Cierre del if Punto Negro
} // Cierre While
} // Cierre Tarea Avance

task peligro() // Tarea de Peligro al momento de una advertencia ante un posible choque con una pared o obtáculo.
{
while(true) // Mientras sea verdadero
{
if(Sensor(IN_2) >= Umbral_Sonido) // Si el sensor de sonido detecte un sonido ( aplauso)
{
Acquire(bandera); // Usada para que tenga el control del robot mientras sucede lo anterior
OnFwd(OUT_A,75); // Instrucciones para que se realice un giro de 180° grados
OnRev(OUT_C,75);
Wait(200);
Release(bandera); // Marca el final del control de la tarea, de los recursos.} //Cierre IF
} // Cierre While
} // Cierre Tarea Peligro

task final() // Tarea final es la que arranca al momento de detectar un golpe
{while (true) // Mientras sea verdadero
{if ((Sensor(IN_1)==1)) // Si el sensor de tacto es igual a 1, detecta un golpe
{ while(contadorp<=15) // Mientras el contador de los puntos sea menor o igual a 15
{NumOut(0, altura, puntos[pos]); // Muestra en pantalla el valor de los puntajes obtenidos
TextOut(30,30,"Pje.Total"); // Muestra en pantalla el texto "Pje.Total"
NumOut(30,20, suma); // Muestra en pantalla el resultado de la suma de los puntajes obtenidos
contadorp++; // Le suma uno al contador de los puntos
pos++; // Suma uno a la variable de la posición usada para el arreglo
altura=altura+5; // Usado para que cada que muestre un valor se valla corriendo lugares en la pantalla.
} // Cierre del while

Acquire(bandera); // Con esto se asegura que al momento de ocurrir lo de arriba el control lo tenga esta tarea.
Off(OUT_AC); // Apaga los motores por 5 segundos
Wait(5000);
Release(bandera);// Se detiene los recursos, se liberan de la tarea, el uso de los motores.
StopAllTasks(); // Detiene todas las tareas
}// Cierre del If
} // Cierre While
} // Cierre Tarea final.

task main () // Tarea Principal.
{Precedes(musica,avance,final,peligro);// Usado para que todas las tareas trabajen paralelamente
SetSensorTouch(IN_1); // Encender Sensor de Tacto, Puerto numero 1
SetSensorSound(IN_2); // Encender Sensor de Sonido, Puerto numero 2
SetSensorLight(IN_3); // Encender Sensor de Luz, Puerto numero 3}
Se puede destacar del codigo fuente que existen muchas instrucciones para la realización optima del proyecto, se aprecia el uso de tareas, y el guardado de valores en un arreglo, lo anterior nombrado es lo fundamental para realizar el proyecto,además se encuentran órdenes para asignar recursos, liberar recursos, mostrar en pantalla, avanzar, girar entre otras.
 El video que muestra el proyecto Dribbler es este:
 
 Reflexión

El uso de tareas y arreglos marcó totalmente el desarrollo de la actividad ya que fue necesario saber manejar las condiciones para que arranque cada tarea, ademas de asignar, liberar recursos para que no ocurra un conflicto en la ejecución del código, esto fue realizado de manera más fácil programarlo por el aprendizaje propio obtenidos en este y otros cursos. Lo que mayor complejidad fue el manejo de arreglo, al tener que modificar la posición que se guardará, así como en el mostrado en pantalla.
Te invito a que si tienes dudas o quieres complentar esta actividades mediante opiniones, otras informaciones no tengas miedo de emitir tus comentarios, a participar donde cada comentario hará que se haga más interactivo este espacio.
 

No hay comentarios:

Publicar un comentario