def main(scenarios, headless, seed): scenarios_iterator = Scenario.scenario_variations(scenarios, []) for _ in scenarios: scenario = next(scenarios_iterator) agent_missions = scenario.discover_missions_of_traffic_histories() for agent_id, mission in agent_missions.items(): scenario.set_ego_missions({agent_id: mission}) agent_spec = AgentSpec( interface=AgentInterface.from_type(AgentType.Laner, max_episode_steps=None), agent_builder=KeepLaneAgent, ) agent = agent_spec.build_agent() smarts = SMARTS( agent_interfaces={agent_id: agent_spec.interface}, traffic_sim=SumoTrafficSimulation(headless=True, auto_start=True), envision=Envision(), ) observations = smarts.reset(scenario) dones = {agent_id: False} while not dones[agent_id]: agent_obs = observations[agent_id] agent_action = agent.act(agent_obs) observations, rewards, dones, infos = smarts.step( {agent_id: agent_action})
def setup_smarts(self, headless: bool = True, seed: int = 42, time_ratio: float = 1.0): """Do the setup of the underlying SMARTS instance.""" assert not self._smarts if not self._state_publisher: raise RuntimeError("must call setup_ros() first.") self._zoo_module = rospy.get_param("~zoo_module", "zoo") headless = rospy.get_param("~headless", headless) seed = rospy.get_param("~seed", seed) time_ratio = rospy.get_param("~time_ratio", time_ratio) assert time_ratio > 0.0 self._time_ratio = time_ratio self._smarts = SMARTS( agent_interfaces={}, traffic_sim=None, fixed_timestep_sec=None, envision=None if headless else Envision(), external_provider=True, ) assert self._smarts.external_provider self._last_step_time = None with self._reset_lock: self._reset_msg = None self._scenario_path = None self._agents = {} self._agents_to_add = {}
def smarts(agent_spec): smarts = SMARTS( agent_interfaces={AGENT_ID: agent_spec.interface}, traffic_sim=SumoTrafficSimulation(), ) yield smarts smarts.destroy()
def __init__(self, config): self._config = config # XXX: These are intentionally left public at PyMARL's request self.n_agents = config.get("n_agents", 1) self.episode_limit = config.get("episode_limit", 1000) self.observation_space = config.get("observation_space", DEFAULT_OBSERVATION_SPACE) self.action_space = config.get("action_space", DEFAULT_ACTION_SPACE) self.state_space = config.get("state_space", DEFAULT_STATE_SPACE) self._agent_ids = ["Agent %i" % i for i in range(self.n_agents)] self._reward_adapter = config.get("reward_adapter", default_reward_adapter) self._observation_adapter = config.get("observation_adapter", default_obs_adapter) self._action_adapter = config.get("action_adapter", default_action_adapter) self._done_adapter = config.get("done_adapter", lambda dones: list(dones.values())) self._state_adapter = config.get("state_adapter", default_state_adapter) self._headless = config.get("headless", False) self._timestep_sec = config.get("timestep_sec", 0.01) self._observations = None self._state = None self._steps = 0 seed = self._config.get("seed", 42) smarts.core.seed(seed) self._scenarios_iterator = Scenario.scenario_variations( config["scenarios"], self._agent_ids) agent_interfaces = { agent_id: AgentInterface.from_type( config.get("agent_type", AgentType.Laner), max_episode_steps=self.episode_limit, debug=config.get("debug", False), ) for i, agent_id, in enumerate(self._agent_ids) } envision = None if not self._headless: envision = Envision( endpoint=config.get("envision_endpoint", None), output_dir=config.get("envision_record_data_replay_path", None), ) self._smarts = SMARTS( agent_interfaces=agent_interfaces, traffic_sim=SumoTrafficSimulation( time_resolution=self._timestep_sec), envision=envision, timestep_sec=self._timestep_sec, )
def reset(self, choose=True): if choose: try: self.current_observations = self._reset() except: self.close() self._smarts = SMARTS( agent_interfaces=self.agent_interfaces, traffic_sim=SumoTrafficSimulation( headless=self.all_args.sumo_headless, time_resolution=self.all_args.timestep_sec, num_external_sumo_clients=self.all_args. num_external_sumo_clients, sumo_port=self.all_args.sumo_port, auto_start=self.all_args.sumo_auto_start, endless_traffic=self.all_args.endless_traffic, ), envision=self.envision_client, visdom=self.visdom_client, timestep_sec=self.all_args.timestep_sec, zoo_workers=self.all_args.zoo_workers, auth_key=self.all_args.auth_key, ) self.current_observations = self._reset() return self.get_obs() else: return [np.zeros(self.obs_dim) for agent_id in self.agent_ids]
def __init__( self, scenarios: Sequence[str], agent_specs, shuffle_scenarios=True, headless=False, visdom=False, timestep_sec=0.1, seed=42, num_external_sumo_clients=0, sumo_headless=True, sumo_port=None, sumo_auto_start=True, endless_traffic=True, envision_endpoint=None, envision_record_data_replay_path=None, zoo_workers=None, auth_key=None, ): self._log = logging.getLogger(self.__class__.__name__) smarts.core.seed(seed) self._agent_specs = agent_specs self._dones_registered = 0 self._scenarios_iterator = Scenario.scenario_variations( scenarios, list(agent_specs.keys()), shuffle_scenarios, ) agent_interfaces = { agent_id: agent.interface for agent_id, agent in agent_specs.items() } envision_client = None if not headless: envision_client = Envision( endpoint=envision_endpoint, output_dir=envision_record_data_replay_path ) visdom_client = None if visdom: visdom_client = VisdomClient() self._smarts = SMARTS( agent_interfaces=agent_interfaces, traffic_sim=SumoTrafficSimulation( headless=sumo_headless, time_resolution=timestep_sec, num_external_sumo_clients=num_external_sumo_clients, sumo_port=sumo_port, auto_start=sumo_auto_start, endless_traffic=endless_traffic, ), envision=envision_client, visdom=visdom_client, timestep_sec=timestep_sec, zoo_workers=zoo_workers, auth_key=auth_key, )
def test_data_replay(agent_spec, scenarios_iterator, data_replay_path, monkeypatch): """We stub out the websocket the Envision client writes to and store the sent data. We do the same under Envision client's replay feature and compare that the data sent to the websocket is the same as before. """ def step_through_episodes(agent_spec, smarts, scenarios_iterator): for i in range(NUM_EPISODES): agent = agent_spec.build_agent() scenario = next(scenarios_iterator) obs = smarts.reset(scenario) done = False while not done: obs = agent_spec.observation_adapter(obs[AGENT_ID]) action = agent.act(obs) action = agent_spec.action_adapter(action) obs, _, dones, _ = smarts.step({AGENT_ID: action}) done = dones[AGENT_ID] # 1. Inspect sent data during SMARTS simulation # Mock WebSocketApp so we can inspect the websocket frames being sent FakeWebSocketApp, original_sent_data = fake_websocket_app_class() monkeypatch.setattr(websocket, "WebSocketApp", FakeWebSocketApp) assert original_sent_data.qsize() == 0 envision = Envision(output_dir=data_replay_path) smarts = SMARTS( agent_interfaces={AGENT_ID: agent_spec.interface}, traffic_sim=SumoTrafficSimulation(time_resolution=TIMESTEP_SEC), envision=envision, timestep_sec=TIMESTEP_SEC, ) step_through_episodes(agent_spec, smarts, scenarios_iterator) smarts.destroy() data_replay_path = Path(data_replay_path) data_replay_run_paths = [x for x in data_replay_path.iterdir() if x.is_dir()] assert len(data_replay_run_paths) == 1 jsonl_paths = list(data_replay_run_paths[0].glob("*.jsonl")) assert len(jsonl_paths) == 1 assert original_sent_data.qsize() > 0 # 2. Inspect replay data # Mock WebSocketApp so we can inspect the websocket frames being sent FakeWebSocketApp, new_sent_data = fake_websocket_app_class() monkeypatch.setattr(websocket, "WebSocketApp", FakeWebSocketApp) assert new_sent_data.qsize() == 0 # Now read data replay Envision.read_and_send(jsonl_paths[0], timestep_sec=TIMESTEP_SEC) # Verify the new data matches the original data assert original_sent_data.qsize() == new_sent_data.qsize() for _ in range(new_sent_data.qsize()): assert original_sent_data.get() == new_sent_data.get()
def test_no_renderer(smarts_wo_renderer: SMARTS, scenario): assert not smarts_wo_renderer.is_rendering smarts_wo_renderer.reset(scenario) assert not smarts_wo_renderer.is_rendering for _ in range(10): smarts_wo_renderer.step({AGENT_ID: "keep_lane"}) assert not smarts_wo_renderer.is_rendering
def test_no_recapture_agent(smarts_two_agents: SMARTS, two_agent_capture_offset_tenth_of_second): smarts_two_agents.reset(next(two_agent_capture_offset_tenth_of_second)) for i in range(3): smarts_two_agents.step({}) assert len(smarts_two_agents.agent_manager.pending_agent_ids) == 0 assert len(smarts_two_agents.agent_manager.active_agents) == 2 assert len(smarts_two_agents.vehicle_index.agent_vehicle_ids()) == 2
def smarts(): smarts_ = SMARTS( agent_interfaces={ AGENT_ID: AgentInterface.from_type(AgentType.Laner, max_episode_steps=30) }, traffic_sim=SumoTrafficSimulation(time_resolution=0.1), ) yield smarts_ smarts_.destroy()
def smarts(traffic_sim): buddha = AgentInterface( max_episode_steps=1000, neighborhood_vehicles=True, action=ActionSpaceType.Lane, ) agents = {"Agent-007": buddha} smarts = SMARTS(agents, traffic_sim=traffic_sim) yield smarts smarts.destroy()
def smarts(): laner = AgentInterface(max_episode_steps=1000, action=ActionSpaceType.Lane,) buddha = AgentInterface(max_episode_steps=1000, action=ActionSpaceType.Lane,) agents = {AGENT_1: laner, AGENT_2: buddha} smarts = SMARTS( agents, traffic_sim=SumoTrafficSimulation(headless=True), envision=None, ) yield smarts smarts.destroy()
def smarts(): smarts_ = SMARTS( agent_interfaces={}, traffic_sim=mock.Mock(), ) scenario = next( Scenario.scenario_variations(["scenarios/intersections/4lane_t"], ["Agent-007"])) smarts_.reset(scenario) return smarts_
def test_capture_vehicle(smarts: SMARTS, scenarios): vehicle_prefix = "car-flow-route-west_1_0-east_1_max" smarts.reset(next(scenarios)) vehicle_id = list(smarts.vehicle_index.agent_vehicle_ids())[0] assert vehicle_id.startswith(vehicle_prefix) assert smarts.elapsed_sim_time < 1 assert len(smarts.vehicle_index.agent_vehicle_ids()) == 1 assert smarts.vehicle_index.actor_id_from_vehicle_id( vehicle_id).startswith(AGENT_ID)
def main(scenarios, headless, seed): agent_spec = AgentSpec( interface=AgentInterface.from_type(AgentType.Laner, max_episode_steps=None), agent_builder=None, observation_adapter=None, ) smarts = SMARTS( agent_interfaces={}, traffic_sim=SumoTrafficSimulation(headless=True, auto_start=True), envision=Envision(), ) scenarios_iterator = Scenario.scenario_variations( scenarios, list([]), ) smarts.reset(next(scenarios_iterator)) for _ in range(5000): smarts.step({}) smarts.attach_sensors_to_vehicles( agent_spec, smarts.vehicle_index.social_vehicle_ids()) obs, _, _, _ = smarts.observe_from( smarts.vehicle_index.social_vehicle_ids())
def __init__( self, scenarios: Sequence[str], agent_specs, visdom=False, headless=False, timestep_sec=0.1, seed=42, num_external_sumo_clients=0, sumo_headless=True, sumo_port=None, sumo_auto_start=True, endless_traffic=True, envision_endpoint=None, envision_record_data_replay_path=None, ): self._log = logging.getLogger(self.__class__.__name__) smarts.core.seed(seed) self._visdom_obs_queue = None if visdom: self._log.debug("Running with visdom") self._visdom_obs_queue = build_visdom_watcher_queue() self._agent_specs = agent_specs self._dones_registered = 0 self._scenarios_iterator = Scenario.scenario_variations( scenarios, list(agent_specs.keys()), ) agent_interfaces = { agent_id: agent.interface for agent_id, agent in agent_specs.items() } envision = None if not headless: envision = Envision(endpoint=envision_endpoint, output_dir=envision_record_data_replay_path) self._smarts = SMARTS( agent_interfaces=agent_interfaces, traffic_sim=SumoTrafficSimulation( headless=sumo_headless, time_resolution=timestep_sec, num_external_sumo_clients=num_external_sumo_clients, sumo_port=sumo_port, auto_start=sumo_auto_start, endless_traffic=endless_traffic, ), envision=envision, timestep_sec=timestep_sec, )
def smarts(): buddha = AgentInterface( max_episode_steps=1000, neighborhood_vehicles=True, action=ActionSpaceType.Lane, ) smarts = SMARTS( agent_interfaces={"Agent-007": buddha}, traffic_sim=SumoTrafficSimulation(headless=True), envision=None, ) yield smarts smarts.destroy()
def smarts(scenarios, mock_provider): smarts_ = SMARTS( agent_interfaces={}, traffic_sim=SumoTrafficSimulation(time_resolution=0.1), ) smarts_.add_provider(mock_provider) smarts_.reset(next(scenarios)) yield smarts_ smarts_.destroy()
def main(scenarios: Sequence[str], headless: bool, seed: int): agent_spec = AgentSpec( interface=AgentInterface.from_type(AgentType.Laner, max_episode_steps=None), agent_builder=None, observation_adapter=None, ) smarts = SMARTS( agent_interfaces={}, traffic_sim=SumoTrafficSimulation(headless=headless, auto_start=True), envision=None if headless else Envision(), ) scenarios_iterator = Scenario.scenario_variations( scenarios, list([]), ) scenario = next(scenarios_iterator) obs = smarts.reset(scenario) collected_data = {} _record_data(smarts.elapsed_sim_time, obs, collected_data) # could also include "motorcycle" or "truck" in this set if desired vehicle_types = frozenset({"car"}) while True: smarts.step({}) current_vehicles = smarts.vehicle_index.social_vehicle_ids( vehicle_types=vehicle_types) if collected_data and not current_vehicles: print("no more vehicles. exiting...") break smarts.attach_sensors_to_vehicles(agent_spec, current_vehicles) obs, _, _, dones = smarts.observe_from(current_vehicles) _record_data(smarts.elapsed_sim_time, obs, collected_data) # an example of how we might save the data per car for car, data in collected_data.items(): outfile = f"data_{scenario.name}_{scenario.traffic_history.name}_{car}.pkl" with open(outfile, "wb") as of: pickle.dump(data, of) smarts.destroy()
def _build_smarts(self): agent_interfaces = { agent_id: spec.interface for agent_id, spec in self._agent_specs.items() } envision = None if not self._headless or self._envision_record_data_replay_path: envision = Envision( endpoint=self._envision_endpoint, sim_name=self._sim_name, output_dir=self._envision_record_data_replay_path, headless=self._headless, ) sim = SMARTS( agent_interfaces=agent_interfaces, traffic_sim=SumoTrafficSimulation( headless=self._sumo_headless, time_resolution=self._fixed_timestep_sec, num_external_sumo_clients=self._num_external_sumo_clients, sumo_port=self._sumo_port, auto_start=self._sumo_auto_start, endless_traffic=self._endless_traffic, ), envision=envision, fixed_timestep_sec=self._fixed_timestep_sec, ) return sim
def _smarts_with_agent(agent) -> SMARTS: agents = {AGENT_ID: agent} return SMARTS( agents, traffic_sim=SumoTrafficSimulation(headless=True), envision=None, )
def sim(request): shared_interface = AgentInterface(done_criteria=DoneCriteria( agents_alive=request.param)) agents = { AGENT1: shared_interface, AGENT2: shared_interface, AGENT3: shared_interface, } smarts = SMARTS( agents, traffic_sim=SumoTrafficSimulation(headless=True), envision=None, ) yield smarts smarts.destroy()
def setup_smarts( self, headless: bool = True, seed: int = 42, time_ratio: float = 1.0, sumo_traffic: bool = False, ): """Do the setup of the underlying SMARTS instance.""" assert not self._smarts if not self._state_publisher: raise RuntimeError("must call setup_ros() first.") self._zoo_module = rospy.get_param("~zoo_module", "zoo") headless = rospy.get_param("~headless", headless) seed = rospy.get_param("~seed", seed) time_ratio = rospy.get_param("~time_ratio", time_ratio) assert time_ratio > 0.0 self._time_ratio = time_ratio traffic_sim = None if rospy.get_param("~sumo_traffic", sumo_traffic): from smarts.core.sumo_traffic_simulation import SumoTrafficSimulation # Note that Sumo uses a fixed timestep, so if we have a highly-variable step rate, # we may want to set time_resolution to a mutiple of the target_freq? time_resolution = 1.0 / self._target_freq if self._target_freq else None traffic_sim = SumoTrafficSimulation( headless=headless, time_resolution=time_resolution, ) self._smarts = SMARTS( agent_interfaces={}, traffic_sim=traffic_sim, fixed_timestep_sec=None, envision=None if headless else Envision(), external_provider=True, ) assert self._smarts.external_provider self._last_step_time = None
def main(scenarios, headless, seed): scenarios_iterator = Scenario.scenario_variations(scenarios, []) smarts = SMARTS( agent_interfaces={}, traffic_sim=None, envision=None if headless else Envision(), ) for _ in scenarios: scenario = next(scenarios_iterator) agent_missions = scenario.discover_missions_of_traffic_histories() for agent_id, mission in agent_missions.items(): agent_spec = AgentSpec( interface=AgentInterface.from_type(AgentType.LanerWithSpeed, max_episode_steps=None), agent_builder=KeepLaneAgent, agent_params=scenario.traffic_history_target_speed, ) agent = agent_spec.build_agent() # Take control of vehicle with corresponding agent_id smarts.switch_ego_agent({agent_id: agent_spec.interface}) # tell the traffic history provider to start traffic # at the point when this agent enters... traffic_history_provider = smarts.get_provider_by_type( TrafficHistoryProvider) assert traffic_history_provider traffic_history_provider.start_time = mission.start_time # agent vehicle will enter right away... modified_mission = replace(mission, start_time=0.0) scenario.set_ego_missions({agent_id: modified_mission}) observations = smarts.reset(scenario) dones = {agent_id: False} while not dones.get(agent_id, True): agent_obs = observations[agent_id] agent_action = agent.act(agent_obs) observations, rewards, dones, infos = smarts.step( {agent_id: agent_action}) smarts.destroy()
def main(scenarios, headless, seed): scenarios_iterator = Scenario.scenario_variations(scenarios, []) smarts = SMARTS( agent_interfaces={}, traffic_sim=SumoTrafficSimulation(headless=True, auto_start=True), envision=Envision(), ) for _ in scenarios: scenario = next(scenarios_iterator) agent_missions = scenario.discover_missions_of_traffic_histories() for agent_id, mission in agent_missions.items(): agent_spec = AgentSpec( interface=AgentInterface.from_type(AgentType.Laner, max_episode_steps=None), agent_builder=KeepLaneAgent, ) agent = agent_spec.build_agent() smarts.switch_ego_agent({agent_id: agent_spec.interface}) # required: get traffic_history_provider and set time offset traffic_history_provider = smarts.get_provider_by_type( TrafficHistoryProvider) assert traffic_history_provider traffic_history_provider.set_start_time(mission.start_time) modified_mission = replace(mission, start_time=0.0) scenario.set_ego_missions({agent_id: modified_mission}) observations = smarts.reset(scenario) dones = {agent_id: False} while not dones[agent_id]: agent_obs = observations[agent_id] agent_action = agent.act(agent_obs) observations, rewards, dones, infos = smarts.step( {agent_id: agent_action}) smarts.destroy()
def test_optional_renderer(smarts: SMARTS, scenario): assert not smarts.is_rendering renderer = smarts.renderer assert renderer smarts._renderer = None smarts.reset(scenario) assert smarts.is_rendering smarts._renderer = None for _ in range(10): smarts.step({AGENT_ID: "keep_lane"}) assert not smarts.is_rendering
def test_emit_on_default(smarts: SMARTS, empty_scenarios): smarts.reset(next(empty_scenarios)) assert smarts.elapsed_sim_time == 3 assert len(smarts.vehicle_index.agent_vehicle_ids()) == 1 assert len(smarts.vehicle_index.vehicle_ids_by_actor_id(AGENT_ID)) == 1
def main(script: str, scenarios: Sequence[str], headless: bool, seed: int): logger = logging.getLogger(script) logger.setLevel(logging.INFO) agent_spec = AgentSpec( interface=AgentInterface.from_type(AgentType.Laner, max_episode_steps=None), agent_builder=None, observation_adapter=None, ) smarts = SMARTS( agent_interfaces={}, traffic_sim=SumoTrafficSimulation(headless=headless, auto_start=True), envision=None if headless else Envision(), ) scenario_list = Scenario.get_scenario_list(scenarios) scenarios_iterator = Scenario.variations_for_all_scenario_roots(scenario_list, []) for scenario in scenarios_iterator: obs = smarts.reset(scenario) collected_data = {} _record_data(smarts.elapsed_sim_time, obs, collected_data) # could also include "motorcycle" or "truck" in this set if desired vehicle_types = frozenset({"car"}) # filter off-road vehicles from observations vehicles_off_road = set() while True: smarts.step({}) current_vehicles = smarts.vehicle_index.social_vehicle_ids( vehicle_types=vehicle_types ) if collected_data and not current_vehicles: print("no more vehicles. exiting...") break for veh_id in current_vehicles: try: smarts.attach_sensors_to_vehicles(agent_spec.interface, {veh_id}) except ControllerOutOfLaneException: logger.warning(f"{veh_id} out of lane, skipped attaching sensors") vehicles_off_road.add(veh_id) valid_vehicles = {v for v in current_vehicles if v not in vehicles_off_road} obs, _, _, dones = smarts.observe_from(valid_vehicles) _record_data(smarts.elapsed_sim_time, obs, collected_data) # an example of how we might save the data per car observation_folder = "collected_observations" if not os.path.exists(observation_folder): os.makedirs(observation_folder) for car, data in collected_data.items(): outfile = f"{observation_folder}/{scenario.name}_{scenario.traffic_history.name}_{car}.pkl" with open(outfile, "wb") as of: pickle.dump(data, of) smarts.destroy()
def main( script: str, scenarios: Sequence[str], headless: bool, seed: int, vehicles_to_replace: int, episodes: int, ): assert vehicles_to_replace > 0 assert episodes > 0 logger = logging.getLogger(script) logger.setLevel(logging.INFO) logger.debug("initializing SMARTS") smarts = SMARTS( agent_interfaces={}, traffic_sim=None, envision=None if headless else Envision(), ) random_seed(seed) traffic_history_provider = smarts.get_provider_by_type( TrafficHistoryProvider) assert traffic_history_provider scenario_list = Scenario.get_scenario_list(scenarios) scenarios_iterator = Scenario.variations_for_all_scenario_roots( scenario_list, []) for scenario in scenarios_iterator: logger.debug("working on scenario {}".format(scenario.name)) veh_missions = scenario.discover_missions_of_traffic_histories() if not veh_missions: logger.warning("no vehicle missions found for scenario {}.".format( scenario.name)) continue veh_start_times = { v_id: mission.start_time for v_id, mission in veh_missions.items() } k = vehicles_to_replace if k > len(veh_missions): logger.warning( "vehicles_to_replace={} is greater than the number of vehicle missions ({})." .format(vehicles_to_replace, len(veh_missions))) k = len(veh_missions) # XXX replace with AgentSpec appropriate for IL model agent_spec = AgentSpec( interface=AgentInterface.from_type(AgentType.Imitation), agent_builder=ReplayCheckerAgent, agent_params=smarts.fixed_timestep_sec, ) for episode in range(episodes): logger.info(f"starting episode {episode}...") agentid_to_vehid = {} agent_interfaces = {} # Build the Agents for the to-be-hijacked vehicles # and gather their missions agents = {} dones = {} ego_missions = {} sample = {} if scenario.traffic_history.dataset_source == "Waymo": # For Waymo, we only hijack the vehicle that was autonomous in the dataset waymo_ego_id = scenario.traffic_history.ego_vehicle_id if waymo_ego_id is not None: assert ( k == 1 ), f"do not specify -k > 1 when just hijacking Waymo ego vehicle (it was {k})" veh_id = str(waymo_ego_id) sample = {veh_id} else: logger.warning( f"Waymo ego vehicle id not mentioned in the dataset. Hijacking a random vehicle." ) if not sample: # For other datasets, hijack a sample of the recorded vehicles # Pick k vehicle missions to hijack with agent # and figure out which one starts the earliest sample = scenario.traffic_history.random_overlapping_sample( veh_start_times, k) if len(sample) < k: logger.warning( f"Unable to choose {k} overlapping missions. allowing non-overlapping." ) leftover = set(veh_start_times.keys()) - sample sample.update(set(random.sample(leftover, k - len(sample)))) agent_spec.interface.max_episode_steps = max([ scenario.traffic_history.vehicle_final_exit_time(veh_id) / 0.1 for veh_id in sample ]) history_start_time = None logger.info(f"chose vehicles: {sample}") for veh_id in sample: agent_id = f"ego-agent-IL-{veh_id}" agentid_to_vehid[agent_id] = veh_id agent_interfaces[agent_id] = agent_spec.interface if (not history_start_time or veh_start_times[veh_id] < history_start_time): history_start_time = veh_start_times[veh_id] for agent_id in agent_interfaces.keys(): agent = agent_spec.build_agent() veh_id = agentid_to_vehid[agent_id] agent.load_data_for_vehicle(veh_id, scenario, history_start_time) agents[agent_id] = agent dones[agent_id] = False mission = veh_missions[veh_id] ego_missions[agent_id] = replace( mission, start_time=mission.start_time - history_start_time) # Tell the traffic history provider to start traffic # at the point when the earliest agent enters... traffic_history_provider.start_time = history_start_time # and all the other agents to offset their missions by this much too scenario.set_ego_missions(ego_missions) logger.info(f"offsetting sim_time by: {history_start_time}") # Take control of vehicles with corresponding agent_ids smarts.switch_ego_agents(agent_interfaces) # Finally start the simulation loop... logger.info(f"starting simulation loop...") observations = smarts.reset(scenario) while not all(done for done in dones.values()): actions = { agent_id: agents[agent_id].act(agent_obs) for agent_id, agent_obs in observations.items() } logger.debug("stepping @ sim_time={} for agents={}...".format( smarts.elapsed_sim_time, list(observations.keys()))) observations, rewards, dones, infos = smarts.step(actions) for agent_id in agents.keys(): if dones.get(agent_id, False): if not observations[agent_id].events.reached_goal: logger.warning( "agent_id={} exited @ sim_time={}".format( agent_id, smarts.elapsed_sim_time)) logger.warning(" ... with {}".format( observations[agent_id].events)) else: logger.info( "agent_id={} reached goal @ sim_time={}". format(agent_id, smarts.elapsed_sim_time)) logger.debug(" ... with {}".format( observations[agent_id].events)) del observations[agent_id] smarts.destroy()
class HiWayEnv(gym.Env): """A complete gym environment that wraps a SMARTS simulation. Args: scenarios: a list of directories of the scenarios that will be run agent_specs: a list of agents that will run in the environment sim_name: a string that gives this simulation a name headless: true|false envision disabled visdom: true|false visdom integration timestep_sec: the step length for all components of the simulation seed: the seed for random number generation num_external_sumo_clients: the number of SUMO clients beyond SMARTS sumo_headless: true|false for SUMO visualization disabled [sumo-gui|sumo] sumo_port: used to specify a specific sumo port sumo_auto_start: true|false sumo will start automatically envision_endpoint: used to specify envision's uri envision_record_data_replay_path: used to specify envision's data replay output directory zoo_addrs: List of (ip, port) tuples of zoo server, used to instantiate remote social agents """ metadata = {"render.modes": ["human"]} """Metadata for gym's use""" def __init__( self, scenarios: Sequence[str], agent_specs, sim_name=None, shuffle_scenarios=True, headless=False, visdom=False, timestep_sec=0.1, seed=42, num_external_sumo_clients=0, sumo_headless=True, sumo_port=None, sumo_auto_start=True, endless_traffic=True, envision_endpoint=None, envision_record_data_replay_path=None, zoo_addrs=None, ): self._log = logging.getLogger(self.__class__.__name__) smarts.core.seed(seed) self._agent_specs = agent_specs self._dones_registered = 0 self._scenarios_iterator = Scenario.scenario_variations( scenarios, list(agent_specs.keys()), shuffle_scenarios, ) agent_interfaces = { agent_id: agent.interface for agent_id, agent in agent_specs.items() } envision_client = None if not headless: envision_client = Envision( endpoint=envision_endpoint, sim_name=sim_name, output_dir=envision_record_data_replay_path, ) visdom_client = None if visdom: visdom_client = VisdomClient() self._smarts = SMARTS( agent_interfaces=agent_interfaces, traffic_sim=SumoTrafficSimulation( headless=sumo_headless, time_resolution=timestep_sec, num_external_sumo_clients=num_external_sumo_clients, sumo_port=sumo_port, auto_start=sumo_auto_start, endless_traffic=endless_traffic, ), envision=envision_client, visdom=visdom_client, timestep_sec=timestep_sec, zoo_addrs=zoo_addrs, ) @property def scenario_log(self): """Simulation step logs. Returns: A dictionary with the following: timestep_sec: The timestep of the simulation. scenario_map: The name of the current scenario. scenario_routes: The routes in the map. mission_hash: The hash identifier for the current scenario. """ scenario = self._smarts.scenario return { "timestep_sec": self._smarts.timestep_sec, "scenario_map": scenario.name, "scenario_routes": scenario.route or "", "mission_hash": str(hash(frozenset(scenario.missions.items()))), } def step(self, agent_actions): agent_actions = { agent_id: self._agent_specs[agent_id].action_adapter(action) for agent_id, action in agent_actions.items() } observations, rewards, agent_dones, extras = self._smarts.step( agent_actions) infos = { agent_id: { "score": value, "env_obs": observations[agent_id] } for agent_id, value in extras["scores"].items() } for agent_id in observations: agent_spec = self._agent_specs[agent_id] observation = observations[agent_id] reward = rewards[agent_id] info = infos[agent_id] rewards[agent_id] = agent_spec.reward_adapter(observation, reward) observations[agent_id] = agent_spec.observation_adapter( observation) infos[agent_id] = agent_spec.info_adapter(observation, reward, info) for done in agent_dones.values(): self._dones_registered += 1 if done else 0 agent_dones["__all__"] = self._dones_registered == len( self._agent_specs) return observations, rewards, agent_dones, infos def reset(self): scenario = next(self._scenarios_iterator) self._dones_registered = 0 env_observations = self._smarts.reset(scenario) observations = { agent_id: self._agent_specs[agent_id].observation_adapter(obs) for agent_id, obs in env_observations.items() } return observations def render(self, mode="human"): """Does nothing.""" pass def close(self): if self._smarts is not None: self._smarts.destroy()