martes, 11 de octubre de 2011

Proyecto PitFinder

Autor: Jorge Henriquez Romero
Competencia: Desarrollo de Software (Nivel 1)
Palabras claves: NXC, Lego, Programacion, PitFinder


Descripción de la actividad
En el siguiente blog daré a conocer los resultados de un proyecto realizado el segundo semestre, el cual fue muy provechoso, porque comenzamos a utilizar arreglos y creación de archivos en NXC.


El proyecto consistió en que un robot debe recorre la meseta de una montaña, y su misión es detectar las alturas de los precipicios de ésta, información que servirá para escaladores, paracaidistas, deportes extremos en general. Esto se guardara en un arreglo y posteriormente pasado a un archivo.

Solución
La solución se demuestra el siguiente Pseudocódigo, en donde se demuestra la forma de solución en palabras.
Pseudocódigo:
Definición de variables, arreglo, umbrales, etc.
sub TraspasaArchivo()
{
  Borra el archivo “Datos.txt”;
  Crea un archivo llamado “Datos.txt”;
  Escribe una cadena que dice "REPORTE PITFINDER";
  Escribe una cadena que dice "------------------";
  Para j=0 y j < ArrayLen(alt) y j++
   {
     Escribe una cadena con los datos tomados;
   }
  Cierra el archivo “Datos.txt”;
} 

sub GuarAlt()              
{
 Guarda en el arreglo “alt” posicion "a" la altura leida;
 Imprime por pantalla la altura leida
 a++;                       
}

