From dfe0645a4c3cf1cb2415917f6a5fb58f6c336f35 Mon Sep 17 00:00:00 2001 From: Tucker Alban Date: Thu, 16 Nov 2023 17:10:16 -0500 Subject: [PATCH] Allow random routes to vary across traffic groups. (#2112) * Allow random routes to vary across traffic groups. * Update changelog. * Vary seed using interation instead. * Remove unused imports. --- CHANGELOG.md | 1 + scenarios/sumo/intersections/4lane/scenario.py | 6 ++++-- smarts/sstudio/generators.py | 5 ++++- smarts/sstudio/genscenario.py | 8 ++++++-- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a499bdfb5d..2d9ca64254 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Copy and pasting the git commit messages is __NOT__ enough. ### Changed ### Deprecated ### Fixed +- Fixed an issue where `RandomRoute` would always give the same route across traffic groups in scenario studio. - Fixed an issue where `SMARTS` might not be explicitly destroyed in the `ros_driver`. - Fixed issue where `SumoTrafficSimulation` could get locked up on reset if a scenario had only 1 map but multiple scenario variations. - Fixed an issue where an out-of-scope method reference caused a pickling error. diff --git a/scenarios/sumo/intersections/4lane/scenario.py b/scenarios/sumo/intersections/4lane/scenario.py index 977fed8a4c..cb9bf50295 100644 --- a/scenarios/sumo/intersections/4lane/scenario.py +++ b/scenarios/sumo/intersections/4lane/scenario.py @@ -74,18 +74,20 @@ ), ] +variations = 40 scenario = Scenario( traffic={ - "basic": Traffic( + f"t{i}": Traffic( flows=[ Flow( route=RandomRoute(), - repeat_route=True, rate=3600, + randomly_spaced=True, actors={TrafficActor(name="car"): 1.0}, ) ] ) + for i in range(variations) }, ego_missions=ego_missions, map_spec=MapSpec( diff --git a/smarts/sstudio/generators.py b/smarts/sstudio/generators.py index 4762fa9634..a90f36dfdf 100644 --- a/smarts/sstudio/generators.py +++ b/smarts/sstudio/generators.py @@ -30,10 +30,12 @@ import tempfile from typing import Optional +import numpy as np from yattag import Doc, indent from smarts.core.road_map import RoadMap from smarts.core.utils.file import make_dir_in_smarts_log_dir, replace +from smarts.core.utils.math import wrap_value from . import types @@ -184,6 +186,7 @@ def plan_and_save( from smarts.core.utils.sumo import sumolib + int32_limits = np.iinfo(np.int32) duarouter_path = sumolib.checkBinary("duarouter") subprocess.check_call( [ @@ -197,7 +200,7 @@ def plan_and_save( "--output-file", route_path, "--seed", - str(seed), + str(wrap_value(seed, int32_limits.min, int32_limits.max)), "--ignore-errors", "false", "--no-step-log", diff --git a/smarts/sstudio/genscenario.py b/smarts/sstudio/genscenario.py index 0b43d12f1c..ea52cbeafc 100644 --- a/smarts/sstudio/genscenario.py +++ b/smarts/sstudio/genscenario.py @@ -35,6 +35,7 @@ import cloudpickle import yaml +import smarts.core from smarts.core.default_map_builder import find_mapfile_in_dir from smarts.core.utils.file import file_md5_hash, path2hash, pickle_hash from smarts.core.utils.logging import timeit @@ -164,6 +165,7 @@ def gen_scenario( """ # XXX: For now this simply coalesces the sub-calls but in the future this allows # us to simplify our serialization between SStudio and SMARTS. + smarts.core.seed(seed) scenario_dir = os.path.abspath(str(output_dir)) build_dir = os.path.join(scenario_dir, "build") @@ -242,12 +244,14 @@ def gen_scenario( db_conn, scenario.traffic, artifact_paths, obj_hash, map_needs_rebuild ): with timeit("traffic", logger.info): - for name, traffic in scenario.traffic.items(): + + for iteration, (name, traffic) in enumerate(scenario.traffic.items()): + derived_seed = seed + iteration gen_traffic( scenario=scenario_dir, traffic=traffic, name=name, - seed=seed, + seed=derived_seed, map_spec=map_spec, ) _update_artifacts(db_conn, artifact_paths, obj_hash)