lunes, 10 de octubre de 2011

Actividad #1 Proyectos de Robots

Autor: Manuel Vidal Jaque 
Competencia: Desarrollo de Software (Nivel 1): Desarrolla soluciones de software aplicando procesos de análisis, diseño y prueba a problemas simples; centrados en la programación, los datos y las Interfaces Humano/Computador (IHM).
Palabras Clave: Programación, NXC, robótica, lego.


Descripción de la Actividad
En esta entrada de mi blog le contare sobre mi primera actividad del ramo Proyecto de Robótica, esta actividad consistió en un repaso del contenido del primer semestre, agregando la funcionalidad del uso de parámetros dentro de las subtareas. Para practicar esto se nos pidió programar un robot que se desplace por una superficie blanca delimitada por paredes, y con puntos negros en su superficie. El robot debía reaccionar a los puntos negros y las paredes, haciendo giros aleatorios y aumentando su velocidad si pasaba por un punto negro y disminuyendo su velocidad si chocaba con una pared. En detalle las instrucciones eran las siguientes:

Cada vez que el robot chocaba con una pared debía:
Retroceder un poco,
Girar 180° a la izquierda o derecha,
Disminuir su potencia en 10,
Contar los choques con las paredes,
Y seguir su recorrido con la nueva potencia
 Al pasar por un punto negro debía:
Contarlo,
Girar en un ángulo aleatorio menor a 180° a la izquierda o derecha,
Aumentar su potencia en 10,
Y seguir su recorrido con la nueva potencia.
El robot se desplazaba por tiempo indefinido, deteniendo su recorrido ante una señal auditiva sobre 80 db.
Al final del recorrido, informaba atreves de su visor el n° de choques y el n° de puntos negros detectados.

Solución
Para resolver el problema que se nos planteo primero que nada desarrollamos el pseudocódigo, luego diseñamos el robot de manera que cumpliera con los requisitos para poder cumplir con la actividad y finalmente implementamos el código en NXC.

Pseudocódigo del código NXC


Encender sensores de luz, sonido y tacto.
Definir constantes de umbral de sonido y color blanco para sensor de luz.
Definir variables para las funciones.

Subtarea GiroPotencia
Si el evento es “choque”
 Retroceder 8 segundos.
Potencia total disminuir en 10.
Contador choque++
Si la potencia era inferior a 30, la potencia vuelve a 30.
Si la dirección es “izquierda”
Girar hacia la izquierda por t segundos (t random).
Volver al avance hacia adelante con potencia modificada.
Si la dirección es “derecha”
Girar hacia la derecha por t segundos.
 Volver al avance hacia adelante con potencia modificada.
Si el evento es “puntos negros”
Potencia total aumentar en 10.
Si la potencia es mayor que 100, volver a 100.
Contador puntos++.
Si la dirección es “izquierda”
Girar hacia la izquierda por t segundos. (random)
Seguir avance hacia adelante con nueva potencia.
Si la dirección es “derecha”
 Girar hacia la derecha por t segundos (random)
Seguir avance con nueva potencia.

Subtarea para cambio de dirección.
Si un numero random es mayor que 100 -> return “d”
                Si un numero random es menor que 100 -> return “i”

Tarea main
 Ejecutar mientras el ruido sea menor de 80 dB lo siguiente:
 Avanzar a velocidad x.
si el sensor tacto es presionado…
 evento = choque
 subtarea GiroPotencia
si el sensor de luz detecta color negro…
evento = punto negro
subtarea GiroPotencia
 Si el sonido supera el umbral de 80 db.
 Imprimir contador choques y puntos negros.
 Esperar.
                        Terminar programa



Código fuente final del robot

//UC Temuco
//Ing Civil Informatica
//PROYECTO ROBOTICA
//Grupo MISSING NO
//Pablo Hernandez, Nicolas Miranda y Manuel Vidal.
//Actividad #1

#define UMBRAL 80
#define BLANCO 50

//VARIABLES
int t=0;                      //variable que contendrá los tiempos para los giros
int potencia= 30;             //variable que contendrá el valor de la potencia de los motores
int azar=0;                   //variable que contendrá valores enteros al azar
int cuentaChoque =0;          //contador de choques
int cuentaCirculo=0;          //contador de círculos negros
string direccion, evento;     //variables que contendrán los string que se usaran como parámetros


