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
9cd884a0
Commit
9cd884a0
authored
Jan 10, 2014
by
Ioannis Papagiannopoulos
Committed by
Jérome Perrin
Jan 20, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Comments added
parent
9c33bce8
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
253 additions
and
117 deletions
+253
-117
dream/simulation/CoreObject.py
dream/simulation/CoreObject.py
+82
-33
dream/simulation/Dismantle.py
dream/simulation/Dismantle.py
+60
-30
dream/simulation/Globals.py
dream/simulation/Globals.py
+18
-4
dream/simulation/Job.py
dream/simulation/Job.py
+17
-11
dream/simulation/LineGenerationJSON.py
dream/simulation/LineGenerationJSON.py
+9
-6
dream/simulation/MachinePreemptive.py
dream/simulation/MachinePreemptive.py
+8
-4
dream/simulation/Order.py
dream/simulation/Order.py
+7
-5
dream/simulation/OrderComponent.py
dream/simulation/OrderComponent.py
+3
-3
dream/simulation/OrderDecomposition.py
dream/simulation/OrderDecomposition.py
+26
-13
dream/simulation/QueuePreemptive.py
dream/simulation/QueuePreemptive.py
+10
-5
dream/simulation/ScheduledMaintenance.py
dream/simulation/ScheduledMaintenance.py
+13
-3
No files found.
dream/simulation/CoreObject.py
View file @
9cd884a0
This diff is collapsed.
Click to expand it.
dream/simulation/Dismantle.py
View file @
9cd884a0
...
@@ -34,10 +34,13 @@ from RandomNumberGenerator import RandomNumberGenerator
...
@@ -34,10 +34,13 @@ from RandomNumberGenerator import RandomNumberGenerator
import
scipy.stats
as
stat
import
scipy.stats
as
stat
from
CoreObject
import
CoreObject
from
CoreObject
import
CoreObject
#the Dismantle object
# ===========================================================================
# the Dismantle object
# ===========================================================================
class
Dismantle
(
CoreObject
):
class
Dismantle
(
CoreObject
):
# =======================================================================
#initialize the object
# initialize the object
# =======================================================================
def
__init__
(
self
,
id
,
name
,
distribution
=
'Fixed'
,
mean
=
1
,
stdev
=
0.1
,
min
=
0
,
max
=
5
):
def
__init__
(
self
,
id
,
name
,
distribution
=
'Fixed'
,
mean
=
1
,
stdev
=
0.1
,
min
=
0
,
max
=
5
):
CoreObject
.
__init__
(
self
)
CoreObject
.
__init__
(
self
)
self
.
id
=
id
self
.
id
=
id
...
@@ -63,13 +66,15 @@ class Dismantle(CoreObject):
...
@@ -63,13 +66,15 @@ class Dismantle(CoreObject):
self
.
Working
=
[]
self
.
Working
=
[]
self
.
Blockage
=
[]
self
.
Blockage
=
[]
#
============================== variable that is used for the loading of machines =============
#
variable that is used for the loading of machines
self
.
exitAssignedToReceiver
=
False
# by default the objects are not blocked
self
.
exitAssignedToReceiver
=
False
# by default the objects are not blocked
# when the entities have to be loaded to operatedMachines
# when the entities have to be loaded to operatedMachines
# then the giverObjects have to be blocked for the time
# then the giverObjects have to be blocked for the time
# that the machine is being loaded
# that the machine is being loaded
# =======================================================================
# the initialize method
# =======================================================================
def
initialize
(
self
):
def
initialize
(
self
):
Process
.
__init__
(
self
)
Process
.
__init__
(
self
)
CoreObject
.
initialize
(
self
)
CoreObject
.
initialize
(
self
)
...
@@ -91,8 +96,6 @@ class Dismantle(CoreObject):
...
@@ -91,8 +96,6 @@ class Dismantle(CoreObject):
self
.
processingTimeOfCurrentEntity
=
0
#holds the total processing time that the current entity required
self
.
processingTimeOfCurrentEntity
=
0
#holds the total processing time that the current entity required
self
.
totalBlockageTime
=
0
#holds the total blockage time
self
.
totalBlockageTime
=
0
#holds the total blockage time
self
.
totalWaitingTime
=
0
#holds the total waiting time
self
.
totalWaitingTime
=
0
#holds the total waiting time
self
.
totalWorkingTime
=
0
#holds the total working time
self
.
totalWorkingTime
=
0
#holds the total working time
...
@@ -108,7 +111,9 @@ class Dismantle(CoreObject):
...
@@ -108,7 +111,9 @@ class Dismantle(CoreObject):
self
.
Res
.
activeQ
=
[]
self
.
Res
.
activeQ
=
[]
self
.
Res
.
waitQ
=
[]
self
.
Res
.
waitQ
=
[]
# =======================================================================
# the run method
# =======================================================================
def
run
(
self
):
def
run
(
self
):
while
1
:
while
1
:
yield
waituntil
,
self
,
self
.
canAcceptAndIsRequested
#wait until the Assembly can accept a frame
yield
waituntil
,
self
,
self
.
canAcceptAndIsRequested
#wait until the Assembly can accept a frame
...
@@ -136,21 +141,30 @@ class Dismantle(CoreObject):
...
@@ -136,21 +141,30 @@ class Dismantle(CoreObject):
self
.
waitToDisposeFrame
=
False
#the Dismantle has no Frame to dispose now
self
.
waitToDisposeFrame
=
False
#the Dismantle has no Frame to dispose now
#self.totalBlockageTime+=now()-startBlockageTime #add the blockage time
#self.totalBlockageTime+=now()-startBlockageTime #add the blockage time
# =======================================================================
#checks if the Dismantle can accept an entity and there is a Frame waiting for it
# checks if the Dismantle can accept an entity and there is a Frame
# waiting for it
# =======================================================================
def
canAcceptAndIsRequested
(
self
):
def
canAcceptAndIsRequested
(
self
):
return
len
(
self
.
getActiveObjectQueue
())
==
0
and
self
.
getGiverObject
().
haveToDispose
(
self
)
return
len
(
self
.
getActiveObjectQueue
())
==
0
and
self
.
getGiverObject
().
haveToDispose
(
self
)
#checks if the Dismantle can accept an entity
# =======================================================================
# checks if the Dismantle can accept an entity
# =======================================================================
def
canAccept
(
self
,
callerObject
=
None
):
def
canAccept
(
self
,
callerObject
=
None
):
return
len
(
self
.
getActiveObjectQueue
())
==
0
return
len
(
self
.
getActiveObjectQueue
())
==
0
#defines where parts and frames go after they leave the object
# =======================================================================
# defines where parts and frames go after they leave the object
# =======================================================================
def
definePartFrameRouting
(
self
,
successorPartList
=
[],
successorFrameList
=
[]):
def
definePartFrameRouting
(
self
,
successorPartList
=
[],
successorFrameList
=
[]):
self
.
nextPart
=
successorPartList
self
.
nextPart
=
successorPartList
self
.
nextFrame
=
successorFrameList
self
.
nextFrame
=
successorFrameList
#checks if the caller waits for a part or a frame and if the Dismantle is in the state of disposing one it returnse true
# =======================================================================
# checks if the caller waits for a part or a frame and if the Dismantle
# is in the state of disposing one it returnse true
# =======================================================================
def
haveToDispose
(
self
,
callerObject
=
None
):
def
haveToDispose
(
self
,
callerObject
=
None
):
thecaller
=
callerObject
thecaller
=
callerObject
...
@@ -165,16 +179,22 @@ class Dismantle(CoreObject):
...
@@ -165,16 +179,22 @@ class Dismantle(CoreObject):
self
.
receiver
=
thecaller
self
.
receiver
=
thecaller
return
True
return
True
return
False
return
False
#checks if the frame is emptied
# =======================================================================
# checks if the frame is emptied
# =======================================================================
def
frameIsEmpty
(
self
):
def
frameIsEmpty
(
self
):
return
len
(
self
.
getActiveObjectQueue
())
==
1
return
len
(
self
.
getActiveObjectQueue
())
==
1
#checks if Dismantle is emptied
# =======================================================================
# checks if Dismantle is emptied
# =======================================================================
def
isEmpty
(
self
):
def
isEmpty
(
self
):
return
len
(
self
.
getActiveObjectQueue
())
==
0
return
len
(
self
.
getActiveObjectQueue
())
==
0
#gets a frame from the giver
# =======================================================================
# gets a frame from the giver
# =======================================================================
def
getEntity
(
self
):
def
getEntity
(
self
):
activeEntity
=
CoreObject
.
getEntity
(
self
)
#run the default method
activeEntity
=
CoreObject
.
getEntity
(
self
)
#run the default method
activeObjectQueue
=
self
.
getActiveObjectQueue
()
activeObjectQueue
=
self
.
getActiveObjectQueue
()
...
@@ -189,10 +209,12 @@ class Dismantle(CoreObject):
...
@@ -189,10 +209,12 @@ class Dismantle(CoreObject):
activeObjectQueue
.
pop
(
0
)
activeObjectQueue
.
pop
(
0
)
return
activeEntity
return
activeEntity
#removes an entity from the Dismantle
# =======================================================================
# removes an entity from the Dismantle
# =======================================================================
def
removeEntity
(
self
):
def
removeEntity
(
self
):
activeObjectQueue
=
self
.
getActiveObjectQueue
()
activeObjectQueue
=
self
.
getActiveObjectQueue
()
activeEntity
=
CoreObject
.
removeEntity
(
self
)
#run the default method
activeEntity
=
CoreObject
.
removeEntity
(
self
)
#run the default method
#update the flags
#update the flags
if
(
len
(
activeObjectQueue
)
==
0
):
if
(
len
(
activeObjectQueue
)
==
0
):
...
@@ -202,7 +224,9 @@ class Dismantle(CoreObject):
...
@@ -202,7 +224,9 @@ class Dismantle(CoreObject):
self
.
waitToDisposePart
=
False
self
.
waitToDisposePart
=
False
return
activeEntity
return
activeEntity
#add the blockage only if the very last Entity (Frame) is to depart
# =======================================================================
# add the blockage only if the very last Entity (Frame) is to depart
# =======================================================================
def
addBlockage
(
self
):
def
addBlockage
(
self
):
if
len
(
self
.
getActiveObjectQueue
())
==
1
:
if
len
(
self
.
getActiveObjectQueue
())
==
1
:
self
.
totalTimeInCurrentEntity
=
now
()
-
self
.
timeLastEntityEntered
self
.
totalTimeInCurrentEntity
=
now
()
-
self
.
timeLastEntityEntered
...
@@ -210,8 +234,9 @@ class Dismantle(CoreObject):
...
@@ -210,8 +234,9 @@ class Dismantle(CoreObject):
blockage
=
now
()
-
(
self
.
timeLastEntityEnded
+
self
.
downTimeInTryingToReleaseCurrentEntity
)
blockage
=
now
()
-
(
self
.
timeLastEntityEnded
+
self
.
downTimeInTryingToReleaseCurrentEntity
)
self
.
totalBlockageTime
+=
blockage
self
.
totalBlockageTime
+=
blockage
# =======================================================================
#actions to be taken after the simulation ends
# actions to be taken after the simulation ends
# =======================================================================
def
postProcessing
(
self
,
MaxSimtime
=
None
):
def
postProcessing
(
self
,
MaxSimtime
=
None
):
if
MaxSimtime
==
None
:
if
MaxSimtime
==
None
:
from
Globals
import
G
from
Globals
import
G
...
@@ -234,8 +259,10 @@ class Dismantle(CoreObject):
...
@@ -234,8 +259,10 @@ class Dismantle(CoreObject):
self
.
Working
.
append
(
100
*
self
.
totalWorkingTime
/
MaxSimtime
)
self
.
Working
.
append
(
100
*
self
.
totalWorkingTime
/
MaxSimtime
)
self
.
Blockage
.
append
(
100
*
self
.
totalBlockageTime
/
MaxSimtime
)
self
.
Blockage
.
append
(
100
*
self
.
totalBlockageTime
/
MaxSimtime
)
# =======================================================================
#outputs message to the trace.xls. Format is (Simulation Time | Entity or Frame Name | message)
# outputs message to the trace.xls.
# Format is (Simulation Time | Entity or Frame Name | message)
# =======================================================================
def
outputTrace
(
self
,
name
,
message
):
def
outputTrace
(
self
,
name
,
message
):
from
Globals
import
G
from
Globals
import
G
if
(
G
.
trace
==
"Yes"
):
#output only if the user has selected to
if
(
G
.
trace
==
"Yes"
):
#output only if the user has selected to
...
@@ -250,8 +277,9 @@ class Dismantle(CoreObject):
...
@@ -250,8 +277,9 @@ class Dismantle(CoreObject):
G
.
sheetIndex
+=
1
G
.
sheetIndex
+=
1
G
.
traceSheet
=
G
.
traceFile
.
add_sheet
(
'sheet '
+
str
(
G
.
sheetIndex
),
cell_overwrite_ok
=
True
)
G
.
traceSheet
=
G
.
traceFile
.
add_sheet
(
'sheet '
+
str
(
G
.
sheetIndex
),
cell_overwrite_ok
=
True
)
# =======================================================================
#outputs data to "output.xls"
# outputs data to "output.xls"
# =======================================================================
def
outputResultsXL
(
self
,
MaxSimtime
=
None
):
def
outputResultsXL
(
self
,
MaxSimtime
=
None
):
from
Globals
import
G
from
Globals
import
G
if
MaxSimtime
==
None
:
if
MaxSimtime
==
None
:
...
@@ -302,8 +330,10 @@ class Dismantle(CoreObject):
...
@@ -302,8 +330,10 @@ class Dismantle(CoreObject):
G
.
outputSheet
.
write
(
G
.
outputIndex
,
3
,
self
.
Waiting
[
0
])
G
.
outputSheet
.
write
(
G
.
outputIndex
,
3
,
self
.
Waiting
[
0
])
G
.
outputIndex
+=
1
G
.
outputIndex
+=
1
G
.
outputIndex
+=
1
G
.
outputIndex
+=
1
#outputs results to JSON File
# =======================================================================
# outputs results to JSON File
# =======================================================================
def
outputResultsJSON
(
self
):
def
outputResultsJSON
(
self
):
from
Globals
import
G
from
Globals
import
G
if
(
G
.
numberOfReplications
==
1
):
#if we had just one replication output the results to excel
if
(
G
.
numberOfReplications
==
1
):
#if we had just one replication output the results to excel
...
...
dream/simulation/Globals.py
View file @
9cd884a0
...
@@ -34,7 +34,9 @@ import xlrd
...
@@ -34,7 +34,9 @@ import xlrd
from
random
import
Random
,
expovariate
,
gammavariate
,
normalvariate
from
random
import
Random
,
expovariate
,
gammavariate
,
normalvariate
from
SimPy.Simulation
import
now
from
SimPy.Simulation
import
now
# ===========================================================================
# globals
# globals
# ===========================================================================
class
G
:
class
G
:
seed
=
1450
#the seed of the random number generator
seed
=
1450
#the seed of the random number generator
Rnd
=
Random
(
seed
)
#random number generator
Rnd
=
Random
(
seed
)
#random number generator
...
@@ -49,7 +51,7 @@ class G:
...
@@ -49,7 +51,7 @@ class G:
maxSimTime
=
0
#the total simulation time
maxSimTime
=
0
#the total simulation time
# data for the trace output in excel
# data for the trace output in excel
#
=======================================================================
#
-----------------------------------------------------------------------
trace
=
""
#this is written from input. If it is "Yes" then you write to trace, else we do not
trace
=
""
#this is written from input. If it is "Yes" then you write to trace, else we do not
traceIndex
=
0
#index that shows in what row we are
traceIndex
=
0
#index that shows in what row we are
sheetIndex
=
1
#index that shows in what sheet we are
sheetIndex
=
1
#index that shows in what sheet we are
...
@@ -58,19 +60,22 @@ class G:
...
@@ -58,19 +60,22 @@ class G:
# variables for excel output
# variables for excel output
#
=======================================================================
#
-----------------------------------------------------------------------
outputIndex
=
0
#index that shows in what row we are
outputIndex
=
0
#index that shows in what row we are
sheetIndex
=
1
#index that shows in what sheet we are
sheetIndex
=
1
#index that shows in what sheet we are
outputFile
=
xlwt
.
Workbook
()
#create excel file
outputFile
=
xlwt
.
Workbook
()
#create excel file
outputSheet
=
outputFile
.
add_sheet
(
'sheet '
+
str
(
sheetIndex
),
cell_overwrite_ok
=
True
)
#create excel sheet
outputSheet
=
outputFile
.
add_sheet
(
'sheet '
+
str
(
sheetIndex
),
cell_overwrite_ok
=
True
)
#create excel sheet
#variables for json output
#variables for json output
#
=======================================================================
#
-----------------------------------------------------------------------
outputJSON
=
{}
outputJSON
=
{}
outputJSONFile
=
None
outputJSONFile
=
None
numberOfEntities
=
0
numberOfEntities
=
0
# =======================================================================
# method to move entities exceeding a certain safety stock
# =======================================================================
def
moveExcess
(
argumentDict
=
{}):
def
moveExcess
(
argumentDict
=
{}):
giver
=
findObjectById
(
argumentDict
.
get
(
'from'
,
None
))
giver
=
findObjectById
(
argumentDict
.
get
(
'from'
,
None
))
receiver
=
findObjectById
(
argumentDict
.
get
(
'to'
,
None
))
receiver
=
findObjectById
(
argumentDict
.
get
(
'to'
,
None
))
...
@@ -87,20 +92,29 @@ def moveExcess(argumentDict={}):
...
@@ -87,20 +92,29 @@ def moveExcess(argumentDict={}):
else
:
else
:
print
"Giver and/or Receiver not defined"
print
"Giver and/or Receiver not defined"
# =======================================================================
# method finding objects by ID
# =======================================================================
def
findObjectById
(
id
):
def
findObjectById
(
id
):
for
obj
in
G
.
ObjList
:
for
obj
in
G
.
ObjList
:
if
obj
.
id
==
id
:
if
obj
.
id
==
id
:
return
obj
return
obj
return
None
return
None
# =======================================================================
# method to set-up the entities in the current stations
# as Work In Progress
# =======================================================================
def
setWIP
(
entityList
):
def
setWIP
(
entityList
):
for
entity
in
entityList
:
for
entity
in
entityList
:
# if the entity is of type Part
if
entity
.
type
==
'Part'
:
if
entity
.
type
==
'Part'
:
object
=
entity
.
currentStation
#identify the object
object
=
entity
.
currentStation
#identify the object
object
.
getActiveObjectQueue
().
append
(
entity
)
#append the entity to its Queue
object
.
getActiveObjectQueue
().
append
(
entity
)
#append the entity to its Queue
entity
.
schedule
.
append
([
object
,
now
()])
#append the time to schedule so that it can be read in the result
entity
.
schedule
.
append
([
object
,
now
()])
#append the time to schedule so that it can be read in the result
# if the entity is of type Job/OrderComponent/Order
elif
entity
.
type
==
'Job'
or
'OrderComponent'
or
'Order'
:
elif
entity
.
type
==
'Job'
or
'OrderComponent'
or
'Order'
:
object
=
findObjectById
(
entity
.
remainingRoute
[
0
][
0
])
# find the object in the 'G.ObjList
object
=
findObjectById
(
entity
.
remainingRoute
[
0
][
0
])
# find the object in the 'G.ObjList'
object
.
getActiveObjectQueue
().
append
(
entity
)
# append the entity to its Queue
object
.
getActiveObjectQueue
().
append
(
entity
)
# append the entity to its Queue
object
.
receiver
=
findObjectById
(
entity
.
remainingRoute
[
1
][
0
])
object
.
receiver
=
findObjectById
(
entity
.
remainingRoute
[
1
][
0
])
entity
.
remainingRoute
.
pop
(
0
)
# remove data from the remaining route.
entity
.
remainingRoute
.
pop
(
0
)
# remove data from the remaining route.
...
...
dream/simulation/Job.py
View file @
9cd884a0
...
@@ -29,7 +29,9 @@ in the system and also in the processing times at each station
...
@@ -29,7 +29,9 @@ in the system and also in the processing times at each station
from
Globals
import
G
from
Globals
import
G
from
Entity
import
Entity
from
Entity
import
Entity
# ============================ The job object ==============================
# =======================================================================
# The job object
# =======================================================================
class
Job
(
Entity
):
# inherits from the Entity class
class
Job
(
Entity
):
# inherits from the Entity class
type
=
"Job"
type
=
"Job"
...
@@ -43,11 +45,13 @@ class Job(Entity): # inherits from the Entity c
...
@@ -43,11 +45,13 @@ class Job(Entity): # inherits from the Entity c
self
.
remainingRoute
=
list
(
route
)
# the remaining route. in the beginning
self
.
remainingRoute
=
list
(
route
)
# the remaining route. in the beginning
# this should be the same as the full route
# this should be the same as the full route
# the scheduling of the entity as resolved by the simulation
# the scheduling of the entity as resolved by the simulation
self
.
schedule
=
[]
# keeps the result of the simulation.
#
self.schedule=[] # keeps the result of the simulation.
# A list with the stations and time of entrance
#
# A list with the stations and time of entrance
self
.
extraPropertyDict
=
extraPropertyDict
self
.
extraPropertyDict
=
extraPropertyDict
#==================== outputs results to JSON File ======================
# =======================================================================
# outputs results to JSON File
# =======================================================================
def
outputResultsJSON
(
self
):
def
outputResultsJSON
(
self
):
from
Globals
import
G
from
Globals
import
G
if
(
G
.
numberOfReplications
==
1
):
#if we had just one replication output the results to excel
if
(
G
.
numberOfReplications
==
1
):
#if we had just one replication output the results to excel
...
@@ -73,14 +77,16 @@ class Job(Entity): # inherits from the Entity c
...
@@ -73,14 +77,16 @@ class Job(Entity): # inherits from the Entity c
json
[
'results'
][
'schedule'
]
=
[]
json
[
'results'
][
'schedule'
]
=
[]
i
=
0
i
=
0
for
record
in
self
.
schedule
:
for
record
in
self
.
schedule
:
json
[
'results'
][
'schedule'
].
append
({})
# dictionary holding time and
json
[
'results'
][
'schedule'
].
append
({})
# dictionary holding time and
json
[
'results'
][
'schedule'
][
i
][
'stepNumber'
]
=
i
#the step number
json
[
'results'
][
'schedule'
][
i
][
'stepNumber'
]
=
i
#
the step number
json
[
'results'
][
'schedule'
][
i
][
'stationId'
]
=
record
[
0
].
id
# id of the Object
json
[
'results'
][
'schedule'
][
i
][
'stationId'
]
=
record
[
0
].
id
# id of the Object
json
[
'results'
][
'schedule'
][
i
][
'entranceTime'
]
=
record
[
1
]
# time entering the Object
json
[
'results'
][
'schedule'
][
i
][
'entranceTime'
]
=
record
[
1
]
# time entering the Object
i
+=
1
i
+=
1
G
.
outputJSON
[
'elementList'
].
append
(
json
)
G
.
outputJSON
[
'elementList'
].
append
(
json
)
# ==== initializes all the Entity for a new simulation replication ======
# =======================================================================
# initializes all the Entity for a new simulation replication
# =======================================================================
def
initialize
(
self
):
def
initialize
(
self
):
# has to be re-initialized each time a new Job is added
# has to be re-initialized each time a new Job is added
self
.
remainingRoute
=
list
(
self
.
route
)
self
.
remainingRoute
=
list
(
self
.
route
)
...
...
dream/simulation/LineGenerationJSON.py
View file @
9cd884a0
...
@@ -691,7 +691,6 @@ def createObjects():
...
@@ -691,7 +691,6 @@ def createObjects():
if
possible_successor
.
id
==
nextId
:
if
possible_successor
.
id
==
nextId
:
possible_successor
.
previousIds
.
append
(
element
.
id
)
possible_successor
.
previousIds
.
append
(
element
.
id
)
# ===========================================================================
# ===========================================================================
# defines the topology (predecessors and successors for all the objects)
# defines the topology (predecessors and successors for all the objects)
# ===========================================================================
# ===========================================================================
...
@@ -914,7 +913,10 @@ def createWIP():
...
@@ -914,7 +913,10 @@ def createWIP():
orderDate
=
float
(
entity
.
get
(
'orderDate'
,
'0'
))
orderDate
=
float
(
entity
.
get
(
'orderDate'
,
'0'
))
isCritical
=
bool
(
int
(
entity
.
get
(
'isCritical'
,
'0'
)))
isCritical
=
bool
(
int
(
entity
.
get
(
'isCritical'
,
'0'
)))
basicsEnded
=
bool
(
int
(
entity
.
get
(
'basicsEnded'
,
'0'
)))
basicsEnded
=
bool
(
int
(
entity
.
get
(
'basicsEnded'
,
'0'
)))
# read the manager ID
manager
=
entity
.
get
(
'manager'
,
None
)
manager
=
entity
.
get
(
'manager'
,
None
)
# if a manager ID is assigned then search for the operator with the corresponding ID
# and assign it as the manager of the order
if
manager
:
if
manager
:
for
operator
in
G
.
OperatorsList
:
for
operator
in
G
.
OperatorsList
:
if
manager
==
operator
.
id
:
if
manager
==
operator
.
id
:
...
@@ -968,7 +970,6 @@ def createWIP():
...
@@ -968,7 +970,6 @@ def createWIP():
G
.
WipList
.
append
(
O
)
G
.
WipList
.
append
(
O
)
G
.
EntityList
.
append
(
O
)
G
.
EntityList
.
append
(
O
)
# ===========================================================================
# ===========================================================================
# reads the interruptions of the stations
# reads the interruptions of the stations
# ===========================================================================
# ===========================================================================
...
@@ -980,9 +981,12 @@ def createObjectInterruptions():
...
@@ -980,9 +981,12 @@ def createObjectInterruptions():
json_data
=
G
.
JSONData
json_data
=
G
.
JSONData
#Read the json data
#Read the json data
nodes
=
json_data
[
'nodes'
]
# read from the dictionary the dicts with key 'nodes'
nodes
=
json_data
[
'nodes'
]
# read from the dictionary the dicts with key 'nodes'
# for the elements in the nodes dict
for
(
element_id
,
element
)
in
nodes
.
iteritems
():
for
(
element_id
,
element
)
in
nodes
.
iteritems
():
element
[
'id'
]
=
element_id
element
[
'id'
]
=
element_id
scheduledMaintenance
=
element
.
get
(
'scheduledMaintenance'
,
{})
scheduledMaintenance
=
element
.
get
(
'scheduledMaintenance'
,
{})
# if there is a scheduled maintenance initiate it and append it
# to the interruptions- and scheduled maintenances- list
if
len
(
scheduledMaintenance
):
if
len
(
scheduledMaintenance
):
start
=
float
(
scheduledMaintenance
.
get
(
'start'
,
0
))
start
=
float
(
scheduledMaintenance
.
get
(
'start'
,
0
))
duration
=
float
(
scheduledMaintenance
.
get
(
'duration'
,
1
))
duration
=
float
(
scheduledMaintenance
.
get
(
'duration'
,
1
))
...
@@ -990,7 +994,9 @@ def createObjectInterruptions():
...
@@ -990,7 +994,9 @@ def createObjectInterruptions():
SM
=
ScheduledMaintenance
(
victim
=
victim
,
start
=
start
,
duration
=
duration
)
SM
=
ScheduledMaintenance
(
victim
=
victim
,
start
=
start
,
duration
=
duration
)
G
.
ObjectInterruptionList
.
append
(
SM
)
G
.
ObjectInterruptionList
.
append
(
SM
)
G
.
ScheduledMaintenanceList
.
append
(
SM
)
G
.
ScheduledMaintenanceList
.
append
(
SM
)
failure
=
element
.
get
(
'failures'
,
{})
failure
=
element
.
get
(
'failures'
,
{})
# if there are failures assigned
# initiate them
if
len
(
failure
):
if
len
(
failure
):
distributionType
=
failure
.
get
(
'failureDistribution'
,
'No'
)
distributionType
=
failure
.
get
(
'failureDistribution'
,
'No'
)
if
distributionType
==
'No'
:
if
distributionType
==
'No'
:
...
@@ -1004,15 +1010,12 @@ def createObjectInterruptions():
...
@@ -1004,15 +1010,12 @@ def createObjectInterruptions():
G
.
ObjectInterruptionList
.
append
(
F
)
G
.
ObjectInterruptionList
.
append
(
F
)
G
.
FailureList
.
append
(
F
)
G
.
FailureList
.
append
(
F
)
# ===========================================================================
# ===========================================================================
# used to convert a string read from the input to object type
# used to convert a string read from the input to object type
# ===========================================================================
# ===========================================================================
def
str_to_class
(
str
):
def
str_to_class
(
str
):
return
getattr
(
sys
.
modules
[
__name__
],
str
)
return
getattr
(
sys
.
modules
[
__name__
],
str
)
# ===========================================================================
# ===========================================================================
# the main script that is ran
# the main script that is ran
# ===========================================================================
# ===========================================================================
...
...
dream/simulation/MachinePreemptive.py
View file @
9cd884a0
...
@@ -27,7 +27,9 @@ inherits from MachineJobShop it can preempt the currently processed Entity if ne
...
@@ -27,7 +27,9 @@ inherits from MachineJobShop it can preempt the currently processed Entity if ne
from
MachineJobShop
import
MachineJobShop
from
MachineJobShop
import
MachineJobShop
from
SimPy.Simulation
import
reactivate
,
now
from
SimPy.Simulation
import
reactivate
,
now
#the MachineJobShop object
# ===========================================================================
# the MachineJobShop object
# ===========================================================================
class
MachinePreemptive
(
MachineJobShop
):
class
MachinePreemptive
(
MachineJobShop
):
def
__init__
(
self
,
id
,
name
,
capacity
=
1
,
distribution
=
'Fixed'
,
mean
=
1
,
stdev
=
0
,
min
=
0
,
max
=
10
,
\
def
__init__
(
self
,
id
,
name
,
capacity
=
1
,
distribution
=
'Fixed'
,
mean
=
1
,
stdev
=
0
,
min
=
0
,
max
=
10
,
\
...
@@ -41,7 +43,9 @@ class MachinePreemptive(MachineJobShop):
...
@@ -41,7 +43,9 @@ class MachinePreemptive(MachineJobShop):
self
.
lastGiver
=
self
.
giver
self
.
lastGiver
=
self
.
giver
return
activeEntity
return
activeEntity
#method to execute the preemption
# =======================================================================
# method to execute the preemption
# =======================================================================
def
preempt
(
self
):
def
preempt
(
self
):
activeEntity
=
self
.
getActiveObjectQueue
()[
0
]
#get the active Entity
activeEntity
=
self
.
getActiveObjectQueue
()[
0
]
#get the active Entity
#calculate the remaining processing time
#calculate the remaining processing time
...
@@ -55,9 +59,9 @@ class MachinePreemptive(MachineJobShop):
...
@@ -55,9 +59,9 @@ class MachinePreemptive(MachineJobShop):
#update the remaining route of activeEntity
#update the remaining route of activeEntity
activeEntity
.
remainingRoute
.
insert
(
0
,
[
self
.
id
,
remainingProcessingTime
])
activeEntity
.
remainingRoute
.
insert
(
0
,
[
self
.
id
,
remainingProcessingTime
])
activeEntity
.
remainingRoute
.
insert
(
0
,
[
self
.
lastGiver
.
id
,
0
])
activeEntity
.
remainingRoute
.
insert
(
0
,
[
self
.
lastGiver
.
id
,
0
])
#set the receiver as the object where the active entity was
preempted from
#set the receiver as the object where the active entity was preempted from
self
.
receiver
=
self
.
lastGiver
self
.
receiver
=
self
.
lastGiver
self
.
waitToDispose
=
True
#set
that I have to dispose
self
.
waitToDispose
=
True
#set that I have to dispose
reactivate
(
self
)
reactivate
(
self
)
...
...
dream/simulation/Order.py
View file @
9cd884a0
...
@@ -28,7 +28,9 @@ Order is an Entity that can have its design, get broken to sub-components
...
@@ -28,7 +28,9 @@ Order is an Entity that can have its design, get broken to sub-components
from
Globals
import
G
from
Globals
import
G
from
Job
import
Job
from
Job
import
Job
# ============================ The Order object ==============================
# =======================================================================
# The Order object
# =======================================================================
class
Order
(
Job
):
class
Order
(
Job
):
type
=
"Order"
type
=
"Order"
...
@@ -36,10 +38,10 @@ class Order(Job):
...
@@ -36,10 +38,10 @@ class Order(Job):
componentsList
=
[],
manager
=
None
,
basicsEnded
=
False
,
extraPropertyDict
=
None
):
componentsList
=
[],
manager
=
None
,
basicsEnded
=
False
,
extraPropertyDict
=
None
):
Job
.
__init__
(
self
,
id
=
id
,
name
=
name
,
route
=
route
,
priority
=
priority
,
dueDate
=
dueDate
,
orderDate
=
orderDate
,
Job
.
__init__
(
self
,
id
=
id
,
name
=
name
,
route
=
route
,
priority
=
priority
,
dueDate
=
dueDate
,
orderDate
=
orderDate
,
extraPropertyDict
=
extraPropertyDict
)
extraPropertyDict
=
extraPropertyDict
)
self
.
isCritical
=
isCritical
self
.
isCritical
=
isCritical
# flag to inform weather the order is critical -> preemption
self
.
componentsList
=
componentsList
self
.
componentsList
=
componentsList
# list of components that the order will be broken into
self
.
manager
=
manager
self
.
manager
=
manager
# the manager responsible to handle the order
self
.
basicsEnded
=
basicsEnded
self
.
basicsEnded
=
basicsEnded
# flag that informs that the basic components of the order are finished
dream/simulation/OrderComponent.py
View file @
9cd884a0
...
@@ -35,6 +35,6 @@ class OrderComponent(Job): # inherits from the
...
@@ -35,6 +35,6 @@ class OrderComponent(Job): # inherits from the
def
__init__
(
self
,
id
=
None
,
name
=
None
,
route
=
[],
priority
=
0
,
dueDate
=
None
,
orderDate
=
None
,
extraPropertyDict
=
None
,
def
__init__
(
self
,
id
=
None
,
name
=
None
,
route
=
[],
priority
=
0
,
dueDate
=
None
,
orderDate
=
None
,
extraPropertyDict
=
None
,
componentType
=
'Basic'
,
order
=
None
,
isCritical
=
False
):
componentType
=
'Basic'
,
order
=
None
,
isCritical
=
False
):
Job
.
__init__
(
self
,
id
,
name
,
route
,
priority
,
dueDate
,
orderDate
,
extraPropertyDict
)
Job
.
__init__
(
self
,
id
,
name
,
route
,
priority
,
dueDate
,
orderDate
,
extraPropertyDict
)
self
.
auxiliaryList
=
[]
self
.
auxiliaryList
=
[]
# Holds the auxiliary components that the component needs for a certain processing
self
.
order
=
order
self
.
order
=
order
# parent order of the order component
self
.
isCritical
=
isCritical
#this should be self.order.isCritical. Added now for testing
self
.
isCritical
=
isCritical
#
this should be self.order.isCritical. Added now for testing
dream/simulation/OrderDecomposition.py
View file @
9cd884a0
...
@@ -47,6 +47,9 @@ class OrderDecomposition(CoreObject):
...
@@ -47,6 +47,9 @@ class OrderDecomposition(CoreObject):
self
.
objName
=
name
self
.
objName
=
name
self
.
type
=
'OrderDecomposition'
self
.
type
=
'OrderDecomposition'
# =======================================================================
# the initialize method
# =======================================================================
def
initialize
(
self
):
def
initialize
(
self
):
self
.
previous
=
G
.
ObjList
self
.
previous
=
G
.
ObjList
self
.
next
=
G
.
ObjList
self
.
next
=
G
.
ObjList
...
@@ -56,20 +59,25 @@ class OrderDecomposition(CoreObject):
...
@@ -56,20 +59,25 @@ class OrderDecomposition(CoreObject):
self
.
newlyCreatedComponents
=
[]
# a list to hold components just after decomposition
self
.
newlyCreatedComponents
=
[]
# a list to hold components just after decomposition
self
.
orderToBeDecomposed
=
None
self
.
orderToBeDecomposed
=
None
#run just waits until there is something to get and gets it
# =======================================================================
# run just waits until there is something to get and gets it
# =======================================================================
def
run
(
self
):
def
run
(
self
):
while
1
:
while
1
:
yield
waituntil
,
self
,
self
.
canAcceptAndIsRequested
#wait until the Queue can accept an entity
yield
waituntil
,
self
,
self
.
canAcceptAndIsRequested
#wait until the Queue can accept an entity
#and one predecessor requests it
#and one predecessor requests it
self
.
getEntity
()
self
.
getEntity
()
self
.
decompose
()
self
.
decompose
()
# =======================================================================
# as a dummy object can always accept
# =======================================================================
def
canAccept
(
self
,
callerObject
=
None
):
def
canAccept
(
self
,
callerObject
=
None
):
return
True
return
True
# =======================================================================
# =======================================================================
# checks if the OrderDecomposition can accept an entity
and there is an entity in
# checks if the OrderDecomposition can accept an entity
# some possible giver waiting for it
#
and there is an entity in
some possible giver waiting for it
# 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
):
def
canAcceptAndIsRequested
(
self
):
...
@@ -104,7 +112,8 @@ class OrderDecomposition(CoreObject):
...
@@ -104,7 +112,8 @@ class OrderDecomposition(CoreObject):
return
activeObject
.
Up
and
isRequested
return
activeObject
.
Up
and
isRequested
# =======================================================================
# =======================================================================
# checks if the OrderDecomposition can dispose an entity to the following object
# checks if the OrderDecomposition can dispose
# an entity to the following object
# =======================================================================
# =======================================================================
def
haveToDispose
(
self
,
callerObject
=
None
):
def
haveToDispose
(
self
,
callerObject
=
None
):
activeObjectQueue
=
self
.
getActiveObjectQueue
()
activeObjectQueue
=
self
.
getActiveObjectQueue
()
...
@@ -117,15 +126,17 @@ class OrderDecomposition(CoreObject):
...
@@ -117,15 +126,17 @@ class OrderDecomposition(CoreObject):
self
.
receiver
=
Globals
.
findObjectById
(
activeEntity
.
remainingRoute
[
0
][
0
])
#read the next station
self
.
receiver
=
Globals
.
findObjectById
(
activeEntity
.
remainingRoute
[
0
][
0
])
#read the next station
#return True if the OrderDecomposition in the state of disposing and the caller is the receiver
#return True if the OrderDecomposition in the state of disposing and the caller is the receiver
return
self
.
Up
and
(
callerObject
is
self
.
receiver
)
return
self
.
Up
and
(
callerObject
is
self
.
receiver
)
#decomposes the order to its components
# =======================================================================
# decomposes the order to its components
# =======================================================================
def
decompose
(
self
):
def
decompose
(
self
):
activeObjectQueue
=
self
.
getActiveObjectQueue
()
activeObjectQueue
=
self
.
getActiveObjectQueue
()
#loop in the internal Queue. Decompose only if an Entity is of type order
#loop in the internal Queue. Decompose only if an Entity is of type order
for
entity
in
activeObjectQueue
:
for
entity
in
activeObjectQueue
:
if
entity
.
type
==
'Order'
:
if
entity
.
type
==
'Order'
:
self
.
orderToBeDecomposed
=
entity
self
.
orderToBeDecomposed
=
entity
activeObjectQueue
.
remove
(
entity
)
#remove the order from the internal Queue
activeObjectQueue
.
remove
(
entity
)
#remove the order from the internal Queue
#append the components in the internal queue
#append the components in the internal queue
for
component
in
entity
.
componentsList
:
for
component
in
entity
.
componentsList
:
self
.
createOrderComponent
(
component
)
self
.
createOrderComponent
(
component
)
...
@@ -136,8 +147,10 @@ class OrderDecomposition(CoreObject):
...
@@ -136,8 +147,10 @@ class OrderDecomposition(CoreObject):
#reset attributes
#reset attributes
self
.
orderToBeDecomposed
=
None
self
.
orderToBeDecomposed
=
None
self
.
newlyCreatedComponents
=
[]
self
.
newlyCreatedComponents
=
[]
#creates the components
# =======================================================================
# creates the components
# =======================================================================
def
createOrderComponent
(
self
,
component
):
def
createOrderComponent
(
self
,
component
):
#read attributes fromthe json or from the orderToBeDecomposed
#read attributes fromthe json or from the orderToBeDecomposed
id
=
component
.
get
(
'id'
,
'not found'
)
id
=
component
.
get
(
'id'
,
'not found'
)
...
@@ -145,7 +158,7 @@ class OrderDecomposition(CoreObject):
...
@@ -145,7 +158,7 @@ class OrderDecomposition(CoreObject):
JSONRoute
=
component
.
get
(
'route'
,
[])
# dummy variable that holds the routes of the jobs
JSONRoute
=
component
.
get
(
'route'
,
[])
# dummy variable that holds the routes of the jobs
# the route from the JSON file
# the route from the JSON file
# is a sequence of dictionaries
# is a sequence of dictionaries
route
=
[
None
for
i
in
range
(
len
(
JSONRoute
))]
#
variable that holds the argument used in the Job initiation
route
=
[
None
for
i
in
range
(
len
(
JSONRoute
))]
#
variable that holds the argument used in the Job initiation
# hold None for each entry in the 'route' list
# hold None for each entry in the 'route' list
for
routeentity
in
JSONRoute
:
# for each 'step' dictionary in the JSONRoute
for
routeentity
in
JSONRoute
:
# for each 'step' dictionary in the JSONRoute
...
@@ -190,6 +203,6 @@ class OrderDecomposition(CoreObject):
...
@@ -190,6 +203,6 @@ class OrderDecomposition(CoreObject):
G
.
JobList
.
append
(
OC
)
G
.
JobList
.
append
(
OC
)
G
.
WipList
.
append
(
OC
)
G
.
WipList
.
append
(
OC
)
G
.
EntityList
.
append
(
OC
)
G
.
EntityList
.
append
(
OC
)
self
.
newlyCreatedComponents
.
append
(
OC
)
#keep these to pass them to setWIP
self
.
newlyCreatedComponents
.
append
(
OC
)
#keep these to pass them to setWIP
OC
.
initialize
()
#initialize the component
OC
.
initialize
()
#initialize the component
\ No newline at end of file
dream/simulation/QueuePreemptive.py
View file @
9cd884a0
...
@@ -28,10 +28,13 @@ Inherits from QueueJobShop. If it gets an isCritical Entity it can interrupt the
...
@@ -28,10 +28,13 @@ Inherits from QueueJobShop. If it gets an isCritical Entity it can interrupt the
from
QueueJobShop
import
QueueJobShop
from
QueueJobShop
import
QueueJobShop
from
SimPy.Simulation
import
now
from
SimPy.Simulation
import
now
#the QueuePreemptive object
# ===========================================================================
# the QueuePreemptive object
# ===========================================================================
class
QueuePreemptive
(
QueueJobShop
):
class
QueuePreemptive
(
QueueJobShop
):
# =======================================================================
#extend he default so that it can interrupt the receiver if need be
# extend he default so that it can interrupt the receiver if need be
# =======================================================================
def
getEntity
(
self
):
def
getEntity
(
self
):
activeEntity
=
QueueJobShop
.
getEntity
(
self
)
#execute default behaviour
activeEntity
=
QueueJobShop
.
getEntity
(
self
)
#execute default behaviour
#if the obtained Entity is critical
#if the obtained Entity is critical
...
@@ -43,8 +46,10 @@ class QueuePreemptive(QueueJobShop):
...
@@ -43,8 +46,10 @@ class QueuePreemptive(QueueJobShop):
self
.
receiver
.
shouldPreempt
=
True
self
.
receiver
.
shouldPreempt
=
True
self
.
receiver
.
preempt
()
self
.
receiver
.
preempt
()
self
.
receiver
.
timeLastEntityEnded
=
now
()
#required to count blockage correctly in the preemptied station
self
.
receiver
.
timeLastEntityEnded
=
now
()
#required to count blockage correctly in the preemptied station
#for future use
# =======================================================================
# for future use
# =======================================================================
def
sortEntities
(
self
):
def
sortEntities
(
self
):
QueueJobShop
.
sortEntities
(
self
)
QueueJobShop
.
sortEntities
(
self
)
...
...
dream/simulation/ScheduledMaintenance.py
View file @
9cd884a0
...
@@ -30,15 +30,25 @@ from SimPy.Simulation import now, Process, hold, request, release, infinity
...
@@ -30,15 +30,25 @@ from SimPy.Simulation import now, Process, hold, request, release, infinity
from
RandomNumberGenerator
import
RandomNumberGenerator
from
RandomNumberGenerator
import
RandomNumberGenerator
from
ObjectInterruption
import
ObjectInterruption
from
ObjectInterruption
import
ObjectInterruption
# ===========================================================================
# the scheduled maintenance class
# ===========================================================================
class
ScheduledMaintenance
(
ObjectInterruption
):
class
ScheduledMaintenance
(
ObjectInterruption
):
# =======================================================================
# the __init__() method of the class
# =======================================================================
def
__init__
(
self
,
victim
=
None
,
start
=
0
,
duration
=
1
):
def
__init__
(
self
,
victim
=
None
,
start
=
0
,
duration
=
1
):
ObjectInterruption
.
__init__
(
self
,
victim
)
ObjectInterruption
.
__init__
(
self
,
victim
)
self
.
start
=
start
self
.
start
=
start
self
.
duration
=
duration
self
.
duration
=
duration
# =======================================================================
# the run method
# holds till the defined start time, interrupts the victim,
# holds for the maintenance duration, and finally reactivates the victim
# =======================================================================
def
run
(
self
):
def
run
(
self
):
yield
hold
,
self
,
self
.
start
#wait until the start time
yield
hold
,
self
,
self
.
start
#wait until the start time
try
:
try
:
if
(
len
(
self
.
getVictimQueue
())
>
0
):
# when a Machine gets failure
if
(
len
(
self
.
getVictimQueue
())
>
0
):
# when a Machine gets failure
self
.
interruptVictim
()
# while in process it is interrupted
self
.
interruptVictim
()
# while in process it is interrupted
...
@@ -48,7 +58,7 @@ class ScheduledMaintenance(ObjectInterruption):
...
@@ -48,7 +58,7 @@ class ScheduledMaintenance(ObjectInterruption):
except
AttributeError
:
except
AttributeError
:
print
"AttributeError1"
print
"AttributeError1"
yield
hold
,
self
,
self
.
duration
#wait until the start time
yield
hold
,
self
,
self
.
duration
# wait for the defined duration of the interruption
self
.
victim
.
totalFailureTime
+=
self
.
duration
self
.
victim
.
totalFailureTime
+=
self
.
duration
try
:
try
:
...
...
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