Next: El almacén de las Up: Examen de Programación Concurrente Previous: Examen de Programación Concurrente

Subsecciones

- Interfaz con los dispositivos externos
- Aclaración: el algoritmo del ascensor
- Resultados a entregar
- Solución propuesta -- Parte 1
- Solución propuesta -- Parte 2

# Controlador de un ascensor

Tenemos un ascensor que atiende P pisos, numerados del 1 al P; se supone la existencia de un tipo . En cada piso hay un único botón de llamada al ascensor, y en la cabina del ascensor hay un botón para cada piso. En cada piso, a media altura respecto de la puerta del ascensor, hay un sensor que detecta la llegada de la cabina; el sensor no conoce en qué dirección va el ascensor, y tampoco da ninguna señal que nos indique que el ascensor abandona el piso: se limita a recoger cambios de estado de no haber ascensor a haber ascensor (ver la figura ).

Figura: Esquema del ascensor

Se trata de diseñar un controlador del ascensor que atienda a las llamadas desde los pisos o la cabina, haciendo que el ascensor suba o baje en función de las mismas, y ocupándose también de que el ascensor se detenga en los pisos en que se haya solicitado parada y se abran y cierren las puertas. Los dispositivos físicos que el controlador debe manejar son las puertas y el motor que mueve el ascensor.

El controlador recibirá la información de los sensores para determinar la posición del ascensor y deberá ocuparse de la parada del mismo cuando corresponda, siempre en función de las llamadas pendientes. Si el ascensor debe detenerse en un piso se debe ordenar la parada en el momento en que se detecte el paso por el sensor correspondiente a ese piso.

Las puertas deben abrirse automáticamente al llegar a un piso en que realice una parada. Las puertas se cierran automáticamente cuando se pulsa un botón de petición de piso desde el panel del ascensor, o, si no se pulsa ningún botón dentro del ascensor, cuando hayan transcurrido T segundos desde la apertura de las puertas. De haber alguna petición pendiente, el ascensor debe ponerse en marcha inmediatamente después del cierre de las puertas. Una llamada desde un piso cuando el ascensor está detenido con las puertas abiertas no debe cerrarlas, pero debe quedar registrada. El ascensor no debe estar en movimiento a menos que haya alguna petición pendiente.

## Interfaz con los dispositivos externos

Se dispone de los siguientes procedimientos ya implementados para actuar sobre los distintos dispositivos involucrados:

#### Control del motor:

`MOTOR.Subir()`
  Pone en marcha el motor causando la subida del ascensor. El ascensor debe encontrarse detenido cuando se llama a esta operación.

`MOTOR.Bajar()`
  Ídem para bajar.

`MOTOR.Parar()`
  Para el motor, deteniendo el movimiento de la cabina. El ascensor se para automáticamente en el piso inmediatamente próximo según la dirección que llevase en el momento de la llamada. Es decir, si un sensor de un piso N detecta el paso del ascensor (ya sea subiendo o bajando) y en ese momento se llama a `MOTOR.Parar`, el ascensor tiene capacidad para detenerse en el piso N, y lo hará.

El controlador debe asegurarse de que en ningún momento se llama a dos o más de estas operaciones simultáneamente, pues su implementación no garantiza la exclusión mutua. Cada una de ellas retorna cuando el ascensor se ha puesto en marcha o se ha detenido.

#### Control de las puertas:

`PUERTA.Abrir()`
  Abre las puertas del ascensor. Retorna cuando las puertas están completamente abiertas. La cabina debe estar detenida y las puertas completamente cerradas en el momento de llamar a esta operación.
`PUERTA.Cerrar()`
  Cierra las puertas del ascensor. Retorna cuando las puertas están completamente cerradas. La cabina debe estar detenida y las puertas completamente abiertas en el momento de llamar a esta operación.

De nuevo se requiere garantizar que no habrá dos operaciones simultáneamente activas; la exclusión mutua no está dada por las operaciones en sí. El tiempo necesario para abrir o cerrar las puertas está acotado, y es relativamente corto, pero no podemos hacer suposiciones acerca de su duración con respecto a la de otros sucesos de este problema.

#### Lectura de peticiones de pisos:

`BOTON.LeerCabina(VAR numPlanta: TipoNumPlanta)`
  La llamada se bloquea y retorna cuando desde el interior de la cabina se pulsa el botón correspondiente a un piso, devolviendo éste en el parámetro de salida del procedimiento. Supondremos que no se pulsan varios botones simultáneamente.
`BOTON.LeerPlanta(numPlanta: TipoNumPlanta)`
  La llamada retorna cuando se pulsa el botón de llamada de la planta `numPlanta`. El parámetro `numPlanta` es entrada, no de salida.

