Diseño y Programación Orientados a Objetos
1er. Sem 2017
Tarea 3: Ascensor como Objeto de Software en C++

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 C++ (se sugiere trabajar con Eclipse )
* Reconocer clases y relaciones entre ellas en lenguaje C++.
* Ejercitar la entrada y salida de datos en C++.
* Ejjercitar 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 parcialmente un ascensor de un edificio como un objeto de software similar a la Tarea 1. En esta tarea su grupo trabajará en C++ y no modelaremos la botonera de la cabina. En esta tarea su grupo puede portar código Java a C++ o crear su propia solución en C++. Los ascensores normalmente tienen: botonera en cada piso para solicitar ascensor, botonera dentro del ascensor (cabina) para indicar destino, la cabina misma con su motor, sensores de llegada de la cabina a cada piso, y una unidad de control con la lógica requerida para accionar la detención, subida y bajada de la cabina, además de apagar las luces de solicitud en botoneras, ver figura 1.

  

Figura 1: Modelo simplificado de un ascesor de cuatro pisos
El modelo de la Figura 1 ayuda a identificar los elementos que constituyen el sistema y los correspondientes candidatos a objetos de software.
La Unidad de Control es el "cerebro" del ascensor. Allí reside toda la lógica de su operación. Por ejemplo, ésta se entera cuando la cabina llega a un piso y apaga la luz de la botonera correspondiente. La tarea principal de la Unidad de Control es ordenar detener, subir o bajar a la cabina.
Su programa vinculará objetos de distintas clases de manera de simular el comportamiento del ascensor ante los eventos generados en las botoneras. Un archivo de texto será la entrada del programa y su formato el siguiente:

<tiempo>  <TAB>  <número de piso>  <TAB>   <U | D >  <RET>

Cada línea de este archivo de entrada representa un evento generado por alguna persona. <tiempo> es expresado en segundos y debe ser siempre ascendente. El <número de botonera> va de 1..<número de pisos del edificio>. El valor 1 corresponde al piso 1 del edificio. U y D representan solicitud de subida (Up) o bajada (Down). Si por alguna razón su archivo estuviera mal formado, el programa enviará el mensaje "Input file format error" y terminará.
Como salida, su programa enviará a pantalla una línea con la ubicación de la cabina, estado de los sensores de piso, y el estado de las botoneras de piso, cada vez que la cabina llegue a un piso y cuando se active o desactive un botón de piso. La líne a de salida tiene el siguiente formato:

<tiempo>, <altura de cabina en metros>, <estado sensores de piso>,  <estado activado o no de botones parra subir de piso>, <estado activado o no de botones para bajar de piso>  <RET>

<tiempo> se expresa en milisegundos. El estado de sensores de piso se representa por una secuencia de 1 y 0 indicando el estado de los sensores desde el primer al último piso. De forma análoga se muestra el estado de los botones en cada piso. El primer y último piso son casos especiales, el estado de bajada en primer piso se mostrará como - . Lo mismo para el estado de subida del último piso.
 All ejecutar el programa, use una redirección de la salida a un archivo de texto con extensión .csv. Luego usted podrá importar su contenido en una planilla y generar un gráfico de los movimientos del ascensor en el tiempo. El formato .csv viene de "comma-separated values"; sin embargo, otros separadores son posibles. Planillas de cálculo como excel y otras pueden importar datos desde este formato.

Desarrollo en Etapas

Para llegar al resultado final de esta tarea usted aplicará la metodología "Iterativa e Incremental" para el desarrollo de software. Su grupo irá desarrollando etapas que irán abordando los requerimientos gradualmente. En cada etapa usted obtendrá una solución que funciona para un subconjunto de los requerimientos finales. 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

Esta etapa sólo se implementa clases para representar la botonera de cada piso. El programa leerá los eventos del archivo de entrada y apagará el botón previamente encendido cuando uno nuevo sea presionado. La salida en este caso omite la ubicacion de la cabina y el estado de los sensores de piso. Considere el siguiente código como base para el test de prueba para esta etapa: stage1Test.cpp

Segunda Etapa

En esta segunda etapa se implementará el motor, la cabina y los sensores de piso. Cada sensor se ubica en una posición específica de la caja del ascensor y la cabina circula por su interior. Su grupo debe ejecutar el programa de prueba stage2Test.cpp (revise la versión similar en Java) que hará subir la cabina desde el primer piso al último y luego bajar. La salida del programa debe mostrar la ubicación de la cabina y los cambios de estado de cada uno de los sensores de piso. En esta etapa no hay interacción con las botoneras de piso.

Tercera Etapa

Como tercer paso su grupo debe incorporar la Unidad de Control. En esta etapa, al activar un potón de piso, éste debe invocar un método de la Unidad de Control para cambiar el estado de la cabina si ésta está detenida. Una vez que la cabina llega a un piso, apaga la luz del llamado y sigue su viaje si hay más llamados (no se simularemos la detención). Su comportamiento equivale a un ascensor llamado desde distintos pisos sin que alguien ingrese a la cabina. Para evidenciar el funcionamiento de su programa envía a la salida el estado el ascensor en formato indicado arriba de manera que se puede veridicar la operación del ascensor. Cree el programa de prueba elevatorTest.cpp a partir del pseudocódigo sugerido abajo.

Resultados Esperados de su Grupo

Si bien usted puede usar un IDE (Integrated Development Environment), usted debe saber cómo compilar y correr su tarea desde la línea de comandos.
Su tarea podrá ser ejecutada en aragorn.elo.utfsm.cl usando:
  $ elevatorTest  <nombre archivo de entrada> 
La salida del programa será a pantalla.
El programa corre hasta que procesa el último evento del archivo de entrada.

Usted deberá entregar los siguientes archivos:
- readme
- makefile     /* para compilar */
- Archivo de Documentación: para cada etapa, éste incluye el archivo de entrada usado por usted y la salida obtenida. En las etapas 2 y 3 incluya un gráfico de la ubicación vertical de la cabina versus tiempo. Indique las dificultades encontradas y cómo las resolvió.
- En directorios separados ponga los archivos de cada etapa.
Su programa no generará el gráfico, éste lo debe generar con una planilla de cálculo a partir de los datos de salida de su programa.


Ayudas
* Revise las instrucciones para la realización de tareas.
* Para enviar los datos a un archivo de salida, redireccione la salida a pantalla usando:
$ elevatorTest <nombre de archivo de entrada, sin símbolos mayor y menor>  >  miSalida.csv      //   > significa redireccionar la salida
  Luego trate este archivo como si fuera planilla electrónica. Usted puede usar "comas" como separadores de columnas.

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

Sobre la simulación del main
En cada programa de prueba, se trabajará con la siguiente idea para realizar la simulación del ascensor:
    Crear e inicializar los objetos de la etapa;
    Abrir archivo;
    Leer primera línea del archivo;
    t=0;
   while(no llegue a fin de archivo) {
      t+= delta_t;
      Hacer avanzar el motor; // esto es similar a invocar actionPerformed de la tarea 1, si motor no está subiendo o bajando, nada pasa.
      if (t >=tiempo del evento del archivo)
         Ejecute evento en objeto que corresponda;
         Leer siguiente línea del archivo;
    }
    while (motor no está detenido) {  // aquí terminamos de atender últimos llamados.
       t+=denta_t;
      Hacer avanzar el motor; // esto es similar a invocar actionPerformed de la tarea 1, si motor no está subiendo o bajando, nada pasa.
    }