Diseño y Programación Orientados a Objetos
1er. Sem 2018
Tarea 1: Robot en Laberinto como Objeto de Software

Lea detenidamente la tarea. Si algo no lo entiende, consulte en clases. Si es preciso, se incorporarán aclaraciones al final.
Objetivos de la tarea:
* Ejercitar la configuración de un ambiente de trabajo para desarrollar aplicaciones en lenguaje Java (se sugiere trabajar con Jgrasp o Eclipse )
* Modelar objetos reales como objetos de software.
* Reconocer clases y relaciones entre ellas en códigos fuentes Java.
* Ejercitar la extensión de clases dadas para satisfacer nuevos requerimientos.
* Ejercitar la entrada y salida de datos.
* Conocer el formato .csv y su importación a una planilla electrónica.
* Ejercitar la preparación y entrega de resultados de software (creación de makefiles, readme, documentación, manejo de repositorio -GIT).
* Familiarización con una metodología de desarrollo "iterativa" e "incremental". 

Descripción General

  En esta tarea se pide modelar un robot que ingresa a un laberinto y busca la manera de salir de él por un lugar distinto al de ingreso. El robot a considerar es muy simple porque tendrá capacidad para desplazarse en un plano y contará con sensores para detectar la proximidad de paredes. En cierta manera será como poner en un laberinto un robot aspiradora, como el de la Figura 1.


Figura 1: Robot a modelar de forma sencilla en esta tarea
El robot a modelar tiene capacidad para desplazarse en todas direcciones. Además posee sensores de proximidad para detectar la presencia de obstáculos que en el caso de la tarea serán paredes. Ante una colisión inminente, se espera que el robot tome otra dirección. Las paredes serán modeladas como segmentos de líneas en un plano horizontal. El robot tiene sensores de proximidad para detectar, al menos, paredes por delante o los costados. La orientación y número de sensores puede definirlos usted. Se recomienda considerar uno en la dirección de movimiento y dos laterales. El laberinto a recorrer por el robot, se modela con segmentos de líneas paralelas o perpendiculares entre sí. El laberinto tendrá al menos un punto para ingresar y otro distinto para salir. Una instancia de laberinto se muestra en la Figura 2 (se omiten puntos de entrada y salida).



Figura 2: Laberinto con segmentos paralelos y verticales entre sí.
El laberinto será leído desde un archivo con formato estándar (PBM). Un laberinto será modelado como un objeto con la estructura de paredes leídas desde el archivo de entrada, un punto de entra y otro de salida. Las coordenadas del laberinto serán medidas en pixeles.
En esta tarea se tendrá una instancia de robot circulando en el laberinto por vez. Cada robot ingresará por la apertura de entrada del laberinto y lo recorrerá con la intención de llegar a una salida. El modelo del robot reconoce al menos tres elementos de éste: sistema motriz, sensores de proximidad, y navegante. El sistema motriz responde a órdenes de movimiento dadas por el navegante y actualiza su posición. El robot seguirá sólo movimientos según la velocidad que el navegador le defina. Sólo nos interesa modelar la cinemática del robot, no se preocupe por su dinámica. Los sensores detectan la cercanía de paredes. El navegante actúa sobre el sistema motriz según la información de los sensores y basado en alguna estrategia que le permita llegar a una salida. El robot tiene un interruptor que permite ponerlo en marcha y detenerlo.
Para modelar la situación se sugiere considerar un objeto "mundo", en él se incluye el laberinto y el robot. El mundo pondrá en marcha el robot, hará avanzar el tiempo, y lo detendrá cuando el robot haya llegado a una salida. El mundo también ayudará a informar al sensor si hay o no alguna pared dentro de su rango de sensado.
Para visualizar la trayectoria seguida por el robot, cada robot registrará su posición en el objeto bitácora el cual tiene una estructura similar a la del laberinto. Al término del programa, la bitácora generará un archivo de salida de formato estándar (PBM) y similar al archivo de entrada. Usando algún programa visualizador de imágenes será posible visualizar la trayectoria seguida por el robot.

Desarrollo en Etapas

Para llegar al resultado final de esta tarea, usted aplicará la metodología "Iterativa e Incremental" para el desarrollo de software. Junto a su grupo usted irá desarrollando etapas que irán abordando gradualmente los requerimientos de la tarea. En cada etapa usted obtendrá una solución que funciona para un subconjunto de los requerimientos finales y será un avance hacia el resultado final. Su grupo deberá entregar una solución para cada una de las etapas aún cuando la última integre las primeras. Esto tiene por finalidad, educar en la metodología iterativa e incremental.