//SUBRUTINAS

sub GiroPotencia(int t, string direccion, string evento)   //subrutina que funcionara con 3 parámetros
    {
    if(evento == "choque")                                 //si la variable evento contiene el string "choque"
      {
      OnRevReg(OUT_AB,75,OUT_REGMODE_SPEED);               //retroceder
      Wait (800);
      if(direccion == "i" )                                //si la variable direccion contiene "i"
                  {
        OnFwdReg(OUT_B, 75,OUT_REGMODE_SPEED);             //giro a la izquierda
                  OnRevReg(OUT_A, 75,OUT_REGMODE_SPEED);
                  Wait (t) ;                                         //tiempo para el giro
        OnFwdReg(OUT_AB, potencia,OUT_REGMODE_SPEED);      //avanzar
                  }
      if(direccion == "d")                                 //si la variable direccion contiene "d"
                  {
                  OnFwdReg(OUT_A, 75,OUT_REGMODE_SPEED);             //giro a la derecha
                  OnRevReg(OUT_B, 75,OUT_REGMODE_SPEED);
                  Wait (t) ;                                         //tiempo para el giro
        OnFwdReg(OUT_AB, potencia,OUT_REGMODE_SPEED);      //avanzar
                  }
      potencia= potencia-10;                               //disminución de la potencia
      if( potencia<30){                                    //condición que impide que la potencia sea inferior a 30
         potencia=30;}
      cuentaChoque++;                                      //se aumenta el contador de choques
      }
     
    if(evento == "circulo")                                //si la variable evento contiene el string "circulo"
      {
      if(direccion == "i" )                                //si la variable direccion contiene "i"
                  {
        OnFwdReg(OUT_B, 75,OUT_REGMODE_SPEED);             //giro a la izquierda
                  OnRevReg(OUT_A, 75,OUT_REGMODE_SPEED);
                  Wait (t) ;                                         //tiempo para el giro
        OnFwdReg(OUT_AB, potencia,OUT_REGMODE_SPEED);      //avanzar
                  }
      if(direccion == "d")                                 //si la variable direccion contiene "d"
        {
                  OnFwdReg(OUT_A, 75,OUT_REGMODE_SPEED);             //giro a la derecha
                  OnRevReg(OUT_B, 75,OUT_REGMODE_SPEED);
                  Wait (t) ;                                         //tiempo para el giro
        OnFwdReg(OUT_AB, potencia,OUT_REGMODE_SPEED);      //avanzar
                  }
      potencia= potencia+10;                               //se aumenta la potencia
      if( potencia>100){                                   //condición que impide que la potencia sobrepase 100
         potencia=100;}
      cuentaCirculo++;                                    //se aumenta el contador de círculos
           }
    }


inline string direccionador()                    //función que retorna al azar un string
{
azar=random(200);
if(azar<100){
       return "d" ;}                                  //retorna "d" indicando giro a la derecha
if(azar>100){
       return "i";}                                   //retorna "i" indicando giro a la izquierda
}


task main()                                      //Tarea principal
{
SetSensorTouch(IN_1);                            //se encienden los sensores
SetSensorLight(IN_2);
SetSensorSound(IN_3);

while(SENSOR_3<UMBRAL)                           //ciclo que se ejecuta mientras el sensor de sonido no detecte 80 db
  {
       OnFwdReg(OUT_AB, potencia, OUT_REGMODE_SPEED); //avanzara según la potencia que contenga la variable potencia
       if(SENSOR_1==1)                                //si es detectado un choque
    {
    t=400;                                       //se asigna a t el tiempo necesario para realizar el giro de 180 grados
    direccion =direccionador();                  //se asigna a la variable direccion el string retornado por la función inline
    evento="choque";                             //se asigna a la variable evento el string "choque"
    GiroPotencia(t,direccion,evento);            //se llama a la subrutina y se le pasan los parametros
    }
  if(SENSOR_2<BLANCO)                            //si es detectado un círculo negro
    {
    t =random(400);                              //se asigna a la variable t un int al azar
    direccion =direccionador();                  //se asigna a la variable direccion el string retornado por la función inline
    evento="circulo";                            //se asigna a la variable evento el string "circulo"
    GiroPotencia(t,direccion,evento);            //se llama a la subrutina y se le pasan los parámetros
    }
  }
Float(OUT_AB);                                   //se detienen los motores
ClearScreen();                                   //se limpia e imprime en pantalla la cantidad de choque y círculos
TextOut(6,10,"Choques" );
NumOut(51,10, cuentaChoque);
TextOut(7,30, "Circulos" );
NumOut(50,30, cuentaCirculo);
Wait(10000);
}                                                //FIN


Este es el vídeo que documenta esta actividad



Reflexión

Con esta actividad fui capaz de comprender como programar funciones que trabajen con parámetros, ya sean ingresados o retornados por otras funciones o sub rutinas.

Les invito a que dejen sus comentarios sobre esta entrada.




Mi primer programa en java

Autor: Manuel Vidal Jaque 
Competencia: Desarrollo de Software (Nivel 1): Desarrolla soluciones de software aplicando procesos de análisis, diseño y prueba a problemas simples; centrados en la programación, los datos y las Interfaces Humano/Computador (IHM).
Palabras Clave: Programación, Java, BlueJ.


Descripción de la Actividad
En esta entrada les mostrare el primer programa en java que tuve que implementar como respuesta a una actividad del ramo Programación 1. El programa que debí crear tenía que responder al siguiente enunciado:Crear un programa que haga la conversión de cierta cantidad de años a su equivalencia en las siguientes medidas de tiempo: Meses, Semanas, Días, Horas, Minutos, Segundos y Mili segundos.


Solución

Resolví el problema planteado utilizando un método de análisis de varios pasos: primero analice cuales eran los datos de entrada y salida para el programa, también desarrolle la solución usando un ejemplo concreto paso a paso y a partir del hice una generalización mediante un diagrama de flujo para finalmente implementar el programa en el lenguaje java. 




Ejemplo 1:
Si se ingresan 2 años  la salida debiera ser:
Meses
Semanas
Días
Horas
Minutos
Segundos
Milisegundos
24
104
730
17532
1051920
63115200
63115200000

Ejemplo 2:
Si se ingresan 5 años las salidas debieran ser:
Meses
Semanas
Días
Horas
Minutos
Segundos
Milisegundos
60
260
1825
43830
2629800
157788000
157788000000

Ejemplo 3:
Si se ingresaran 10 años las salidas debieran ser:
Meses
Semanas
Días
Horas
Minutos
Segundos
Milisegundos
120
520
3650
87660
5259600
315576000
315576000000

Ejemplo 4 :
Si se ingresan 0,5 años las salidas  debieran ser:
Meses
Semanas
Días
Horas
Minutos
Segundos
Milisegundos
6
26
182,5
4383
262980
15778800
15778800000



Generalización con diagrama de flujo



Código Fuente de la Solución:

/**
 * Programa que transforma una cantidad de años en otras unidades de tiempo.
 * 
 * Autor: Manuel Vidal J.
 * @Versión 24.03.2011
 */
import java.math.*;
import java.util.*;
public class Tiempo
{
static void main()
{
int meses, semanas, días, Hrs, min, s, n;    // variables
// Entrada de datos
Scanner read= new Scanner(System.in);
System.out.println ("Ingrese cantidad de años a transformar (únicamente números enteros positivos o negativos)");
n= read.nextInt();
// proceso de transformación
if(n>=0){
    meses= n*12;
    semanas= n*52;
    días= n*365;
    Hrs= n*8766;
    min= n*525960;
    s= n*31557600;
    // salida de datos
    System.out.println("meses:        "+meses);
    System.out.println("días:         "+días);
    System.out.println("horas:        "+Hrs);
    System.out.println("minutos:      "+min);
    System.out.println("segundos:     "+s);
    }
else
     System.out.println("datos ingresados no son validos");   
}
}



Reflexión
Con esta actividad fue uno de mis primeros acercamientos a la programación en el lenguaje java y a la programación en general gracias a actividades aprendí el razonamiento que se debe llevar a cabo para programar y algunos métodos para analizar los problemas y ser capaz de llegar a la solución.

Los invito a comentar sus inquietudes o experiencias similares en sus inicios en la programación.