Implement dynamic adjustment of velocity
This commit is contained in:
parent
caae4e54d7
commit
ad74621616
@ -2,22 +2,22 @@
|
|||||||
{
|
{
|
||||||
"id": "1",
|
"id": "1",
|
||||||
"location": [16.20719, 47.89584],
|
"location": [16.20719, 47.89584],
|
||||||
"range": 2000,
|
"range": 542,
|
||||||
"switchingTime": 500,
|
"switchingTime": 15,
|
||||||
"initialColor": "RED"
|
"initialColor": "RED"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "2",
|
"id": "2",
|
||||||
"location": [16.20814, 47.90937],
|
"location": [16.20814, 47.90937],
|
||||||
"range": 800,
|
"range": 725,
|
||||||
"switchingTime": 240,
|
"switchingTime": 20,
|
||||||
"initialColor": "GREEN"
|
"initialColor": "GREEN"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "3",
|
"id": "3",
|
||||||
"location": [16.20917, 47.92703],
|
"location": [16.20917, 47.92703],
|
||||||
"range": 1000,
|
"range": 910,
|
||||||
"switchingTime": 360,
|
"switchingTime": 25,
|
||||||
"initialColor": "RED"
|
"initialColor": "RED"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -11,7 +11,7 @@ from dse_shared_libs.message_broker_wrapper import MBWrapper
|
|||||||
from dse_shared_libs.traffic_light_state import TrafficLightState
|
from dse_shared_libs.traffic_light_state import TrafficLightState
|
||||||
from pika.exceptions import AMQPConnectionError
|
from pika.exceptions import AMQPConnectionError
|
||||||
|
|
||||||
SWITCHING_TIME = 10
|
SWITCHING_TIME = 15
|
||||||
# Scale speed of switching by factor x
|
# Scale speed of switching by factor x
|
||||||
SCALING = 1
|
SCALING = 1
|
||||||
|
|
||||||
|
|||||||
@ -16,18 +16,18 @@ from dse_shared_libs.target_velocity import TargetVelocity
|
|||||||
from pika.exceptions import AMQPConnectionError
|
from pika.exceptions import AMQPConnectionError
|
||||||
|
|
||||||
STARTING_POINT = geopy.Point(47.89053, 16.20703)
|
STARTING_POINT = geopy.Point(47.89053, 16.20703)
|
||||||
# in km/h
|
|
||||||
STARTING_VELOCITY = 130
|
|
||||||
# Driving direction in degrees: 0=N, 90=E, 180=S, 270=W
|
# Driving direction in degrees: 0=N, 90=E, 180=S, 270=W
|
||||||
BEARING = 0
|
BEARING = 0
|
||||||
# Scale speed of vehicles by factor x
|
# Scale speed of vehicles by factor x
|
||||||
SCALING = 2
|
SCALING = 1
|
||||||
|
# in km/h
|
||||||
|
STARTING_VELOCITY = 130 * SCALING
|
||||||
# Interval between status updates in seconds (is not scaled)
|
# Interval between status updates in seconds (is not scaled)
|
||||||
UPDATE_INTERVAL = 1
|
UPDATE_INTERVAL = 1
|
||||||
# At x km the NCE shall happen
|
# At x km the NCE shall happen
|
||||||
NCE_KM = 2.4
|
NCE_KM = 2.4
|
||||||
# Time in seconds to recover from NCE (will be scaled)
|
# Time in seconds to recover from NCE (will be scaled)
|
||||||
TIME_TO_RECOVER = 10
|
TIME_TO_RECOVER = 5
|
||||||
# Resets vehicle at km x
|
# Resets vehicle at km x
|
||||||
RESET_KM = 4
|
RESET_KM = 4
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,8 @@ import pickle
|
|||||||
import sys
|
import sys
|
||||||
from random import randrange
|
from random import randrange
|
||||||
from typing import List, Dict
|
from typing import List, Dict
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
from math import floor, ceil
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from dse_shared_libs import daf, traffic_light_state, traffic_light_color, target_velocity
|
from dse_shared_libs import daf, traffic_light_state, traffic_light_color, target_velocity
|
||||||
@ -11,6 +13,7 @@ from dse_shared_libs.message_broker_wrapper import MBWrapper
|
|||||||
# necessary to unpickle daf object
|
# necessary to unpickle daf object
|
||||||
from dse_shared_libs.target_velocity import TargetVelocity
|
from dse_shared_libs.target_velocity import TargetVelocity
|
||||||
from dse_shared_libs.traffic_light_state import TrafficLightState
|
from dse_shared_libs.traffic_light_state import TrafficLightState
|
||||||
|
from dse_shared_libs.traffic_light_color import TrafficLightColor
|
||||||
from requests import Session
|
from requests import Session
|
||||||
|
|
||||||
sys.modules['daf'] = daf
|
sys.modules['daf'] = daf
|
||||||
@ -18,7 +21,6 @@ sys.modules['traffic_light_state'] = traffic_light_state
|
|||||||
sys.modules['traffic_light_color'] = traffic_light_color
|
sys.modules['traffic_light_color'] = traffic_light_color
|
||||||
sys.modules['target_velocity'] = target_velocity
|
sys.modules['target_velocity'] = target_velocity
|
||||||
|
|
||||||
|
|
||||||
ENTITY_IDENT_URL = 'http://entityident:5002/api/v1/resources/'
|
ENTITY_IDENT_URL = 'http://entityident:5002/api/v1/resources/'
|
||||||
|
|
||||||
|
|
||||||
@ -53,7 +55,8 @@ class Orchestrator:
|
|||||||
|
|
||||||
for traffic_light in traffic_lights['cursor']:
|
for traffic_light in traffic_lights['cursor']:
|
||||||
self.tls[traffic_light['id']] = {'color': traffic_light['initialColor'],
|
self.tls[traffic_light['id']] = {'color': traffic_light['initialColor'],
|
||||||
'switching_time': traffic_light['switchingTime']}
|
'switching_time': traffic_light['switchingTime'],
|
||||||
|
'last_switch': datetime.now()}
|
||||||
|
|
||||||
def setup_msg_queues(self):
|
def setup_msg_queues(self):
|
||||||
# spawn the vehicle related message broker channels
|
# spawn the vehicle related message broker channels
|
||||||
@ -82,28 +85,47 @@ class Orchestrator:
|
|||||||
"""
|
"""
|
||||||
received_daf_object: DAF = pickle.loads(pickle_binary)
|
received_daf_object: DAF = pickle.loads(pickle_binary)
|
||||||
loc = received_daf_object.gps_location
|
loc = received_daf_object.gps_location
|
||||||
print(received_daf_object)
|
print('Received DAF object: {}'.format(received_daf_object))
|
||||||
|
|
||||||
# TODO ask entity ident if tl in range?!
|
|
||||||
# something like the following below ...
|
|
||||||
response = self._session.get(ENTITY_IDENT_URL + 'traffic_lights_geo',
|
response = self._session.get(ENTITY_IDENT_URL + 'traffic_lights_geo',
|
||||||
params={'lat': loc.latitude, 'lon': loc.longitude})
|
params={'lat': loc.latitude, 'lon': loc.longitude})
|
||||||
traffic_lights_geo = response.json()
|
traffic_lights_geo = response.json()
|
||||||
print('TLGeo', traffic_lights_geo)
|
current_vel = received_daf_object.velocity
|
||||||
# TODO in the best case we get a traffic light ID and some sort of visibility range here?
|
target_vel = 130
|
||||||
# we need to calculate new speed regarding current speed and position and visibility of TL to ensure a
|
print('Nearest traffic lights: {}'.format(traffic_lights_geo['cursor']))
|
||||||
# green wave
|
print('Nearest traffic light count: {}'.format(len(traffic_lights_geo['cursor'])))
|
||||||
# keep NCE in mind ... vehicle will not adapt to target velocity if still recovering from NCE
|
for traffic_light in traffic_lights_geo['cursor']:
|
||||||
|
# Should only ever contain one traffic light
|
||||||
# TODO use the data from the traffic lights (self.tls)
|
tl_id = traffic_light['id']
|
||||||
# to transmit a new target velocity for this vehicle to achieve a green wave
|
distance = traffic_light['calculatedRange']
|
||||||
|
next_switch_time = self.tls[tl_id]['last_switch'] + timedelta(seconds=self.tls[tl_id]['switching_time'])
|
||||||
|
time_until_switch = next_switch_time - datetime.now()
|
||||||
|
print('Distance to TL: {}'.format(distance))
|
||||||
|
print('Time until switch in seconds: {}'.format(time_until_switch.total_seconds()))
|
||||||
|
if self.tls[tl_id]['color'] is TrafficLightColor.RED:
|
||||||
|
# Ceil because we want to get there AFTER the light changed
|
||||||
|
speed_needed = (distance / float(time_until_switch.total_seconds())) * 3.6
|
||||||
|
if current_vel > speed_needed:
|
||||||
|
print('Current velocity too high ({}), adjusting to {}'.format(current_vel, speed_needed))
|
||||||
|
target_vel = speed_needed
|
||||||
|
else:
|
||||||
|
print('Current velocity lower ({})'.format(current_vel))
|
||||||
|
target_vel = current_vel
|
||||||
|
else:
|
||||||
|
# Check if we can cross in time with max speed (130)
|
||||||
|
speed_needed = (distance / float(time_until_switch.total_seconds())) * 3.6
|
||||||
|
if speed_needed >= 130:
|
||||||
|
# Cannot make it in time, wait for next green
|
||||||
|
print('Wait on green -> red -> green switch')
|
||||||
|
time_until_green = time_until_switch + timedelta(seconds=self.tls[tl_id]['switching_time'])
|
||||||
|
target_vel = (distance / float(time_until_green.total_seconds())) * 3.6
|
||||||
|
print('Speed should be way lower than 130: {}'.format(target_vel))
|
||||||
|
|
||||||
response_channel = self._velocity_mbs[received_daf_object.vehicle_identification_number]
|
response_channel = self._velocity_mbs[received_daf_object.vehicle_identification_number]
|
||||||
target_vel = randrange(0, 130)
|
|
||||||
print('Target velocity: {}'.format(target_vel))
|
print('Target velocity: {}'.format(target_vel))
|
||||||
response_channel.send(pickle.dumps(
|
response_channel.send(pickle.dumps(
|
||||||
TargetVelocity(vin=received_daf_object.vehicle_identification_number, target_velocity=target_vel,
|
TargetVelocity(vin=received_daf_object.vehicle_identification_number, target_velocity=target_vel,
|
||||||
timestamp=datetime.datetime.now())))
|
timestamp=datetime.now())))
|
||||||
|
|
||||||
def handle_tl_state_receive(self, msg):
|
def handle_tl_state_receive(self, msg):
|
||||||
"""
|
"""
|
||||||
@ -117,4 +139,5 @@ class Orchestrator:
|
|||||||
"""
|
"""
|
||||||
tl_state: TrafficLightState = pickle.loads(msg)
|
tl_state: TrafficLightState = pickle.loads(msg)
|
||||||
self.tls[tl_state.tlid]['color'] = tl_state.color
|
self.tls[tl_state.tlid]['color'] = tl_state.color
|
||||||
|
self.tls[tl_state.tlid]['last_switch'] = tl_state.last_switch
|
||||||
print(tl_state)
|
print(tl_state)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user