simulation_classes.truck     
                        Creates class object for Trucks.
1""" 2Creates class object for Trucks. 3""" 4import constants 5import random 6from simulation_handler.helpers import get_value_by_terminal, log_line 7from simulation_classes.pipeline import Pipeline 8 9# Initialize the constants from the constants file 10TRUCK_WAITING_TIME_MIN, TRUCK_WAITING_TIME_MAX = constants.TRUCK_WAITING_TIME 11actions = { 12 (1, 1): "both", 13 (1, 0): "load", 14 (0, 1): "unload", 15 (0, 0): None 16} 17 18 19class Truck(object): 20 """ 21 Truck class to simulate the loading and unloading of trucks at different terminals. 22 Args: 23 env (simpy.Environment): Simulation environment. 24 liq_terminals_with_pipeline_source (list): List of liquid terminals with pipeline source. 25 liq_terminals_with_pipeline_sink (list): List of liquid terminals with pipeline sink. 26 chassis_bays_utilization (dict): Dictionary to track chassis bays utilization. 27 truck_id (int): Unique identifier for the truck. 28 run_id (int): Unique identifier for the simulation run. 29 terminal_type (str): Type of the terminal (e.g., "Container", "Liquid", "DryBulk"). 30 terminal_id (int): Unique identifier for the terminal, starts from 1. 31 container_amount (tuple): Amount of containers to load and unload. 32 liquid_amount (int): Amount of liquid to load or unload. 33 drybulk_amount (int): Amount of dry bulk to load or unload. 34 loading_bays (simpy.Resource): Resource representing the loading bays. 35 port_tanks (simpy.Container): Container representing the liquid storage tanks at the port. 36 truck_chassis (simpy.Resource): Resource representing the truck chassis. 37 port_yard (simpy.Store): Store representing the container yard at the port. 38 port_silos (simpy.Container): Container representing the dry bulk storage silos at the port. 39 drybulk_bays (simpy.Resource): Resource representing the dry bulk loading bays. 40 events (list): List to store events for logging. 41 seed (int): Random seed for reproducibility. 42 """ 43 44 def __init__(self, env, liq_terminals_with_pipeline_source, liq_terminals_with_pipeline_sink, chassis_bays_utilization, truck_id, run_id, terminal_type, terminal_id, container_amount, liquid_amount, drybulk_amount, loading_bays, port_tanks, truck_chassis, port_yard, port_silos, drybulk_bays, events, seed, terminal_data): 45 46 self.env = env 47 self.events = events 48 self.truck_id = truck_id 49 self.terminal_type = terminal_type 50 self.terminal_id = terminal_id # starts from 1 51 self.terminal_data = terminal_data 52 self.run_id = run_id 53 self.chassis_bays_utilization = chassis_bays_utilization 54 55 self.container_amount = container_amount 56 self.liquid_amount = liquid_amount 57 self.drybulk_amount = drybulk_amount 58 59 self.transfer_rate = get_value_by_terminal( 60 self.terminal_data, terminal_type, terminal_id, 'truck loading/unloading rate') 61 62 self.loading_bays = loading_bays 63 # port_tanks_liquid_terminals[terminal_id] 64 self.port_tanks = port_tanks 65 66 self.truck_chassis = truck_chassis 67 # port_yard_container_terminals[terminal_id] 68 self.port_yard = port_yard 69 70 # port_silos_drybulk_terminals[terminal_id] 71 self.port_silos = port_silos 72 self.drybulk_bays = drybulk_bays 73 74 self.liq_terminals_with_pipeline_source = liq_terminals_with_pipeline_source 75 self.liq_terminals_with_pipeline_sink = liq_terminals_with_pipeline_sink 76 77 self.env.process(self.process(seed, self.run_id)) 78 79 def process(self, seed, run_id): 80 """ 81 Process to handle the truck loading and unloading at the terminal. 82 Args: 83 seed (int): Random seed for reproducibility. 84 run_id (int): Unique identifier for the simulation run. 85 Yields: 86 simpy.Process: The truck loading and unloading process. 87 Returns: 88 None 89 """ 90 import_terminal = get_value_by_terminal( 91 self.terminal_data, self.terminal_type, self.terminal_id, 'import') 92 export_terminal = get_value_by_terminal( 93 self.terminal_data, self.terminal_type, self.terminal_id, 'export') 94 action = actions.get((import_terminal, export_terminal)) 95 96 start_time = self.env.now 97 98 if self.terminal_type == "Container": 99 yield self.env.process(self.container_truck(run_id=run_id, truck_id=f"C.{self.terminal_id}:{self.truck_id}", load_amount=self.container_amount[0], unload_amount=self.container_amount[1], terminal_id=1, action=action, seed=seed)) 100 elif self.terminal_type == "Liquid": 101 # if action == "both": 102 # action = random.choice(["load", "unload"]) # new 103 yield self.env.process(self.tanker_truck(truck_id=f"L.{self.terminal_id}:{self.truck_id}", amount=self.liquid_amount, terminal_id=1, action=action, seed=seed)) 104 elif self.terminal_type == "DryBulk": 105 # if action == "both": 106 # action = random.choice(["load", "unload"]) # new 107 yield self.env.process(self.drybulk_truck(truck_id=f"D.{self.terminal_id}:{self.truck_id}", amount=self.drybulk_amount, terminal_id=1, action=action, seed=seed)) 108 109 dwell_time = self.env.now - start_time 110 111 # log the truck id, start time, dwell time, terminal id, terminal type 112 log_line(self.run_id, "truck_data.txt", f'truck_id: {self.truck_id}, start_time: {start_time}, dwell_time: {dwell_time}, terminal_id: {self.terminal_id}, terminal_type: {self.terminal_type}') 113 114 115 def tanker_truck(self, truck_id, amount, terminal_id, action, seed): 116 """ 117 Process to handle the tanker truck loading and unloading at the liquid terminal. 118 Args: 119 truck_id (str): Unique identifier for the truck. 120 amount (int): Amount of liquid to load or unload. 121 terminal_id (int): Unique identifier for the terminal. 122 action (str): Action to perform, either "load" or "unload". 123 seed (int): Random seed for reproducibility. 124 Yields: 125 simpy.Process: The tanker truck loading and unloading process. 126 Returns: 127 None 128 """ 129 random.seed(seed) 130 self.chassis_bays_utilization["Liquid"][self.terminal_id].append( 131 (self.env.now, self.loading_bays.count / self.loading_bays.capacity)) 132 with self.loading_bays.request() as req: 133 yield req 134 TRUCK_WAITING_TIME = random.uniform( 135 TRUCK_WAITING_TIME_MIN, TRUCK_WAITING_TIME_MAX) 136 yield self.env.timeout(TRUCK_WAITING_TIME) 137 TRUCK_PUMP_RATE = self.transfer_rate 138 139 if action == "load": 140 yield self.port_tanks.get(amount) 141 load_time = amount / TRUCK_PUMP_RATE 142 yield self.env.timeout(load_time) 143 elif action == "unload": 144 yield self.port_tanks.put(amount) 145 unload_time = amount / TRUCK_PUMP_RATE 146 yield self.env.timeout(unload_time) 147 148 if self.port_tanks.level + amount >= 0.9 * self.port_tanks.capacity: 149 if terminal_id in self.liq_terminals_with_pipeline_sink: 150 Pipeline(self.run_id, self.env, self.port_tanks, 151 mode='sink', rate=constants.PIPELINE_RATE) 152 with open(f'.{self.run_id}/logs/force_action.txt', 'a') as f: 153 f.write( 154 f"Pipeline from source sink activated {self.env.now}") 155 f.write('\n') 156 157 if self.port_tanks.level - amount <= 0.1 * self.port_tanks.capacity: 158 if terminal_id in self.liq_terminals_with_pipeline_source: 159 Pipeline(self.run_id, self.env, self.port_tanks, 160 mode='source', rate=constants.PIPELINE_RATE) 161 with open(f'.{self.run_id}/logs/force_action.txt', 'a') as f: 162 f.write( 163 f"Pipeline from source source activated {self.env.now}") 164 f.write('\n') 165 166 def drybulk_truck(self, truck_id, amount, terminal_id, action, seed): 167 """ 168 Process to handle the dry bulk truck loading and unloading at the dry bulk terminal. 169 Args: 170 truck_id (str): Unique identifier for the truck. 171 amount (int): Amount of dry bulk to load or unload. 172 terminal_id (int): Unique identifier for the terminal. 173 action (str): Action to perform, either "load" or "unload". 174 seed (int): Random seed for reproducibility. 175 Yields: 176 simpy.Process: The dry bulk truck loading and unloading process. 177 Returns: 178 None 179 """ 180 random.seed(seed) 181 self.chassis_bays_utilization["DryBulk"][self.terminal_id].append( 182 (self.env.now, self.drybulk_bays.count / self.drybulk_bays.capacity)) 183 start_time = self.env.now 184 with self.drybulk_bays.request() as req: 185 yield req 186 TRUCK_WAITING_TIME = random.uniform( 187 TRUCK_WAITING_TIME_MIN, TRUCK_WAITING_TIME_MAX) 188 yield self.env.timeout(TRUCK_WAITING_TIME) 189 TRUCK_TRANSFER_RATE = self.transfer_rate 190 191 if action == "load": 192 yield self.port_silos.get(amount) 193 load_time = amount / TRUCK_TRANSFER_RATE 194 yield self.env.timeout(load_time) 195 elif action == "unload": 196 yield self.port_silos.put(amount) 197 unload_time = amount / TRUCK_TRANSFER_RATE 198 yield self.env.timeout(unload_time) 199 200 def container_truck(self, run_id, truck_id, load_amount, unload_amount, terminal_id, action, seed): 201 """ 202 Process to handle the container truck loading and unloading at the container terminal. 203 Args: 204 run_id (int): Unique identifier for the simulation run. 205 truck_id (str): Unique identifier for the truck. 206 load_amount (int): Amount of containers to load. 207 unload_amount (int): Amount of containers to unload. 208 terminal_id (int): Unique identifier for the terminal. 209 action (str): Action to perform, either "load", "unload", or "both". 210 seed (int): Random seed for reproducibility. 211 Yields: 212 simpy.Process: The container truck loading and unloading process. 213 Returns: 214 None 215 """ 216 random.seed(seed) 217 start_time = self.env.now 218 self.chassis_bays_utilization["Container"][self.terminal_id].append( 219 (self.env.now, len(self.truck_chassis.items) / self.truck_chassis.capacity)) 220 TRUCK_WAITING_TIME = random.uniform( 221 TRUCK_WAITING_TIME_MIN, TRUCK_WAITING_TIME_MAX) 222 yield self.env.timeout(TRUCK_WAITING_TIME) 223 224 force = False 225 if constants.CTR_TRUCK_OVERRIDE: 226 if len(self.port_yard.items) <= 0.05 * self.port_yard.capacity: 227 action = "unload" 228 force = True 229 with open(f'.{run_id}/logs/force_action.txt', 'a') as f: 230 f.write( 231 f"Container truck force unloading at {self.env.now}") 232 f.write('\n') 233 elif len(self.port_yard.items) >= 0.95 * self.port_yard.capacity: 234 action = "load" 235 force = True 236 with open(f'.{run_id}/logs/force_action.txt', 'a') as f: 237 f.write(f"Container truck force loading at {self.env.now}") 238 f.write('\n') 239 if action == "both": 240 force = False 241 action = random.choice(["load", "unload"]) 242 243 if action == "load": 244 if not force: 245 yield self.truck_chassis.get() 246 for _ in range(load_amount): 247 yield self.port_yard.get() 248 load_time = 1 / self.transfer_rate 249 yield self.env.timeout(load_time) 250 if action == "unload": 251 for _ in range(unload_amount): 252 yield self.port_yard.put(1) 253 unload_time = 1 / self.transfer_rate 254 yield self.env.timeout(unload_time) 255 if not force: 256 yield self.truck_chassis.put(1)
            
    class
    Truck:
                
    
    
            20class Truck(object): 21 """ 22 Truck class to simulate the loading and unloading of trucks at different terminals. 23 Args: 24 env (simpy.Environment): Simulation environment. 25 liq_terminals_with_pipeline_source (list): List of liquid terminals with pipeline source. 26 liq_terminals_with_pipeline_sink (list): List of liquid terminals with pipeline sink. 27 chassis_bays_utilization (dict): Dictionary to track chassis bays utilization. 28 truck_id (int): Unique identifier for the truck. 29 run_id (int): Unique identifier for the simulation run. 30 terminal_type (str): Type of the terminal (e.g., "Container", "Liquid", "DryBulk"). 31 terminal_id (int): Unique identifier for the terminal, starts from 1. 32 container_amount (tuple): Amount of containers to load and unload. 33 liquid_amount (int): Amount of liquid to load or unload. 34 drybulk_amount (int): Amount of dry bulk to load or unload. 35 loading_bays (simpy.Resource): Resource representing the loading bays. 36 port_tanks (simpy.Container): Container representing the liquid storage tanks at the port. 37 truck_chassis (simpy.Resource): Resource representing the truck chassis. 38 port_yard (simpy.Store): Store representing the container yard at the port. 39 port_silos (simpy.Container): Container representing the dry bulk storage silos at the port. 40 drybulk_bays (simpy.Resource): Resource representing the dry bulk loading bays. 41 events (list): List to store events for logging. 42 seed (int): Random seed for reproducibility. 43 """ 44 45 def __init__(self, env, liq_terminals_with_pipeline_source, liq_terminals_with_pipeline_sink, chassis_bays_utilization, truck_id, run_id, terminal_type, terminal_id, container_amount, liquid_amount, drybulk_amount, loading_bays, port_tanks, truck_chassis, port_yard, port_silos, drybulk_bays, events, seed, terminal_data): 46 47 self.env = env 48 self.events = events 49 self.truck_id = truck_id 50 self.terminal_type = terminal_type 51 self.terminal_id = terminal_id # starts from 1 52 self.terminal_data = terminal_data 53 self.run_id = run_id 54 self.chassis_bays_utilization = chassis_bays_utilization 55 56 self.container_amount = container_amount 57 self.liquid_amount = liquid_amount 58 self.drybulk_amount = drybulk_amount 59 60 self.transfer_rate = get_value_by_terminal( 61 self.terminal_data, terminal_type, terminal_id, 'truck loading/unloading rate') 62 63 self.loading_bays = loading_bays 64 # port_tanks_liquid_terminals[terminal_id] 65 self.port_tanks = port_tanks 66 67 self.truck_chassis = truck_chassis 68 # port_yard_container_terminals[terminal_id] 69 self.port_yard = port_yard 70 71 # port_silos_drybulk_terminals[terminal_id] 72 self.port_silos = port_silos 73 self.drybulk_bays = drybulk_bays 74 75 self.liq_terminals_with_pipeline_source = liq_terminals_with_pipeline_source 76 self.liq_terminals_with_pipeline_sink = liq_terminals_with_pipeline_sink 77 78 self.env.process(self.process(seed, self.run_id)) 79 80 def process(self, seed, run_id): 81 """ 82 Process to handle the truck loading and unloading at the terminal. 83 Args: 84 seed (int): Random seed for reproducibility. 85 run_id (int): Unique identifier for the simulation run. 86 Yields: 87 simpy.Process: The truck loading and unloading process. 88 Returns: 89 None 90 """ 91 import_terminal = get_value_by_terminal( 92 self.terminal_data, self.terminal_type, self.terminal_id, 'import') 93 export_terminal = get_value_by_terminal( 94 self.terminal_data, self.terminal_type, self.terminal_id, 'export') 95 action = actions.get((import_terminal, export_terminal)) 96 97 start_time = self.env.now 98 99 if self.terminal_type == "Container": 100 yield self.env.process(self.container_truck(run_id=run_id, truck_id=f"C.{self.terminal_id}:{self.truck_id}", load_amount=self.container_amount[0], unload_amount=self.container_amount[1], terminal_id=1, action=action, seed=seed)) 101 elif self.terminal_type == "Liquid": 102 # if action == "both": 103 # action = random.choice(["load", "unload"]) # new 104 yield self.env.process(self.tanker_truck(truck_id=f"L.{self.terminal_id}:{self.truck_id}", amount=self.liquid_amount, terminal_id=1, action=action, seed=seed)) 105 elif self.terminal_type == "DryBulk": 106 # if action == "both": 107 # action = random.choice(["load", "unload"]) # new 108 yield self.env.process(self.drybulk_truck(truck_id=f"D.{self.terminal_id}:{self.truck_id}", amount=self.drybulk_amount, terminal_id=1, action=action, seed=seed)) 109 110 dwell_time = self.env.now - start_time 111 112 # log the truck id, start time, dwell time, terminal id, terminal type 113 log_line(self.run_id, "truck_data.txt", f'truck_id: {self.truck_id}, start_time: {start_time}, dwell_time: {dwell_time}, terminal_id: {self.terminal_id}, terminal_type: {self.terminal_type}') 114 115 116 def tanker_truck(self, truck_id, amount, terminal_id, action, seed): 117 """ 118 Process to handle the tanker truck loading and unloading at the liquid terminal. 119 Args: 120 truck_id (str): Unique identifier for the truck. 121 amount (int): Amount of liquid to load or unload. 122 terminal_id (int): Unique identifier for the terminal. 123 action (str): Action to perform, either "load" or "unload". 124 seed (int): Random seed for reproducibility. 125 Yields: 126 simpy.Process: The tanker truck loading and unloading process. 127 Returns: 128 None 129 """ 130 random.seed(seed) 131 self.chassis_bays_utilization["Liquid"][self.terminal_id].append( 132 (self.env.now, self.loading_bays.count / self.loading_bays.capacity)) 133 with self.loading_bays.request() as req: 134 yield req 135 TRUCK_WAITING_TIME = random.uniform( 136 TRUCK_WAITING_TIME_MIN, TRUCK_WAITING_TIME_MAX) 137 yield self.env.timeout(TRUCK_WAITING_TIME) 138 TRUCK_PUMP_RATE = self.transfer_rate 139 140 if action == "load": 141 yield self.port_tanks.get(amount) 142 load_time = amount / TRUCK_PUMP_RATE 143 yield self.env.timeout(load_time) 144 elif action == "unload": 145 yield self.port_tanks.put(amount) 146 unload_time = amount / TRUCK_PUMP_RATE 147 yield self.env.timeout(unload_time) 148 149 if self.port_tanks.level + amount >= 0.9 * self.port_tanks.capacity: 150 if terminal_id in self.liq_terminals_with_pipeline_sink: 151 Pipeline(self.run_id, self.env, self.port_tanks, 152 mode='sink', rate=constants.PIPELINE_RATE) 153 with open(f'.{self.run_id}/logs/force_action.txt', 'a') as f: 154 f.write( 155 f"Pipeline from source sink activated {self.env.now}") 156 f.write('\n') 157 158 if self.port_tanks.level - amount <= 0.1 * self.port_tanks.capacity: 159 if terminal_id in self.liq_terminals_with_pipeline_source: 160 Pipeline(self.run_id, self.env, self.port_tanks, 161 mode='source', rate=constants.PIPELINE_RATE) 162 with open(f'.{self.run_id}/logs/force_action.txt', 'a') as f: 163 f.write( 164 f"Pipeline from source source activated {self.env.now}") 165 f.write('\n') 166 167 def drybulk_truck(self, truck_id, amount, terminal_id, action, seed): 168 """ 169 Process to handle the dry bulk truck loading and unloading at the dry bulk terminal. 170 Args: 171 truck_id (str): Unique identifier for the truck. 172 amount (int): Amount of dry bulk to load or unload. 173 terminal_id (int): Unique identifier for the terminal. 174 action (str): Action to perform, either "load" or "unload". 175 seed (int): Random seed for reproducibility. 176 Yields: 177 simpy.Process: The dry bulk truck loading and unloading process. 178 Returns: 179 None 180 """ 181 random.seed(seed) 182 self.chassis_bays_utilization["DryBulk"][self.terminal_id].append( 183 (self.env.now, self.drybulk_bays.count / self.drybulk_bays.capacity)) 184 start_time = self.env.now 185 with self.drybulk_bays.request() as req: 186 yield req 187 TRUCK_WAITING_TIME = random.uniform( 188 TRUCK_WAITING_TIME_MIN, TRUCK_WAITING_TIME_MAX) 189 yield self.env.timeout(TRUCK_WAITING_TIME) 190 TRUCK_TRANSFER_RATE = self.transfer_rate 191 192 if action == "load": 193 yield self.port_silos.get(amount) 194 load_time = amount / TRUCK_TRANSFER_RATE 195 yield self.env.timeout(load_time) 196 elif action == "unload": 197 yield self.port_silos.put(amount) 198 unload_time = amount / TRUCK_TRANSFER_RATE 199 yield self.env.timeout(unload_time) 200 201 def container_truck(self, run_id, truck_id, load_amount, unload_amount, terminal_id, action, seed): 202 """ 203 Process to handle the container truck loading and unloading at the container terminal. 204 Args: 205 run_id (int): Unique identifier for the simulation run. 206 truck_id (str): Unique identifier for the truck. 207 load_amount (int): Amount of containers to load. 208 unload_amount (int): Amount of containers to unload. 209 terminal_id (int): Unique identifier for the terminal. 210 action (str): Action to perform, either "load", "unload", or "both". 211 seed (int): Random seed for reproducibility. 212 Yields: 213 simpy.Process: The container truck loading and unloading process. 214 Returns: 215 None 216 """ 217 random.seed(seed) 218 start_time = self.env.now 219 self.chassis_bays_utilization["Container"][self.terminal_id].append( 220 (self.env.now, len(self.truck_chassis.items) / self.truck_chassis.capacity)) 221 TRUCK_WAITING_TIME = random.uniform( 222 TRUCK_WAITING_TIME_MIN, TRUCK_WAITING_TIME_MAX) 223 yield self.env.timeout(TRUCK_WAITING_TIME) 224 225 force = False 226 if constants.CTR_TRUCK_OVERRIDE: 227 if len(self.port_yard.items) <= 0.05 * self.port_yard.capacity: 228 action = "unload" 229 force = True 230 with open(f'.{run_id}/logs/force_action.txt', 'a') as f: 231 f.write( 232 f"Container truck force unloading at {self.env.now}") 233 f.write('\n') 234 elif len(self.port_yard.items) >= 0.95 * self.port_yard.capacity: 235 action = "load" 236 force = True 237 with open(f'.{run_id}/logs/force_action.txt', 'a') as f: 238 f.write(f"Container truck force loading at {self.env.now}") 239 f.write('\n') 240 if action == "both": 241 force = False 242 action = random.choice(["load", "unload"]) 243 244 if action == "load": 245 if not force: 246 yield self.truck_chassis.get() 247 for _ in range(load_amount): 248 yield self.port_yard.get() 249 load_time = 1 / self.transfer_rate 250 yield self.env.timeout(load_time) 251 if action == "unload": 252 for _ in range(unload_amount): 253 yield self.port_yard.put(1) 254 unload_time = 1 / self.transfer_rate 255 yield self.env.timeout(unload_time) 256 if not force: 257 yield self.truck_chassis.put(1)
