Assembly and Dismantle updated. Source and CoreObject minor fixes

parent b242d7a5
......@@ -26,8 +26,9 @@ Models an assembly object
it gathers frames and parts which are loaded to the frames
'''
from SimPy.Simulation import Process, Resource
from SimPy.Simulation import waitevent, now, hold
# from SimPy.Simulation import Process, Resource
# from SimPy.Simulation import waitevent, now, hold
import simpy
import xlwt
from RandomNumberGenerator import RandomNumberGenerator
from CoreObject import CoreObject
......@@ -41,6 +42,8 @@ class Assembly(CoreObject):
# initialize the object
#===========================================================================
def __init__(self, id, name, processingTime=None):
from Globals import G
self.env=G.env
if not processingTime:
processingTime = {'distributionType': 'Fixed',
'mean': 0,
......@@ -80,7 +83,7 @@ class Assembly(CoreObject):
# initialize method
#===========================================================================
def initialize(self):
Process.__init__(self)
# Process.__init__(self)
CoreObject.initialize(self)
self.waitToDispose=False #flag that shows if the object waits to dispose an entity
......@@ -97,8 +100,6 @@ class Assembly(CoreObject):
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.totalBlockageTime=0 #holds the total blockage time
self.totalWaitingTime=0 #holds the total waiting time
......@@ -111,9 +112,9 @@ class Assembly(CoreObject):
self.nameLastFrameWasFull="" #holds the name of the last frame that was full, ie that assembly process started
self.nameLastEntityEntered="" #holds the name of the last frame that entered processing in the object
self.nameLastEntityEnded="" #holds the name of the last frame that ended processing in the object
self.Res=Resource(1)
self.Res.activeQ=[]
self.Res.waitQ=[]
self.Res=simpy.Resource(self.env, 1)
self.Res.users=[]
# self.Res.waitQ=[]
#===========================================================================
# class generator
......@@ -125,50 +126,50 @@ class Assembly(CoreObject):
while 1:
self.printTrace(self.id, waitEvent='')
# wait until the Queue can accept an entity and one predecessor requests it
yield waitevent, self, self.isRequested #[self.isRequested,self.canDispose, self.loadOperatorAvailable]
if self.isRequested.signalparam:
self.printTrace(self.id, isRequested=self.isRequested.signalparam.id)
yield self.isRequested #[self.isRequested,self.canDispose, self.loadOperatorAvailable]
if self.isRequested.value:
self.printTrace(self.id, isRequested=self.isRequested.value.id)
# reset the isRequested signal parameter
self.isRequested.signalparam=None
self.isRequested=self.env.event()
self.getEntity("Frame") #get the Frame
for i in range(self.getActiveObjectQueue()[0].capacity): #this loop will be carried until the Frame is full with the parts
self.printTrace(self.id, waitEvent='(to load parts)')
yield waitevent, self, self.isRequested
if self.isRequested.signalparam:
self.printTrace(self.id, isRequested=self.isRequested.signalparam.id)
yield self.isRequested
if self.isRequested.value:
self.printTrace(self.id, isRequested=self.isRequested.value.id)
# reset the isRequested signal parameter
self.isRequested.signalparam=None
self.isRequested=self.env.event()
# TODO: fix the getEntity 'Part' case
self.getEntity("Part")
self.outputTrace(self.getActiveObjectQueue()[0].name, "is now full in "+ self.objName)
self.timeLastFrameWasFull=now()
self.timeLastFrameWasFull=self.env.now
self.nameLastFrameWasFull=self.getActiveObjectQueue()[0].name
startWorkingTime=now()
startWorkingTime=self.env.now
self.totalProcessingTimeInCurrentEntity=self.calculateProcessingTime()
yield hold,self,self.totalProcessingTimeInCurrentEntity #hold for the time the assembly operation is carried
self.totalWorkingTime+=now()-startWorkingTime
yield self.env.timeout(self.totalProcessingTimeInCurrentEntity) #hold for the time the assembly operation is carried
self.totalWorkingTime+=self.env.now-startWorkingTime
self.outputTrace(self.getActiveObjectQueue()[0].name, "ended processing in " + self.objName)
self.timeLastEntityEnded=now()
self.timeLastEntityEnded=self.env.now
self.nameLastEntityEnded=self.getActiveObjectQueue()[0].name
startBlockageTime=now()
startBlockageTime=self.env.now
self.completedJobs+=1 #Assembly completed a job
self.waitToDispose=True #since all the frame is full
self.printTrace(self.id, attemptSignalReceiver='(generator')
self.printTrace(self.id, attemptSignalReceiver='(generator)')
# signal the receiver that the activeObject has something to dispose of
if not self.signalReceiver():
# if there was no available receiver, get into blocking control
while 1:
# wait the event canDispose, this means that the station can deliver the item to successor
event=yield waitevent, self, self.canDispose #[self.canDispose, self.interruptionStart]
receivedEvent=yield self.canDispose #[self.canDispose, self.interruptionStart]
self.canDispose=self.env.event()
# try to signal a receiver, if successful then proceed to get an other entity
if self.signalReceiver():
break
......@@ -177,11 +178,11 @@ class Assembly(CoreObject):
# signals the preceding station (e.g. self.machine) and immediately after that gets the entity.
# the preceding machine gets the canDispose signal which is actually useless, is emptied by the following station
# and then cannot exit an infinite loop.
yield hold, self, 0
yield self.env.timeout(0)
# if while waiting (for a canDispose event) became free as the machines that follows emptied it, then proceed
if not self.haveToDispose():
break
#self.totalBlockageTime+=now()-startBlockageTime #add the blockage time
#self.totalBlockageTime+=self.env.now-startBlockageTime #add the blockage time
#===========================================================================
......@@ -275,7 +276,7 @@ class Assembly(CoreObject):
# if the type is Frame
if(activeEntity.type=="Frame"):
self.nameLastEntityEntered=activeEntity.name
self.timeLastEntityEntered=now()
self.timeLastEntityEntered=self.env.now
activeEntity.currentStation=self
# if the frame is not fully loaded then signal a giver
......@@ -317,11 +318,11 @@ class Assembly(CoreObject):
#the following Object
#till the end of simulation, we have to add this blockage to the percentage of blockage in Assembly
if (mightBeBlocked) and ((self.nameLastEntityEntered == self.nameLastEntityEnded)):
self.totalBlockageTime+=now()-self.timeLastEntityEnded
self.totalBlockageTime+=self.env.now-self.timeLastEntityEnded
#if Assembly is currently processing an entity we should count this working time
if(len(activeObjectQueue)>0) and (not (self.nameLastEntityEnded==self.nameLastFrameWasFull)):
self.totalWorkingTime+=now()-self.timeLastFrameWasFull
self.totalWorkingTime+=self.env.now-self.timeLastFrameWasFull
self.totalWaitingTime=MaxSimtime-self.totalWorkingTime-self.totalBlockageTime
......
......@@ -262,7 +262,7 @@ class CoreObject(object):
# update the next list of the object
self.updateNext(activeEntity)
self.outputTrace(activeEntity.name, "got into "+self.objName)
# self.printTrace(activeEntity.name, enter=self.id)
self.printTrace(activeEntity.name, enter=self.id)
return activeEntity
#===========================================================================
......@@ -522,14 +522,14 @@ class CoreObject(object):
assert len(kw)==1, 'only one phrase per printTrace supported for the moment'
from Globals import G
import Globals
time=self.env.now
time=G.env.now
charLimit=60
remainingChar=charLimit-len(entity)-len(str(time))
if(G.console=='Yes'):
print time,entity,
for key in kw:
if key not in Globals.getSupportedPrintKwrds():
raise ValueError("Unsupported phrase %s for %s" % (key, entity.name))
raise ValueError("Unsupported phrase %s for %s" % (key, entity))
element=Globals.getPhrase()[key]
phrase=element['phrase']
prefix=element.get('prefix',None)
......
......@@ -27,8 +27,9 @@ Models a dicmantle object
it gathers frames that have parts loaded, unloads the parts and sends the frame to one destination and the parts to another
'''
from SimPy.Simulation import Process, Resource
from SimPy.Simulation import waitevent, now, hold, infinity
# from SimPy.Simulation import Process, Resource
# from SimPy.Simulation import waitevent, now, hold, infinity
import simpy
import xlwt
from RandomNumberGenerator import RandomNumberGenerator
from CoreObject import CoreObject
......@@ -43,6 +44,9 @@ class Dismantle(CoreObject):
#===========================================================================
def __init__(self, id, name, distribution='Fixed', mean=1, stdev=0.1, min=0, max=5):
CoreObject.__init__(self, id, name)
from Globals import G
self.env=G.env
self.type="Dismantle" #String that shows the type of object
self.distType=distribution #the distribution that the procTime follows
self.rng=RandomNumberGenerator(self, self.distType)
......@@ -74,7 +78,7 @@ class Dismantle(CoreObject):
# the initialize method
#===========================================================================
def initialize(self):
Process.__init__(self)
# Process.__init__(self)
CoreObject.initialize(self)
self.waitToDispose=False #flag that shows if the object waits to dispose an entity
self.waitToDisposePart=False #flag that shows if the object waits to dispose a part
......@@ -105,9 +109,9 @@ class Dismantle(CoreObject):
self.nameLastFrameWasFull="" #holds the name of the last frame that was full, ie that assembly process started
self.nameLastEntityEntered="" #holds the name of the last frame that entered processing in the object
self.nameLastEntityEnded="" #holds the name of the last frame that ended processing in the object
self.Res=Resource(capacity=infinity)
self.Res.activeQ=[]
self.Res.waitQ=[]
self.Res=simpy.Resource(self.env, capacity='inf')
self.Res.users=[]
# self.Res.waitQ=[]
#===========================================================================
# the run method
......@@ -119,23 +123,23 @@ class Dismantle(CoreObject):
while 1:
self.printTrace(self.id, waitEvent='(frame)')
# 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 self.isRequested #[self.isRequested,self.canDispose, self.loadOperatorAvailable]
if self.isRequested.signalparam:
self.printTrace(self.id, isRequested=self.isRequested.signalparam.id)
if self.isRequested.value:
self.printTrace(self.id, isRequested=self.isRequested.value.id)
# reset the isRequested signal parameter
self.isRequested.signalparam=None
self.isRequested=self.env.event()
self.getEntity() #get the Frame with the parts
self.timeLastEntityEntered=now()
startWorkingTime=now()
self.timeLastEntityEntered=self.env.now
startWorkingTime=self.env.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()
yield self.env.timeout(self.totalProcessingTimeInCurrentEntity)
self.totalWorkingTime+=self.env.now-startWorkingTime
self.timeLastEntityEnded=self.env.now
startBlockageTime=self.env.now
self.waitToDispose=True
self.waitToDisposePart=True #Dismantle is in state to dispose a part
......@@ -144,12 +148,13 @@ class Dismantle(CoreObject):
# try and signal the receiver
if not self.signalReceiver():
# if not possible, then wait till a receiver is available
yield waitevent, self, self.canDispose
yield self.canDispose
self.canDispose=self.env.event()
# 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
yield self.env.timeout(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
......@@ -275,7 +280,7 @@ class Dismantle(CoreObject):
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, attemptSingalGiver='(removeEntity)')
activeObject.printTrace(self.id, attemptSignalGiver='(removeEntity)')
activeObject.signalGiver()
return activeEntity
......@@ -284,9 +289,9 @@ class Dismantle(CoreObject):
#===========================================================================
def addBlockage(self):
if len(self.getActiveObjectQueue())==1:
self.totalTimeInCurrentEntity=now()-self.timeLastEntityEntered
self.totalTimeInCurrentEntity=self.env.now-self.timeLastEntityEntered
self.totalTimeWaitingForOperator += self.operatorWaitTimeCurrentEntity
blockage=now()-(self.timeLastEntityEnded+self.downTimeInTryingToReleaseCurrentEntity)
blockage=self.env.now-(self.timeLastEntityEnded+self.downTimeInTryingToReleaseCurrentEntity)
self.totalBlockageTime+=blockage
#===========================================================================
......@@ -300,12 +305,12 @@ class Dismantle(CoreObject):
#if there is an entity that finished processing in Dismantle 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 Dismantle
if (len(self.Res.activeQ)>0) and (self.waitToDisposeFrame) or (self.waitToDisposePart):
self.totalBlockageTime+=now()-self.timeLastEntityEnded
if (len(self.Res.users)>0) and (self.waitToDisposeFrame) or (self.waitToDisposePart):
self.totalBlockageTime+=self.env.now-self.timeLastEntityEnded
#if Dismantle is currently processing an entity we should count this working time
if(len(self.Res.activeQ)>0) and (not ((self.waitToDisposeFrame) or (self.waitToDisposePart))):
self.totalWorkingTime+=now()-self.timeLastEntityEntered
if(len(self.Res.users)>0) and (not ((self.waitToDisposeFrame) or (self.waitToDisposePart))):
self.totalWorkingTime+=self.env.now-self.timeLastEntityEntered
self.totalWaitingTime=MaxSimtime-self.totalWorkingTime-self.totalBlockageTime
......@@ -322,7 +327,7 @@ class Dismantle(CoreObject):
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,0,str(self.env.now))
G.traceSheet.write(G.traceIndex,1,name)
G.traceSheet.write(G.traceIndex,2,message)
G.traceIndex+=1 #increment the row
......
......@@ -115,6 +115,7 @@ class Failure(ObjectInterruption):
self.reactivateVictim() # since repairing is over, the Machine is reactivated
self.victim.Up=True
self.outputTrace("is up")
self.repairman.totalWorkingTime+=self.env.now-timeOperationStarted
continue
......@@ -125,6 +126,7 @@ class Failure(ObjectInterruption):
self.reactivateVictim() # since repairing is over, the Machine is reactivated
self.victim.Up=True
self.outputTrace("is up")
# if(self.repairman and self.repairman!="None"): #if a resource was used, it is now released
# print self.repairman.Res.users
# print self.env.now, self.repairman.id, 'about to be release from', self.victim.id
......
......@@ -146,20 +146,19 @@ class Source(CoreObject):
while 1:
# wait for any event (entity creation or request for disposal of entity)
receivedEvent=yield self.entityCreated | self.canDispose | self.loadOperatorAvailable
self.printTrace(self.id, received='')
# if an entity is created try to signal the receiver and continue
if self.entityCreated in receivedEvent:
self.entityCreated=self.env.event()
if self.signalReceiver():
continue
# otherwise, if the receiver requests availability then try to signal him if there is anything to dispose of
if self.canDispose in receivedEvent or self.loadOperatorAvailable in receivedEvent:
# self.canDispose.signalparam=None
self.canDispose=self.env.event()
# self.loadOperatorAvailable.signalparam=None
self.loadOperatorAvailable=self.env.event()
if self.haveToDispose():
if self.signalReceiver():
continue
if self.haveToDispose():
if self.signalReceiver():
continue
#===========================================================================
# add newly created entity to pendingEntities
......
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