RepeatActivity + stop condition#
This notebook provides an example of a simulation that takes a number of sub_processes, grouped in a SequentialActivity, that is executed in a WhileActivity while a stop condition is not yet met.
For this example we work with the following sub_processes:
sailing empty
loading
sailing full
unloading
0. Import libraries#
import datetime, time
import simpy
import shapely.geometry
import pandas as pd
import openclsim.core as core
import openclsim.model as model
import openclsim.plot as plot
1. Initialise simpy environment#
# setup environment
simulation_start = 0
my_env = simpy.Environment(initial_time=simulation_start)
2. Define object classes#
# create a Site object based on desired mixin classes
Site = type(
"Site",
(
core.Identifiable,
core.Log,
core.Locatable,
core.HasContainer,
core.HasResource,
),
{},
)
# create a TransportProcessingResource object based on desired mixin classes
TransportProcessingResource = type(
"TransportProcessingResource",
(
core.ContainerDependentMovable,
core.Processor,
core.HasResource,
core.LoadingFunction,
core.UnloadingFunction,
core.Identifiable,
core.Log,
),
{},
)
3. Create objects#
3.1. Create site object(s)#
# prepare input data for from_site
location_from_site = shapely.geometry.Point(4.18055556, 52.18664444)
data_from_site = {"env": my_env,
"name": "from_site",
"geometry": location_from_site,
"capacity": 100,
"level": 100
}
# instantiate from_site
from_site = Site(**data_from_site)
# prepare input data for to_site
location_to_site = shapely.geometry.Point(4.25222222, 52.11428333)
data_to_site = {"env": my_env,
"name": "to_site",
"geometry": location_to_site,
"capacity": 100,
"level": 0
}
# instantiate to_site
to_site = Site(**data_to_site)
3.2. Create vessel object(s)#
# prepare input data for vessel_01
data_vessel01 = {"env": my_env,
"name": "vessel01",
"geometry": location_from_site,
"loading_rate": 0.0004,
"unloading_rate": 0.0004,
"capacity": 4,
"compute_v": lambda x: 10
}
# instantiate vessel_01
vessel01 = TransportProcessingResource(**data_vessel01)
3.3 Create activity/activities#
# initialise registry
registry = {}
# create a list of the sub processes
sub_processes = [
model.MoveActivity(
env=my_env,
name="sailing empty",
registry=registry,
mover=vessel01,
destination=from_site,
),
model.ShiftAmountActivity(
env=my_env,
name="loading",
registry=registry,
processor=vessel01,
origin=from_site,
destination=vessel01,
amount=4,
duration=1000,
),
model.MoveActivity(
env=my_env,
name="sailing full",
registry=registry,
mover=vessel01,
destination=to_site,
),
model.ShiftAmountActivity(
env=my_env,
name="unloading",
registry=registry,
processor=vessel01,
origin=vessel01,
destination=to_site,
amount=4,
duration=1000,
),
model.BasicActivity(
env=my_env,
name="basic activity",
registry=registry,
duration=0,
additional_logs=[vessel01],
),
]
# create a 'sequential activity' that is made up of the 'sub_processes'
sequential_activity = model.SequentialActivity(
env=my_env,
name="sequential",
registry=registry,
sub_processes=sub_processes,
)
# create a while activity that executes the 'sequential activity' while the stop condition is not triggered
while_activity = model.WhileActivity(
env=my_env,
name="while",
registry=registry,
sub_processes=[sequential_activity],
condition_event=[{"type": "container", "concept": to_site, "state": "full"}],
)
4. Register processes and run simpy#
# initate the simpy processes defined in the 'while activity' and run simpy
model.register_processes([while_activity])
my_env.run()
5. Inspect results#
5.1 Inspect logs#
plot.get_log_dataframe(vessel01, [while_activity])
Activity | Timestamp | ActivityState | container level | geometry | type | ref | |
---|---|---|---|---|---|---|---|
0 | sailing empty | 1970-01-01 00:00:00.000000 | START | 0.0 | POINT (4.18055556 52.18664444) | NaN | NaN |
1 | sailing empty | 1970-01-01 00:00:00.000000 | STOP | 0.0 | POINT (4.18055556 52.18664444) | NaN | NaN |
2 | loading | 1970-01-01 00:00:00.000000 | START | 0.0 | POINT (4.18055556 52.18664444) | NaN | NaN |
3 | loading | 1970-01-01 00:16:40.000000 | STOP | 4.0 | POINT (4.18055556 52.18664444) | NaN | NaN |
4 | sailing full | 1970-01-01 00:16:40.000000 | START | 4.0 | POINT (4.18055556 52.18664444) | NaN | NaN |
... | ... | ... | ... | ... | ... | ... | ... |
245 | sailing full | 1970-01-02 02:26:38.404972 | STOP | 4.0 | POINT (4.25222222 52.11428333) | NaN | NaN |
246 | unloading | 1970-01-02 02:26:38.404972 | START | 4.0 | POINT (4.25222222 52.11428333) | NaN | NaN |
247 | unloading | 1970-01-02 02:43:18.404972 | STOP | 0.0 | POINT (4.25222222 52.11428333) | NaN | NaN |
248 | basic activity | 1970-01-02 02:43:18.404972 | START | 0.0 | POINT (4.25222222 52.11428333) | additional log | f3e55f40-2c68-4e38-b86d-e228b9fbd84e |
249 | basic activity | 1970-01-02 02:43:18.404972 | STOP | 0.0 | POINT (4.25222222 52.11428333) | additional log | f3e55f40-2c68-4e38-b86d-e228b9fbd84e |
250 rows × 7 columns
5.2 Visualise gantt charts#
plot.get_gantt_chart([while_activity])
plot.get_gantt_chart([vessel01, from_site, to_site],id_map=[while_activity])
5.3 Visualise container volume developments#
fig = plot.get_step_chart([vessel01, from_site, to_site])
Sandbox#
pd.DataFrame.from_dict(vessel01.log)
Timestamp | ActivityID | ActivityState | ObjectState | ActivityLabel | |
---|---|---|---|---|---|
0 | 1970-01-01 00:00:00.000000 | 9d762179-acd5-4700-8587-a4a98ea484a9 | START | {'container level': 0.0, 'geometry': POINT (4.... | {} |
1 | 1970-01-01 00:00:00.000000 | 9d762179-acd5-4700-8587-a4a98ea484a9 | STOP | {'container level': 0.0, 'geometry': POINT (4.... | {} |
2 | 1970-01-01 00:00:00.000000 | 15f76a8b-df06-44d7-87cc-f53b655e263a | START | {'container level': 0.0, 'geometry': POINT (4.... | {} |
3 | 1970-01-01 00:16:40.000000 | 15f76a8b-df06-44d7-87cc-f53b655e263a | STOP | {'container level': 4.0, 'geometry': POINT (4.... | {} |
4 | 1970-01-01 00:16:40.000000 | f2fe8407-924a-4d6a-9fd7-89c2f78bf6d5 | START | {'container level': 4.0, 'geometry': POINT (4.... | {} |
... | ... | ... | ... | ... | ... |
245 | 1970-01-02 02:26:38.404972 | f2fe8407-924a-4d6a-9fd7-89c2f78bf6d5 | STOP | {'container level': 4.0, 'geometry': POINT (4.... | {} |
246 | 1970-01-02 02:26:38.404972 | 67fb2e0a-6bfe-4c27-a8f3-99fab2bd054e | START | {'container level': 4.0, 'geometry': POINT (4.... | {} |
247 | 1970-01-02 02:43:18.404972 | 67fb2e0a-6bfe-4c27-a8f3-99fab2bd054e | STOP | {'container level': 0.0, 'geometry': POINT (4.... | {} |
248 | 1970-01-02 02:43:18.404972 | f3e55f40-2c68-4e38-b86d-e228b9fbd84e | START | {'container level': 0.0, 'geometry': POINT (4.... | {'type': 'additional log', 'ref': 'f3e55f40-2c... |
249 | 1970-01-02 02:43:18.404972 | f3e55f40-2c68-4e38-b86d-e228b9fbd84e | STOP | {'container level': 0.0, 'geometry': POINT (4.... | {'type': 'additional log', 'ref': 'f3e55f40-2c... |
250 rows × 5 columns
list(set(vessel01.log["ActivityID"]))
['9d762179-acd5-4700-8587-a4a98ea484a9',
'15f76a8b-df06-44d7-87cc-f53b655e263a',
'67fb2e0a-6bfe-4c27-a8f3-99fab2bd054e',
'f3e55f40-2c68-4e38-b86d-e228b9fbd84e',
'f2fe8407-924a-4d6a-9fd7-89c2f78bf6d5']