No se puede suponer ningún límite de tiempo para el retorno de ninguna de estas llamadas. En particular no se puede suponer que en algún momento alguien hará una petición para un piso dado.

#### Detección de paso del ascensor por los sensores:

`SENSOR.DetectarPaso(VAR numPlanta: TipoNumPlanta)`
  La llamada se queda bloqueada y retorna cuando el sensor detecta la llegada del ascensor a una planta, y devuelve el número de planta por la que está pasando.

#### Control del tiempo:

`TIEMPO.ahora(): CARDINAL`
  Devuelve la hora actual en segundos contados desde un momento en el pasado.
`TIEMPO.espera(lapso: CARDINAL)`
  Se bloquea durante el tiempo, expresado en segundos, determinado por su argumento.

De cara a la especificación, las llamadas a operaciones que actúan sobre un dispositivo externo pueden ponerse como POST(Subir), si ello es necesario. Las operaciones que devuelven un resultado se supondrán especificadas como acciones.

## Aclaración: el algoritmo del ascensor

Aunque no es estrictamente necesario, se sugiere utilizar el llamado algoritmo del ascensor, aplicado frecuentemente en el acceso a discos. La idea de este algoritmo es que el ascensor sube y baja alternativamente. Mientras va en una dirección se efectúan las paradas necesarias en esa dirección. Cuando no quedan más peticiones en la dirección actual, se invierte el sentido de la marcha. Si no hay ninguna petición pendiente, el ascensor se detiene.

## Resultados a entregar

1. Este apartado es exactamente igual al ya dejado para su realización. Sobre el problema anteriormente descrito, se pide:
   - Análisis del problema, identificando y justificando qué procesos y recursos (pueden ser uno o más de uno) se han de utilizar. No es necesario considerar ni especificar las operaciones correspondientes al `MOTOR`, `PUERTA`, `SENSOR`, `BOTON` o `TIEMPO`. Se suponen dadas, y son operaciones externas.
   - Grafo de procesos y recursos, aclarando:
     - qué operaciones y variables de estado tiene cada uno de los recursos diseñados,
     - qué operaciones de cada recurso necesita cada uno de los procesos identificados,
     - qué operaciones externas usa cada uno de los procesos y de los recursos.
   - Código de cada uno de los procesos anteriormente identificados.
   - Especificación formal de los recursos, donde se modele claramente la sincronización entre las operaciones, añadiendo una explicación de esa sincronización en lenguaje natural. La selección del piso a atender debe garantizar la ausencia de inanición. No es necesario hacer las tablas de bloqueos ni de desbloqueos.

2. Este apartado es nuevo. Corregir el diseño anterior, adaptándolo a la siguiente situación:

   En lugar de un solo ascensor, se controlarán conjuntamente `N` ascensores. Para ello se modifica el interfaz con los módulos `MOTOR`, `PUERTA`, `BOTON` y `SENSOR` de manera que tengan un parámetro que indique el ascensor al que se refieren, de tipo `TipoNumAscensor` (`TYPE TipoNumAscensor = [1..N]`):

   `MOTOR.Subir/Bajar/Parar(k: TipoNumAscensor)`
   `PUERTA.Abrir/Cerrar(k: TipoNumAscensor)`
   `BOTON.LeerCabina(k: TipoNumAscensor; VAR numPlanta: TipoNumPlanta)`
   `SENSOR.DetectarPaso(k: TipoNumAscensor; VAR numPlanta: TipoNumPlanta)`

   El controlador debe asegurar que no se dan dos órdenes simultáneas para el mismo ascensor, pero sí se admiten órdenes simultáneas si van dirigidas a ascensores diferentes.

   Se mantiene un solo botón de llamada en cada piso, pero se simplifica la operación de lectura de esos botones para hacerla similar a la lectura de los botones de una cabina:

   `BOTON.LeerPlanta(VAR numPlanta: TipoNumPlanta)`
     La llamada se bloquea y retorna cuando se haya pulsado algún botón de llamada desde un piso, devolviendo éste en el parámetro de salida del procedimiento. Supondremos que no se pulsan varios botones al mismo tiempo.

   Con estos supuestos, se pide:

   - Rehacer el diseño, indicando los procesos y recursos que se van a utilizar en la nueva situación.
   - Dibujar el nuevo diagrama de procesos y recursos.
   - Especificar los procesos, en seudocódigo.
   - Especificar los recursos, indicando formalmente las variables de estado necesarias y los parámetros de cada operación. Las precondiciones y postcondiciones de las operaciones se indicarán de manera informal (en lenguaje natural).

## Solución propuesta -- Parte 1

