From 572812c5fe73e735ca371f8bb12d1ffe8a463eaa Mon Sep 17 00:00:00 2001 From: Ahp06 Date: Wed, 7 Nov 2018 11:23:32 +0100 Subject: [PATCH 01/15] Add sumo factory to interact with the simulation --- sumo_project/Area.py | 17 ++++++ sumo_project/EmissionGetter.py | 108 +++++++++++++++++---------------- sumo_project/SUMOFactory.py | 40 ++++++++++++ 3 files changed, 113 insertions(+), 52 deletions(-) create mode 100644 sumo_project/Area.py create mode 100644 sumo_project/SUMOFactory.py diff --git a/sumo_project/Area.py b/sumo_project/Area.py new file mode 100644 index 0000000..473c708 --- /dev/null +++ b/sumo_project/Area.py @@ -0,0 +1,17 @@ +''' +Created on 6 nov. 2018 + +@author: Admin +''' + +class Area: + + locked = False + + def __init__(self, coords): + self.coords = coords + + + def getCoords(self): + return self.coords + \ No newline at end of file diff --git a/sumo_project/EmissionGetter.py b/sumo_project/EmissionGetter.py index aac1aaf..271bb36 100644 --- a/sumo_project/EmissionGetter.py +++ b/sumo_project/EmissionGetter.py @@ -1,92 +1,96 @@ -''' -Created on 11 oct. 2018 - -@author: Axel HUYNH-PHUC -''' - import os, sys +from sumo_project.SUMOFactory import SUMOFactory + +# Traci launch +if 'SUMO_HOME' in os.environ: + tools = os.path.join(os.environ['SUMO_HOME'], 'tools') + sys.path.append(os.path.join(os.environ['SUMO_HOME'], tools)) + sumoBinary = os.path.join(os.environ['SUMO_HOME'], 'bin', 'sumo-gui') + sumoCmd = [sumoBinary, "-c", "mulhouse_simulation/osm.sumocfg"] +else: + sys.exit("please declare environment variable 'SUMO_HOME'") + import traci from traci import polygon -'''Launch traci''' -if 'SUMO_HOME' in os.environ: - tools = os.path.join(os.environ['SUMO_HOME'], 'tools') - sys.path.append(tools) -else: - sys.exit("please declare environment variable 'SUMO_HOME'") - -sumoBinary = "C:\\Users\\Admin\\AppData\\Roaming\\Microsoft\\Installer\\{A63B306E-2B15-11E1-88C8-028037EC0200}\\sumogui.exe" -sumoCmd = [sumoBinary, "-c", "mulhouse_simulation\\osm.sumocfg"] -traci.start(sumoCmd) -'''Variables and constants declaration''' -cells_step = 10 -boundary = traci.simulation.getNetBoundary() -areas = [[0] * cells_step for _ in range(cells_step)] -emissionsArea = [[0] * cells_step for _ in range(cells_step)] -width = boundary[1][0] / cells_step # width/step -height = boundary[1][1] / cells_step # height/step -CO2_threshold = 500000 - - -'''creating multiple zones of equal sizes''' +# creating multiple zones of equal sizes def init_grid(): - default_color = (0, 255, 0) + default_color = (0, 255, 0) for i in range(cells_step): for j in range(cells_step): area = ((i * width, j * height), (i * width, (j + 1) * height), ((i + 1) * width, (j + 1) * height), ((i + 1) * width, j * height)) areas[i][j] = area polygon.add("area " + str(i) + "," + str(j), area, default_color, False, "rectangle") - -'''Emissions recovery by area''' + +# Emissions recovery by area def getEmissionsByArea(i, j): vehicles = [] - '''Vehicle IDs retrieving into this area''' + + # Vehicle IDs retrieving into this area for veh_id in traci.vehicle.getIDList(): pos = traci.vehicle.getPosition(veh_id) - if((i * width < pos[0] and (i + 1) * width > pos[0]) + if((i * width < pos[0] and (i + 1) * width > pos[0]) and (j * height < pos[1] and (j + 1) * height > pos[1])): vehicles.append(veh_id) - - '''Sum all emissions''' + + # Sum all emissions emissions = 0.0 for veh_id in vehicles: emission = traci.vehicle.getCO2Emission(veh_id) - emissions += emission - - '''Change area color if emisssions exceeds the threshold''' + emissions += emission + + # Change area color if emisssions exceeds the threshold emissionsArea[i][j] += emissions if(emissionsArea[i][j] >= CO2_threshold): red = (255, 0, 0) + factory.lock_area(areas[i][j]) polygon.setColor("area " + str(i) + "," + str(j), red) polygon.setFilled("area " + str(i) + "," + str(j), True) -'''Recover emissions from all areas''' + +# Recover emissions from all areas def getAllEmissions(): for i in range(cells_step): for j in range(cells_step): getEmissionsByArea(i, j) -'''Display emissions information''' + +# Display emissions information def showEmissions(): for i in range(cells_step): for j in range(cells_step): print("Total CO2 emissions into Area " + str(i) + "," + str(j) - + " = " , str(emissionsArea[i][j]) + " mg" ) - + +" = " , str(emissionsArea[i][j]) + " mg") -'''Simulation launch''' -step = 0 -init_grid() -while step < 100: # while traci.simulation.getMinExpectedNumber() > 0: - traci.simulationStep() - getAllEmissions() - step += 1 -'''Display emissions information and close simulation''' -showEmissions() -traci.close() +if __name__ == "__main__": + # Simulation launch + traci.start(sumoCmd) + + # Variables and constants declaration + cells_step = 10 + boundary = traci.simulation.getNetBoundary() + areas = [[0] * cells_step for _ in range(cells_step)] + emissionsArea = [[0] * cells_step for _ in range(cells_step)] + width = boundary[1][0] / cells_step # width/step + height = boundary[1][1] / cells_step # height/step + CO2_threshold = 500000 + + step = 0 + init_grid() + factory = SUMOFactory() + + #factory.lock_area(areas[5][5]) + + while traci.simulation.getMinExpectedNumber() > 0: + traci.simulationStep() + getAllEmissions() + step += 1 + + # Display emissions information and close simulation + showEmissions() + traci.close() sys.stdout.flush() - diff --git a/sumo_project/SUMOFactory.py b/sumo_project/SUMOFactory.py new file mode 100644 index 0000000..9d2efd7 --- /dev/null +++ b/sumo_project/SUMOFactory.py @@ -0,0 +1,40 @@ +''' +Created on 17 oct. 2018 + +@author: Admin +''' +import os, sys +import traci +from shapely.geometry import Polygon +from shapely.geometry import Point +from shapely.geometry.linestring import LineString + + +class SUMOFactory(object): + + def __init__(self): + '''Constructor''' + + def stopVehicle(self, veh_id): + traci.vehicle.remove(veh_id, traci.constants.REMOVE_PARKING) + + def getLanesIntoArea(self, area): + polygon_area = Polygon(area) + lanes = [] + for lane_id in traci.lane.getIDList(): + polygon_lane = LineString(traci.lane.getShape(lane_id)) + if polygon_area.intersects(polygon_lane): + print("lane is in area : ", polygon_lane) + lanes.append(lane_id) + return lanes + + def lock_area(self, area): + lanes = self.getLanesIntoArea(area) + for lane_id in lanes: + '''print("Vehicles number into lane = ", traci.lane.getLastStepVehicleNumber(lane_id)) + if traci.lane.getLastStepVehicleNumber(lane_id) == 0: + traci.lane.setDisallowed(lane_id, "passenger") + print("lane blocked : ", lane_id)''' + traci.lane.setMaxSpeed(lane_id, 30) + for veh_id in traci.vehicle.getIDList(): + traci.vehicle.rerouteTraveltime(veh_id, True) From 5a79858d04dfa81b90279c622241b90fb835b575 Mon Sep 17 00:00:00 2001 From: Thibaud Date: Wed, 14 Nov 2018 14:40:05 +0100 Subject: [PATCH 02/15] Add area data model --- sumo_project/Area.py | 17 ------ sumo_project/EmissionGetter.py | 96 ---------------------------------- sumo_project/area.py | 28 ++++++++++ 3 files changed, 28 insertions(+), 113 deletions(-) delete mode 100644 sumo_project/Area.py delete mode 100644 sumo_project/EmissionGetter.py create mode 100644 sumo_project/area.py diff --git a/sumo_project/Area.py b/sumo_project/Area.py deleted file mode 100644 index 473c708..0000000 --- a/sumo_project/Area.py +++ /dev/null @@ -1,17 +0,0 @@ -''' -Created on 6 nov. 2018 - -@author: Admin -''' - -class Area: - - locked = False - - def __init__(self, coords): - self.coords = coords - - - def getCoords(self): - return self.coords - \ No newline at end of file diff --git a/sumo_project/EmissionGetter.py b/sumo_project/EmissionGetter.py deleted file mode 100644 index 271bb36..0000000 --- a/sumo_project/EmissionGetter.py +++ /dev/null @@ -1,96 +0,0 @@ -import os, sys -from sumo_project.SUMOFactory import SUMOFactory - -# Traci launch -if 'SUMO_HOME' in os.environ: - tools = os.path.join(os.environ['SUMO_HOME'], 'tools') - sys.path.append(os.path.join(os.environ['SUMO_HOME'], tools)) - sumoBinary = os.path.join(os.environ['SUMO_HOME'], 'bin', 'sumo-gui') - sumoCmd = [sumoBinary, "-c", "mulhouse_simulation/osm.sumocfg"] -else: - sys.exit("please declare environment variable 'SUMO_HOME'") - -import traci -from traci import polygon - - -# creating multiple zones of equal sizes -def init_grid(): - default_color = (0, 255, 0) - for i in range(cells_step): - for j in range(cells_step): - area = ((i * width, j * height), (i * width, (j + 1) * height), - ((i + 1) * width, (j + 1) * height), ((i + 1) * width, j * height)) - areas[i][j] = area - polygon.add("area " + str(i) + "," + str(j), area, default_color, False, "rectangle") - - -# Emissions recovery by area -def getEmissionsByArea(i, j): - vehicles = [] - - # Vehicle IDs retrieving into this area - for veh_id in traci.vehicle.getIDList(): - pos = traci.vehicle.getPosition(veh_id) - if((i * width < pos[0] and (i + 1) * width > pos[0]) - and (j * height < pos[1] and (j + 1) * height > pos[1])): - vehicles.append(veh_id) - - # Sum all emissions - emissions = 0.0 - for veh_id in vehicles: - emission = traci.vehicle.getCO2Emission(veh_id) - emissions += emission - - # Change area color if emisssions exceeds the threshold - emissionsArea[i][j] += emissions - if(emissionsArea[i][j] >= CO2_threshold): - red = (255, 0, 0) - factory.lock_area(areas[i][j]) - polygon.setColor("area " + str(i) + "," + str(j), red) - polygon.setFilled("area " + str(i) + "," + str(j), True) - - -# Recover emissions from all areas -def getAllEmissions(): - for i in range(cells_step): - for j in range(cells_step): - getEmissionsByArea(i, j) - - -# Display emissions information -def showEmissions(): - for i in range(cells_step): - for j in range(cells_step): - print("Total CO2 emissions into Area " + str(i) + "," + str(j) - +" = " , str(emissionsArea[i][j]) + " mg") - - -if __name__ == "__main__": - # Simulation launch - traci.start(sumoCmd) - - # Variables and constants declaration - cells_step = 10 - boundary = traci.simulation.getNetBoundary() - areas = [[0] * cells_step for _ in range(cells_step)] - emissionsArea = [[0] * cells_step for _ in range(cells_step)] - width = boundary[1][0] / cells_step # width/step - height = boundary[1][1] / cells_step # height/step - CO2_threshold = 500000 - - step = 0 - init_grid() - factory = SUMOFactory() - - #factory.lock_area(areas[5][5]) - - while traci.simulation.getMinExpectedNumber() > 0: - traci.simulationStep() - getAllEmissions() - step += 1 - - # Display emissions information and close simulation - showEmissions() - traci.close() -sys.stdout.flush() diff --git a/sumo_project/area.py b/sumo_project/area.py new file mode 100644 index 0000000..7f41202 --- /dev/null +++ b/sumo_project/area.py @@ -0,0 +1,28 @@ +from shapely.geometry import Polygon +from shapely.geometry import Point + + +class Area: + + def __init__(self, coords, name=''): + self.rectangle = Polygon(coords) + self.name = name + self.emissions = 0.0 + + def __eq__(self, other): + return self.rectangle.__eq__(other) + + @property + def bounds(self): + return self.rectangle.bounds + + def contains(self, other): + return self.rectangle.contains(Point(other)) + + @classmethod + def from_bounds(cls, xmin, ymin, xmax, ymax): + return cls(( + (xmin, ymin), + (xmin, ymax), + (xmax, ymax), + (xmax, ymin))) From 6c36eafe09df8a03da5fb4abe1ac402948b19537 Mon Sep 17 00:00:00 2001 From: Thibaud Date: Wed, 14 Nov 2018 14:40:55 +0100 Subject: [PATCH 03/15] Update existing code to use the new area data model --- sumo_project/SUMOFactory.py | 39 ++++++++------------- sumo_project/emissions.py | 68 +++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 25 deletions(-) create mode 100644 sumo_project/emissions.py diff --git a/sumo_project/SUMOFactory.py b/sumo_project/SUMOFactory.py index 9d2efd7..4037fb0 100644 --- a/sumo_project/SUMOFactory.py +++ b/sumo_project/SUMOFactory.py @@ -1,40 +1,29 @@ ''' Created on 17 oct. 2018 -@author: Admin +@author: Axel Huynh-Phuc, Thibaud Gasser ''' -import os, sys -import traci -from shapely.geometry import Polygon -from shapely.geometry import Point + +import traci from shapely.geometry.linestring import LineString class SUMOFactory(object): - def __init__(self): - '''Constructor''' - - def stopVehicle(self, veh_id): + def stop_vehicle(self, veh_id): traci.vehicle.remove(veh_id, traci.constants.REMOVE_PARKING) - - def getLanesIntoArea(self, area): - polygon_area = Polygon(area) - lanes = [] + + def lanes_in_area(self, area): + polygon_area = area.rectangle for lane_id in traci.lane.getIDList(): polygon_lane = LineString(traci.lane.getShape(lane_id)) if polygon_area.intersects(polygon_lane): - print("lane is in area : ", polygon_lane) - lanes.append(lane_id) - return lanes + yield lane_id def lock_area(self, area): - lanes = self.getLanesIntoArea(area) - for lane_id in lanes: - '''print("Vehicles number into lane = ", traci.lane.getLastStepVehicleNumber(lane_id)) - if traci.lane.getLastStepVehicleNumber(lane_id) == 0: - traci.lane.setDisallowed(lane_id, "passenger") - print("lane blocked : ", lane_id)''' - traci.lane.setMaxSpeed(lane_id, 30) - for veh_id in traci.vehicle.getIDList(): - traci.vehicle.rerouteTraveltime(veh_id, True) + for lane_id in self.lanes_in_area(area): + print(f'Setting max speed of {lane_id} to 30.') + traci.lane.setMaxSpeed(lane_id, 30) + + for veh_id in traci.vehicle.getIDList(): + traci.vehicle.rerouteTraveltime(veh_id, True) diff --git a/sumo_project/emissions.py b/sumo_project/emissions.py new file mode 100644 index 0000000..e76ac22 --- /dev/null +++ b/sumo_project/emissions.py @@ -0,0 +1,68 @@ +import os +import sys + +from SUMOFactory import SUMOFactory + +if 'SUMO_HOME' in os.environ: + tools = os.path.join(os.environ['SUMO_HOME'], 'tools') + sys.path.append(tools) +else: + sys.exit("please declare environment variable 'SUMO_HOME'") + +import traci +from area import Area + +sumoBinary = os.path.join(os.environ['SUMO_HOME'], 'bin', 'sumo-gui') +sumoCmd = [sumoBinary, "-c", "mulhouse_simulation/map.sumocfg"] +CELLS_NUMBER = 10 +CO2_THRESHOLD = 500000 + + +def init_grid(simulation_bounds, cells_number): + width = simulation_bounds[1][0] / cells_number + height = simulation_bounds[1][1] / cells_number + # TODO: change data structure? + areas = list() + for i in range(cells_number): + for j in range(cells_number): + # bounds coordinates for the area : (xmin, ymin, xmax, ymax) + 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) + areas.append(area) + traci.polygon.add(area.name, ar_bounds, (0, 255, 0)) + return areas + + +def emission_for_area(area): + # retrieve all vehicles into this area + for veh_id in traci.vehicle.getIDList(): + pos = traci.vehicle.getPosition(veh_id) + if area.contains(pos): + area.emissions += traci.vehicle.getCO2Emission(veh_id) + + +def get_emissions(areas, factory): + for area in areas: + emission_for_area(area) + if area.emissions > CO2_THRESHOLD: + # print(f'Threshold exceeded in {area.name} : {area.emissions}') + factory.lock_area(area) + traci.polygon.setColor(area.name, (255, 0, 0)) + traci.polygon.setFilled(area.name, True) + + +def main(): + try: + traci.start(sumoCmd) + grid = init_grid(traci.simulation.getNetBoundary(), CELLS_NUMBER) + while traci.simulation.getMinExpectedNumber() > 0: + traci.simulationStep() + get_emissions(grid, SUMOFactory()) + finally: + traci.close(False) + + +if __name__ == '__main__': + main() From 7cbc1d85a0c56e8905c56be516dc41499e9ecdaf Mon Sep 17 00:00:00 2001 From: Thibaud Date: Wed, 14 Nov 2018 14:56:54 +0100 Subject: [PATCH 04/15] Externalize configuration in config.py --- sumo_project/config.py | 22 ++++++++++++++++++++++ sumo_project/emissions.py | 23 +++++------------------ 2 files changed, 27 insertions(+), 18 deletions(-) create mode 100644 sumo_project/config.py diff --git a/sumo_project/config.py b/sumo_project/config.py new file mode 100644 index 0000000..4b04b14 --- /dev/null +++ b/sumo_project/config.py @@ -0,0 +1,22 @@ +""" +Global configuration for the simulation +""" + +import os +import sys + +if 'SUMO_HOME' in os.environ: + tools = os.path.join(os.environ['SUMO_HOME'], 'tools') + sys.path.append(tools) +else: + sys.exit("please declare environment variable 'SUMO_HOME'") + +_SUMOCMD = 'sumo-gui' +_SUMOCFG = "mulhouse_simulation/map.sumocfg" +CELLS_NUMBER = 10 +CO2_THRESHOLD = 500000 + +sumo_binary = os.path.join(os.environ['SUMO_HOME'], 'bin', _SUMOCMD) +sumo_cmd = [sumo_binary, "-c", _SUMOCFG] + + diff --git a/sumo_project/emissions.py b/sumo_project/emissions.py index e76ac22..7766ade 100644 --- a/sumo_project/emissions.py +++ b/sumo_project/emissions.py @@ -1,22 +1,9 @@ -import os -import sys +import traci +import config from SUMOFactory import SUMOFactory - -if 'SUMO_HOME' in os.environ: - tools = os.path.join(os.environ['SUMO_HOME'], 'tools') - sys.path.append(tools) -else: - sys.exit("please declare environment variable 'SUMO_HOME'") - -import traci from area import Area -sumoBinary = os.path.join(os.environ['SUMO_HOME'], 'bin', 'sumo-gui') -sumoCmd = [sumoBinary, "-c", "mulhouse_simulation/map.sumocfg"] -CELLS_NUMBER = 10 -CO2_THRESHOLD = 500000 - def init_grid(simulation_bounds, cells_number): width = simulation_bounds[1][0] / cells_number @@ -46,7 +33,7 @@ def emission_for_area(area): def get_emissions(areas, factory): for area in areas: emission_for_area(area) - if area.emissions > CO2_THRESHOLD: + if area.emissions > config.CO2_THRESHOLD: # print(f'Threshold exceeded in {area.name} : {area.emissions}') factory.lock_area(area) traci.polygon.setColor(area.name, (255, 0, 0)) @@ -55,8 +42,8 @@ def get_emissions(areas, factory): def main(): try: - traci.start(sumoCmd) - grid = init_grid(traci.simulation.getNetBoundary(), CELLS_NUMBER) + traci.start(config.sumo_cmd) + grid = init_grid(traci.simulation.getNetBoundary(), config.CELLS_NUMBER) while traci.simulation.getMinExpectedNumber() > 0: traci.simulationStep() get_emissions(grid, SUMOFactory()) From 0d4961bd091a17b6ef28e913c17a26ed3a70237a Mon Sep 17 00:00:00 2001 From: Thibaud Date: Wed, 14 Nov 2018 15:02:52 +0100 Subject: [PATCH 05/15] Fix sumo config name --- sumo_project/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sumo_project/config.py b/sumo_project/config.py index 4b04b14..c93397d 100644 --- a/sumo_project/config.py +++ b/sumo_project/config.py @@ -12,7 +12,7 @@ else: sys.exit("please declare environment variable 'SUMO_HOME'") _SUMOCMD = 'sumo-gui' -_SUMOCFG = "mulhouse_simulation/map.sumocfg" +_SUMOCFG = "mulhouse_simulation/osm.sumocfg" CELLS_NUMBER = 10 CO2_THRESHOLD = 500000 From 938e64b1f4a3f2c72814377b824098bbeeea366d Mon Sep 17 00:00:00 2001 From: Thibaud Date: Fri, 16 Nov 2018 16:39:01 +0100 Subject: [PATCH 06/15] Fix lock_area with correct speed value (9 m/s) --- sumo_project/SUMOFactory.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sumo_project/SUMOFactory.py b/sumo_project/SUMOFactory.py index 4037fb0..8f529db 100644 --- a/sumo_project/SUMOFactory.py +++ b/sumo_project/SUMOFactory.py @@ -22,8 +22,8 @@ class SUMOFactory(object): def lock_area(self, area): for lane_id in self.lanes_in_area(area): - print(f'Setting max speed of {lane_id} to 30.') - traci.lane.setMaxSpeed(lane_id, 30) + print(f'Setting max speed of {lane_id} to 9.') + traci.lane.setMaxSpeed(lane_id, 9) for veh_id in traci.vehicle.getIDList(): traci.vehicle.rerouteTraveltime(veh_id, True) From 8d51343e0c13da51f6d971d4f99e3d5e2029dd53 Mon Sep 17 00:00:00 2001 From: Thibaud Date: Thu, 15 Nov 2018 12:23:56 +0100 Subject: [PATCH 07/15] Rename area.py to model.py --- sumo_project/emissions.py | 2 +- sumo_project/{area.py => model.py} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename sumo_project/{area.py => model.py} (100%) diff --git a/sumo_project/emissions.py b/sumo_project/emissions.py index 7766ade..17b42c0 100644 --- a/sumo_project/emissions.py +++ b/sumo_project/emissions.py @@ -2,7 +2,7 @@ import traci import config from SUMOFactory import SUMOFactory -from area import Area +from model import Area def init_grid(simulation_bounds, cells_number): diff --git a/sumo_project/area.py b/sumo_project/model.py similarity index 100% rename from sumo_project/area.py rename to sumo_project/model.py From 779539ee697e1e182420492a2a23f3564943c287 Mon Sep 17 00:00:00 2001 From: Thibaud Date: Thu, 15 Nov 2018 12:20:19 +0100 Subject: [PATCH 08/15] Use __contains__ method to check vehicules in area --- sumo_project/SUMOFactory.py | 3 +-- sumo_project/area.py | 6 +++--- sumo_project/emissions.py | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/sumo_project/SUMOFactory.py b/sumo_project/SUMOFactory.py index 8f529db..80c9444 100644 --- a/sumo_project/SUMOFactory.py +++ b/sumo_project/SUMOFactory.py @@ -14,10 +14,9 @@ class SUMOFactory(object): traci.vehicle.remove(veh_id, traci.constants.REMOVE_PARKING) def lanes_in_area(self, area): - polygon_area = area.rectangle for lane_id in traci.lane.getIDList(): polygon_lane = LineString(traci.lane.getShape(lane_id)) - if polygon_area.intersects(polygon_lane): + if area.rectangle.intersects(polygon_lane): yield lane_id def lock_area(self, area): diff --git a/sumo_project/area.py b/sumo_project/area.py index 7f41202..b552aee 100644 --- a/sumo_project/area.py +++ b/sumo_project/area.py @@ -12,13 +12,13 @@ class Area: def __eq__(self, other): return self.rectangle.__eq__(other) + def __contains__(self, item): + return self.rectangle.contains(Point(item)) + @property def bounds(self): return self.rectangle.bounds - def contains(self, other): - return self.rectangle.contains(Point(other)) - @classmethod def from_bounds(cls, xmin, ymin, xmax, ymax): return cls(( diff --git a/sumo_project/emissions.py b/sumo_project/emissions.py index 7766ade..276dbb8 100644 --- a/sumo_project/emissions.py +++ b/sumo_project/emissions.py @@ -26,7 +26,7 @@ def emission_for_area(area): # retrieve all vehicles into this area for veh_id in traci.vehicle.getIDList(): pos = traci.vehicle.getPosition(veh_id) - if area.contains(pos): + if pos in area: area.emissions += traci.vehicle.getCO2Emission(veh_id) From 9600dee7e5d704d9fd14ef7878ec81e9cf4cf70b Mon Sep 17 00:00:00 2001 From: Thibaud Date: Thu, 15 Nov 2018 13:44:15 +0100 Subject: [PATCH 09/15] Chache vehicle information locally at each step --- sumo_project/emissions.py | 35 +++++++++++++++++++++-------------- sumo_project/model.py | 16 ++++++++++++++-- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/sumo_project/emissions.py b/sumo_project/emissions.py index 390c280..0ecbfe2 100644 --- a/sumo_project/emissions.py +++ b/sumo_project/emissions.py @@ -1,8 +1,9 @@ -import traci -import config +from typing import List -from SUMOFactory import SUMOFactory -from model import Area +import traci + +import config +from model import Area, Vehicle def init_grid(simulation_bounds, cells_number): @@ -22,20 +23,24 @@ def init_grid(simulation_bounds, cells_number): return areas -def emission_for_area(area): - # retrieve all vehicles into this area +def get_all_vehicles() -> List[Vehicle]: + vehicles = list() for veh_id in traci.vehicle.getIDList(): - pos = traci.vehicle.getPosition(veh_id) - if pos in area: - area.emissions += traci.vehicle.getCO2Emission(veh_id) + veh_pos = traci.vehicle.getPosition(veh_id) + vehicle = Vehicle(veh_id, veh_pos) + vehicle.co2 = traci.vehicle.getCO2Emission(vehicle.id) + vehicles.append(vehicle) + return vehicles -def get_emissions(areas, factory): - for area in areas: - emission_for_area(area) +def get_emissions(grid: List[Area], vehicles: List[Vehicle]): + for area in grid: + for vehicle in vehicles: + if vehicle.pos in area: + area.emissions += vehicle.co2 if area.emissions > config.CO2_THRESHOLD: # print(f'Threshold exceeded in {area.name} : {area.emissions}') - factory.lock_area(area) + # factory.lock_area(area) traci.polygon.setColor(area.name, (255, 0, 0)) traci.polygon.setFilled(area.name, True) @@ -46,7 +51,9 @@ def main(): grid = init_grid(traci.simulation.getNetBoundary(), config.CELLS_NUMBER) while traci.simulation.getMinExpectedNumber() > 0: traci.simulationStep() - get_emissions(grid, SUMOFactory()) + # get_emissions(grid, SUMOFactory()) + vehicles = get_all_vehicles() + get_emissions(grid, vehicles) finally: traci.close(False) diff --git a/sumo_project/model.py b/sumo_project/model.py index b552aee..541e3c1 100644 --- a/sumo_project/model.py +++ b/sumo_project/model.py @@ -1,5 +1,7 @@ -from shapely.geometry import Polygon +from typing import Tuple + from shapely.geometry import Point +from shapely.geometry import Polygon class Area: @@ -13,7 +15,7 @@ class Area: return self.rectangle.__eq__(other) def __contains__(self, item): - return self.rectangle.contains(Point(item)) + return self.rectangle.contains(item) @property def bounds(self): @@ -26,3 +28,13 @@ class Area: (xmin, ymax), (xmax, ymax), (xmax, ymin))) + + +class Vehicle: + + def __init__(self, id: int, pos: Tuple[float, float]): + self.id = id + self.pos = Point(pos) + + def __repr__(self) -> str: + return str(self.__dict__) From b33d3b750ace0aae79953f269e4a12bba032a083 Mon Sep 17 00:00:00 2001 From: Thibaud Date: Thu, 15 Nov 2018 13:51:46 +0100 Subject: [PATCH 10/15] Delete SUMOFactory class --- sumo_project/SUMOFactory.py | 56 ++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/sumo_project/SUMOFactory.py b/sumo_project/SUMOFactory.py index 80c9444..2f80bfc 100644 --- a/sumo_project/SUMOFactory.py +++ b/sumo_project/SUMOFactory.py @@ -1,28 +1,28 @@ -''' -Created on 17 oct. 2018 - -@author: Axel Huynh-Phuc, Thibaud Gasser -''' - -import traci -from shapely.geometry.linestring import LineString - - -class SUMOFactory(object): - - def stop_vehicle(self, veh_id): - traci.vehicle.remove(veh_id, traci.constants.REMOVE_PARKING) - - def lanes_in_area(self, area): - for lane_id in traci.lane.getIDList(): - polygon_lane = LineString(traci.lane.getShape(lane_id)) - if area.rectangle.intersects(polygon_lane): - yield lane_id - - def lock_area(self, area): - for lane_id in self.lanes_in_area(area): - print(f'Setting max speed of {lane_id} to 9.') - traci.lane.setMaxSpeed(lane_id, 9) - - for veh_id in traci.vehicle.getIDList(): - traci.vehicle.rerouteTraveltime(veh_id, True) +''' +Created on 17 oct. 2018 + +@author: Axel Huynh-Phuc, Thibaud Gasser +''' + +import traci +from shapely.geometry.linestring import LineString + + +def stop_vehicle(veh_id): + traci.vehicle.remove(veh_id, traci.constants.REMOVE_PARKING) + + +def lanes_in_area(area): + for lane_id in traci.lane.getIDList(): + polygon_lane = LineString(traci.lane.getShape(lane_id)) + if area.rectangle.intersects(polygon_lane): + yield lane_id + + +def lock_area(area): + for lane_id in lanes_in_area(area): + print(f'Setting max speed of {lane_id} to 30.') + traci.lane.setMaxSpeed(lane_id, 30) + + for veh_id in traci.vehicle.getIDList(): + traci.vehicle.rerouteTraveltime(veh_id, True) From 1cf12fec81cd7236f5070602b947c5b0a499bba0 Mon Sep 17 00:00:00 2001 From: Thibaud Date: Thu, 15 Nov 2018 13:52:11 +0100 Subject: [PATCH 11/15] Rename SUMOFactory.py to actions.py --- sumo_project/{SUMOFactory.py => actions.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename sumo_project/{SUMOFactory.py => actions.py} (100%) diff --git a/sumo_project/SUMOFactory.py b/sumo_project/actions.py similarity index 100% rename from sumo_project/SUMOFactory.py rename to sumo_project/actions.py From e058f0692827bc50836a60280d044d2a1967eb51 Mon Sep 17 00:00:00 2001 From: Thibaud Date: Thu, 15 Nov 2018 22:15:43 +0100 Subject: [PATCH 12/15] Improve speed of the actions --- sumo_project/actions.py | 21 ++++++++++++--------- sumo_project/emissions.py | 28 +++++++++++++++++++++++----- sumo_project/model.py | 32 ++++++++++++++++++++++++++++---- 3 files changed, 63 insertions(+), 18 deletions(-) diff --git a/sumo_project/actions.py b/sumo_project/actions.py index 2f80bfc..b2e9001 100644 --- a/sumo_project/actions.py +++ b/sumo_project/actions.py @@ -1,12 +1,15 @@ -''' +""" Created on 17 oct. 2018 @author: Axel Huynh-Phuc, Thibaud Gasser -''' +""" +from typing import Iterable import traci from shapely.geometry.linestring import LineString +from model import Area, Vehicle + def stop_vehicle(veh_id): traci.vehicle.remove(veh_id, traci.constants.REMOVE_PARKING) @@ -19,10 +22,10 @@ def lanes_in_area(area): yield lane_id -def lock_area(area): - for lane_id in lanes_in_area(area): - print(f'Setting max speed of {lane_id} to 30.') - traci.lane.setMaxSpeed(lane_id, 30) - - for veh_id in traci.vehicle.getIDList(): - traci.vehicle.rerouteTraveltime(veh_id, True) +def lock_area(area: Area, vehicles: Iterable[Vehicle]): + for lane in area._lanes: + print(f'Setting max speed of {lane.lane_id} to 30.') + traci.lane.setMaxSpeed(lane.lane_id, 30) + area.locked = True + for vehicle in vehicles: + traci.vehicle.rerouteTraveltime(vehicle.veh_id, True) diff --git a/sumo_project/emissions.py b/sumo_project/emissions.py index 0ecbfe2..bfdb484 100644 --- a/sumo_project/emissions.py +++ b/sumo_project/emissions.py @@ -1,15 +1,16 @@ from typing import List import traci +from shapely.geometry import LineString +import actions import config -from model import Area, Vehicle +from model import Area, Vehicle, Lane def init_grid(simulation_bounds, cells_number): width = simulation_bounds[1][0] / cells_number height = simulation_bounds[1][1] / cells_number - # TODO: change data structure? areas = list() for i in range(cells_number): for j in range(cells_number): @@ -28,11 +29,19 @@ def get_all_vehicles() -> List[Vehicle]: for veh_id in traci.vehicle.getIDList(): veh_pos = traci.vehicle.getPosition(veh_id) vehicle = Vehicle(veh_id, veh_pos) - vehicle.co2 = traci.vehicle.getCO2Emission(vehicle.id) + vehicle.co2 = traci.vehicle.getCO2Emission(vehicle.veh_id) 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)) + lanes.append(Lane(lane_id, polygon_lane)) + return lanes + + def get_emissions(grid: List[Area], vehicles: List[Vehicle]): for area in grid: for vehicle in vehicles: @@ -40,18 +49,27 @@ def get_emissions(grid: List[Area], vehicles: List[Vehicle]): area.emissions += vehicle.co2 if area.emissions > config.CO2_THRESHOLD: # print(f'Threshold exceeded in {area.name} : {area.emissions}') - # factory.lock_area(area) + if not area.locked: + actions.lock_area(area, vehicles) traci.polygon.setColor(area.name, (255, 0, 0)) traci.polygon.setFilled(area.name, True) +def add_lanes_to_areas(areas: List[Area]): + lanes = get_all_lanes() + for area in areas: + for lane in lanes: + if area.rectangle.intersects(lane.polygon): + area.add_lane(lane) + + def main(): try: traci.start(config.sumo_cmd) grid = init_grid(traci.simulation.getNetBoundary(), config.CELLS_NUMBER) + add_lanes_to_areas(grid) while traci.simulation.getMinExpectedNumber() > 0: traci.simulationStep() - # get_emissions(grid, SUMOFactory()) vehicles = get_all_vehicles() get_emissions(grid, vehicles) finally: diff --git a/sumo_project/model.py b/sumo_project/model.py index 541e3c1..5f6e69d 100644 --- a/sumo_project/model.py +++ b/sumo_project/model.py @@ -1,15 +1,29 @@ -from typing import Tuple +from typing import Tuple, Set -from shapely.geometry import Point +from shapely.geometry import Point, LineString from shapely.geometry import Polygon +from shapely.geometry.base import BaseGeometry + + +class Lane: + + def __init__(self, lane_id: str, polygon: LineString): + self.polygon = polygon + self.lane_id = lane_id + + def __hash__(self): + """Overrides the default implementation""" + return hash(self.lane_id) class Area: def __init__(self, coords, name=''): + self.locked = False self.rectangle = Polygon(coords) self.name = name self.emissions = 0.0 + self._lanes: Set[Lane] = set() def __eq__(self, other): return self.rectangle.__eq__(other) @@ -21,6 +35,15 @@ class Area: def bounds(self): return self.rectangle.bounds + def intersects(self, other: BaseGeometry) -> bool: + return self.rectangle.intersects(other) + + def add_lane(self, lane: Lane): + self._lanes.add(lane) + + def remove_lane(self, lane: Lane): + self._lanes.remove(lane) + @classmethod def from_bounds(cls, xmin, ymin, xmax, ymax): return cls(( @@ -32,8 +55,9 @@ class Area: class Vehicle: - def __init__(self, id: int, pos: Tuple[float, float]): - self.id = id + def __init__(self, veh_id: int, pos: Tuple[float, float]): + self.co2: float = None + self.veh_id = veh_id self.pos = Point(pos) def __repr__(self) -> str: From 77d196d6c30f775100226dd3e918d5ddef0b5f79 Mon Sep 17 00:00:00 2001 From: Ahp06 Date: Mon, 19 Nov 2018 16:28:29 +0100 Subject: [PATCH 13/15] Fixed a bug about grid initialization --- sumo_project/actions.py | 25 ++++++++++++++++++------- sumo_project/config.py | 3 ++- sumo_project/emissions.py | 34 +++++++++++++++++++++++++++------- 3 files changed, 47 insertions(+), 15 deletions(-) diff --git a/sumo_project/actions.py b/sumo_project/actions.py index b2e9001..b115fc9 100644 --- a/sumo_project/actions.py +++ b/sumo_project/actions.py @@ -11,21 +11,32 @@ from shapely.geometry.linestring import LineString from model import Area, Vehicle -def stop_vehicle(veh_id): +def remove_vehicle(veh_id): traci.vehicle.remove(veh_id, traci.constants.REMOVE_PARKING) - def lanes_in_area(area): for lane_id in traci.lane.getIDList(): polygon_lane = LineString(traci.lane.getShape(lane_id)) if area.rectangle.intersects(polygon_lane): yield lane_id +def computeEdgeWeight(edge_id): + return traci.edge.getCO2Emission(edge_id) + +#Useless because vehicles reroute automatically by travelTime +def rerouteVehicles(): + for veh_id in traci.vehicle.getIDList(): + traci.vehicle.rerouteTraveltime(veh_id,True) + +def adjustEdgesWeight(): + for edge_id in traci.edge.getIDList(): + weight = computeEdgeWeight(edge_id) #by default edges weight = length/mean speed + traci.edge.adaptTraveltime(edge_id, weight) def lock_area(area: Area, vehicles: Iterable[Vehicle]): - for lane in area._lanes: - print(f'Setting max speed of {lane.lane_id} to 30.') - traci.lane.setMaxSpeed(lane.lane_id, 30) + max_speed = 30 + print(f' Setting max speed into {area.name} to {max_speed} km/h') area.locked = True - for vehicle in vehicles: - traci.vehicle.rerouteTraveltime(vehicle.veh_id, True) + for lane in area._lanes: + traci.lane.setMaxSpeed(lane.lane_id, max_speed/3.6) + diff --git a/sumo_project/config.py b/sumo_project/config.py index c93397d..e71e19a 100644 --- a/sumo_project/config.py +++ b/sumo_project/config.py @@ -11,10 +11,11 @@ if 'SUMO_HOME' in os.environ: else: sys.exit("please declare environment variable 'SUMO_HOME'") -_SUMOCMD = 'sumo-gui' +_SUMOCMD = 'sumo' # use 'sumo-gui' cmd for UI _SUMOCFG = "mulhouse_simulation/osm.sumocfg" CELLS_NUMBER = 10 CO2_THRESHOLD = 500000 +n_steps = 400 sumo_binary = os.path.join(os.environ['SUMO_HOME'], 'bin', _SUMOCMD) sumo_cmd = [sumo_binary, "-c", _SUMOCFG] diff --git a/sumo_project/emissions.py b/sumo_project/emissions.py index bfdb484..80b0724 100644 --- a/sumo_project/emissions.py +++ b/sumo_project/emissions.py @@ -5,20 +5,21 @@ from shapely.geometry import LineString import actions import config +import sys from model import Area, Vehicle, Lane +areas = list() def init_grid(simulation_bounds, cells_number): width = simulation_bounds[1][0] / cells_number height = simulation_bounds[1][1] / cells_number - areas = list() for i in range(cells_number): for j in range(cells_number): # bounds coordinates for the area : (xmin, ymin, xmax, ymax) 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) areas.append(area) traci.polygon.add(area.name, ar_bounds, (0, 255, 0)) return areas @@ -47,10 +48,8 @@ def get_emissions(grid: List[Area], vehicles: List[Vehicle]): for vehicle in vehicles: if vehicle.pos in area: area.emissions += vehicle.co2 - if area.emissions > config.CO2_THRESHOLD: - # print(f'Threshold exceeded in {area.name} : {area.emissions}') - if not area.locked: - actions.lock_area(area, vehicles) + if area.emissions > config.CO2_THRESHOLD and area.locked == False: + actions.lock_area(area, vehicles) traci.polygon.setColor(area.name, (255, 0, 0)) traci.polygon.setFilled(area.name, True) @@ -68,11 +67,32 @@ def main(): traci.start(config.sumo_cmd) grid = init_grid(traci.simulation.getNetBoundary(), config.CELLS_NUMBER) add_lanes_to_areas(grid) - while traci.simulation.getMinExpectedNumber() > 0: + + step = 0 + while step < config.n_steps : #traci.simulation.getMinExpectedNumber() > 0: traci.simulationStep() + vehicles = get_all_vehicles() get_emissions(grid, vehicles) + #actions.adjustEdgesWeight() + + + step += 1 + sys.stdout.write(f'Simulation step = {step}/{config.n_steps}'+'\r') + sys.stdout.flush() + finally: + total_emissions = 0 + for area in areas: + total_emissions += area.emissions + + #For 200 steps, total emissions = 42816869.054364316 mg + #For 400 steps, total emissions = 136020579.71122485 mg + + print(f'\n**** Total emissions (CO2) = {total_emissions} mg') + diff_with_lock = (136020579.71122485 - total_emissions)/136020579.71122485 + print(f'**** Reduction percentage of CO2 emissions = {diff_with_lock*100} % ****\n') + traci.close(False) From 4c0ffc3778e2a258b94eeed46743c690bd3c589f Mon Sep 17 00:00:00 2001 From: Ahp06 Date: Tue, 20 Nov 2018 13:52:23 +0100 Subject: [PATCH 14/15] Changed vehicle class --- sumo_project/actions.py | 7 +++---- sumo_project/config.py | 2 +- sumo_project/emissions.py | 26 ++++++++++++++++---------- sumo_project/model.py | 3 ++- 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/sumo_project/actions.py b/sumo_project/actions.py index b115fc9..c600e54 100644 --- a/sumo_project/actions.py +++ b/sumo_project/actions.py @@ -23,15 +23,14 @@ def lanes_in_area(area): def computeEdgeWeight(edge_id): return traci.edge.getCO2Emission(edge_id) -#Useless because vehicles reroute automatically by travelTime -def rerouteVehicles(): +def rerouteEffortVehicles(): for veh_id in traci.vehicle.getIDList(): - traci.vehicle.rerouteTraveltime(veh_id,True) + traci.vehicle.rerouteEffort(veh_id) def adjustEdgesWeight(): for edge_id in traci.edge.getIDList(): weight = computeEdgeWeight(edge_id) #by default edges weight = length/mean speed - traci.edge.adaptTraveltime(edge_id, weight) + traci.edge.setEffort(edge_id, weight) def lock_area(area: Area, vehicles: Iterable[Vehicle]): max_speed = 30 diff --git a/sumo_project/config.py b/sumo_project/config.py index e71e19a..f90ba92 100644 --- a/sumo_project/config.py +++ b/sumo_project/config.py @@ -15,7 +15,7 @@ _SUMOCMD = 'sumo' # use 'sumo-gui' cmd for UI _SUMOCFG = "mulhouse_simulation/osm.sumocfg" CELLS_NUMBER = 10 CO2_THRESHOLD = 500000 -n_steps = 400 +n_steps = 200 sumo_binary = os.path.join(os.environ['SUMO_HOME'], 'bin', _SUMOCMD) sumo_cmd = [sumo_binary, "-c", _SUMOCFG] diff --git a/sumo_project/emissions.py b/sumo_project/emissions.py index 80b0724..dc6370d 100644 --- a/sumo_project/emissions.py +++ b/sumo_project/emissions.py @@ -24,13 +24,19 @@ def init_grid(simulation_bounds, cells_number): traci.polygon.add(area.name, ar_bounds, (0, 255, 0)) return areas - +def compute_vehicle_emissions(veh_id): + return (traci.vehicle.getCOEmission(veh_id) + + traci.vehicle.getNOxEmission(veh_id) + + traci.vehicle.getHCEmission(veh_id) + + traci.vehicle.getPMxEmission(veh_id) + + traci.vehicle.getCO2Emission(veh_id)) + def get_all_vehicles() -> List[Vehicle]: vehicles = list() for veh_id in traci.vehicle.getIDList(): veh_pos = traci.vehicle.getPosition(veh_id) vehicle = Vehicle(veh_id, veh_pos) - vehicle.co2 = traci.vehicle.getCO2Emission(vehicle.veh_id) + vehicle.emissions = compute_vehicle_emissions(veh_id) vehicles.append(vehicle) return vehicles @@ -47,7 +53,7 @@ def get_emissions(grid: List[Area], vehicles: List[Vehicle]): for area in grid: for vehicle in vehicles: if vehicle.pos in area: - area.emissions += vehicle.co2 + area.emissions += vehicle.emissions if area.emissions > config.CO2_THRESHOLD and area.locked == False: actions.lock_area(area, vehicles) traci.polygon.setColor(area.name, (255, 0, 0)) @@ -75,7 +81,7 @@ def main(): vehicles = get_all_vehicles() get_emissions(grid, vehicles) #actions.adjustEdgesWeight() - + #actions.rerouteEffortVehicles() step += 1 sys.stdout.write(f'Simulation step = {step}/{config.n_steps}'+'\r') @@ -86,12 +92,12 @@ def main(): for area in areas: total_emissions += area.emissions - #For 200 steps, total emissions = 42816869.054364316 mg - #For 400 steps, total emissions = 136020579.71122485 mg - - print(f'\n**** Total emissions (CO2) = {total_emissions} mg') - diff_with_lock = (136020579.71122485 - total_emissions)/136020579.71122485 - print(f'**** Reduction percentage of CO2 emissions = {diff_with_lock*100} % ****\n') + #Total of emissions of all pollutants in mg for 200 steps of simulation without locking areas + total_emissions200 = 43970763.15084749 + + print(f'\n**** Total emissions = {total_emissions} mg ****') + diff_with_lock = (total_emissions200 - total_emissions)/total_emissions200 + print(f'**** Reduction percentage of emissions = {diff_with_lock*100} % ****\n') traci.close(False) diff --git a/sumo_project/model.py b/sumo_project/model.py index 5f6e69d..9853bed 100644 --- a/sumo_project/model.py +++ b/sumo_project/model.py @@ -56,9 +56,10 @@ class Area: class Vehicle: def __init__(self, veh_id: int, pos: Tuple[float, float]): - self.co2: float = None + self.emissions: float = None self.veh_id = veh_id self.pos = Point(pos) def __repr__(self) -> str: return str(self.__dict__) + From f092e6af8dcb43cd7bf6c3663a0c1da4e51c6dbc Mon Sep 17 00:00:00 2001 From: Ahp06 Date: Tue, 20 Nov 2018 14:54:19 +0100 Subject: [PATCH 15/15] Changed some config parameters --- sumo_project/actions.py | 16 ++++++++-------- sumo_project/config.py | 5 ++++- sumo_project/emissions.py | 19 ++++++++++++------- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/sumo_project/actions.py b/sumo_project/actions.py index c600e54..7b0e776 100644 --- a/sumo_project/actions.py +++ b/sumo_project/actions.py @@ -21,20 +21,20 @@ def lanes_in_area(area): yield lane_id def computeEdgeWeight(edge_id): - return traci.edge.getCO2Emission(edge_id) - -def rerouteEffortVehicles(): - for veh_id in traci.vehicle.getIDList(): - traci.vehicle.rerouteEffort(veh_id) - + return (traci.edge.getCOEmission(edge_id) + + traci.edge.getNOxEmission(edge_id) + + traci.edge.getHCEmission(edge_id) + + traci.edge.getPMxEmission(edge_id) + + traci.edge.getCO2Emission(edge_id)) + def adjustEdgesWeight(): for edge_id in traci.edge.getIDList(): weight = computeEdgeWeight(edge_id) #by default edges weight = length/mean speed - traci.edge.setEffort(edge_id, weight) + traci.edge.adaptTraveltime(edge_id, weight) def lock_area(area: Area, vehicles: Iterable[Vehicle]): max_speed = 30 - print(f' Setting max speed into {area.name} to {max_speed} km/h') + print(f'Setting max speed into {area.name} to {max_speed} km/h') area.locked = True for lane in area._lanes: traci.lane.setMaxSpeed(lane.lane_id, max_speed/3.6) diff --git a/sumo_project/config.py b/sumo_project/config.py index f90ba92..a27bd0f 100644 --- a/sumo_project/config.py +++ b/sumo_project/config.py @@ -14,9 +14,12 @@ else: _SUMOCMD = 'sumo' # use 'sumo-gui' cmd for UI _SUMOCFG = "mulhouse_simulation/osm.sumocfg" CELLS_NUMBER = 10 -CO2_THRESHOLD = 500000 +EMISSIONS_THRESHOLD = 500000 n_steps = 200 +lock_mode = True +routing_mode = False + sumo_binary = os.path.join(os.environ['SUMO_HOME'], 'bin', _SUMOCMD) sumo_cmd = [sumo_binary, "-c", _SUMOCFG] diff --git a/sumo_project/emissions.py b/sumo_project/emissions.py index dc6370d..6a1d077 100644 --- a/sumo_project/emissions.py +++ b/sumo_project/emissions.py @@ -19,7 +19,7 @@ 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) areas.append(area) traci.polygon.add(area.name, ar_bounds, (0, 255, 0)) return areas @@ -37,6 +37,7 @@ def get_all_vehicles() -> List[Vehicle]: veh_pos = traci.vehicle.getPosition(veh_id) vehicle = Vehicle(veh_id, veh_pos) vehicle.emissions = compute_vehicle_emissions(veh_id) + traci.vehicle.setRoutingMode(veh_id, traci.constants.ROUTING_MODE_AGGREGATED) vehicles.append(vehicle) return vehicles @@ -54,7 +55,7 @@ def get_emissions(grid: List[Area], vehicles: List[Vehicle]): for vehicle in vehicles: if vehicle.pos in area: area.emissions += vehicle.emissions - if area.emissions > config.CO2_THRESHOLD and area.locked == False: + if config.lock_mode == True and area.emissions > config.EMISSIONS_THRESHOLD and area.locked == False: actions.lock_area(area, vehicles) traci.polygon.setColor(area.name, (255, 0, 0)) traci.polygon.setFilled(area.name, True) @@ -74,32 +75,36 @@ def main(): grid = init_grid(traci.simulation.getNetBoundary(), config.CELLS_NUMBER) add_lanes_to_areas(grid) + + step = 0 while step < config.n_steps : #traci.simulation.getMinExpectedNumber() > 0: traci.simulationStep() vehicles = get_all_vehicles() get_emissions(grid, vehicles) - #actions.adjustEdgesWeight() - #actions.rerouteEffortVehicles() + + if config.routing_mode == True: + actions.adjustEdgesWeight() + actions.rerouteAllVehicles() step += 1 sys.stdout.write(f'Simulation step = {step}/{config.n_steps}'+'\r') sys.stdout.flush() finally: + traci.close(False) + total_emissions = 0 for area in areas: total_emissions += area.emissions - #Total of emissions of all pollutants in mg for 200 steps of simulation without locking areas + #Total of emissions of all pollutants in mg for 200 steps of simulation without locking areas total_emissions200 = 43970763.15084749 print(f'\n**** Total emissions = {total_emissions} mg ****') diff_with_lock = (total_emissions200 - total_emissions)/total_emissions200 print(f'**** Reduction percentage of emissions = {diff_with_lock*100} % ****\n') - - traci.close(False) if __name__ == '__main__':