Truck class to simulate the loading and unloading of trucks at different terminals.
Arguments:
- env (simpy.Environment): Simulation environment.
- liq_terminals_with_pipeline_source (list): List of liquid terminals with pipeline source.
- liq_terminals_with_pipeline_sink (list): List of liquid terminals with pipeline sink.
- chassis_bays_utilization (dict): Dictionary to track chassis bays utilization.
- truck_id (int): Unique identifier for the truck.
- run_id (int): Unique identifier for the simulation run.
- terminal_type (str): Type of the terminal (e.g., "Container", "Liquid", "DryBulk").
- terminal_id (int): Unique identifier for the terminal, starts from 1.
- container_amount (tuple): Amount of containers to load and unload.
- liquid_amount (int): Amount of liquid to load or unload.
- drybulk_amount (int): Amount of dry bulk to load or unload.
- loading_bays (simpy.Resource): Resource representing the loading bays.
- port_tanks (simpy.Container): Container representing the liquid storage tanks at the port.
- truck_chassis (simpy.Resource): Resource representing the truck chassis.
- port_yard (simpy.Store): Store representing the container yard at the port.
- port_silos (simpy.Container): Container representing the dry bulk storage silos at the port.
- drybulk_bays (simpy.Resource): Resource representing the dry bulk loading bays.
- events (list): List to store events for logging.
- seed (int): Random seed for reproducibility.
            
        def
        process(self, seed, run_id):
                
    
    
            80 def process(self, seed, run_id): 81 """ 82 Process to handle the truck loading and unloading at the terminal. 83 Args: 84 seed (int): Random seed for reproducibility. 85 run_id (int): Unique identifier for the simulation run. 86 Yields: 87 simpy.Process: The truck loading and unloading process. 88 Returns: 89 None 90 """ 91 import_terminal = get_value_by_terminal( 92 self.terminal_data, self.terminal_type, self.terminal_id, 'import') 93 export_terminal = get_value_by_terminal( 94 self.terminal_data, self.terminal_type, self.terminal_id, 'export') 95 action = actions.get((import_terminal, export_terminal)) 96 97 start_time = self.env.now 98 99 if self.terminal_type == "Container": 100 yield self.env.process(self.container_truck(run_id=run_id, truck_id=f"C.{self.terminal_id}:{self.truck_id}", load_amount=self.container_amount[0], unload_amount=self.container_amount[1], terminal_id=1, action=action, seed=seed)) 101 elif self.terminal_type == "Liquid": 102 # if action == "both": 103 # action = random.choice(["load", "unload"]) # new 104 yield self.env.process(self.tanker_truck(truck_id=f"L.{self.terminal_id}:{self.truck_id}", amount=self.liquid_amount, terminal_id=1, action=action, seed=seed)) 105 elif self.terminal_type == "DryBulk": 106 # if action == "both": 107 # action = random.choice(["load", "unload"]) # new 108 yield self.env.process(self.drybulk_truck(truck_id=f"D.{self.terminal_id}:{self.truck_id}", amount=self.drybulk_amount, terminal_id=1, action=action, seed=seed)) 109 110 dwell_time = self.env.now - start_time 111 112 # log the truck id, start time, dwell time, terminal id, terminal type 113 log_line(self.run_id, "truck_data.txt", f'truck_id: {self.truck_id}, start_time: {start_time}, dwell_time: {dwell_time}, terminal_id: {self.terminal_id}, terminal_type: {self.terminal_type}')
