Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
dream
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
1
Issues
1
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
dream
Commits
c469da69
Commit
c469da69
authored
Mar 26, 2015
by
Georgios Dagkakis
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
OperatedMachine removed. It has been long merged to standard Machine
parent
f0f1e189
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
0 additions
and
596 deletions
+0
-596
dream/simulation/OperatedMachine.py
dream/simulation/OperatedMachine.py
+0
-596
No files found.
dream/simulation/OperatedMachine.py
deleted
100644 → 0
View file @
f0f1e189
# ===========================================================================
# 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 22 Nov 2012
@author: Ioannis
'''
'''
Models a machine that can also have failures
'''
# XXX
#from SimPy.Simulation import activate, passivate, waituntil, hold, request, release
from
Failure
import
Failure
# from CoreObject import CoreObject
from
Machine
import
Machine
from
OperatedPoolBroker
import
Broker
from
OperatorPool
import
OperatorPool
from
RandomNumberGenerator
import
RandomNumberGenerator
# ===========================================================================
# the Machine object
# ===========================================================================
class
OperatedMachine
(
Machine
):
# =======================================================================
# initialise the id the capacity, of the resource and the distribution
# =======================================================================
def
__init__
(
self
,
id
,
name
,
capacity
=
1
,
processingTime
=
None
,
failureDistribution
=
'No'
,
MTTF
=
0
,
MTTR
=
0
,
availability
=
0
,
repairman
=
'None'
,
\
operatorPool
=
'None'
,
operationType
=
'None'
,
setupTime
=
None
,
loadTime
=
None
):
Machine
.
__init__
(
self
,
id
,
name
,
capacity
=
capacity
,
processingTime
=
processingTime
,
failureDistribution
=
failureDistribution
,
MTTF
=
MTTF
,
MTTR
=
MTTR
,
availability
=
availability
,
repairman
=
repairman
,
operatorPool
=
operatorPool
,
operationType
=
operationType
,
setupTime
=
setupTime
,
loadTime
=
loadTime
,)
# type of the machine
self
.
type
=
"OperatedMachine"
# sets the operator resource of the Machine
# check if the operatorPool is a List or a OperatorPool type Object
# if it is a list then initiate a OperatorPool type object containing
# the list of operators provided
'''
change! if the list is empty create operator pool with empty list
'''
if
(
type
(
operatorPool
)
is
list
):
#and len(operatorPool)>0:
id
=
id
+
'_OP'
name
=
self
.
objName
+
'_operatorPool'
self
.
operatorPool
=
OperatorPool
(
id
,
name
,
operatorsList
=
operatorPool
)
else
:
self
.
operatorPool
=
operatorPool
# update the operatorPool coreObjects list
if
self
.
operatorPool
!=
'None'
:
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
self
.
operationType
=
operationType
# boolean to check weather the machine is being operated
self
.
toBeOperated
=
False
# examine if there are multiple operation types performed by the operator
# there can be Setup/Processing operationType
# or the combination of both (MT-Load-Setup-Processing)
self
.
multOperationTypeList
=
[]
if
self
.
operationType
.
startswith
(
"MT"
):
OTlist
=
operationType
.
split
(
'-'
)
self
.
operationType
=
OTlist
.
pop
(
0
)
self
.
multOperationTypeList
=
OTlist
else
:
self
.
multOperationTypeList
.
append
(
self
.
operationType
)
# lists to hold statistics of multiple runs
self
.
WaitingForOperator
=
[]
self
.
WaitingForLoadOperator
=
[]
self
.
Loading
=
[]
self
.
SettingUp
=
[]
# =======================================================================
# initialize the machine
# =======================================================================
def
initialize
(
self
):
Machine
.
initialize
(
self
)
# initiate the Broker responsible to control the request/release
# initialize the operator pool if any
if
(
self
.
operatorPool
!=
"None"
):
self
.
operatorPool
.
initialize
()
self
.
broker
=
Broker
(
self
)
activate
(
self
.
broker
,
self
.
broker
.
run
())
for
operator
in
self
.
operatorPool
.
operators
:
operator
.
coreObjectIds
.
append
(
self
.
id
)
operator
.
coreObjects
.
append
(
self
)
# the time that the machine started/ended its wait for the operator
self
.
timeWaitForOperatorStarted
=
0
self
.
timeWaitForOperatorEnded
=
0
self
.
totalTimeWaitingForOperator
=
0
# the time that the machine started/ended its wait for the operator
self
.
timeWaitForLoadOperatorStarted
=
0
self
.
timeWaitForLoadOperatorEnded
=
0
self
.
totalTimeWaitingForLoadOperator
=
0
# the time that the operator started/ended loading the machine
self
.
timeLoadStarted
=
0
self
.
timeLoadEnded
=
0
self
.
totalLoadTime
=
0
# the time that the operator started/ended setting-up the machine
self
.
timeSetupStarted
=
0
self
.
timeSetupEnded
=
0
self
.
totalSetupTime
=
0
# Current entity load/setup/loadOperatorwait/operatorWait related times
self
.
operatorWaitTimeCurrentEntity
=
0
# holds the time that the machine was waiting for the operator
self
.
loadOperatorWaitTimeCurrentEntity
=
0
# holds the time that the machine waits for operator to load the it
self
.
loadTimeCurrentEntity
=
0
# holds the time to load the current entity
self
.
setupTimeCurrentEntity
=
0
# holds the time to setup the machine before processing the current entity
# =======================================================================
# the main process of the machine
# =======================================================================
def
run
(
self
):
# execute all through simulation time
while
1
:
# wait until the machine can accept an entity and one predecessor requests it
# canAcceptAndIsRequested is invoked to check when the machine requested to receive an entity
yield
waituntil
,
self
,
self
.
canAcceptAndIsRequested
# here or in the get entity (apart from the loatTimeCurrentEntity)
# in case they are placed inside the getEntity then the initialize of
# the corresponding variables should be moved to the initialize() of the CoreObject
self
.
operatorWaitTimeCurrentEntity
=
0
self
.
loadOperatorWaitTimeCurrentEntity
=
0
self
.
loadTimeCurrentEntity
=
0
self
.
setupTimeCurrentEntity
=
0
# ======= request a resource
if
(
self
.
operatorPool
!=
"None"
)
and
any
(
type
==
'Load'
for
type
in
self
.
multOperationTypeList
):
# when it's ready to accept (canAcceptAndIsRequested) then inform the broker
# machines waits to be operated (waits for the operator)
self
.
requestOperator
()
self
.
timeWaitForLoadOperatorStarted
=
self
.
env
.
now
# wait until the Broker has waited times equal to loadTime (if any)
yield
waituntil
,
self
,
self
.
broker
.
brokerIsSet
self
.
timeWaitForLoadOperatorEnded
=
self
.
env
.
now
self
.
loadOperatorWaitTimeCurrentEntity
+=
self
.
timeWaitForLoadOperatorEnded
-
self
.
timeWaitForLoadOperatorStarted
self
.
totalTimeWaitingForLoadOperator
+=
self
.
loadOperatorWaitTimeCurrentEntity
# ======= Load the machine if the Load is defined as one of the Operators' operation types
if
any
(
type
==
"Load"
for
type
in
self
.
multOperationTypeList
)
and
self
.
isOperated
():
self
.
timeLoadStarted
=
self
.
env
.
now
yield
hold
,
self
,
self
.
calculateLoadTime
()
# if self.interrupted(): There is the issue of failure during the Loading
self
.
timeLoadEnded
=
self
.
env
.
now
self
.
loadTimeCurrentEntity
=
self
.
timeLoadEnded
-
self
.
timeLoadStarted
self
.
totalLoadTime
+=
self
.
loadTimeCurrentEntity
# ======= release a resource if the only operation type is Load
if
(
self
.
operatorPool
!=
"None"
)
\
and
any
(
type
==
"Load"
for
type
in
self
.
multOperationTypeList
)
\
and
not
any
(
type
==
"Processing"
or
type
==
"Setup"
for
type
in
self
.
multOperationTypeList
)
\
and
self
.
isOperated
():
# after getting the entity release the operator
# machine has to release the operator
self
.
releaseOperator
()
# wait until the Broker has finished processing
yield
waituntil
,
self
,
self
.
broker
.
brokerIsSet
# get the entity
# if there was loading time then we must solve the problem of getting an entity
# from an unidentified giver or not getting an entity at all as the giver
# may fall in failure mode
self
.
currentEntity
=
self
.
getEntity
()
# set the currentEntity as the Entity just received and initialize the timer timeLastEntityEntered
self
.
nameLastEntityEntered
=
self
.
currentEntity
.
name
# this holds the name of the last entity that got into Machine
self
.
timeLastEntityEntered
=
self
.
env
.
now
#this holds the last time that an entity got into Machine
# variables dedicated to hold the processing times, the time when the Entity entered,
# and the processing time left
timeEntered
=
self
.
env
.
now
# timeEntered dummy Timer that holds the time the last Entity Entered
# ======= request a resource if it is not already assigned an Operator
if
(
self
.
operatorPool
!=
"None"
)
\
and
any
(
type
==
"Processing"
or
type
==
"Setup"
for
type
in
self
.
multOperationTypeList
)
\
and
not
self
.
isOperated
():
# when it's ready to accept (canAcceptAndIsRequested) then inform the broker
# machines waits to be operated (waits for the operator)
self
.
requestOperator
()
self
.
timeWaitForOperatorStarted
=
self
.
env
.
now
# wait until the Broker has waited times equal to loadTime (if any)
yield
waituntil
,
self
,
self
.
broker
.
brokerIsSet
self
.
timeWaitForOperatorEnded
=
self
.
env
.
now
self
.
operatorWaitTimeCurrentEntity
+=
self
.
timeWaitForOperatorEnded
-
self
.
timeWaitForOperatorStarted
self
.
totalProcessingTimeInCurrentEntity
=
self
.
calculateProcessingTime
()
# get the processing time, tinMStarts holds the processing time of the machine
tinM
=
self
.
totalProcessingTimeInCurrentEntity
# timer to hold the processing time left
# ======= setup the machine if the Setup is defined as one of the Operators' operation types
# in plantSim the setup is performed when the machine has to process a new type of Entity and only once
if
any
(
type
==
"Setup"
for
type
in
self
.
multOperationTypeList
)
and
self
.
isOperated
():
self
.
timeSetupStarted
=
self
.
env
.
now
yield
hold
,
self
,
self
.
calculateSetupTime
()
# if self.interrupted(): There is the issue of failure during the setup
self
.
timeSetupEnded
=
self
.
env
.
now
self
.
setupTimeCurrentEntity
=
self
.
timeSetupEnded
-
self
.
timeSetupStarted
self
.
totalSetupTime
+=
self
.
setupTimeCurrentEntity
# ======= release a resource if the only operation type is Setup
if
(
self
.
operatorPool
!=
"None"
)
\
and
self
.
isOperated
()
\
and
any
(
type
==
"Setup"
or
type
==
"Load"
for
type
in
self
.
multOperationTypeList
)
\
and
not
any
(
type
==
"Processing"
for
type
in
self
.
multOperationTypeList
):
# after getting the entity release the operator
# machine has to release the operator
self
.
releaseOperator
()
# print self.objName, 'operator released', self.env.now
# wait until the Broker has finished processing
yield
waituntil
,
self
,
self
.
broker
.
brokerIsSet
# variables used to flag any interruptions and the end of the processing
interruption
=
False
processingEndedFlag
=
True
# timers to follow up the failure time of the machine while on current Entity
failureTime
=
0
# dummy variable keeping track of the failure time
# might be feasible to avoid it
self
.
downTimeInCurrentEntity
=
0
#holds the total time that the
#object was down while holding current entity
# this loop is repeated until the processing time is expired with no failure
# check when the processingEndedFlag switched to false
while
processingEndedFlag
:
# tBefore : dummy variable to keep track of the time that the processing starts after
# every interruption
tBefore
=
self
.
env
.
now
# wait for the processing time left tinM, if no interruption occurs then change the
# processingEndedFlag and exit loop,
# else (if interrupted()) set interruption flag to true (only if tinM==0),
# and recalculate the processing time left tinM,
# passivate while waiting for repair.
yield
hold
,
self
,
tinM
# getting processed for remaining processing time tinM
if
self
.
interrupted
():
# if a failure occurs while processing the machine is interrupted.
# output to trace that the Machine (self.objName) got interrupted
self
.
outputTrace
(
self
.
getActiveObjectQueue
()[
0
].
name
,
"Interrupted at "
+
self
.
objName
)
# recalculate the processing time left tinM
tinM
=
tinM
-
(
self
.
env
.
now
-
tBefore
)
if
(
tinM
==
0
):
# sometimes the failure may happen exactly at the time that the processing would finish
# this may produce disagreement with the simul8 because in both SimPy and Simul8
# it seems to be random which happens 1st
# this should not appear often to stochastic models though where times are random
interruption
=
True
# passivate the Machine for as long as there is no repair
# start counting the down time at breatTime dummy variable
breakTime
=
self
.
env
.
now
# dummy variable that the interruption happened
# =============== release the operator if there is failure
if
(
self
.
operatorPool
!=
"None"
)
\
and
self
.
isOperated
()
\
and
any
(
type
==
"Processing"
for
type
in
self
.
multOperationTypeList
):
self
.
releaseOperator
()
# print self.objName, 'operator released due to failure', self.env.now
yield
waituntil
,
self
,
self
.
broker
.
brokerIsSet
# if there is a failure in the machine it is passivated
yield
passivate
,
self
# use the timers to count the time that Machine is down and related
self
.
downTimeProcessingCurrentEntity
+=
self
.
env
.
now
-
breakTime
# count the time that Machine is down while processing this Entity
self
.
downTimeInCurrentEntity
+=
self
.
env
.
now
-
breakTime
# count the time that Machine is down while on currentEntity
self
.
timeLastFailureEnded
=
self
.
env
.
now
# set the timeLastFailureEnded
failureTime
+=
self
.
env
.
now
-
breakTime
# dummy variable keeping track of the failure time
# output to trace that the Machine self.objName was passivated for the current failure time
self
.
outputTrace
(
self
.
getActiveObjectQueue
()[
0
].
name
,
"passivated in "
+
self
.
objName
+
" for "
+
str
(
self
.
env
.
now
-
breakTime
))
# =============== request a resource after the repair
if
(
self
.
operatorPool
!=
"None"
)
\
and
any
(
type
==
"Processing"
for
type
in
self
.
multOperationTypeList
)
\
and
not
interruption
:
self
.
timeWaitForOperatorStarted
=
self
.
env
.
now
self
.
requestOperator
()
yield
waituntil
,
self
,
self
.
broker
.
brokerIsSet
self
.
timeWaitForOperatorEnded
=
self
.
env
.
now
self
.
operatorWaitTimeCurrentEntity
+=
self
.
timeWaitForOperatorEnded
-
self
.
timeWaitForOperatorStarted
# if no interruption occurred the processing in M1 is ended
else
:
processingEndedFlag
=
False
# output to trace that the processing in the Machine self.objName ended
self
.
outputTrace
(
self
.
getActiveObjectQueue
()[
0
].
name
,
"ended processing in "
+
self
.
objName
)
# =============== release resource after the end of processing
if
(
self
.
operatorPool
!=
'None'
)
\
and
any
(
type
==
"Processing"
for
type
in
self
.
multOperationTypeList
)
\
and
not
interruption
:
self
.
releaseOperator
()
yield
waituntil
,
self
,
self
.
broker
.
brokerIsSet
# set the variable that flags an Entity is ready to be disposed
self
.
waitToDispose
=
True
# update the total working time
self
.
totalWorkingTime
+=
self
.
totalProcessingTimeInCurrentEntity
# the total processing time for this entity
# is what the distribution initially gave
# update the variables keeping track of Entity related attributes of the machine
self
.
timeLastEntityEnded
=
self
.
env
.
now
# this holds the time that the last entity ended processing in Machine
self
.
nameLastEntityEnded
=
self
.
currentEntity
.
name
# this holds the name of the last entity that ended processing in Machine
self
.
completedJobs
+=
1
# Machine completed one more Job
# re-initialize the downTimeProcessingCurrentEntity.
# a new machine is about to enter
self
.
downTimeProcessingCurrentEntity
=
0
# dummy variable requests the successor object now
reqTime
=
self
.
env
.
now
# entity has ended processing in Machine and requests for the next object
# initialize the timer downTimeInTryingToReleaseCurrentEntity, we have to count how much time
# the Entity will wait for the next successor to be able to accept (canAccept)
self
.
downTimeInTryingToReleaseCurrentEntity
=
0
while
1
:
# wait until the next Object is available or machine has failure
yield
waituntil
,
self
,
self
.
ifCanDisposeOrHaveFailure
# if Next object available break
if
self
.
Up
:
break
# if M1 had failure, we want to wait until it is fixed and also count the failure time.
else
:
failTime
=
self
.
env
.
now
# dummy variable holding the time failure happened
# passivate until machine is up
yield
waituntil
,
self
,
self
.
checkIfMachineIsUp
failureTime
+=
self
.
env
.
now
-
failTime
# count the failure while on current entity time with failureTime variable
# calculate the time the Machine was down while trying to dispose the current Entity,
# and the total down time while on current Entity
self
.
downTimeInTryingToReleaseCurrentEntity
+=
self
.
env
.
now
-
failTime
self
.
downTimeInCurrentEntity
+=
self
.
env
.
now
-
failTime
# already updated from failures during processing
# update the timeLastFailureEnded
self
.
timeLastFailureEnded
=
self
.
env
.
now
# dummy variable holding the total time the Entity spent in the Machine
# count the time the Machine was blocked subtracting the failureTime
# and the processing time from the totalTime spent in the Machine
self
.
totalTimeInCurrentEntity
=
self
.
env
.
now
-
timeEntered
# =======================================================================
# checks if the Machine can accept an entity
# it checks also who called it and returns TRUE only to the predecessor
# that will give the entity.
# =======================================================================
def
canAccept
(
self
,
callerObject
=
None
):
# 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 and the machine is up
# this is done to achieve better (cpu) processing time
# then we can also use it as a filter for a yield method
if
(
len
(
activeObject
.
previous
)
==
1
or
callerObject
==
None
):
if
(
activeObject
.
operatorPool
!=
'None'
and
any
(
type
==
'Load'
for
type
in
activeObject
.
multOperationTypeList
)):
return
activeObject
.
operatorPool
.
checkIfResourceIsAvailable
()
\
and
activeObject
.
Up
\
and
len
(
activeObjectQueue
)
<
activeObject
.
capacity
else
:
return
activeObject
.
Up
and
len
(
activeObjectQueue
)
<
activeObject
.
capacity
\
thecaller
=
callerObject
# return True ONLY if the length of the activeOjbectQue is smaller than
# the object capacity, and the callerObject is not None but the giverObject
if
(
activeObject
.
operatorPool
!=
'None'
and
any
(
type
==
'Load'
for
type
in
activeObject
.
multOperationTypeList
)):
return
activeObject
.
operatorPool
.
checkIfResourceIsAvailable
()
\
and
activeObject
.
Up
\
and
len
(
activeObjectQueue
)
<
activeObject
.
capacity
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
# 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
# =======================================================================
# 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
(
activeObject
.
operatorPool
!=
'None'
and
any
(
type
==
'Load'
for
type
in
activeObject
.
multOperationTypeList
)):
if
activeObject
.
operatorPool
.
checkIfResourceIsAvailable
()
\
and
activeObject
.
Up
and
len
(
activeObjectQueue
)
<
activeObject
.
capacity
\
and
giverObject
.
haveToDispose
(
activeObject
)
and
not
giverObject
.
exitIsAssigned
():
activeObject
.
giver
.
assignExit
()
return
True
else
:
return
False
else
:
# the operator performs no load and the entity is received by the machine while there is
# no need for operators presence. The operator needs to be present only where the load Type
# operation is assigned
return
activeObject
.
Up
and
len
(
activeObjectQueue
)
<
activeObject
.
capacity
\
and
giverObject
.
haveToDispose
(
activeObject
)
# if the set-up performance needs be first performed before the transfer of the entity to
# the machine then the presence of an operator to setup the machine before the getEntity()
# is requested
# return (activeObject.operatorPool=='None'\
# or activeObject.operatorPool.checkIfResourceIsAvailable())\
# and activeObject.Up and len(activeObjectQueue)<activeObject.capacity\
# and giverObject.haveToDispose()
# 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 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
=
self
.
env
.
now
-
object
.
timeLastFailureEnded
# the timeWaiting dummy variable counts the time end of the last failure of the giver object
else
:
timeWaiting
=
self
.
env
.
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
)):
if
activeObject
.
operatorPool
.
checkIfResourceIsAvailable
()
\
and
activeObject
.
Up
and
len
(
activeObjectQueue
)
<
activeObject
.
capacity
\
and
isRequested
and
not
activeObject
.
giver
.
exitIsAssigned
():
activeObject
.
giver
.
assignExit
()
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
# =======================================================================
# calculates the setup time
# =======================================================================
def
calculateSetupTime
(
self
):
return
self
.
stpRng
.
generateNumber
()
# =======================================================================
# calculates the Load time
# =======================================================================
def
calculateLoadTime
(
self
):
return
self
.
loadRng
.
generateNumber
()
# =======================================================================
# prepare the machine to be operated
# =======================================================================
def
requestOperator
(
self
):
self
.
broker
.
invokeBroker
()
self
.
toBeOperated
=
True
# =======================================================================
# prepare the machine to be released
# =======================================================================
def
releaseOperator
(
self
):
self
.
broker
.
invokeBroker
()
self
.
toBeOperated
=
False
# =======================================================================
# check if the machine is currently operated by an operator
# =======================================================================
def
isOperated
(
self
):
return
self
.
toBeOperated
# =======================================================================
# check if the machine is already set-up
# =======================================================================
def
isSetUp
(
self
):
return
self
.
setUp
# =======================================================================
# request that the machine is set-up by an operator
# =======================================================================
def
requestSetup
(
self
):
self
.
setUp
=
False
# =======================================================================
# actions to be taken after the simulation ends
# =======================================================================
def
postProcessing
(
self
,
MaxSimtime
=
None
):
if
MaxSimtime
==
None
:
from
Globals
import
G
MaxSimtime
=
G
.
maxSimTime
activeObject
=
self
.
getActiveObject
()
activeObjectQueue
=
self
.
getActiveObjectQueue
()
alreadyAdded
=
False
# a flag that shows if the blockage time has already been added
# checks all the successors. If no one can accept an Entity then the machine might be blocked
mightBeBlocked
=
True
for
nextObject
in
self
.
next
:
if
nextObject
.
canAccept
():
mightBeBlocked
=
False
# if there is an entity that finished processing in a Machine 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 Machine
# we should exclude the failure time in current entity though!
# if (len(self.Res.activeQ)>0) and (len(self.next[0].Res.activeQ)>0) and ((self.nameLastEntityEntered == self.nameLastEntityEnded)):
if
(
len
(
activeObjectQueue
)
>
0
)
and
(
mightBeBlocked
)
\
and
((
activeObject
.
nameLastEntityEntered
==
activeObject
.
nameLastEntityEnded
)):
# be careful here, might have to reconsider
activeObject
.
totalBlockageTime
+=
self
.
env
.
now
-
(
activeObject
.
timeLastEntityEnded
+
activeObject
.
downTimeInTryingToReleaseCurrentEntity
)
if
activeObject
.
Up
==
False
:
activeObject
.
totalBlockageTime
-=
self
.
env
.
now
-
activeObject
.
timeLastFailure
alreadyAdded
=
True
#if Machine is currently processing an entity we should count this working time
if
(
len
(
activeObject
.
getActiveObjectQueue
())
>
0
)
\
and
(
not
(
activeObject
.
nameLastEntityEnded
==
activeObject
.
nameLastEntityEntered
))
\
and
(
not
(
activeObject
.
operationType
==
'Processing'
and
(
activeObject
.
currentOperator
==
None
))):
#if Machine is down we should add this last failure time to the time that it has been down in current entity
if
self
.
Up
==
False
:
# if(len(activeObjectQueue)>0) and (self.Up==False):
activeObject
.
downTimeProcessingCurrentEntity
+=
self
.
env
.
now
-
activeObject
.
timeLastFailure
activeObject
.
totalWorkingTime
+=
self
.
env
.
now
-
activeObject
.
timeLastEntityEntered
\
-
activeObject
.
downTimeProcessingCurrentEntity
\
-
activeObject
.
operatorWaitTimeCurrentEntity
\
-
activeObject
.
setupTimeCurrentEntity
activeObject
.
totalTimeWaitingForOperator
+=
activeObject
.
operatorWaitTimeCurrentEntity
elif
(
len
(
activeObject
.
getActiveObjectQueue
())
>
0
)
\
and
(
not
(
activeObject
.
nameLastEntityEnded
==
activeObject
.
nameLastEntityEntered
))
\
and
(
activeObject
.
currentOperator
==
None
):
# needs further research as the time of failure while waiting for operator is not counted yet
if
self
.
Up
==
False
:
activeObject
.
downTimeProcessingCurrentEntity
+=
self
.
env
.
now
-
activeObject
.
timeLastFailure
activeObject
.
totalTimeWaitingForOperator
+=
self
.
env
.
now
-
activeObject
.
timeWaitForOperatorStarted
\
-
activeObject
.
downTimeProcessingCurrentEntity
# if Machine is down we have to add this failure time to its total failure time
# we also need to add the last blocking time to total blockage time
if
(
activeObject
.
Up
==
False
):
activeObject
.
totalFailureTime
+=
self
.
env
.
now
-
activeObject
.
timeLastFailure
# we add the value only if it hasn't already been added
#if((len(self.next[0].Res.activeQ)>0) and (self.nameLastEntityEnded==self.nameLastEntityEntered) and (not alreadyAdded)):
if
((
mightBeBlocked
)
and
(
activeObject
.
nameLastEntityEnded
==
activeObject
.
nameLastEntityEntered
)
and
(
not
alreadyAdded
)):
activeObject
.
totalBlockageTime
+=
(
self
.
env
.
now
-
activeObject
.
timeLastEntityEnded
)
-
(
self
.
env
.
now
-
activeObject
.
timeLastFailure
)
-
activeObject
.
downTimeInTryingToReleaseCurrentEntity
#Machine was idle when it was not in any other state
activeObject
.
totalWaitingTime
=
MaxSimtime
-
activeObject
.
totalWorkingTime
-
activeObject
.
totalBlockageTime
-
activeObject
.
totalFailureTime
if
activeObject
.
totalBlockageTime
<
0
and
activeObject
.
totalBlockageTime
>-
0.00001
:
#to avoid some effects of getting negative cause of rounding precision
self
.
totalBlockageTime
=
0
if
activeObject
.
totalWaitingTime
<
0
and
activeObject
.
totalWaitingTime
>-
0.00001
:
#to avoid some effects of getting negative cause of rounding precision
self
.
totalWaitingTime
=
0
activeObject
.
Failure
.
append
(
100
*
self
.
totalFailureTime
/
MaxSimtime
)
activeObject
.
Blockage
.
append
(
100
*
self
.
totalBlockageTime
/
MaxSimtime
)
activeObject
.
Waiting
.
append
(
100
*
self
.
totalWaitingTime
/
MaxSimtime
)
activeObject
.
Working
.
append
(
100
*
self
.
totalWorkingTime
/
MaxSimtime
)
activeObject
.
WaitingForOperator
.
append
(
100
*
self
.
totalTimeWaitingForOperator
/
MaxSimtime
)
activeObject
.
WaitingForLoadOperator
.
append
(
100
*
self
.
totalTimeWaitingForLoadOperator
/
MaxSimtime
)
activeObject
.
Loading
.
append
(
100
*
self
.
totalLoadTime
/
MaxSimtime
)
activeObject
.
SettingUp
.
append
(
100
*
self
.
totalSetupTime
/
MaxSimtime
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment