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
a6618f51
Commit
a6618f51
authored
May 27, 2014
by
Ioannis Papagiannopoulos
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
first changes, topology09 running
parent
f9392dab
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
231 additions
and
179 deletions
+231
-179
dream/simulation/CoreObject.py
dream/simulation/CoreObject.py
+55
-42
dream/simulation/Exit.py
dream/simulation/Exit.py
+9
-7
dream/simulation/LineGenerationJSON.py
dream/simulation/LineGenerationJSON.py
+18
-11
dream/simulation/Machine.py
dream/simulation/Machine.py
+109
-88
dream/simulation/Source.py
dream/simulation/Source.py
+40
-31
No files found.
dream/simulation/CoreObject.py
View file @
a6618f51
...
@@ -25,15 +25,18 @@ Created on 12 Jul 2012
...
@@ -25,15 +25,18 @@ Created on 12 Jul 2012
Class that acts as an abstract. It should have no instances. All the core-objects should inherit from it
Class that acts as an abstract. It should have no instances. All the core-objects should inherit from it
'''
'''
from
SimPy.Simulation
import
Process
,
Resource
,
now
,
SimEvent
,
waitevent
# from SimPy.Simulation import Process, Resource, now, SimEvent, waitevent
import
simpy
# ===========================================================================
# ===========================================================================
# the core object
# the core object
# ===========================================================================
# ===========================================================================
class
CoreObject
(
Process
):
class
CoreObject
(
object
):
def
__init__
(
self
,
id
,
name
,
**
kw
):
def
__init__
(
self
,
id
,
name
,
**
kw
):
Process
.
__init__
(
self
)
from
Globals
import
G
self
.
env
=
G
.
env
# Process.__init__(self)
self
.
id
=
id
self
.
id
=
id
self
.
objName
=
name
self
.
objName
=
name
# lists that hold the previous and next objects in the flow
# lists that hold the previous and next objects in the flow
...
@@ -54,14 +57,18 @@ class CoreObject(Process):
...
@@ -54,14 +57,18 @@ class CoreObject(Process):
self
.
interruptCause
=
None
self
.
interruptCause
=
None
self
.
gatherWipStat
=
False
self
.
gatherWipStat
=
False
# signalizing an event that activates the generator
# signalizing an event that activates the generator
self
.
isRequested
=
SimEvent
(
'isRequested'
)
# self.isRequested=SimEvent('isRequested')
self
.
canDispose
=
SimEvent
(
'canDispose'
)
self
.
isRequested
=
self
.
env
.
event
()
self
.
interruptionEnd
=
SimEvent
(
'interruptionEnd'
)
# self.canDispose=SimEvent('canDispose')
self
.
interruptionStart
=
SimEvent
(
'interruptionStart'
)
self
.
canDispose
=
self
.
env
.
event
()
# self.interruptionEnd=SimEvent('interruptionEnd')
self
.
interruptionEnd
=
self
.
env
.
event
()
# self.interruptionStart=SimEvent('interruptionStart')
self
.
interruptionStart
=
self
.
env
.
event
()
def
initialize
(
self
):
def
initialize
(
self
):
# XXX why call super.__init__ outside of __init__ ?
# XXX why call super.__init__ outside of __init__ ?
Process
.
__init__
(
self
)
#
Process.__init__(self)
self
.
Up
=
True
#Boolean that shows if the machine is in failure ("Down") or not ("up")
self
.
Up
=
True
#Boolean that shows if the machine is in failure ("Down") or not ("up")
self
.
onShift
=
True
self
.
onShift
=
True
self
.
currentEntity
=
None
self
.
currentEntity
=
None
...
@@ -133,10 +140,14 @@ class CoreObject(Process):
...
@@ -133,10 +140,14 @@ class CoreObject(Process):
# TODO, this should be also updated in Globals.setWIP (in case we have initial wip)
# TODO, this should be also updated in Globals.setWIP (in case we have initial wip)
self
.
wipStatList
=
[[
0
,
0
]]
self
.
wipStatList
=
[[
0
,
0
]]
# signalizing an event that activates the generator
# signalizing an event that activates the generator
self
.
isRequested
=
SimEvent
(
'isRequested'
)
# self.isRequested=SimEvent('isRequested')
self
.
canDispose
=
SimEvent
(
'canDispose'
)
self
.
isRequested
=
self
.
env
.
event
()
self
.
interruptionEnd
=
SimEvent
(
'interruptionEnd'
)
# self.canDispose=SimEvent('canDispose')
self
.
interruptionStart
=
SimEvent
(
'interruptionStart'
)
self
.
canDispose
=
self
.
env
.
event
()
# self.interruptionEnd=SimEvent('interruptionEnd')
self
.
interruptionEnd
=
self
.
env
.
event
()
# self.interruptionStart=SimEvent('interruptionStart')
self
.
interruptionStart
=
self
.
env
.
event
()
# =======================================================================
# =======================================================================
# the main process of the core object
# the main process of the core object
...
@@ -167,7 +178,7 @@ class CoreObject(Process):
...
@@ -167,7 +178,7 @@ class CoreObject(Process):
def
removeEntity
(
self
,
entity
=
None
):
def
removeEntity
(
self
,
entity
=
None
):
self
.
addBlockage
()
self
.
addBlockage
()
activeObjectQueue
=
self
.
Res
.
activeQ
activeObjectQueue
=
self
.
Res
.
users
activeObjectQueue
.
remove
(
entity
)
#remove the Entity from the queue
activeObjectQueue
.
remove
(
entity
)
#remove the Entity from the queue
if
self
.
receiver
:
if
self
.
receiver
:
self
.
receiver
.
appendEntity
(
entity
)
self
.
receiver
.
appendEntity
(
entity
)
...
@@ -176,11 +187,11 @@ class CoreObject(Process):
...
@@ -176,11 +187,11 @@ class CoreObject(Process):
self
.
downTimeInTryingToReleaseCurrentEntity
=
0
self
.
downTimeInTryingToReleaseCurrentEntity
=
0
self
.
offShiftTimeTryingToReleaseCurrentEntity
=
0
self
.
offShiftTimeTryingToReleaseCurrentEntity
=
0
self
.
timeLastEntityLeft
=
now
()
self
.
timeLastEntityLeft
=
self
.
env
.
now
self
.
outputTrace
(
entity
.
name
,
"released "
+
self
.
objName
)
self
.
outputTrace
(
entity
.
name
,
"released "
+
self
.
objName
)
# update wipStatList
# update wipStatList
if
self
.
gatherWipStat
:
if
self
.
gatherWipStat
:
self
.
wipStatList
.
append
([
now
()
,
len
(
activeObjectQueue
)])
self
.
wipStatList
.
append
([
self
.
env
.
now
,
len
(
activeObjectQueue
)])
return
entity
return
entity
#===========================================================================
#===========================================================================
...
@@ -188,7 +199,7 @@ class CoreObject(Process):
...
@@ -188,7 +199,7 @@ class CoreObject(Process):
# this method is created to be overridden by the Assembly class in its getEntity where Frames are loaded
# this method is created to be overridden by the Assembly class in its getEntity where Frames are loaded
#===========================================================================
#===========================================================================
def
appendEntity
(
self
,
entity
=
None
):
def
appendEntity
(
self
,
entity
=
None
):
activeObjectQueue
=
self
.
Res
.
activeQ
activeObjectQueue
=
self
.
Res
.
users
activeObjectQueue
.
append
(
entity
)
activeObjectQueue
.
append
(
entity
)
# =======================================================================
# =======================================================================
...
@@ -205,11 +216,11 @@ class CoreObject(Process):
...
@@ -205,11 +216,11 @@ class CoreObject(Process):
# each time an Entity is removed
# each time an Entity is removed
# =======================================================================
# =======================================================================
def
addBlockage
(
self
):
def
addBlockage
(
self
):
self
.
totalTimeInCurrentEntity
=
now
()
-
self
.
timeLastEntityEntered
self
.
totalTimeInCurrentEntity
=
self
.
env
.
now
-
self
.
timeLastEntityEntered
self
.
totalTimeWaitingForOperator
+=
self
.
operatorWaitTimeCurrentEntity
self
.
totalTimeWaitingForOperator
+=
self
.
operatorWaitTimeCurrentEntity
if
self
.
timeLastEntityEnded
<
self
.
timeLastShiftStarted
:
if
self
.
timeLastEntityEnded
<
self
.
timeLastShiftStarted
:
self
.
offShiftTimeTryingToReleaseCurrentEntity
=
self
.
timeLastShiftStarted
-
self
.
timeLastShiftEnded
self
.
offShiftTimeTryingToReleaseCurrentEntity
=
self
.
timeLastShiftStarted
-
self
.
timeLastShiftEnded
blockage
=
now
()
-
(
self
.
timeLastEntityEnded
+
self
.
downTimeInTryingToReleaseCurrentEntity
+
self
.
offShiftTimeTryingToReleaseCurrentEntity
)
blockage
=
self
.
env
.
now
-
(
self
.
timeLastEntityEnded
+
self
.
downTimeInTryingToReleaseCurrentEntity
+
self
.
offShiftTimeTryingToReleaseCurrentEntity
)
self
.
totalBlockageTime
+=
blockage
self
.
totalBlockageTime
+=
blockage
# =======================================================================
# =======================================================================
...
@@ -219,12 +230,12 @@ class CoreObject(Process):
...
@@ -219,12 +230,12 @@ class CoreObject(Process):
# get active object and its queue, as well as the active (to be) entity
# get active object and its queue, as well as the active (to be) entity
#(after the sorting of the entities in the queue of the giver object)
#(after the sorting of the entities in the queue of the giver object)
# activeObject=self.getActiveObject()
# activeObject=self.getActiveObject()
activeObjectQueue
=
self
.
Res
.
activeQ
activeObjectQueue
=
self
.
Res
.
users
# get giver object, its queue, and sort the entities according to this object priorities
# get giver object, its queue, and sort the entities according to this object priorities
giverObject
=
self
.
giver
giverObject
=
self
.
giver
giverObject
.
sortEntities
()
#sort the Entities of the giver
giverObject
.
sortEntities
()
#sort the Entities of the giver
#according to the scheduling rule if applied
#according to the scheduling rule if applied
giverObjectQueue
=
giverObject
.
Res
.
activeQ
giverObjectQueue
=
giverObject
.
Res
.
users
# if the giverObject is blocked then unBlock it
# if the giverObject is blocked then unBlock it
if
giverObject
.
exitIsAssignedTo
():
if
giverObject
.
exitIsAssignedTo
():
giverObject
.
unAssignExit
()
giverObject
.
unAssignExit
()
...
@@ -242,10 +253,10 @@ class CoreObject(Process):
...
@@ -242,10 +253,10 @@ class CoreObject(Process):
#append the time to schedule so that it can be read in the result
#append the time to schedule so that it can be read in the result
#remember that every entity has it's schedule which is supposed to be updated every time
#remember that every entity has it's schedule which is supposed to be updated every time
# he entity enters a new object
# he entity enters a new object
activeEntity
.
schedule
.
append
([
self
,
now
()
])
activeEntity
.
schedule
.
append
([
self
,
self
.
env
.
now
])
#update variables
#update variables
activeEntity
.
currentStation
=
self
activeEntity
.
currentStation
=
self
self
.
timeLastEntityEntered
=
now
()
self
.
timeLastEntityEntered
=
self
.
env
.
now
self
.
nameLastEntityEntered
=
activeEntity
.
name
# this holds the name of the last entity that got into Machine
self
.
nameLastEntityEntered
=
activeEntity
.
name
# this holds the name of the last entity that got into Machine
self
.
downTimeProcessingCurrentEntity
=
0
self
.
downTimeProcessingCurrentEntity
=
0
# update the next list of the object
# update the next list of the object
...
@@ -265,7 +276,7 @@ class CoreObject(Process):
...
@@ -265,7 +276,7 @@ class CoreObject(Process):
# and if preemption is required
# and if preemption is required
#===========================================================================
#===========================================================================
def
preemptReceiver
(
self
):
def
preemptReceiver
(
self
):
activeObjectQueue
=
self
.
Res
.
activeQ
activeObjectQueue
=
self
.
Res
.
users
# find a critical order if any
# find a critical order if any
critical
=
False
critical
=
False
...
@@ -296,13 +307,13 @@ class CoreObject(Process):
...
@@ -296,13 +307,13 @@ class CoreObject(Process):
# if the obtained Entity is critical and the receiver is preemptive and not operated
# if the obtained Entity is critical and the receiver is preemptive and not operated
# in the case that the receiver is operated the preemption is performed by the operators
# in the case that the receiver is operated the preemption is performed by the operators
# if the receiver is not Up then no preemption will be performed
# if the receiver is not Up then no preemption will be performed
if
not
receiverOperated
and
len
(
receiver
.
Res
.
activeQ
)
>
0
:
if
not
receiverOperated
and
len
(
receiver
.
Res
.
users
)
>
0
:
#if the receiver does not hold an Entity that is also critical
#if the receiver does not hold an Entity that is also critical
if
not
receiver
.
Res
.
activeQ
[
0
].
isCritical
:
if
not
receiver
.
Res
.
users
[
0
].
isCritical
:
receiver
.
shouldPreempt
=
True
receiver
.
shouldPreempt
=
True
# self.printTrace(self.id, preempt=receiver.id)
# self.printTrace(self.id, preempt=receiver.id)
receiver
.
preempt
()
receiver
.
preempt
()
receiver
.
timeLastEntityEnded
=
now
()
#required to count blockage correctly in the preemptied station
receiver
.
timeLastEntityEnded
=
self
.
env
.
now
#required to count blockage correctly in the preemptied station
# sort so that the critical entity is placed in front
# sort so that the critical entity is placed in front
activeObjectQueue
.
sort
(
key
=
lambda
x
:
x
==
activeEntity
,
reverse
=
True
)
activeObjectQueue
.
sort
(
key
=
lambda
x
:
x
==
activeEntity
,
reverse
=
True
)
# if there is a critical entity and the possible receivers are operated then signal the Router
# if there is a critical entity and the possible receivers are operated then signal the Router
...
@@ -311,7 +322,7 @@ class CoreObject(Process):
...
@@ -311,7 +322,7 @@ class CoreObject(Process):
activeObjectQueue
.
sort
(
key
=
lambda
x
:
x
==
activeEntity
,
reverse
=
True
)
activeObjectQueue
.
sort
(
key
=
lambda
x
:
x
==
activeEntity
,
reverse
=
True
)
# update wipStatList
# update wipStatList
if
self
.
gatherWipStat
:
if
self
.
gatherWipStat
:
self
.
wipStatList
.
append
([
now
()
,
len
(
activeObjectQueue
)])
self
.
wipStatList
.
append
([
self
.
env
.
now
,
len
(
activeObjectQueue
)])
#===========================================================================
#===========================================================================
...
@@ -364,7 +375,7 @@ class CoreObject(Process):
...
@@ -364,7 +375,7 @@ class CoreObject(Process):
# self.printTrace(self.id, signalReceiver=self.receiver.id)
# self.printTrace(self.id, signalReceiver=self.receiver.id)
# assign the entry of the receiver
# assign the entry of the receiver
self
.
receiver
.
assignEntryTo
()
self
.
receiver
.
assignEntryTo
()
self
.
receiver
.
isRequested
.
s
ignal
(
self
)
self
.
receiver
.
isRequested
.
s
ucceed
(
self
)
return
True
return
True
# if no receiver can accept then try to preempt a receive if the stations holds a critical order
# if no receiver can accept then try to preempt a receive if the stations holds a critical order
self
.
preemptReceiver
()
self
.
preemptReceiver
()
...
@@ -379,8 +390,9 @@ class CoreObject(Process):
...
@@ -379,8 +390,9 @@ class CoreObject(Process):
# dummy variables that help prioritize the objects requesting to give objects to the Machine (activeObject)
# dummy variables that help prioritize the objects requesting to give objects to the Machine (activeObject)
maxTimeWaiting
=
0
# dummy variable counting the time a successor is waiting
maxTimeWaiting
=
0
# dummy variable counting the time a successor is waiting
receiver
=
None
receiver
=
None
from
Globals
import
G
for
object
in
candidates
:
for
object
in
candidates
:
timeWaiting
=
now
()
-
object
.
timeLastEntityLeft
# the time it has been waiting is updated and stored in dummy variable timeWaiting
timeWaiting
=
G
.
env
.
now
-
object
.
timeLastEntityLeft
# the time it has been waiting is updated and stored in dummy variable timeWaiting
if
(
timeWaiting
>
maxTimeWaiting
or
maxTimeWaiting
==
0
):
# if the timeWaiting is the maximum among the ones of the successors
if
(
timeWaiting
>
maxTimeWaiting
or
maxTimeWaiting
==
0
):
# if the timeWaiting is the maximum among the ones of the successors
maxTimeWaiting
=
timeWaiting
maxTimeWaiting
=
timeWaiting
receiver
=
object
# set the receiver as the longest waiting possible receiver
receiver
=
object
# set the receiver as the longest waiting possible receiver
...
@@ -394,13 +406,13 @@ class CoreObject(Process):
...
@@ -394,13 +406,13 @@ class CoreObject(Process):
# if an operator is not assigned to the receiver then do not signal the receiver but the Router
# if an operator is not assigned to the receiver then do not signal the receiver but the Router
try
:
try
:
if
not
receiver
.
assignedOperator
or
\
if
not
receiver
.
assignedOperator
or
\
(
receiver
.
isPreemptive
and
len
(
receiver
.
Res
.
activeQ
)
>
0
):
(
receiver
.
isPreemptive
and
len
(
receiver
.
Res
.
users
)
>
0
):
if
receiver
.
isLoadRequested
():
if
receiver
.
isLoadRequested
():
from
Globals
import
G
from
Globals
import
G
if
not
G
.
Router
.
invoked
:
if
not
G
.
Router
.
invoked
:
# self.printTrace(self.id, signal='router')
# self.printTrace(self.id, signal='router')
G
.
Router
.
invoked
=
True
G
.
Router
.
invoked
=
True
G
.
Router
.
isCalled
.
s
ignal
(
now
()
)
G
.
Router
.
isCalled
.
s
ucceed
(
self
.
env
.
now
)
return
True
return
True
else
:
else
:
return
False
return
False
...
@@ -454,7 +466,7 @@ class CoreObject(Process):
...
@@ -454,7 +466,7 @@ class CoreObject(Process):
self
.
giver
=
giver
self
.
giver
=
giver
self
.
giver
.
receiver
=
self
self
.
giver
.
receiver
=
self
# self.printTrace(self.id, signalGiver=self.giver.id)
# self.printTrace(self.id, signalGiver=self.giver.id)
self
.
giver
.
canDispose
.
s
ignal
(
self
)
self
.
giver
.
canDispose
.
s
ucceed
(
self
)
return
True
return
True
return
False
return
False
...
@@ -467,12 +479,13 @@ class CoreObject(Process):
...
@@ -467,12 +479,13 @@ class CoreObject(Process):
# dummy variables that help prioritize the objects requesting to give objects to the Machine (activeObject)
# dummy variables that help prioritize the objects requesting to give objects to the Machine (activeObject)
maxTimeWaiting
=
0
# dummy variable counting the time a predecessor is blocked
maxTimeWaiting
=
0
# dummy variable counting the time a predecessor is blocked
giver
=
None
giver
=
None
from
Globals
import
G
# loop through the possible givers to see which have to dispose and which is the one blocked for longer
# loop through the possible givers to see which have to dispose and which is the one blocked for longer
for
object
in
candidates
:
for
object
in
candidates
:
if
(
object
.
downTimeInTryingToReleaseCurrentEntity
>
0
):
# and the predecessor has been down while trying to give away the Entity
if
(
object
.
downTimeInTryingToReleaseCurrentEntity
>
0
):
# and the predecessor 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
timeWaiting
=
self
.
env
.
now
-
object
.
timeLastFailureEnded
# the timeWaiting dummy variable counts the time end of the last failure of the giver object
else
:
else
:
timeWaiting
=
now
()
-
object
.
timeLastEntityEnded
# in any other case, it holds the time since the end of the Entity processing
timeWaiting
=
G
.
env
.
now
-
object
.
timeLastEntityEnded
# in any other case, it holds the time since the end of the Entity processing
#if more than one predecessor have to dispose take the part from the one that is blocked longer
#if more than one predecessor have to dispose take the part from the one that is blocked longer
if
(
timeWaiting
>=
maxTimeWaiting
):
if
(
timeWaiting
>=
maxTimeWaiting
):
giver
=
object
# the object to deliver the Entity to the activeObject is set to the ith member of the previous list
giver
=
object
# the object to deliver the Entity to the activeObject is set to the ith member of the previous list
...
@@ -493,7 +506,7 @@ class CoreObject(Process):
...
@@ -493,7 +506,7 @@ class CoreObject(Process):
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
(
self
.
env
.
now
))
G
.
traceSheet
.
write
(
G
.
traceIndex
,
1
,
entityName
)
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
...
@@ -509,7 +522,7 @@ class CoreObject(Process):
...
@@ -509,7 +522,7 @@ class CoreObject(Process):
assert
len
(
kw
)
==
1
,
'only one phrase per printTrace supported for the moment'
assert
len
(
kw
)
==
1
,
'only one phrase per printTrace supported for the moment'
from
Globals
import
G
from
Globals
import
G
import
Globals
import
Globals
time
=
now
()
time
=
self
.
env
.
now
charLimit
=
60
charLimit
=
60
remainingChar
=
charLimit
-
len
(
entity
)
-
len
(
str
(
time
))
remainingChar
=
charLimit
-
len
(
entity
)
-
len
(
str
(
time
))
if
(
G
.
console
==
'Yes'
):
if
(
G
.
console
==
'Yes'
):
...
@@ -549,7 +562,7 @@ class CoreObject(Process):
...
@@ -549,7 +562,7 @@ class CoreObject(Process):
# checks if the Object can dispose an entity to the following object
# checks if the Object can dispose an entity to the following object
# =======================================================================
# =======================================================================
def
haveToDispose
(
self
,
callerObject
=
None
):
def
haveToDispose
(
self
,
callerObject
=
None
):
activeObjectQueue
=
self
.
Res
.
activeQ
activeObjectQueue
=
self
.
Res
.
users
return
len
(
activeObjectQueue
)
>
0
return
len
(
activeObjectQueue
)
>
0
# =======================================================================
# =======================================================================
...
@@ -581,7 +594,7 @@ class CoreObject(Process):
...
@@ -581,7 +594,7 @@ class CoreObject(Process):
# get the activeQ of the active object.
# get the activeQ of the active object.
# =======================================================================
# =======================================================================
def
getActiveObjectQueue
(
self
):
def
getActiveObjectQueue
(
self
):
return
self
.
Res
.
activeQ
return
self
.
Res
.
users
# =======================================================================
# =======================================================================
# get the giver object in a getEntity transaction.
# get the giver object in a getEntity transaction.
...
@@ -593,7 +606,7 @@ class CoreObject(Process):
...
@@ -593,7 +606,7 @@ class CoreObject(Process):
# get the giver object queue in a getEntity transaction.
# get the giver object queue in a getEntity transaction.
# =======================================================================
# =======================================================================
def
getGiverObjectQueue
(
self
):
def
getGiverObjectQueue
(
self
):
return
self
.
giver
.
Res
.
activeQ
return
self
.
giver
.
Res
.
users
# =======================================================================
# =======================================================================
# get the receiver object in a removeEntity transaction.
# get the receiver object in a removeEntity transaction.
...
@@ -605,7 +618,7 @@ class CoreObject(Process):
...
@@ -605,7 +618,7 @@ class CoreObject(Process):
# get the receiver object queue in a removeEntity transaction.
# get the receiver object queue in a removeEntity transaction.
# =======================================================================
# =======================================================================
def
getReceiverObjectQueue
(
self
):
def
getReceiverObjectQueue
(
self
):
return
self
.
receiver
.
Res
.
activeQ
return
self
.
receiver
.
Res
.
users
# =======================================================================
# =======================================================================
# calculates the processing time
# calculates the processing time
...
@@ -674,7 +687,7 @@ class CoreObject(Process):
...
@@ -674,7 +687,7 @@ class CoreObject(Process):
# false if object holds entities in its queue
# false if object holds entities in its queue
#===========================================================================
#===========================================================================
def
activeQueueIsEmpty
(
self
):
def
activeQueueIsEmpty
(
self
):
return
len
(
self
.
Res
.
activeQ
)
==
0
return
len
(
self
.
Res
.
users
)
==
0
# =======================================================================
# =======================================================================
# actions to be carried out when the processing of an Entity ends
# actions to be carried out when the processing of an Entity ends
...
@@ -686,5 +699,5 @@ class CoreObject(Process):
...
@@ -686,5 +699,5 @@ class CoreObject(Process):
# check if an entity is in the internal Queue of the object
# check if an entity is in the internal Queue of the object
#===========================================================================
#===========================================================================
def
isInActiveQueue
(
self
,
entity
=
None
):
def
isInActiveQueue
(
self
,
entity
=
None
):
activeObjectQueue
=
self
.
Res
.
activeQ
activeObjectQueue
=
self
.
Res
.
users
return
any
(
x
==
entity
for
x
in
activeObjectQueue
)
return
any
(
x
==
entity
for
x
in
activeObjectQueue
)
dream/simulation/Exit.py
View file @
a6618f51
...
@@ -25,7 +25,8 @@ Created on 6 Feb 2013
...
@@ -25,7 +25,8 @@ Created on 6 Feb 2013
models the exit of the model
models the exit of the model
'''
'''
from
SimPy.Simulation
import
now
,
Process
,
Resource
,
infinity
,
waituntil
,
waitevent
# from SimPy.Simulation import now, Process, Resource, infinity, waituntil, waitevent
import
simpy
import
xlwt
import
xlwt
from
CoreObject
import
CoreObject
from
CoreObject
import
CoreObject
...
@@ -54,7 +55,7 @@ class Exit(CoreObject):
...
@@ -54,7 +55,7 @@ class Exit(CoreObject):
CoreObject
.
initialize
(
self
)
CoreObject
.
initialize
(
self
)
# initialize the internal Queue (type Resource) of the Exit
# initialize the internal Queue (type Resource) of the Exit
self
.
Res
=
Resource
(
capacity
=
infinity
)
self
.
Res
=
simpy
.
Resource
(
self
.
env
,
capacity
=
10000
)
# The number of resource that exited through this exit.
# The number of resource that exited through this exit.
# XXX bug: cannot output as json when nothing has exited.
# XXX bug: cannot output as json when nothing has exited.
self
.
numOfExits
=
0
self
.
numOfExits
=
0
...
@@ -68,7 +69,8 @@ class Exit(CoreObject):
...
@@ -68,7 +69,8 @@ class Exit(CoreObject):
def
run
(
self
):
def
run
(
self
):
while
1
:
while
1
:
# wait until the Queue can accept an entity and one predecessor requests it
# wait until the Queue can accept an entity and one predecessor requests it
yield
waitevent
,
self
,
self
.
isRequested
yield
self
.
isRequested
self
.
isRequested
=
self
.
env
.
event
()
# TODO: insert extra controls to check whether the self.giver attribute is correctly updated
# TODO: insert extra controls to check whether the self.giver attribute is correctly updated
self
.
getEntity
()
self
.
getEntity
()
...
@@ -109,13 +111,13 @@ class Exit(CoreObject):
...
@@ -109,13 +111,13 @@ class Exit(CoreObject):
# if activeEntity in G.EntityList:
# if activeEntity in G.EntityList:
# G.EntityList.remove(activeEntity)
# G.EntityList.remove(activeEntity)
# self.clear(activeEntity)
# self.clear(activeEntity)
self
.
totalLifespan
+=
now
()
-
activeEntity
.
startTime
#Add the entity's lifespan to the total one.
self
.
totalLifespan
+=
self
.
env
.
now
-
activeEntity
.
startTime
#Add the entity's lifespan to the total one.
self
.
numOfExits
+=
1
# increase the exits by one
self
.
numOfExits
+=
1
# increase the exits by one
self
.
totalNumberOfUnitsExited
+=
activeEntity
.
numberOfUnits
# add the number of units that xited
self
.
totalNumberOfUnitsExited
+=
activeEntity
.
numberOfUnits
# add the number of units that xited
self
.
totalTaktTime
+=
now
()
-
self
.
timeLastEntityLeft
# add the takt time
self
.
totalTaktTime
+=
self
.
env
.
now
-
self
.
timeLastEntityLeft
# add the takt time
self
.
timeLastEntityLeft
=
now
()
# update the time that the last entity left from the Exit
self
.
timeLastEntityLeft
=
self
.
env
.
now
# update the time that the last entity left from the Exit
activeObjectQueue
=
self
.
getActiveObjectQueue
()
activeObjectQueue
=
self
.
getActiveObjectQueue
()
del
self
.
Res
.
activeQ
[:]
del
self
.
Res
.
users
[:]
return
activeEntity
return
activeEntity
@
staticmethod
@
staticmethod
...
...
dream/simulation/LineGenerationJSON.py
View file @
a6618f51
...
@@ -40,7 +40,8 @@ import numpy
...
@@ -40,7 +40,8 @@ import numpy
numpy
.
seterr
(
all
=
'raise'
)
numpy
.
seterr
(
all
=
'raise'
)
from
SimPy.Simulation
import
activate
,
initialize
,
simulate
,
now
,
infinity
# from SimPy.Simulation import activate, initialize, simulate, now, infinity
import
simpy
from
Globals
import
G
from
Globals
import
G
from
Source
import
Source
from
Source
import
Source
from
Machine
import
Machine
from
Machine
import
Machine
...
@@ -885,11 +886,14 @@ def initializeObjects():
...
@@ -885,11 +886,14 @@ def initializeObjects():
# ===========================================================================
# ===========================================================================
def
activateObjects
():
def
activateObjects
():
for
element
in
G
.
ObjList
:
for
element
in
G
.
ObjList
:
activate
(
element
,
element
.
run
())
# activate(element, element.run())
G
.
env
.
process
(
element
.
run
())
for
ev
in
G
.
EventGeneratorList
:
for
ev
in
G
.
EventGeneratorList
:
activate
(
ev
,
ev
.
run
())
# activate(ev, ev.run())
G
.
env
.
process
(
ev
.
run
())
for
oi
in
G
.
ObjectInterruptionList
:
for
oi
in
G
.
ObjectInterruptionList
:
activate
(
oi
,
oi
.
run
())
# activate(oi, oi.run())
G
.
env
.
process
(
oi
.
run
())
# ===========================================================================
# ===========================================================================
# reads the WIP of the stations
# reads the WIP of the stations
...
@@ -1261,6 +1265,7 @@ def main(argv=[], input_data=None):
...
@@ -1261,6 +1265,7 @@ def main(argv=[], input_data=None):
#read the input from the JSON file and create the line
#read the input from the JSON file and create the line
G
.
JSONData
=
json
.
loads
(
G
.
InputData
)
# create the dictionary JSONData
G
.
JSONData
=
json
.
loads
(
G
.
InputData
)
# create the dictionary JSONData
readGeneralInput
()
readGeneralInput
()
G
.
env
=
simpy
.
Environment
()
# initialize the environment
createObjects
()
createObjects
()
createObjectInterruptions
()
createObjectInterruptions
()
setTopology
()
setTopology
()
...
@@ -1272,7 +1277,7 @@ def main(argv=[], input_data=None):
...
@@ -1272,7 +1277,7 @@ def main(argv=[], input_data=None):
G
.
Rnd
=
Random
(
'%s%s'
%
(
G
.
seed
,
i
))
G
.
Rnd
=
Random
(
'%s%s'
%
(
G
.
seed
,
i
))
else
:
else
:
G
.
Rnd
=
Random
()
G
.
Rnd
=
Random
()
initialize
()
#initialize the simulation
# initialize() #initialize the simulation
createWIP
()
createWIP
()
initializeObjects
()
initializeObjects
()
Globals
.
setWIP
(
G
.
EntityList
)
Globals
.
setWIP
(
G
.
EntityList
)
...
@@ -1281,22 +1286,24 @@ def main(argv=[], input_data=None):
...
@@ -1281,22 +1286,24 @@ def main(argv=[], input_data=None):
# if the simulation is ran until no more events are scheduled,
# if the simulation is ran until no more events are scheduled,
# then we have to find the end time as the time the last entity ended.
# then we have to find the end time as the time the last entity ended.
if
G
.
maxSimTime
==-
1
:
if
G
.
maxSimTime
==-
1
:
simulate
(
until
=
infinity
)
# simulate until there are no more events.
G
.
env
.
run
(
until
=
infinity
)
# If someone does it for a model that has always events, then it will run forever!
# simulate(until=infinity) # simulate until there are no more events.
# # If someone does it for a model that has always events, then it will run forever!
# # identify from the exits what is the time that the last entity has ended.
# # identify from the exits what is the time that the last entity has ended.
# endList=[]
# endList=[]
# for exit in G.ExitList:
# for exit in G.ExitList:
# endList.append(exit.timeLastEntityLeft)
# endList.append(exit.timeLastEntityLeft)
# G.maxSimTime=float(max(endList))
# G.maxSimTime=float(max(endList))
# identify the time of the last event
# identify the time of the last event
if
now
()
!=
0
:
#do not let G.maxSimTime=0 so that there will be no crash
if
G
.
env
.
now
!=
0
:
#do not let G.maxSimTime=0 so that there will be no crash
G
.
maxSimTime
=
now
()
G
.
maxSimTime
=
env
.
now
else
:
else
:
print
"simulation ran for 0 time, something may have gone wrong"
print
"simulation ran for 0 time, something may have gone wrong"
logger
.
info
(
"simulation ran for 0 time, something may have gone wrong"
)
logger
.
info
(
"simulation ran for 0 time, something may have gone wrong"
)
#else we simulate until the given maxSimTime
#else we simulate until the given maxSimTime
else
:
else
:
simulate
(
until
=
G
.
maxSimTime
)
#simulate until the given maxSimTime
G
.
env
.
run
(
until
=
G
.
maxSimTime
)
# simulate(until=G.maxSimTime) #simulate until the given maxSimTime
#carry on the post processing operations for every object in the topology
#carry on the post processing operations for every object in the topology
for
element
in
G
.
ObjList
:
for
element
in
G
.
ObjList
:
...
...
dream/simulation/Machine.py
View file @
a6618f51
...
@@ -25,8 +25,9 @@ Created on 8 Nov 2012
...
@@ -25,8 +25,9 @@ Created on 8 Nov 2012
Models a machine that can also have failures
Models a machine that can also have failures
'''
'''
from
SimPy.Simulation
import
Process
,
Resource
,
SimEvent
# from SimPy.Simulation import Process, Resource, SimEvent
from
SimPy.Simulation
import
activate
,
passivate
,
waituntil
,
now
,
hold
,
request
,
release
,
waitevent
# from SimPy.Simulation import activate, passivate, waituntil, now, hold, request, release, waitevent
import
simpy
from
Failure
import
Failure
from
Failure
import
Failure
from
CoreObject
import
CoreObject
from
CoreObject
import
CoreObject
...
@@ -150,12 +151,14 @@ class Machine(CoreObject):
...
@@ -150,12 +151,14 @@ class Machine(CoreObject):
self
.
isPreemptive
=
isPreemptive
self
.
isPreemptive
=
isPreemptive
self
.
resetOnPreemption
=
resetOnPreemption
self
.
resetOnPreemption
=
resetOnPreemption
# events used by the broker
# events used by the broker
self
.
brokerIsSet
=
SimEvent
(
'brokerIsSet'
)
# self.brokerIsSet=SimEvent('brokerIsSet')
self
.
brokerIsSet
=
self
.
env
.
event
()
# this event is generated every time an operator is requested by machine for Load operation type.
# this event is generated every time an operator is requested by machine for Load operation type.
# if the machine has not succeeded in getting an entity due to the resource absence
# if the machine has not succeeded in getting an entity due to the resource absence
# and waits for the next event to get the entity,
# and waits for the next event to get the entity,
# then it must be signalled that the operator is now available
# then it must be signalled that the operator is now available
self
.
loadOperatorAvailable
=
SimEvent
(
'loadOperatorAvailable'
)
# self.loadOperatorAvailable=SimEvent('loadOperatorAvailable')
self
.
loadOperatorAvailable
=
self
.
env
.
event
()
# flag notifying that there is operator assigned to the actievObject
# flag notifying that there is operator assigned to the actievObject
self
.
assignedOperator
=
True
self
.
assignedOperator
=
True
...
@@ -166,7 +169,8 @@ class Machine(CoreObject):
...
@@ -166,7 +169,8 @@ class Machine(CoreObject):
# using the Process __init__ and not the CoreObject __init__
# using the Process __init__ and not the CoreObject __init__
CoreObject
.
initialize
(
self
)
CoreObject
.
initialize
(
self
)
# initialize the internal Queue (type Resource) of the Machine
# initialize the internal Queue (type Resource) of the Machine
self
.
Res
=
Resource
(
self
.
capacity
)
#self.Res=Resource(self.capacity)
self
.
Res
=
simpy
.
Resource
(
self
.
env
,
capacity
=
1
)
# initiate the Broker responsible to control the request/release
# initiate the Broker responsible to control the request/release
# initialize the operator pool if any
# initialize the operator pool if any
if
(
self
.
operatorPool
!=
"None"
):
if
(
self
.
operatorPool
!=
"None"
):
...
@@ -211,12 +215,14 @@ class Machine(CoreObject):
...
@@ -211,12 +215,14 @@ class Machine(CoreObject):
# flag notifying that there is operator assigned to the actievObject
# flag notifying that there is operator assigned to the actievObject
self
.
assignedOperator
=
True
self
.
assignedOperator
=
True
self
.
brokerIsSet
=
SimEvent
(
'brokerIsSet'
)
# self.brokerIsSet=SimEvent('brokerIsSet')
self
.
brokerIsSet
=
self
.
env
.
event
()
# this event is generated every time an operator is requested by machine for Load operation type.
# this event is generated every time an operator is requested by machine for Load operation type.
# if the machine has not succeeded in getting an entity due to the resource absence
# if the machine has not succeeded in getting an entity due to the resource absence
# and waits for the next event to get the entity,
# and waits for the next event to get the entity,
# then it must be signalled that the operator is now available
# then it must be signalled that the operator is now available
self
.
loadOperatorAvailable
=
SimEvent
(
'loadOperatorAvailable'
)
# self.loadOperatorAvailable=SimEvent('loadOperatorAvailable')
self
.
loadOperatorAvailable
=
self
.
env
.
event
()
# =======================================================================
# =======================================================================
# the main process of the machine
# the main process of the machine
...
@@ -229,23 +235,29 @@ class Machine(CoreObject):
...
@@ -229,23 +235,29 @@ class Machine(CoreObject):
# waitEvent isRequested /interruptionEnd/loadOperatorAvailable
# waitEvent isRequested /interruptionEnd/loadOperatorAvailable
while
1
:
while
1
:
# self.printTrace(self.id, waitEvent='')
# self.printTrace(self.id, waitEvent='')
yield
waitevent
,
self
,
[
self
.
isRequested
,
self
.
interruptionEnd
,
self
.
loadOperatorAvailable
]
# yield waitevent, self, [self.isRequested, self.interruptionEnd, self.loadOperatorAvailable]
receivedEvent
=
yield
self
.
isRequested
|
self
.
interruptionEnd
|
self
.
loadOperatorAvailable
# self.printTrace(self.id, received='')
# self.printTrace(self.id, received='')
# if the machine can accept an entity and one predecessor requests it continue with receiving the entity
# if the machine can accept an entity and one predecessor requests it continue with receiving the entity
if
self
.
isRequested
.
signalparam
:
if
self
.
isRequested
in
receivedEvent
:
# self.printTrace(self.id, isRequested=self.isRequested.
signalparam
.id)
# self.printTrace(self.id, isRequested=self.isRequested.
value
.id)
assert
self
.
isRequested
.
signalparam
==
self
.
giver
,
'the giver is not the requestingObject'
assert
self
.
isRequested
.
value
==
self
.
giver
,
'the giver is not the requestingObject'
assert
self
.
giver
.
receiver
==
self
,
'the receiver of the signalling object in not the station'
assert
self
.
giver
.
receiver
==
self
,
'the receiver of the signalling object in not the station'
# reset the signalparam of the isRequested event
# reset the signalparam of the isRequested event
self
.
isRequested
.
signalparam
=
None
# self.isRequested.value=None
self
.
isRequested
=
self
.
env
.
event
()
break
break
# if an interruption caused the control to be taken by the machine or
# if an interruption caused the control to be taken by the machine or
# if an operator was rendered available while it was needed by the machine to proceed with getEntity
# if an operator was rendered available while it was needed by the machine to proceed with getEntity
if
self
.
interruptionEnd
.
signalparam
==
now
()
or
self
.
loadOperatorAvailable
.
signalparam
==
now
():
if
self
.
interruptionEnd
.
value
==
self
.
env
.
now
or
self
.
loadOperatorAvailable
.
value
==
self
.
env
.
now
:
# if self.interruptionEnd.signalparam==now():
if
self
.
interruptionEnd
in
receivedEvent
:
# self.printTrace(self.id, interruptionEnd=str(self.interruptionEnd.signalparam))
self
.
interruptionEnd
=
self
.
env
.
event
()
# elif self.loadOperatorAvailable.signalparam==now():
if
self
.
loadOperatorAvailable
in
receivedEvent
:
# self.printTrace(self.id,loadOperatorAvailable=str(self.loadOperatorAvailable.signalparam))
self
.
loadOperatorAvailable
=
self
.
env
.
event
()
# if self.interruptionEnd.value==self.env.now:
# self.printTrace(self.id, interruptionEnd=str(self.interruptionEnd.value))
# elif self.loadOperatorAvailable.value==self.env.now:
# self.printTrace(self.id,loadOperatorAvailable=str(self.loadOperatorAvailable.value))
# try to signal the Giver, otherwise wait until it is requested
# try to signal the Giver, otherwise wait until it is requested
if
self
.
signalGiver
():
if
self
.
signalGiver
():
break
break
...
@@ -264,19 +276,20 @@ class Machine(CoreObject):
...
@@ -264,19 +276,20 @@ class Machine(CoreObject):
# when it's ready to accept (canAcceptAndIsRequested) then inform the broker
# when it's ready to accept (canAcceptAndIsRequested) then inform the broker
# machines waits to be operated (waits for the operator)
# machines waits to be operated (waits for the operator)
self
.
requestOperator
()
self
.
requestOperator
()
self
.
timeWaitForLoadOperatorStarted
=
now
()
self
.
timeWaitForLoadOperatorStarted
=
self
.
env
.
now
# wait until the Broker has waited times equal to loadTime (if any)
# wait until the Broker has waited times equal to loadTime (if any)
yield
waitevent
,
self
,
self
.
brokerIsSet
yield
self
.
brokerIsSet
self
.
timeWaitForLoadOperatorEnded
=
now
()
self
.
brokerIsSet
=
self
.
env
.
event
()
self
.
timeWaitForLoadOperatorEnded
=
self
.
env
.
now
self
.
loadOperatorWaitTimeCurrentEntity
+=
self
.
timeWaitForLoadOperatorEnded
-
self
.
timeWaitForLoadOperatorStarted
self
.
loadOperatorWaitTimeCurrentEntity
+=
self
.
timeWaitForLoadOperatorEnded
-
self
.
timeWaitForLoadOperatorStarted
self
.
totalTimeWaitingForLoadOperator
+=
self
.
loadOperatorWaitTimeCurrentEntity
self
.
totalTimeWaitingForLoadOperator
+=
self
.
loadOperatorWaitTimeCurrentEntity
# ======= Load the machine if the Load is defined as one of the Operators' operation types
# ======= 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
():
if
any
(
type
==
"Load"
for
type
in
self
.
multOperationTypeList
)
and
self
.
isOperated
():
self
.
timeLoadStarted
=
now
()
self
.
timeLoadStarted
=
self
.
env
.
now
yield
hold
,
self
,
self
.
calculateLoadTime
(
)
yield
self
.
env
.
timeout
(
self
.
calculateLoadTime
()
)
# TODO: if self.interrupted(): There is the issue of failure during the Loading
# TODO: if self.interrupted(): There is the issue of failure during the Loading
self
.
timeLoadEnded
=
now
()
self
.
timeLoadEnded
=
self
.
env
.
now
self
.
loadTimeCurrentEntity
=
self
.
timeLoadEnded
-
self
.
timeLoadStarted
self
.
loadTimeCurrentEntity
=
self
.
timeLoadEnded
-
self
.
timeLoadStarted
self
.
totalLoadTime
+=
self
.
loadTimeCurrentEntity
self
.
totalLoadTime
+=
self
.
loadTimeCurrentEntity
...
@@ -290,7 +303,8 @@ class Machine(CoreObject):
...
@@ -290,7 +303,8 @@ class Machine(CoreObject):
# machine has to release the operator
# machine has to release the operator
self
.
releaseOperator
()
self
.
releaseOperator
()
# wait until the Broker has finished processing
# wait until the Broker has finished processing
yield
waitevent
,
self
,
self
.
brokerIsSet
yield
self
.
brokerIsSet
self
.
brokerIsSet
=
self
.
env
.
event
()
# TODO: reset the requestinEntity before receiving the currentEntity
# TODO: reset the requestinEntity before receiving the currentEntity
self
.
requestingEntity
=
None
self
.
requestingEntity
=
None
...
@@ -310,10 +324,11 @@ class Machine(CoreObject):
...
@@ -310,10 +324,11 @@ class Machine(CoreObject):
# when it's ready to accept (canAcceptAndIsRequested) then inform the broker
# when it's ready to accept (canAcceptAndIsRequested) then inform the broker
# machines waits to be operated (waits for the operator)
# machines waits to be operated (waits for the operator)
self
.
requestOperator
()
self
.
requestOperator
()
self
.
timeWaitForOperatorStarted
=
now
()
self
.
timeWaitForOperatorStarted
=
self
.
env
.
now
# wait until the Broker has waited times equal to loadTime (if any)
# wait until the Broker has waited times equal to loadTime (if any)
yield
waitevent
,
self
,
self
.
brokerIsSet
yield
self
.
brokerIsSet
self
.
timeWaitForOperatorEnded
=
now
()
self
.
brokerIsSet
=
self
.
env
.
event
()
self
.
timeWaitForOperatorEnded
=
self
.
env
.
now
self
.
operatorWaitTimeCurrentEntity
+=
self
.
timeWaitForOperatorEnded
-
self
.
timeWaitForOperatorStarted
self
.
operatorWaitTimeCurrentEntity
+=
self
.
timeWaitForOperatorEnded
-
self
.
timeWaitForOperatorStarted
# variables dedicated to hold the processing times, the time when the Entity entered,
# variables dedicated to hold the processing times, the time when the Entity entered,
...
@@ -324,10 +339,10 @@ class Machine(CoreObject):
...
@@ -324,10 +339,10 @@ class Machine(CoreObject):
# ======= setup the machine if the Setup is defined as one of the Operators' operation types
# ======= 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
# 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
():
if
any
(
type
==
"Setup"
for
type
in
self
.
multOperationTypeList
)
and
self
.
isOperated
():
self
.
timeSetupStarted
=
now
()
self
.
timeSetupStarted
=
self
.
env
.
now
yield
hold
,
self
,
self
.
calculateSetupTime
(
)
yield
self
.
env
.
timeout
(
self
.
calculateSetupTime
()
)
# TODO: if self.interrupted(): There is the issue of failure during the setup
# TODO: if self.interrupted(): There is the issue of failure during the setup
self
.
timeSetupEnded
=
now
()
self
.
timeSetupEnded
=
self
.
env
.
now
self
.
setupTimeCurrentEntity
=
self
.
timeSetupEnded
-
self
.
timeSetupStarted
self
.
setupTimeCurrentEntity
=
self
.
timeSetupEnded
-
self
.
timeSetupStarted
self
.
totalSetupTime
+=
self
.
setupTimeCurrentEntity
self
.
totalSetupTime
+=
self
.
setupTimeCurrentEntity
...
@@ -336,10 +351,10 @@ class Machine(CoreObject):
...
@@ -336,10 +351,10 @@ class Machine(CoreObject):
# but setupTime is given for the entity to be processed
# but setupTime is given for the entity to be processed
# try:
# try:
# if self.setupTime and not any(type=="Setup" for type in self.multOperationTypeList):
# if self.setupTime and not any(type=="Setup" for type in self.multOperationTypeList):
# self.timeSetupStarted =
now()
# self.timeSetupStarted =
self.env.now
# yield hold,self,self.calculateSetupTime()
# yield hold,self,self.calculateSetupTime()
# # TODO: if self.interrupted(): There is the issue of failure during the setup
# # TODO: if self.interrupted(): There is the issue of failure during the setup
# self.timeSetupEnded =
now()
# self.timeSetupEnded =
self.env.now
# self.setupTimeCurrentEntity = self.timeSetupEnded-self.timeSetupStarted
# self.setupTimeCurrentEntity = self.timeSetupEnded-self.timeSetupStarted
# self.totalSetupTime += self.setupTimeCurrentEntity
# self.totalSetupTime += self.setupTimeCurrentEntity
# except:
# except:
...
@@ -355,7 +370,8 @@ class Machine(CoreObject):
...
@@ -355,7 +370,8 @@ class Machine(CoreObject):
# machine has to release the operator
# machine has to release the operator
self
.
releaseOperator
()
self
.
releaseOperator
()
# wait until the Broker has finished processing
# wait until the Broker has finished processing
yield
waitevent
,
self
,
self
.
brokerIsSet
yield
self
.
brokerIsSet
self
.
brokerIsSet
=
self
.
env
.
event
()
# variables used to flag any interruptions and the end of the processing
# variables used to flag any interruptions and the end of the processing
self
.
interruption
=
False
self
.
interruption
=
False
...
@@ -368,13 +384,15 @@ class Machine(CoreObject):
...
@@ -368,13 +384,15 @@ class Machine(CoreObject):
while
processingNotFinished
:
while
processingNotFinished
:
# timeRestartingProcessing : dummy variable to keep track of the time that the processing starts after
# timeRestartingProcessing : dummy variable to keep track of the time that the processing starts after
# every interruption
# every interruption
self
.
timeRestartingProcessing
=
now
()
self
.
timeRestartingProcessing
=
self
.
env
.
now
# wait for the processing time left tinM, if no interruption occurs then change the processingEndedFlag and exit loop,
# 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),
# else (if interrupted()) set interruption flag to true (only if tinM==0),
# and recalculate the processing time left tinM, passivate while waiting for repair.
# and recalculate the processing time left tinM, passivate while waiting for repair.
# if a preemption has occurred then react accordingly (proceed with getting the critical entity)
# if a preemption has occurred then react accordingly (proceed with getting the critical entity)
yield
hold
,
self
,
self
.
tinM
# getting processed for remaining processing time tinM
receivedEvent
=
yield
self
.
env
.
timeout
(
self
.
tinM
)
|
self
.
interruptionStart
# getting processed for remaining processing time tinM
if
self
.
interrupted
():
# if a failure occurs while processing the machine is interrupted.
if
self
.
interruptionStart
in
receivedEvent
:
# if a failure occurs while processing the machine is interrupted.
assert
self
.
interruptionStart
.
value
==
self
.
env
.
now
,
'the interruption has not been processed on the time of activation'
self
.
interruptionStart
=
self
.
env
.
event
()
self
.
interruptionActions
()
# execute interruption actions
self
.
interruptionActions
()
# execute interruption actions
# =============== release the operator if there is interruption
# =============== release the operator if there is interruption
...
@@ -382,12 +400,14 @@ class Machine(CoreObject):
...
@@ -382,12 +400,14 @@ class Machine(CoreObject):
and
self
.
isOperated
()
\
and
self
.
isOperated
()
\
and
any
(
type
==
"Processing"
for
type
in
self
.
multOperationTypeList
):
and
any
(
type
==
"Processing"
for
type
in
self
.
multOperationTypeList
):
self
.
releaseOperator
()
self
.
releaseOperator
()
yield
waitevent
,
self
,
self
.
brokerIsSet
yield
self
.
brokerIsSet
self
.
brokerIsSet
=
self
.
env
.
event
()
# if there is a failure in the machine or interruption due to preemption, it is passivated
# if there is a failure in the machine or interruption due to preemption, it is passivated
# passivate the Machine for as long as there is no repair
# passivate the Machine for as long as there is no repair
yield
waitevent
,
self
,
self
.
interruptionEnd
yield
self
.
interruptionEnd
assert
now
()
==
self
.
interruptionEnd
.
signalparam
,
'the victim of the failure is not the object that received it'
assert
self
.
env
.
now
==
self
.
interruptionEnd
.
value
,
'the victim of the failure is not the object that received it'
self
.
interruptionEnd
=
self
.
env
.
event
()
self
.
postInterruptionActions
()
self
.
postInterruptionActions
()
...
@@ -395,10 +415,11 @@ class Machine(CoreObject):
...
@@ -395,10 +415,11 @@ class Machine(CoreObject):
if
(
self
.
operatorPool
!=
"None"
)
\
if
(
self
.
operatorPool
!=
"None"
)
\
and
any
(
type
==
"Processing"
for
type
in
self
.
multOperationTypeList
)
\
and
any
(
type
==
"Processing"
for
type
in
self
.
multOperationTypeList
)
\
and
not
self
.
interruption
:
and
not
self
.
interruption
:
self
.
timeWaitForOperatorStarted
=
now
()
self
.
timeWaitForOperatorStarted
=
self
.
env
.
now
self
.
requestOperator
()
self
.
requestOperator
()
yield
waitevent
,
self
,
self
.
brokerIsSet
yield
self
.
brokerIsSet
self
.
timeWaitForOperatorEnded
=
now
()
self
.
brokerIsSet
=
self
.
env
.
event
()
self
.
timeWaitForOperatorEnded
=
self
.
env
.
now
self
.
operatorWaitTimeCurrentEntity
+=
self
.
timeWaitForOperatorEnded
-
self
.
timeWaitForOperatorStarted
self
.
operatorWaitTimeCurrentEntity
+=
self
.
timeWaitForOperatorEnded
-
self
.
timeWaitForOperatorStarted
# if the station is reactivated by the preempt method
# if the station is reactivated by the preempt method
elif
(
self
.
shouldPreempt
):
elif
(
self
.
shouldPreempt
):
...
@@ -409,7 +430,8 @@ class Machine(CoreObject):
...
@@ -409,7 +430,8 @@ class Machine(CoreObject):
and
self
.
isOperated
()
\
and
self
.
isOperated
()
\
and
any
(
type
==
"Processing"
for
type
in
self
.
multOperationTypeList
):
and
any
(
type
==
"Processing"
for
type
in
self
.
multOperationTypeList
):
self
.
releaseOperator
()
self
.
releaseOperator
()
yield
waitevent
,
self
,
self
.
brokerIsSet
yield
self
.
brokerIsSet
self
.
brokerIsSet
=
self
.
env
.
event
()
self
.
postInterruptionActions
()
self
.
postInterruptionActions
()
break
break
...
@@ -426,30 +448,29 @@ class Machine(CoreObject):
...
@@ -426,30 +448,29 @@ class Machine(CoreObject):
and
any
(
type
==
"Processing"
for
type
in
self
.
multOperationTypeList
)
\
and
any
(
type
==
"Processing"
for
type
in
self
.
multOperationTypeList
)
\
and
not
self
.
interruption
:
and
not
self
.
interruption
:
self
.
releaseOperator
()
self
.
releaseOperator
()
yield
waitevent
,
self
,
self
.
brokerIsSet
yield
self
.
brokerIsSet
self
.
brokerIsSet
=
self
.
env
.
event
()
# signal the receiver that the activeObject has something to dispose of
# signal the receiver that the activeObject has something to dispose of
if
not
self
.
signalReceiver
():
if
not
self
.
signalReceiver
():
# if there was no available receiver, get into blocking control
# if there was no available receiver, get into blocking control
while
1
:
while
1
:
# wait the event canDispose, this means that the station can deliver the item to successor
# wait the event canDispose, this means that the station can deliver the item to successor
event
=
yield
waitevent
,
self
,
[
self
.
canDispose
,
self
.
interruptionStart
]
receivedEvent
=
yield
self
.
canDispose
|
self
.
interruptionStart
# if there was interruption
# if there was interruption
#if self.interrupted():
#if self.interrupted():
# TODO not good implementation
# TODO not good implementation
if
self
.
interruptionStart
.
signalparam
==
now
():
if
self
.
interruptionStart
in
receivedEvent
:
assert
self
.
interruptionStart
.
value
==
self
.
env
.
now
,
'the interruption has not been processed on the time of activation'
self
.
interruptionStart
=
self
.
env
.
event
()
# wait for the end of the interruption
# wait for the end of the interruption
self
.
interruptionActions
()
# execute interruption actions
self
.
interruptionActions
()
# execute interruption actions
yield
waitevent
,
self
,
self
.
interruptionEnd
# interruptionEnd to be triggered by ObjectInterruption
yield
self
.
interruptionEnd
# interruptionEnd to be triggered by ObjectInterruption
assert
now
()
==
self
.
interruptionEnd
.
signalparam
,
'the victim of the failure is not the object that received it'
assert
self
.
env
.
now
==
self
.
interruptionEnd
.
value
,
'the victim of the failure is not the object that received it'
self
.
interruptionEnd
=
self
.
env
.
event
()
self
.
postInterruptionActions
()
self
.
postInterruptionActions
()
#=======================================================
if
self
.
canDispose
in
receivedEvent
:
# TODO: not sure if this is required now
self
.
canDispose
=
self
.
env
.
event
()
# #if during the interruption the object became empty break
# if (len(self.getActiveObjectQueue())==0 and self.shouldPreempt):
# self.shouldPreempt==False
# break
#=======================================================
# try to signal a receiver, if successful then proceed to get an other entity
# try to signal a receiver, if successful then proceed to get an other entity
if
self
.
signalReceiver
():
if
self
.
signalReceiver
():
break
break
...
@@ -458,7 +479,7 @@ class Machine(CoreObject):
...
@@ -458,7 +479,7 @@ class Machine(CoreObject):
# signals the preceding station (e.g. self.machine) and immediately after that gets the entity.
# 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
# the preceding machine gets the canDispose signal which is actually useless, is emptied by the following station
# and then cannot exit an infinite loop.
# 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 while waiting (for a canDispose event) became free as the machines that follows emptied it, then proceed
if
not
self
.
haveToDispose
():
if
not
self
.
haveToDispose
():
break
break
...
@@ -467,7 +488,7 @@ class Machine(CoreObject):
...
@@ -467,7 +488,7 @@ class Machine(CoreObject):
# actions to be carried out when the processing of an Entity ends
# actions to be carried out when the processing of an Entity ends
# =======================================================================
# =======================================================================
def
endProcessingActions
(
self
):
def
endProcessingActions
(
self
):
activeObjectQueue
=
self
.
Res
.
activeQ
activeObjectQueue
=
self
.
Res
.
users
activeEntity
=
activeObjectQueue
[
0
]
activeEntity
=
activeObjectQueue
[
0
]
# self.printTrace(activeObject.getActiveObjectQueue()[0].name, processEnd=activeObject.objName)
# self.printTrace(activeObject.getActiveObjectQueue()[0].name, processEnd=activeObject.objName)
# reset the variables used to handle the interruptions timing
# reset the variables used to handle the interruptions timing
...
@@ -498,16 +519,16 @@ class Machine(CoreObject):
...
@@ -498,16 +519,16 @@ class Machine(CoreObject):
self
.
waitToDispose
=
True
self
.
waitToDispose
=
True
#do this so that if it is overtime working it is not counted as off-shift time
#do this so that if it is overtime working it is not counted as off-shift time
if
not
self
.
onShift
:
if
not
self
.
onShift
:
self
.
timeLastShiftEnded
=
now
()
self
.
timeLastShiftEnded
=
self
.
env
.
now
# update the total working time
# update the total working time
# the total processing time for this entity is what the distribution initially gave
# the total processing time for this entity is what the distribution initially gave
if
not
self
.
shouldPreempt
:
if
not
self
.
shouldPreempt
:
self
.
totalWorkingTime
+=
self
.
totalProcessingTimeInCurrentEntity
self
.
totalWorkingTime
+=
self
.
totalProcessingTimeInCurrentEntity
# if the station was preemptied for a critical order then calculate the total working time accorindingly
# if the station was preemptied for a critical order then calculate the total working time accorindingly
else
:
else
:
self
.
totalWorkingTime
+=
now
()
-
(
self
.
timeLastEntityEntered
)
self
.
totalWorkingTime
+=
self
.
env
.
now
-
(
self
.
timeLastEntityEntered
)
# update the variables keeping track of Entity related attributes of the machine
# update the variables keeping track of Entity related attributes of the machine
self
.
timeLastEntityEnded
=
now
()
# this holds the time that the last entity ended processing in 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
.
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
self
.
completedJobs
+=
1
# Machine completed one more Job
# reseting the shouldPreempt flag
# reseting the shouldPreempt flag
...
@@ -517,7 +538,7 @@ class Machine(CoreObject):
...
@@ -517,7 +538,7 @@ class Machine(CoreObject):
# actions to be carried out when the processing of an Entity ends
# actions to be carried out when the processing of an Entity ends
# =======================================================================
# =======================================================================
def
interruptionActions
(
self
):
def
interruptionActions
(
self
):
activeObjectQueue
=
self
.
Res
.
activeQ
activeObjectQueue
=
self
.
Res
.
users
activeEntity
=
activeObjectQueue
[
0
]
activeEntity
=
activeObjectQueue
[
0
]
# self.printTrace(activeEntity.name, interrupted=self.objName)
# self.printTrace(activeEntity.name, interrupted=self.objName)
# if the interrupt occured while processing an entity
# if the interrupt occured while processing an entity
...
@@ -528,40 +549,40 @@ class Machine(CoreObject):
...
@@ -528,40 +549,40 @@ class Machine(CoreObject):
except
IndexError
:
except
IndexError
:
pass
pass
# recalculate the processing time left tinM
# recalculate the processing time left tinM
self
.
tinM
=
self
.
tinM
-
(
now
()
-
self
.
timeRestartingProcessing
)
self
.
tinM
=
self
.
tinM
-
(
self
.
env
.
now
-
self
.
timeRestartingProcessing
)
if
(
self
.
tinM
==
0
):
# sometimes the failure may happen exactly at the time that the processing would finish
if
(
self
.
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
# this may produce disagreement with the simul8 because in both SimPy and Simul8
# it seems to be random which happens 1st
# it seems to be random which happens 1st
# this should not appear often to stochastic models though where times are random
# this should not appear often to stochastic models though where times are random
self
.
interruption
=
True
self
.
interruption
=
True
# start counting the down time at breatTime dummy variable
# start counting the down time at breatTime dummy variable
self
.
breakTime
=
now
()
# dummy variable that the interruption happened
self
.
breakTime
=
self
.
env
.
now
# dummy variable that the interruption happened
# =======================================================================
# =======================================================================
# actions to be carried out when the processing of an Entity ends
# actions to be carried out when the processing of an Entity ends
# =======================================================================
# =======================================================================
def
postInterruptionActions
(
self
):
def
postInterruptionActions
(
self
):
activeObjectQueue
=
self
.
Res
.
activeQ
activeObjectQueue
=
self
.
Res
.
users
activeEntity
=
activeObjectQueue
[
0
]
activeEntity
=
activeObjectQueue
[
0
]
# if the machine returns from an failure while processing an entity
# if the machine returns from an failure while processing an entity
if
not
self
.
waitToDispose
:
if
not
self
.
waitToDispose
:
# use the timers to count the time that Machine is down and related
# use the timers to count the time that Machine is down and related
self
.
downTimeProcessingCurrentEntity
+=
now
()
-
self
.
breakTime
# count the time that Machine is down while processing this Entity
self
.
downTimeProcessingCurrentEntity
+=
self
.
env
.
now
-
self
.
breakTime
# count the time that Machine is down while processing this Entity
self
.
downTimeInCurrentEntity
+=
now
()
-
self
.
breakTime
# count the time that Machine is down while on currentEntity
self
.
downTimeInCurrentEntity
+=
self
.
env
.
now
-
self
.
breakTime
# count the time that Machine is down while on currentEntity
self
.
timeLastFailureEnded
=
now
()
# set the timeLastFailureEnded
self
.
timeLastFailureEnded
=
self
.
env
.
now
# set the timeLastFailureEnded
self
.
failureTimeInCurrentEntity
+=
now
()
-
self
.
breakTime
# dummy variable keeping track of the failure time
self
.
failureTimeInCurrentEntity
+=
self
.
env
.
now
-
self
.
breakTime
# dummy variable keeping track of the failure time
# output to trace that the Machine self.objName was passivated for the current failure time
# output to trace that the Machine self.objName was passivated for the current failure time
self
.
outputTrace
(
activeObjectQueue
[
0
].
name
,
"passivated in "
+
self
.
objName
+
" for "
+
str
(
now
()
-
self
.
breakTime
))
self
.
outputTrace
(
activeObjectQueue
[
0
].
name
,
"passivated in "
+
self
.
objName
+
" for "
+
str
(
self
.
env
.
now
-
self
.
breakTime
))
# when a machine returns from failure while trying to deliver an entity
# when a machine returns from failure while trying to deliver an entity
else
:
else
:
# count the failure while on current entity time with failureTime variable
# count the failure while on current entity time with failureTime variable
self
.
failureTimeInCurrentEntity
+=
now
()
-
self
.
breakTime
self
.
failureTimeInCurrentEntity
+=
self
.
env
.
now
-
self
.
breakTime
# calculate the time the Machine was down while trying to dispose the current Entity,
# calculate the time the Machine was down while trying to dispose the current Entity,
# and the total down time while on current Entity
# and the total down time while on current Entity
self
.
downTimeInTryingToReleaseCurrentEntity
+=
now
()
-
self
.
breakTime
self
.
downTimeInTryingToReleaseCurrentEntity
+=
self
.
env
.
now
-
self
.
breakTime
self
.
downTimeInCurrentEntity
+=
now
()
-
self
.
breakTime
# already updated from failures during processing
self
.
downTimeInCurrentEntity
+=
self
.
env
.
now
-
self
.
breakTime
# already updated from failures during processing
# update the timeLastFailureEnded
# update the timeLastFailureEnded
self
.
timeLastFailureEnded
=
now
()
self
.
timeLastFailureEnded
=
self
.
env
.
now
# reset the variable holding the time the failure happened
# reset the variable holding the time the failure happened
self
.
breakTime
=
0
self
.
breakTime
=
0
...
@@ -577,7 +598,7 @@ class Machine(CoreObject):
...
@@ -577,7 +598,7 @@ class Machine(CoreObject):
# that will give the entity.
# that will give the entity.
# =======================================================================
# =======================================================================
def
canAccept
(
self
,
callerObject
=
None
):
def
canAccept
(
self
,
callerObject
=
None
):
activeObjectQueue
=
self
.
Res
.
activeQ
activeObjectQueue
=
self
.
Res
.
users
# if we have only one predecessor just check if there is a place and the machine is up
# 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
# this is done to achieve better (cpu) processing time
# then we can also use it as a filter for a yield method
# then we can also use it as a filter for a yield method
...
@@ -615,7 +636,7 @@ class Machine(CoreObject):
...
@@ -615,7 +636,7 @@ class Machine(CoreObject):
# also updates the giver to the one that is to be taken
# also updates the giver to the one that is to be taken
# =======================================================================
# =======================================================================
def
canAcceptAndIsRequested
(
self
,
callerObject
=
None
):
def
canAcceptAndIsRequested
(
self
,
callerObject
=
None
):
activeObjectQueue
=
self
.
Res
.
activeQ
activeObjectQueue
=
self
.
Res
.
users
giverObject
=
callerObject
giverObject
=
callerObject
assert
giverObject
,
'there must be a caller for canAcceptAndIsRequested'
assert
giverObject
,
'there must be a caller for canAcceptAndIsRequested'
# check if there is a place, the machine is up and the predecessor has an entity to dispose. if the machine has to compete
# check if there is a place, the machine is up and the predecessor has an entity to dispose. if the machine has to compete
...
@@ -701,7 +722,7 @@ class Machine(CoreObject):
...
@@ -701,7 +722,7 @@ class Machine(CoreObject):
# checks if the Machine can dispose an entity to the following object
# checks if the Machine can dispose an entity to the following object
# =======================================================================
# =======================================================================
def
haveToDispose
(
self
,
callerObject
=
None
):
def
haveToDispose
(
self
,
callerObject
=
None
):
activeObjectQueue
=
self
.
Res
.
activeQ
activeObjectQueue
=
self
.
Res
.
users
#if we have only one successor just check if machine waits to dispose and also is up
#if we have only one successor just check if machine waits to dispose and also is up
# this is done to achieve better (cpu) processing time
# this is done to achieve better (cpu) processing time
if
(
len
(
self
.
next
)
==
1
or
callerObject
==
None
):
if
(
len
(
self
.
next
)
==
1
or
callerObject
==
None
):
...
@@ -796,7 +817,7 @@ class Machine(CoreObject):
...
@@ -796,7 +817,7 @@ class Machine(CoreObject):
offShiftTimeInCurrentEntity
=
0
offShiftTimeInCurrentEntity
=
0
if
self
.
interruptCause
:
if
self
.
interruptCause
:
if
self
.
onShift
==
False
and
self
.
interruptCause
.
type
==
'ShiftScheduler'
:
if
self
.
onShift
==
False
and
self
.
interruptCause
.
type
==
'ShiftScheduler'
:
offShiftTimeInCurrentEntity
=
now
()
-
activeObject
.
timeLastShiftEnded
offShiftTimeInCurrentEntity
=
self
.
env
.
now
-
activeObject
.
timeLastShiftEnded
# if there is an entity that finished processing in a Machine but did not get to reach
# 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,
# the following Object till the end of simulation,
...
@@ -805,9 +826,9 @@ class Machine(CoreObject):
...
@@ -805,9 +826,9 @@ class Machine(CoreObject):
if
(
len
(
activeObjectQueue
)
>
0
)
and
(
mightBeBlocked
)
\
if
(
len
(
activeObjectQueue
)
>
0
)
and
(
mightBeBlocked
)
\
and
((
activeObject
.
nameLastEntityEntered
==
activeObject
.
nameLastEntityEnded
))
and
self
.
onShift
:
and
((
activeObject
.
nameLastEntityEntered
==
activeObject
.
nameLastEntityEnded
))
and
self
.
onShift
:
# be careful here, might have to reconsider
# be careful here, might have to reconsider
activeObject
.
totalBlockageTime
+=
now
()
-
(
activeObject
.
timeLastEntityEnded
+
activeObject
.
downTimeInTryingToReleaseCurrentEntity
)
activeObject
.
totalBlockageTime
+=
self
.
env
.
now
-
(
activeObject
.
timeLastEntityEnded
+
activeObject
.
downTimeInTryingToReleaseCurrentEntity
)
if
activeObject
.
Up
==
False
:
if
activeObject
.
Up
==
False
:
activeObject
.
totalBlockageTime
-=
now
()
-
activeObject
.
timeLastFailure
activeObject
.
totalBlockageTime
-=
self
.
env
.
now
-
activeObject
.
timeLastFailure
alreadyAdded
=
True
alreadyAdded
=
True
#if Machine is currently processing an entity we should count this working time
#if Machine is currently processing an entity we should count this working time
...
@@ -817,8 +838,8 @@ class Machine(CoreObject):
...
@@ -817,8 +838,8 @@ class Machine(CoreObject):
#if Machine is down we should add this last failure time to the time that it has been down in current entity
#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
self
.
Up
==
False
:
# if(len(activeObjectQueue)>0) and (self.Up==False):
# if(len(activeObjectQueue)>0) and (self.Up==False):
activeObject
.
downTimeProcessingCurrentEntity
+=
now
()
-
activeObject
.
timeLastFailure
activeObject
.
downTimeProcessingCurrentEntity
+=
self
.
env
.
now
-
activeObject
.
timeLastFailure
activeObject
.
totalWorkingTime
+=
now
()
-
activeObject
.
timeLastEntityEntered
\
activeObject
.
totalWorkingTime
+=
self
.
env
.
now
-
activeObject
.
timeLastEntityEntered
\
-
activeObject
.
downTimeProcessingCurrentEntity
\
-
activeObject
.
downTimeProcessingCurrentEntity
\
-
activeObject
.
operatorWaitTimeCurrentEntity
\
-
activeObject
.
operatorWaitTimeCurrentEntity
\
-
activeObject
.
setupTimeCurrentEntity
\
-
activeObject
.
setupTimeCurrentEntity
\
...
@@ -830,17 +851,17 @@ class Machine(CoreObject):
...
@@ -830,17 +851,17 @@ class Machine(CoreObject):
and
(
activeObject
.
currentOperator
==
None
):
and
(
activeObject
.
currentOperator
==
None
):
# TODO: needs further research as the time of failure while waiting for operator is not counted yet
# TODO: needs further research as the time of failure while waiting for operator is not counted yet
if
self
.
Up
==
False
:
if
self
.
Up
==
False
:
activeObject
.
downTimeProcessingCurrentEntity
+=
now
()
-
activeObject
.
timeLastFailure
activeObject
.
downTimeProcessingCurrentEntity
+=
self
.
env
.
now
-
activeObject
.
timeLastFailure
activeObject
.
totalTimeWaitingForOperator
+=
now
()
-
activeObject
.
timeWaitForOperatorStarted
\
activeObject
.
totalTimeWaitingForOperator
+=
self
.
env
.
now
-
activeObject
.
timeWaitForOperatorStarted
\
-
activeObject
.
downTimeProcessingCurrentEntity
\
-
activeObject
.
downTimeProcessingCurrentEntity
\
-
offShiftTimeInCurrentEntity
-
offShiftTimeInCurrentEntity
# if Machine is down we have to add this failure time to its total failure time
# 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
# we also need to add the last blocking time to total blockage time
if
(
activeObject
.
Up
==
False
):
if
(
activeObject
.
Up
==
False
):
activeObject
.
totalFailureTime
+=
now
()
-
activeObject
.
timeLastFailure
activeObject
.
totalFailureTime
+=
self
.
env
.
now
-
activeObject
.
timeLastFailure
# we add the value only if it hasn't already been added
# we add the value only if it hasn't already been added
if
((
mightBeBlocked
)
and
(
activeObject
.
nameLastEntityEnded
==
activeObject
.
nameLastEntityEntered
)
and
(
not
alreadyAdded
)):
if
((
mightBeBlocked
)
and
(
activeObject
.
nameLastEntityEnded
==
activeObject
.
nameLastEntityEntered
)
and
(
not
alreadyAdded
)):
activeObject
.
totalBlockageTime
+=
(
now
()
-
activeObject
.
timeLastEntityEnded
)
-
(
now
()
-
activeObject
.
timeLastFailure
)
-
activeObject
.
downTimeInTryingToReleaseCurrentEntity
activeObject
.
totalBlockageTime
+=
(
self
.
env
.
now
-
activeObject
.
timeLastEntityEnded
)
-
(
self
.
env
.
now
-
activeObject
.
timeLastFailure
)
-
activeObject
.
downTimeInTryingToReleaseCurrentEntity
alreadyAdded
=
True
alreadyAdded
=
True
#if the machine is off shift,add this to the off-shift time
#if the machine is off shift,add this to the off-shift time
...
@@ -849,12 +870,12 @@ class Machine(CoreObject):
...
@@ -849,12 +870,12 @@ class Machine(CoreObject):
#add the time only if the object is interrupted because of off-shift
#add the time only if the object is interrupted because of off-shift
if
self
.
interruptCause
:
if
self
.
interruptCause
:
if
self
.
interruptCause
.
type
==
'ShiftScheduler'
:
if
self
.
interruptCause
.
type
==
'ShiftScheduler'
:
self
.
totalOffShiftTime
+=
now
()
-
self
.
timeLastShiftEnded
self
.
totalOffShiftTime
+=
self
.
env
.
now
-
self
.
timeLastShiftEnded
elif
len
(
self
.
getActiveObjectQueue
())
==
0
or
self
.
waitToDispose
:
elif
len
(
self
.
getActiveObjectQueue
())
==
0
or
self
.
waitToDispose
:
self
.
totalOffShiftTime
+=
now
()
-
self
.
timeLastShiftEnded
self
.
totalOffShiftTime
+=
self
.
env
.
now
-
self
.
timeLastShiftEnded
# we add the value only if it hasn't already been added
# we add the value only if it hasn't already been added
if
((
mightBeBlocked
)
and
(
activeObject
.
nameLastEntityEnded
==
activeObject
.
nameLastEntityEntered
)
and
(
not
alreadyAdded
)):
if
((
mightBeBlocked
)
and
(
activeObject
.
nameLastEntityEnded
==
activeObject
.
nameLastEntityEntered
)
and
(
not
alreadyAdded
)):
activeObject
.
totalBlockageTime
+=
(
now
()
-
activeObject
.
timeLastEntityEnded
)
-
(
now
()
-
activeObject
.
timeLastShiftEnded
)
-
offShiftTimeInCurrentEntity
activeObject
.
totalBlockageTime
+=
(
self
.
env
.
now
-
activeObject
.
timeLastEntityEnded
)
-
(
self
.
env
.
now
-
activeObject
.
timeLastShiftEnded
)
-
offShiftTimeInCurrentEntity
#Machine was idle when it was not in any other state
#Machine was idle when it was not in any other state
activeObject
.
totalWaitingTime
=
MaxSimtime
-
activeObject
.
totalWorkingTime
-
activeObject
.
totalBlockageTime
-
activeObject
.
totalFailureTime
-
activeObject
.
totalLoadTime
-
activeObject
.
totalSetupTime
-
self
.
totalOffShiftTime
activeObject
.
totalWaitingTime
=
MaxSimtime
-
activeObject
.
totalWorkingTime
-
activeObject
.
totalBlockageTime
-
activeObject
.
totalFailureTime
-
activeObject
.
totalLoadTime
-
activeObject
.
totalSetupTime
-
self
.
totalOffShiftTime
...
...
dream/simulation/Source.py
View file @
a6618f51
...
@@ -26,7 +26,8 @@ Created on 8 Nov 2012
...
@@ -26,7 +26,8 @@ Created on 8 Nov 2012
models the source object that generates the entities
models the source object that generates the entities
'''
'''
from
SimPy.Simulation
import
now
,
Process
,
Resource
,
infinity
,
hold
,
SimEvent
,
activate
,
waitevent
# from SimPy.Simulation import now, Process, Resource, infinity, hold, SimEvent, activate, waitevent
import
simpy
from
RandomNumberGenerator
import
RandomNumberGenerator
from
RandomNumberGenerator
import
RandomNumberGenerator
from
CoreObject
import
CoreObject
from
CoreObject
import
CoreObject
from
Globals
import
G
from
Globals
import
G
...
@@ -36,20 +37,20 @@ import Globals
...
@@ -36,20 +37,20 @@ import Globals
#============================================================================
#============================================================================
# the EntityGenerator object
# the EntityGenerator object
#============================================================================
#============================================================================
class
EntityGenerator
(
Process
):
class
EntityGenerator
(
object
):
#===========================================================================
#===========================================================================
# the __init__ method of the EntityGenerator
# the __init__ method of the EntityGenerator
#===========================================================================
#===========================================================================
def
__init__
(
self
,
victim
=
None
):
def
__init__
(
self
,
victim
=
None
):
Process
.
__init__
(
self
)
self
.
env
=
G
.
env
self
.
type
=
"EntityGenerator"
#String that shows the type of object
self
.
type
=
"EntityGenerator"
#String that shows the type of object
self
.
victim
=
victim
self
.
victim
=
victim
#===========================================================================
#
#===========================================================================
# initialize method of the EntityGenerator
#
# initialize method of the EntityGenerator
#===========================================================================
#
#===========================================================================
def
initialize
(
self
):
#
def initialize(self):
Process
.
__init__
(
self
)
# Process.__init__(self)
#===========================================================================
#===========================================================================
# the generator of the EntitiesGenerator
# the generator of the EntitiesGenerator
...
@@ -59,8 +60,8 @@ class EntityGenerator(Process):
...
@@ -59,8 +60,8 @@ class EntityGenerator(Process):
# if the Source is empty create the Entity
# if the Source is empty create the Entity
if
len
(
self
.
victim
.
getActiveObjectQueue
())
==
0
:
if
len
(
self
.
victim
.
getActiveObjectQueue
())
==
0
:
entity
=
self
.
victim
.
createEntity
()
# create the Entity object and assign its name
entity
=
self
.
victim
.
createEntity
()
# create the Entity object and assign its name
entity
.
creationTime
=
now
()
# assign the current simulation time as the Entity's creation time
entity
.
creationTime
=
self
.
env
.
now
# assign the current simulation time as the Entity's creation time
entity
.
startTime
=
now
()
# assign the current simulation time as the Entity's start time
entity
.
startTime
=
self
.
env
.
now
# assign the current simulation time as the Entity's start time
entity
.
currentStation
=
self
.
victim
# update the current station of the Entity
entity
.
currentStation
=
self
.
victim
# update the current station of the Entity
G
.
EntityList
.
append
(
entity
)
G
.
EntityList
.
append
(
entity
)
self
.
victim
.
outputTrace
(
entity
.
name
,
"generated"
)
# output the trace
self
.
victim
.
outputTrace
(
entity
.
name
,
"generated"
)
# output the trace
...
@@ -68,13 +69,13 @@ class EntityGenerator(Process):
...
@@ -68,13 +69,13 @@ class EntityGenerator(Process):
self
.
victim
.
numberOfArrivals
+=
1
# we have one new arrival
self
.
victim
.
numberOfArrivals
+=
1
# we have one new arrival
G
.
numberOfEntities
+=
1
G
.
numberOfEntities
+=
1
self
.
victim
.
appendEntity
(
entity
)
self
.
victim
.
appendEntity
(
entity
)
self
.
victim
.
entityCreated
.
s
ignal
(
entity
)
self
.
victim
.
entityCreated
.
s
ucceed
(
entity
)
# else put it on the time list for scheduled Entities
# else put it on the time list for scheduled Entities
else
:
else
:
#print
now()
, 'appending to the list'
#print
self.env.now
, 'appending to the list'
self
.
victim
.
scheduledEntities
.
append
(
now
()
)
self
.
victim
.
scheduledEntities
.
append
(
self
.
env
.
now
)
self
.
victim
.
outputTrace
(
entity
.
name
,
"generated"
)
# output the trace
self
.
victim
.
outputTrace
(
entity
.
name
,
"generated"
)
# output the trace
yield
hold
,
self
,
self
.
victim
.
calculateInterarrivalTime
(
)
# wait until the next arrival
yield
self
.
env
.
timeout
(
self
.
victim
.
calculateInterarrivalTime
()
)
# wait until the next arrival
#============================================================================
#============================================================================
# The Source object is a Process
# The Source object is a Process
...
@@ -104,9 +105,11 @@ class Source(CoreObject):
...
@@ -104,9 +105,11 @@ class Source(CoreObject):
self
.
entityGenerator
=
EntityGenerator
(
victim
=
self
)
# the EntityGenerator of the Source
self
.
entityGenerator
=
EntityGenerator
(
victim
=
self
)
# the EntityGenerator of the Source
self
.
entityCreated
=
SimEvent
(
'an entity is created'
)
# self.entityCreated=SimEvent('an entity is created')
self
.
entityCreated
=
self
.
env
.
event
()
# event used by router
# event used by router
self
.
loadOperatorAvailable
=
SimEvent
(
'loadOperatorAvailable'
)
# self.loadOperatorAvailable=SimEvent('loadOperatorAvailable')
self
.
loadOperatorAvailable
=
self
.
env
.
event
()
self
.
scheduledEntities
=
[]
# list of creations that are scheduled
self
.
scheduledEntities
=
[]
# list of creations that are scheduled
...
@@ -118,15 +121,19 @@ class Source(CoreObject):
...
@@ -118,15 +121,19 @@ class Source(CoreObject):
CoreObject
.
initialize
(
self
)
CoreObject
.
initialize
(
self
)
# initialize the internal Queue (type Resource) of the Source
# initialize the internal Queue (type Resource) of the Source
self
.
Res
=
Resource
(
capacity
=
infinity
)
# self.Res=Resource(capacity=infinity)
self
.
Res
.
activeQ
=
[]
self
.
Res
=
simpy
.
Resource
(
self
.
env
,
capacity
=
10000
)
self
.
Res
.
waitQ
=
[]
self
.
Res
.
users
=
[]
# self.Res.waitQ=[]
self
.
numberOfArrivals
=
0
self
.
numberOfArrivals
=
0
self
.
entityGenerator
.
initialize
()
# self.entityGenerator.initialize()
activate
(
self
.
entityGenerator
,
self
.
entityGenerator
.
run
())
# activate(self.entityGenerator,self.entityGenerator.run())
self
.
entityCreated
=
SimEvent
(
'an entity is created'
)
self
.
env
.
process
(
self
.
entityGenerator
.
run
())
# self.entityCreated=SimEvent('an entity is created')
self
.
entityCreated
=
self
.
env
.
event
()
# event used by router
# event used by router
self
.
loadOperatorAvailable
=
SimEvent
(
'loadOperatorAvailable'
)
# self.loadOperatorAvailable=SimEvent('loadOperatorAvailable')
self
.
loadOperatorAvailable
=
self
.
env
.
event
()
self
.
scheduledEntities
=
[]
# list of creations that are scheduled
self
.
scheduledEntities
=
[]
# list of creations that are scheduled
#===========================================================================
#===========================================================================
...
@@ -138,16 +145,18 @@ class Source(CoreObject):
...
@@ -138,16 +145,18 @@ class Source(CoreObject):
activeObjectQueue
=
self
.
getActiveObjectQueue
()
activeObjectQueue
=
self
.
getActiveObjectQueue
()
while
1
:
while
1
:
# wait for any event (entity creation or request for disposal of entity)
# wait for any event (entity creation or request for disposal of entity)
yield
waitevent
,
self
,
[
self
.
entityCreated
,
self
.
canDispose
,
self
.
loadOperatorAvailable
]
receivedEvent
=
yield
self
.
entityCreated
|
self
.
canDispose
|
self
.
loadOperatorAvailable
# if an entity is created try to signal the receiver and continue
# if an entity is created try to signal the receiver and continue
if
self
.
entityCreated
.
signalparam
:
if
self
.
entityCreated
in
receivedEvent
:
self
.
entityCreated
.
signalparam
=
None
self
.
entityCreated
=
self
.
env
.
event
()
if
self
.
signalReceiver
():
if
self
.
signalReceiver
():
continue
continue
# otherwise, if the receiver requests availability then try to signal him if there is anything to dispose of
# otherwise, if the receiver requests availability then try to signal him if there is anything to dispose of
if
self
.
canDispose
.
signalparam
or
self
.
loadOperatorAvailable
.
signalparam
:
if
self
.
canDispose
in
receivedEvent
or
self
.
loadOperatorAvailable
in
receivedEvent
:
self
.
canDispose
.
signalparam
=
None
# self.canDispose.signalparam=None
self
.
loadOperatorAvailable
.
signalparam
=
None
self
.
canDispose
=
self
.
env
.
event
()
# self.loadOperatorAvailable.signalparam=None
self
.
loadOperatorAvailable
=
self
.
env
.
event
()
if
self
.
haveToDispose
():
if
self
.
haveToDispose
():
if
self
.
signalReceiver
():
if
self
.
signalReceiver
():
continue
continue
...
@@ -188,7 +197,7 @@ class Source(CoreObject):
...
@@ -188,7 +197,7 @@ class Source(CoreObject):
newEntity
=
self
.
createEntity
()
# create the Entity object and assign its name
newEntity
=
self
.
createEntity
()
# create the Entity object and assign its name
newEntity
.
creationTime
=
self
.
scheduledEntities
.
pop
(
0
)
# assign the current simulation time as the Entity's creation time
newEntity
.
creationTime
=
self
.
scheduledEntities
.
pop
(
0
)
# assign the current simulation time as the Entity's creation time
newEntity
.
startTime
=
newEntity
.
creationTime
# assign the current simulation time as the Entity's start time
newEntity
.
startTime
=
newEntity
.
creationTime
# assign the current simulation time as the Entity's start time
#print
now()
, 'getting from the list. StartTime=',newEntity.startTime
#print
self.env.now
, 'getting from the list. StartTime=',newEntity.startTime
newEntity
.
currentStation
=
self
# update the current station of the Entity
newEntity
.
currentStation
=
self
# update the current station of the Entity
G
.
EntityList
.
append
(
newEntity
)
G
.
EntityList
.
append
(
newEntity
)
self
.
getActiveObjectQueue
().
append
(
newEntity
)
# append the entity to the resource
self
.
getActiveObjectQueue
().
append
(
newEntity
)
# append the entity to the resource
...
@@ -197,5 +206,5 @@ class Source(CoreObject):
...
@@ -197,5 +206,5 @@ class Source(CoreObject):
self
.
appendEntity
(
newEntity
)
self
.
appendEntity
(
newEntity
)
activeEntity
=
CoreObject
.
removeEntity
(
self
,
entity
)
# run the default method
activeEntity
=
CoreObject
.
removeEntity
(
self
,
entity
)
# run the default method
if
len
(
self
.
getActiveObjectQueue
())
==
1
:
if
len
(
self
.
getActiveObjectQueue
())
==
1
:
self
.
entityCreated
.
s
ignal
(
newEntity
)
self
.
entityCreated
.
s
ucceed
(
newEntity
)
return
activeEntity
return
activeEntity
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