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
}
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