87 lines
3.4 KiB
Python
87 lines
3.4 KiB
Python
import pickle
|
|
import sys
|
|
from random import randrange
|
|
from typing import List, Dict
|
|
|
|
from dse_shared_libs import daf, traffic_light_state, traffic_light_color, target_velocity
|
|
from dse_shared_libs.message_broker_wrapper import MBWrapper
|
|
# necessary to unpickle daf object
|
|
from dse_shared_libs.target_velocity import TargetVelocity
|
|
from dse_shared_libs.traffic_light_state import TrafficLightState
|
|
|
|
sys.modules['daf'] = daf
|
|
sys.modules['traffic_light_state'] = traffic_light_state
|
|
sys.modules['traffic_light_color'] = traffic_light_color
|
|
sys.modules['target_velocity'] = target_velocity
|
|
|
|
|
|
class Orchestrator:
|
|
# vehicle ids
|
|
vins: List[str] = []
|
|
# traffic lights {tlid: {color: color, switching_time: in_seconds}}
|
|
tls: Dict[str, Dict] = {}
|
|
|
|
# cache all active incoming daf connections
|
|
_daf_mbs: Dict[str, MBWrapper] = {}
|
|
_velocity_mbs: Dict[str, MBWrapper] = {}
|
|
|
|
def __init__(self, cars, traffic_lights):
|
|
for car in cars['cursor']:
|
|
self.vins.append(car['vin'])
|
|
|
|
for traffic_light in traffic_lights['cursor']:
|
|
self.tls[traffic_light['id']] = {'color': traffic_light['initialColor'],
|
|
'switching_time': traffic_light['switchingTime']}
|
|
|
|
def setup_msg_queues(self):
|
|
# spawn the vehicle related message broker channels
|
|
for vin in self.vins:
|
|
daf_channel = MBWrapper(exchange_name='vehicle_daf_{}'.format(vin), callback=self.handle_daf_receive)
|
|
daf_channel.setup_receiver()
|
|
self._daf_mbs[vin] = daf_channel
|
|
|
|
velocity_channel = MBWrapper(exchange_name='vehicle_velocity_{}'.format(vin))
|
|
velocity_channel.setup_sender()
|
|
self._velocity_mbs[vin] = velocity_channel
|
|
|
|
# spawn the traffic light related mb channels
|
|
for tl in self.tls:
|
|
tl_channel = MBWrapper(exchange_name='traffic_light_state_{}'.format(tl),
|
|
callback=self.handle_tl_state_receive)
|
|
tl_channel.setup_receiver()
|
|
|
|
def handle_daf_receive(self, pickle_binary):
|
|
"""
|
|
Gets the daf object's pickle binary dump.
|
|
Unpickle, calculate new target velocity based on daf and current tl data and
|
|
respond new target velicity for this vehicle.
|
|
|
|
:param pickle_binary: daf object pickle binary dump
|
|
"""
|
|
received_daf_object = pickle.loads(pickle_binary)
|
|
print(received_daf_object)
|
|
|
|
# TODO ask entity ident if tl in range?!
|
|
# TODO use the data from the traffic lights (self.tls)
|
|
# to transmit a new target velocity for this vehicle to achieve a green wave
|
|
|
|
response_channel = self._velocity_mbs[received_daf_object.vehicle_identification_number]
|
|
target_vel = randrange(0, 130)
|
|
print('Target velocity: {}'.format(target_vel))
|
|
response_channel.send(pickle.dumps(
|
|
TargetVelocity(vin=received_daf_object.vehicle_identification_number, target_velocity=target_vel)))
|
|
|
|
def handle_tl_state_receive(self, msg):
|
|
"""
|
|
Gets a dict full of traffic light state information:
|
|
{
|
|
'tlid': str,
|
|
'color': TrafficLightColor,
|
|
'last_switch': datetime
|
|
}
|
|
Updates internal information about available TLs
|
|
"""
|
|
tl_state: TrafficLightState = pickle.loads(msg)
|
|
self.tls[tl_state.tlid]['color'] = tl_state.color
|
|
print(tl_state)
|