|
|
@@ -12,7 +12,13 @@ class Footprint:
|
|
|
usage_time: float = 0.0
|
|
|
idle_time: float = 0.0
|
|
|
idle_since: float = 0.0
|
|
|
+
|
|
|
+ sailing_time: float = 0.0
|
|
|
+ tugging_time: float = 0.0
|
|
|
+
|
|
|
fuel_usage: float = 0.0
|
|
|
+ velocity_total: float = 0.0
|
|
|
+ tasks: int = 0
|
|
|
|
|
|
@staticmethod
|
|
|
def get_fuel_efficiency(velocity):
|
|
|
@@ -44,6 +50,8 @@ class Vessel:
|
|
|
time_until_departure: float = 0.0
|
|
|
|
|
|
footprint: Footprint = field(default_factory=Footprint)
|
|
|
+ name: str = ""
|
|
|
+ category: str = "weak"
|
|
|
|
|
|
|
|
|
class Pool(AtomicDEVS):
|
|
|
@@ -92,6 +100,9 @@ class Pool(AtomicDEVS):
|
|
|
vessel.target = request["target_lon"], request["target_lat"]
|
|
|
vessel.task = request["task"]
|
|
|
|
|
|
+ vessel.name = request["name"]
|
|
|
+ vessel.category = request["category"]
|
|
|
+
|
|
|
self.state["should_exit"].append(vessel)
|
|
|
if vessel.mmsi in self.state["waiting"]:
|
|
|
del self.state["waiting"][vessel.mmsi]
|
|
|
@@ -104,8 +115,15 @@ class Pool(AtomicDEVS):
|
|
|
vessel.source = vessel.target
|
|
|
vessel.target = None
|
|
|
if vessel.velocity > 0:
|
|
|
- vessel.footprint.fuel_usage += Footprint.get_fuel(vessel.total_distance, vessel.velocity)
|
|
|
- vessel.footprint.usage_time += vessel.total_distance / vessel.velocity
|
|
|
+ time = vessel.total_distance / vessel.velocity
|
|
|
+ # vessel.footprint.fuel_usage += Footprint.get_fuel(vessel.total_distance, vessel.velocity)
|
|
|
+ vessel.footprint.usage_time += time
|
|
|
+ if vessel.task == "sailing":
|
|
|
+ vessel.footprint.sailing_time += time
|
|
|
+ else:
|
|
|
+ vessel.footprint.tugging_time += time
|
|
|
+ vessel.footprint.velocity_total += vessel.velocity
|
|
|
+ vessel.footprint.tasks += 1
|
|
|
|
|
|
vessel.footprint.idle_since = self.state["time"]
|
|
|
|
|
|
@@ -263,6 +281,7 @@ class Planner(AtomicDEVS):
|
|
|
super(Planner, self).__init__(name)
|
|
|
|
|
|
self.graph = get_graph()
|
|
|
+ self.tugs = pd.read_excel("20230405_Tugs.xlsx", dtype={"MMSI": str, "NAME": str, "category": str})
|
|
|
|
|
|
self.state = {
|
|
|
"request": None
|
|
|
@@ -280,6 +299,10 @@ class Planner(AtomicDEVS):
|
|
|
if self.req_in in inputs:
|
|
|
request = inputs[self.req_in]
|
|
|
|
|
|
+ tug = self.tugs[self.tugs["MMSI"] == str(request["mmsi"])].iloc[0]
|
|
|
+ request["name"] = tug["NAME"]
|
|
|
+ request["category"] = tug["category"]
|
|
|
+
|
|
|
request["source_lon"], request["source_lat"] = eval(request["source"])
|
|
|
request["target_lon"], request["target_lat"] = eval(request["target"])
|
|
|
|
|
|
@@ -352,12 +375,56 @@ class Port(CoupledDEVS):
|
|
|
return imm_children[0]
|
|
|
|
|
|
def print_statistics(self):
|
|
|
- print("TOTAL USAGES:")
|
|
|
- S = 0
|
|
|
+ # Costs // Dummy data for now
|
|
|
+ C_Tug_S = { # euro/hour
|
|
|
+ "strong": 150,
|
|
|
+ "average": 100,
|
|
|
+ "weak": 50
|
|
|
+ }
|
|
|
+ C_Tug_P = { # euro/hour
|
|
|
+ "strong": 200,
|
|
|
+ "average": 133,
|
|
|
+ "weak": 67
|
|
|
+ }
|
|
|
+ C_Tug_F = { # euro/day
|
|
|
+ "strong": 1500,
|
|
|
+ "average": 1000,
|
|
|
+ "weak": 500
|
|
|
+ }
|
|
|
+ C_Tug_W = { # euro/hour
|
|
|
+ "strong": 100,
|
|
|
+ "average": 67,
|
|
|
+ "weak": 33
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ Z = 0.0
|
|
|
+ S1 = 0.0
|
|
|
+ S2 = 0.0
|
|
|
+ S3 = 0.0
|
|
|
+ S4 = 0.0
|
|
|
for vessel in list(self.pool.state["waiting"].values()) + self.sailer.state["vessels"]:
|
|
|
- if vessel.footprint.usage_time > 0:
|
|
|
- print("\t%s: %f seconds" % (vessel.mmsi, vessel.footprint.usage_time))
|
|
|
- S += vessel.footprint.usage_time
|
|
|
- cost_per_hour = 100
|
|
|
- print("-------------")
|
|
|
- print("OVERALL: %f euros" % (S / 3600 * cost_per_hour))
|
|
|
+ T_Tug_S = vessel.footprint.sailing_time / 3600
|
|
|
+ T_Tug_P = vessel.footprint.tugging_time / 3600
|
|
|
+ T_Tug_W = vessel.footprint.idle_time / 3600
|
|
|
+
|
|
|
+ S1 += C_Tug_S[vessel.category] * T_Tug_S
|
|
|
+ S2 += C_Tug_P[vessel.category] * T_Tug_P
|
|
|
+ S3 += C_Tug_W[vessel.category] * T_Tug_W
|
|
|
+ S4 += C_Tug_F[vessel.category] * 31
|
|
|
+ Z += S1 + S2 + S3 + S4
|
|
|
+
|
|
|
+ print("OVERALL COST: %f euros" % Z)
|
|
|
+ print("Travelling: %f euros" % S1)
|
|
|
+ print("Tugging: %f euros" % S2)
|
|
|
+ print("Waiting: %f euros" % S3)
|
|
|
+ print("Fixed: %f euros" % S4)
|
|
|
+ # print("AVERAGE USAGES:")
|
|
|
+ # S = 0
|
|
|
+ # for vessel in list(self.pool.state["waiting"].values()) + self.sailer.state["vessels"]:
|
|
|
+ # if vessel.footprint.usage_time > 0:
|
|
|
+ # print("\t%s: %f m/s" % (vessel.mmsi, vessel.footprint.velocity_total / vessel.footprint.tasks))
|
|
|
+ # S += vessel.footprint.usage_time
|
|
|
+ # cost_per_hour = 100
|
|
|
+ # print("-------------")
|
|
|
+ # print("OVERALL: %f euros" % (S / 3600 * cost_per_hour))
|