fixing codacy warnings
This commit is contained in:
parent
d429a22978
commit
708f3ccfe3
|
@ -10,9 +10,17 @@
|
|||
Script to integrate CARLA and SUMO simulations
|
||||
"""
|
||||
|
||||
# ==============================================================================
|
||||
# -- find carla module ---------------------------------------------------------
|
||||
# ==============================================================================
|
||||
# ==================================================================================================
|
||||
# -- imports ---------------------------------------------------------------------------------------
|
||||
# ==================================================================================================
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
import time
|
||||
|
||||
# ==================================================================================================
|
||||
# -- find carla module -----------------------------------------------------------------------------
|
||||
# ==================================================================================================
|
||||
|
||||
import glob
|
||||
import os
|
||||
|
@ -26,34 +34,33 @@ try:
|
|||
except IndexError:
|
||||
pass
|
||||
|
||||
# ==============================================================================
|
||||
# -- find traci module ---------------------------------------------------------
|
||||
# ==============================================================================
|
||||
# ==================================================================================================
|
||||
# -- find traci module -----------------------------------------------------------------------------
|
||||
# ==================================================================================================
|
||||
|
||||
if 'SUMO_HOME' in os.environ:
|
||||
tools = os.path.join(os.environ['SUMO_HOME'], 'tools')
|
||||
sys.path.append(tools)
|
||||
sys.path.append(os.path.join(os.environ['SUMO_HOME'], 'tools'))
|
||||
else:
|
||||
sys.exit("please declare environment variable 'SUMO_HOME'")
|
||||
|
||||
# ==============================================================================
|
||||
# -- imports -------------------------------------------------------------------
|
||||
# ==============================================================================
|
||||
# ==================================================================================================
|
||||
# -- sumo integration importants -------------------------------------------------------------------
|
||||
# ==================================================================================================
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
import time
|
||||
from sumo_integration.bridge_helper import BridgeHelper # pylint: disable=wrong-import-position
|
||||
from sumo_integration.carla_simulation import CarlaSimulation # pylint: disable=wrong-import-position
|
||||
from sumo_integration.constants import INVALID_ACTOR_ID # pylint: disable=wrong-import-position
|
||||
from sumo_integration.sumo_simulation import SumoSimulation # pylint: disable=wrong-import-position
|
||||
|
||||
from sumo_integration.bridge_helper import BridgeHelper
|
||||
from sumo_integration.carla_simulation import CarlaSimulation
|
||||
from sumo_integration.constants import *
|
||||
from sumo_integration.sumo_simulation import SumoSimulation
|
||||
# ==================================================================================================
|
||||
# -- simulation synchro ----------------------------------------------------------------------------
|
||||
# ==================================================================================================
|
||||
|
||||
# ==============================================================================
|
||||
# -- simulation synchro --------------------------------------------------------
|
||||
# ==============================================================================
|
||||
|
||||
def main(args):
|
||||
"""
|
||||
Entry point sumo-carla co-simulation.
|
||||
"""
|
||||
sumo = SumoSimulation(args)
|
||||
carla = CarlaSimulation(args)
|
||||
|
||||
|
@ -61,8 +68,8 @@ def main(args):
|
|||
sumo2carla_ids = {} # Contains only actors controlled by sumo.
|
||||
carla2sumo_ids = {} # Contains only actors controlled by carla.
|
||||
|
||||
BridgeHelper._blueprint_library = carla.world.get_blueprint_library()
|
||||
BridgeHelper._offset = sumo.get_net_offset()
|
||||
BridgeHelper.blueprint_library = carla.world.get_blueprint_library()
|
||||
BridgeHelper.offset = sumo.get_net_offset()
|
||||
|
||||
try:
|
||||
while True:
|
||||
|
@ -81,7 +88,8 @@ def main(args):
|
|||
|
||||
carla_blueprint = BridgeHelper.get_carla_blueprint(sumo_actor)
|
||||
if carla_blueprint is not None:
|
||||
carla_transform = BridgeHelper.get_carla_transform(sumo_actor.transform, sumo_actor.extent)
|
||||
carla_transform = BridgeHelper.get_carla_transform(
|
||||
sumo_actor.transform, sumo_actor.extent)
|
||||
|
||||
carla_actor_id = carla.spawn_actor(carla_blueprint, carla_transform)
|
||||
if carla_actor_id != INVALID_ACTOR_ID:
|
||||
|
@ -101,9 +109,11 @@ def main(args):
|
|||
sumo_actor = sumo.get_actor(sumo_actor_id)
|
||||
carla_actor = carla.get_actor(carla_actor_id)
|
||||
|
||||
carla_transform = BridgeHelper.get_carla_transform(sumo_actor.transform, sumo_actor.extent)
|
||||
carla_transform = BridgeHelper.get_carla_transform(sumo_actor.transform,
|
||||
sumo_actor.extent)
|
||||
if args.sync_vehicle_lights:
|
||||
carla_lights = BridgeHelper.get_carla_lights_state(carla_actor.get_light_state(), sumo_actor.signals)
|
||||
carla_lights = BridgeHelper.get_carla_lights_state(
|
||||
carla_actor.get_light_state(), sumo_actor.signals)
|
||||
else:
|
||||
carla_lights = None
|
||||
|
||||
|
@ -138,11 +148,13 @@ def main(args):
|
|||
carla_actor = carla.get_actor(carla_actor_id)
|
||||
sumo_actor = sumo.get_actor(sumo_actor_id)
|
||||
|
||||
sumo_transform = BridgeHelper.get_sumo_transform(carla_actor.get_transform(), carla_actor.bounding_box.extent)
|
||||
sumo_transform = BridgeHelper.get_sumo_transform(carla_actor.get_transform(),
|
||||
carla_actor.bounding_box.extent)
|
||||
if args.sync_vehicle_lights:
|
||||
carla_lights = carla.get_actor_light_state(carla_actor_id)
|
||||
if carla_lights is not None:
|
||||
sumo_lights = BridgeHelper.get_sumo_lights_state(sumo_actor.signals, carla_lights)
|
||||
sumo_lights = BridgeHelper.get_sumo_lights_state(
|
||||
sumo_actor.signals, carla_lights)
|
||||
else:
|
||||
sumo_lights = None
|
||||
else:
|
||||
|
@ -158,9 +170,6 @@ def main(args):
|
|||
except KeyboardInterrupt:
|
||||
logging.info('Cancelled by user.')
|
||||
|
||||
except Exception as error:
|
||||
logging.error('Synchronization failed. {}'.format(error))
|
||||
|
||||
finally:
|
||||
logging.info('Cleaning up synchronization')
|
||||
|
||||
|
@ -180,68 +189,49 @@ def main(args):
|
|||
# Closing sumo client.
|
||||
sumo.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
argparser = argparse.ArgumentParser(
|
||||
description=__doc__
|
||||
)
|
||||
argparser.add_argument(
|
||||
'--carla-host',
|
||||
metavar='H',
|
||||
default='127.0.0.1',
|
||||
help='IP of the carla host server (default: 127.0.0.1)'
|
||||
)
|
||||
argparser.add_argument(
|
||||
'--carla-port',
|
||||
metavar='P',
|
||||
default=2000,
|
||||
type=int,
|
||||
help='TCP port to listen to (default: 2000)'
|
||||
)
|
||||
argparser.add_argument(
|
||||
'--sumo-host',
|
||||
metavar='H',
|
||||
default=None,
|
||||
help='IP of the sumo host server (default: 127.0.0.1)'
|
||||
)
|
||||
argparser.add_argument(
|
||||
'--sumo-port',
|
||||
metavar='P',
|
||||
default=None,
|
||||
type=int,
|
||||
help='TCP port to liston to (default: 8813)'
|
||||
)
|
||||
argparser.add_argument(
|
||||
'-c', '--sumo-cfg-file',
|
||||
default=None,
|
||||
type=str,
|
||||
help='sumo configuration file'
|
||||
)
|
||||
argparser.add_argument(
|
||||
'--sumo-gui',
|
||||
default=True,
|
||||
help='run the gui version of sumo (default: True)'
|
||||
)
|
||||
argparser.add_argument(
|
||||
'--step-length',
|
||||
default=0.05,
|
||||
type=float,
|
||||
help='set fixed delta seconds (default: 0.05s)'
|
||||
)
|
||||
argparser = argparse.ArgumentParser(description=__doc__)
|
||||
argparser.add_argument('--carla-host',
|
||||
metavar='H',
|
||||
default='127.0.0.1',
|
||||
help='IP of the carla host server (default: 127.0.0.1)')
|
||||
argparser.add_argument('--carla-port',
|
||||
metavar='P',
|
||||
default=2000,
|
||||
type=int,
|
||||
help='TCP port to listen to (default: 2000)')
|
||||
argparser.add_argument('--sumo-host',
|
||||
metavar='H',
|
||||
default=None,
|
||||
help='IP of the sumo host server (default: 127.0.0.1)')
|
||||
argparser.add_argument('--sumo-port',
|
||||
metavar='P',
|
||||
default=None,
|
||||
type=int,
|
||||
help='TCP port to liston to (default: 8813)')
|
||||
argparser.add_argument('-c',
|
||||
'--sumo-cfg-file',
|
||||
default=None,
|
||||
type=str,
|
||||
help='sumo configuration file')
|
||||
argparser.add_argument('--sumo-gui',
|
||||
default=True,
|
||||
help='run the gui version of sumo (default: True)')
|
||||
argparser.add_argument('--step-length',
|
||||
default=0.05,
|
||||
type=float,
|
||||
help='set fixed delta seconds (default: 0.05s)')
|
||||
argparser.add_argument(
|
||||
'--sync-vehicle-lights',
|
||||
action='store_true',
|
||||
help='synchronize vehicle lights state between simulations (default: False)'
|
||||
)
|
||||
argparser.add_argument(
|
||||
'--debug',
|
||||
action='store_true',
|
||||
help='enable debug messages'
|
||||
)
|
||||
args = argparser.parse_args()
|
||||
help='synchronize vehicle lights state between simulations (default: False)')
|
||||
argparser.add_argument('--debug', action='store_true', help='enable debug messages')
|
||||
arguments = argparser.parse_args()
|
||||
|
||||
if args.debug:
|
||||
if arguments.debug:
|
||||
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.DEBUG)
|
||||
else:
|
||||
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
|
||||
|
||||
main(args)
|
||||
main(arguments)
|
||||
|
|
|
@ -6,38 +6,44 @@
|
|||
# This work is licensed under the terms of the MIT license.
|
||||
# For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
# ==============================================================================
|
||||
# -- imports -------------------------------------------------------------------
|
||||
# ==============================================================================
|
||||
""" This module provides a helper for the co-simulation between sumo and carla ."""
|
||||
|
||||
# ==================================================================================================
|
||||
# -- imports ---------------------------------------------------------------------------------------
|
||||
# ==================================================================================================
|
||||
|
||||
import json
|
||||
import logging
|
||||
import math
|
||||
import random
|
||||
|
||||
import carla
|
||||
import traci
|
||||
import carla # pylint: disable=import-error
|
||||
import traci # pylint: disable=import-error
|
||||
|
||||
from .sumo_simulation import SumoVehSignal
|
||||
|
||||
# ==============================================================================
|
||||
# -- Bridge helper (SUMO <=> CARLA) --------------------------------------------
|
||||
# ==============================================================================
|
||||
# ==================================================================================================
|
||||
# -- Bridge helper (SUMO <=> CARLA) ----------------------------------------------------------------
|
||||
# ==================================================================================================
|
||||
|
||||
|
||||
class BridgeHelper(object):
|
||||
"""
|
||||
BridgeHelper provides methos to ease the co-simulation between sumo and carla.
|
||||
"""
|
||||
|
||||
_blueprint_library = None
|
||||
_offset = (0, 0)
|
||||
blueprint_library = []
|
||||
offset = (0, 0)
|
||||
|
||||
with open('data/vtypes.json') as f:
|
||||
_VTYPES = json.load(f)['carla_blueprints']
|
||||
|
||||
@staticmethod
|
||||
def get_carla_transform(in_sumo_transform, extent):
|
||||
"""Returns carla transform based on sumo transform.
|
||||
"""
|
||||
offset = BridgeHelper._offset
|
||||
Returns carla transform based on sumo transform.
|
||||
"""
|
||||
offset = BridgeHelper.offset
|
||||
in_location = in_sumo_transform.location
|
||||
in_rotation = in_sumo_transform.rotation
|
||||
|
||||
|
@ -45,93 +51,80 @@ class BridgeHelper(object):
|
|||
# (http://sumo.sourceforge.net/userdoc/Purgatory/Vehicle_Values.html#angle)
|
||||
yaw = -1 * in_rotation.yaw + 90
|
||||
length = 2.0 * extent.x
|
||||
out_location = (
|
||||
in_location.x - math.cos(math.radians(yaw)) * (length / 2.0),
|
||||
in_location.y - math.sin(math.radians(yaw)) * (length / 2.0),
|
||||
in_location.z
|
||||
)
|
||||
out_location = (in_location.x - math.cos(math.radians(yaw)) * (length / 2.0),
|
||||
in_location.y - math.sin(math.radians(yaw)) * (length / 2.0), in_location.z)
|
||||
out_rotation = (in_rotation.pitch, in_rotation.yaw, in_rotation.roll)
|
||||
|
||||
# Applying offset sumo-carla net.
|
||||
out_location = (
|
||||
out_location[0] - offset[0],
|
||||
out_location[1] - offset[1],
|
||||
out_location[2]
|
||||
)
|
||||
out_rotation = out_rotation
|
||||
out_location = (out_location[0] - offset[0], out_location[1] - offset[1], out_location[2])
|
||||
|
||||
# Transform to carla reference system (left-handed system).
|
||||
return carla.Transform(
|
||||
carla.Location(out_location[0], -out_location[1], out_location[2]),
|
||||
carla.Rotation(out_rotation[0], out_rotation[1] - 90, out_rotation[2])
|
||||
)
|
||||
carla.Rotation(out_rotation[0], out_rotation[1] - 90, out_rotation[2]))
|
||||
|
||||
@staticmethod
|
||||
def get_sumo_transform(in_carla_transform, extent):
|
||||
"""Returns sumo transform based on carla transform.
|
||||
"""
|
||||
offset = BridgeHelper._offset
|
||||
Returns sumo transform based on carla transform.
|
||||
"""
|
||||
offset = BridgeHelper.offset
|
||||
in_location = in_carla_transform.location
|
||||
in_rotation = in_carla_transform.rotation
|
||||
|
||||
# From center to front-center-bumper (carla reference system).
|
||||
yaw = -1 * in_rotation.yaw
|
||||
length = 2.0 * extent.x
|
||||
out_location = (
|
||||
in_location.x + math.cos(math.radians(yaw)) * (length / 2.0),
|
||||
in_location.y - math.sin(math.radians(yaw)) * (length / 2.0),
|
||||
in_location.z
|
||||
)
|
||||
out_location = (in_location.x + math.cos(math.radians(yaw)) * (length / 2.0),
|
||||
in_location.y - math.sin(math.radians(yaw)) * (length / 2.0), in_location.z)
|
||||
out_rotation = (in_rotation.pitch, in_rotation.yaw, in_rotation.roll)
|
||||
|
||||
# Applying offset carla-sumo net
|
||||
out_location = (
|
||||
out_location[0] + offset[0],
|
||||
out_location[1] - offset[1],
|
||||
out_location[2]
|
||||
)
|
||||
out_rotation = out_rotation
|
||||
out_location = (out_location[0] + offset[0], out_location[1] - offset[1], out_location[2])
|
||||
|
||||
# Transform to sumo reference system.
|
||||
return carla.Transform(
|
||||
carla.Location(out_location[0], -out_location[1], out_location[2]),
|
||||
carla.Rotation(out_rotation[0], out_rotation[1] + 90, out_rotation[2])
|
||||
)
|
||||
carla.Rotation(out_rotation[0], out_rotation[1] + 90, out_rotation[2]))
|
||||
|
||||
@staticmethod
|
||||
def _get_recommended_carla_blueprint(sumo_actor):
|
||||
"""Returns an appropriate blueprint based on the given sumo actor.
|
||||
"""
|
||||
Returns an appropriate blueprint based on the given sumo actor.
|
||||
"""
|
||||
vclass = sumo_actor.vclass.value
|
||||
|
||||
blueprints = []
|
||||
for blueprint in BridgeHelper._blueprint_library:
|
||||
for blueprint in BridgeHelper.blueprint_library:
|
||||
if blueprint.id in BridgeHelper._VTYPES and \
|
||||
BridgeHelper._VTYPES[blueprint.id]['vClass'] == vclass:
|
||||
blueprints.append(blueprint)
|
||||
|
||||
if len(blueprints) == 0:
|
||||
if not blueprints:
|
||||
return None
|
||||
|
||||
return random.choice(blueprints)
|
||||
|
||||
@staticmethod
|
||||
def get_carla_blueprint(sumo_actor):
|
||||
"""Returns an appropriate blueprint based on the received sumo actor.
|
||||
"""
|
||||
blueprint_library = BridgeHelper._blueprint_library
|
||||
Returns an appropriate blueprint based on the received sumo actor.
|
||||
"""
|
||||
blueprint_library = BridgeHelper.blueprint_library
|
||||
type_id = sumo_actor.type_id
|
||||
|
||||
if type_id in [bp.id for bp in blueprint_library]:
|
||||
blueprint = blueprint_library.filter(type_id)[0]
|
||||
logging.debug('[BridgeHelper] sumo vtype {} found in carla blueprints'.format(type_id))
|
||||
logging.debug('[BridgeHelper] sumo vtype %s found in carla blueprints', type_id)
|
||||
else:
|
||||
blueprint = BridgeHelper._get_recommended_carla_blueprint(sumo_actor)
|
||||
if blueprint is not None:
|
||||
logging.warning(
|
||||
'sumo vtype {} not found in carla blueprints. The following blueprint will be used: {}'.format(type_id, blueprint.id))
|
||||
'sumo vtype %s not found in carla. The following blueprint will be used: %s'
|
||||
, type_id, blueprint.id)
|
||||
else:
|
||||
logging.error('sumo vtype {} not supported. No vehicle will be spawned in carla'.format(type_id))
|
||||
logging.error(
|
||||
'sumo vtype %s not supported. No vehicle will be spawned in carla', type_id)
|
||||
return None
|
||||
|
||||
if blueprint.has_attribute('color'):
|
||||
|
@ -139,26 +132,23 @@ class BridgeHelper(object):
|
|||
blueprint.set_attribute('color', color)
|
||||
|
||||
if blueprint.has_attribute('driver_id'):
|
||||
driver_id = random.choice(
|
||||
blueprint.get_attribute('driver_id').recommended_values)
|
||||
driver_id = random.choice(blueprint.get_attribute('driver_id').recommended_values)
|
||||
blueprint.set_attribute('driver_id', driver_id)
|
||||
|
||||
blueprint.set_attribute('role_name', 'sumo_driver')
|
||||
|
||||
logging.debug('''[BridgeHelper] sumo vtype {vtype} will be spawned in carla with the following attributes:
|
||||
\tblueprint: {bp_id:}
|
||||
\tcolor: {color:}'''.format(
|
||||
vtype=type_id,
|
||||
bp_id=blueprint.id,
|
||||
color=sumo_actor.color if blueprint.has_attribute('color') else (-1, -1, -1)
|
||||
)
|
||||
)
|
||||
logging.debug(
|
||||
'''[BridgeHelper] sumo vtype %s will be spawned in carla with the following attributes:
|
||||
\tblueprint: %s
|
||||
\tcolor: %s''', type_id, blueprint.id,
|
||||
sumo_actor.color if blueprint.has_attribute('color') else (-1, -1, -1))
|
||||
|
||||
return blueprint
|
||||
|
||||
@staticmethod
|
||||
def _create_sumo_vtype(carla_actor):
|
||||
"""Creates an appropriate vtype based on the given carla_actor.
|
||||
"""
|
||||
Creates an appropriate vtype based on the given carla_actor.
|
||||
"""
|
||||
type_id = carla_actor.type_id
|
||||
attrs = carla_actor.attributes
|
||||
|
@ -186,47 +176,46 @@ class BridgeHelper(object):
|
|||
traci.vehicletype.setWidth(type_id, 2.0 * extent.y)
|
||||
traci.vehicletype.setHeight(type_id, 2.0 * extent.z)
|
||||
|
||||
logging.debug('''[BridgeHelper] blueprint{bp_id} not found in sumo vtypes
|
||||
\tdefault vtype: {dvtype:}
|
||||
\tvtype: {vtype:}
|
||||
\tclass: {_class:}
|
||||
\tshape: {shape:}
|
||||
\tcolor: {color:}
|
||||
\tlenght: {lenght:}
|
||||
\twidth: {width:}
|
||||
\theight: {height:}'''.format(
|
||||
bp_id=type_id,
|
||||
dvtype='DEFAULT_BIKETYPE' if int(attrs['number_of_wheels']) == 2 else 'DEFAULT_VEHTYPE',
|
||||
vtype=type_id,
|
||||
_class=traci.vehicletype.getVehicleClass(type_id),
|
||||
shape=traci.vehicletype.getShapeClass(type_id),
|
||||
color=traci.vehicletype.getColor(type_id),
|
||||
lenght=traci.vehicletype.getLength(type_id),
|
||||
width=traci.vehicletype.getWidth(type_id),
|
||||
height=traci.vehicletype.getHeight(type_id)
|
||||
)
|
||||
)
|
||||
logging.debug(
|
||||
'''[BridgeHelper] blueprint %s not found in sumo vtypes
|
||||
\tdefault vtype: %s
|
||||
\tvtype: %s
|
||||
\tclass: %s
|
||||
\tshape: %s
|
||||
\tcolor: %s
|
||||
\tlenght: %s
|
||||
\twidth: %s
|
||||
\theight: %s''', type_id,
|
||||
'DEFAULT_BIKETYPE' if int(attrs['number_of_wheels']) == 2 else 'DEFAULT_VEHTYPE',
|
||||
type_id, traci.vehicletype.getVehicleClass(type_id),
|
||||
traci.vehicletype.getShapeClass(type_id), traci.vehicletype.getColor(type_id),
|
||||
traci.vehicletype.getLength(type_id), traci.vehicletype.getWidth(type_id),
|
||||
traci.vehicletype.getHeight(type_id))
|
||||
|
||||
return type_id
|
||||
|
||||
@staticmethod
|
||||
def get_sumo_vtype(carla_actor):
|
||||
"""Returns an appropriate vtype based on the type id and attributes.
|
||||
"""
|
||||
Returns an appropriate vtype based on the type id and attributes.
|
||||
"""
|
||||
type_id = carla_actor.type_id
|
||||
|
||||
if not type_id.startswith('vehicle'):
|
||||
logging.error('[BridgeHelper] Blueprint {} not supported. No vehicle will be spawned in sumo'.format(type_id))
|
||||
logging.error(
|
||||
'[BridgeHelper] Blueprint %s not supported. No vehicle will be spawned in sumo',
|
||||
type_id)
|
||||
return None
|
||||
|
||||
if type_id in traci.vehicletype.getIDList():
|
||||
logging.debug('[BridgeHelper] blueprint {} found in sumo vtypes'.format(type_id))
|
||||
logging.debug('[BridgeHelper] blueprint %s found in sumo vtypes', type_id)
|
||||
return type_id
|
||||
return BridgeHelper._create_sumo_vtype(carla_actor)
|
||||
|
||||
@staticmethod
|
||||
def get_carla_lights_state(current_carla_lights, sumo_lights):
|
||||
"""Returns carla vehicle light state based on sumo signals.
|
||||
"""
|
||||
Returns carla vehicle light state based on sumo signals.
|
||||
"""
|
||||
current_lights = current_carla_lights
|
||||
|
||||
|
@ -280,7 +269,8 @@ class BridgeHelper(object):
|
|||
|
||||
@staticmethod
|
||||
def get_sumo_lights_state(current_sumo_lights, carla_lights):
|
||||
"""Returns sumo signals based on carla vehicle light state.
|
||||
"""
|
||||
Returns sumo signals based on carla vehicle light state.
|
||||
"""
|
||||
current_lights = current_sumo_lights
|
||||
|
||||
|
@ -326,4 +316,4 @@ class BridgeHelper(object):
|
|||
bool(current_lights & SumoVehSignal.BACKDRIVE)):
|
||||
current_lights ^= SumoVehSignal.BACKDRIVE
|
||||
|
||||
return current_lights
|
||||
return current_lights
|
||||
|
|
|
@ -6,32 +6,34 @@
|
|||
# This work is licensed under the terms of the MIT license.
|
||||
# For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
# ==============================================================================
|
||||
# -- imports -------------------------------------------------------------------
|
||||
# ==============================================================================
|
||||
""" This module is responsible for the management of the carla simulation. """
|
||||
|
||||
# ==================================================================================================
|
||||
# -- imports ---------------------------------------------------------------------------------------
|
||||
# ==================================================================================================
|
||||
|
||||
import logging
|
||||
|
||||
import carla
|
||||
SpawnActor = carla.command.SpawnActor
|
||||
FutureActor = carla.command.FutureActor
|
||||
SetSimulatePhysics = carla.command.SetSimulatePhysics
|
||||
import carla # pylint: disable=import-error
|
||||
|
||||
from .constants import *
|
||||
from .constants import INVALID_ACTOR_ID, SPAWN_OFFSET_Z
|
||||
|
||||
# ==============================================================================
|
||||
# -- carla simulation ----------------------------------------------------------
|
||||
# ==============================================================================
|
||||
# ==================================================================================================
|
||||
# -- carla simulation ------------------------------------------------------------------------------
|
||||
# ==================================================================================================
|
||||
|
||||
|
||||
class CarlaSimulation(object):
|
||||
"""
|
||||
CarlaSimulation is responsible for the management of the carla simulation.
|
||||
"""
|
||||
|
||||
def __init__(self, args):
|
||||
self.args = args
|
||||
self.host = args.carla_host
|
||||
self.port = args.carla_port
|
||||
self.step_length = args.step_length
|
||||
host = args.carla_host
|
||||
port = args.carla_port
|
||||
|
||||
self.client = carla.Client(self.host, self.port)
|
||||
self.client = carla.Client(host, port)
|
||||
self.client.set_timeout(2.0)
|
||||
|
||||
self.world = self.client.get_world()
|
||||
|
@ -40,7 +42,7 @@ class CarlaSimulation(object):
|
|||
# Configuring carla simulation in sync mode.
|
||||
settings = self.world.get_settings()
|
||||
settings.synchronous_mode = True
|
||||
settings.fixed_delta_seconds = self.step_length
|
||||
settings.fixed_delta_seconds = args.step_length
|
||||
self.world.apply_settings(settings)
|
||||
|
||||
# The following sets contain updated information for the current frame.
|
||||
|
@ -49,12 +51,20 @@ class CarlaSimulation(object):
|
|||
self.destroyed_actors = set()
|
||||
|
||||
def get_actor(self, actor_id):
|
||||
"""
|
||||
Accessor for carla actor.
|
||||
"""
|
||||
return self.world.get_actor(actor_id)
|
||||
|
||||
# This is a workaround to fix synchronization issues when other carla
|
||||
# clients remove an actor in carla without waiting for tick (e.g.,
|
||||
# running sumo co-simulation and manual control at the same time)
|
||||
def get_actor_light_state(self, actor_id):
|
||||
"""
|
||||
Accessor for carla actor light state.
|
||||
|
||||
If the actor is not alive, returns None.
|
||||
"""
|
||||
try:
|
||||
actor = self.get_actor(actor_id)
|
||||
return actor.get_light_state()
|
||||
|
@ -62,30 +72,46 @@ class CarlaSimulation(object):
|
|||
return None
|
||||
|
||||
def spawn_actor(self, blueprint, transform):
|
||||
"""Spawns a new actor.
|
||||
"""
|
||||
Spawns a new actor.
|
||||
|
||||
:param blueprint: blueprint of the actor to be spawned.
|
||||
:param transform: transform where the actor will be spawned.
|
||||
:return: actor id if the actor is successfully spawned. Otherwise, INVALID_ACTOR_ID.
|
||||
"""
|
||||
transform = carla.Transform(
|
||||
transform.location + carla.Location(0, 0, SPAWN_OFFSET_Z),
|
||||
transform.rotation)
|
||||
|
||||
batch = [
|
||||
SpawnActor(blueprint,transform)
|
||||
.then(SetSimulatePhysics(FutureActor, False))
|
||||
carla.command.SpawnActor(blueprint, transform)
|
||||
.then(carla.command.SetSimulatePhysics(carla.command.FutureActor, False))
|
||||
]
|
||||
response = self.client.apply_batch_sync(batch, True)[0]
|
||||
if response.error:
|
||||
logging.error('Spawn carla actor failed. {}'.format(response.error))
|
||||
logging.error('Spawn carla actor failed. %s', response.error)
|
||||
return INVALID_ACTOR_ID
|
||||
else:
|
||||
return response.actor_id
|
||||
|
||||
return response.actor_id
|
||||
|
||||
def destroy_actor(self, actor_id):
|
||||
"""
|
||||
Destroys the given actor.
|
||||
"""
|
||||
actor = self.world.get_actor(actor_id)
|
||||
if actor is not None:
|
||||
return actor.destroy()
|
||||
return False
|
||||
|
||||
def synchronize_vehicle(self, vehicle_id, transform, lights=None):
|
||||
"""
|
||||
Updates vehicle state.
|
||||
|
||||
:param vehicle_id: id of the actor to be updated.
|
||||
:param transform: new vehicle transform (i.e., position and rotation).
|
||||
:param lights: new vehicle light state.
|
||||
:return: True if successfully updated. Otherwise, False.
|
||||
"""
|
||||
vehicle = self.world.get_actor(vehicle_id)
|
||||
if vehicle is None:
|
||||
return False
|
||||
|
@ -93,11 +119,12 @@ class CarlaSimulation(object):
|
|||
vehicle.set_transform(transform)
|
||||
if lights is not None and self.args.sync_vehicle_lights:
|
||||
vehicle.set_light_state(carla.VehicleLightState(lights))
|
||||
|
||||
def synchronize_walker(self, walker_id, transform):
|
||||
pass
|
||||
return True
|
||||
|
||||
def tick(self):
|
||||
"""
|
||||
Tick to carla simulation.
|
||||
"""
|
||||
self.world.tick()
|
||||
|
||||
# Update data structures for the current frame.
|
||||
|
@ -106,4 +133,4 @@ class CarlaSimulation(object):
|
|||
])
|
||||
self.spawned_actors = current_actors.difference(self._active_actors)
|
||||
self.destroyed_actors = self._active_actors.difference(current_actors)
|
||||
self._active_actors = current_actors
|
||||
self._active_actors = current_actors
|
||||
|
|
|
@ -6,9 +6,11 @@
|
|||
# This work is licensed under the terms of the MIT license.
|
||||
# For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
# ==============================================================================
|
||||
# -- constants -----------------------------------------------------------------
|
||||
# ==============================================================================
|
||||
""" This module defines constants used for the sumo-carla co-simulation. """
|
||||
|
||||
# ==================================================================================================
|
||||
# -- constants -------------------------------------------------------------------------------------
|
||||
# ==================================================================================================
|
||||
|
||||
INVALID_ACTOR_ID = -1
|
||||
SPAWN_OFFSET_Z = 5.0 # meters
|
||||
SPAWN_OFFSET_Z = 5.0 # meters
|
||||
|
|
|
@ -6,28 +6,32 @@
|
|||
# This work is licensed under the terms of the MIT license.
|
||||
# For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
# ==============================================================================
|
||||
# -- imports -------------------------------------------------------------------
|
||||
# ==============================================================================
|
||||
""" This module is responsible for the management of the sumo simulation. """
|
||||
|
||||
# ==================================================================================================
|
||||
# -- imports ---------------------------------------------------------------------------------------
|
||||
# ==================================================================================================
|
||||
|
||||
import collections
|
||||
import enum
|
||||
import logging
|
||||
|
||||
import carla
|
||||
import sumolib
|
||||
import traci
|
||||
import carla # pylint: disable=import-error
|
||||
import sumolib # pylint: disable=import-error
|
||||
import traci # pylint: disable=import-error
|
||||
|
||||
from .constants import *
|
||||
from .constants import INVALID_ACTOR_ID
|
||||
|
||||
# ==============================================================================
|
||||
# -- sumo definitions ----------------------------------------------------------
|
||||
# ==============================================================================
|
||||
# ==================================================================================================
|
||||
# -- sumo definitions ------------------------------------------------------------------------------
|
||||
# ==================================================================================================
|
||||
|
||||
|
||||
# Sumo vehicle signals.
|
||||
# https://sumo.dlr.de/docs/TraCI/Vehicle_Signalling.html
|
||||
class SumoVehSignal(object):
|
||||
"""
|
||||
SumoVehSignal contains the different sumo vehicle signals.
|
||||
"""
|
||||
BLINKER_RIGHT = 1 << 0
|
||||
BLINKER_LEFT = 1 << 1
|
||||
BLINKER_EMERGENCY = 1 << 2
|
||||
|
@ -46,6 +50,9 @@ class SumoVehSignal(object):
|
|||
|
||||
# https://sumo.dlr.de/docs/Definition_of_Vehicles,_Vehicle_Types,_and_Routes.html#abstract_vehicle_class
|
||||
class SumoActorClass(enum.Enum):
|
||||
"""
|
||||
SumoActorClass enumerates the different sumo actor classes.
|
||||
"""
|
||||
IGNORING = "ignoring"
|
||||
PRIVATE = "private"
|
||||
EMERGENCY = "emergency"
|
||||
|
@ -84,13 +91,16 @@ SumoActor = collections.namedtuple(
|
|||
|
||||
|
||||
class SumoSimulation(object):
|
||||
"""
|
||||
SumoSimulation is responsible for the management of the sumo simulation.
|
||||
"""
|
||||
|
||||
def __init__(self, args):
|
||||
self.args = args
|
||||
self.host = args.sumo_host
|
||||
self.port = args.sumo_port
|
||||
host = args.sumo_host
|
||||
port = args.sumo_port
|
||||
|
||||
self.sumo_gui = args.sumo_gui
|
||||
if self.sumo_gui is True:
|
||||
if args.sumo_gui is True:
|
||||
sumo_binary = sumolib.checkBinary('sumo-gui')
|
||||
else:
|
||||
sumo_binary = sumolib.checkBinary('sumo')
|
||||
|
@ -105,11 +115,11 @@ class SumoSimulation(object):
|
|||
'--collision.check-junctions'
|
||||
])
|
||||
|
||||
if self.sumo_gui:
|
||||
if args.sumo_gui:
|
||||
logging.info('Remember to press the play button to start the simulation')
|
||||
else:
|
||||
logging.info('Connection to sumo server. Host: {} Port: {}'.format(self.host, self.port))
|
||||
traci.init(host=self.host, port=self.port)
|
||||
logging.info('Connection to sumo server. Host: %s Port: %s', host, port)
|
||||
traci.init(host=host, port=port)
|
||||
|
||||
# Structures to keep track of the spawned and destroyed vehicles at each time step.
|
||||
self.spawned_actors = set()
|
||||
|
@ -123,6 +133,19 @@ class SumoSimulation(object):
|
|||
|
||||
@staticmethod
|
||||
def subscribe(actor_id):
|
||||
"""
|
||||
Subscribe the given actor to the following variables:
|
||||
|
||||
* Type.
|
||||
* Vehicle class.
|
||||
* Color.
|
||||
* Length, Width, Height.
|
||||
* Position3D (i.e., x, y, z).
|
||||
* Angle, Slope.
|
||||
* Speed.
|
||||
* Lateral speed.
|
||||
* Signals.
|
||||
"""
|
||||
traci.vehicle.subscribe(actor_id, [
|
||||
traci.constants.VAR_TYPE, traci.constants.VAR_VEHICLECLASS,
|
||||
traci.constants.VAR_COLOR, traci.constants.VAR_LENGTH,
|
||||
|
@ -134,16 +157,28 @@ class SumoSimulation(object):
|
|||
|
||||
@staticmethod
|
||||
def unsubscribe(actor_id):
|
||||
"""
|
||||
Unsubscribe the given actor from receiving updated information each step.
|
||||
"""
|
||||
traci.vehicle.unsubscribe(actor_id)
|
||||
|
||||
def get_net_offset(self):
|
||||
"""
|
||||
Accessor for sumo net offset.
|
||||
"""
|
||||
offset = traci.simulation.convertGeo(0, 0)
|
||||
return (-offset[0], -offset[1])
|
||||
|
||||
def get_step_length(self):
|
||||
"""
|
||||
Accessor for sumo simulation step length.
|
||||
"""
|
||||
return traci.simulation.getDeltaT()
|
||||
|
||||
def get_actor(self, actor_id):
|
||||
"""
|
||||
Accessor for sumo actor.
|
||||
"""
|
||||
results = traci.vehicle.getSubscriptionResults(actor_id)
|
||||
|
||||
type_id = results[traci.constants.VAR_TYPE]
|
||||
|
@ -169,39 +204,57 @@ class SumoSimulation(object):
|
|||
|
||||
return SumoActor(type_id, vclass, transform, signals, extent, color)
|
||||
|
||||
def spawn_actor(self, type_id, attrs={}):
|
||||
"""Spawns a new actor based on given type.
|
||||
def spawn_actor(self, type_id, attrs=None):
|
||||
"""
|
||||
Spawns a new actor.
|
||||
|
||||
:param type_id: vtype to be spawned.
|
||||
:param attrs: dictionary with additional attributes for this specific actor.
|
||||
:return: actor id if the actor is successfully spawned. Otherwise, INVALID_ACTOR_ID.
|
||||
"""
|
||||
actor_id = 'carla' + str(self._sequential_id)
|
||||
try:
|
||||
traci.vehicle.add(actor_id, 'carla_route', typeID=type_id)
|
||||
except Exception as error:
|
||||
logging.error('Spawn sumo actor failed: {}'.format(error))
|
||||
except traci.exceptions.TraCIException as error:
|
||||
logging.error('Spawn sumo actor failed: %s', error)
|
||||
return INVALID_ACTOR_ID
|
||||
|
||||
if 'color' in attrs:
|
||||
color = attrs['color'].split(',')
|
||||
traci.vehicle.setColor(actor_id, color)
|
||||
if attrs is not None:
|
||||
if 'color' in attrs:
|
||||
color = attrs['color'].split(',')
|
||||
traci.vehicle.setColor(actor_id, color)
|
||||
|
||||
self._sequential_id += 1
|
||||
|
||||
return actor_id
|
||||
|
||||
def destroy_actor(self, actor_id):
|
||||
"""
|
||||
Destroys the given actor.
|
||||
"""
|
||||
traci.vehicle.remove(actor_id)
|
||||
|
||||
def synchronize_vehicle(self, vehicle_id, transform, signals=None):
|
||||
x, y = transform.location.x, transform.location.y
|
||||
"""
|
||||
Updates vehicle state.
|
||||
|
||||
:param vehicle_id: id of the actor to be updated.
|
||||
:param transform: new vehicle transform (i.e., position and rotation).
|
||||
:param signals: new vehicle signals.
|
||||
:return: True if successfully updated. Otherwise, False.
|
||||
"""
|
||||
loc_x, loc_y = transform.location.x, transform.location.y
|
||||
yaw = transform.rotation.yaw
|
||||
|
||||
traci.vehicle.moveToXY(vehicle_id, "", 0, x, y, angle=yaw, keepRoute=2)
|
||||
traci.vehicle.moveToXY(vehicle_id, "", 0, loc_x, loc_y, angle=yaw, keepRoute=2)
|
||||
if signals is not None and self.args.sync_vehicle_lights:
|
||||
traci.vehicle.setSignals(vehicle_id, signals)
|
||||
|
||||
def synchronize_walker(self, walker_id, transform):
|
||||
pass
|
||||
return True
|
||||
|
||||
def tick(self):
|
||||
"""
|
||||
Tick to sumo simulation.
|
||||
"""
|
||||
traci.simulationStep()
|
||||
|
||||
# Update data structures for the current frame.
|
||||
|
@ -209,4 +262,7 @@ class SumoSimulation(object):
|
|||
self.destroyed_actors = set(traci.simulation.getArrivedIDList())
|
||||
|
||||
def close(self):
|
||||
traci.close()
|
||||
"""
|
||||
Closes traci client.
|
||||
"""
|
||||
traci.close()
|
||||
|
|
|
@ -10,37 +10,38 @@
|
|||
Script to create sumo vtypes based on carla blueprints.
|
||||
"""
|
||||
|
||||
# ==============================================================================
|
||||
# -- find carla module ---------------------------------------------------------
|
||||
# ==============================================================================
|
||||
|
||||
import glob
|
||||
import os
|
||||
import sys
|
||||
|
||||
try:
|
||||
sys.path.append(glob.glob('../../../PythonAPI/carla/dist/carla-*%d.%d-%s.egg' % (
|
||||
sys.version_info.major,
|
||||
sys.version_info.minor,
|
||||
'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
# ==============================================================================
|
||||
# -- imports -------------------------------------------------------------------
|
||||
# ==============================================================================
|
||||
|
||||
import carla
|
||||
# ==================================================================================================
|
||||
# -- imports ---------------------------------------------------------------------------------------
|
||||
# ==================================================================================================
|
||||
|
||||
import argparse
|
||||
import glob
|
||||
import datetime
|
||||
import json
|
||||
import logging
|
||||
import lxml.etree as ET
|
||||
import os
|
||||
import sys
|
||||
|
||||
# ==============================================================================
|
||||
# -- load specs definition -----------------------------------------------------
|
||||
# ==============================================================================
|
||||
import lxml.etree as ET # pylint: disable=import-error
|
||||
|
||||
# ==================================================================================================
|
||||
# -- find carla module -----------------------------------------------------------------------------
|
||||
# ==================================================================================================
|
||||
|
||||
try:
|
||||
sys.path.append(
|
||||
glob.glob('../../../PythonAPI/carla/dist/carla-*%d.%d-%s.egg' %
|
||||
(sys.version_info.major, sys.version_info.minor,
|
||||
'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
import carla # pylint: disable=import-error, wrong-import-position
|
||||
|
||||
|
||||
# ==================================================================================================
|
||||
# -- load specs definition -------------------------------------------------------------------------
|
||||
# ==================================================================================================
|
||||
|
||||
with open('../data/vtypes.json') as f:
|
||||
SPECS = json.load(f)
|
||||
|
@ -49,19 +50,20 @@ with open('../data/vtypes.json') as f:
|
|||
DEFAULT_WHEELED_VEHICLE = SPECS['DEFAULT_WHEELED_VEHICLE']
|
||||
CARLA_BLUEPRINTS_SPECS = SPECS['carla_blueprints']
|
||||
|
||||
# ==============================================================================
|
||||
# -- main ----------------------------------------------------------------------
|
||||
# ==============================================================================
|
||||
# ==================================================================================================
|
||||
# -- main ------------------------------------------------------------------------------------------
|
||||
# ==================================================================================================
|
||||
|
||||
|
||||
def write_vtype_xml(filename, vtypes):
|
||||
"""
|
||||
Write route xml file.
|
||||
"""
|
||||
root = ET.Element('routes')
|
||||
|
||||
root.addprevious(ET.Comment(
|
||||
'generated on {date:%Y-%m-%d %H:%M:%S} by {script:}'.format(
|
||||
date=datetime.datetime.now(),
|
||||
script=os.path.basename(__file__))
|
||||
)
|
||||
)
|
||||
root.addprevious(
|
||||
ET.Comment('generated on {date:%Y-%m-%d %H:%M:%S} by {script:}'.format(
|
||||
date=datetime.datetime.now(), script=os.path.basename(__file__))))
|
||||
|
||||
for vtype in vtypes:
|
||||
ET.SubElement(root, 'vType', vtype)
|
||||
|
@ -69,6 +71,7 @@ def write_vtype_xml(filename, vtypes):
|
|||
tree = ET.ElementTree(root)
|
||||
tree.write(filename, pretty_print=True, encoding='UTF-8', xml_declaration=True)
|
||||
|
||||
|
||||
def generate_vtype(vehicle):
|
||||
"""Generates sumo vtype specification for a given carla vehicle.
|
||||
|
||||
|
@ -80,23 +83,21 @@ def generate_vtype(vehicle):
|
|||
if type_id not in CARLA_BLUEPRINTS_SPECS:
|
||||
number_of_wheels = int(vehicle.attributes['number_of_wheels'])
|
||||
if number_of_wheels == 2:
|
||||
logging.warning('type id {id:} not mapped to any sumo vtype. Using default specification for two-wheeled vehicles: {specs:}'.format(
|
||||
id=type_id,
|
||||
specs=DEFAULT_2_WHEELED_VEHICLE)
|
||||
)
|
||||
logging.warning(
|
||||
'''type id %s not mapped to any sumo vtype.
|
||||
\tUsing default specification for two-wheeled vehicles: %s''', type_id,
|
||||
DEFAULT_2_WHEELED_VEHICLE)
|
||||
user_specs = DEFAULT_2_WHEELED_VEHICLE
|
||||
else:
|
||||
logging.warning('type id {id:} not mapped to any sumo vtype. Using default specification for wheeled vehicles: {specs:}'.format(
|
||||
id=type_id,
|
||||
specs=DEFAULT_WHEELED_VEHICLE)
|
||||
)
|
||||
logging.warning(
|
||||
'''type id %s not mapped to any sumo vtype.
|
||||
\tUsing default specification for wheeled vehicles: %s''', type_id,
|
||||
DEFAULT_WHEELED_VEHICLE)
|
||||
user_specs = DEFAULT_WHEELED_VEHICLE
|
||||
|
||||
else:
|
||||
logging.info('type id {id:} mapped to the following specifications: {specs:}'.format(
|
||||
id=type_id,
|
||||
specs=CARLA_BLUEPRINTS_SPECS[type_id])
|
||||
)
|
||||
logging.info('type id %s mapped to the following specifications: %s', type_id,
|
||||
CARLA_BLUEPRINTS_SPECS[type_id])
|
||||
user_specs = CARLA_BLUEPRINTS_SPECS[type_id]
|
||||
|
||||
specs = {
|
||||
|
@ -109,27 +110,32 @@ def generate_vtype(vehicle):
|
|||
specs.update(user_specs)
|
||||
return specs
|
||||
|
||||
|
||||
def main(args):
|
||||
"""
|
||||
Main method.
|
||||
"""
|
||||
client = carla.Client(args.carla_host, args.carla_port)
|
||||
client.set_timeout(2.0)
|
||||
|
||||
try:
|
||||
world = client.get_world()
|
||||
vehicle_blueprints = world.get_blueprint_library().filter('vehicle.*')
|
||||
#walker_blueprints = world.get_blueprint_library().filter('walker.pedestrian.*')
|
||||
#walker_blueprints = world.get_blueprint_library().filter('walker.pedestrian.*')
|
||||
|
||||
transform = world.get_map().get_spawn_points()[0]
|
||||
|
||||
vtypes = []
|
||||
for blueprint in vehicle_blueprints:
|
||||
logging.info('processing vtype for {}'.format(blueprint.id))
|
||||
logging.info('processing vtype for %s', blueprint.id)
|
||||
vehicle = world.spawn_actor(blueprint, transform)
|
||||
|
||||
vtype = generate_vtype(vehicle)
|
||||
if vtype:
|
||||
vtypes.append(vtype)
|
||||
else:
|
||||
logging.error('type id {id:} could no be mapped to any vtype'.format(id=vehicle.type_id))
|
||||
logging.error(
|
||||
'type id %s could no be mapped to any vtype', vehicle.type_id)
|
||||
|
||||
vehicle.destroy()
|
||||
|
||||
|
@ -138,37 +144,32 @@ def main(args):
|
|||
finally:
|
||||
logging.info('done')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Define arguments that will be received and parsed.
|
||||
argparser = argparse.ArgumentParser(
|
||||
description=__doc__)
|
||||
argparser = argparse.ArgumentParser(description=__doc__)
|
||||
argparser.add_argument('--carla-host',
|
||||
metavar='H',
|
||||
default='127.0.0.1',
|
||||
help='IP of the host server (default: 127.0.0.1)')
|
||||
argparser.add_argument('--carla-port',
|
||||
metavar='P',
|
||||
default=2000,
|
||||
type=int,
|
||||
help='TCP port to listen to (default: 2000)')
|
||||
argparser.add_argument(
|
||||
'--carla-host',
|
||||
metavar='H',
|
||||
default='127.0.0.1',
|
||||
help='IP of the host server (default: 127.0.0.1)')
|
||||
argparser.add_argument(
|
||||
'--carla-port',
|
||||
metavar='P',
|
||||
default=2000,
|
||||
type=int,
|
||||
help='TCP port to listen to (default: 2000)')
|
||||
argparser.add_argument(
|
||||
'--output-file', '-o',
|
||||
'--output-file',
|
||||
'-o',
|
||||
metavar='FILE',
|
||||
default='carlavtypes.rou.xml',
|
||||
type=str,
|
||||
help='the generated vtypes will be written to FILE (default: carlavtypes.rou.xml)')
|
||||
argparser.add_argument(
|
||||
'--verbose', '-v',
|
||||
action='store_true',
|
||||
help='increase output verbosity'
|
||||
)
|
||||
args = argparser.parse_args()
|
||||
argparser.add_argument('--verbose', '-v', action='store_true', help='increase output verbosity')
|
||||
arguments = argparser.parse_args()
|
||||
|
||||
if args.verbose:
|
||||
if arguments.verbose:
|
||||
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
|
||||
else:
|
||||
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.WARNING)
|
||||
|
||||
main(args)
|
||||
main(arguments)
|
||||
|
|
|
@ -10,29 +10,33 @@
|
|||
Script to modify automatically vtypes to carla type ids in sumo route files.
|
||||
"""
|
||||
|
||||
# ==============================================================================
|
||||
# -- imports -------------------------------------------------------------------
|
||||
# ==============================================================================
|
||||
# ==================================================================================================
|
||||
# -- imports ---------------------------------------------------------------------------------------
|
||||
# ==================================================================================================
|
||||
|
||||
import argparse
|
||||
import fnmatch
|
||||
import json
|
||||
import logging
|
||||
import lxml.etree as ET
|
||||
import random
|
||||
|
||||
# ==============================================================================
|
||||
# -- load vtypes ---------------------------------------------------------------
|
||||
# ==============================================================================
|
||||
import lxml.etree as ET # pylint: disable=import-error
|
||||
|
||||
with open('../data/vtypes.json') as f:
|
||||
# ==================================================================================================
|
||||
# -- load vtypes -----------------------------------------------------------------------------------
|
||||
# ==================================================================================================
|
||||
|
||||
with open('../data/vtypes.json') as f:
|
||||
VTYPES = json.load(f)['carla_blueprints'].keys()
|
||||
|
||||
# ==============================================================================
|
||||
# -- main ----------------------------------------------------------------------
|
||||
# ==============================================================================
|
||||
# ==================================================================================================
|
||||
# -- main ------------------------------------------------------------------------------------------
|
||||
# ==================================================================================================
|
||||
|
||||
def main(route_files, vtypes, _random=False):
|
||||
"""
|
||||
Main method to automatically modify vtypes to carla type ids in sumo route files.
|
||||
"""
|
||||
for filename in route_files:
|
||||
tree = ET.parse(filename)
|
||||
root = tree.getroot()
|
||||
|
@ -46,47 +50,34 @@ def main(route_files, vtypes, _random=False):
|
|||
new_type = random.choice(vtypes)
|
||||
else:
|
||||
new_type = vtypes[index]
|
||||
index = (index + 1) if index < (len(vtypes) - 1) else 0
|
||||
|
||||
index = (index + 1) if index < (len(vtypes) - 1) else 0
|
||||
|
||||
vtype.set('type', new_type)
|
||||
counter += 1
|
||||
|
||||
tree = ET.ElementTree(root)
|
||||
tree.write(filename, pretty_print=True, encoding='UTF-8', xml_declaration=True)
|
||||
|
||||
logging.info('modified {counter:} vtype(s) in {file:}'.format(
|
||||
counter=counter,
|
||||
file=filename
|
||||
))
|
||||
logging.info('modified %d vtype(s) in %s', counter, filename)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Define arguments that will be received and parsed.
|
||||
argparser = argparse.ArgumentParser(
|
||||
description=__doc__
|
||||
)
|
||||
argparser.add_argument(
|
||||
'--route-files', '-r',
|
||||
metavar='FILES',
|
||||
nargs='+',
|
||||
default=[],
|
||||
help='sumo route files'
|
||||
)
|
||||
argparser.add_argument(
|
||||
'--random',
|
||||
action='store_true',
|
||||
help='apply vtypes randomly or sequentially'
|
||||
)
|
||||
argparser.add_argument(
|
||||
'--filterv',
|
||||
metavar='PATTERN',
|
||||
default='vehicle.*',
|
||||
help='vehicles filter (default: "vehicle.*")'
|
||||
)
|
||||
argparser.add_argument(
|
||||
'--verbose', '-v',
|
||||
action='store_true',
|
||||
help='increase output verbosity'
|
||||
)
|
||||
argparser = argparse.ArgumentParser(description=__doc__)
|
||||
argparser.add_argument('--route-files',
|
||||
'-r',
|
||||
metavar='FILES',
|
||||
nargs='+',
|
||||
default=[],
|
||||
help='sumo route files')
|
||||
argparser.add_argument('--random',
|
||||
action='store_true',
|
||||
help='apply vtypes randomly or sequentially')
|
||||
argparser.add_argument('--filterv',
|
||||
metavar='PATTERN',
|
||||
default='vehicle.*',
|
||||
help='vehicles filter (default: "vehicle.*")')
|
||||
argparser.add_argument('--verbose', '-v', action='store_true', help='increase output verbosity')
|
||||
args = argparser.parse_args()
|
||||
|
||||
if args.verbose:
|
||||
|
@ -94,5 +85,5 @@ if __name__ == '__main__':
|
|||
else:
|
||||
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.WARNING)
|
||||
|
||||
vtypes = [vtype for vtype in VTYPES if fnmatch.fnmatch(vtype, args.filterv)]
|
||||
main(args.route_files, vtypes, args.random)
|
||||
filtered_vtypes = [vtype for vtype in VTYPES if fnmatch.fnmatch(vtype, args.filterv)]
|
||||
main(args.route_files, filtered_vtypes, args.random)
|
||||
|
|
Loading…
Reference in New Issue