Process to handle the truck loading and unloading at the terminal.
Arguments:
- seed (int): Random seed for reproducibility.
- run_id (int): Unique identifier for the simulation run.
Yields:
simpy.Process: The truck loading and unloading process.
Returns:
None
            
        def
        tanker_truck(self, truck_id, amount, terminal_id, action, seed):
                
    
    
            116 def tanker_truck(self, truck_id, amount, terminal_id, action, seed): 117 """ 118 Process to handle the tanker truck loading and unloading at the liquid terminal. 119 Args: 120 truck_id (str): Unique identifier for the truck. 121 amount (int): Amount of liquid to load or unload. 122 terminal_id (int): Unique identifier for the terminal. 123 action (str): Action to perform, either "load" or "unload". 124 seed (int): Random seed for reproducibility. 125 Yields: 126 simpy.Process: The tanker truck loading and unloading process. 127 Returns: 128 None 129 """ 130 random.seed(seed) 131 self.chassis_bays_utilization["Liquid"][self.terminal_id].append( 132 (self.env.now, self.loading_bays.count / self.loading_bays.capacity)) 133 with self.loading_bays.request() as req: 134 yield req 135 TRUCK_WAITING_TIME = random.uniform( 136 TRUCK_WAITING_TIME_MIN, TRUCK_WAITING_TIME_MAX) 137 yield self.env.timeout(TRUCK_WAITING_TIME) 138 TRUCK_PUMP_RATE = self.transfer_rate 139 140 if action == "load": 141 yield self.port_tanks.get(amount) 142 load_time = amount / TRUCK_PUMP_RATE 143 yield self.env.timeout(load_time) 144 elif action == "unload": 145 yield self.port_tanks.put(amount) 146 unload_time = amount / TRUCK_PUMP_RATE 147 yield self.env.timeout(unload_time) 148 149 if self.port_tanks.level + amount >= 0.9 * self.port_tanks.capacity: 150 if terminal_id in self.liq_terminals_with_pipeline_sink: 151 Pipeline(self.run_id, self.env, self.port_tanks, 152 mode='sink', rate=constants.PIPELINE_RATE) 153 with open(f'.{self.run_id}/logs/force_action.txt', 'a') as f: 154 f.write( 155 f"Pipeline from source sink activated {self.env.now}") 156 f.write('\n') 157 158 if self.port_tanks.level - amount <= 0.1 * self.port_tanks.capacity: 159 if terminal_id in self.liq_terminals_with_pipeline_source: 160 Pipeline(self.run_id, self.env, self.port_tanks, 161 mode='source', rate=constants.PIPELINE_RATE) 162 with open(f'.{self.run_id}/logs/force_action.txt', 'a') as f: 163 f.write( 164 f"Pipeline from source source activated {self.env.now}") 165 f.write('\n')
Process to handle the tanker truck loading and unloading at the liquid terminal.
Arguments:
- truck_id (str): Unique identifier for the truck.
- amount (int): Amount of liquid to load or unload.
- terminal_id (int): Unique identifier for the terminal.
- action (str): Action to perform, either "load" or "unload".
- seed (int): Random seed for reproducibility.
Yields:
simpy.Process: The tanker truck loading and unloading process.
Returns:
None
            
        def
        drybulk_truck(self, truck_id, amount, terminal_id, action, seed):
                
    
    
            167 def drybulk_truck(self, truck_id, amount, terminal_id, action, seed): 168 """ 169 Process to handle the dry bulk truck loading and unloading at the dry bulk terminal. 170 Args: 171 truck_id (str): Unique identifier for the truck. 172 amount (int): Amount of dry bulk to load or unload. 173 terminal_id (int): Unique identifier for the terminal. 174 action (str): Action to perform, either "load" or "unload". 175 seed (int): Random seed for reproducibility. 176 Yields: 177 simpy.Process: The dry bulk truck loading and unloading process. 178 Returns: 179 None 180 """ 181 random.seed(seed) 182 self.chassis_bays_utilization["DryBulk"][self.terminal_id].append( 183 (self.env.now, self.drybulk_bays.count / self.drybulk_bays.capacity)) 184 start_time = self.env.now 185 with self.drybulk_bays.request() as req: 186 yield req 187 TRUCK_WAITING_TIME = random.uniform( 188 TRUCK_WAITING_TIME_MIN, TRUCK_WAITING_TIME_MAX) 189 yield self.env.timeout(TRUCK_WAITING_TIME) 190 TRUCK_TRANSFER_RATE = self.transfer_rate 191 192 if action == "load": 193 yield self.port_silos.get(amount) 194 load_time = amount / TRUCK_TRANSFER_RATE 195 yield self.env.timeout(load_time) 196 elif action == "unload": 197 yield self.port_silos.put(amount) 198 unload_time = amount / TRUCK_TRANSFER_RATE 199 yield self.env.timeout(unload_time)
