lunes, 26 de septiembre de 2016

Simulación de Ascensor

Simulación de Ascensores

Autor: Yanina Baeza Astroza

Competencia: Desarrollo de Software (Nivel 1)

Ramo: Programación II

Descripcion de la Actividad:


        En este laboratorio, usted deberá programar un script en Python + Pygame que simule el
movimiento de 10 ascensores en un edificio de 20 pisos. Los ascensores de color Rojo sólo se mueven por los pisos impares, mientras que los de color Amarillo por los pisos pares. El control de los movimientos de los ascensores lo maneja otro script que se conecta mediante coneccion serial a 2.400-8N1 utilizando el simulador serial Virtual Serial Port Emulator por un Connector en Port COM2 con emulación de baudios.
        El script serial envía al script de simulación un paquete (trama) que contiene la siguiente estructura:



donde #1, #2, #3, etc., corresponde al número del ascensor y #P corresponde al piso destino. 
        Los ascensores no pueden moverse a mismo piso donde se encuentran. Cuando todos los ascensores han llegado a sus respectivos pisos, entonces el scrip simulador envía un 'OK' al script serial para que envíe el siguiente paquete de datos.



Solución:


        Para completar esta actividad fue necesario crear 2 script en Python uno que envie datos y el otro que los reciba.

Crea datos y envia:

import serial
import random as ra


s = serial.Serial('COM2')

OK = True
nAsc = 10

while 1:
    cmd = ''
    while OK:
        sDato = ''; nI = 0; nP = 1;
        for a in range(nAsc/2):

            nPImp = ra.randint(0,19)
            while nPImp%2 == 0:
                nPImp = ra.randint(0,19)

            nPPar = ra.randint(1,20)
            while nPPar%2 != 0:
                nPPar = ra.randint(1,20)

            sDato += str(nI) + ','
            sDato += str(nPImp) + ','
            nI += 2
            sDato += str(nP) + ','
            sDato += str(nPPar) + ','
            nP += 2


        sDato = sDato[:-1]
        sDato += '\n'
        print sDato
        s.write(sDato)
        OK = False

    cmd = s.read(2)
    if cmd == 'OK':
        OK = True
        print cmd

s.close()


Recibe y muestra resultados:

import pygame as py
from pygame.locals import *
import serial
import random as ra
import time as ti
import ctypes as ct
#---Constantes-----------------------------------------------------------------
nAsc = 10   # Numero de Ascensores / Minimo 2 Maximo 10
nPiso = 20 # Numero Pisos / Maximo 20
aP = []; aA = []; OK = True; nPAUSA = 5
nAlP = 34; nAnP = 21
nA = [e for e in range (nAsc)]
nP = [0 for e in range (nAsc)]
#---Estructura Ascensor--------------------------------------------------------
class eAsc(ct.Structure):
    _fields_ = [('nX', ct.c_short),  # Pos X de Ascensor
                ('nY', ct.c_short),  # Pos Y del Piso
                ('nD', ct.c_short),  # Nivel de Destino.-
                ('nI', ct.c_short),  # Direc: -1: Sube, +1: Baja, +0: Stop
                ('nT', ct.c_short),  # Time de espera.-
                ('OK', ct.c_bool)    #Verifica si llego a su Destino
               ]
#---Funciones------------------------------------------------------------------
def Coordenadas():
    y = 715; x = 45
    for i in range (nPiso):
        aP.append(y)
        y -= int(nAlP)
    for i in range (nAsc):
        aA.append(x)
        x += int(nAnP)
def Load_Img(foto,transp = False):
    try: image = py.image.load(foto)
    except py.error,message:
           raise SystemExit,message
    image = image.convert()
    if transp:
       color = image.get_at((0,0))
       image.set_colorkey(color,RLEACCEL)
    return image
def Fig_Init():
    aImg = []
    aImg.append(Load_Img('building.png'))
    aImg.append(Load_Img('asc rojo.png',True ))
    aImg.append(Load_Img('asc ama.png',True ))
    return aImg
def Asc_Init():
    for i in range(nAsc):
        aAscs[i].nX = aA[i]
        aAscs[i].nY = aP[0]
        aAscs[i].nD = 1
        aAscs[i].nI = -1
        aAscs[i].nT = nPAUSA
        aAscs[i].OK = False
    return
def Coloca_Asc():
    r = 0
    a = 1
    for i in range(nAsc/2):
        wind.blit(Fig[1] , (aAscs[r].nX, aAscs[r].nY))
        wind.blit(Fig[2] , (aAscs[a].nX ,aAscs[a].nY))
        r += 2
        a += 2
    return
def PisoAct(nSelAsc):
    for i in range(nPiso):
        if aAscs[nSelAsc].nY == aP[i]:
            return i
def Mueve_Asc(nA, nP):
    for e in range(nAsc):
        if aAscs[nA[e]].nD == PisoAct(nA[e]):
            aAscs[nA[e]].OK = True
            #ti.sleep(1)
            nNewDest = nP[e]
            if aAscs[nA[e]].nD > nNewDest:
                aAscs[nA[e]].nI = +1 # Ascensor Baja.-
            if aAscs[nA[e]].nD < nNewDest:
                aAscs[nA[e]].nI = -1 # Ascensor Sube.-
            if aAscs[nA[e]].nD == nNewDest:
                aAscs[nA[e]].nI = 0 # Ascensor Detenido.-
            aAscs[nA[e]].nD = nNewDest # Asignamos nuevo Nivel.-
        else:
            aAscs[nA[e]].OK = False
            aAscs[nA[e]].nT -= 1
            aAscs[nA[e]].nY += aAscs[nA[e]].nI
            aAscs[nA[e]].nT = nPAUSA
            if aAscs[nA[e]].nY < aP[19]:
                aAscs[nA[e]].nI = +1
            if aAscs[nA[e]].nY > aP[0]:
                aAscs[nA[e]].nI = -1
    return
def Get_Datos(sD):
    a = 0; p = 1
    #sD = s.readline()
    sD = sD[:-1]
    aD = sD.split(',')
    print "aD " , aD
    for e in range(nAsc):
        nA[e] = int(aD[a])
        nP[e] = int(aD[p])
        a += 2
        p += 2
    print "nAscensores " , nA
    print "nPisos      " , nP
    return nA, nP
def Make_Datos():
    sDato = ''; nI = 0; nP = 1;
    for a in range(nAsc/2):
        nPImp = ra.randint(0,19)
        while nPImp%2 == 0:
            nPImp = ra.randint(0,19)
        nPPar = ra.randint(1,20)
        while nPPar%2 != 0:
            nPPar = ra.randint(1,20)
        sDato += str(nI) + ','
        sDato += str(nPImp) + ','
        nI += 2
        sDato += str(nP) + ','
        sDato += str(nPPar) + ','
        nP += 2
    sDato = sDato[:-1]
    sDato += '\n'
    print "sDAto ", sDato
    return sDato
def Comprobar():
    nOk = 0
    for i in range(nAsc):
        if aAscs[i].OK:
            nOk += 1
    if nOk == nAsc:
        print "OK"
        s.write("OK")
        return True
#---Main-----------------------------------------------------------------------
s = serial.Serial('COM2')
py.init()
Coordenadas()
wind = py.display.set_mode((430,759))
py.display.set_caption("Laboratorio #4")
aAscs = [eAsc() for i in range(nAsc)]
Fig = Fig_Init()
Asc_Init()
while OK:
    cKey = py.key.get_pressed()
    if cKey[py.K_ESCAPE]:
        OK = False
    ev = py.event.get()
    for e in ev:
        if e.type == QUIT:
            OK = False
    wind.blit(Fig[0],(0,0)) #coloca fondo
    Coloca_Asc()
  #  sD = s.readline()
    sD = Make_Datos()
    a,p = Get_Datos(sD)
    Mueve_Asc(a,p)
    Comprobar()
    py.display.flip()
py.quit()
s.close()


Conclusión:

        Esta actividad no pude completarla satisactoriamente, hubo un error en la lectura de los datos enviado pero no pude saber en donde se encontraba. Aún asi, aprendi mucho del uso de la libreria Pygame y comunicación serial, habilidades que me serviran en el futuro para poder completar otras actividades de la mejor forma posible