|
|
@@ -71,6 +71,7 @@ class Pool(AtomicDEVS):
|
|
|
self.state = {
|
|
|
"waiting": {},
|
|
|
"should_exit": [],
|
|
|
+ "delayed": [],
|
|
|
"time": 0.0
|
|
|
}
|
|
|
|
|
|
@@ -83,47 +84,49 @@ class Pool(AtomicDEVS):
|
|
|
if isinstance(mmsi, str):
|
|
|
self.state["waiting"][mmsi] = Vessel(mmsi)
|
|
|
|
|
|
+ def request_vessel(self, vessel, request):
|
|
|
+ vessel.footprint.idle_time += self.state["time"] - vessel.footprint.idle_since
|
|
|
+
|
|
|
+ # vessel.time_until_departure = (request["end"] - request["start"]) / 1000
|
|
|
+ # vessel.velocity = request["distance"] / vessel.time_until_departure
|
|
|
+ # vessel.distance_left = request["distance"]
|
|
|
+ # vessel.total_distance = request["distance"]
|
|
|
+ # vessel.source = (request["source_lon"], request["source_lat"])
|
|
|
+ # vessel.target = (request["target_lon"], request["target_lat"])
|
|
|
+ # vessel.location = request["location"]
|
|
|
+
|
|
|
+ vessel.velocity = request["velocity"]
|
|
|
+ if vessel.velocity >= 0: # requests for idling should be ignored!
|
|
|
+ vessel.distance_left = request["distance"]
|
|
|
+ vessel.total_distance = vessel.distance_left
|
|
|
+ # vessel.time_until_departure = vessel.distance_left / vessel.velocity
|
|
|
+ vessel.source = request["source_lon"], request["source_lat"]
|
|
|
+ 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]
|
|
|
+
|
|
|
def extTransition(self, inputs):
|
|
|
self.state["time"] += self.elapsed
|
|
|
if self.req_in in inputs:
|
|
|
for request in inputs[self.req_in]:
|
|
|
if request["mmsi"] in self.state["waiting"]:
|
|
|
vessel = self.state["waiting"][request["mmsi"]]
|
|
|
+ self.request_vessel(vessel, request)
|
|
|
else:
|
|
|
- print("VESSEL %s DOES NOT EXIST IN POOL" % str(request["mmsi"]))
|
|
|
- # print("\t", request)
|
|
|
- vessel = Vessel(request["mmsi"])
|
|
|
-
|
|
|
- vessel.footprint.idle_time += self.state["time"] - vessel.footprint.idle_since
|
|
|
-
|
|
|
- # vessel.time_until_departure = (request["end"] - request["start"]) / 1000
|
|
|
- # vessel.velocity = request["distance"] / vessel.time_until_departure
|
|
|
- # vessel.distance_left = request["distance"]
|
|
|
- # vessel.total_distance = request["distance"]
|
|
|
- # vessel.source = (request["source_lon"], request["source_lat"])
|
|
|
- # vessel.target = (request["target_lon"], request["target_lat"])
|
|
|
- # vessel.location = request["location"]
|
|
|
-
|
|
|
- vessel.velocity = request["velocity"]
|
|
|
- if vessel.velocity > 0: # requests for idling should be ignored!
|
|
|
- vessel.distance_left = request["distance"]
|
|
|
- vessel.total_distance = vessel.distance_left
|
|
|
- # vessel.time_until_departure = vessel.distance_left / vessel.velocity
|
|
|
- vessel.source = request["source_lon"], request["source_lat"]
|
|
|
- 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]
|
|
|
+ print("[WARN] %4.4f Vessel %s does not exist in pool - delaying request" % (self.state["time"], str(request["mmsi"])))
|
|
|
+ self.state["delayed"].append(request)
|
|
|
+
|
|
|
if self.vessel_in in inputs:
|
|
|
for vessel in inputs[self.vessel_in]:
|
|
|
if vessel.mmsi in self.state["waiting"]:
|
|
|
- raise ValueError("Cannot create duplicate vessels (loc = %s; mmsi = %s; d = %f)" %
|
|
|
- (str(vessel.location), str(vessel.mmsi), vessel.total_distance))
|
|
|
+ raise ValueError("[WARN] %4.4f Cannot create duplicate vessels (mmsi = %s; d = %f)" %
|
|
|
+ (self.state["time"], str(vessel.mmsi), vessel.total_distance))
|
|
|
else:
|
|
|
vessel.source = vessel.target
|
|
|
vessel.target = None
|
|
|
@@ -141,6 +144,13 @@ class Pool(AtomicDEVS):
|
|
|
vessel.footprint.idle_since = self.state["time"]
|
|
|
|
|
|
self.state["waiting"][vessel.mmsi] = vessel
|
|
|
+
|
|
|
+ for ix, r in enumerate(self.state["delayed"]):
|
|
|
+ if r["mmsi"] == vessel.mmsi:
|
|
|
+ self.request_vessel(vessel, r)
|
|
|
+ self.state["delayed"].pop(ix)
|
|
|
+ print("[INFO] %4.4f Delay for vessel %s cleared" % (self.state["time"], r["mmsi"]))
|
|
|
+ break
|
|
|
return self.state
|
|
|
|
|
|
def timeAdvance(self):
|
|
|
@@ -192,7 +202,10 @@ class Sailer(AtomicDEVS):
|
|
|
vessel.velocity = -1
|
|
|
while vessel.velocity <= 0 or vessel.velocity > self.v_max:
|
|
|
vessel.velocity = random.normalvariate(*self.v_sailing)
|
|
|
- vessel.time_until_departure = vessel.distance_left / vessel.velocity
|
|
|
+ if vessel.distance_left == 0.0:
|
|
|
+ vessel.time_until_departure = 0.0
|
|
|
+ else:
|
|
|
+ vessel.time_until_departure = vessel.distance_left / vessel.velocity
|
|
|
self.state["vessels"].append(vessel)
|
|
|
self.state["vessels"].sort(key=lambda v: v.time_until_departure)
|
|
|
return self.state
|
|
|
@@ -344,7 +357,6 @@ class Port(CoupledDEVS):
|
|
|
def __init__(self, name, ivef, v_tugging=None, v_sailing=None, v_max=None):
|
|
|
super(Port, self).__init__(name)
|
|
|
|
|
|
- self.clock = self.addSubModel(Clock("clock"))
|
|
|
self.scheduler = self.addSubModel(Scheduler("scheduler", ivef))
|
|
|
self.planner = self.addSubModel(RoutePlanner("planner"))
|
|
|
# self.tracer = self.addSubModel(Tracer("tracer", ivef))
|
|
|
@@ -357,7 +369,8 @@ class Port(CoupledDEVS):
|
|
|
self.connectPorts(self.pool.vessel_out, self.sailer.vessel_in)
|
|
|
self.connectPorts(self.sailer.vessel_out, self.pool.vessel_in)
|
|
|
|
|
|
- self.connectPorts(self.clock.outp, self.sailer.update)
|
|
|
+ # self.clock = self.addSubModel(Clock("clock"))
|
|
|
+ # self.connectPorts(self.clock.outp, self.sailer.update)
|
|
|
|
|
|
def select(self, imm_children):
|
|
|
for child in imm_children:
|