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 @@
"confidenceLevel": "0.95",
"maxSimTime": "1440",
"numberOfReplications": "2",
"trace": "Yes"
"trace": "No"
},
"nodes": {
"DummyQ": {
......
......@@ -84,7 +84,7 @@
"capacity": "1000"
},
"E1": {
"_class": "Dream.Exit",
"_class": "Dream.ExitJobShop",
"name": "Exit"
},
"J1": {
......
......@@ -84,7 +84,7 @@
"capacity": "1000"
},
"E1": {
"_class": "Dream.Exit",
"_class": "Dream.ExitJobShop",
"name": "Exit"
},
"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
class Job(Entity):
type="Job"
def __init__(self, name, id, route):
def __init__(self, id, name, route):
Entity.__init__(self, name)
self.id=id
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
from Job import Job
from MachineJobShop import MachineJobShop
from QueueJobShop import QueueJobShop
#from ExitJobShop import ExitJobShop
from ExitJobShop import ExitJobShop
import xlwt
import xlrd
import time
......@@ -116,6 +116,8 @@ def createObjects():
G.WipList=[]
G.EntityList=[]
G.MachineJobShopList=[]
G.QueueJobShopList=[]
G.ExitJobShopList=[]
#loop through all the model resources
#search for repairmen in order to create them
......@@ -204,6 +206,13 @@ def createObjects():
G.ExitList.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':
id=element.get('id', 'not found')
name=element.get('name', 'not found')
......@@ -221,7 +230,7 @@ def createObjects():
isDummy=bool(int(element.get('isDummy', '0')))
Q=QueueJobShop(id, name, capacity, isDummy)
Q.nextIds=getSuccessorList(id)
G.QueueList.append(Q)
G.QueueJobShopList.append(Q)
G.ObjList.append(Q)
elif objClass=='Dream.QueueLIFO':
......@@ -371,7 +380,8 @@ def setWIP():
for obj in G.ObjList:
if obj.id==objectId:
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
def main(argv=[], input_data=None):
......@@ -410,18 +420,12 @@ def main(argv=[], input_data=None):
initialize() #initialize the simulation
initializeObjects()
setWIP()
activateObjects()
for obj in G.ObjList:
for Q in G.QueueJobShopList:
pass
#print obj.id, obj.Res.activeQ, obj.haveToDispose(), obj.canAcceptAndIsRequested()
'''
if obj.type is "Machine":
print obj.next[0].id
if obj.type is "Queue":
print obj.previous[0].id
'''
activateObjects()
simulate(until=G.maxSimTime) #start the simulation
#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
from Machine import Machine
from RandomNumberGenerator import RandomNumberGenerator
#the MachineJobShop object
class MachineJobShop(Machine):
......
......@@ -33,7 +33,7 @@ from CoreObject import CoreObject
#the Queue object
class Queue(CoreObject):
def __init__(self, id, name, capacity, dummy):
def __init__(self, id, name, capacity, dummy, schedulingRule="FIFO"):
Process.__init__(self)
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
......@@ -50,6 +50,7 @@ class Queue(CoreObject):
self.previousIds=[] #list with the ids of the previous objects in the flow
self.type="Queue" #String that shows the type of object
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):
Process.__init__(self)
......@@ -83,9 +84,7 @@ class Queue(CoreObject):
while 1:
yield waituntil, self, self.canAcceptAndIsRequested #wait until the Queue can accept an entity
#and one predecessor requests it
self.getEntity()
self.outputTrace("got into "+self.objName)
self.getEntity()
#if entity just got to the dummyQ set its startTime as the current time
if self.isDummy:
......@@ -141,10 +140,9 @@ class Queue(CoreObject):
#removes an entity from the Object
def removeEntity(self):
self.outputTrace("releases "+self.objName)
self.outputTrace(self.Res.activeQ[0].name, "releases "+self.objName)
self.Res.activeQ.pop(0)
#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
def canAcceptAndIsRequested(self):
......@@ -169,14 +167,26 @@ class Queue(CoreObject):
self.predecessorIndex=i
maxTimeWaiting=timeWaiting
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)
def outputTrace(self, message):
def outputTrace(self, entityName, 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,self.Res.activeQ[0].name)
G.traceSheet.write(G.traceIndex,1,entityName)
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)
......
......@@ -22,7 +22,7 @@ Created on 1 oct 2012
@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
......@@ -30,7 +30,6 @@ from SimPy.Simulation import activate, passivate, waituntil, now, hold
from Queue import Queue
from RandomNumberGenerator import RandomNumberGenerator
#the MachineJobShop object
class QueueJobShop(Queue):
......@@ -63,8 +62,12 @@ class QueueJobShop(Queue):
def getEntity(self):
self.Res.activeQ.append(self.previousStation.Res.activeQ[0]) #get the entity from the previous object
#and put it in front of the activeQ
self.previousStation.removeEntity() #remove the entity from the previous object
self.Res.activeQ[0].remainingRoute[0][0]="" #remove data from the remaining route.
self.previousStation.removeEntity() #remove the entity from the previous object
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
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