1
0
mirror of https://github.com/Ahp06/SUMO_Emissions.git synced 2024-11-22 11:36:29 +00:00

Add simple logger

This commit is contained in:
Thibaud Gasser 2019-02-01 16:49:19 +01:00
parent 5454b8805b
commit 112c90ff08
2 changed files with 47 additions and 18 deletions

View File

@ -1,9 +1,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import argparse import argparse
import datetime
import json import json
import logging
import os import os
import shutil import shutil
import subprocess import subprocess
import sys
import tempfile import tempfile
import time import time
from sys import argv from sys import argv
@ -13,10 +16,28 @@ from xml.etree import ElementTree
import randomTrips import randomTrips
import sumolib import sumolib
if 'SUMO_HOME' in os.environ:
TOOLSDIR = os.path.join(os.environ['SUMO_HOME'], 'tools')
sys.path.append(TOOLSDIR)
else:
sys.exit("Please declare environment variable 'SUMO_HOME'")
# Absolute path of the directory the script is in # Absolute path of the directory the script is in
SCRIPTDIR = os.path.dirname(__file__) SCRIPTDIR = os.path.dirname(__file__)
TEMPLATEDIR = os.path.join(SCRIPTDIR, 'templates') TEMPLATEDIR = os.path.join(SCRIPTDIR, 'templates')
# Init logger
logfile = os.path.join(SCRIPTDIR, f'files/logs/configurator_{datetime.datetime.utcnow().isoformat()}.log')
logging.basicConfig(
filename=logfile,
level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
"""
Definition of vehicle classes.
See http://sumo.dlr.de/wiki/Definition_of_Vehicles,_Vehicle_Types,_and_Routes#Abstract_Vehicle_Class
"""
vehicle_classes = { vehicle_classes = {
'passenger': { 'passenger': {
'--vehicle-class': 'passenger', '--vehicle-class': 'passenger',
@ -56,11 +77,8 @@ class RandomTripsGenerator:
self._init_trips(edges, vclass, density) self._init_trips(edges, vclass, density)
self.options.update(vehicle_classes[self.vclass]) self.options.update(vehicle_classes[self.vclass])
def add_option(self, opt_name, value):
self.options[opt_name] = value
def generate(self): def generate(self):
print(f'Generating trips for vehicle class {self.vclass} with density of {self.density} veh/km/h') logging.info(f'Generating trips for vehicle class {self.vclass} with density of {self.density} veh/km/h')
randomTrips.main(randomTrips.get_options(dict_to_list(self.options) + self.flags)) randomTrips.main(randomTrips.get_options(dict_to_list(self.options) + self.flags))
def _init_trips(self, edges, vclass, density): def _init_trips(self, edges, vclass, density):
@ -74,10 +92,10 @@ class RandomTripsGenerator:
if edge.allows(vclass): if edge.allows(vclass):
length += edge.getLaneNumber() * edge.getLength() length += edge.getLaneNumber() * edge.getLength()
print(f'density = {density}') logging.debug(f'density = {density}')
period = 3600 / (length / 1000) / density period = 3600 / (length / 1000) / density
print(f'Period computed for network : {period}, vclass={self.vclass}') logging.debug(f'Period computed for network : {period}, vclass={self.vclass}')
self.flags.extend(['-p', period]) self.options.update({'-p': period})
class StoreDictKeyPair(argparse.Action): class StoreDictKeyPair(argparse.Action):
@ -136,8 +154,9 @@ def generate_scenario(osm_file, out_path, scenario_name, generate_polygons=False
# Copy typemaps to tempdir # Copy typemaps to tempdir
shutil.copytree(os.path.join(TEMPLATEDIR, 'typemap'), os.path.join(tmpdirname, 'typemap')) shutil.copytree(os.path.join(TEMPLATEDIR, 'typemap'), os.path.join(tmpdirname, 'typemap'))
# Call NETCONVERT # Call NETCONVERT
print("Generate network...") logging.info("Generating network…")
netconvertcmd = ['netconvert', '-c', netconfig] netconvertcmd = ['netconvert', '-c', netconfig]
logging.debug(f'Calling {" ".join(netconvertcmd)}')
subprocess.run(netconvertcmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) subprocess.run(netconvertcmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
# Optionaly generate polygons # Optionaly generate polygons
if generate_polygons: if generate_polygons:
@ -152,8 +171,9 @@ def generate_polygons_(osm_file, scenario_name, dest):
poly_template = load_polyconvert_template(osm_file, 'typemap/osmPolyconvert.typ.xml', scenario_name) poly_template = load_polyconvert_template(osm_file, 'typemap/osmPolyconvert.typ.xml', scenario_name)
poly_template.write(polyconfig) poly_template.write(polyconfig)
# Call POLYCONVERT # Call POLYCONVERT
print('Generate polygons...') logging.info('Generating polygons…')
polyconvert_cmd = ['polyconvert', '-c', polyconfig] polyconvert_cmd = ['polyconvert', '-c', polyconfig]
logging.debug(f'Calling {" ".join(polyconvert_cmd)}')
subprocess.run(polyconvert_cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) subprocess.run(polyconvert_cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
@ -168,14 +188,17 @@ def generate_mobility(out_path, name, vclasses):
routefile = f'{name}.{vclass}.rou.xml' routefile = f'{name}.{vclass}.rou.xml'
routepath = os.path.join(out_path, routefile) routepath = os.path.join(out_path, routefile)
routefiles.append(routefile) routefiles.append(routefile)
generator = RandomTripsGenerator(netpath, routepath, output, vclass, float(density), '-l', '--validate', logging.debug(routefile)
**{'--end': end_time}) generator = RandomTripsGenerator(netpath, routepath, output, vclass, float(density))
generator.flags.append('-l')
generator.flags.append('--validate')
generator.options.update(**{'--end': end_time})
generator.generate() generator.generate()
return routefiles return routefiles
def generate_sumo_configuration(routefiles, path, scenario_name, generate_polygons=False): def generate_sumo_configuration(routefiles, path, scenario_name, generate_polygons):
sumo_template = load_sumoconfig_template(scenario_name, routefiles=routefiles, generate_polygons=False) sumo_template = load_sumoconfig_template(scenario_name, routefiles, generate_polygons)
sumo_template.write(os.path.join(path, f'{scenario_name}.sumocfg')) sumo_template.write(os.path.join(path, f'{scenario_name}.sumocfg'))
@ -188,9 +211,10 @@ def generate_all(args):
generate_polygons = False generate_polygons = False
osm_file = args.osmfile osm_file = args.osmfile
logs_dir = os.path.join(simulation_dir, 'log') logs_dir = os.path.join(simulation_dir, 'log')
generate_scenario(osm_file, simulation_dir, simulation_name, generate_polygons) generate_scenario(osm_file, simulation_dir, simulation_name, generate_polygons)
routefiles = generate_mobility(simulation_dir, simulation_name, args.vclasses) routefiles = generate_mobility(simulation_dir, simulation_name, args.vclasses)
generate_sumo_configuration(routefiles, simulation_dir, simulation_name, generate_polygons, ) generate_sumo_configuration(routefiles, simulation_dir, simulation_name, generate_polygons)
# Move all logs to logdir # Move all logs to logdir
move_logs(simulation_dir, logs_dir) move_logs(simulation_dir, logs_dir)
@ -210,8 +234,8 @@ def parse_command_line():
parser.add_argument('osmfile', help='Path to the .osm file to convert to a SUMO simulation') parser.add_argument('osmfile', help='Path to the .osm file to convert to a SUMO simulation')
parser.add_argument('--path', help='Where to generate the files') parser.add_argument('--path', help='Where to generate the files')
parser.add_argument('--name', required=True, help='Name of the SUMO scenario to generate') parser.add_argument('--name', required=True, help='Name of the SUMO scenario to generate')
parser.add_argument('--generate-polygons', default=False, action='store_true', help='Whether to generate polygons ' parser.add_argument('--generate-polygons', default=False, action='store_true',
'and POIs (defaults to false).') help='Whether to generate polygons and POIs (defaults to false).')
parser.add_argument('--vclass', dest='vclasses', action=StoreDictKeyPair, parser.add_argument('--vclass', dest='vclasses', action=StoreDictKeyPair,
nargs="+", metavar="VCLASS=DENSITY", nargs="+", metavar="VCLASS=DENSITY",
help='Generate this vclass with given density, in pair form vclass=density. The density is ' help='Generate this vclass with given density, in pair form vclass=density. The density is '
@ -230,11 +254,14 @@ def handle_args(options):
if os.path.isdir(simul_dir): if os.path.isdir(simul_dir):
input(f'{simul_dir} already exists ! Press Enter to delete...') input(f'{simul_dir} already exists ! Press Enter to delete...')
shutil.rmtree(simul_dir) shutil.rmtree(simul_dir)
logging.debug(f'Options : {options}')
generate_all(options) generate_all(options)
def parse_json(json_file): def parse_json(json_file):
logging.info(f'Loading config from {json_file}')
config = SimpleNamespace(**json.load(json_file)) config = SimpleNamespace(**json.load(json_file))
logging.debug(f'Config {config}')
handle_args(config) handle_args(config)
@ -246,7 +273,9 @@ if __name__ == '__main__':
with open(argv[2]) as jsonfile: with open(argv[2]) as jsonfile:
parse_json(jsonfile) parse_json(jsonfile)
except FileNotFoundError: except FileNotFoundError:
raise FileNotFoundError(f'The config file {argv[2]} does not exist!') msg = f'The config file {argv[2]} does not exist!'
logging.fatal(msg)
raise FileNotFoundError(msg)
else: else:
# Run with command line arguments # Run with command line arguments
parse_command_line() parse_command_line()

View File

@ -24,7 +24,7 @@
</report> </report>
<random_number> <random_number>
<seed value=""/> <seed value="1"/>
</random_number> </random_number>
</configuration> </configuration>