Mostrando entradas con la etiqueta Programación. Mostrar todas las entradas
Mostrando entradas con la etiqueta Programación. Mostrar todas las entradas

sábado

Actividad 1 - Proyecto de Robótica

Competencia: Aprendizaje Autónomo (Nivel 1)
Palabras Clave: NXC, Lego, Mindstorm, Programación, Robots.

Descripción

    Al retorno de vacaciones, continuamos con la programación en NXC. Esta vez la asignatura es Proyecto de Robótica y como primera actividad se nos pidió construir una aplicación para el robot NXT que repasara conceptos de la asignatura anterior y además implementar un contenido nuevo, la entrega de parámetros. Además para evaluar nuestro aprendizaje autónomo se nos pidió implementar al menos 2 instrucciones de una lista de 13. 
    La actividad consistía en desarrollar el código NXC para un robot se desplaza por una superficie blanca con puntos negros. La superficie es rectangular y posee paredes en sus bordes. Construya un robot que implemente las siguientes funcionalidades:
  1. Cada vez que el robot choca con una pared debe:
  1. retroceder un poco,
  2. girar 180° a la izquierda o derecha,
  3. disminur su potencia en 10,
  4. contar los choques con las paredes,
  5. y seguir su recorrido con la nueva potencia
  1. Al pasar por un punto negro debe:
  1. contarlo,
  2. girar en un ángulo aleatorio menor a 180° a la izquierda o derecha,
  3. aumentar su potencia en 10,
  4. y seguir su recorrido con la nueva potencia.
  1. El robot se desplaza por tiempo indefinido, deteniendo su recorrido ante una señal auditiva sobre 80 db.
  2. Al final del recorrido, informará en su visor el n° de choques y el n° de puntos negros detectados.
Los giros y cambios de potencia se implementarán con una subtarea exclusiva para ello, con la siguiente estructura:
sub GiroPotencia(int t, string direccion, string evento)
donde,
        t                tiempo de giro
        direccion        dirección de giro, “D” -> Derecha, “I” -> Izquierda
        evento        especifica si es “choque” o “círculo”
    La potencia utilizada por el robot en el avance, nunca debe sobrepasar 100 ni ser menos de 30.

   El listado de instrucciones está compuesto por:
OnFwdReg(),
OnRevReg()
Float(),
Coast()
GraphicOut(), LineOut(), PointOut(), RectOut(), CircleOut()
RotateMotor(), RotateMotorEx()
OnFwdSync(),
OnRevSync()




Modelo de Solución

    La solución propuesta por mi grupo consistió en:


Estrategia de Trabajo

    La Actividad #1 de Proyecto de Robótica se nos presenta como la combinación de todos los contenidos aprendidos durante el Primer semestre en Programación de Robots.
    Considerando Que De Partida Se nos Pide este nivel de complejidad y agregando un nuevo componente (el uso de parámetros), procedemos a separar nuestro código en subtareas y encargar a los miembros del grupo la tarea que mejor manejaban (según aprendieron el semestre anterior). Esto nos tomó muy poco tiempo puesto que reciclamos códigos anteriores, adaptandolo a la actividad actual.
    Ahora, si bien el Programa cumplía el objetivo, necesitaba aun cumplir con lo pedido:
Que Según el Evento que se produjera (Choque ó Punto) Este Generase un Identificador para que sea enviado al método:

“ sub GiroPotencia(int t, string direccion, string evento) “

el cual determinaba que tipo de movimiento debía hacer.
Implementar una subtarea de este tipo le dio la cuota de complejidad al trabajo, ya
que contar eventos y realizar giros no era algo nuevo para nosotros. Pero como bien hemos ido aprendiendo hay ciertas tareas que por repetitivas, conviene optimizarlas con el fin de evitar extensas lineas de código, procesos innecesarios, etc.
    Luego de Haber integrado Las Subtareas Principales del programa, nos quedaba ahora darle los pequeños detalles. Agregamos La restricción de que la potencia de avance debía estar siempre entre 30 y 100, agregamos las 2 instrucciones nuevas sobre las que teníamos que investigar y Acotamos que Todo este proceso se realizara hasta escuchar un ruido donde entonces se detendría y se mostrarían por pantalla los contadores de eventos que habíamos implementado.
     Nuestra Estrategia de Trabajo (usada ya durante todos estos meses), de comenzar de menos a mas, agregando a medida que se avanza las restricciones pedidas, Nos sirvió para no bloquearnos y no saber por donde comenzar con esta actividad que tenía muchas aristas y varios requisitos.
    Para finalizar, agregamos RecOut() a nuestro código, línea de código que permite dibujar un rectángulo en pantalla. 