Primera Etapa: robot movible

En esta etapa se pide implementar un robot con capacidad de moverse según un patrón definido por el programa e irá registrando su posición mientras se mueve. La posición del robot será mostrada en la salida estándar (pantalla) siguiendo el siguiente formato de texto:
Tiempo, <TAB> x, <TAB> y,
0.1, <TAB> 10, <TAB> 10,
0.2 <TAB> 15, <TAB> 20,
:
Los <TAB> corresponde al caracter tabulador y los números son sólo ejemplos. A la clase principal de esta etapa llámela Stage1.
Para esta etapa se pide que el robot avance y haga algunos cambios de dirección de 90° cada vez hasta detenerse. Como ayuda inicial para esta etapa considere, si lo desea, este código o este otro (use el que le parezca más natural).
El programa será ejecutado siguiendo formato:
$ java Stage1
Una vez concluida esta etapa, usted deberá guardar la salida del programa en un archivo de texto con extensión .csv. Este formato es conocido como "comma-separated values", el cual permite a planillas de cálculo como excel y otras importar sus datos. Usted notará que otros separadores de campos son posibles. Una vez creada su planilla, haga un gráfico (x,y) a partir de los datos de su tabla. Así usted podrá visualizar más fácilmente si el robot hizo el recorrido esperado. Notar que el trabajo con la planilla excel es externo y posterior la ejecución de su programa Java. Se debe generar un gráfico como en Figura 3. Para esta etapa usted debe entregar sus clases y el archivo con la planilla excel que contiene su gráfico.
Para escribir en un archivo el texto de la salida estándar usar:
$ java Stage1 > salida_stage1.csv
El símbolo > permite redirigir hacia un archivo lo que usted antes veía en la pantalla.

Figura 3: Ejemplo de gráfico a generar en una planilla de cálculo

Segunda Etapa: Lectura y escritura de laberinto

En esta etapa su programa recibe argumentos con la siguiente información: <nombre_archivo_laberinto_entrada> <nombre_archivo_laberinto_salida>. Su programa leerá el archivo de entrada con el laberinto y lo almacenará en una instancia de la clase Maze, luego lo rotará en +90° y generará un archivo de salida con el laberinto rotado. La idea es que usted se familiarice con la lectura del laberinto y luego con lo que será la escritura de la trayectoria seguida por el robot. Como ayuda puede revisar este código. Esta etapa se ejecutará así:
$ java Stage2 maze_in.pbm maze_out.pbm
Stage2 leerá el archivo maze_in.pbm (éste es sólo un ejemplo), lo rotará en +90° y escribirá su resultado en el archivo maze_out.pbm. El formato a usar en PBM, éste permite almacenar imágenes en formato ASCII (texto). Se recomienda abrir el archivo maze_in.pbm con algún visualizador de imágenes y luego con un editor de texto. Usted podrá comprobar la estructura de este formato de imagen. Si no cuenta con un visualizador de archivos .pbm, puede usar este programa para convertir de pbm a jpg, png o gif. Se usa como: java convertPBM <ORIGEN.pbm> <DESTINO.png>

Tercera Etapa: Robot con sensores de proximidad

Su grupo debe incluir la clase DistanceSensor. Un objeto sensor mide la distancia a alguna pared en una dirección definida. El sensor tiene un alcance finito. El sensor no tiene movimiento propio, se mueve empotrado al robot con orientación hacia adelante, o alguno de sus costados según como se haya instalado en el robot.
Incluya tres sensores de alcance 3 [m] en el robot. Prepare el programa de prueba Stage3.java el cual lee una  configuración de paredes, lo incorpora al "mundo" y pone en marcha un robot ingresando por el centro de la cavidad. Supondremos que un pixel es 1 [m] (podríamos haber supuesto 1 [cm], no es relevante).  Luego de cada cambio de posición, el robot toma la lectura de los sensores y decide si seguir o cambiar la dirección del robot.
Su programa deberá duplicar la cavidad y en la copia el robot irá registrando su recorrido. Después de un tiempo fijo el programa concluye la simulación y genera un archivo de salida para mostrar el recorrido seguido por el robot.
La ejecución del programa será:
$ java Stage3 simple_maze.pbm robot_route.pbm
Entregar las clases de las etapas previas más la clase DistanceSensor y otros archivos necesarios para correr su programa. Como ayuda, usted puede revisar estas clases,  la clase Vector2D debe agregarse y completarse. También puede ver esta otra ayuda, elija la más natural para usted.

