def _apply_rl_actions(self, rl_actions): """See class definition.""" if self.env_params.additional_params["use_follower_stopper"]: for veh_id in rl_actions.keys(): self._av_controller.veh_id = veh_id self._av_controller.v_des = rl_actions[veh_id][0] acceleration = self._av_controller.get_action(self) # Apply the action via the simulator. self.k.vehicle.apply_acceleration(veh_id, acceleration) else: rl_ids = list(rl_actions.keys()) acceleration = get_rl_accel( accel=[deepcopy(rl_actions[veh_id][0]) for veh_id in rl_ids], vel=self.k.vehicle.get_speed(rl_ids), max_accel=self.env_params.additional_params["max_accel"], dt=self.sim_step, ) # Run the action through the controller, to include failsafe # actions. for i, veh_id in enumerate(rl_ids): acceleration[i] = self.k.vehicle.get_acc_controller( veh_id).get_action(self, acceleration=acceleration[i]) # Apply the action via the simulator. self.k.vehicle.apply_acceleration(acc=acceleration, veh_ids=list(rl_actions.keys()))
def _apply_per_lane_actions(self, rl_actions, veh_ids): """Apply accelerations to RL vehicles on a given lane. Parameters ---------- rl_actions : array_like the actions to be performed on the given lane veh_ids : list of str the names of the RL vehicles on the given lane """ if self.env_params.additional_params["use_follower_stopper"]: accelerations = [] for i, veh_id in enumerate(veh_ids): self._av_controller.veh_id = veh_id self._av_controller.v_des = rl_actions[i] accelerations.append(self._av_controller.get_action(self)) else: accelerations = get_rl_accel( accel=deepcopy(rl_actions), vel=self.k.vehicle.get_speed(veh_ids), max_accel=self.env_params.additional_params["max_accel"], dt=self.sim_step, ) # Run the action through the controller, to include failsafe # actions. for i, veh_id in enumerate(veh_ids): accelerations[i] = self.k.vehicle.get_acc_controller( veh_id).get_action(self, acceleration=accelerations[i]) # Apply the actions via the simulator. self.k.vehicle.apply_acceleration(veh_ids, accelerations[:len(veh_ids)])
def _apply_rl_actions(self, rl_actions): """See class definition.""" if self.env_params.additional_params["use_follower_stopper"]: accelerations = [] for i, veh_id in enumerate(self.rl_ids()): self._av_controller.veh_id = veh_id self._av_controller.v_des = rl_actions[i] accelerations.append(self._av_controller.get_action(self)) else: accelerations = get_rl_accel( accel=deepcopy(rl_actions), vel=self.k.vehicle.get_speed(self.rl_ids()), max_accel=self.env_params.additional_params["max_accel"], dt=self.sim_step, ) # Run the action through the controller, to include failsafe # actions. for i, veh_id in enumerate(self.rl_ids()): accelerations[i] = self.k.vehicle.get_acc_controller( veh_id).get_action(self, acceleration=accelerations[i]) # Apply the actions via the simulator. self.k.vehicle.apply_acceleration(self.rl_ids(), accelerations[:len(self.rl_ids())])
def _apply_rl_actions(self, rl_actions): """See class definition.""" for key in rl_actions.keys(): # Get the lane ID. lane = int(key.split("_")[-1]) # Get the acceleration for the given lane. acceleration = get_rl_accel( accel=deepcopy(rl_actions[key]), vel=self.k.vehicle.get_speed(self.rl_ids()[lane]), max_accel=self.env_params.additional_params["max_accel"], dt=self.sim_step, ) # Apply the actions to the given lane. self._apply_per_lane_actions(acceleration, self.rl_ids()[lane])
def step(self, action): """Advance the simulation by one step.""" collision = False done = False for _ in range(self.sims_per_step): self.t += 1 # Compute the accelerations. self.accelerations = self._get_accel(self.speeds, self.headways) if self.rl_ids is not None and action is not None: # Compute the accelerations for RL vehicles. self.accelerations[self.rl_ids] = get_rl_accel( accel=action, vel=self.speeds[self.rl_ids], max_accel=self.max_accel, dt=self.dt, ) # Clip by safe, non-negative bounds. accel_min = -self.speeds[self.rl_ids] / self.dt accel_max = self._failsafe(self.rl_ids) self.accelerations[self.rl_ids] = np.clip( self.accelerations[self.rl_ids], a_max=accel_max, a_min=accel_min) # Update the speeds, positions, and headways. self.positions, self.speeds = self._update_state( pos=self.positions, vel=self.speeds, accel=self.accelerations, ) self.headways = self._compute_headway() if self.gen_emission: data = {"t": self.t} data.update({ "pos_{}".format(i): self.positions[i] for i in range(self.num_vehicles) }) data.update({ "vel_{}".format(i): self.speeds[i] for i in range(self.num_vehicles) }) self._emission_data.append(data) # Determine whether the rollout is done. collision = any(self.headways < 0) done = (self.t >= (self.warmup_steps + self.horizon) * self.sims_per_step) or collision if done: break if collision: print("Collision") info = {} if self.t > self.warmup_steps * self.sims_per_step: speed = np.mean(self.speeds) self._mean_speeds.append(speed) self._mean_accels.append(np.mean(np.abs(self.accelerations))) info.update({"v_eq": self._v_eq}) info.update({"v_eq_frac": np.mean(self._mean_speeds) / self._v_eq}) info.update({"v_eq_frac_final": speed / self._v_eq}) info.update({"speed": np.mean(self._mean_speeds)}) info.update({"abs_accel": np.mean(self._mean_accels)}) obs = self.get_state() if isinstance(obs, dict): obs = {key: np.asarray(obs[key]) for key in obs.keys()} else: obs = np.asarray(self.get_state()) reward = self.compute_reward(action if action is not None else [0]) return obs, reward, done, info