Commit 0fd23e97 authored by Georgios Dagkakis's avatar Georgios Dagkakis Committed by Jérome Perrin

Machine/QueueManagedJob added. These are JobShop Machine and Queue but they...

Machine/QueueManagedJob added. These are JobShop Machine and Queue but they read the operator from the Job. Testing needed. Also enhancement in how the Machine creates the OperatorPool
parent d57bc7ac
......@@ -92,6 +92,8 @@ from Mould import Mould
from OrderDecomposition import OrderDecomposition
from ConditionalBuffer import ConditionalBuffer
from MouldAssemblyBuffer import MouldAssemblyBuffer
from MachineManagedJob import MachineManagedJob
from QueueManagedJob import QueueManagedJob
import ExcelHandler
import time
......@@ -167,6 +169,9 @@ def createObjects():
G.ConditionalBufferList=[]
G.MouldAssemblyBufferList=[]
G.MouldAssemblyList=[]
G.MachineManagedJobList=[]
G.QueueManagedJobList=[]
G.ModelResourceList=[]
# -----------------------------------------------------------------------
# loop through all the model resources
......@@ -187,6 +192,7 @@ def createObjects():
R.coreObjectIds=getSuccessorList(id) # update the list of objects that the repairman repairs
# calling the getSuccessorList() method on the repairman
G.RepairmanList.append(R) # add the repairman to the RepairmanList
G.ModelResourceList.append(R)
elif resourceClass=='Dream.Operator':
id = element.get('id', 'not found') # get the id of the element / default 'not_found'
name = element.get('name', 'not found') # get the name of the element / default 'not_found'
......@@ -195,6 +201,7 @@ def createObjects():
O.coreObjectIds=getSuccessorList(id) # update the list of objects that the operator operates
# calling the getSuccesorList() method on the operator
G.OperatorsList.append(O) # add the operator to the RepairmanList
#G.ModelResourceList.append(O)
# -----------------------------------------------------------------------
# loop through all the model resources
# search for operatorPools in order to create them
......@@ -463,6 +470,76 @@ def createObjects():
G.OperatedMachineList.append(M) # add the machine to the operatedMachines List
G.ObjList.append(M)
elif objClass=='Dream.MachineManagedJob':
id=element.get('id', 'not found')
name=element.get('name', 'not found')
processingTime=element.get('processingTime', {})
distributionType=processingTime.get('distributionType', 'not found')
mean=float(processingTime.get('mean', '0'))
stdev=float(processingTime.get('stdev', '0'))
min=float(processingTime.get('min', '0'))
max=float(processingTime.get('max', '0'))
failures=element.get('failures', {})
failureDistribution=failures.get('failureDistribution', 'not found')
MTTF=float(failures.get('MTTF', '0'))
MTTR=float(failures.get('MTTR', '0'))
availability=float(failures.get('availability', '0'))
# type of operation and related times
operationType=element.get('operationType','not found')
setupTime = element.get('setupTime',{})
setupDistribution = setupTime.get('setupDistribution','not found')
setupMean = float(setupTime.get('setupMean','0'))
setupStdev=float(setupTime.get('setupStdev', '0'))
setupMin=float(setupTime.get('setupMin', '0'))
setupMax=float(setupTime.get('setupMax', '0'))
loadTime = element.get('loadTime',{})
loadDistribution = loadTime.get('loadDistribution','not found')
loadMean = float(loadTime.get('loadMean','0'))
loadStdev = float(loadTime.get('loadStdev', '0'))
loadMin=float(loadTime.get('loadMin', '0'))
loadMax=float(loadTime.get('loadMax', '0'))
preemption=element.get('preemption',{})
isPreemptive=resetOnPreemption=False
if len(preemption)>0:
isPreemptive=bool(int(preemption.get('isPreemptive', 0)))
resetOnPreemption=bool(int(preemption.get('resetOnPreemption', 0)))
if len(G.OperatorPoolsList)>0:
for operatorPool in G.OperatorPoolsList: # find the operatorPool assigned to the machine
if(id in operatorPool.coreObjectIds): # and add it to the machine's operatorPool
machineOperatorPoolList=operatorPool # there must only one operator pool assigned to the machine,
# otherwise only one of them will be taken into account
else:
machineOperatorPoolList=[] # if there is no operatorPool assigned to the machine
else: # then machineOperatorPoolList/operatorPool is a list
machineOperatorPoolList=[] # if there are no operatorsPool created then the
# then machineOperatorPoolList/operatorPool is a list
if (type(machineOperatorPoolList) is list): # if the machineOperatorPoolList is a list
# find the operators assigned to it and add them to the list
for operator in G.OperatorsList: # check which operator in the G.OperatorsList
if(id in operator.coreObjectIds): # (if any) is assigned to operate
machineOperatorPoolList.append(operator) # the machine with ID equal to id
# if there is no operator assigned then the list will be empty
r='None'
for repairman in G.RepairmanList:
if(id in repairman.coreObjectIds):
r=repairman
M=MachineManagedJob(id, name, 1, distribution=distributionType, failureDistribution=failureDistribution,
MTTF=MTTF, MTTR=MTTR, availability=availability, #repairman=r,
mean=mean,stdev=stdev,min=min,max=max,
operatorPool=machineOperatorPoolList, operationType=operationType,
loadDistribution=loadDistribution, setupDistribution=setupDistribution,
setupMean=setupMean,setupStdev=setupStdev,setupMin=setupMin,setupMax=setupMax,
loadMean=loadMean,loadStdev=loadStdev,loadMin=loadMin,loadMax=loadMax,
repairman=r, isPreemptive=isPreemptive, resetOnPreemption=resetOnPreemption)
M.nextIds=getSuccessorList(id)
G.MachineManagedJobList.append(M)
G.MachineJobShopList.append(M)
G.MachineList.append(M)
if M.operatorPool!="None":
G.OperatedMachineList.append(M) # add the machine to the operatedMachines List
G.ObjList.append(M)
elif objClass=='Dream.Exit':
id=element.get('id', 'not found')
......@@ -501,6 +578,19 @@ def createObjects():
G.QueueList.append(Q)
G.QueueJobShopList.append(Q)
G.ObjList.append(Q)
elif objClass=='Dream.QueueManagedJob':
id=element.get('id', 'not found')
name=element.get('name', 'not found')
capacity=int(element.get('capacity', '1'))
isDummy=bool(int(element.get('isDummy', '0')))
schedulingRule=element.get('schedulingRule', 'FIFO')
Q=QueueManagedJob(id, name, capacity, isDummy, schedulingRule=schedulingRule)
Q.nextIds=getSuccessorList(id)
G.QueueList.append(Q)
G.QueueManagedJobList.append(Q)
G.QueueJobShopList.append(Q)
G.ObjList.append(Q)
elif objClass=='Dream.QueueLIFO':
id=element.get('id', 'not found')
......@@ -878,7 +968,7 @@ def setTopology():
def initializeObjects():
for element in G.ObjList:
element.initialize()
for repairman in G.RepairmanList:
for repairman in G.ModelResourceList:
repairman.initialize()
for entity in G.EntityList:
entity.initialize()
......@@ -1269,7 +1359,7 @@ def main(argv=[], input_data=None):
element.postProcessing()
#carry on the post processing operations for every model resource in the topology
for model_resource in G.RepairmanList:
for model_resource in G.ModelResourceList:
model_resource.postProcessing()
#output trace to excel
......@@ -1288,7 +1378,7 @@ def main(argv=[], input_data=None):
element.outputResultsJSON()
#output data to JSON for every resource in the topology
for model_resource in G.RepairmanList:
for model_resource in G.ModelResourceList:
model_resource.outputResultsJSON()
for job in G.JobList:
......
......@@ -77,16 +77,20 @@ class Machine(CoreObject):
the list of operators provided
if the list is empty create operator pool with empty list
'''
if (type(operatorPool) is list): #and len(operatorPool)>0:
if (type(operatorPool) is list) and len(operatorPool)>0:
id = id+'_OP'
name=self.objName+'_operatorPool'
self.operatorPool=OperatorPool(id, name, operatorsList=operatorPool)
elif(type(operatorPool) is OperatorPool):
self.operatorPool=operatorPool
else:
self.operatorPool=operatorPool
self.operatorPool='None'
#self.operatorPool=operatorPool
#print operatorPool
# update the operatorPool coreObjects list
if self.operatorPool!='None':
self.operatorPool.coreObjectIds.append(self.id)
self.operatorPool.coreObjects.append(self)
self.operatorPool.coreObjectIds.append(self.id)
self.operatorPool.coreObjects.append(self)
# holds the Operator currently processing the Machine
self.currentOperator=None
# define if load/setup/removal/processing are performed by the operator
......
# ===========================================================================
# 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 4 Feb 2014
@author: George
'''
'''
inherits from MachineJobShop. The difference is that it reads the operator from the Entity and
checks if he is available before it takes it
'''
from SimPy.Simulation import Process, Resource, activate, now
from OperatedPoolBroker import Broker
from OperatorPool import OperatorPool
from MachineJobShop import MachineJobShop
# ===========================================================================
# the MachineManagedJob object
# ===========================================================================
class MachineManagedJob(MachineJobShop):
# =======================================================================
# initialize the MachineManagedJob
# =======================================================================
def initialize(self):
MachineJobShop.initialize(self)
#creat an empty Operator Pool. This will be updated by canAcceptAndIsRequested
id = self.id+'_OP'
name=self.objName+'_operatorPool'
self.operatorPool=OperatorPool(id, name, operatorsList=[])
self.operatorPool.initialize()
#create a Broker
self.broker = Broker(self)
activate(self.broker,self.broker.run())
# =======================================================================
# checks if the Machine can accept an entity and there is an entity in
# some possible giver waiting for it
# also updates the giver to the one that is to be taken
# =======================================================================
def canAcceptAndIsRequested(self):
# get active and giver objects
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 the machine has to compete for an Operator that loads the entities onto it
# check if the predecessor if blocked by an other Machine
# if not then the machine has to block the predecessor giverObject to avoid conflicts
# with other competing machines
if(len(activeObject.previous)==1):
if (any(type=='Load' for type in activeObject.multOperationTypeList)):
if activeObject.Up and len(activeObjectQueue)<activeObject.capacity\
and giverObject.haveToDispose(activeObject) and not giverObject.exitIsAssigned():
activeObject.giver.assignExit()
#make the operatorsList so that it holds only the manager of the current order
activeObject.operatorPool.operatorsList=[activeObject.giver.getActiveObjectQueue()[0].manager]
return True
else:
return False
# dummy variables that help prioritise the objects requesting to give objects to the Machine (activeObject)
isRequested=False # is requested is dummyVariable checking if it is requested to accept an item
maxTimeWaiting=0 # dummy variable counting the time a predecessor is blocked
# loop through the possible givers to see which have to dispose and which is the one blocked for longer
for object in activeObject.previous:
if(object.haveToDispose(activeObject) and object.receiver==self):# and not object.exitIsAssigned()):
isRequested=True # if the possible giver has entities to dispose of
if(object.downTimeInTryingToReleaseCurrentEntity>0):# and the possible giver has been down while trying to give away the Entity
timeWaiting=now()-object.timeLastFailureEnded # the timeWaiting dummy variable counts the time end of the last failure of the giver object
else:
timeWaiting=now()-object.timeLastEntityEnded # in any other case, it holds the time since the end of the Entity processing
#if more than one possible givers have to dispose take the part from the one that is blocked longer
if(timeWaiting>=maxTimeWaiting):
activeObject.giver=object # set the giver
maxTimeWaiting=timeWaiting
if (activeObject.operatorPool!='None' and (any(type=='Load' for type in activeObject.multOperationTypeList)\
or any(type=='Setup' for type in activeObject.multOperationTypeList))):
if isRequested:
# TODO:
# check whether this entity is the one to be hand in
# to be used in operatorPreemptive
activeObject.requestingEntity=activeObject.giver.getActiveObjectQueue()[0]
# TODO:
# update the object requesting the operator
activeObject.operatorPool.requestingObject=activeObject.giver
# TODOD:
# update the last object calling the operatorPool
activeObject.operatorPool.receivingObject=activeObject
if activeObject.operatorPool.checkIfResourceIsAvailable()\
and activeObject.Up and len(activeObjectQueue)<activeObject.capacity\
and isRequested and not activeObject.giver.exitIsAssigned():
activeObject.giver.assignExit()
#make the operatorsList so that it holds only the manager of the current order
activeObject.operatorPool.operatorsList=[activeObject.giver.getActiveObjectQueue()[0].manager]
return True
else:
return False
else:
# the operator doesn't have to be present for the loading of the machine as the load operation
# is not assigned to operators
return activeObject.Up and len(activeObjectQueue)<activeObject.capacity and isRequested
# while if the set up is performed before the (automatic) loading of the machine then the availability of the
# operator is requested
# return (activeObject.operatorPool=='None' or activeObject.operatorPool.checkIfResourceIsAvailable())\
# and activeObject.Up and len(activeObjectQueue)<activeObject.capacity and isRequested
\ No newline at end of file
# ===========================================================================
# 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 4 Feb 2014
@author: George
'''
'''
inherits from QueueJobShop. The difference is that it reads the operator from the Entity and
checks if he is available before it disposed it
'''
from SimPy.Simulation import now
from QueueJobShop import QueueJobShop
# ===========================================================================
# the QueueManagedJob object
# ===========================================================================
class QueueManagedJob(QueueJobShop):
# =======================================================================
# checks if the Queue can dispose an entity.
# Returns True only to the potential receiver
# =======================================================================
def haveToDispose(self, callerObject=None):
# get active object and its queue
activeObject=self.getActiveObject()
activeObjectQueue=self.getActiveObjectQueue()
thecaller = callerObject
#search if for one or more of the Entities the operator is available
haveEntityWithAvailableManager=False
for entity in activeObjectQueue:
if entity.manager:
if entity.manager.checkIfResourceIsAvailable:
haveEntityWithAvailableManager=True
#if none of the Entities has an available manager return False
if not haveEntityWithAvailableManager:
return False
#sort the internal queue so that the Entities that have an available manager go in the front
self.sortEntities()
#if we have only one possible receiver just check if the Queue holds one or more entities
if(len(activeObject.next)==1 or callerObject==None):
activeObject.receiver=activeObject.next[0]
return len(activeObjectQueue)>0\
and thecaller==activeObject.receiver
#give the entity to the possible receiver that is waiting for the most time.
maxTimeWaiting=0
# loop through the object in the successor list
for object in activeObject.next:
if(object.canAccept(activeObject)): # if the object can accept
timeWaiting=now()-object.timeLastEntityLeft # compare the time that it has been waiting
if(timeWaiting>maxTimeWaiting or maxTimeWaiting==0):# with the others'
maxTimeWaiting=timeWaiting
self.receiver=object # and update the receiver to the index of this object
#return True if the Queue has Entities and the caller is the receiver
return len(activeObjectQueue)>0 and (thecaller is self.receiver)
\ 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