From 50d338da17e8adcc8c3a7046d51dd39070d12175 Mon Sep 17 00:00:00 2001 From: QuanyiLi Date: Mon, 8 May 2023 13:26:41 +0100 Subject: [PATCH] provide scripts --- scenarionet/builder/utils.py | 2 +- .../scripts/combine_dataset_and_run.py | 60 ------------------- scenarionet/scripts/convert_nuplan.py | 20 +++++-- scenarionet/scripts/convert_nuscenes.py | 20 +++++-- scenarionet/scripts/convert_pg.py | 22 +++++-- scenarionet/scripts/convert_waymo.py | 19 ++++-- .../scripts/generate_from_error_file.py | 12 ++++ scenarionet/scripts/run_simulation.py | 52 ++++++++++++++++ .../tests/test_generate_from_error_file.py | 12 ++-- scenarionet/verifier/error.py | 10 +++- 10 files changed, 141 insertions(+), 88 deletions(-) delete mode 100644 scenarionet/scripts/combine_dataset_and_run.py create mode 100644 scenarionet/scripts/generate_from_error_file.py create mode 100644 scenarionet/scripts/run_simulation.py diff --git a/scenarionet/builder/utils.py b/scenarionet/builder/utils.py index d908781..ca51870 100644 --- a/scenarionet/builder/utils.py +++ b/scenarionet/builder/utils.py @@ -45,7 +45,7 @@ def combine_multiple_dataset( raise FileExistsError("Output path already exists!") else: shutil.rmtree(output_abs_path) - os.mkdir(output_abs_path) + os.makedirs(output_abs_path, exist_ok=False) summaries = {} mappings = {} diff --git a/scenarionet/scripts/combine_dataset_and_run.py b/scenarionet/scripts/combine_dataset_and_run.py deleted file mode 100644 index 04b881d..0000000 --- a/scenarionet/scripts/combine_dataset_and_run.py +++ /dev/null @@ -1,60 +0,0 @@ -import os - -from metadrive.envs.scenario_env import ScenarioEnv -from metadrive.policy.replay_policy import ReplayEgoCarPolicy -from metadrive.scenario.utils import get_number_of_scenarios - -from scenarionet import SCENARIONET_DATASET_PATH -from scenarionet.builder.utils import combine_multiple_dataset - -if __name__ == '__main__': - dataset_paths = [ - os.path.join(SCENARIONET_DATASET_PATH, "nuscenes"), - os.path.join(SCENARIONET_DATASET_PATH, "nuplan"), - os.path.join(SCENARIONET_DATASET_PATH, "waymo"), - os.path.join(SCENARIONET_DATASET_PATH, "pg") - ] - - combine_path = os.path.join(SCENARIONET_DATASET_PATH, "combined_dataset") - combine_multiple_dataset(combine_path, *dataset_paths, force_overwrite=True, try_generate_missing_file=True) - - env = ScenarioEnv( - { - "use_render": True, - "agent_policy": ReplayEgoCarPolicy, - "manual_control": False, - "show_interface": True, - "show_logo": False, - "show_fps": False, - "num_scenarios": get_number_of_scenarios(combine_path), - "horizon": 1000, - "no_static_vehicles": True, - "vehicle_config": dict( - show_navi_mark=False, - no_wheel_friction=True, - lidar=dict(num_lasers=120, distance=50, num_others=4), - lane_line_detector=dict(num_lasers=12, distance=50), - side_detector=dict(num_lasers=160, distance=50) - ), - "data_directory": combine_path, - } - ) - success = [] - while True: - for seed in [91]: - env.reset(force_seed=seed) - for t in range(10000): - o, r, d, info = env.step([0, 0]) - assert env.observation_space.contains(o) - c_lane = env.vehicle.lane - long, lat, = c_lane.local_coordinates(env.vehicle.position) - # if env.config["use_render"]: - env.render(text={ - "seed": env.engine.global_seed + env.config["start_scenario_index"], - }) - - if d: - if info["arrive_dest"]: - print("seed:{}, success".format(env.engine.global_random_seed)) - print(t) - break diff --git a/scenarionet/scripts/convert_nuplan.py b/scenarionet/scripts/convert_nuplan.py index 4c1d6f2..7278e5f 100644 --- a/scenarionet/scripts/convert_nuplan.py +++ b/scenarionet/scripts/convert_nuplan.py @@ -2,17 +2,27 @@ This script aims to convert nuplan scenarios to ScenarioDescription, so that we can load any nuplan scenarios into MetaDrive. """ +import argparse import os from scenarionet import SCENARIONET_DATASET_PATH from scenarionet.converter.nuplan.utils import get_nuplan_scenarios, convert_nuplan_scenario from scenarionet.converter.utils import write_to_directory -if __name__ == "__main__": - force_overwrite = True - dataset_name = "nuplan" - output_path = os.path.join(SCENARIONET_DATASET_PATH, dataset_name) - version = 'v1.1' +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument("--dataset_name", "-n", default="nuplan", + help="Dataset name, will be used to generate scenario files") + parser.add_argument("--dataset_path", "-d", default=os.path.join(SCENARIONET_DATASET_PATH, "nuplan"), + help="The path of the dataset") + parser.add_argument("--version", "-v", default='v1.1', required=True, help="version") + parser.add_argument("--overwrite", action="store_true", help="If the dataset_path exists, overwrite it") + args = parser.parse_args() + + force_overwrite = args.overwrite + dataset_name = args.dataset_name + output_path = args.dataset_path + version = args.version data_root = os.path.join(os.getenv("NUPLAN_DATA_ROOT"), "nuplan-v1.1/splits/mini") map_root = os.getenv("NUPLAN_MAPS_ROOT") diff --git a/scenarionet/scripts/convert_nuscenes.py b/scenarionet/scripts/convert_nuscenes.py index f0e5fb6..d8a42a4 100644 --- a/scenarionet/scripts/convert_nuscenes.py +++ b/scenarionet/scripts/convert_nuscenes.py @@ -2,17 +2,27 @@ This script aims to convert nuscenes scenarios to ScenarioDescription, so that we can load any nuscenes scenarios into MetaDrive. """ +import argparse import os.path from scenarionet import SCENARIONET_DATASET_PATH from scenarionet.converter.nuscenes.utils import convert_nuscenes_scenario, get_nuscenes_scenarios from scenarionet.converter.utils import write_to_directory -if __name__ == "__main__": - dataset_name = "nuscenes" - output_path = os.path.join(SCENARIONET_DATASET_PATH, dataset_name) - version = 'v1.0-mini' - force_overwrite = True +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument("--dataset_name", "-n", default="nuscenes", + help="Dataset name, will be used to generate scenario files") + parser.add_argument("--dataset_path", "-d", default=os.path.join(SCENARIONET_DATASET_PATH, "nuscenes"), + help="The path of the dataset") + parser.add_argument("--version", "-v", default='v1.0-mini', required=True, help="version") + parser.add_argument("--overwrite", action="store_true", help="If the dataset_path exists, overwrite it") + args = parser.parse_args() + + force_overwrite = args.overwrite + dataset_name = args.dataset_name + output_path = args.dataset_path + version = args.version dataroot = '/home/shady/data/nuscenes' scenarios, nusc = get_nuscenes_scenarios(dataroot, version) diff --git a/scenarionet/scripts/convert_pg.py b/scenarionet/scripts/convert_pg.py index 072c0b4..ce6e35a 100644 --- a/scenarionet/scripts/convert_pg.py +++ b/scenarionet/scripts/convert_pg.py @@ -1,18 +1,28 @@ +# from metadrive.policy.expert_policy import ExpertPolicy +import argparse import os.path import metadrive +from metadrive.policy.idm_policy import IDMPolicy from scenarionet import SCENARIONET_DATASET_PATH from scenarionet.converter.pg.utils import get_pg_scenarios, convert_pg_scenario from scenarionet.converter.utils import write_to_directory -from metadrive.policy.idm_policy import IDMPolicy -# from metadrive.policy.expert_policy import ExpertPolicy if __name__ == '__main__': - dataset_name = "pg" - output_path = os.path.join(SCENARIONET_DATASET_PATH, dataset_name) - version = metadrive.constants.DATA_VERSION - force_overwrite = True + parser = argparse.ArgumentParser() + parser.add_argument("--dataset_name", "-n", default="pg", + help="Dataset name, will be used to generate scenario files") + parser.add_argument("--dataset_path", "-d", default=os.path.join(SCENARIONET_DATASET_PATH, "pg"), + help="The path of the dataset") + parser.add_argument("--version", "-v", default=metadrive.constants.DATA_VERSION, required=True, help="version") + parser.add_argument("--overwrite", action="store_true", help="If the dataset_path exists, overwrite it") + args = parser.parse_args() + + force_overwrite = args.overwrite + dataset_name = args.dataset_name + output_path = args.dataset_path + version = args.version scenario_indices, env = get_pg_scenarios(30, IDMPolicy) diff --git a/scenarionet/scripts/convert_waymo.py b/scenarionet/scripts/convert_waymo.py index 1e20a41..faeba64 100644 --- a/scenarionet/scripts/convert_waymo.py +++ b/scenarionet/scripts/convert_waymo.py @@ -1,5 +1,7 @@ +import argparse import logging import os + from scenarionet import SCENARIONET_DATASET_PATH from scenarionet.converter.utils import write_to_directory from scenarionet.converter.waymo.utils import convert_waymo_scenario, get_waymo_scenarios @@ -7,10 +9,19 @@ from scenarionet.converter.waymo.utils import convert_waymo_scenario, get_waymo_ logger = logging.getLogger(__name__) if __name__ == '__main__': - force_overwrite = True - dataset_name = "waymo" - output_path = os.path.join(SCENARIONET_DATASET_PATH, dataset_name) - version = 'v1.2' + parser = argparse.ArgumentParser() + parser.add_argument("--dataset_name", "-n", default="waymo", + help="Dataset name, will be used to generate scenario files") + parser.add_argument("--dataset_path", "-d", default=os.path.join(SCENARIONET_DATASET_PATH, "waymo"), + help="The path of the dataset") + parser.add_argument("--version", "-v", default='v1.2', required=True, help="version") + parser.add_argument("--overwrite", action="store_true", help="If the dataset_path exists, overwrite it") + args = parser.parse_args() + + force_overwrite = args.overwrite + dataset_name = args.dataset_name + output_path = args.dataset_path + version = args.version waymo_data_direction = os.path.join(SCENARIONET_DATASET_PATH, "waymo_origin") scenarios = get_waymo_scenarios(waymo_data_direction) diff --git a/scenarionet/scripts/generate_from_error_file.py b/scenarionet/scripts/generate_from_error_file.py new file mode 100644 index 0000000..8f4aa1b --- /dev/null +++ b/scenarionet/scripts/generate_from_error_file.py @@ -0,0 +1,12 @@ +import argparse + +from scenarionet.verifier.error import ErrorFile + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument("--file", "-f", required=True, help="The path of the error file") + parser.add_argument("--dataset_path", "-d", required=True, help="The path of the generated dataset") + parser.add_argument("--overwrite", action="store_true", help="If the dataset_path exists, overwrite it") + parser.add_argument("--broken", action="store_true", help="Generate dataset containing only broken files") + args = parser.parse_args() + ErrorFile.generate_dataset(args.file, args.dataset_path, args.overwrite, args.broken) diff --git a/scenarionet/scripts/run_simulation.py b/scenarionet/scripts/run_simulation.py new file mode 100644 index 0000000..0ec261b --- /dev/null +++ b/scenarionet/scripts/run_simulation.py @@ -0,0 +1,52 @@ +import argparse +import os + +from metadrive.envs.scenario_env import ScenarioEnv +from metadrive.policy.replay_policy import ReplayEgoCarPolicy +from metadrive.scenario.utils import get_number_of_scenarios + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument("--dataset_path", "-d", required=True, help="The path of the dataset") + parser.add_argument("--render", action="store_true", help="Enable 3D rendering") + parser.add_argument("--scenario_index", default=None, type=int, help="Specifying a scenario to run") + args = parser.parse_args() + + dataset_path = os.path.abspath(args.dataset_path) + num_scenario = get_number_of_scenarios(dataset_path) + if args.scenario_index is not None: + assert args.scenario_index < num_scenario, \ + "The specified scenario index exceeds the scenario range: {}!".format(num_scenario) + + env = ScenarioEnv( + { + "use_render": args.render, + "agent_policy": ReplayEgoCarPolicy, + "manual_control": False, + "show_interface": True, + "show_logo": False, + "show_fps": False, + "num_scenarios": num_scenario, + "horizon": 1000, + "vehicle_config": dict( + show_navi_mark=False, + no_wheel_friction=True, + lidar=dict(num_lasers=120, distance=50, num_others=4), + lane_line_detector=dict(num_lasers=12, distance=50), + side_detector=dict(num_lasers=160, distance=50) + ), + "data_directory": dataset_path, + } + ) + for seed in range(num_scenario if args.scenario_index is not None else 1000000): + env.reset(force_seed=seed if args.scenario_index is not None else args.scenario_index) + for t in range(10000): + o, r, d, info = env.step([0, 0]) + if env.config["use_render"]: + env.render(text={ + "seed": env.engine.global_seed + env.config["start_scenario_index"], + }) + + if d and info["arrive_dest"]: + print("scenario:{}, success".format(env.engine.global_random_seed)) + break diff --git a/scenarionet/tests/test_generate_from_error_file.py b/scenarionet/tests/test_generate_from_error_file.py index 66770fa..ec742fc 100644 --- a/scenarionet/tests/test_generate_from_error_file.py +++ b/scenarionet/tests/test_generate_from_error_file.py @@ -2,6 +2,8 @@ import copy import os import os.path +from metadrive.scenario.scenario_description import ScenarioDescription as SD + from scenarionet import SCENARIONET_PACKAGE_PATH from scenarionet.builder.utils import combine_multiple_dataset from scenarionet.common_utils import read_dataset_summary, read_scenario @@ -44,15 +46,17 @@ def test_combine_multiple_dataset(): assert recursive_equal(read_fail_summary, fail_summary) # assert pass+fail = origin - all_summaries = copy.deep(read_pass_summary) + all_summaries = copy.deepcopy(read_pass_summary) all_summaries.update(fail_summary) assert recursive_equal(all_summaries, summary) # test read for scenario in read_pass_summary: - read_scenario(pass_dataset, read_pass_mapping, scenario) - for scenario in read_pass_summary: - read_scenario(fail_dataset, read_fail_mapping, scenario) + sd = read_scenario(pass_dataset, read_pass_mapping, scenario) + SD.sanity_check(sd) + for scenario in read_fail_summary: + sd = read_scenario(fail_dataset, read_fail_mapping, scenario) + SD.sanity_check(sd) if __name__ == '__main__': diff --git a/scenarionet/verifier/error.py b/scenarionet/verifier/error.py index c3a5bb5..d436f85 100644 --- a/scenarionet/verifier/error.py +++ b/scenarionet/verifier/error.py @@ -1,4 +1,5 @@ import json +import shutil import logging import os from typing import List @@ -64,10 +65,13 @@ class ErrorFile: """ # TODO Add test! new_dataset_path = os.path.abspath(new_dataset_path) - if os.path.exists(new_dataset_path) and not force_overwrite: - raise ValueError("Directory: {} already exists! " + if os.path.exists(new_dataset_path): + if force_overwrite: + shutil.rmtree(new_dataset_path) + else: + raise ValueError("Directory: {} already exists! " "Set force_overwrite=True to overwrite".format(new_dataset_path)) - os.makedirs(new_dataset_path, exist_ok=True) + os.makedirs(new_dataset_path, exist_ok=False) with open(error_file_path, "r+") as f: error_file = json.load(f)