Para determinar qué procesos se necesitan, se puede analizar qué operaciones no instantáneas puede que tengan que realizarse al mismo tiempo. Esto ocurre con las siguientes:

- Lectura de pulsaciones de los botones de la cabina (de uno en uno).

- Lectura de pulsaciones de los botones de las plantas (todos a la vez).

- Alguna de las siguientes: arrancar o parar el motor, abrir o cerrar las puertas, esperar a que se llegue al siguiente piso (sólo una de ellas al tiempo).

- Dependiendo de cómo se realice la temporización de la apertura de puertas, puede ser necesaria otra operación simultánea más, que es mantener la temporización hasta el tiempo límite aunque ya se estén cerrando las puertas porque se ha pulsado un botón de la cabina.

La comunicación y sincronización entre los procesos puede hacerse mediante un recurso compartido que gestione las peticiones pendientes y el estado del ascensor en un momento dado. Este recurso contendrá información sobre:

- Peticiones realizadas para los diferentes pisos.
- Sentido de movimiento actual.
- Posición actual del ascensor.
- Indicación de si se pueden cerrar ya las puertas.

Esta última información podría plantearse también como correspondiente a un recurso separado que gestione solamente la temporización de la apertura y cierre de las puertas.

También es posible realizar la temporización directamente en el proceso que ordena el movimiento del ascensor, si el tiempo se va contando por periodos pequeños, y no con una espera única hasta el tiempo límite.

A continuación se describe la solución que usa un proceso separado para temporizar, y un recurso único que gestiona las peticiones y el permiso para cerrar las puertas. El diagrama de procesos y recursos se muestra en la figura

Figura: Diagrama de procesos y recursos -- primer supuesto

### Código de las tareas

### Especificación del recurso

    C-TADSOL TipoGestor

    C-Operaciones

    ACCION  PulsadoCabina: TipoGestor  TipoNumPlanta[ent]

    ACCION  PulsadoPlanta: TipoGestor  TipoNumPlanta[ent]

    ACCION  HayPeticion: TipoGestor  TipoNumPlanta[ent]  [sal]

    ACCION  ParadoEnPlanta: TipoGestor  TipoNumPlanta[ent]

    ACCION  IniciarEspera: TipoGestor [sal]

    ACCION  TerminarEspera: TipoGestor

    ACCION  ElegirMovimiento: TipoGestor  TipoMovimiento[sal]

    TRANSACCIONES

    PulsadoCabina

    PulsadoPlanta

    HayPeticion

    ParadoEnPlanta

    IniciarEspera

    TerminarEspera

    ElegirMovimiento

    CONCURRENCIA

    ninguna

    Dominio

    Tipo: TipoGestor = (peticion: Secuencia()     sentido: TipoMovimiento     posicion: TipoNumPlanta

    pulsadaCabina:      tiempoActual:     tiempoLimite: )

    TipoNumPlanta = 1..P

    TipoMovimiento = (SUBIR  BAJAR)

    		Invariante:

    CPRE: cierto

    PulsadoCabina(g, p)

    POST: Anota la petici'on y marca pulsaci'on desde cabina

    POST:

    CPRE: cierto

    PulsadoPlanta(g, p)

    POST: Anota la petici'on

    POST:

    CPRE: cierto

    HayPeticion(g, p, hay)

    POST: Indica si hay petici'on para esa planta

    POST:

    CPRE: cierto

    ParadoEnPlanta(g, p)

    POST: Anota que se ha atendido la petici'on de esa planta, y    comienza el plazo de apertura de puertas

    POST:

    CPRE: g.tiempoActual  g.tiempoLimite

    IniciarEspera(g, t)

    POST: Indica el tiempo l'imite hasta el que hay que esperar

    POST: g.tiempoLimite

    CPRE: cierto

    TerminarEspera(g)

    POST: Anota el nuevo tiempo actual

    POST: TIEMPO.Ahora

    CPRE: Hay peticiones para otra planta y se han mantenido laspuertas abiertas el tiempo suficiente

    CPRE:

    ElegirMovimiento(g, mov)

    POST: Indica que hay que subir si hay peticiones superiores y,      o bien est'a subiendo o no hay peticiones inferiores.

    Indica que hay que bajar en caso contrario. Adem'as anota      el nuevo sentido de movimiento y que

    las puertas est'an cerradas. y anula peticiones para el piso      en que estaba.

    POST:

## Solución propuesta -- Parte 2

Se puede mantener en esencia el diseño anterior, con los siguientes cambios.

