-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsim.py
More file actions
103 lines (79 loc) · 3.67 KB
/
sim.py
File metadata and controls
103 lines (79 loc) · 3.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
"""
Gas Station Refueling example
Covers:
- Resources: Resource
- Resources: Container
- Waiting for other processes
Scenario:
An airport gas station has a limited number of gas pumps that share a common
fuel reservoir. Planes randomly arrive at the gas station, request one
of the fuel pumps and start refueling from that reservoir.
A gas station control process observes the gas station's fuel level
and calls a tank truck for refueling if the station's level drops
below a threshold.
"""
import itertools
import random
import logging
import simpy
import pandas as pd
# Parameters
RANDOM_SEED = 42
STATION_TANK_SIZE = 700000 # Size of the gas station tank (liters)
THRESHOLD = 25 # Station tank minimum level (% of full)
PLANE_TANK_SIZE = 150000 # Size of plane fuel tanks (liters)
PLANE_TANK_LEVEL = [30000, 100000] # Min/max levels of plane fuel tanks (liters)
REFUELING_SPEED = 1600 # Rate of refuelling plane fuel tank (liters / second)
TANK_TRUCK_TIME = 1000 # Time it takes tank truck to arrive (seconds)
T_INTER = [4000, 8000] # Interval between plane arrivals [min, max] (seconds)
SIM_TIME = 1000000 # Simulation time (seconds)
times = []
def plane(name, env, gas_station, station_tank):
# TODO: Docstring
plane_tank_level = random.randint(*PLANE_TANK_LEVEL)
logging.debug(f'{env.now:6.1f} s: {name} arrived at gas station')
start_time = env.now
with gas_station.request() as req:
# Request one of the gas pumps
yield req
# Get the required amount of fuel
fuel_required = PLANE_TANK_SIZE - plane_tank_level
yield station_tank.get(fuel_required)
# The "actual" refueling process takes some time
yield env.timeout(fuel_required / REFUELING_SPEED)
times.append((env.now, env.now - start_time, fuel_required))
logging.debug(f'{env.now:6.1f} s: {name} refueled with {fuel_required:.1f}L')
def gas_station_control(env, station_tank):
"""Periodically check the level of the gas station tank and call the tank
truck if the level falls below a threshold."""
while True:
# TODO: Add a condition to check if the station tank level is below the threshold
# We need to call the tank truck now!
logging.debug(f'{env.now:6.1f} s: Calling tank truck')
# Wait for the tank truck to arrive and refuel the station tank
yield env.process(tank_truck(env, station_tank))
yield env.timeout(10) # Check every 10 seconds
def tank_truck(env, station_tank):
"""Arrives at the gas station after a certain delay and refuels it."""
yield env.timeout(TANK_TRUCK_TIME)
amount = station_tank.capacity - station_tank.level
station_tank.put(amount)
logging.debug(
f'{env.now:6.1f} s: Tank truck arrived and refuelled station with {amount:.1f}L'
)
def plane_generator(env, gas_station, station_tank):
"""Generate new planes that arrive at the gas station."""
for i in itertools.count():
yield env.timeout(random.randint(*T_INTER))
env.process(plane(f'Plane {i}', env, gas_station, station_tank))
# Setup and start the simulation
random.seed(RANDOM_SEED)
# Create environment and start processes
env = simpy.Environment()
gas_station = simpy.Resource(env, 2)
station_tank = simpy.Container(env, STATION_TANK_SIZE, init=STATION_TANK_SIZE)
env.process(gas_station_control(env, station_tank))
env.process(plane_generator(env, gas_station, station_tank))
# Execute!
# TODO run simulation for the time you want
pd.DataFrame(times, columns=['entry_time', 'duration', 'fuel_litres']).to_csv('sim.csv', index=False)