Cuarta Etapa:  Robot con  sensores y navegante

A la etapa tres, se agrega ahora la clase Pilot. Ésta es una clase con referencias a los tres sensores y un método para fijar el curso del robot. La lógica a implementar será recorrer el laberinto apegado a la pared derecha del robot.
En su archivo laberinto incorpore una primera línea de comentario con 7 números. Los dos primeros representan la posición de entrada al laberinto, los dos segundos representan la dirección (el vector) de entrada al laberinto, y los tres siguientes la posición y el radio de la base de la salida del laberinto (un ejemplo de laberinto es éste). La ejecución del programa será:
$ java Stage4 maze.pbm  robot_route.pbm  [ix iy  dx  dy  fx  fy  r]
Al igual que en etapa 3, registre la trayectoria del robot en una copia del laberinto (robot_route.pbm). Los argumentos entre paréntesis son opcionales. Si son ingresados, éstos tienen precedencia para la posición y dirección inicial del robot y la definición de la zona de término del laberinto.
Entregar las clases de las etapas previas más la clase Pilot y otros archivos necesarios para correr su programa. Como ayuda, usted puede revisar estas clases.

Quinta Etapa: 2 Corridas con 2 estrategias de navegación (tomar siempre derecha, más otra a definir por grupo)

En esta etapa usted debe crear la clase MyPilot la cual hereda de Pilot y redefine los métodos necesarios para incorporar otra estrategia de navegación. Su programa principal en Stage5 deberá generar dos corridas para el mismo laberinto. La primera será con un piloto o navegante que siempre se apegue a la derecha, la segunda será otro robot que recorrerá el mismo laberinto pero con la estrategia que su grupo definirá en la clase MyPilot. Como salida se generará dos archivos, de igual nombre pero agregando _1 y el otro _2 para diferenciar ambas estrategias.
La ejecución del programa será como en etapa 4:
$ java Stage4 maze.pbm  robot_route.pbm  [ix iy  dx  dy  fx  fy  r]
Notar que en este caso se generarán dos archivos de salida; para este caso serían: robot_route_1.pbm y robot_route_2.pbm. En Stage5.java registre el tiempo en salir para la estrategia "apegado a la derecha", el programa termina cuando su segunda estrategia permite la salida del laberinto o el robot lo ha intentado por el doble del tiempo de la primera.
Entregar las clases de las etapas previas más la clase MyPilot y otros archivos necesarios para correr su programa. Para esta etapa debe agregar además la documentación de la tarea la cual debe describir sólo esta etapa.

Extra créditos: 3 Corridas agregando estrategia de navegación aleatoria.

Su grupo puede aspirar a ganar hasta 5 puntos adicionales (la nota final igual se satura en 100%) si cambia su programa StageE.java para que tres robot avancen de manera simultánea hacia la salida usando las dos estrategias previas más una aleatoria o semi aleatoria. El programa para cuando  los tres salen o la pasado el doble del tiempo desde que el primero salió. Genere  tres archivos de salida con el laberinto y la trayectoria seguida similar a la etapa 5.

Aspectos generales:

* Los grupos sólo deben ser constituidos por alumnos de un mismo paralelo.
* Si su grupo no lograra concluir todas las etapas, envíe hasta donde hayan llegado, documentando la etapa de mayor nivel lograda.
* Revise las instrucciones para la realización de tareas.
* Dé una mirada a los códigos de avance proporcionados. Usted no está obligado a usarlos. Puede idear su propia solución y mostrar el mismo resultado de salida pedido en la tarea. Si encuentra errores o algo mejorable, avise al profesor.
* Para enviar los datos a un archivo de salida, redireccione la salida a pantalla usando:
$ java StageX  <parámetros>  >  miSalida.csv
  Luego trate este archivo como si fuera planilla electrónica. Usted podrá usar "tabs" y "comas" como separadores de columnas.

* No dude en consultar al profesor o ayudantes sobre dudas de esta tarea.