Commit 071661ca authored by Georgios Dagkakis's avatar Georgios Dagkakis Committed by Sebastien Robin

1st version of conveyer object - not working properly

parent b5814f12
'''
Created on 23 May 2013
@author: George
'''
'''
Models a conveyer object
it gathers entities and transfers them with a certain speed
'''
from SimPy.Simulation import *
import xlwt
import scipy.stats as stat
#The conveyer object
class Conveyer(Process):
def __init__(self, id, name,length,speed):
self.id=id
self.objName=name
self.type="Conveyer"
self.speed=speed #the speed of the conveyer in m/sec
self.length=length #the length of the conveyer in meters
self.previous=[] #list with the previous objects in the flow
self.next=[] #list with the next objects in the flow
self.nextIds=[] #list with the ids of the next objects in the flow. For the exit it is always empty!
self.previousIds=[] #list with the ids of the previous objects in the flow
#lists to hold statistics of multiple runs
self.Waiting=[]
self.Working=[]
self.Blockage=[]
def initialize(self):
Process.__init__(self)
self.Res=Resource(capacity=infinity)
self.Up=True #Boolean that shows if the object is in failure ("Down") or not ("up")
self.currentEntity=None
self.totalBlockageTime=0 #holds the total blockage time
self.totalFailureTime=0 #holds the total failure time
self.totalWaitingTime=0 #holds the total waiting time
self.totalWorkingTime=0 #holds the total working time
self.completedJobs=0 #holds the number of completed jobs
self.timeLastEntityEnded=0 #holds the last time that an entity ended processing in the object
self.nameLastEntityEnded="" #holds the name of the last entity that ended processing in the object
self.timeLastEntityEntered=0 #holds the last time that an entity entered in the object
self.nameLastEntityEntered="" #holds the name of the last entity that entered in the object
self.timeLastFailure=0 #holds the time that the last failure of the object started
self.timeLastFailureEnded=0 #holds the time that the last failure of the object Ended
self.downTimeProcessingCurrentEntity=0 #holds the time that the object was down while processing the current entity
self.downTimeInTryingToReleaseCurrentEntity=0 #holds the time that the object was down while trying
#to release the current entity
self.downTimeInCurrentEntity=0 #holds the total time that the object was down while holding current entity
self.timeLastEntityLeft=0 #holds the last time that an entity left the object
self.processingTimeOfCurrentEntity=0 #holds the total processing time that the current entity required
self.waitToDispose=False #shows if the object waits to dispose an entity
self.position=[] #list that shows the position of the corresponding element in the conveyer
self.timeLastMoveHappened=0 #holds the last time that the move was performed (in reality it is
#continues, in simulation we have to handle it as discrete)
self.justDisposed=False
def run(self):
#these are just for the first Entity
yield waituntil, self, self.canAcceptAndIsRequested #wait until the Queue can accept an entity #and one predecessor requests it
self.getEntity() #get the entity
self.timeLastMoveHappened=now()
while 1:
yield waituntil, self, self.somethingHappened #wait for an important event in order to move the items
#print now()
self.moveEntities()
if self.canAcceptAndIsRequested():
self.getEntity()
if self.waitToDispose:
#yield waituntil, self, self.entityJustDisposed
#self.justDisposed=False
pass
'''
now we have to wait until something happens. The things that are important are (may be not a full list)
one item reaches the end
one item is received
one predecessor requests to dispose
one item is disposed
'''
#checks if the Conveyer can accept an entity
def canAccept(self):
#if there is no object in the predecessor just return false
if len(self.previous[0].Res.activeQ)==0:
return False
interval=now()-self.timeLastMoveHappened
interval=(float(interval))*60.0 #the simulation time that passed since the last move was taken care
requestedLength=self.previous[0].Res.activeQ[0].length #read what length the entity has
if len(self.Res.activeQ)==0:
availableLength=self.length #if the conveyer is empty it is all available
else:
#print "!"*40
#print (self.position[-1]+interval*self.speed)-self.Res.activeQ[-1].length
availableLength=(self.position[-1]+interval*self.speed)-self.Res.activeQ[-1].length #else calculate what length is available at the end of the line
#print now()
#print requestedLength
#print availableLength
if requestedLength<=availableLength:
return True
else:
return False
#moves the entities in the line
def moveEntities(self):
interval=now()-self.timeLastMoveHappened
self.totalWorkingTime+=interval
interval=(float(interval))*60.0 #the simulation time that passed since the last move was taken care
#for the first entity
#print self.position[0]
#print self.position[0]!=self.length
if len(self.position)>0:
if self.position[0]!=self.length:
#if it does not reach the end of conveyer move it according to speed
if self.position[0]+interval*self.speed<self.length:
self.position[0]=self.position[0]+interval*self.speed
#else move it to the end of conveyer
else:
self.position[0]=self.length
#for the other entities
for i in range(1,len(self.Res.activeQ)):
#if it does not reach the preceding entity move it according to speed
if self.position[i]+interval*self.speed<self.position[i-1]-self.Res.activeQ[i].length:
self.position[i]=self.position[i]+interval*self.speed
#else move it right before the preceding entity
else:
self.position[i]=self.position[i-1]-self.Res.activeQ[i].length
self.timeLastMoveHappened=now()
#checks if the Conveyer can accept an entity and there is a Frame waiting for it
def canAcceptAndIsRequested(self):
return self.canAccept() and self.previous[0].haveToDispose()
#gets an entity from the predecessor
def getEntity(self):
self.Res.activeQ.append(self.previous[0].Res.activeQ[0]) #get the entity from the predecessor
self.position.append(self.Res.activeQ[-1].length) #the entity is placed in the start of the conveyer
self.previous[0].removeEntity() #remove the entity from the previous object
self.outputTrace(self.Res.activeQ[-1].name, "got into "+ self.objName)
#removes an entity from the Conveyer
def removeEntity(self):
self.outputTrace(self.Res.activeQ[0].name, "releases "+ self.objName)
self.Res.activeQ.pop(0)
self.position.pop(0)
self.justDisposed=True
self.waitToDispose=False
#checks if the Conveyer can dispose an entity to the following object
def haveToDispose(self):
return len(self.Res.activeQ)>0 and self.position[0]==self.length #the conveyer can dispose an object only when an entity is at the end of it
#sets the routing in and out elements for the Conveyer
def defineRouting(self, p, n):
self.next=n
self.previous=p
#checks if the first Entity just reached the end of the conveyer
def entityJustReachedEnd(self):
interval=now()-self.timeLastMoveHappened
interval=(float(interval))*60.0 #the simulation time that passed since the last move was taken care
if(len(self.position)==0):
return False
if ((self.position[0]+interval*self.speed>=self.length) and (not self.position[0]==self.length)):
self.waitToDispose=True
return True
else:
return False
'''
#checks if the first one place was made available in the conveyer
def onePlaceJustMadeAvailable(self):
interval=now()-self.timeLastMoveHappened
interval=(float(interval))/60.0 #the simulation time that passed since the last move was taken care
if self.position[0]+interval*self.speed>=self.length:
self.waitToDispose=True
return True
else:
return False
'''
def somethingHappened(self):
return self.canAcceptAndIsRequested() or self.entityJustReachedEnd()
#checks if the Conveyer is requested by the predecessor
def isRequested(self):
return self.previous[0].haveToDispose
def entityJustDisposed(self):
return self.justDisposed
#actions to be taken after the simulation ends
def postProcessing(self, MaxSimtime):
'''
#if there is an entity that finished processing in Conveyer but did not get to reach
#the following Object
#till the end of simulation, we have to add this blockage to the percentage of blockage in Assembly
if (len(self.next[0].Res.activeQ)>0) and ((self.nameLastEntityEntered == self.nameLastEntityEnded)):
self.totalBlockageTime+=now()-self.timeLastEntityEnded
#if Assembly is currently processing an entity we should count this working time
if(len(self.Res.activeQ)>0) and (not (self.nameLastEntityEnded==self.nameLastFrameWasFull)):
self.totalWorkingTime+=now()-self.timeLastFrameWasFull
self.totalWaitingTime=MaxSimtime-self.totalWorkingTime-self.totalBlockageTime
'''
self.Waiting.append(100*self.totalWaitingTime/MaxSimtime)
self.Working.append(100*self.totalWorkingTime/MaxSimtime)
self.Blockage.append(100*self.totalBlockageTime/MaxSimtime)
#outputs message to the trace.xls. Format is (Simulation Time | Entity or Frame Name | message)
def outputTrace(self, name, message):
from Globals import G
if(G.trace=="Yes"): #output only if the user has selected to
#handle the 3 columns
G.traceSheet.write(G.traceIndex,0,str(now()))
G.traceSheet.write(G.traceIndex,1,name)
G.traceSheet.write(G.traceIndex,2,message)
G.traceIndex+=1 #increment the row
#if we reach row 65536 we need to create a new sheet (excel limitation)
if(G.traceIndex==65536):
G.traceIndex=0
G.sheetIndex+=1
G.traceSheet=G.traceFile.add_sheet('sheet '+str(G.sheetIndex), cell_overwrite_ok=True)
#outputs data to "output.xls"
def outputResultsXL(self, MaxSimtime):
from Globals import G
if(G.numberOfReplications==1): #if we had just one replication output the results to excel
G.outputSheet.write(G.outputIndex,0, "The percentage of Working of "+self.objName +" is:")
G.outputSheet.write(G.outputIndex,1,100*self.totalWorkingTime/MaxSimtime)
G.outputIndex+=1
G.outputSheet.write(G.outputIndex,0, "The percentage of Blockage of "+self.objName +" is:")
G.outputSheet.write(G.outputIndex,1,100*self.totalBlockageTime/MaxSimtime)
G.outputIndex+=1
G.outputSheet.write(G.outputIndex,0, "The percentage of Waiting of "+self.objName +" is:")
G.outputSheet.write(G.outputIndex,1,100*self.totalWaitingTime/MaxSimtime)
G.outputIndex+=1
else: #if we had multiple replications we output confidence intervals to excel
#for some outputs the results may be the same for each run (eg model is stochastic but failures fixed
#so failurePortion will be exactly the same in each run). That will give 0 variability and errors.
#so for each output value we check if there was difference in the runs' results
#if yes we output the Confidence Intervals. if not we output just the fix value
G.outputSheet.write(G.outputIndex,0, "CI "+str(G.confidenceLevel*100)+"% for the mean percentage of Working of "+self.objName +" is:")
if self.checkIfArrayHasDifValues(self.Working):
G.outputSheet.write(G.outputIndex,1,stat.bayes_mvs(self.Working, G.confidenceLevel)[0][1][0])
G.outputSheet.write(G.outputIndex,2,stat.bayes_mvs(self.Working, G.confidenceLevel)[0][0])
G.outputSheet.write(G.outputIndex,3,stat.bayes_mvs(self.Working, G.confidenceLevel)[0][1][1])
else:
G.outputSheet.write(G.outputIndex,1,self.Working[0])
G.outputSheet.write(G.outputIndex,2,self.Working[0])
G.outputSheet.write(G.outputIndex,3,self.Working[0])
G.outputIndex+=1
G.outputSheet.write(G.outputIndex,0, "CI "+str(G.confidenceLevel*100)+"% for the mean percentage of Blockage of "+self.objName +" is:")
if self.checkIfArrayHasDifValues(self.Blockage):
G.outputSheet.write(G.outputIndex,1,stat.bayes_mvs(self.Blockage, G.confidenceLevel)[0][1][0])
G.outputSheet.write(G.outputIndex,2,stat.bayes_mvs(self.Blockage, G.confidenceLevel)[0][0])
G.outputSheet.write(G.outputIndex,3,stat.bayes_mvs(self.Blockage, G.confidenceLevel)[0][1][1])
else:
G.outputSheet.write(G.outputIndex,1,self.Blockage[0])
G.outputSheet.write(G.outputIndex,2,self.Blockage[0])
G.outputSheet.write(G.outputIndex,3,self.Blockage[0])
G.outputIndex+=1
G.outputSheet.write(G.outputIndex,0, "CI "+str(G.confidenceLevel*100)+"% for the mean percentage of Waiting of "+self.objName +" is:")
if self.checkIfArrayHasDifValues(self.Waiting):
G.outputSheet.write(G.outputIndex,1,stat.bayes_mvs(self.Waiting, G.confidenceLevel)[0][1][0])
G.outputSheet.write(G.outputIndex,2,stat.bayes_mvs(self.Waiting, G.confidenceLevel)[0][0])
G.outputSheet.write(G.outputIndex,3,stat.bayes_mvs(self.Waiting, G.confidenceLevel)[0][1][1])
else:
G.outputSheet.write(G.outputIndex,1,self.Waiting[0])
G.outputSheet.write(G.outputIndex,2,self.Waiting[0])
G.outputSheet.write(G.outputIndex,3,self.Waiting[0])
G.outputIndex+=1
G.outputIndex+=1
#takes the array and checks if all its values are identical (returns false) or not (returns true)
#needed because if somebody runs multiple runs in deterministic case it would crash!
def checkIfArrayHasDifValues(self, array):
difValuesFlag=False
for i in range(1, len(array)):
if(array[i]!=array[1]):
difValuesFlag=True
return difValuesFlag
\ No newline at end of file
...@@ -93,9 +93,8 @@ class Exit(Process): ...@@ -93,9 +93,8 @@ class Exit(Process):
#gets an entity from the predecessor #gets an entity from the predecessor
def getEntity(self): def getEntity(self):
name=self.previous[self.predecessorIndex].Res.activeQ[0].name #get the name of the entity for the trace name=self.previous[0].Res.activeQ[0].name #get the name of the entity for the trace
self.totalLifespan+=now()-self.previous[self.predecessorIndex].Res.activeQ[0].startTime #Add the entity's lifespan to the total one. self.previous[0].removeEntity() #remove the entity from the previous object
self.previous[self.predecessorIndex].removeEntity() #remove the entity from the previous object
self.outputTrace(name) self.outputTrace(name)
#actions to be taken after the simulation ends #actions to be taken after the simulation ends
......
...@@ -22,5 +22,9 @@ class Frame(object): ...@@ -22,5 +22,9 @@ class Frame(object):
self.creationTime=0 self.creationTime=0
self.startTime=0 #holds the startTime for the lifespan self.startTime=0 #holds the startTime for the lifespan
self.Res=Resource(self.numOfParts) self.Res=Resource(self.numOfParts)
#dimension data
self.width=2
self.height=2
self.lenght=2
{"_class": "Dream.Simulation",
"general": {
"_class": "Dream.Configuration",
"numberOfReplications": "1",
"maxSimTime": "60",
"trace": "Yes",
"confidenceLevel": "0.95"
},
"modelResource": [
{"_class": "Dream.Repairman",
"id": "W1",
"name": "W1",
"capacity": "1"
}
],
"coreObject": [
{"_class": "Dream.Source",
"id": "S1",
"name": "Raw Material",
"interarrivalTime":
{
"distributionType": "Fixed",
"mean": "0.5"
},
"entity": "Part",
"successorList": ["DummyQ"]
},
{"_class": "Dream.Machine",
"id": "M1",
"name": "Machine1",
"processingTime": {
"distributionType": "Fixed",
"mean": "0.25"
},
"failures":{
"failureDistribution": "No",
"MTTF": "60",
"MTTR": "5",
"repairman": "W1"
},
"predecessorList": ["DummyQ"],
"successorList": ["C1"]
},
{"_class": "Dream.Machine",
"id": "M2",
"name": "Machine2",
"processingTime": {
"distributionType": "Fixed",
"mean": "1.5"
},
"failures":{
"failureDistribution": "No",
"MTTF": "40",
"MTTR": "10",
"repairman": "W1"
},
"predecessorList": ["C1"],
"successorList": ["E1"]
},
{"_class": "Dream.Queue",
"id": "DummyQ",
"name": "DummyQ",
"isDummy": "1",
"capacity": "1",
"predecessorList": ["S1"],
"successorList": ["M1"]
},
{"_class": "Dream.Conveyer",
"id": "C1",
"name": "C1",
"length": "8",
"speed": "1",
"predecessorList": ["M1"],
"successorList": ["M2"]
},
{"_class": "Dream.Exit",
"id": "E1",
"name": "Stock",
"predecessorList": ["M2"]
}
]
}
...@@ -19,6 +19,7 @@ from Part import Part ...@@ -19,6 +19,7 @@ from Part import Part
from Frame import Frame from Frame import Frame
from Assembly import Assembly from Assembly import Assembly
from Dismantle import Dismantle from Dismantle import Dismantle
from Conveyer import Conveyer
import xlwt import xlwt
import xlrd import xlrd
import time import time
...@@ -49,6 +50,7 @@ def createObjects(): ...@@ -49,6 +50,7 @@ def createObjects():
G.RepairmanList=[] G.RepairmanList=[]
G.AssemblyList=[] G.AssemblyList=[]
G.DismantleList=[] G.DismantleList=[]
G.ConveyerList=[]
#loop through all the model resources #loop through all the model resources
#read the data and create them #read the data and create them
...@@ -168,6 +170,19 @@ def createObjects(): ...@@ -168,6 +170,19 @@ def createObjects():
G.DismantleList.append(D) G.DismantleList.append(D)
G.ObjList.append(D) G.ObjList.append(D)
elif objClass=='Dream.Conveyer':
id=coreObject[i].get('id', 'not found')
name=coreObject[i].get('name', 'not found')
length=float(coreObject[i].get('length', '10'))
speed=float(coreObject[i].get('speed', '1'))
successorList=coreObject[i].get('successorList', 'not found')
predecessorList=coreObject[i].get('predecessorList', 'not found')
C=Conveyer(id, name, length, speed)
C.previousIds=predecessorList
C.nextIds=successorList
G.ObjList.append(C)
G.ConveyerList.append(C)
#defines the topology (predecessors and successors for all the objects) #defines the topology (predecessors and successors for all the objects)
def setTopology(): def setTopology():
......
...@@ -22,6 +22,10 @@ class Part(object): ...@@ -22,6 +22,10 @@ class Part(object):
self.currentStop=None #contains the current object that the material is in self.currentStop=None #contains the current object that the material is in
self.creationTime=0 self.creationTime=0
self.startTime=0 #holds the startTime for the lifespan self.startTime=0 #holds the startTime for the lifespan
#dimension data
self.width=1
self.height=1
self.length=1
def __del__(self): def __del__(self):
pass pass
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment