mirror of
				https://github.com/Ahp06/SUMO_Emissions.git
				synced 2025-10-31 02:19:18 +00:00 
			
		
		
		
	Added floating window for data recovery
This commit is contained in:
		| @@ -3,13 +3,14 @@ Created on 17 oct. 2018 | |||||||
|  |  | ||||||
| @author: Axel Huynh-Phuc, Thibaud Gasser | @author: Axel Huynh-Phuc, Thibaud Gasser | ||||||
| """ | """ | ||||||
|  | import traci | ||||||
|  | from traci._trafficlight import Logic | ||||||
| from typing import Iterable | from typing import Iterable | ||||||
|  |  | ||||||
| import traci |  | ||||||
| from shapely.geometry.linestring import LineString | from shapely.geometry.linestring import LineString | ||||||
|  |  | ||||||
| from model import Area, Vehicle | from model import Area, Vehicle | ||||||
| from traci._trafficlight import Logic |  | ||||||
|  |  | ||||||
| def compute_edge_weight(edge_id): | def compute_edge_weight(edge_id): | ||||||
|     return (traci.edge.getCOEmission(edge_id) |     return (traci.edge.getCOEmission(edge_id) | ||||||
|   | |||||||
| @@ -2,15 +2,15 @@ | |||||||
| Global configuration for the simulation | Global configuration for the simulation | ||||||
| """ | """ | ||||||
|  |  | ||||||
| import os |  | ||||||
| import sys |  | ||||||
| import datetime | import datetime | ||||||
| import logging | import logging | ||||||
|  | import os | ||||||
|  | import sys | ||||||
|  |  | ||||||
|  |  | ||||||
| ############################################################################### | ############################################################################### | ||||||
| ############################# SIMULATION FILE ################################# | ############################# SIMULATION FILE ################################# | ||||||
| ############################################################################### | ############################################################################### | ||||||
|  |  | ||||||
| if 'SUMO_HOME' in os.environ: | if 'SUMO_HOME' in os.environ: | ||||||
|     tools = os.path.join(os.environ['SUMO_HOME'], 'tools') |     tools = os.path.join(os.environ['SUMO_HOME'], 'tools') | ||||||
|     sys.path.append(tools) |     sys.path.append(tools) | ||||||
| @@ -28,13 +28,13 @@ sumo_cmd = [sumo_binary, "-c", _SUMOCFG] | |||||||
|  |  | ||||||
| now = datetime.datetime.now() | now = datetime.datetime.now() | ||||||
| current_date = now.strftime("%Y_%m_%d_%H_%M_%S") | current_date = now.strftime("%Y_%m_%d_%H_%M_%S") | ||||||
| LOG_FILENAME = f'sumo_logs_{current_date}.log' | log_filename = f'sumo_logs_{current_date}.log' | ||||||
|  |  | ||||||
| # create logger | # create logger | ||||||
| logger = logging.getLogger("sumo_logger") | logger = logging.getLogger("sumo_logger") | ||||||
| logger.setLevel(logging.INFO) | logger.setLevel(logging.INFO) | ||||||
| # create console handler and set level to info | # create handler and set level to info | ||||||
| handler = logging.FileHandler(LOG_FILENAME) | handler = logging.FileHandler(log_filename) | ||||||
| # create formatter | # create formatter | ||||||
| formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") | formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") | ||||||
| # add formatter to handler | # add formatter to handler | ||||||
| @@ -46,9 +46,10 @@ logger.addHandler(handler) | |||||||
| ########################## SIMULATION CONFIGURATION ########################### | ########################## SIMULATION CONFIGURATION ########################### | ||||||
| ############################################################################### | ############################################################################### | ||||||
|  |  | ||||||
| CELLS_NUMBER = 10 | areas_number = 10 # Simulation boundary will be divided into areas_number x areas_number areas  | ||||||
| EMISSIONS_THRESHOLD = 500000 | emissions_threshold = 500000 | ||||||
| n_steps = 200  | n_steps = 200  | ||||||
|  | window_size = 100 | ||||||
|  |  | ||||||
| ############################################################################### | ############################################################################### | ||||||
| ########################## ACTIONS CONFIGURATION ############################## | ########################## ACTIONS CONFIGURATION ############################## | ||||||
| @@ -88,28 +89,27 @@ if without_actions_mode: | |||||||
| ############################################################################### | ############################################################################### | ||||||
|  |  | ||||||
| # Total of emissions of all pollutants in mg for n steps of simulation without locking areas | # Total of emissions of all pollutants in mg for n steps of simulation without locking areas | ||||||
| total_emissions200 = 43970763.15084749   | # These constants are simulation dependant, you must change them according to your simulation  | ||||||
| total_emissions300 = 87382632.08217141 | total_emissions100 = 13615949.148296086 | ||||||
| total_emissions400 = 140757491.8489904 | total_emissions200 = 43970763.15084738 | ||||||
| total_emissions500 = 202817535.43856794 | total_emissions300 = 87382632.0821697 | ||||||
|  |  | ||||||
| ############################################################################### | ############################################################################### | ||||||
| ########################## CONFIGURATION METHODS ############################## | ########################## CONFIGURATION METHODS ############################## | ||||||
| ############################################################################### | ############################################################################### | ||||||
|  |  | ||||||
| def get_basics_emissions(): | def get_basics_emissions(): | ||||||
|  |     if n_steps == 100: | ||||||
|  |         return total_emissions100 | ||||||
|     if n_steps == 200: |     if n_steps == 200: | ||||||
|         return total_emissions200 |         return total_emissions200 | ||||||
|     if n_steps == 300: |     if n_steps == 300: | ||||||
|         return total_emissions300 |         return total_emissions300 | ||||||
|     if n_steps == 400: |  | ||||||
|         return total_emissions400 |  | ||||||
|     if n_steps == 500: |  | ||||||
|         return total_emissions500 |  | ||||||
|  |  | ||||||
| def show_config(): | def show_config(): | ||||||
|     return (str(f'Grid : {CELLS_NUMBER}x{CELLS_NUMBER}\n') |     return (str(f'Grid : {areas_number}x{areas_number}\n') | ||||||
|     + str(f'step number = {n_steps}\n') |     + str(f'step number = {n_steps}\n') | ||||||
|  |     + str(f'window size = {window_size}\n') | ||||||
|     + str(f'weight routing mode = {weight_routing_mode}\n') |     + str(f'weight routing mode = {weight_routing_mode}\n') | ||||||
|     + str(f'lock area mode = {lock_area_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'limit speed mode = {limit_speed_mode}, RF = {speed_rf*100}%\n') | ||||||
|   | |||||||
| @@ -14,12 +14,15 @@ from traci import trafficlight | |||||||
|  |  | ||||||
| logger = config.logger | logger = config.logger | ||||||
|  |  | ||||||
| def init_grid(simulation_bounds, cells_number): | def init_grid(simulation_bounds, areas_number): | ||||||
|  |     """ | ||||||
|  |     Create all areas according to simulation bounds and the areas number choosen  | ||||||
|  |     """ | ||||||
|     grid = list() |     grid = list() | ||||||
|     width = simulation_bounds[1][0] / cells_number |     width = simulation_bounds[1][0] / areas_number | ||||||
|     height = simulation_bounds[1][1] / cells_number |     height = simulation_bounds[1][1] / areas_number | ||||||
|     for i in range(cells_number): |     for i in range(areas_number): | ||||||
|         for j in range(cells_number): |         for j in range(areas_number): | ||||||
|             # bounds coordinates for the area : (xmin, ymin, xmax, ymax) |             # bounds coordinates for the area : (xmin, ymin, xmax, ymax) | ||||||
|             ar_bounds = ((i * width, j * height), (i * width, (j + 1) * height), |             ar_bounds = ((i * width, j * height), (i * width, (j + 1) * height), | ||||||
|                          ((i + 1) * width, (j + 1) * height), ((i + 1) * width, j * height)) |                          ((i + 1) * width, (j + 1) * height), ((i + 1) * width, j * height)) | ||||||
| @@ -81,12 +84,16 @@ def get_all_vehicles() -> List[Vehicle]: | |||||||
|         vehicles.append(vehicle) |         vehicles.append(vehicle) | ||||||
|     return vehicles |     return vehicles | ||||||
|  |  | ||||||
| def get_emissions(grid: List[Area], vehicles: List[Vehicle]): | def get_emissions(grid: List[Area], vehicles: List[Vehicle], current_step): | ||||||
|     for area in grid: |     for area in grid: | ||||||
|  |         vehicle_emissions = 0 | ||||||
|         for vehicle in vehicles: |         for vehicle in vehicles: | ||||||
|             if vehicle.pos in area: |             if vehicle.pos in area: | ||||||
|                 area.emissions += vehicle.emissions |                 vehicle_emissions += vehicle.emissions | ||||||
|         if area.emissions > config.EMISSIONS_THRESHOLD:  |                  | ||||||
|  |         area.emissions_by_step.append(vehicle_emissions) | ||||||
|  |          | ||||||
|  |         if area.sum_emissions_by_step(current_step, config.window_size) > config.emissions_threshold:  | ||||||
|                  |                  | ||||||
|             if config.limit_speed_mode and not area.limited_speed: |             if config.limit_speed_mode and not area.limited_speed: | ||||||
|                 logger.info(f'Action - Decreased max speed into {area.name} by {config.speed_rf*100}%') |                 logger.info(f'Action - Decreased max speed into {area.name} by {config.speed_rf*100}%') | ||||||
| @@ -102,15 +109,16 @@ def get_emissions(grid: List[Area], vehicles: List[Vehicle]): | |||||||
|                     logger.info(f'Action - {area.name} blocked') |                     logger.info(f'Action - {area.name} blocked') | ||||||
|                     actions.lock_area(area) |                     actions.lock_area(area) | ||||||
|  |  | ||||||
|  |  | ||||||
| def main(): | def main(): | ||||||
|     grid = list() |     grid = list() | ||||||
|     try: |     try: | ||||||
|         traci.start(config.sumo_cmd) |         traci.start(config.sumo_cmd) | ||||||
|          |         logger.info(f'Loaded simulation file : {config._SUMOCFG}') | ||||||
|         logger.info('Loading data for the simulation') |         logger.info('Loading data for the simulation') | ||||||
|         start = time.perf_counter() |         start = time.perf_counter() | ||||||
|         |         | ||||||
|         grid = init_grid(traci.simulation.getNetBoundary(), config.CELLS_NUMBER) |         grid = init_grid(traci.simulation.getNetBoundary(), config.areas_number) | ||||||
|         add_data_to_areas(grid) |         add_data_to_areas(grid) | ||||||
|          |          | ||||||
|         loading_time = round(time.perf_counter() - start,2) |         loading_time = round(time.perf_counter() - start,2) | ||||||
| @@ -122,7 +130,7 @@ def main(): | |||||||
|             traci.simulationStep() |             traci.simulationStep() | ||||||
|  |  | ||||||
|             vehicles = get_all_vehicles() |             vehicles = get_all_vehicles() | ||||||
|             get_emissions(grid, vehicles) |             get_emissions(grid, vehicles,step) | ||||||
|  |  | ||||||
|             if config.weight_routing_mode: |             if config.weight_routing_mode: | ||||||
|                 logger.info('Action - Lane weights adjusted') |                 logger.info('Action - Lane weights adjusted') | ||||||
| @@ -137,12 +145,13 @@ def main(): | |||||||
|          |          | ||||||
|         total_emissions = 0 |         total_emissions = 0 | ||||||
|         for area in grid: |         for area in grid: | ||||||
|             total_emissions += area.emissions |             total_emissions += area.sum_all_emissions() | ||||||
|      |      | ||||||
|         logger.info(f'Total emissions = {total_emissions} mg') |         logger.info(f'Total emissions = {total_emissions} mg') | ||||||
|          |          | ||||||
|         if not config.without_actions_mode: |         if not config.without_actions_mode : | ||||||
|             ref = config.get_basics_emissions() |             ref = config.get_basics_emissions() | ||||||
|  |             if not (ref is None): | ||||||
|                 diff_with_actions = (ref - total_emissions)/ref     |                 diff_with_actions = (ref - total_emissions)/ref     | ||||||
|                 logger.info(f'Reduction percentage of emissions = {diff_with_actions*100} %') |                 logger.info(f'Reduction percentage of emissions = {diff_with_actions*100} %') | ||||||
|          |          | ||||||
|   | |||||||
| @@ -1,9 +1,9 @@ | |||||||
|  | from traci._trafficlight import Logic as SUMO_Logic | ||||||
| from typing import Tuple, Set | from typing import Tuple, Set | ||||||
|  |  | ||||||
| from shapely.geometry import Point, LineString | from shapely.geometry import Point, LineString | ||||||
| from shapely.geometry import Polygon | from shapely.geometry import Polygon | ||||||
| from shapely.geometry.base import BaseGeometry | from shapely.geometry.base import BaseGeometry | ||||||
| from traci._trafficlight import Logic as SUMO_Logic |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class Lane: | class Lane: | ||||||
| @@ -51,7 +51,7 @@ class Area: | |||||||
|         self.tls_adjusted = False |         self.tls_adjusted = False | ||||||
|         self.rectangle = Polygon(coords) |         self.rectangle = Polygon(coords) | ||||||
|         self.name = name |         self.name = name | ||||||
|         self.emissions = 0.0 |         self.emissions_by_step = []  | ||||||
|         self._lanes: Set[Lane] = set() |         self._lanes: Set[Lane] = set() | ||||||
|         self._tls: Set[TrafficLight] = set()  |         self._tls: Set[TrafficLight] = set()  | ||||||
|  |  | ||||||
| @@ -77,6 +77,19 @@ class Area: | |||||||
|     def remove_lane(self, lane: Lane): |     def remove_lane(self, lane: Lane): | ||||||
|         self._lanes.remove(lane) |         self._lanes.remove(lane) | ||||||
|          |          | ||||||
|  |     def sum_all_emissions(self): | ||||||
|  |         sum = 0  | ||||||
|  |         for emission in self.emissions_by_step: | ||||||
|  |             sum += emission | ||||||
|  |         return sum  | ||||||
|  |      | ||||||
|  |     def sum_emissions_by_step(self, current_step, window_size): | ||||||
|  |         sum = 0 | ||||||
|  |         q = current_step // window_size #Returns the integral part of the quotient | ||||||
|  |         for i in range(q*window_size, current_step): | ||||||
|  |             sum += self.emissions_by_step[i] | ||||||
|  |         return sum | ||||||
|  |  | ||||||
|     @classmethod |     @classmethod | ||||||
|     def from_bounds(cls, xmin, ymin, xmax, ymax): |     def from_bounds(cls, xmin, ymin, xmax, ymax): | ||||||
|         return cls(( |         return cls(( | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user