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