task Avanzar()              
{
 Mientras i<4
 {
   Avanzar;
  Si el sensor detecta una altura mayor a “CERCA”;
  {
   i++;       
   Adquiere el semáforo;
   Sigue avanzando por 0.3s;
   Apaga los motores por 1s;
   Ejecuta subrutina "GuarAlt";
   Retrocede 1s;
   Giro aleatorio para encontrar un nuevo precipicio;
   Liberación de semáforo;
  }
 }
 Variable para posicion en la impresion del archivo;
 Variable "bulean" para escribir correctamente las lineas del archivo;
 Detener los motores
 Ejecutar subrutina "TraspasaArchivo";
 Limpia lo escrito en pantalla;
 Abre el archivo creado;
Mientras que la variable bulean sea falsa;
{
  Si no quedan lineas por leer
 {
  Se cambia a verdadera variable bulean;
  Imprime en pantalla la linea leida;
  Disminuye en 10 para imprimir en espacios diferentes;
  Espera 0,5s;
 }
 Espera 5s;
 Cierra el archivo “Datos.txt”;
}

task main()                    
{
 Se ejcuta la tarea Avanzar;
 Setea sensor de ultrasonido;
}
 

El código fuente es el siguiente, y muest5a la solución dada e implementada en el robot.

Código fuente:


int alt[4];            //Arreglo de precipicios
int a=0;   

//Sirve para cambio de posicion de arreglo y posicion de impresion por pantalla
int i=0;               //Veces que se ejecutara el ciclo while
int j=0;               //Veces que se ejecuta ciclo de escritura de archivo
int num=0;
string linea="_=>";    //Para guardar en archivo
string nums;           //Para agregar numero de precipicio en el archivo
string cm= "mts";      //Para guardar en archivo la extension en mts de la altura
byte punteroArchivo;   //fija un puntero para escritura y lectura
string cadena;
byte bytesEscritos;
mutex semaforo;
string leer;
int tam=512;
string mas="precipicio";

#define CERCA 20    //Umbral de la altura fijada

sub TraspasaArchivo()        //subrutina que guarda en archivo
{
 DeleteFile("Datos.txt"); //Borra el archivo creado en la ejcucion anterior del código
 CreateFile("Datos.txt", tam, punteroArchivo);  //crea un archivo nombre, tamaño, y puntero
 WriteLnString(punteroArchivo, "REPORTE PITFINDER", bytesEscritos);
 WriteLnString(punteroArchivo, "--------------------", bytesEscritos);
 for(j=0; j < ArrayLen(alt); j++)
 {
  num++;
  nums= NumToStr(num);
  cadena = NumToStr(alt[j]);
  cadena =  mas + nums + linea + cadena + cm;
  WriteLnString(punteroArchivo, cadena, bytesEscritos);
 }
 CloseFile(punteroArchivo); //Cierra el archivo Creado y escrito
}

sub GuarAlt()        //Subrutina que almacena las alturas en un arreglo
{
 alt[a]=SensorUS(IN_2);  //Guarda en el arreglo posicion "a", la altura leida por el sensor
 NumOut(0,10*a,alt[a]);      //Imprime por pantalla la altura leida
 a++;                        //cambia la posicion que se guardara la proxima vez
}

task Avanzar()               //Tarea Avanzar del programa
{
 while (i<4)                 //Ciclo de ejecucion para la lectura de los 4 precipicios
 {
  OnFwd(OUT_C,50);
  OnFwd(OUT_A,55);           //Avanzar
 
  if (SensorUS(IN_2)>CERCA)  //Si el sensor detecta una altura mayor a "20mts"
  {
   i++;                      //Aumenta en 1 el i para luego salir del ciclo
   Acquire(semaforo);        //Adquiere el semáforo
   OnFwd(OUT_C,50);
   OnFwd(OUT_A,55);
   Wait(300);                //Sigue avanzando por 0.3sec para una mejor lectura
   Off(OUT_AC);
   Wait(1000);               //Apaga los motores por 1sec
   GuarAlt();                //Ejecuta subrutina "GuarAlt"
   OnRev(OUT_C,50);
   OnRev(OUT_A,55);
   Wait(1000);               //Retrocede 1sec
   OnFwd(OUT_C,50);
   OnRev(OUT_A,55);
   Wait(Random(1500)+400);   //Giro aleatorio para encontrar un nuevo precipicio
   Release(semaforo);  //devuelve el semaforo
  }
 }
 int pa=50;          //Para fijar posicion en la impresion del archivo
 bool v_f = false;   //Variable "bulean" para escribir correctamente en pantalla todas las lineas del archivo
 Off(OUT_AC);        //Detener los motores
 TraspasaArchivo();  //Ejecutar subrutina "TraspasaArchivo"
 ClearScreen();  //Limpia lo escrito en pantalla
 OpenFileRead("Datos.txt", tam, punteroArchivo); //Abre el archivo creado
 while (v_f == false)     //Ciclo que se ejecuta mientras la variable bulean sea falsa
 {
  if(ReadLnString(punteroArchivo,leer) != NO_ERR) //Si no quedan lineas por leer
  v_f = true;                                     //Cambia a verdadera variable bulean
  TextOut(LCD_LINE8,pa,leer);   //Imprime en pantalla la linea leida
  pa= pa-10;                    //Disminuye en 10 para imprimir en espacios diferentes
  Wait(500);
 }
 Wait(5000);                    //Espera 5sec para apreciar la impresión
 CloseFile(punteroArchivo);     //Cierra el archivo
}

 
task main()                     {
 Precedes(Avanzar);             //Se ejcuta la tarea Avanzar
 SetSensorLowspeed(IN_2);       //Setea sensor de ultrasonido
}


El siguiente video evidencia que el programa si funciona crrectamente:






Reflexión
El proyecto realizado junto a algunos de mis compañeros, me ayudo bastante a entender cómo funcionaban los arreglos y la creación y guardado de archivos en NXC, además de promoverme el trabajo en grupo, el cual es muy importante en la carrera de ing. Civil en informática. En conclusión, fue muy enriquecedora para mí, y me permitió entender mejor el funcionamiento del robot Lego NXT.

Espero les haya servido el contenido de este blog, porque a mí me sirvió bastante en el desarrollo de futuros proyectos.

No hay comentarios:

Publicar un comentario