From 342320bd4ac1a25d8125838e8e9fe3aa76e0ad61 Mon Sep 17 00:00:00 2001 From: Ahp06 Date: Fri, 7 Dec 2018 16:30:23 +0100 Subject: [PATCH] Added a logs file output --- sumo_project/actions.py | 21 +++--- sumo_project/config.py | 48 +++++++++++--- sumo_project/emissions.py | 131 ++++++++++++++++++++++---------------- sumo_project/model.py | 1 + 4 files changed, 125 insertions(+), 76 deletions(-) diff --git a/sumo_project/actions.py b/sumo_project/actions.py index 483abb4..1758d6c 100644 --- a/sumo_project/actions.py +++ b/sumo_project/actions.py @@ -31,11 +31,10 @@ def adjust_edges_weights(): for veh_id in traci.vehicle.getIDList(): traci.vehicle.rerouteEffort(veh_id) -def limit_speed_into_area(area: Area, vehicles: Iterable[Vehicle], max_speed): - print(f'Setting max speed into {area.name} to {max_speed} km/h') +def limit_speed_into_area(area: Area, vehicles: Iterable[Vehicle], speed_rf): area.limited_speed = True for lane in area._lanes: - traci.lane.setMaxSpeed(lane.lane_id, max_speed/3.6) + traci.lane.setMaxSpeed(lane.lane_id, speed_rf * lane.initial_max_speed) def modifyLogic(logic, rf): #rf for "reduction factor" new_phases = [] @@ -46,20 +45,20 @@ def modifyLogic(logic, rf): #rf for "reduction factor" return traci.trafficlight.Logic("new-program", 0 , 0 , 0 , new_phases) def adjust_traffic_light_phase_duration(area, reduction_factor): - print(f'Decrease of traffic lights duration by a factor of {reduction_factor}') + area.tls_adjusted = True for tl in area._tls: for logic in tl._logics: traci.trafficlights.setCompleteRedYellowGreenDefinition(tl.tl_id, modifyLogic(logic,reduction_factor)) -def lock_area(area): +def count_vehicles_in_area(area): #Trying to lock area vehicles_in_area = 0 for lane in area._lanes: vehicles_in_area += traci.lane.getLastStepVehicleNumber(lane.lane_id) - #Waiting for the area to be empty before blocking it - if vehicles_in_area == 0: - area.locked = True - print(f'Area locked : {area.name}') - for lane in area._lanes: - traci.lane.setDisallowed(lane.lane_id, 'passenger') \ No newline at end of file + return vehicles_in_area + +def lock_area(area): + area.locked = True + for lane in area._lanes: + traci.lane.setDisallowed(lane.lane_id, 'passenger') \ No newline at end of file diff --git a/sumo_project/config.py b/sumo_project/config.py index 51fe185..1fc819b 100644 --- a/sumo_project/config.py +++ b/sumo_project/config.py @@ -4,6 +4,11 @@ Global configuration for the simulation import os import sys +import datetime + +############################################################################### +############################# SIMULATION FILE ################################# +############################################################################### if 'SUMO_HOME' in os.environ: tools = os.path.join(os.environ['SUMO_HOME'], 'tools') @@ -13,39 +18,63 @@ else: _SUMOCMD = 'sumo' # use 'sumo-gui' cmd for UI _SUMOCFG = "mulhouse_simulation/osm.sumocfg" +sumo_binary = os.path.join(os.environ['SUMO_HOME'], 'bin', _SUMOCMD) +sumo_cmd = [sumo_binary, "-c", _SUMOCFG] + +############################################################################### +############################# LOGS OUTPUT ##################################### +############################################################################### + +now = datetime.datetime.now() +current_date = now.strftime("%Y_%m_%d_%H_%M") +LOG_FILENAME = f'sumo_logs_{current_date}.log' + +############################################################################### +########################## SIMULATION CONFIGURATION ########################### +############################################################################### + CELLS_NUMBER = 10 EMISSIONS_THRESHOLD = 500000 n_steps = 200 +############################################################################### +########################## ACTIONS CONFIGURATION ############################## +############################################################################### + #Limit the speed into areas when the threshold is exceeded -limited_speed = 30 +speed_rf = 0.1 limit_speed_mode = False #Decrease all traffic lights duration into the area when the threshold is exceeded -rf_trafficLights_duration = 1.4 +trafficLights_duration_rf = 0.2 adjust_traffic_light_mode = False #Immediately delete all vehicles in the simulation area remove_vehicles_mode = False #Vehicles are routed according to the less polluted route (HEAVY) -weight_routing_mode = True +weight_routing_mode = False #Lock the area when the threshold is exceeded (NOT FIXED) -lock_area_mode = False +lock_area_mode = True #Weight routing mode cannot be combinated with other actions if weight_routing_mode: limit_speed_mode = False adjust_traffic_light_mode = False -sumo_binary = os.path.join(os.environ['SUMO_HOME'], 'bin', _SUMOCMD) -sumo_cmd = [sumo_binary, "-c", _SUMOCFG] +############################################################################### +########################## SIMULATION REFERENCES ############################## +############################################################################### # Total of emissions of all pollutants in mg for n steps of simulation without locking areas total_emissions200 = 43970763.15084749 total_emissions300 = 87382632.08217141 +############################################################################### +########################## CONFIGURATION METHODS ############################## +############################################################################### + def get_basics_emissions(): if n_steps == 200: return total_emissions200 @@ -55,7 +84,8 @@ def get_basics_emissions(): def showConfig(): return (str(f'Grid : {CELLS_NUMBER}x{CELLS_NUMBER}\n') + str(f'step number = {n_steps}\n') - + str(f'weight routing mode= {weight_routing_mode}\n') - + str(f'limit speed mode = {limit_speed_mode}, limited speed to {limited_speed}\n') - + str(f'adjust traffic light mode = {adjust_traffic_light_mode} , RF = {rf_trafficLights_duration}\n')) + + str(f'weight routing mode = {weight_routing_mode}\n') + + str(f'lock area mode = {lock_area_mode}\n') + + str(f'limit speed mode = {limit_speed_mode}, RF = {speed_rf*100}%\n') + + str(f'adjust traffic light mode = {adjust_traffic_light_mode} , RF = {trafficLights_duration_rf*100}%\n')) diff --git a/sumo_project/emissions.py b/sumo_project/emissions.py index be52a1f..24c22f3 100644 --- a/sumo_project/emissions.py +++ b/sumo_project/emissions.py @@ -1,8 +1,9 @@ -# -*- coding: latin-1 -*- - from typing import List import traci +import logging +import time + from shapely.geometry import LineString from parse import * @@ -12,6 +13,18 @@ import sys from model import Area, Vehicle, Lane , TrafficLight , Phase , Logic from traci import trafficlight +# create logger +logger = logging.getLogger("sumo_logger") +logger.setLevel(logging.INFO) +# create console handler and set level to info +handler = logging.FileHandler(config.LOG_FILENAME) +# create formatter +formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") +# add formatter to handler +handler.setFormatter(formatter) +# add handler to logger +logger.addHandler(handler) + def init_grid(simulation_bounds, cells_number): grid = list() @@ -23,11 +36,47 @@ def init_grid(simulation_bounds, cells_number): ar_bounds = ((i * width, j * height), (i * width, (j + 1) * height), ((i + 1) * width, (j + 1) * height), ((i + 1) * width, j * height)) area = Area(ar_bounds) - area.name = 'area ({},{})'.format(i, j) + area.name = 'Area ({},{})'.format(i, j) grid.append(area) traci.polygon.add(area.name, ar_bounds, (0, 255, 0)) return grid +def get_all_lanes() -> List[Lane]: + lanes = [] + for lane_id in traci.lane.getIDList(): + polygon_lane = LineString(traci.lane.getShape(lane_id)) + initial_max_speed = traci.lane.getMaxSpeed(lane_id) + lanes.append(Lane(lane_id, polygon_lane, initial_max_speed)) + return lanes + +def parsePhase(phase_repr): + duration = search('duration: {:f}', phase_repr) + minDuration = search('minDuration: {:f}', phase_repr) + maxDuration = search('maxDuration: {:f}', phase_repr) + phaseDef = search('phaseDef: {}\n', phase_repr) + + if phaseDef is None: phaseDef = '' + else : phaseDef = phaseDef[0] + + return Phase(duration[0], minDuration[0], maxDuration[0], phaseDef) + +def add_data_to_areas(areas: List[Area]): + + + lanes = get_all_lanes() + for area in areas: + for lane in lanes: # add lanes + if area.rectangle.intersects(lane.polygon): + area.add_lane(lane) + for tl_id in traci.trafficlight.getIDList(): # add traffic lights + if lane.lane_id in traci.trafficlight.getControlledLanes(tl_id): + logics = [] + for l in traci.trafficlight.getCompleteRedYellowGreenDefinition(tl_id): #add logics + phases = [] + for phase in traci.trafficlight.Logic.getPhases(l): #add phases to logics + phases.append(parsePhase(phase.__repr__())) + logics.append(Logic(l,phases)) + area.add_tl(TrafficLight(tl_id,logics)) def compute_vehicle_emissions(veh_id): return (traci.vehicle.getCOEmission(veh_id) @@ -46,16 +95,6 @@ def get_all_vehicles() -> List[Vehicle]: vehicles.append(vehicle) return vehicles - -def get_all_lanes() -> List[Lane]: - lanes = [] - for lane_id in traci.lane.getIDList(): - polygon_lane = LineString(traci.lane.getShape(lane_id)) - initial_max_speed = traci.lane.getMaxSpeed(lane_id) - lanes.append(Lane(lane_id, polygon_lane, initial_max_speed)) - return lanes - - def get_emissions(grid: List[Area], vehicles: List[Vehicle]): for area in grid: for vehicle in vehicles: @@ -64,52 +103,34 @@ def get_emissions(grid: List[Area], vehicles: List[Vehicle]): if area.emissions > config.EMISSIONS_THRESHOLD: if config.limit_speed_mode and not area.limited_speed: - actions.limit_speed_into_area(area, vehicles, config.limited_speed) + logger.info(f'Action - Decrease of max speed into {area.name} by {config.speed_rf*100}%') + actions.limit_speed_into_area(area, vehicles, config.speed_rf) traci.polygon.setColor(area.name, (255, 0, 0)) traci.polygon.setFilled(area.name, True) - if config.adjust_traffic_light_mode: - actions.adjust_traffic_light_phase_duration(area, config.rf_trafficLights_duration) + if config.adjust_traffic_light_mode and not area.tls_adjusted: + logger.info(f'Action - Decrease of traffic lights duration by {config.trafficLights_duration_rf*100}%') + actions.adjust_traffic_light_phase_duration(area, config.trafficLights_duration_rf) if config.lock_area_mode and not area.locked: - actions.lock_area(area) + if actions.count_vehicles_in_area(area): + logger.info(f'Action - {area.name} blocked') + actions.lock_area(area) - -def parsePhase(phase_repr): - duration = search('duration: {:f}', phase_repr) - minDuration = search('minDuration: {:f}', phase_repr) - maxDuration = search('maxDuration: {:f}', phase_repr) - phaseDef = search('phaseDef: {}\n', phase_repr) - - if phaseDef is None: phaseDef = '' - else : phaseDef = phaseDef[0] - - return Phase(duration[0], minDuration[0], maxDuration[0], phaseDef) - - -def add_data_to_areas(areas: List[Area]): - lanes = get_all_lanes() - for area in areas: - for lane in lanes: # add lanes - if area.rectangle.intersects(lane.polygon): - area.add_lane(lane) - for tl_id in traci.trafficlight.getIDList(): # add traffic lights - if lane.lane_id in traci.trafficlight.getControlledLanes(tl_id): - logics = [] - for l in traci.trafficlight.getCompleteRedYellowGreenDefinition(tl_id): #add logics - phases = [] - for phase in traci.trafficlight.Logic.getPhases(l): #add phases to logics - phases.append(parsePhase(phase.__repr__())) - logics.append(Logic(l,phases)) - area.add_tl(TrafficLight(tl_id,logics)) - - def main(): grid = list() try: traci.start(config.sumo_cmd) + + logger.info('Loading data for the simulation') + start = time.perf_counter() + grid = init_grid(traci.simulation.getNetBoundary(), config.CELLS_NUMBER) add_data_to_areas(grid) - + + loading_time = round(time.perf_counter() - start,2) + logger.info(f'Data loaded ({loading_time}s)') + + logger.info('Start of the simulation') step = 0 while step < config.n_steps : #traci.simulation.getMinExpectedNumber() > 0: traci.simulationStep() @@ -118,28 +139,26 @@ def main(): get_emissions(grid, vehicles) if config.weight_routing_mode: + logger.info('Action - Lane weights adjusted') actions.adjust_edges_weights() step += 1 - progress = round(step/config.n_steps*100,2) - sys.stdout.write(f'Progress : {progress}%'+'\r') - sys.stdout.flush() finally: traci.close(False) - + logger.info('End of the simulation') total_emissions = 0 for area in grid: total_emissions += area.emissions - print("\n**** RESULTS ****") - print(f'Total emissions = {total_emissions} mg') + logger.info(f'Total emissions = {total_emissions} mg') ref = config.get_basics_emissions() diff_with_actions = (ref - total_emissions)/ref - print(f'Reduction percentage of emissions = {diff_with_actions*100} %') - print("**** With the configuration : ****\n" + str(config.showConfig())) + logger.info(f'Reduction percentage of emissions = {diff_with_actions*100} %') + logger.info('With the configuration : \n' + str(config.showConfig())) + logger.info('Logs END') if __name__ == '__main__': diff --git a/sumo_project/model.py b/sumo_project/model.py index 736e3e6..888cef7 100644 --- a/sumo_project/model.py +++ b/sumo_project/model.py @@ -48,6 +48,7 @@ class Area: def __init__(self, coords, name=''): self.limited_speed = False self.locked = False + self.tls_adjusted = False self.rectangle = Polygon(coords) self.name = name self.emissions = 0.0