- La lectura de los botones de las plantas se hará con un solo proceso.
- Habrá un proceso Cabina y un proceso Ascensor por cada ascensor
- Se mantiene un solo proceso Temporizador, que irá marcando en cada momento al final del plazo de espera más corto de los que estén pendientes (también se podría haber repetido el proceso Temporizador por cada ascensor).
- Se mantiene un solo recurso que gestiona el estado de todos los ascensores, cambiando lo siguiente:
  - Las acciones PulsadoCabina, HayPeticion, ParadoEnPlanta y ElegirMovimiento tendrán un parámetro adicional para indicar a qué ascensor se refieren.
  - Se repiten los elementos del dominio para cada uno de los ascensores.
  - Además habrá un vector de peticiones desde los pisos, común a todos los ascensores.
  Estas peticiones tendrán tres estados: inactiva, pedida y asignada. Esto es necesario para evitar que varios ascensores acudan a la misma llamada de un piso. Una petición de piso no asignada se asigna a un ascensor cuando está en su sentido de movimiento y no hay peticiones de su cabina en ese sentido, o bien cuando el ascensor se para en ese piso por el motivo que sea.

El diagrama de procesos y recursos se muestra en la figura .

### Código de las tareas

Figura: Diagrama de procesos y recursos -- segundo supuesto

### Especificación del recurso

    C-TADSOL TipoGestor

    C-Operaciones

    ACCION  PulsadoCabina: TipoGestor  TipoNumAscensor[ent]  TipoNumPlanta[ent]

    ACCION  PulsadoPlanta: TipoGestor  TipoNumPlanta[ent]

    ACCION  HayPeticion: TipoGestor  TipoNumAscensor[ent]  TipoNumPlanta[ent]  [sal]

    ACCION  ParadoEnPlanta: TipoGestor  TipoNumAscensor[ent]  TipoNumPlanta[ent]

    ACCION  IniciarEspera: TipoGestor  [sal]

    ACCION  TerminarEspera: TipoGestor

    ACCION  ElegirMovimiento: TipoGestor TipoNumAscensor[ent]   TipoMovimiento[sal]

    TRANSACCIONES

    PulsadoCabina

    PulsadoPlanta

    HayPeticion

    ParadoEnPlanta

    IniciarEspera

    TerminarEspera

    ElegirMovimiento

    CONCURRENCIA

    ninguna

    DOMINIO

    TIPO: TipoGestor = (petPlanta:  Secuencia(TipoPeticion)                  peticion: Secuencia(Secuencia())

    asignada: Secuencia()                  sentido: Secuencia(TipoMovimiento)

    posicion: Secuencia(TipoNumPlanta)                  pulsadaCabina: Secuencia()

    tiempoActual:                  tiempoLimite: Secuencia())

    TipoNumPlanta = (1..P)

    TipoMovimiento = (SUBIR  BAJAR)

    TipoPeticion = (INACTIVA, PEDIDA, ASIGNADA)

    		 INVARIANTE:

    CPRE: cierto

    PulsadoCabina(g, a, p)

    POST: Anota la petici'on y marca pulsaci'on desde cabina

    CPRE: cierto

    PulsadoPlanta(g, p)

    POST: Anota la petici'on, si no lo estaba todav'ia

    CPRE: cierto

    HayPeticion(g, a, p, hay)

    POST: Indica si hay petici'on desde cabina o planta paraese ascensor y planta. Si hay petici'on PEDIDA

    para esa planta, sele asigna a ese ascensor,deshaciendo la asignaci'on anterior, si la hubiera.

    CPRE: cierto

    ParadoEnPlanta(g, a, p)

    POST: Anota que se ha atendido la petici'on de cabina y/o planta ASIGNADA de esa planta,

    y comienza el plazo de apertura de puertas

    CPRE: Hay alguna temporizaci'on pendiente

    CPRE:

    IniciarEspera(g, t)

    POST: Indica el m'inimo tiempo l'imite hasta el que hayque esperar

    CPRE: cierto

    TerminarEspera(g)

    POST: Anota el nuevo tiempo actual

    CPRE: Hay alguna petici'on para atender por ese ascensor(desde cabina, o bien desde planta, no asignada)

    y se ha cumplido el plazo para mantener las puertas abiertas.

    ElegirMovimiento(g, a, mov)

    POST: Indica que hay que subir si hay peticiones superiores y,      o bien est'a subiendo o no hay peticiones inferiores.

    Indica que hay que bajar en caso contrario.      Adem'as anota el nuevo sentido de movimiento.

    La asignaci'on de petici'on desde una planta a ese      ascensor se hace si no hay  peticiones de cabina

    pero s'i      peticiones de planta en el       sentido      de      su movimiento.

Next: El almacén de las Up: Examen de Programación Concurrente Previous: Examen de Programación Concurrente