Dismantle updated for the signalling approach

parent b8c6f37e
...@@ -126,8 +126,7 @@ class Assembly(CoreObject): ...@@ -126,8 +126,7 @@ class Assembly(CoreObject):
self.printTrace(self.id, 'will wait for frame event') self.printTrace(self.id, 'will wait for frame event')
# wait until the Queue can accept an entity and one predecessor requests it # wait until the Queue can accept an entity and one predecessor requests it
yield waitevent, self, self.isRequested #[self.isRequested,self.canDispose, self.loadOperatorAvailable] yield waitevent, self, self.isRequested #[self.isRequested,self.canDispose, self.loadOperatorAvailable]
# yield waituntil, self, self.canAcceptAndIsRequested #wait until the Assembly can accept a frame
# #and one "frame" giver requests it
if self.isRequested.signalparam: if self.isRequested.signalparam:
self.printTrace(self.id, 'received a isRequested event from '+self.isRequested.signalparam.id) self.printTrace(self.id, 'received a isRequested event from '+self.isRequested.signalparam.id)
# reset the isRequested signal parameter # reset the isRequested signal parameter
...@@ -142,7 +141,6 @@ class Assembly(CoreObject): ...@@ -142,7 +141,6 @@ class Assembly(CoreObject):
self.printTrace(self.id, 'received a isRequested event from '+self.isRequested.signalparam.id) self.printTrace(self.id, 'received a isRequested event from '+self.isRequested.signalparam.id)
# reset the isRequested signal parameter # reset the isRequested signal parameter
self.isRequested.signalparam=None self.isRequested.signalparam=None
# yield waituntil, self, self.isRequestedFromPart #wait until a part is requesting for the assembly
# TODO: fix the getEntity 'Part' case # TODO: fix the getEntity 'Part' case
self.getEntity("Part") self.getEntity("Part")
...@@ -213,7 +211,6 @@ class Assembly(CoreObject): ...@@ -213,7 +211,6 @@ class Assembly(CoreObject):
# get the active and the giver objects # get the active and the giver objects
activeObject=self.getActiveObject() activeObject=self.getActiveObject()
activeObjectQueue=self.getActiveObjectQueue() activeObjectQueue=self.getActiveObjectQueue()
# giverObject=self.getGiverObject()
giverObject=callerObject giverObject=callerObject
assert giverObject, 'there must be a caller for canAcceptAndIsRequested' assert giverObject, 'there must be a caller for canAcceptAndIsRequested'
if(len(giverObject.getActiveObjectQueue())>0): if(len(giverObject.getActiveObjectQueue())>0):
......
...@@ -28,19 +28,19 @@ it gathers frames that have parts loaded, unloads the parts and sends the frame ...@@ -28,19 +28,19 @@ it gathers frames that have parts loaded, unloads the parts and sends the frame
''' '''
from SimPy.Simulation import Process, Resource from SimPy.Simulation import Process, Resource
from SimPy.Simulation import waituntil, now, hold, infinity from SimPy.Simulation import waitevent, now, hold, infinity
import xlwt import xlwt
from RandomNumberGenerator import RandomNumberGenerator from RandomNumberGenerator import RandomNumberGenerator
from CoreObject import CoreObject from CoreObject import CoreObject
# =========================================================================== #===============================================================================
# the Dismantle object # the Dismantle object
# =========================================================================== #===============================================================================
class Dismantle(CoreObject): class Dismantle(CoreObject):
class_name = 'Dream.Dismantle' class_name = 'Dream.Dismantle'
# ======================================================================= #===========================================================================
# initialize the object # initialize the object
# ======================================================================= #===========================================================================
def __init__(self, id, name, distribution='Fixed', mean=1, stdev=0.1, min=0, max=5): def __init__(self, id, name, distribution='Fixed', mean=1, stdev=0.1, min=0, max=5):
CoreObject.__init__(self, id, name) CoreObject.__init__(self, id, name)
self.type="Dismantle" #String that shows the type of object self.type="Dismantle" #String that shows the type of object
...@@ -69,10 +69,10 @@ class Dismantle(CoreObject): ...@@ -69,10 +69,10 @@ class Dismantle(CoreObject):
# when the entities have to be loaded to operatedMachines # when the entities have to be loaded to operatedMachines
# then the giverObjects have to be blocked for the time # then the giverObjects have to be blocked for the time
# that the machine is being loaded # that the machine is being loaded
# ======================================================================= #===========================================================================
# the initialize method # the initialize method
# ======================================================================= #===========================================================================
def initialize(self): def initialize(self):
Process.__init__(self) Process.__init__(self)
CoreObject.initialize(self) CoreObject.initialize(self)
...@@ -109,84 +109,136 @@ class Dismantle(CoreObject): ...@@ -109,84 +109,136 @@ class Dismantle(CoreObject):
self.Res.activeQ=[] self.Res.activeQ=[]
self.Res.waitQ=[] self.Res.waitQ=[]
# ======================================================================= #===========================================================================
# the run method # the run method
# ======================================================================= #===========================================================================
def run(self): def run(self):
activeObjectQueue=self.getActiveObjectQueue()
# check if there is WIP and signal receiver
self.initialSignalReceiver()
while 1: while 1:
yield waituntil, self, self.canAcceptAndIsRequested #wait until the Assembly can accept a frame self.printTrace(self.id, 'will wait for frame event')
#and one "frame" giver requests it # wait until the Queue can accept an entity and one predecessor requests it
self.getEntity() #get the Frame with the parts yield waitevent, self, self.isRequested #[self.isRequested,self.canDispose, self.loadOperatorAvailable]
self.timeLastEntityEntered=now()
startWorkingTime=now()
self.totalProcessingTimeInCurrentEntity=self.calculateProcessingTime() if self.isRequested.signalparam:
yield hold,self,self.totalProcessingTimeInCurrentEntity #hold for the time the assembly operation is carried self.printTrace(self.id, 'received a isRequested event from '+self.isRequested.signalparam.id)
# reset the isRequested signal parameter
self.totalWorkingTime+=now()-startWorkingTime self.isRequested.signalparam=None
self.timeLastEntityEnded=now()
startBlockageTime=now()
self.waitToDisposePart=True #Dismantle is in state to dispose a part
yield waituntil, self, self.frameIsEmpty #wait until all the parts are disposed
self.waitToDisposePart=False #Dismantle has no parts now
self.waitToDisposeFrame=True #Dismantle is in state to dispose a part
yield waituntil, self, self.isEmpty #wait until all the frame is disposed
self.completedJobs+=1 #Dismantle completed a job
self.waitToDisposeFrame=False #the Dismantle has no Frame to dispose now
#self.totalBlockageTime+=now()-startBlockageTime #add the blockage time
# ======================================================================= self.getEntity() #get the Frame with the parts
self.timeLastEntityEntered=now()
startWorkingTime=now()
self.totalProcessingTimeInCurrentEntity=self.calculateProcessingTime()
#hold for the time the assembly operation is carried
yield hold,self,self.totalProcessingTimeInCurrentEntity
self.totalWorkingTime+=now()-startWorkingTime
self.timeLastEntityEnded=now()
startBlockageTime=now()
self.waitToDispose=True
self.waitToDisposePart=True #Dismantle is in state to dispose a part
# while the object still holds the frame
while not self.isEmpty():
# try and signal the receiver
if not self.signalReceiver():
# if not possible, then wait till a receiver is available
yield waitevent, self, self.canDispose
# and signal it again
if not self.signalReceiver():
continue
# if the receiver was not responsive, release the control to let him remove the entity
yield hold, self, 0
# if all the parts are removed but not the frame, then set the flag waitToDisposeFrame
if self.frameIsEmpty() and not self.waitToDisposeFrame:
self.waitToDisposePart=False
self.waitToDisposeFrame=True
# if the internal queue is empty then update the corresponding flags and proceed with getting a new entity
if self.isEmpty():
self.completedJobs+=1 #Dismantle completed a job
self.waitToDisposeFrame=False #the Dismantle has no Frame to dispose now
break
#===========================================================================
# checks if the Dismantle can accept an entity and there is a Frame # checks if the Dismantle can accept an entity and there is a Frame
# waiting for it # waiting for it
# ======================================================================= #===========================================================================
def canAcceptAndIsRequested(self): def canAcceptAndIsRequested(self,callerObject=None):
return len(self.getActiveObjectQueue())==0 and self.getGiverObject().haveToDispose(self) # get the active and the giver objects
activeObject=self.getActiveObject()
activeObjectQueue=self.getActiveObjectQueue()
giverObject=callerObject
assert giverObject, 'there must be a caller for canAcceptAndIsRequested'
return len(activeObjectQueue)==0 and giverObject.haveToDispose(activeObject)
# ======================================================================= #===========================================================================
# checks if the Dismantle can accept an entity # checks if the Dismantle can accept an entity
# ======================================================================= #===========================================================================
def canAccept(self, callerObject=None): def canAccept(self, callerObject=None):
return len(self.getActiveObjectQueue())==0 thecaller=callerObject
# if there is no caller return True only when the internal queue is empty
if not thecaller:
return len(self.getActiveObjectQueue())==0
# otherrwise check additionally if the caller is in the previous list
return len(self.getActiveObjectQueue())==0 and (callerObject in self.previous)
# ======================================================================= #===========================================================================
# defines where parts and frames go after they leave the object # defines where parts and frames go after they leave the object
# ======================================================================= #===========================================================================
def definePartFrameRouting(self, successorPartList=[], successorFrameList=[]): def definePartFrameRouting(self, successorPartList=[], successorFrameList=[]):
self.nextPart=successorPartList self.nextPart=successorPartList
self.nextFrame=successorFrameList self.nextFrame=successorFrameList
# ======================================================================= #===========================================================================
# checks if the caller waits for a part or a frame and if the Dismantle # checks if the caller waits for a part or a frame and if the Dismantle
# is in the state of disposing one it returnse true # is in the state of disposing one it returnse true
# ======================================================================= #===========================================================================
def haveToDispose(self, callerObject=None): def haveToDispose(self, callerObject=None):
activeObject=self.getActiveObject()
activeObjectQueue=self.getActiveObjectQueue()
thecaller=callerObject thecaller=callerObject
#if we have only one possible receiver just check if the Queue holds one or more entities
if(thecaller==None):
return len(activeObjectQueue)>0
#according to the caller return true or false #according to the caller return true or false
if thecaller in self.nextPart: if thecaller in self.nextPart:
if len(self.getActiveObjectQueue())>1 and self.waitToDisposePart: if len(self.getActiveObjectQueue())>1 and self.waitToDisposePart:
self.receiver=thecaller
return True return True
elif thecaller in self.nextFrame: elif thecaller in self.nextFrame:
if len(self.getActiveObjectQueue())==1 and self.waitToDisposeFrame: if len(self.getActiveObjectQueue())==1 and self.waitToDisposeFrame:
self.receiver=thecaller
return True return True
return False return False
# ======================================================================= #===========================================================================
# find possible receivers
#===========================================================================
def findReceivers(self):
activeObject=self.getActiveObject()
next=[]
receivers=[]
# if the parts are not yet disposed
if not activeObject.frameIsEmpty():
# search for receivers within the nextPart list
next=activeObject.nextPart
else:
# otherwise search within the nextFrame list
next=activeObject.nextFrame
for object in [x for x in next if x.canAccept(activeObject)]:
receivers.append(object)
return receivers
#===========================================================================
# checks if the frame is emptied # checks if the frame is emptied
# ======================================================================= #===========================================================================
def frameIsEmpty(self): def frameIsEmpty(self):
return len(self.getActiveObjectQueue())==1 return len(self.getActiveObjectQueue())==1
# ======================================================================= #===========================================================================
# checks if Dismantle is emptied # checks if Dismantle is emptied
# ======================================================================= #===========================================================================
def isEmpty(self): def isEmpty(self):
return len(self.getActiveObjectQueue())==0 return len(self.getActiveObjectQueue())==0
...@@ -207,24 +259,29 @@ class Dismantle(CoreObject): ...@@ -207,24 +259,29 @@ class Dismantle(CoreObject):
activeObjectQueue.pop(0) activeObjectQueue.pop(0)
return activeEntity return activeEntity
# ======================================================================= #===========================================================================
# removes an entity from the Dismantle # removes an entity from the Dismantle
# ======================================================================= #===========================================================================
def removeEntity(self, entity=None): def removeEntity(self, entity=None):
activeObjectQueue=self.getActiveObjectQueue() activeObject=self.getActiveObject()
activeEntity=CoreObject.removeEntity(self, entity) #run the default method activeObjectQueue=activeObject.getActiveObjectQueue()
#run the default method
activeEntity=CoreObject.removeEntity(self, entity)
#update the flags #update the flags
if(len(activeObjectQueue)==0): if(len(activeObjectQueue)==0):
self.waitToDisposeFrame=False activeObject.waitToDisposeFrame=False
else: else:
if(len(activeObjectQueue)==1): if(len(activeObjectQueue)==1):
self.waitToDisposePart=False activeObject.waitToDisposePart=False
# if the internal queue is empty then try to signal the giver that the object can now receive
if activeObject.canAccept():
activeObject.printTrace(self.id, 'will try signalling a giver from removeEntity')
activeObject.signalGiver()
return activeEntity return activeEntity
# ======================================================================= #===========================================================================
# add the blockage only if the very last Entity (Frame) is to depart # add the blockage only if the very last Entity (Frame) is to depart
# ======================================================================= #===========================================================================
def addBlockage(self): def addBlockage(self):
if len(self.getActiveObjectQueue())==1: if len(self.getActiveObjectQueue())==1:
self.totalTimeInCurrentEntity=now()-self.timeLastEntityEntered self.totalTimeInCurrentEntity=now()-self.timeLastEntityEntered
...@@ -232,9 +289,9 @@ class Dismantle(CoreObject): ...@@ -232,9 +289,9 @@ class Dismantle(CoreObject):
blockage=now()-(self.timeLastEntityEnded+self.downTimeInTryingToReleaseCurrentEntity) blockage=now()-(self.timeLastEntityEnded+self.downTimeInTryingToReleaseCurrentEntity)
self.totalBlockageTime+=blockage self.totalBlockageTime+=blockage
# ======================================================================= #===========================================================================
# actions to be taken after the simulation ends # actions to be taken after the simulation ends
# ======================================================================= #===========================================================================
def postProcessing(self, MaxSimtime=None): def postProcessing(self, MaxSimtime=None):
if MaxSimtime==None: if MaxSimtime==None:
from Globals import G from Globals import G
...@@ -256,11 +313,11 @@ class Dismantle(CoreObject): ...@@ -256,11 +313,11 @@ class Dismantle(CoreObject):
self.Waiting.append(100*self.totalWaitingTime/MaxSimtime) self.Waiting.append(100*self.totalWaitingTime/MaxSimtime)
self.Working.append(100*self.totalWorkingTime/MaxSimtime) self.Working.append(100*self.totalWorkingTime/MaxSimtime)
self.Blockage.append(100*self.totalBlockageTime/MaxSimtime) self.Blockage.append(100*self.totalBlockageTime/MaxSimtime)
# ======================================================================= #===========================================================================
# outputs message to the trace.xls. # outputs message to the trace.xls.
# Format is (Simulation Time | Entity or Frame Name | message) # Format is (Simulation Time | Entity or Frame Name | message)
# ======================================================================= #===========================================================================
def outputTrace(self, name, message): def outputTrace(self, name, message):
from Globals import G from Globals import G
if(G.trace=="Yes"): #output only if the user has selected to if(G.trace=="Yes"): #output only if the user has selected to
...@@ -274,10 +331,10 @@ class Dismantle(CoreObject): ...@@ -274,10 +331,10 @@ class Dismantle(CoreObject):
G.traceIndex=0 G.traceIndex=0
G.sheetIndex+=1 G.sheetIndex+=1
G.traceSheet=G.traceFile.add_sheet('sheet '+str(G.sheetIndex), cell_overwrite_ok=True) G.traceSheet=G.traceFile.add_sheet('sheet '+str(G.sheetIndex), cell_overwrite_ok=True)
# ======================================================================= #===========================================================================
# outputs data to "output.xls" # outputs data to "output.xls"
# ======================================================================= #===========================================================================
def outputResultsXL(self, MaxSimtime=None): def outputResultsXL(self, MaxSimtime=None):
from Globals import G from Globals import G
from Globals import getConfidenceIntervals from Globals import getConfidenceIntervals
...@@ -315,10 +372,10 @@ class Dismantle(CoreObject): ...@@ -315,10 +372,10 @@ class Dismantle(CoreObject):
G.outputSheet.write(G.outputIndex, 3, waiting_ci['max']) G.outputSheet.write(G.outputIndex, 3, waiting_ci['max'])
G.outputIndex+=1 G.outputIndex+=1
G.outputIndex+=1 G.outputIndex+=1
# ======================================================================= #===========================================================================
# outputs results to JSON File # outputs results to JSON File
# ======================================================================= #===========================================================================
def outputResultsJSON(self): def outputResultsJSON(self):
from Globals import G from Globals import G
from Globals import getConfidenceIntervals from Globals import getConfidenceIntervals
......
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