Commit 56cff46e authored by Georgios Dagkakis's avatar Georgios Dagkakis Committed by Sebastien Robin

machine object updated so that it uses the new methods (getActiveEntityQueue, getGiverEntity etc)

parent bd460546
......@@ -147,7 +147,7 @@ class CoreObject(Process):
#get the receiver object in a removeEntity transaction.
def getReceiverObject(self):
return self.next[self.predecessorIndex]
return self.next[self.successorIndex]
#get the receiver object queue in a removeEntity transaction.
def getReceiverObjectQueue(self):
......
......@@ -128,8 +128,7 @@ class Machine(CoreObject):
processingEndedFlag=True
failureTime=0
self.downTimeInCurrentEntity=0
#this loop is repeated until the processing time is expired with no failure
while processingEndedFlag:
tBefore=now()
......@@ -198,47 +197,50 @@ class Machine(CoreObject):
#checks if the Machine can accept an entity
#it checks also who called it and returns TRUE only to the predecessor that will give the entity.
def canAccept(self, callerObject=None):
activeObject=self.getActiveObject()
activeObjectQueue=self.getActiveObjectQueue()
giverObject=self.getGiverObject()
#if we have only one predecessor just check if there is a place and the machine is up
if(len(self.previous)==1 or callerObject==None):
return self.Up and len(self.Res.activeQ)==0
if(len(activeObject.previous)==1 or callerObject==None):
return activeObject.Up and len(activeObjectQueue)==0
#if the machine is busy return False immediately
if len(self.Res.activeQ)==self.capacity:
if len(activeObjectQueue)==activeObject.capacity:
return False
thecaller=callerObject
#return true only to the predecessor from which the queue will take
flag=False
if thecaller is self.previous[self.predecessorIndex]:
flag=True
return len(self.Res.activeQ)<self.capacity and flag
return len(activeObjectQueue)<self.capacity and (thecaller is giverObject)
#checks if the Machine can accept an entity and there is an entity in some predecessor waiting for it
#also updates the predecessorIndex to the one that is to be taken
def canAcceptAndIsRequested(self):
activeObject=self.getActiveObject()
activeObjectQueue=self.getActiveObjectQueue()
giverObject=self.getGiverObject()
#if we have only one predecessor just check if there is a place, the machine is up and the predecessor has an entity to dispose
if(len(self.previous)==1):
return self.Up and len(self.Res.activeQ)==0 and self.previous[0].haveToDispose(self)
if(len(activeObject.previous)==1):
return activeObject.Up and len(activeObjectQueue)==0 and giverObject.haveToDispose(activeObject)
isRequested=False
maxTimeWaiting=0
#loop through the predecessors to see which have to dispose and which is the one blocked for longer
for i in range(len(self.previous)):
if(self.previous[i].haveToDispose(self)):
for i in range(len(activeObject.previous)):
if(activeObject.previous[i].haveToDispose(self)):
isRequested=True
if(self.previous[i].downTimeInTryingToReleaseCurrentEntity>0):
timeWaiting=now()-self.previous[i].timeLastFailureEnded
if(activeObject.previous[i].downTimeInTryingToReleaseCurrentEntity>0):
timeWaiting=now()-activeObject.previous[i].timeLastFailureEnded
else:
timeWaiting=now()-self.previous[i].timeLastEntityEnded
timeWaiting=now()-activeObject.previous[i].timeLastEntityEnded
#if more than one predecessor have to dispose take the part from the one that is blocked longer
if(timeWaiting>=maxTimeWaiting):
self.predecessorIndex=i
maxTimeWaiting=timeWaiting
return len(self.Res.activeQ)<self.capacity and isRequested
return len(activeObjectQueue)<activeObject.capacity and isRequested
#checks if the machine down or it can dispose the object
def ifCanDisposeOrHaveFailure(self):
......@@ -247,44 +249,52 @@ class Machine(CoreObject):
#removes an entity from the Machine
def removeEntity(self):
self.timeLastEntityLeft=now()
self.outputTrace("releases "+self.objName)
self.waitToDispose=False
self.Res.activeQ.pop(0)
self.downTimeInTryingToReleaseCurrentEntity=0
activeObject=self.getActiveObject()
activeObjectQueue=self.getActiveObjectQueue()
activeObject.timeLastEntityLeft=now()
activeObject.outputTrace("releases "+activeObject.objName)
activeObject.waitToDispose=False
activeObjectQueue.pop(0) #remove the Entity from the activeQ
activeObject.downTimeInTryingToReleaseCurrentEntity=0
#checks if the Machine can dispose an entity to the following object
def haveToDispose(self, callerObject=None):
activeObject=self.getActiveObject()
activeObjectQueue=self.getActiveObjectQueue()
#if we have only one successor just check if machine waits to dispose and also is up
if(len(self.next)==1 or callerObject==None):
return len(self.Res.activeQ)>0 and self.waitToDispose and self.Up
if(len(activeObject.next)==1 or callerObject==None):
return len(activeObjectQueue)>0 and activeObject.waitToDispose and activeObject.Up
#if the Machine is empty it returns false right away
if(len(self.Res.activeQ)==0):
if(len(activeObjectQueue)==0):
return False
thecaller=callerObject
#give the entity to the successor that is waiting for the most time.
#plant does not do this in every occasion!
#(plant simulation does not do this in every occasion!)
maxTimeWaiting=0
for i in range(len(self.next)):
if(self.next[i].canAccept(self)):
timeWaiting=now()-self.next[i].timeLastEntityLeft
i=0
for object in activeObject.next:
if(object.canAccept(activeObject)):
timeWaiting=now()-object.timeLastEntityLeft
if(timeWaiting>maxTimeWaiting or maxTimeWaiting==0):
maxTimeWaiting=timeWaiting
self.successorIndex=i
activeObject.successorIndex=i
i+=1
#return true only to the predecessor from which the queue will take
flag=False
if thecaller is self.next[self.successorIndex]:
flag=True
return len(self.Res.activeQ)>0 and self.waitToDispose and self.Up and flag
receiverObject=activeObject.getReceiverObject()
return len(activeObjectQueue)>0 and activeObject.waitToDispose and activeObject.Up and (thecaller is receiverObject)
#actions to be taken after the simulation ends
def postProcessing(self, MaxSimtime):
activeObject=self.getActiveObject()
activeObjectQueue=self.getActiveObjectQueue()
alreadyAdded=False #a flag that shows if the blockage time has already been added
#checks all the successors. If no one can accept an Entity then the machine might be blocked
......@@ -298,41 +308,41 @@ class Machine(CoreObject):
#till the end of simulation, we have to add this blockage to the percentage of blockage in Machine
#we should exclude the failure time in current entity though!
#if (len(self.Res.activeQ)>0) and (len(self.next[0].Res.activeQ)>0) and ((self.nameLastEntityEntered == self.nameLastEntityEnded)):
if (len(self.Res.activeQ)>0) and (mightBeBlocked) and ((self.nameLastEntityEntered == self.nameLastEntityEnded)):
self.totalBlockageTime+=now()-(self.timeLastEntityEnded+self.downTimeInTryingToReleaseCurrentEntity)
if self.Up==False:
self.totalBlockageTime-=now()-self.timeLastFailure
if (len(activeObjectQueue)>0) and (mightBeBlocked) and ((activeObject.nameLastEntityEntered == activeObject.nameLastEntityEnded)):
activeObject.totalBlockageTime+=now()-(activeObject.timeLastEntityEnded+activeObject.downTimeInTryingToReleaseCurrentEntity)
if activeObject.Up==False:
activeObject.totalBlockageTime-=now()-activeObject.timeLastFailure
alreadyAdded=True
#if Machine is currently processing an entity we should count this working time
if(len(self.Res.activeQ)>0) and (not (self.nameLastEntityEnded==self.nameLastEntityEntered)):
if(len(activeObject.Res.activeQ)>0) and (not (activeObject.nameLastEntityEnded==activeObject.nameLastEntityEntered)):
#if Machine is down we should add this last failure time to the time that it has been down in current entity
if(len(self.Res.activeQ)>0) and (self.Up==False):
self.downTimeProcessingCurrentEntity+=now()-self.timeLastFailure
self.totalWorkingTime+=now()-self.timeLastEntityEntered-self.downTimeProcessingCurrentEntity
if(len(activeObjectQueue)>0) and (self.Up==False):
activeObject.downTimeProcessingCurrentEntity+=now()-activeObject.timeLastFailure
activeObject.totalWorkingTime+=now()-activeObject.timeLastEntityEntered-activeObject.downTimeProcessingCurrentEntity
#if Machine is down we have to add this failure time to its total failure time
#we also need to add the last blocking time to total blockage time
if(self.Up==False):
self.totalFailureTime+=now()-self.timeLastFailure
if(activeObject.Up==False):
activeObject.totalFailureTime+=now()-activeObject.timeLastFailure
#we add the value only if it hasn't already been added
#if((len(self.next[0].Res.activeQ)>0) and (self.nameLastEntityEnded==self.nameLastEntityEntered) and (not alreadyAdded)):
if((mightBeBlocked) and (self.nameLastEntityEnded==self.nameLastEntityEntered) and (not alreadyAdded)):
self.totalBlockageTime+=(now()-self.timeLastEntityEnded)-(now()-self.timeLastFailure)-self.downTimeInTryingToReleaseCurrentEntity
if((mightBeBlocked) and (activeObject.nameLastEntityEnded==activeObject.nameLastEntityEntered) and (not alreadyAdded)):
activeObject.totalBlockageTime+=(now()-activeObject.timeLastEntityEnded)-(now()-activeObject.timeLastFailure)-activeObject.downTimeInTryingToReleaseCurrentEntity
#Machine was idle when it was not in any other state
self.totalWaitingTime=MaxSimtime-self.totalWorkingTime-self.totalBlockageTime-self.totalFailureTime
activeObject.totalWaitingTime=MaxSimtime-activeObject.totalWorkingTime-activeObject.totalBlockageTime-activeObject.totalFailureTime
if self.totalBlockageTime<0 and self.totalBlockageTime>-0.00001: #to avoid some effects of getting negative cause of rounding precision
if activeObject.totalBlockageTime<0 and activeObject.totalBlockageTime>-0.00001: #to avoid some effects of getting negative cause of rounding precision
self.totalBlockageTime=0
if self.totalWaitingTime<0 and self.totalWaitingTime>-0.00001: #to avoid some effects of getting negative cause of rounding precision
if activeObject.totalWaitingTime<0 and activeObject.totalWaitingTime>-0.00001: #to avoid some effects of getting negative cause of rounding precision
self.totalWaitingTime=0
self.Failure.append(100*self.totalFailureTime/MaxSimtime)
self.Blockage.append(100*self.totalBlockageTime/MaxSimtime)
self.Waiting.append(100*self.totalWaitingTime/MaxSimtime)
self.Working.append(100*self.totalWorkingTime/MaxSimtime)
activeObject.Failure.append(100*self.totalFailureTime/MaxSimtime)
activeObject.Blockage.append(100*self.totalBlockageTime/MaxSimtime)
activeObject.Waiting.append(100*self.totalWaitingTime/MaxSimtime)
activeObject.Working.append(100*self.totalWorkingTime/MaxSimtime)
#outputs message to the trace.xls. Format is (Simulation Time | Entity Name | message)
def outputTrace(self, message):
......@@ -353,8 +363,7 @@ class Machine(CoreObject):
#outputs the the "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
if(G.numberOfReplications==1): #if we had just one replication output the results to excel
G.outputSheet.write(G.outputIndex,0, "The percentage of Failure of " +self.objName+ " is:")
G.outputSheet.write(G.outputIndex,1,100*self.totalFailureTime/MaxSimtime)
G.outputIndex+=1
......
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