Pseudocódigo
Mientras No Detecte Ruido Hacer:
{
    avanzar con “potencia” 
    SI Choque con pared:
    {
          contador de choques crece en 1.
          retrocede.
          Llama a GiroPotencia y le entrega sus parámetros Realiza un GiroPotencia
          la potencia se reduce en 10.
    }
    SI detecta un punto negro:
    {
           contador de puntos crece en 1.
           Llama a GiroPotencia y le entrega sus parámetros. Realiza un GiroPotencia.
           la potencia Crece en 10.
     }
    Muestra en Pantalla Los Contadores.
}


GiroPotencia
{
    SI recibe parámetros de Choque:

    {
        asigna una dirección Izquierda o Derecha
        asigna un Giro en 180o en esta dirección 
    }
    SI recibe parámetros de Punto Negro:
    {
         asigna una dirección Izquierda o Derecha 
         asigna un Giro Menor a 180o en esta dirección   

     }
} 



Captura de pantalla 2011-12-17 a la(s) 15.22.17
Captura de pantalla 2011-12-17 a la(s) 15.22.50

Video



    Instrucciones de Aprendizaje Autónomo:
     
        OnRevReg() : La usamos para que el movimiento de reversa sea más regular, puesto que el tercer parámetro que se le entrega a la instrucción estuvo dado por OUT_REGMODE_SYNC, el cual sincroniza el movimiento de los motores.
        RotateMotor(): Aplicamos esta instrucción para realizar un giro de 180 grados sin la necesidad de estar "jugando" con la potencia vs tiempo como fue usada en trabajos anteriores.
        OnFwdReg(): Igual que OnRevReg(), pero en vez de ser usada para el retroceso, es usada para avanzar.
        RectOut(): Nos permitió dibujar un rectángulo en la pantalla del NTX.
        Float(): Es un alias para COAST, instrucción que detiene los motores y se detienen por inercia.


    Reflexión

        Para cumplir con el Aprendizaje Autónomo implementamos 5 instrucciones, si bien se nos pedía una cantidad menor, en nuestro afán de aprender más del lenguaje NXC, decidimos investigar una cantidad mayor. El resto de la actividad fue regular a lo que usualmente preparábamos para Programación de Robots, el trabajo en equipo y desarrollo y armado del robot.
          Estas actividades me resultan absolutamente motivadoras puesto que no son el típico desarrollo de un contenido en teoría, la implementación de la teoría en un concepto práctico como la robótica me generó una motivación mayor.


   

viernes

Actividad de Programación Creativa



Autor:Angel Aedo Busto
Competencia: Creatividad e Innovación (Nivel 1)
Palabras Clave: NXC, Lego,  Mindstorm, Programación, Robot.

Descripción 
    
    Primero que todo, en esta tarea aplicamos los nuevos conocimientos adquiridos, ya que en esta actividad debíamos implementar a nuestro robot un sensor de tacto, para que al momento de hacer contacto con los cubos y paredes, se encendiera; seguido de este acto, el robot tenía que retroceder, dar una vuelta y emitir un sonido con el que indicaría que había destruido el objetivo. Esto se debía repetir 5 veces y al final del trayecto tendría que tocar un  sonido diferente a los anteriores con el que indicaría que se había quedado sin explosivos. Luego comenzamos por desarrollar el pseudocódigo con el que tendríamos una idea de cómo seria nuestro código en NXC.

Modelo de Solución

    Estrategia de Trabajo:


Hugo: Se encargó de Traspasar las ideas del recorrido del robot, al papel, mediante el pseudocódigo el cual debería ser lo más claro y legible, para que la creación del código fuera lo más exacta posible.
Ángel y Felipe: Se Preocuparon de Interpretar el pseudocódigo, para así lograr como resultado final un código que cumpliera con el objetivo planteado, pero que se iría modificando a medida que fuéramos comprobando en terreno nuestro código.

José Luis: su tarea fue la de posicionar correctamente el robot, e ir registrando de forma escrita los errores que surgían durante el transcurso del recorrido y dejar un registro visual.
             Finalmente, cuando conseguimos que el robot cumpliera con el objetivo, procedimos a depurar el código , fue en este momento cuando dimos a conocer lo que pensábamos respecto al código, para que así no se pasara a llevar a nadie del grupo, ni tampoco se descarta alguna idea.

Uno de los problemas que se nos presento fue el calcular el giro aleatorio, que éste sea de más de 90º y menos de 720º como se pedía en la pauta. La solución a esto fue generar un random con un intervalo. Otra de las complicaciones fue la implementación de un ciclo que se ejecutara la cantidad de veces requerias, pues iniciamos una variable en 0 y al definirse que realice ciclos menores a 6, realizaba 6 acciones. Esto se debió a que nuestro ciclo realizaba la acción antes de sumar el contador. Nuestro ataque al problema fue reducir el ciclo a menores a 5, de este modo se realiza una acción completa y el contador sube a uno. (quedando ciclo1, contador = 0; ciclo 2, contador=1, etc).

Pseudocódigo

Contador (de bombas)=0

                  Avanza el robot
                  Si robot impacta
                                    Retroceder 0,5 segundos
                                    Reproducir sonido de detonación
                                    Detenerse (Esperar 2 segundos)
                                    Giro derecha al azar entre 90° y 720°
                                    Detener Robot
                                    Contador +1
                  Vuelve a entrar al proceso mientras el contador sea <5
                                    Reproduce Sonido Final (Sin Munición)
                  APAGADO TOTAL

Código NXC

int TiempoGiro;
int Contador=0;
task main()
  {
   SetSensorTouch(IN_4);   //asignar sensor a puerto 4
     do     {
      OnFwd(OUT_AC,75);   //avanzar
      if(SENSOR_4 == 1)  //si el sensor se activa
        {
         TiempoGiro=Random(2521)+360; //variable de giro 90 a 720
         OnRev (OUT_AC,75);           //reversa
         Wait(500);  
         Off(OUT_AC);
         PlayFileEx("! 
Attention.rso",4,FALSE); //sonido bomba
         Wait(2000);
         OnRev(OUT_A,75);        //asginacion potencia giro
         OnFwd (OUT_C,75);       //asignacion potencia giro
         Wait(TiempoGiro);       //ejecucion random del tiempo de giro
         Off(OUT_AC);
         Contador++;             //al terminar ciclo contador aumenta
         }
}
  while (Contador<5);    //fin del ciclo si contador es 4
        Wait(2000);
        PlayFileEx("! Startup.rso",4,FALSE);  //sonido sin stock bomba
        Wait(4000);
 }
Video de la Actividad




Reflexión

    
 En es trabajo tuvimos que utilizar nuevamente los comando básicos para la creación del código, en el que tuvimos que integrarle uno nuevo para poder usar el sensor de tacto que se escribe como: SetSensorTouch (el que es con el que iniciábamos el sensor), en conjunto con los demás comandos logramos que nuestro robot desarrollará sin mayores inconvenientes su recorrido.



     En sí, el trabajo fue muy didáctico al igual que el anterior lo que hace que la materia sea mucho mas fácil de comprender, además de lograr aprender como optimizar nuestros tiempos y  trabajar como un equipo y así cumplir a tiempo con la elaboración del proyecto.
     Hablando a gran escala creo que logramos con gran éxito las competencias ya que nuevamente nos pudimos organizar con gran éxito, dando como resultado final un trabajo de gran nivel. Y un factor que es importante en cada trabajo que se realiza es tener paciencia, para repetir los procesos mas de una vez y también el código hasta obtener resultados que nos satisfagan.