Initial commit

This commit is contained in:
Yentl Van Tendeloo 2016-08-04 17:38:43 +02:00
commit 66a6860316
407 changed files with 1254365 additions and 0 deletions

View file

@ -0,0 +1,770 @@
import sys
sys.path.append("../../../src/")
from infinity import *
from DEVS import *
import random
north = 0
east = 1
south = 2
west = 3
vertical = "02"
horizontal = "13"
dir_to_int = {'n': north, 'e': east, 's': south, 'w': west}
int_to_dir = {north: 'n', east: 'e', south: 's', west: 'w'}
class Car:
def __init__(self, ID, v, v_pref, dv_pos_max, dv_neg_max, departure_time):
self.ID = ID
self.v_pref = v_pref
self.dv_pos_max = dv_pos_max
self.dv_neg_max = dv_neg_max
self.departure_time = departure_time
self.distance_travelled = 0
self.remaining_x = 0
self.v = v
def __eq__(self, other):
return (self.ID == other.ID and
self.v_pref == other.v_pref and
self.dv_pos_max == other.dv_pos_max and
self.dv_neg_max == other.dv_neg_max and
self.departure_time == other.departure_time and
self.distance_travelled == other.distance_travelled and
self.remaining_x == other.remaining_x and
self.v == other.v)
def __str__(self):
return "Car: ID = " + str(self.ID) + ", v_pref = " + str(self.v_pref) + ", dv_pos_max = " + str(self.dv_pos_max) + ", dv_neg_max = " + str(self.dv_neg_max) + ", departure_time = " + str(self.departure_time) + ", distance_travelled = " + str(self.distance_travelled) + (", v = %3f" % self.v) + ", path = " + str(self.path)
def copy(self):
car = Car(self.ID, self.v, self.v_pref, self.dv_pos_max, self.dv_neg_max, self.departure_time)
car.distance_travelled = self.distance_travelled
car.remaining_x = self.remaining_x
car.path = list(self.path)
return car
class Query:
def __init__(self, ID):
self.ID = ID
self.direction = ''
def __str__(self):
return "Query: ID = " + str(self.ID)
def __eq__(self, other):
return (self.ID == other.ID and self.direction == other.direction)
def copy(self):
query = Query(self.ID)
query.direction = self.direction
return query
class QueryAck:
def __init__(self, ID, t_until_dep):
self.ID = ID
self.t_until_dep = t_until_dep
def __str__(self):
return "Query Ack: ID = " + str(self.ID) + ", t_until_dep = %.3f" % self.t_until_dep
def __eq__(self, other):
return (self.ID == other.ID and self.t_until_dep == other.t_until_dep)
def copy(self):
return QueryAck(self.ID, self.t_until_dep)
class BuildingState:
def __init__(self, IAT_min, IAT_max, path, name):
self.currentTime = 0
from randomGenerator import RandomGenerator
seed = random.random()
self.randomGenerator = RandomGenerator(seed)
self.send_query_delay = self.randomGenerator.uniform(IAT_min, IAT_max)
self.send_car_delay = INFINITY
self.path = path
if path == []:
self.send_query_delay = INFINITY
self.name = name
self.send_query_id = int(name.split("_", 1)[1].split("_")[0]) * 1000 + int(name.split("_", 1)[1].split("_")[1])
self.send_car_id = self.send_query_id
self.next_v_pref = 0
self.sent = 0
def copy(self):
new = BuildingState(0, 0, list(self.path), self.name)
new.currentTime = self.currentTime
new.send_query_delay = self.send_query_delay
new.send_car_delay = self.send_car_delay
new.send_query_id = self.send_query_id
new.send_car_id = self.send_car_id
new.next_v_pref = self.next_v_pref
new.randomGenerator = self.randomGenerator.copy()
new.sent = self.sent
return new
def __str__(self):
if self.path != []:
return "Residence: send_query_delay = %.3f, send_query_id = %s, send_car_delay = %.3f, send_car_id = %s" % (self.send_query_delay, self.send_query_id, self.send_car_delay, self.send_car_id)
else:
return "Commercial: waiting..."
class Building(AtomicDEVS):
def __init__(self, generator, district, path = [], IAT_min = 100, IAT_max = 100, v_pref_min = 15, v_pref_max = 15, dv_pos_max = 15, dv_neg_max = 150, name="Building"):
# parent class constructor
AtomicDEVS.__init__(self, name)
# copy of arguments
self.IAT_min = IAT_min
self.IAT_max = IAT_max
self.v_pref_min = v_pref_min
self.v_pref_max = v_pref_max
self.dv_pos_max = dv_pos_max
self.dv_neg_max = dv_neg_max
# output ports
self.q_sans = self.addOutPort(name="q_sans")
self.q_send = self.addOutPort(name="q_send")
self.exit = self.addOutPort(name="exit")
self.Q_send = self.q_send
self.car_out = self.exit
# input ports
self.q_rans = self.addInPort(name="q_rans")
#self.q_recv = self.addInPort(name="q_recv")
self.Q_rack = self.q_rans
self.entry = self.addInPort(name="entry")
# set the state
self.state = BuildingState(IAT_min, IAT_max, path, name)
self.state.next_v_pref = self.state.randomGenerator.uniform(self.v_pref_min, self.v_pref_max)
self.send_max = 1
self.district = district
def intTransition(self):
mintime = self.timeAdvance()
#print("Got mintime: " + str(mintime))
self.state.currentTime += mintime
self.state.send_query_delay -= mintime
self.state.send_car_delay -= mintime
if self.state.send_car_delay == 0:
self.state.send_car_delay = INFINITY
self.state.send_car_id = self.state.send_query_id
self.state.next_v_pref = self.state.randomGenerator.uniform(self.v_pref_min, self.v_pref_max)
elif self.state.send_query_delay == 0:
self.state.send_query_delay = INFINITY
return self.state
def outputFnc(self):
mintime = self.timeAdvance()
#print("Got mintime: " + str(mintime))
currentTime = self.state.currentTime + self.timeAdvance()
outputs = {}
if self.state.send_car_delay == mintime:
v_pref = self.state.next_v_pref
car = Car(self.state.send_car_id, 0, v_pref, self.dv_pos_max, self.dv_neg_max, currentTime)
car.path = self.state.path
#self.poke(self.car_out, car)
outputs[self.car_out] = [car]
elif self.state.send_query_delay == mintime:
query = Query(self.state.send_query_id)
#self.poke(self.Q_send, query)
outputs[self.Q_send] = [query]
return outputs
def timeAdvance(self):
return min(self.state.send_query_delay, self.state.send_car_delay)
def extTransition(self, inputs):
#print("ELAPSED: " + str(self.elapsed))
#print("Got elapsed: " + str(self.elapsed))
self.state.currentTime += self.elapsed
self.state.send_query_delay -= self.elapsed
self.state.send_car_delay -= self.elapsed
queryAcks = inputs.get(self.Q_rack, [])
for queryAck in queryAcks:
if self.state.send_car_id == queryAck.ID and (self.state.sent < self.send_max):
self.state.send_car_delay = queryAck.t_until_dep
if queryAck.t_until_dep < 20000:
self.state.sent += 1
# Generate the next situation
if self.state.sent < self.send_max:
self.state.send_query_delay = self.randomGenerator.uniform(self.IAT_min, self.IAT_max)
#self.state.send_query_id = int(self.randomGenerator.uniform(0, 100000))
self.state.send_query_id += 1000000
return self.state
def preActivityCalculation(self):
return None
def postActivityCalculation(self, _):
return 0 if self.state.send_car_delay == float('inf') else 1
class Residence(Building):
def __init__(self, path, district, name = "Residence", IAT_min = 100, IAT_max = 100, v_pref_min = 15, v_pref_max = 15, dv_pos_max = 15, dv_neg_max = 15):
Building.__init__(self, True, district, path=path, name=name)
class CommercialState(object):
def __init__(self, car):
self.car = car
def __str__(self):
return "CommercialState"
def copy(self):
return CommercialState(self.car)
class Commercial(Building):
def __init__(self, district, name="Commercial"):
Building.__init__(self, False, district, name=name)
self.state = CommercialState(None)
self.toCollector = self.addOutPort(name="toCollector")
def extTransition(self, inputs):
return CommercialState(inputs[self.entry][0])
def intTransition(self):
return CommercialState(None)
def outputFnc(self):
return {self.toCollector: [self.state.car]}
def timeAdvance(self):
if self.state.car is None:
return INFINITY
else:
return 0.0
def preActivityCalculation(self):
return None
def postActivityCalculation(self, _):
return 0
class RoadSegmentState():
def __init__(self):
self.cars_present = []
self.query_buffer = []
self.deny_list = []
self.reserved = False
self.send_query_delay = INFINITY
self.send_query_id = None
self.send_ack_delay = INFINITY
self.send_ack_id = None
self.send_car_delay = INFINITY
self.send_car_id = None
self.last_car = None
def __eq__(self, other):
if not (self.send_query_delay == other.send_query_delay and
self.send_ack_delay == other.send_ack_delay and
self.send_car_delay == other.send_car_delay and
self.send_query_id == other.send_query_id and
self.send_ack_id == other.send_ack_id and
self.send_car_id == other.send_car_id and
self.last_car == other.last_car and
self.reserved == other.reserved):
return False
if self.query_buffer != other.query_buffer:
return False
if len(self.cars_present) != len(other.cars_present):
return False
for c1, c2 in zip(self.cars_present, other.cars_present):
if c1 != c2:
return False
if len(self.deny_list) != len(other.deny_list):
return False
for q1, q2 in zip(self.deny_list, other.deny_list):
if q1 != q2:
return False
return True
def copy(self):
new = RoadSegmentState()
new.cars_present = [c.copy() for c in self.cars_present]
new.query_buffer = list(self.query_buffer)
new.deny_list = [q.copy() for q in self.deny_list]
new.reserved = self.reserved
new.send_query_delay = self.send_query_delay
new.send_query_id = self.send_query_id
new.send_ack_delay = self.send_ack_delay
new.send_ack_id = self.send_ack_id
new.send_car_delay = self.send_car_delay
new.send_car_id = self.send_car_id
new.last_car = self.last_car
return new
def __str__(self):
string = "Road segment: cars_present = ["
for i in self.cars_present:
string += str(i.ID) + ", "
return string + "] , send_query_delay = %.3f, send_ack_delay = %.3f, send_car_delay = %.3f, send_ack_id = %s" % (self.send_query_delay, self.send_ack_delay, self.send_car_delay, self.send_ack_id)
class RoadSegment(AtomicDEVS):
def __init__(self, district, load, l = 100.0, v_max = 18.0, observ_delay = 0.1, name = "RoadSegment"):
AtomicDEVS.__init__(self, name)
# arguments
self.l = float(l)
self.v_max = v_max
self.observ_delay = observ_delay
self.district = district
self.load = load
# in-ports
self.q_rans = self.addInPort(name="q_rans")
self.q_recv = self.addInPort(name="q_recv")
self.car_in = self.addInPort(name="car_in")
self.entries = self.addInPort(name="entries")
self.q_rans_bs = self.addInPort(name="q_rans_bs")
self.q_recv_bs = self.addInPort(name="q_recv_bs")
# compatibility bindings...
self.Q_recv = self.q_recv
self.Q_rack = self.q_rans
# out-ports
self.q_sans = self.addOutPort(name="q_sans")
self.q_send = self.addOutPort(name="q_send")
self.car_out = self.addOutPort(name="car_out")
self.exits = self.addOutPort(name="exits")
self.q_sans_bs = self.addOutPort(name="q_sans_bs")
# compatibility bindings...
self.Q_send = self.q_send
self.Q_sack = self.q_sans
self.state = RoadSegmentState()
def extTransition(self, inputs):
queries = inputs.get(self.Q_recv, [])
queries.extend(inputs.get(self.q_recv_bs, []))
cars = inputs.get(self.car_in, [])
cars.extend(inputs.get(self.entries, []))
acks = inputs.get(self.Q_rack, [])
acks.extend(inputs.get(self.q_rans_bs, []))
self.state.send_query_delay -= self.elapsed
self.state.send_ack_delay -= self.elapsed
self.state.send_car_delay -= self.elapsed
for query in queries:
if (not self.state.reserved) and not (len(self.state.cars_present) > 1 or (len(self.state.cars_present) == 1 and self.state.cars_present[0].v == 0)):
self.state.send_ack_delay = self.observ_delay
self.state.send_ack_id = query.ID
self.state.reserved = True
else:
self.state.query_buffer.append(query.ID)
self.state.deny_list.append(query)
if self.state.send_ack_delay == INFINITY:
self.state.send_ack_delay = self.observ_delay
self.state.send_ack_id = query.ID
self.state.last_car = query.ID
for car in self.state.cars_present:
car.remaining_x -= self.elapsed * car.v
for car in cars:
self.state.last_car = None
car.remaining_x = self.l
self.state.cars_present.append(car)
if len(self.state.cars_present) != 1:
for other_car in self.state.cars_present:
other_car.v = 0
self.state.send_query_delay = INFINITY
self.state.send_ack_delay = INFINITY
self.state.send_car_delay = INFINITY
else:
self.state.send_query_delay = 0
self.state.send_query_id = car.ID
if self.state.cars_present[-1].v == 0:
t_to_dep = INFINITY
else:
t_to_dep = max(0, self.l/self.state.cars_present[-1].v)
self.state.send_car_delay = t_to_dep
self.state.send_car_id = car.ID
for ack in acks:
if (len(self.state.cars_present) == 1) and (ack.ID == self.state.cars_present[0].ID):
car = self.state.cars_present[0]
t_no_col = ack.t_until_dep
v_old = car.v
v_pref = car.v_pref
remaining_x = car.remaining_x
if t_no_col + 1 == t_no_col:
v_new = 0
t_until_dep = INFINITY
else:
v_ideal = remaining_x / max(t_no_col, remaining_x / min(v_pref, self.v_max))
diff = v_ideal - v_old
if diff < 0:
if -diff > car.dv_neg_max:
diff = -car.dv_neg_max
elif diff > 0:
if diff > car.dv_pos_max:
diff = car.dv_pos_max
v_new = v_old + diff
if v_new == 0:
t_until_dep = INFINITY
else:
t_until_dep = car.remaining_x / v_new
car.v = v_new
t_until_dep = max(0, t_until_dep)
if t_until_dep > self.state.send_car_delay and self.state.last_car is not None:
self.state.send_ack_delay = self.observ_delay
self.state.send_ack_id = self.state.last_car
self.state.send_car_delay = t_until_dep
self.state.send_car_id = ack.ID
if t_until_dep == INFINITY:
self.state.send_query_id = ack.ID
else:
self.state.send_query_id = None
self.state.send_query_delay = INFINITY
return self.state
def intTransition(self):
for _ in range(self.load):
pass
mintime = self.mintime()
self.state.send_query_delay -= mintime
self.state.send_ack_delay -= mintime
self.state.send_car_delay -= mintime
if self.state.send_ack_delay == 0:
self.state.send_ack_delay = INFINITY
self.state.send_ack_id = None
elif self.state.send_query_delay == 0:
# Just sent a query, now deny all other queries and wait until the current car has left
self.state.send_query_delay = INFINITY
self.state.send_query_id = None
elif self.state.send_car_delay == 0:
self.state.cars_present = []
self.state.send_car_delay = INFINITY
self.state.send_car_id = None
# A car has left, so we can answer to the first other query we received
if len(self.state.query_buffer) != 0:
self.state.send_ack_delay = self.observ_delay
#print("Setting %s in %s" % (self.state.query_buffer, self.name))
self.state.send_ack_id = self.state.query_buffer.pop()
else:
# No car is waiting for this segment, so 'unreserve' it
self.state.reserved = False
if self.state.send_ack_id == None and len(self.state.deny_list) > 0:
self.state.send_ack_delay = self.observ_delay
#print("Denylist = %s in %s" % (self.state.deny_list, self.name))
self.state.send_ack_id = self.state.deny_list[0].ID
self.state.deny_list = self.state.deny_list[1:]
return self.state
def outputFnc(self):
outputs = {}
mintime = self.mintime()
if self.state.send_ack_delay == mintime:
ackID = self.state.send_ack_id
if len(self.state.cars_present) == 0:
t_until_dep = 0
elif (self.state.cars_present[0].v) == 0:
t_until_dep = INFINITY
else:
t_until_dep = self.l / self.state.cars_present[0].v
ack = QueryAck(ackID, t_until_dep)
outputs[self.Q_sack] = [ack]
outputs[self.q_sans_bs] = [ack]
elif self.state.send_query_delay == mintime:
query = Query(self.state.send_query_id)
if self.state.cars_present[0].path != []:
query.direction = self.state.cars_present[0].path[0]
outputs[self.Q_send] = [query]
elif self.state.send_car_delay == mintime:
car = self.state.cars_present[0]
car.distance_travelled += self.l
if len(car.path) == 0:
outputs[self.exits] = [car]
else:
outputs[self.car_out] = [car]
return outputs
def mintime(self):
return min(self.state.send_query_delay, self.state.send_ack_delay, self.state.send_car_delay)
def timeAdvance(self):
#return min(self.state.send_query_delay, self.state.send_ack_delay, self.state.send_car_delay)
delay = min(self.state.send_query_delay, self.state.send_ack_delay, self.state.send_car_delay)
# Take care of floating point errors
return max(delay, 0)
def preActivityCalculation(self):
return None
def postActivityCalculation(self, _):
# If a car has collided, no activity is here
return 1 if len(self.state.cars_present) == 1 else 0
class Road(CoupledDEVS):
def __init__(self, district, load, name="Road", segments=5):
CoupledDEVS.__init__(self, name)
self.segment = []
for i in range(segments):
self.segment.append(self.addSubModel(RoadSegment(load=load, district=district, name=(name + "_" + str(i)))))
# in-ports
self.q_rans = self.addInPort(name="q_rans")
self.q_recv = self.addInPort(name="q_recv")
self.car_in = self.addInPort(name="car_in")
self.entries = self.addInPort(name="entries")
self.q_rans_bs = self.addInPort(name="q_rans_bs")
self.q_recv_bs = self.addInPort(name="q_recv_bs")
# out-ports
self.q_sans = self.addOutPort(name="q_sans")
self.q_send = self.addOutPort(name="q_send")
self.car_out = self.addOutPort(name="car_out")
self.exits = self.addOutPort(name="exits")
self.q_sans_bs = self.addOutPort(name="q_sans_bs")
self.connectPorts(self.q_rans, self.segment[-1].q_rans)
self.connectPorts(self.q_recv, self.segment[0].q_recv)
self.connectPorts(self.car_in, self.segment[0].car_in)
self.connectPorts(self.entries, self.segment[0].entries)
self.connectPorts(self.q_rans_bs, self.segment[0].q_rans_bs)
self.connectPorts(self.q_recv_bs, self.segment[0].q_recv_bs)
self.connectPorts(self.segment[0].q_sans, self.q_sans)
self.connectPorts(self.segment[-1].q_send, self.q_send)
self.connectPorts(self.segment[-1].car_out, self.car_out)
self.connectPorts(self.segment[0].exits, self.exits)
self.connectPorts(self.segment[0].q_sans_bs, self.q_sans_bs)
for i in range(segments):
if i == 0:
continue
self.connectPorts(self.segment[i].q_sans, self.segment[i-1].q_rans)
self.connectPorts(self.segment[i-1].q_send, self.segment[i].q_recv)
self.connectPorts(self.segment[i-1].car_out, self.segment[i].car_in)
class IntersectionState():
def __init__(self, switch_signal):
self.send_query = []
self.send_ack = []
self.send_car = []
self.queued_queries = []
self.id_locations = [None, None, None, None]
self.block = vertical
self.switch_signal = switch_signal
self.ackDir = {}
def __str__(self):
return "ISECT blocking " + str(self.block)
return "Intersection: send_query = " + str(self.send_query) + ", send_ack = " + str(self.send_ack) + ", send_car = " + str(self.send_car) + ", block = " + str(self.block)
def copy(self):
new = IntersectionState(self.switch_signal)
new.send_query = [q.copy() for q in self.send_query]
new.send_ack = [a.copy() for a in self.send_ack]
new.send_car = [c.copy() for c in self.send_car]
new.queued_queries = [q.copy() for q in self.queued_queries]
new.id_locations = list(self.id_locations)
new.block = self.block
new.switch_signal = self.switch_signal
new.ackDir = dict(self.ackDir)
return new
class Intersection(AtomicDEVS):
def __init__(self, district, name="Intersection", switch_signal = 30):
AtomicDEVS.__init__(self, name=name)
self.state = IntersectionState(switch_signal)
self.switch_signal_delay = switch_signal
self.district = district
self.q_send = []
self.q_send.append(self.addOutPort(name="q_send_to_n"))
self.q_send.append(self.addOutPort(name="q_send_to_e"))
self.q_send.append(self.addOutPort(name="q_send_to_s"))
self.q_send.append(self.addOutPort(name="q_send_to_w"))
self.q_rans = []
self.q_rans.append(self.addInPort(name="q_rans_from_n"))
self.q_rans.append(self.addInPort(name="q_rans_from_e"))
self.q_rans.append(self.addInPort(name="q_rans_from_s"))
self.q_rans.append(self.addInPort(name="q_rans_from_w"))
self.q_recv = []
self.q_recv.append(self.addInPort(name="q_recv_from_n"))
self.q_recv.append(self.addInPort(name="q_recv_from_e"))
self.q_recv.append(self.addInPort(name="q_recv_from_s"))
self.q_recv.append(self.addInPort(name="q_recv_from_w"))
self.q_sans = []
self.q_sans.append(self.addOutPort(name="q_sans_to_n"))
self.q_sans.append(self.addOutPort(name="q_sans_to_e"))
self.q_sans.append(self.addOutPort(name="q_sans_to_s"))
self.q_sans.append(self.addOutPort(name="q_sans_to_w"))
self.car_in = []
self.car_in.append(self.addInPort(name="car_in_from_n"))
self.car_in.append(self.addInPort(name="car_in_from_e"))
self.car_in.append(self.addInPort(name="car_in_from_s"))
self.car_in.append(self.addInPort(name="car_in_from_w"))
self.car_out = []
self.car_out.append(self.addOutPort(name="car_out_to_n"))
self.car_out.append(self.addOutPort(name="car_out_to_e"))
self.car_out.append(self.addOutPort(name="car_out_to_s"))
self.car_out.append(self.addOutPort(name="car_out_to_w"))
def intTransition(self):
self.state.switch_signal -= self.timeAdvance()
if self.state.switch_signal <= 1e-6:
# We switched our traffic lights
self.state.switch_signal = self.switch_signal_delay
self.state.queued_queries = []
self.state.block = vertical if self.state.block == horizontal else horizontal
for loc, car_id in enumerate(self.state.id_locations):
# Notify all cars that got 'green' that they should not continue
if car_id is None:
continue
try:
if str(loc) in self.state.block:
query = Query(car_id)
query.direction = int_to_dir[self.state.ackDir[car_id]]
self.state.queued_queries.append(query)
except KeyError:
pass
self.state.send_car = []
self.state.send_query = []
self.state.send_ack = []
return self.state
def extTransition(self, inputs):
# Simple forwarding of all messages
# Unless the direction in which it is going is blocked
self.state.switch_signal -= self.elapsed
for direction in range(4):
blocked = str(direction) in self.state.block
for car in inputs.get(self.car_in[direction], []):
self.state.send_car.append(car)
# Got a car, so remove its ID location entry
try:
del self.state.ackDir[car.ID]
self.state.id_locations[self.state.id_locations.index(car.ID)] = None
except (KeyError, ValueError):
pass
self.state.queued_queries = [query for query in self.state.queued_queries if query.ID != car.ID]
for query in inputs.get(self.q_recv[direction], []):
self.state.id_locations[direction] = query.ID
self.state.ackDir[query.ID] = dir_to_int[query.direction]
if blocked:
self.state.send_ack.append(QueryAck(query.ID, INFINITY))
self.state.queued_queries.append(query)
else:
self.state.send_query.append(query)
for ack in inputs.get(self.q_rans[direction], []):
self.state.ackDir[ack.ID] = direction
if (ack.t_until_dep > self.state.switch_signal) or ((ack.ID in self.state.id_locations) and (str(self.state.id_locations.index(ack.ID)) in self.state.block)):
try:
self.state.id_locations.index(ack.ID)
t_until_dep = INFINITY
nquery = Query(ack.ID)
nquery.direction = int_to_dir[direction]
self.state.queued_queries.append(nquery)
except ValueError:
continue
else:
t_until_dep = ack.t_until_dep
self.state.send_ack.append(QueryAck(ack.ID, t_until_dep))
return self.state
def outputFnc(self):
# Can simply overwrite, as multiple calls to the same destination is impossible
toSend = {}
new_block = vertical if self.state.block == horizontal else horizontal
if self.state.switch_signal == self.timeAdvance():
# We switch our traffic lights
# Resend all queries for those that are waiting
for query in self.state.queued_queries:
if str(self.state.id_locations.index(query.ID)) not in new_block:
toSend[self.q_send[dir_to_int[query.direction]]] = [query]
for loc, car_id in enumerate(self.state.id_locations):
# Notify all cars that got 'green' that they should not continue
if car_id is None:
continue
if str(loc) in new_block:
toSend[self.q_sans[loc]] = [QueryAck(car_id, INFINITY)]
else:
try:
query = Query(car_id)
query.direction = int_to_dir[self.state.ackDir[car_id]]
toSend[self.q_send[self.state.ackDir[car_id]]] = [query]
except KeyError:
pass
# We might have some messages to forward too
for car in self.state.send_car:
dest = car.path.pop(0)
toSend[self.car_out[dir_to_int[dest]]] = [car]
for query in self.state.send_query:
toSend[self.q_send[dir_to_int[query.direction]]] = [query]
for ack in self.state.send_ack:
# Broadcast for now
try:
toSend[self.q_sans[self.state.id_locations.index(ack.ID)]] = [ack]
except ValueError:
pass
return toSend
def timeAdvance(self):
if len(self.state.send_car) + len(self.state.send_query) + len(self.state.send_ack) > 0:
return 0.0
else:
return max(self.state.switch_signal, 0.0)
def preActivityCalculation(self):
return None
def postActivityCalculation(self, _):
return len(self.state.send_car)
class CollectorState(object):
def __init__(self):
self.cars = []
def copy(self):
new = CollectorState()
new.cars = list(self.cars)
return new
def __str__(self):
## Print your statistics here!
s = "All cars collected:"
for car in self.cars:
s += "\n\t\t\t%s" % car
return s
class Collector(AtomicDEVS):
def __init__(self):
AtomicDEVS.__init__(self, "Collector")
self.car_in = self.addInPort("car_in")
self.state = CollectorState()
self.district = 0
def extTransition(self, inputs):
self.state.cars.extend(inputs[self.car_in])
return self.state
def preActivityCalculation(self):
return None
def postActivityCalculation(self, _):
return 0