Commit 623b2daa authored by Georgios Dagkakis's avatar Georgios Dagkakis Committed by Sebastien Robin

ExitJobShop updated so that the routed jobs can get out of the system

parent 5c913741
# ===========================================================================
# Copyright 2013 University of Limerick
#
# This file is part of DREAM.
#
# DREAM is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# DREAM is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with DREAM. If not, see <http://www.gnu.org/licenses/>.
# ===========================================================================
'''
Created on 2 oct 2012
@author: George
'''
'''
extends the Exit object so that it can act as a jobshop station. Preceding station is read from the Entity
'''
from SimPy.Simulation import Process, Resource
from SimPy.Simulation import activate, passivate, waituntil, now, hold
from Exit import Exit
#the ExitJobShop object
class ExitJobShop(Exit):
#checks if the Exit can accept an entity and there is an entity waiting for it
def canAcceptAndIsRequested(self):
from Globals import G
#loop through the objects to see if there is one that holds an Entity requesting for current object
for obj in G.ObjList:
if len(obj.Res.activeQ)>0 and now()!=0:
activeEntity=obj.Res.activeQ[0]
if activeEntity.remainingRoute[0][0]==self.id:
self.previousStation=obj
return self.previousStation.haveToDispose(self)
return False
#gets an entity from the previous station
def getEntity(self):
name=self.previousStation.Res.activeQ[0].name #get the name of the entity for the trace
self.totalLifespan+=now()-self.previousStation.Res.activeQ[0].startTime #Add the entity's lifespan to the total one.
self.previousStation.removeEntity() #remove the entity from the previous object
self.outputTrace(name)
\ No newline at end of file
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
"confidenceLevel": "0.95", "confidenceLevel": "0.95",
"maxSimTime": "1440", "maxSimTime": "1440",
"numberOfReplications": "2", "numberOfReplications": "2",
"trace": "Yes" "trace": "No"
}, },
"nodes": { "nodes": {
"DummyQ": { "DummyQ": {
......
...@@ -84,7 +84,7 @@ ...@@ -84,7 +84,7 @@
"capacity": "1000" "capacity": "1000"
}, },
"E1": { "E1": {
"_class": "Dream.Exit", "_class": "Dream.ExitJobShop",
"name": "Exit" "name": "Exit"
}, },
"J1": { "J1": {
......
...@@ -84,7 +84,7 @@ ...@@ -84,7 +84,7 @@
"capacity": "1000" "capacity": "1000"
}, },
"E1": { "E1": {
"_class": "Dream.Exit", "_class": "Dream.ExitJobShop",
"name": "Exit" "name": "Exit"
}, },
"J1": { "J1": {
......
{
"_class": "Dream.Simulation",
"edges": {
"0": [
"Q1",
"M1",
{}
],
"1": [
"Q2",
"M2",
{}
],
"2": [
"Q3",
"M3",
{}
]
},
"general": {
"_class": "Dream.Configuration",
"numberOfReplications": "1",
"maxSimTime": "1000",
"trace": "Yes",
"confidenceLevel": "0.95"
},
"nodes": {
"M1": {
"_class": "Dream.MachineJobShop",
"name": "Machine1",
"processingTime": {
"distributionType": "Fixed",
"mean": "0.25"
},
"failures": {
"failureDistribution": "No",
"MTTF": "60",
"MTTR": "5"
}
},
"M2": {
"_class": "Dream.MachineJobShop",
"name": "Machine2",
"processingTime": {
"distributionType": "Fixed",
"mean": "1.5"
},
"failures": {
"failureDistribution": "No",
"MTTF": "40",
"MTTR": "10"
}
},
"M3": {
"_class": "Dream.MachineJobShop",
"name": "Machine3",
"processingTime": {
"distributionType": "Fixed",
"mean": "1.5"
},
"failures": {
"failureDistribution": "No",
"MTTF": "40",
"MTTR": "10"
}
},
"Q1": {
"_class": "Dream.QueueJobShop",
"name": "Queue1",
"isDummy": "0",
"capacity": "1000"
},
"Q2": {
"_class": "Dream.QueueJobShop",
"id": "Q2",
"name": "Queue2",
"isDummy": "0",
"capacity": "1000"
},
"Q3": {
"_class": "Dream.QueueJobShop",
"name": "Queue3",
"isDummy": "0",
"capacity": "1000"
},
"E1": {
"_class": "Dream.ExitJobShop",
"name": "Exit"
},
"J1": {
"_class": "Dream.Job",
"name": "Job1",
"route": [
{
"stationId": "Q1",
"processingTime": {
"distributionType": "Fixed",
"mean": "1"
}
},
{
"stationId": "Q3",
"processingTime": {
"distributionType": "Fixed",
"mean": "3"
}
},
{
"stationId": "Q2",
"processingTime": {
"distributionType": "Fixed",
"mean": "2"
}
},
{
"stationId": "E1",
"processingTime": {
"distributionType": "Fixed",
"mean": "0"
}
}
]
},
"J2": {
"_class": "Dream.Job",
"name": "Job2",
"route": [
{
"stationId": "Q2",
"processingTime": {
"distributionType": "Fixed",
"mean": "3"
}
},
{
"stationId": "Q3",
"processingTime": {
"distributionType": "Fixed",
"mean": "1"
}
},
{
"stationId": "Q2",
"processingTime": {
"distributionType": "Fixed",
"mean": "7"
}
},
{
"stationId": "E1",
"processingTime": {
"distributionType": "Fixed",
"mean": "0"
}
}
]
},
"J3": {
"_class": "Dream.Job",
"name": "Job3",
"route": [
{
"stationId": "Q2",
"processingTime": {
"distributionType": "Fixed",
"mean": "2"
}
},
{
"stationId": "Q3",
"processingTime": {
"distributionType": "Fixed",
"mean": "1"
}
},
{
"stationId": "E1",
"processingTime": {
"distributionType": "Fixed",
"mean": "0"
}
}
]
},
"J4": {
"_class": "Dream.Job",
"name": "Job4",
"route": [
{
"stationId": "Q2",
"processingTime": {
"distributionType": "Fixed",
"mean": "7"
}
},
{
"stationId": "E1",
"processingTime": {
"distributionType": "Fixed",
"mean": "0"
}
}
]
}
}
}
\ No newline at end of file
...@@ -33,7 +33,7 @@ from Entity import Entity ...@@ -33,7 +33,7 @@ from Entity import Entity
class Job(Entity): class Job(Entity):
type="Job" type="Job"
def __init__(self, name, id, route): def __init__(self, id, name, route):
Entity.__init__(self, name) Entity.__init__(self, name)
self.id=id self.id=id
self.fullRoute=route #the route that the job follows, also contains the processing times in each station self.fullRoute=route #the route that the job follows, also contains the processing times in each station
......
...@@ -66,7 +66,7 @@ from Conveyer import Conveyer ...@@ -66,7 +66,7 @@ from Conveyer import Conveyer
from Job import Job from Job import Job
from MachineJobShop import MachineJobShop from MachineJobShop import MachineJobShop
from QueueJobShop import QueueJobShop from QueueJobShop import QueueJobShop
#from ExitJobShop import ExitJobShop from ExitJobShop import ExitJobShop
import xlwt import xlwt
import xlrd import xlrd
import time import time
...@@ -116,6 +116,8 @@ def createObjects(): ...@@ -116,6 +116,8 @@ def createObjects():
G.WipList=[] G.WipList=[]
G.EntityList=[] G.EntityList=[]
G.MachineJobShopList=[] G.MachineJobShopList=[]
G.QueueJobShopList=[]
G.ExitJobShopList=[]
#loop through all the model resources #loop through all the model resources
#search for repairmen in order to create them #search for repairmen in order to create them
...@@ -204,6 +206,13 @@ def createObjects(): ...@@ -204,6 +206,13 @@ def createObjects():
G.ExitList.append(E) G.ExitList.append(E)
G.ObjList.append(E) G.ObjList.append(E)
elif objClass=='Dream.ExitJobShop':
id=element.get('id', 'not found')
name=element.get('name', 'not found')
E=ExitJobShop(id, name)
G.ExitJobShopList.append(E)
G.ObjList.append(E)
elif objClass=='Dream.Queue': elif objClass=='Dream.Queue':
id=element.get('id', 'not found') id=element.get('id', 'not found')
name=element.get('name', 'not found') name=element.get('name', 'not found')
...@@ -221,7 +230,7 @@ def createObjects(): ...@@ -221,7 +230,7 @@ def createObjects():
isDummy=bool(int(element.get('isDummy', '0'))) isDummy=bool(int(element.get('isDummy', '0')))
Q=QueueJobShop(id, name, capacity, isDummy) Q=QueueJobShop(id, name, capacity, isDummy)
Q.nextIds=getSuccessorList(id) Q.nextIds=getSuccessorList(id)
G.QueueList.append(Q) G.QueueJobShopList.append(Q)
G.ObjList.append(Q) G.ObjList.append(Q)
elif objClass=='Dream.QueueLIFO': elif objClass=='Dream.QueueLIFO':
...@@ -371,7 +380,8 @@ def setWIP(): ...@@ -371,7 +380,8 @@ def setWIP():
for obj in G.ObjList: for obj in G.ObjList:
if obj.id==objectId: if obj.id==objectId:
object=obj object=obj
object.Res.activeQ.append(entity) object.Res.activeQ.append(entity)
entity.remainingRoute[0][0]="" #remove data from the remaining route.
#the main script that is ran #the main script that is ran
def main(argv=[], input_data=None): def main(argv=[], input_data=None):
...@@ -410,18 +420,12 @@ def main(argv=[], input_data=None): ...@@ -410,18 +420,12 @@ def main(argv=[], input_data=None):
initialize() #initialize the simulation initialize() #initialize the simulation
initializeObjects() initializeObjects()
setWIP() setWIP()
activateObjects()
for obj in G.ObjList: for Q in G.QueueJobShopList:
pass pass
#print obj.id, obj.Res.activeQ, obj.haveToDispose(), obj.canAcceptAndIsRequested()
''' activateObjects()
if obj.type is "Machine":
print obj.next[0].id
if obj.type is "Queue":
print obj.previous[0].id
'''
simulate(until=G.maxSimTime) #start the simulation simulate(until=G.maxSimTime) #start the simulation
#carry on the post processing operations for every object in the topology #carry on the post processing operations for every object in the topology
......
...@@ -30,8 +30,6 @@ from SimPy.Simulation import activate, passivate, waituntil, now, hold ...@@ -30,8 +30,6 @@ from SimPy.Simulation import activate, passivate, waituntil, now, hold
from Machine import Machine from Machine import Machine
from RandomNumberGenerator import RandomNumberGenerator
#the MachineJobShop object #the MachineJobShop object
class MachineJobShop(Machine): class MachineJobShop(Machine):
......
...@@ -33,7 +33,7 @@ from CoreObject import CoreObject ...@@ -33,7 +33,7 @@ from CoreObject import CoreObject
#the Queue object #the Queue object
class Queue(CoreObject): class Queue(CoreObject):
def __init__(self, id, name, capacity, dummy): def __init__(self, id, name, capacity, dummy, schedulingRule="FIFO"):
Process.__init__(self) Process.__init__(self)
self.predecessorIndex=0 #holds the index of the predecessor from which the Queue will take an entity next self.predecessorIndex=0 #holds the index of the predecessor from which the Queue will take an entity next
self.successorIndex=0 #holds the index of the successor where the Queue will dispose an entity next self.successorIndex=0 #holds the index of the successor where the Queue will dispose an entity next
...@@ -50,6 +50,7 @@ class Queue(CoreObject): ...@@ -50,6 +50,7 @@ class Queue(CoreObject):
self.previousIds=[] #list with the ids of the previous objects in the flow self.previousIds=[] #list with the ids of the previous objects in the flow
self.type="Queue" #String that shows the type of object self.type="Queue" #String that shows the type of object
self.isDummy=dummy #Boolean that shows if it is the dummy first Queue self.isDummy=dummy #Boolean that shows if it is the dummy first Queue
self.schedulingRule=schedulingRule #the scheduling rule that the Queue follows
def initialize(self): def initialize(self):
Process.__init__(self) Process.__init__(self)
...@@ -83,9 +84,7 @@ class Queue(CoreObject): ...@@ -83,9 +84,7 @@ class Queue(CoreObject):
while 1: while 1:
yield waituntil, self, self.canAcceptAndIsRequested #wait until the Queue can accept an entity yield waituntil, self, self.canAcceptAndIsRequested #wait until the Queue can accept an entity
#and one predecessor requests it #and one predecessor requests it
self.getEntity() self.getEntity()
self.outputTrace("got into "+self.objName)
#if entity just got to the dummyQ set its startTime as the current time #if entity just got to the dummyQ set its startTime as the current time
if self.isDummy: if self.isDummy:
...@@ -141,10 +140,9 @@ class Queue(CoreObject): ...@@ -141,10 +140,9 @@ class Queue(CoreObject):
#removes an entity from the Object #removes an entity from the Object
def removeEntity(self): def removeEntity(self):
self.outputTrace("releases "+self.objName) self.outputTrace(self.Res.activeQ[0].name, "releases "+self.objName)
self.Res.activeQ.pop(0) self.Res.activeQ.pop(0)
#checks if the Queue can accept an entity and there is an entity in some predecessor waiting for it #checks if the Queue 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 #also updates the predecessorIndex to the one that is to be taken
def canAcceptAndIsRequested(self): def canAcceptAndIsRequested(self):
...@@ -169,14 +167,26 @@ class Queue(CoreObject): ...@@ -169,14 +167,26 @@ class Queue(CoreObject):
self.predecessorIndex=i self.predecessorIndex=i
maxTimeWaiting=timeWaiting maxTimeWaiting=timeWaiting
return len(self.Res.activeQ)<self.capacity and isRequested return len(self.Res.activeQ)<self.capacity and isRequested
#gets an entity from the predecessor that the predecessor index points to
def getEntity(self):
CoreObject.getEntity(self) #run the default behavior
self.outputTrace(self.Res.activeQ[-1].name, "got into "+self.objName)
self.sortEntities() #sort the Entities
#sorts the Entities of the Queue according to the scheduling rule
def sortEntities(self):
if self.schedulingRule=="FIFO":
pass
#outputs message to the trace.xls. Format is (Simulation Time | Entity Name | message) #outputs message to the trace.xls. Format is (Simulation Time | Entity Name | message)
def outputTrace(self, message): def outputTrace(self, entityName, 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
#handle the 3 columns #handle the 3 columns
G.traceSheet.write(G.traceIndex,0,str(now())) G.traceSheet.write(G.traceIndex,0,str(now()))
G.traceSheet.write(G.traceIndex,1,self.Res.activeQ[0].name) G.traceSheet.write(G.traceIndex,1,entityName)
G.traceSheet.write(G.traceIndex,2,message) G.traceSheet.write(G.traceIndex,2,message)
G.traceIndex+=1 #increment the row G.traceIndex+=1 #increment the row
#if we reach row 65536 we need to create a new sheet (excel limitation) #if we reach row 65536 we need to create a new sheet (excel limitation)
......
...@@ -22,7 +22,7 @@ Created on 1 oct 2012 ...@@ -22,7 +22,7 @@ Created on 1 oct 2012
@author: George @author: George
''' '''
''' '''
extends the Queue object so that it can act as a jobshop station. Preceding station from the Entity extends the Queue object so that it can act as a jobshop station. Preceding station is read from the Entity
''' '''
from SimPy.Simulation import Process, Resource from SimPy.Simulation import Process, Resource
...@@ -30,7 +30,6 @@ from SimPy.Simulation import activate, passivate, waituntil, now, hold ...@@ -30,7 +30,6 @@ from SimPy.Simulation import activate, passivate, waituntil, now, hold
from Queue import Queue from Queue import Queue
from RandomNumberGenerator import RandomNumberGenerator
#the MachineJobShop object #the MachineJobShop object
class QueueJobShop(Queue): class QueueJobShop(Queue):
...@@ -63,8 +62,12 @@ class QueueJobShop(Queue): ...@@ -63,8 +62,12 @@ class QueueJobShop(Queue):
def getEntity(self): def getEntity(self):
self.Res.activeQ.append(self.previousStation.Res.activeQ[0]) #get the entity from the previous object self.Res.activeQ.append(self.previousStation.Res.activeQ[0]) #get the entity from the previous object
#and put it in front of the activeQ #and put it in front of the activeQ
self.previousStation.removeEntity() #remove the entity from the previous object self.previousStation.removeEntity() #remove the entity from the previous object
self.Res.activeQ[0].remainingRoute[0][0]="" #remove data from the remaining route. self.Res.activeQ[-1].remainingRoute[0][0]="" #remove data from the remaining route.
#This is needed so that the Queue will not request again for the Entity #This is needed so that the Queue will not request again for the Entity
self.outputTrace(self.Res.activeQ[-1].name, "got into "+self.objName)
self.sortEntities() #sort the Entities according to the scheduling rule
\ No newline at end of file
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