From 5be8e783d4cd8f50754d61a332aed75279e5abdc Mon Sep 17 00:00:00 2001 From: Henry <ehdykhne@uwaterloo.ca> Date: Sun, 7 Jan 2024 13:54:49 -0500 Subject: [PATCH] temp changes but ray bug is there --- experiments/bulk_running_experiments.ipynb | 2 + .../nuplan_db/nuplan_scenario.py | 3 +- .../abstract_scenario_modifier.py | 14 ++++ .../left_and_right_modifier.py | 78 +++++++++++++++++++ .../builders/scenario_modifier_builder.py | 19 +++++ .../script/builders/simulation_builder.py | 18 ++++- nuplan/planning/script/run_simulation.py | 3 + .../observation/ml_planner_agents.py | 4 + nuplan/planning/simulation/runner/executor.py | 19 +++++ 9 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 nuplan/planning/scenario_builder/scenario_modifier/abstract_scenario_modifier.py create mode 100644 nuplan/planning/scenario_builder/scenario_modifier/left_and_right_modifier.py create mode 100644 nuplan/planning/script/builders/scenario_modifier_builder.py diff --git a/experiments/bulk_running_experiments.ipynb b/experiments/bulk_running_experiments.ipynb index 083112f..0f1e055 100644 --- a/experiments/bulk_running_experiments.ipynb +++ b/experiments/bulk_running_experiments.ipynb @@ -210,6 +210,8 @@ " # # f\"observation.pdm_hybrid_ckpt={hybrid_ckpt}\",\n", " f\"observation.occlusion_cfg.occlusion=true\",\n", " f\"observation.occlusion_cfg.manager_type=wedge\",\n", + " \"+modify_scenario_simulations=true\",\n", + " \"+modifier_types=[left-and-right]\",\n", " \"+occlusion=true\",\n", " \"+occlusion.manager_type=wedge\", # options: [range, shadow, wedge]\n", " \"+occlusion.uncloak_reaction_time=1.5\",\n", diff --git a/nuplan/planning/scenario_builder/nuplan_db/nuplan_scenario.py b/nuplan/planning/scenario_builder/nuplan_db/nuplan_scenario.py index 0fbfb6f..3d2629d 100644 --- a/nuplan/planning/scenario_builder/nuplan_db/nuplan_scenario.py +++ b/nuplan/planning/scenario_builder/nuplan_db/nuplan_scenario.py @@ -121,6 +121,7 @@ class NuPlanScenario(AbstractScenario): # So, we must check and download the file here as well. self._log_file = download_file_if_necessary(self._data_root, self._log_file_load_path) self._log_name: str = absolute_path_to_log_name(self._log_file) + self.modifier = "" def __reduce__(self) -> Tuple[Type[NuPlanScenario], Tuple[Any, ...]]: """ @@ -190,7 +191,7 @@ class NuPlanScenario(AbstractScenario): @property def scenario_name(self) -> str: """Inherited, see superclass.""" - return self.token + return self.token + self.modifier @property def scenario_type(self) -> str: diff --git a/nuplan/planning/scenario_builder/scenario_modifier/abstract_scenario_modifier.py b/nuplan/planning/scenario_builder/scenario_modifier/abstract_scenario_modifier.py new file mode 100644 index 0000000..c19fa79 --- /dev/null +++ b/nuplan/planning/scenario_builder/scenario_modifier/abstract_scenario_modifier.py @@ -0,0 +1,14 @@ +from abc import ABCMeta, abstractmethod +from typing import List + +from nuplan.planning.scenario_builder.abstract_scenario import AbstractScenario +from nuplan.planning.simulation.runner.simulations_runner import SimulationRunner + +class AbstractScenarioModifier(metaclass=ABCMeta): + @abstractmethod + def modify_scenario(self, runner: SimulationRunner) -> List[SimulationRunner]: + """We convert one abstract scenario into many abstract scenarios by modifying the scenario in some way. + :param runner: a simualtion runner + :return: we return a list of scenarios that are modified versions of the input scenario + """ + pass \ No newline at end of file diff --git a/nuplan/planning/scenario_builder/scenario_modifier/left_and_right_modifier.py b/nuplan/planning/scenario_builder/scenario_modifier/left_and_right_modifier.py new file mode 100644 index 0000000..69bea3a --- /dev/null +++ b/nuplan/planning/scenario_builder/scenario_modifier/left_and_right_modifier.py @@ -0,0 +1,78 @@ +from typing import List + +import copy +from nuplan.common.actor_state.tracked_objects_types import TrackedObjectType + +from nuplan.planning.scenario_builder.abstract_scenario import AbstractScenario +from nuplan.planning.scenario_builder.scenario_modifier.abstract_scenario_modifier import AbstractScenarioModifier + + +from nuplan.common.actor_state.agent import Agent +from nuplan.common.actor_state.oriented_box import OrientedBox +from nuplan.common.actor_state.scene_object import SceneObjectMetadata +from nuplan.common.actor_state.state_representation import StateSE2, StateVector2D +import math + +from nuplan.planning.simulation.runner.simulations_runner import SimulationRunner +class LeftAndRightModifier(AbstractScenarioModifier): + def __init__(self): + super().__init__() #maybe we will need this later + + def modify_scenario(self, runner: SimulationRunner) -> List[SimulationRunner]: + """We convert one abstract scenario into many abstract scenarios by modifying the scenario in some way. + :param scenario: a scenario + :return: we return a list of scenarios that are modified versions of the input scenario + """ + modified_simulation_runners = [] + print('original object', runner) + left = copy.deepcopy(runner) + right = copy.deepcopy(runner) + + scenario = runner.scenario + + + angle = scenario.initial_ego_state.center.heading + inserted_agent = Agent( + tracked_object_type=TrackedObjectType.VEHICLE, + oriented_box=OrientedBox(StateSE2(scenario.initial_ego_state.center.x - 2, scenario.initial_ego_state.center.y, angle), 5, 2, 2), + velocity=StateVector2D(scenario.initial_ego_state.agent._velocity.x, scenario.initial_ego_state.agent._velocity.y), + metadata=SceneObjectMetadata(1623707858950113, "inserted_left", -2, "inserted_left"), + angular_velocity=0.0, + ) + + inserted_goal = StateSE2(scenario.initial_ego_state.center.x+100, scenario.initial_ego_state.center.y+100, 1.25) + + iter = runner.simulation._time_controller.get_iteration() + left.simulation._observations.add_agent_to_scene( + inserted_agent, inserted_goal, iter.time_point + ) + + left.scenario.modifier = "left" + + ############################## + + angle = scenario.initial_ego_state.center.heading + inserted_agent = Agent( + tracked_object_type=TrackedObjectType.VEHICLE, + oriented_box=OrientedBox(StateSE2(scenario.initial_ego_state.center.x + 2, scenario.initial_ego_state.center.y, angle), 5, 2, 2), + velocity=StateVector2D(scenario.initial_ego_state.agent._velocity.x, scenario.initial_ego_state.agent._velocity.y), + metadata=SceneObjectMetadata(1623707858950113, "inserted_right", -2, "inserted_right"), + angular_velocity=0.0, + ) + + inserted_goal = StateSE2(scenario.initial_ego_state.center.x+100, scenario.initial_ego_state.center.y+100, 1.25) + + iter = runner.simulation._time_controller.get_iteration() + right.simulation._observations.add_agent_to_scene( + inserted_agent, inserted_goal, iter.time_point + ) + + right.scenario.modifier = "right" + print('modded scenario') + print(right.scenario.scenario_name) + ####################################### + + modified_simulation_runners.append(left) + modified_simulation_runners.append(right) + + return modified_simulation_runners \ No newline at end of file diff --git a/nuplan/planning/script/builders/scenario_modifier_builder.py b/nuplan/planning/script/builders/scenario_modifier_builder.py new file mode 100644 index 0000000..1a49e6c --- /dev/null +++ b/nuplan/planning/script/builders/scenario_modifier_builder.py @@ -0,0 +1,19 @@ +from typing import List + +from nuplan.planning.scenario_builder.scenario_modifier.abstract_scenario_modifier import AbstractScenarioModifier +from nuplan.planning.scenario_builder.scenario_modifier.left_and_right_modifier import LeftAndRightModifier + + +def build_scenario_modifiers(scenario_modifier_types: List[str]) -> List[AbstractScenarioModifier]: + modifiers = [] + for type in scenario_modifier_types: + if type == "left-and-right": + modifiers.append(LeftAndRightModifier()) #this one is an example and just injects an agent to the left of ego in one modifiecation of the scenario and to the right in another + # elif type == "occluder-injection": + # modifiers.append(OccluderInjection()) + # elif type == "occludie-injection": + # modifiers.append(OccludieInjection()) + else: + raise ValueError(f"Unknown scenario modifier type: {type}") + + return modifiers \ No newline at end of file diff --git a/nuplan/planning/script/builders/simulation_builder.py b/nuplan/planning/script/builders/simulation_builder.py index 52abd74..7c12b41 100644 --- a/nuplan/planning/script/builders/simulation_builder.py +++ b/nuplan/planning/script/builders/simulation_builder.py @@ -27,6 +27,8 @@ from nuplan.planning.simulation.simulation_time_controller.abstract_simulation_t ) from nuplan.planning.utils.multithreading.worker_pool import WorkerPool +from nuplan.planning.script.builders.scenario_modifier_builder import build_scenario_modifiers + logger = logging.getLogger(__name__) @@ -138,6 +140,20 @@ def build_simulations( simulation_history_buffer_duration=cfg.simulation_history_buffer_duration, ) simulations.append(SimulationRunner(simulation, planner)) - + + # here we need to convert those simulations to our special scenarios + if 'modify_scenario_simulations' in cfg and cfg.modify_scenario_simulations: + offshoot_scenario_simulations = [] + scenario_modifiers = build_scenario_modifiers(cfg.modifier_types) + logger.info('Modyfing Scenarios...') + original_num_runners = len(simulations) + for simulation in simulations: + for modifier in scenario_modifiers: + offshoot_scenario_simulations.extend(modifier.modify_scenario(simulation)) + simulations = offshoot_scenario_simulations + logger.info(f'Created {len(simulations)} modified scenarios from {original_num_runners} scenarios.') + for simulation in simulations: + print('c') + print(simulation.scenario.scenario_name) logger.info('Building simulations...DONE!') return simulations diff --git a/nuplan/planning/script/run_simulation.py b/nuplan/planning/script/run_simulation.py index 9e3e5cf..469e8a3 100644 --- a/nuplan/planning/script/run_simulation.py +++ b/nuplan/planning/script/run_simulation.py @@ -106,6 +106,9 @@ def run_simulation(cfg: DictConfig, planners: Optional[Union[AbstractPlanner, Li pre_built_planners=planners, callbacks_worker=callbacks_worker_pool, ) + + for runner in runners: + print('d', runner.scenario.scenario_name) if common_builder.profiler: # Stop simulation construction profiling diff --git a/nuplan/planning/simulation/observation/ml_planner_agents.py b/nuplan/planning/simulation/observation/ml_planner_agents.py index 07179e4..2fde6f8 100644 --- a/nuplan/planning/simulation/observation/ml_planner_agents.py +++ b/nuplan/planning/simulation/observation/ml_planner_agents.py @@ -306,8 +306,12 @@ class MLPlannerAgents(AbstractObservation): def add_agent_to_scene(self, agent: Agent, goal: StateSE2, timepoint_record: TimePoint): """ Adds agent to the scene with a given goal during the simulation runtime. + Gets dict of tracked agents, or lazily creates them it + from vehicles at simulation start if it does not exist. """ + self._agents = self._get_agents() #this action is idempotent + route_plan = self._get_roadblock_path(agent, goal) if route_plan: diff --git a/nuplan/planning/simulation/runner/executor.py b/nuplan/planning/simulation/runner/executor.py index 1f42051..33b6633 100644 --- a/nuplan/planning/simulation/runner/executor.py +++ b/nuplan/planning/simulation/runner/executor.py @@ -23,6 +23,10 @@ def run_simulation(sim_runner: AbstractRunner, exit_on_failure: bool = False) -> """ # Store start time so that if the simulations fail, we know how long they ran for start_time = time.perf_counter() + print('hihihi') + print(sim_runner.scenario.modifier) + print(sim_runner) + print('a', sim_runner.scenario.scenario_name) try: return sim_runner.run() except Exception as e: @@ -80,9 +84,23 @@ def execute_runners( # Start simulations number_of_sims = len(runners) logger.info(f"Starting {number_of_sims} simulations using {worker.__class__.__name__}!") + + for runner in runners: + print('hohoho') + print(runner.scenario.modifier) + print(runner) + print('e', runner.scenario.scenario_name) + + #run_simulation(runners[0], exit_on_failure) this if you just want to run one without ray.map + + reports: List[RunnerReport] = worker.map( Task(fn=run_simulation, num_gpus=num_gpus, num_cpus=num_cpus), runners, exit_on_failure, verbose=verbose ) + reports = [] + print(len(reports)) + for report in reports: + print(report.scenario_name, report.planner_name, report.log_name) # Store the results in a dictionary so we can easily store error tracebacks in the next step, if needed results: Dict[Tuple[str, str, str], RunnerReport] = { (report.scenario_name, report.planner_name, report.log_name): report for report in reports @@ -116,6 +134,7 @@ def execute_runners( failed_simulations = str() number_of_successful = 0 runner_reports: List[RunnerReport] = list(results.values()) + print(len(runner_reports)) for result in runner_reports: if result.succeeded: number_of_successful += 1 -- GitLab