Process to handle the dry bulk truck loading and unloading at the dry bulk terminal.
Arguments:
- truck_id (str): Unique identifier for the truck.
- amount (int): Amount of dry bulk to load or unload.
- terminal_id (int): Unique identifier for the terminal.
- action (str): Action to perform, either "load" or "unload".
- seed (int): Random seed for reproducibility.
Yields:
simpy.Process: The dry bulk truck loading and unloading process.
Returns:
None
            
        def
        container_truck(	self,	run_id,	truck_id,	load_amount,	unload_amount,	terminal_id,	action,	seed):
                
    
    
            201 def container_truck(self, run_id, truck_id, load_amount, unload_amount, terminal_id, action, seed): 202 """ 203 Process to handle the container truck loading and unloading at the container terminal. 204 Args: 205 run_id (int): Unique identifier for the simulation run. 206 truck_id (str): Unique identifier for the truck. 207 load_amount (int): Amount of containers to load. 208 unload_amount (int): Amount of containers to unload. 209 terminal_id (int): Unique identifier for the terminal. 210 action (str): Action to perform, either "load", "unload", or "both". 211 seed (int): Random seed for reproducibility. 212 Yields: 213 simpy.Process: The container truck loading and unloading process. 214 Returns: 215 None 216 """ 217 random.seed(seed) 218 start_time = self.env.now 219 self.chassis_bays_utilization["Container"][self.terminal_id].append( 220 (self.env.now, len(self.truck_chassis.items) / self.truck_chassis.capacity)) 221 TRUCK_WAITING_TIME = random.uniform( 222 TRUCK_WAITING_TIME_MIN, TRUCK_WAITING_TIME_MAX) 223 yield self.env.timeout(TRUCK_WAITING_TIME) 224 225 force = False 226 if constants.CTR_TRUCK_OVERRIDE: 227 if len(self.port_yard.items) <= 0.05 * self.port_yard.capacity: 228 action = "unload" 229 force = True 230 with open(f'.{run_id}/logs/force_action.txt', 'a') as f: 231 f.write( 232 f"Container truck force unloading at {self.env.now}") 233 f.write('\n') 234 elif len(self.port_yard.items) >= 0.95 * self.port_yard.capacity: 235 action = "load" 236 force = True 237 with open(f'.{run_id}/logs/force_action.txt', 'a') as f: 238 f.write(f"Container truck force loading at {self.env.now}") 239 f.write('\n') 240 if action == "both": 241 force = False 242 action = random.choice(["load", "unload"]) 243 244 if action == "load": 245 if not force: 246 yield self.truck_chassis.get() 247 for _ in range(load_amount): 248 yield self.port_yard.get() 249 load_time = 1 / self.transfer_rate 250 yield self.env.timeout(load_time) 251 if action == "unload": 252 for _ in range(unload_amount): 253 yield self.port_yard.put(1) 254 unload_time = 1 / self.transfer_rate 255 yield self.env.timeout(unload_time) 256 if not force: 257 yield self.truck_chassis.put(1)
Process to handle the container truck loading and unloading at the container terminal.
Arguments:
- run_id (int): Unique identifier for the simulation run.
- truck_id (str): Unique identifier for the truck.
- load_amount (int): Amount of containers to load.
- unload_amount (int): Amount of containers to unload.
- terminal_id (int): Unique identifier for the terminal.
- action (str): Action to perform, either "load", "unload", or "both".
- seed (int): Random seed for reproducibility.
Yields:
simpy.Process: The container truck loading and unloading process.
Returns:
None