sumo net automatically generated
This commit is contained in:
parent
4ec9723df3
commit
02330cd84d
|
@ -87,6 +87,12 @@ class SimulationSynchronization(object):
|
||||||
BridgeHelper.blueprint_library = self.carla.world.get_blueprint_library()
|
BridgeHelper.blueprint_library = self.carla.world.get_blueprint_library()
|
||||||
BridgeHelper.offset = self.sumo.get_net_offset()
|
BridgeHelper.offset = self.sumo.get_net_offset()
|
||||||
|
|
||||||
|
# Configuring carla simulation in sync mode.
|
||||||
|
settings = self.carla.world.get_settings()
|
||||||
|
settings.synchronous_mode = True
|
||||||
|
settings.fixed_delta_seconds = self.carla.step_length
|
||||||
|
self.carla.world.apply_settings(settings)
|
||||||
|
|
||||||
def tick(self):
|
def tick(self):
|
||||||
"""
|
"""
|
||||||
Tick to simulation synchronization
|
Tick to simulation synchronization
|
||||||
|
@ -225,8 +231,8 @@ def synchronization_loop(args):
|
||||||
Entry point for sumo-carla co-simulation.
|
Entry point for sumo-carla co-simulation.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
sumo_simulation = SumoSimulation(args.sumo_host, args.sumo_port, args.step_length,
|
sumo_simulation = SumoSimulation(args.sumo_cfg_file, args.step_length, args.sumo_host,
|
||||||
args.sumo_cfg_file, args.sumo_gui)
|
args.sumo_port, args.sumo_gui)
|
||||||
carla_simulation = CarlaSimulation(args.carla_host, args.carla_port, args.step_length)
|
carla_simulation = CarlaSimulation(args.carla_host, args.carla_port, args.step_length)
|
||||||
|
|
||||||
synchronization = SimulationSynchronization(sumo_simulation, carla_simulation,
|
synchronization = SimulationSynchronization(sumo_simulation, carla_simulation,
|
||||||
|
@ -254,6 +260,7 @@ def synchronization_loop(args):
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
argparser = argparse.ArgumentParser(description=__doc__)
|
argparser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
argparser.add_argument('sumo_cfg_file', type=str, help='sumo configuration file')
|
||||||
argparser.add_argument('--carla-host',
|
argparser.add_argument('--carla-host',
|
||||||
metavar='H',
|
metavar='H',
|
||||||
default='127.0.0.1',
|
default='127.0.0.1',
|
||||||
|
@ -272,14 +279,7 @@ if __name__ == '__main__':
|
||||||
default=None,
|
default=None,
|
||||||
type=int,
|
type=int,
|
||||||
help='TCP port to liston to (default: 8813)')
|
help='TCP port to liston to (default: 8813)')
|
||||||
argparser.add_argument('-c',
|
argparser.add_argument('--sumo-gui', action='store_true', help='run the gui version of sumo')
|
||||||
'--sumo-cfg-file',
|
|
||||||
default=None,
|
|
||||||
type=str,
|
|
||||||
help='sumo configuration file')
|
|
||||||
argparser.add_argument('--sumo-gui',
|
|
||||||
action='store_true',
|
|
||||||
help='run the gui version of sumo')
|
|
||||||
argparser.add_argument('--step-length',
|
argparser.add_argument('--step-length',
|
||||||
default=0.05,
|
default=0.05,
|
||||||
type=float,
|
type=float,
|
||||||
|
|
|
@ -12,13 +12,13 @@
|
||||||
# ==================================================================================================
|
# ==================================================================================================
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import datetime
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import time
|
|
||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
|
import tempfile
|
||||||
|
import time
|
||||||
|
|
||||||
import lxml.etree as ET # pylint: disable=wrong-import-position
|
import lxml.etree as ET # pylint: disable=wrong-import-position
|
||||||
|
|
||||||
|
@ -59,16 +59,17 @@ from sumo_integration.sumo_simulation import SumoSimulation # pylint: disable=w
|
||||||
|
|
||||||
from run_synchronization import SimulationSynchronization # pylint: disable=wrong-import-position
|
from run_synchronization import SimulationSynchronization # pylint: disable=wrong-import-position
|
||||||
|
|
||||||
|
from util.netconvert_carla import netconvert_carla
|
||||||
|
|
||||||
# ==================================================================================================
|
# ==================================================================================================
|
||||||
# -- main ------------------------------------------------------------------------------------------
|
# -- main ------------------------------------------------------------------------------------------
|
||||||
# ==================================================================================================
|
# ==================================================================================================
|
||||||
|
|
||||||
|
|
||||||
def write_sumocfg_xml(town_name, tmp_path, net_file, vtypes_file, viewsettings_file):
|
def write_sumocfg_xml(cfg_file, net_file, vtypes_file, viewsettings_file):
|
||||||
"""
|
"""
|
||||||
Writes sumo configuration xml file.
|
Writes sumo configuration xml file.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
root = ET.Element('configuration')
|
root = ET.Element('configuration')
|
||||||
|
|
||||||
input_tag = ET.SubElement(root, 'input')
|
input_tag = ET.SubElement(root, 'input')
|
||||||
|
@ -79,58 +80,51 @@ def write_sumocfg_xml(town_name, tmp_path, net_file, vtypes_file, viewsettings_f
|
||||||
ET.SubElement(gui_tag, 'gui-settings-file', {'value': viewsettings_file})
|
ET.SubElement(gui_tag, 'gui-settings-file', {'value': viewsettings_file})
|
||||||
|
|
||||||
tree = ET.ElementTree(root)
|
tree = ET.ElementTree(root)
|
||||||
filename = os.path.join(tmp_path, town_name + '.sumocfg')
|
tree.write(cfg_file, pretty_print=True, encoding='UTF-8', xml_declaration=True)
|
||||||
tree.write(filename, pretty_print=True, encoding='UTF-8', xml_declaration=True)
|
|
||||||
|
|
||||||
return filename
|
|
||||||
|
|
||||||
|
|
||||||
def get_sumo_files(town_name, tmp_path):
|
|
||||||
"""
|
|
||||||
Returns sumo configuration file and sumo net.
|
|
||||||
"""
|
|
||||||
base_path = os.path.dirname(os.path.realpath(__file__))
|
|
||||||
net_file = os.path.join(base_path, 'examples', 'net', town_name + '.net.xml')
|
|
||||||
vtypes_file = os.path.join(base_path, 'examples', 'carlavtypes.rou.xml')
|
|
||||||
viewsettings_file = os.path.join(base_path, 'examples', 'viewsettings.xml')
|
|
||||||
|
|
||||||
cfg_file = write_sumocfg_xml(town_name, tmp_path, net_file, vtypes_file, viewsettings_file)
|
|
||||||
return cfg_file, net_file
|
|
||||||
|
|
||||||
|
|
||||||
def main(args):
|
def main(args):
|
||||||
|
|
||||||
# Creating temporal folder to save configuration file.
|
# Temporal folder to save intermediate files.
|
||||||
tmp_path = 'spawn_npc_sumo-{date:%Y-%m-%d_%H-%M-%S-%f}'.format(date=datetime.datetime.now())
|
tmpdir = tempfile.mkdtemp()
|
||||||
if not os.path.exists(tmp_path):
|
|
||||||
os.mkdir(tmp_path)
|
# ----------------
|
||||||
|
# carla simulation
|
||||||
|
# ----------------
|
||||||
|
carla_simulation = CarlaSimulation(args.host, args.port, args.step_length)
|
||||||
|
|
||||||
|
world = carla_simulation.client.get_world()
|
||||||
|
current_map = carla_simulation.client.get_world().get_map()
|
||||||
|
|
||||||
|
xodr_file = os.path.join(tmpdir, current_map.name + '.xodr')
|
||||||
|
current_map.save_to_disk(xodr_file)
|
||||||
|
|
||||||
|
# ---------------
|
||||||
|
# sumo simulation
|
||||||
|
# ---------------
|
||||||
|
net_file = os.path.join(tmpdir, current_map.name + '.net.xml')
|
||||||
|
netconvert_carla(xodr_file, net_file, guess_tls=True)
|
||||||
|
|
||||||
|
basedir = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
cfg_file = os.path.join(tmpdir, current_map.name + '.sumocfg')
|
||||||
|
vtypes_file = os.path.join(basedir, 'examples', 'carlavtypes.rou.xml')
|
||||||
|
viewsettings_file = os.path.join(basedir, 'examples', 'viewsettings.xml')
|
||||||
|
write_sumocfg_xml(cfg_file, net_file, vtypes_file, viewsettings_file)
|
||||||
|
|
||||||
|
sumo_net = sumolib.net.readNet(net_file)
|
||||||
|
sumo_simulation = SumoSimulation(cfg_file,
|
||||||
|
args.step_length,
|
||||||
|
host=None,
|
||||||
|
port=None,
|
||||||
|
sumo_gui=args.sumo_gui)
|
||||||
|
|
||||||
|
# ---------------
|
||||||
|
# synchronization
|
||||||
|
# ---------------
|
||||||
|
synchronization = SimulationSynchronization(sumo_simulation, carla_simulation, args.tls_manager,
|
||||||
|
args.sync_vehicle_color, args.sync_vehicle_lights)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# ----------------
|
|
||||||
# carla simulation
|
|
||||||
# ----------------
|
|
||||||
carla_simulation = CarlaSimulation(args.host, args.port, args.step_length)
|
|
||||||
|
|
||||||
world = carla_simulation.client.get_world()
|
|
||||||
current_map = world.get_map().name
|
|
||||||
if current_map not in ('Town01', 'Town04', 'Town05'):
|
|
||||||
raise RuntimeError('This script does not support {} yet.'.format(current_map))
|
|
||||||
|
|
||||||
# ---------------
|
|
||||||
# sumo simulation
|
|
||||||
# ---------------
|
|
||||||
cfg_file, net_file = get_sumo_files(current_map, tmp_path)
|
|
||||||
|
|
||||||
sumo_net = sumolib.net.readNet(net_file)
|
|
||||||
sumo_simulation = SumoSimulation(None, None, args.step_length, cfg_file, args.sumo_gui)
|
|
||||||
|
|
||||||
# ---------------
|
|
||||||
# synchronization
|
|
||||||
# ---------------
|
|
||||||
synchronization = SimulationSynchronization(sumo_simulation, carla_simulation,
|
|
||||||
args.tls_manager, args.sync_vehicle_color,
|
|
||||||
args.sync_vehicle_lights)
|
|
||||||
|
|
||||||
# ----------
|
# ----------
|
||||||
# Blueprints
|
# Blueprints
|
||||||
# ----------
|
# ----------
|
||||||
|
@ -183,10 +177,12 @@ def main(args):
|
||||||
|
|
||||||
if index == (len(route) - 1):
|
if index == (len(route) - 1):
|
||||||
current_edge = sumo_net.getEdge(route[index])
|
current_edge = sumo_net.getEdge(route[index])
|
||||||
next_edge = random.choice(list(current_edge.getAllowedOutgoing(vclass).keys()))
|
available_edges = list(current_edge.getAllowedOutgoing(vclass).keys())
|
||||||
|
if available_edges:
|
||||||
|
next_edge = random.choice(available_edges)
|
||||||
|
|
||||||
new_route = [current_edge.getID(), next_edge.getID()]
|
new_route = [current_edge.getID(), next_edge.getID()]
|
||||||
traci.vehicle.setRoute(vehicle_id, new_route)
|
traci.vehicle.setRoute(vehicle_id, new_route)
|
||||||
|
|
||||||
end = time.time()
|
end = time.time()
|
||||||
elapsed = end - start
|
elapsed = end - start
|
||||||
|
@ -197,10 +193,9 @@ def main(args):
|
||||||
logging.info('Cancelled by user.')
|
logging.info('Cancelled by user.')
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
if os.path.exists(tmp_path):
|
if os.path.exists(tmpdir):
|
||||||
shutil.rmtree(tmp_path)
|
shutil.rmtree(tmpdir)
|
||||||
|
|
||||||
logging.info('Destroying %d sumo vehicles.', traci.vehicle.getIDCount())
|
|
||||||
synchronization.close()
|
synchronization.close()
|
||||||
|
|
||||||
|
|
||||||
|
@ -239,9 +234,7 @@ if __name__ == '__main__':
|
||||||
metavar='PATTERN',
|
metavar='PATTERN',
|
||||||
default='walker.pedestrian.*',
|
default='walker.pedestrian.*',
|
||||||
help='pedestrians filter (default: "walker.pedestrian.*")')
|
help='pedestrians filter (default: "walker.pedestrian.*")')
|
||||||
argparser.add_argument('--sumo-gui',
|
argparser.add_argument('--sumo-gui', action='store_true', help='run the gui version of sumo')
|
||||||
action='store_true',
|
|
||||||
help='run the gui version of sumo')
|
|
||||||
argparser.add_argument('--step-length',
|
argparser.add_argument('--step-length',
|
||||||
default=0.05,
|
default=0.05,
|
||||||
type=float,
|
type=float,
|
||||||
|
@ -272,4 +265,4 @@ if __name__ == '__main__':
|
||||||
else:
|
else:
|
||||||
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
|
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
|
||||||
|
|
||||||
main(args)
|
main(args)
|
|
@ -32,12 +32,7 @@ class CarlaSimulation(object):
|
||||||
|
|
||||||
self.world = self.client.get_world()
|
self.world = self.client.get_world()
|
||||||
self.blueprint_library = self.world.get_blueprint_library()
|
self.blueprint_library = self.world.get_blueprint_library()
|
||||||
|
self.step_length = step_length
|
||||||
# Configuring carla simulation in sync mode.
|
|
||||||
settings = self.world.get_settings()
|
|
||||||
settings.synchronous_mode = True
|
|
||||||
settings.fixed_delta_seconds = step_length
|
|
||||||
self.world.apply_settings(settings)
|
|
||||||
|
|
||||||
# The following sets contain updated information for the current frame.
|
# The following sets contain updated information for the current frame.
|
||||||
self._active_actors = set()
|
self._active_actors = set()
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
import collections
|
import collections
|
||||||
import enum
|
import enum
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
|
|
||||||
import carla # pylint: disable=import-error
|
import carla # pylint: disable=import-error
|
||||||
import sumolib # pylint: disable=import-error
|
import sumolib # pylint: disable=import-error
|
||||||
|
@ -21,6 +22,8 @@ import traci # pylint: disable=import-error
|
||||||
|
|
||||||
from .constants import INVALID_ACTOR_ID
|
from .constants import INVALID_ACTOR_ID
|
||||||
|
|
||||||
|
import lxml.etree as ET # pylint: disable=import-error
|
||||||
|
|
||||||
# ==================================================================================================
|
# ==================================================================================================
|
||||||
# -- sumo definitions ------------------------------------------------------------------------------
|
# -- sumo definitions ------------------------------------------------------------------------------
|
||||||
# ==================================================================================================
|
# ==================================================================================================
|
||||||
|
@ -99,7 +102,7 @@ class SumoActorClass(enum.Enum):
|
||||||
SumoActor = collections.namedtuple('SumoActor', 'type_id vclass transform signals extent color')
|
SumoActor = collections.namedtuple('SumoActor', 'type_id vclass transform signals extent color')
|
||||||
|
|
||||||
# ==================================================================================================
|
# ==================================================================================================
|
||||||
# -- sumo simulation -------------------------------------------------------------------------------
|
# -- sumo traffic lights ---------------------------------------------------------------------------
|
||||||
# ==================================================================================================
|
# ==================================================================================================
|
||||||
|
|
||||||
|
|
||||||
|
@ -277,11 +280,35 @@ class SumoTLManager(object):
|
||||||
self._current_phase[tl_id] = current_phase
|
self._current_phase[tl_id] = current_phase
|
||||||
|
|
||||||
|
|
||||||
|
# ==================================================================================================
|
||||||
|
# -- sumo simulation -------------------------------------------------------------------------------
|
||||||
|
# ==================================================================================================
|
||||||
|
|
||||||
|
def _get_sumo_net(cfg_file):
|
||||||
|
"""
|
||||||
|
Returns sumo net.
|
||||||
|
|
||||||
|
This method reads the sumo configuration file and retrieve the sumo net filename to create the
|
||||||
|
net.
|
||||||
|
"""
|
||||||
|
cfg_file = os.path.join(os.getcwd(), cfg_file)
|
||||||
|
|
||||||
|
tree = ET.parse(cfg_file)
|
||||||
|
tag = tree.find('//net-file')
|
||||||
|
if tag is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
net_file = os.path.join(os.path.dirname(cfg_file), tag.get('value'))
|
||||||
|
logging.debug('Reading net file: %s', net_file)
|
||||||
|
|
||||||
|
sumo_net = traci.sumolib.net.readNet(net_file)
|
||||||
|
return sumo_net
|
||||||
|
|
||||||
class SumoSimulation(object):
|
class SumoSimulation(object):
|
||||||
"""
|
"""
|
||||||
SumoSimulation is responsible for the management of the sumo simulation.
|
SumoSimulation is responsible for the management of the sumo simulation.
|
||||||
"""
|
"""
|
||||||
def __init__(self, host, port, step_length, cfg_file, sumo_gui=False):
|
def __init__(self, cfg_file, step_length, host=None, port=None, sumo_gui=False):
|
||||||
if sumo_gui is True:
|
if sumo_gui is True:
|
||||||
sumo_binary = sumolib.checkBinary('sumo-gui')
|
sumo_binary = sumolib.checkBinary('sumo-gui')
|
||||||
else:
|
else:
|
||||||
|
@ -303,6 +330,9 @@ class SumoSimulation(object):
|
||||||
logging.info('Connection to sumo server. Host: %s Port: %s', host, port)
|
logging.info('Connection to sumo server. Host: %s Port: %s', host, port)
|
||||||
traci.init(host=host, port=port)
|
traci.init(host=host, port=port)
|
||||||
|
|
||||||
|
# Retrieving net from configuration file.
|
||||||
|
self.net = _get_sumo_net(cfg_file)
|
||||||
|
|
||||||
# Creating a random route to be able to spawn carla actors.
|
# Creating a random route to be able to spawn carla actors.
|
||||||
traci.route.add("carla_route", [traci.edge.getIDList()[0]])
|
traci.route.add("carla_route", [traci.edge.getIDList()[0]])
|
||||||
|
|
||||||
|
@ -349,20 +379,11 @@ class SumoSimulation(object):
|
||||||
"""
|
"""
|
||||||
traci.vehicle.unsubscribe(actor_id)
|
traci.vehicle.unsubscribe(actor_id)
|
||||||
|
|
||||||
@staticmethod
|
def get_net_offset(self):
|
||||||
def get_net_offset():
|
|
||||||
"""
|
"""
|
||||||
Accessor for sumo net offset.
|
Accessor for sumo net offset.
|
||||||
"""
|
"""
|
||||||
offset = traci.simulation.convertGeo(0, 0)
|
return self.net.getLocationOffset()
|
||||||
return (-offset[0], -offset[1])
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_step_length():
|
|
||||||
"""
|
|
||||||
Accessor for sumo simulation step length.
|
|
||||||
"""
|
|
||||||
return traci.simulation.getDeltaT()
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_actor(actor_id):
|
def get_actor(actor_id):
|
||||||
|
|
|
@ -17,10 +17,10 @@ the net and inserts, manually, the traffic light landmarks retrieved from the op
|
||||||
import argparse
|
import argparse
|
||||||
import bisect
|
import bisect
|
||||||
import collections
|
import collections
|
||||||
import datetime
|
|
||||||
import logging
|
import logging
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import tempfile
|
||||||
|
|
||||||
import lxml.etree as ET # pylint: disable=import-error
|
import lxml.etree as ET # pylint: disable=import-error
|
||||||
|
|
||||||
|
@ -362,29 +362,30 @@ class SumoTrafficLight(object):
|
||||||
# ==================================================================================================
|
# ==================================================================================================
|
||||||
|
|
||||||
|
|
||||||
def netconvert_carla(args, tmp_path):
|
def _netconvert_carla_impl(xodr_file, output, tmpdir, guess_tls=False):
|
||||||
"""
|
"""
|
||||||
Generates sumo net.
|
Implements netconvert carla.
|
||||||
"""
|
"""
|
||||||
# ----------
|
# ----------
|
||||||
# netconvert
|
# netconvert
|
||||||
# ----------
|
# ----------
|
||||||
tmp_file = os.path.splitext(os.path.basename(args.xodr_file))[0]
|
basename = os.path.splitext(os.path.basename(xodr_file))[0]
|
||||||
tmp_sumo_net = os.path.join(tmp_path, tmp_file + '.net.xml')
|
tmp_sumo_net = os.path.join(tmpdir, basename + '.net.xml')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
basedir = os.path.dirname(os.path.realpath(__file__))
|
||||||
result = subprocess.call(['netconvert',
|
result = subprocess.call(['netconvert',
|
||||||
'--opendrive', args.xodr_file,
|
'--opendrive', xodr_file,
|
||||||
'--output-file', tmp_sumo_net,
|
'--output-file', tmp_sumo_net,
|
||||||
'--geometry.min-radius.fix',
|
'--geometry.min-radius.fix',
|
||||||
'--geometry.remove',
|
'--geometry.remove',
|
||||||
'--opendrive.curve-resolution', '1',
|
'--opendrive.curve-resolution', '1',
|
||||||
'--opendrive.import-all-lanes',
|
'--opendrive.import-all-lanes',
|
||||||
'--type-files', 'data/opendrive_netconvert.typ.xml',
|
'--type-files', os.path.join(basedir, 'data/opendrive_netconvert.typ.xml'),
|
||||||
# Necessary to link odr and sumo ids.
|
# Necessary to link odr and sumo ids.
|
||||||
'--output.original-names',
|
'--output.original-names',
|
||||||
# Discard loading traffic lights as them will be inserted manually afterwards.
|
# Discard loading traffic lights as them will be inserted manually afterwards.
|
||||||
'--tls.discard-loaded', 'true'
|
'--tls.discard-loaded', 'true',
|
||||||
])
|
])
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
raise RuntimeError('There was an error when executing netconvert.')
|
raise RuntimeError('There was an error when executing netconvert.')
|
||||||
|
@ -401,7 +402,7 @@ def netconvert_carla(args, tmp_path):
|
||||||
# ---------
|
# ---------
|
||||||
# Carla map
|
# Carla map
|
||||||
# ---------
|
# ---------
|
||||||
with open(args.xodr_file, 'r') as f:
|
with open(xodr_file, 'r') as f:
|
||||||
carla_map = carla.Map('netconvert', str(f.read()))
|
carla_map = carla.Map('netconvert', str(f.read()))
|
||||||
|
|
||||||
# ---------
|
# ---------
|
||||||
|
@ -437,7 +438,7 @@ def netconvert_carla(args, tmp_path):
|
||||||
tls[tlid] = SumoTrafficLight(tlid)
|
tls[tlid] = SumoTrafficLight(tlid)
|
||||||
tl = tls[tlid]
|
tl = tls[tlid]
|
||||||
|
|
||||||
if args.guess_tls:
|
if guess_tls:
|
||||||
for from_edge, from_lane in sumo_topology.get_incoming(road_id, lane_id):
|
for from_edge, from_lane in sumo_topology.get_incoming(road_id, lane_id):
|
||||||
successors = sumo_topology.get_successors(from_edge, from_lane)
|
successors = sumo_topology.get_successors(from_edge, from_lane)
|
||||||
for to_edge, to_lane in successors:
|
for to_edge, to_lane in successors:
|
||||||
|
@ -503,25 +504,33 @@ def netconvert_carla(args, tmp_path):
|
||||||
connection.from_road, connection.to_road, connection.from_lane,
|
connection.from_road, connection.to_road, connection.from_lane,
|
||||||
connection.to_lane))
|
connection.to_lane))
|
||||||
|
|
||||||
tree.write(args.output, pretty_print=True, encoding='UTF-8', xml_declaration=True)
|
tree.write(output, pretty_print=True, encoding='UTF-8', xml_declaration=True)
|
||||||
|
|
||||||
|
def netconvert_carla(xodr_file, output, guess_tls=False):
|
||||||
|
"""
|
||||||
|
Generates sumo net.
|
||||||
|
|
||||||
|
:param xodr_file: opendrive file (*.xodr)
|
||||||
|
:param output: output file (*.net.xml)
|
||||||
|
:param guess_tls: guess traffic lights at intersections.
|
||||||
|
:returns: path to the generated sumo net.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
tmpdir = tempfile.mkdtemp()
|
||||||
|
_netconvert_carla_impl(xodr_file, output, tmpdir, guess_tls)
|
||||||
|
|
||||||
|
finally:
|
||||||
|
if os.path.exists(tmpdir):
|
||||||
|
shutil.rmtree(tmpdir)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
argparser = argparse.ArgumentParser(description=__doc__)
|
argparser = argparse.ArgumentParser(description=__doc__)
|
||||||
argparser.add_argument('xodr_file', help='open drive file (*.xodr')
|
argparser.add_argument('xodr_file', help='opendrive file (*.xodr')
|
||||||
argparser.add_argument('--output', '-o', type=str, help='output file (*.net.xml)')
|
argparser.add_argument('--output', '-o', type=str, help='output file (*.net.xml)')
|
||||||
argparser.add_argument('--guess-tls',
|
argparser.add_argument('--guess-tls',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help='guess traffic lights at intersections (default: False)')
|
help='guess traffic lights at intersections (default: False)')
|
||||||
args = argparser.parse_args()
|
args = argparser.parse_args()
|
||||||
|
|
||||||
try:
|
netconvert_carla(args.xodr_file, args.output, args.guess_tls)
|
||||||
tmp_path = 'tmp-{date:%Y-%m-%d_%H-%M-%S-%f}'.format(date=datetime.datetime.now())
|
|
||||||
if not os.path.exists(tmp_path):
|
|
||||||
os.mkdir(tmp_path)
|
|
||||||
|
|
||||||
netconvert_carla(args, tmp_path)
|
|
||||||
|
|
||||||
finally:
|
|
||||||
if os.path.exists(tmp_path):
|
|
||||||
shutil.rmtree(tmp_path)
|
|
||||||
|
|
Loading…
Reference in New Issue