From 43c5917d7294dadc13fa964cc3fb872f7020b53f Mon Sep 17 00:00:00 2001 From: liljonnystyle Date: Mon, 6 Jul 2020 19:24:56 -0700 Subject: [PATCH 01/14] add energy model classes to master --- flow/core/kernel/vehicle/base.py | 95 ++++++++++++++++++++++++ flow/core/kernel/vehicle/traci.py | 111 +++++++++++++++++++++++++++- flow/core/params.py | 30 +++++++- flow/core/rewards.py | 29 +++++++- flow/energy_models/base_energy.py | 36 +++++++++ flow/energy_models/power_demand.py | 109 +++++++++++++++++++++++++++ flow/energy_models/toyota_energy.py | 54 ++++++++++++++ 7 files changed, 454 insertions(+), 10 deletions(-) create mode 100644 flow/energy_models/base_energy.py create mode 100644 flow/energy_models/power_demand.py create mode 100644 flow/energy_models/toyota_energy.py diff --git a/flow/core/kernel/vehicle/base.py b/flow/core/kernel/vehicle/base.py index d97ade984..2ca51a187 100644 --- a/flow/core/kernel/vehicle/base.py +++ b/flow/core/kernel/vehicle/base.py @@ -131,6 +131,23 @@ def remove(self, veh_id): def apply_acceleration(self, veh_id, acc): """Apply the acceleration requested by a vehicle in the simulator. + In SUMO, this function applies slowDown method which applies smoothing. + + Parameters + ---------- + veh_id : str or list of str + list of vehicle identifiers + acc : float or array_like + requested accelerations from the vehicles + """ + raise NotImplementedError + + def apply_acceleration_not_smooth(self, veh_id, acc): + """Apply the acceleration requested by a vehicle in the simulator. + + In SUMO, this function applies setSpeed method which doesn't apply + smoothing. + Parameters ---------- veh_id : str or list of str @@ -346,6 +363,20 @@ def get_fuel_consumption(self, veh_id, error=-1001): """ pass + @abstractmethod + def get_energy_model(self, veh_id): + """Return the energy model class object of the specified vehicle. + + Parameters + ---------- + veh_id : str or list of str + vehicle id, or list of vehicle ids + Returns + ------- + subclass of BaseEnergyModel + """ + pass + @abstractmethod def get_speed(self, veh_id, error=-1001): """Return the speed of the specified vehicle. @@ -741,3 +772,67 @@ def get_max_speed(self, veh_id, error): float """ pass + + ########################################################################### + # Methods for Datapipeline # + ########################################################################### + + @abstractmethod + def get_accel(self, veh_id): + """Return the acceleration of vehicle with veh_id.""" + pass + + @abstractmethod + def update_accel_no_noise_no_failsafe(self, veh_id, accel_no_noise_no_failsafe): + """Update stored acceleration without noise without failsafe of vehicle with veh_id.""" + pass + + @abstractmethod + def update_accel_no_noise_with_failsafe(self, veh_id, accel_no_noise_with_failsafe): + """Update stored acceleration without noise with failsafe of vehicle with veh_id.""" + raise NotImplementedError + + @abstractmethod + def update_accel_with_noise_no_failsafe(self, veh_id, accel_with_noise_no_failsafe): + """Update stored acceleration with noise without failsafe of vehicle with veh_id.""" + pass + + @abstractmethod + def update_accel_with_noise_with_failsafe(self, veh_id, accel_with_noise_with_failsafe): + """Update stored acceleration with noise with failsafe of vehicle with veh_id.""" + pass + + @abstractmethod + def get_2d_position(self, veh_id, error=-1001): + """Return (x, y) position of vehicle with veh_id.""" + pass + + @abstractmethod + def get_accel_no_noise_no_failsafe(self, veh_id): + """Return the acceleration without noise without failsafe of vehicle with veh_id.""" + pass + + @abstractmethod + def get_accel_no_noise_with_failsafe(self, veh_id): + """Return the acceleration without noise with failsafe of vehicle with veh_id.""" + pass + + @abstractmethod + def get_accel_with_noise_no_failsafe(self, veh_id): + """Return the acceleration with noise without failsafe of vehicle with veh_id.""" + pass + + @abstractmethod + def get_accel_with_noise_with_failsafe(self, veh_id): + """Return the acceleration with noise with failsafe of vehicle with veh_id.""" + pass + + @abstractmethod + def get_realized_accel(self, veh_id): + """Return the acceleration that the vehicle actually make.""" + pass + + @abstractmethod + def get_road_grade(self, veh_id): + """Return the road-grade of the vehicle with veh_id.""" + pass diff --git a/flow/core/kernel/vehicle/traci.py b/flow/core/kernel/vehicle/traci.py index 6f119b7bb..00ee1aeac 100644 --- a/flow/core/kernel/vehicle/traci.py +++ b/flow/core/kernel/vehicle/traci.py @@ -87,6 +87,8 @@ def __init__(self, # old speeds used to compute accelerations self.previous_speeds = {} + # The time that previous speed is recorded, used to calculate realized_accel + self.previous_time = 0 def initialize(self, vehicles): """Initialize vehicle state information. @@ -113,6 +115,7 @@ def initialize(self, vehicles): self.__vehicles[veh_id] = dict() self.__vehicles[veh_id]['type'] = typ['veh_id'] self.__vehicles[veh_id]['initial_speed'] = typ['initial_speed'] + self.num_vehicles += 1 if typ['acceleration_controller'][0] == RLController: self.num_rl_vehicles += 1 @@ -290,6 +293,12 @@ def _add_departed(self, veh_id, veh_type): # specify the type self.__vehicles[veh_id]["type"] = veh_type + # specify energy model + energy_model = \ + self.type_parameters[veh_type]["energy_model"] + self.__vehicles[veh_id]["energy_model"] = \ + energy_model[0](veh_id, **energy_model[1]) + car_following_params = \ self.type_parameters[veh_type]["car_following_params"] @@ -336,7 +345,8 @@ def _add_departed(self, veh_id, veh_type): tc.VAR_POSITION, tc.VAR_ANGLE, tc.VAR_SPEED_WITHOUT_TRACI, - tc.VAR_FUELCONSUMPTION + tc.VAR_FUELCONSUMPTION, + tc.VAR_DISTANCE ]) self.kernel_api.vehicle.subscribeLeader(veh_id, 2000) @@ -546,6 +556,16 @@ def get_fuel_consumption(self, veh_id, error=-1001): return [self.get_fuel_consumption(vehID, error) for vehID in veh_id] return self.__sumo_obs.get(veh_id, {}).get(tc.VAR_FUELCONSUMPTION, error) * ml_to_gallons + def get_energy_model(self, veh_id): + """See parent class.""" + if isinstance(veh_id, (list, np.ndarray)): + return [self.get_energy_model(vehID) for vehID in veh_id] + + if "energy_model" in self.__vehicles.get(veh_id, {}): + return self.__vehicles.get(veh_id, {})["energy_model"] + else: + raise KeyError("Energy model not set for {}".format(veh_id)) + def get_previous_speed(self, veh_id, error=-1001): """See parent class.""" if isinstance(veh_id, (list, np.ndarray)): @@ -750,7 +770,7 @@ def _multi_lane_headways(self): for lane in range(max_lanes): edge_dict[edge][lane].sort(key=lambda x: x[1]) - for veh_id in self.get_rl_ids(): + for veh_id in self.get_ids(): # collect the lane leaders, followers, headways, and tailways for # each vehicle edge = self.get_edge(veh_id) @@ -954,17 +974,32 @@ def _prev_edge_followers(self, veh_id, edge_dict, lane, num_edges): def apply_acceleration(self, veh_ids, acc): """See parent class.""" - # to hand the case of a single vehicle + # to handle the case of a single vehicle if type(veh_ids) == str: veh_ids = [veh_ids] acc = [acc] for i, vid in enumerate(veh_ids): if acc[i] is not None and vid in self.get_ids(): + self.__vehicles[vid]["accel"] = acc[i] this_vel = self.get_speed(vid) next_vel = max([this_vel + acc[i] * self.sim_step, 0]) self.kernel_api.vehicle.slowDown(vid, next_vel, 1e-3) + def apply_acceleration_not_smooth(self, veh_ids, acc): + """See parent class.""" + # to handle the case of a single vehicle + if type(veh_ids) == str: + veh_ids = [veh_ids] + acc = [acc] + + for i, vid in enumerate(veh_ids): + if acc[i] is not None and vid in self.get_ids(): + self.__vehicles[vid]["accel"] = acc[i] + this_vel = self.get_speed(vid) + next_vel = max([this_vel + acc[i] * self.sim_step, 0]) + self.kernel_api.vehicle.setSpeed(vid, next_vel) + def apply_lane_change(self, veh_ids, direction): """See parent class.""" # to hand the case of a single vehicle @@ -993,7 +1028,7 @@ def apply_lane_change(self, veh_ids, direction): # perform the requested lane action action in TraCI if target_lane != this_lane: self.kernel_api.vehicle.changeLane( - veh_id, int(target_lane), 100000) + veh_id, int(target_lane), self.sim_step) if veh_id in self.get_rl_ids(): self.prev_last_lc[veh_id] = \ @@ -1013,6 +1048,8 @@ def choose_routes(self, veh_ids, route_choices): def get_x_by_id(self, veh_id): """See parent class.""" + if isinstance(veh_id, (list, np.ndarray)): + return [self.get_x_by_id(vehID) for vehID in veh_id] if self.get_edge(veh_id) == '': # occurs when a vehicle crashes is teleported for some other reason return 0. @@ -1121,3 +1158,69 @@ def get_max_speed(self, veh_id, error=-1001): def set_max_speed(self, veh_id, max_speed): """See parent class.""" self.kernel_api.vehicle.setMaxSpeed(veh_id, max_speed) + + # add for data pipeline + def get_accel(self, veh_id): + """See parent class.""" + if "accel" not in self.__vehicles[veh_id]: + self.__vehicles[veh_id]["accel"] = None + return self.__vehicles[veh_id]["accel"] + + def update_accel_no_noise_no_failsafe(self, veh_id, accel_no_noise_no_failsafe): + """See parent class.""" + self.__vehicles[veh_id]["accel_no_noise_no_failsafe"] = accel_no_noise_no_failsafe + + def update_accel_no_noise_with_failsafe(self, veh_id, accel_no_noise_with_failsafe): + """See parent class.""" + self.__vehicles[veh_id]["accel_no_noise_with_failsafe"] = accel_no_noise_with_failsafe + + def update_accel_with_noise_no_failsafe(self, veh_id, accel_with_noise_no_failsafe): + """See parent class.""" + self.__vehicles[veh_id]["accel_with_noise_no_failsafe"] = accel_with_noise_no_failsafe + + def update_accel_with_noise_with_failsafe(self, veh_id, accel_with_noise_with_failsafe): + """See parent class.""" + self.__vehicles[veh_id]["accel_with_noise_with_failsafe"] = accel_with_noise_with_failsafe + + def get_accel_no_noise_no_failsafe(self, veh_id): + """See parent class.""" + if "accel_no_noise_no_failsafe" not in self.__vehicles[veh_id]: + self.__vehicles[veh_id]["accel_no_noise_no_failsafe"] = None + return self.__vehicles[veh_id]["accel_no_noise_no_failsafe"] + + def get_accel_no_noise_with_failsafe(self, veh_id): + """See parent class.""" + if "accel_no_noise_with_failsafe" not in self.__vehicles[veh_id]: + self.__vehicles[veh_id]["accel_no_noise_with_failsafe"] = None + return self.__vehicles[veh_id]["accel_no_noise_with_failsafe"] + + def get_accel_with_noise_no_failsafe(self, veh_id): + """See parent class.""" + if "accel_with_noise_no_failsafe" not in self.__vehicles[veh_id]: + self.__vehicles[veh_id]["accel_with_noise_no_failsafe"] = None + return self.__vehicles[veh_id]["accel_with_noise_no_failsafe"] + + def get_accel_with_noise_with_failsafe(self, veh_id): + """See parent class.""" + if "accel_with_noise_with_failsafe" not in self.__vehicles[veh_id]: + self.__vehicles[veh_id]["accel_with_noise_with_failsafe"] = None + return self.__vehicles[veh_id]["accel_with_noise_with_failsafe"] + + def get_realized_accel(self, veh_id): + """See parent class.""" + if self.get_distance(veh_id) == 0: + return 0 + return (self.get_speed(veh_id) - self.get_previous_speed(veh_id)) / self.sim_step + + def get_2d_position(self, veh_id, error=-1001): + """See parent class.""" + return self.__sumo_obs.get(veh_id, {}).get(tc.VAR_POSITION, error) + + def get_distance(self, veh_id, error=-1001): + """See parent class.""" + return self.__sumo_obs.get(veh_id, {}).get(tc.VAR_DISTANCE, error) + + def get_road_grade(self, veh_id): + """See parent class.""" + # TODO : Brent + return 0 diff --git a/flow/core/params.py b/flow/core/params.py index 79ad8d689..cfa2cf853 100755 --- a/flow/core/params.py +++ b/flow/core/params.py @@ -7,6 +7,10 @@ from flow.controllers.car_following_models import SimCarFollowingController from flow.controllers.rlcontroller import RLController from flow.controllers.lane_change_controllers import SimLaneChangeController +from flow.energy_models.toyota_energy import PriusEnergy +from flow.energy_models.toyota_energy import TacomaEnergy +from flow.energy_models.power_demand import PDMCombustionEngine +from flow.energy_models.power_demand import PDMElectric SPEED_MODES = { @@ -39,6 +43,8 @@ "only_right_drive_safe": 576 } +ENERGY_MODELS = set([PriusEnergy, TacomaEnergy, PDMCombustionEngine, PDMElectric]) + # Traffic light defaults PROGRAM_ID = 1 MAX_GAP = 3.0 @@ -262,6 +268,7 @@ def add(self, num_vehicles=0, car_following_params=None, lane_change_params=None, + energy_model=PDMCombustionEngine, color=None): """Add a sequence of vehicles to the list of vehicles in the network. @@ -298,6 +305,9 @@ def add(self, # FIXME: depends on simulator lane_change_params = SumoLaneChangeParams() + if energy_model not in ENERGY_MODELS: + energy_model = PDMCombustionEngine + type_params = {} type_params.update(car_following_params.controller_params) type_params.update(lane_change_params.controller_params) @@ -311,7 +321,8 @@ def add(self, "routing_controller": routing_controller, "initial_speed": initial_speed, "car_following_params": car_following_params, - "lane_change_params": lane_change_params} + "lane_change_params": lane_change_params, + "energy_model": energy_model} if color: type_params['color'] = color @@ -334,7 +345,9 @@ def add(self, "car_following_params": car_following_params, "lane_change_params": - lane_change_params + lane_change_params, + "energy_model": + energy_model }) # This is used to return the actual headways from the vehicles class. @@ -588,6 +601,8 @@ class SumoParams(SimParams): current time step use_ballistic: bool, optional If true, use a ballistic integration step instead of an euler step + disable_collisions: bool, optional + If true, disables explicit collision checking and teleporting in SUMO """ def __init__(self, @@ -609,7 +624,8 @@ def __init__(self, teleport_time=-1, num_clients=1, color_by_speed=False, - use_ballistic=False): + use_ballistic=False, + disable_collisions=False): """Instantiate SumoParams.""" super(SumoParams, self).__init__( sim_step, render, restart_instance, emission_path, save_render, @@ -624,6 +640,7 @@ def __init__(self, self.num_clients = num_clients self.color_by_speed = color_by_speed self.use_ballistic = use_ballistic + self.disable_collisions = disable_collisions class EnvParams: @@ -657,6 +674,9 @@ class EnvParams: specifies whether to clip actions from the policy by their range when they are inputted to the reward function. Note that the actions are still clipped before they are provided to `apply_rl_actions`. + done_at_exit : bool, optional + If true, done is returned as True when the vehicle exits. This is only + applied to multi-agent environments. """ def __init__(self, @@ -665,7 +685,8 @@ def __init__(self, warmup_steps=0, sims_per_step=1, evaluate=False, - clip_actions=True): + clip_actions=True, + done_at_exit=True): """Instantiate EnvParams.""" self.additional_params = \ additional_params if additional_params is not None else {} @@ -674,6 +695,7 @@ def __init__(self, self.sims_per_step = sims_per_step self.evaluate = evaluate self.clip_actions = clip_actions + self.done_at_exit = done_at_exit def get_additional_param(self, key): """Return a variable from additional_params.""" diff --git a/flow/core/rewards.py b/flow/core/rewards.py index 3cca916f5..6825043a2 100755 --- a/flow/core/rewards.py +++ b/flow/core/rewards.py @@ -322,6 +322,8 @@ def energy_consumption(env, gain=.001): rho = 1.225 # air density (kg/m^3) A = 2.6 # vehicle cross sectional area (m^2) for veh_id in env.k.vehicle.get_ids(): + if veh_id not in env.k.vehicle.previous_speeds.keys(): + continue speed = env.k.vehicle.get_speed(veh_id) prev_speed = env.k.vehicle.get_previous_speed(veh_id) @@ -347,6 +349,10 @@ def veh_energy_consumption(env, veh_id, gain=.001): Ca = 0.3 # aerodynamic drag coefficient rho = 1.225 # air density (kg/m^3) A = 2.6 # vehicle cross sectional area (m^2) + + if veh_id not in env.k.vehicle.previous_speeds: + return 0 + speed = env.k.vehicle.get_speed(veh_id) prev_speed = env.k.vehicle.get_previous_speed(veh_id) @@ -384,7 +390,7 @@ def miles_per_megajoule(env, veh_ids=None, gain=.001): speed = env.k.vehicle.get_speed(veh_id) # convert to be positive since the function called is a penalty power = -veh_energy_consumption(env, veh_id, gain=1.0) - if power > 0 and speed >= 0.0: + if power > 0 and speed >= 0.1: counter += 1 # meters / joule is (v * \delta t) / (power * \delta t) mpj += speed / power @@ -394,7 +400,7 @@ def miles_per_megajoule(env, veh_ids=None, gain=.001): # convert from meters per joule to miles per joule mpj /= 1609.0 # convert from miles per joule to miles per megajoule - mpj *= 10**6 + mpj *= 10 ** 6 return mpj * gain @@ -436,3 +442,22 @@ def miles_per_gallon(env, veh_ids=None, gain=.001): mpg /= 1609.0 return mpg * gain + + +def instantaneous_power(env, veh_id): + """Calculate the instantaneous power for every simulation step specific to the vehicle type. + + Parameters + ---------- + env : flow.envs.Env + the environment variable, which contains information on the current + state of the system. + veh_id : str + veh_id to compute the reward for + """ + speed = env.k.vehicle.get_speed(veh_id) + accel = env.k.vehicle.get_accel_no_noise_with_failsafe(veh_id) + grade = env.k.vehicle.get_road_grade(veh_id) + inst_power = env.k.vehicle.get_energy_model(veh_id).get_instantaneous_power(accel, speed, grade) + + return inst_power diff --git a/flow/energy_models/base_energy.py b/flow/energy_models/base_energy.py new file mode 100644 index 000000000..6c10d1eeb --- /dev/null +++ b/flow/energy_models/base_energy.py @@ -0,0 +1,36 @@ +"""Script containing the base vehicle energy class.""" +from abc import ABCMeta, abstractmethod + + +class BaseEnergyModel(metaclass=ABCMeta): + """Base energy model class. + + Calculate the instantaneous power consumption of a vehicle in + the network. It returns the power in Watts regardless of the + vehicle type: whether EV or Combustion Engine, Toyota Prius or Tacoma + or non-Toyota vehicles. Non-Toyota vehicles are set by default + to be an averaged-size vehicle. + """ + + def __init__(self, kernel): + self.k = kernel + + @abstractmethod + def get_instantaneous_power(self, accel, speed, grade): + """Calculate the instantaneous power consumption of a vehicle. + + Must be implemented by child classes. + + Parameters + ---------- + accel : float + Instantaneous acceleration of the vehicle + speed : float + Instantaneous speed of the vehicle + grade : float + Instantaneous road grade of the vehicle + Returns + ------- + float + """ + pass diff --git a/flow/energy_models/power_demand.py b/flow/energy_models/power_demand.py new file mode 100644 index 000000000..03e859c33 --- /dev/null +++ b/flow/energy_models/power_demand.py @@ -0,0 +1,109 @@ +"""Script containing the vehicle power demand model energy classes.""" +import math +import numpy as np +from flow.energy_models.base_energy import BaseEnergyModel +from abc import ABCMeta, abstractmethod + + +class PowerDemandModel(BaseEnergyModel, metaclass=ABCMeta): + """Vehicle Power Demand base energy model class. + + Calculate power consumption of a vehicle based on physics + derivation. Assumes some vehicle characteristics. The + power calculated here is the lower bound of the actual + power consumed by the vehicle. + """ + + def __init__(self, kernel, mass=2041, area=3.2, rolling_res_coeff=0.0027, aerodynamic_drag_coeff=0.4): + self.k = kernel + self.g = 9.807 + self.rho_air = 1.225 + self.mass = mass + self.rolling_res_coeff = rolling_res_coeff + self.aerodynamic_drag_coeff = aerodynamic_drag_coeff + self.cross_area = area + self.gamma = 1 + + def calculate_power_at_the_wheels(self, accel, speed, grade): + """Calculate the instantaneous power required. + + Parameters + ---------- + accel : float + Instantaneous acceleration of the vehicle + speed : float + Instantaneous speed of the vehicle + grade : float + Instantaneous road grade of the vehicle + Returns + ------- + float + """ + accel_slope_forces = self.mass * speed * ((np.heaviside(accel, 0.5) * (1 - self.gamma) + self.gamma)) * accel + accel_slope_forces += + self.g * math.sin(grade) + rolling_friction = self.mass * self.g * self.rolling_res_coeff * speed + air_drag = 0.5 * self.rho_air * self.cross_area * self.aerodynamic_drag_coeff * speed**3 + power = accel_slope_forces + rolling_friction + air_drag + return power + + @abstractmethod + def get_regen_cap(self, accel, speed, grade): + """Set the maximum power retainable from regenerative braking. + + A negative regen cap is interpretted as a positive regenerative power. + + Parameters + ---------- + accel : float + Instantaneous acceleration of the vehicle + speed : float + Instantaneous speed of the vehicle + grade : float + Instantaneous road grade of the vehicle + Returns + ------- + float + """ + pass + + def get_instantaneous_power(self, accel, speed, grade): + """Apply the regenerative braking cap to the modelled power demand. + + Parameters + ---------- + accel : float + Instantaneous acceleration of the vehicle + speed : float + Instantaneous speed of the vehicle + grade : float + Instantaneous road grade of the vehicle + Returns + ------- + float + """ + regen_cap = self.get_regen_cap(accel, speed, grade) + power_at_the_wheels = self.calculate_power_at_the_wheels(accel, speed, grade) + return max(regen_cap, power_at_the_wheels) + + +class PDMCombustionEngine(PowerDemandModel): + """Power Demand Model for a combustion engine vehicle.""" + + def get_regen_cap(self, accel, speed, grade): + """See parent class.""" + return 0 + + +class PDMElectric(PowerDemandModel): + """Power Demand Model for an electric vehicle.""" + + def __init__(self, kernel): + super(PDMElectric, self).__init__(kernel, + mass=1663, + area=2.4, + rolling_res_coeff=0.007, + aerodynamic_drag_coeff=0.24) + + def get_regen_cap(self, accel, speed, grade): + """See parent class.""" + return -2.8 * speed diff --git a/flow/energy_models/toyota_energy.py b/flow/energy_models/toyota_energy.py new file mode 100644 index 000000000..864dabd2b --- /dev/null +++ b/flow/energy_models/toyota_energy.py @@ -0,0 +1,54 @@ +"""Script containing the Toyota energy classes.""" +import dill as pickle +import boto3 +from flow.energy_models.base_energy import BaseEnergyModel +import os +from abc import ABCMeta, abstractmethod + + +class ToyotaModel(BaseEnergyModel, metaclass=ABCMeta): + """Base Toyota Energy model class.""" + + def __init__(self, kernel, filename=None): + self.k = kernel + + # download file from s3 bucket + s3 = boto3.client('s3') + s3.download_file('toyota.restricted', filename, 'temp.pkl') + with open('temp.pkl', 'rb') as file: + self.toyota_energy = pickle.load(file) + + # delete pickle file + os.remove(file.pkl) + + @abstractmethod + def get_instantaneous_power(self, accel, speed, grade): + """See parent class.""" + pass + + +class PriusEnergy(ToyotaModel): + """Toyota Prius (EV) energy model class.""" + + def __init__(self, kernel, soc=0.9): + super(PriusEnergy, self).__init__(kernel, filename='prius_ev.pkl') + self.soc = soc + + def get_instantaneous_power(self, accel, speed, grade): + """See parent class.""" + socdot = self.toyota_energy(self.soc, accel, speed, grade) + self.soc -= socdot * self.k.env.sim_step + # FIXME (Joy): convert socdot to power + return socdot + + +class TacomaEnergy(ToyotaModel): + """Toyota Tacoma energy model class.""" + + def __init__(self, kernel): + super(TacomaEnergy, self).__init__(kernel, filename='tacoma.pkl') + + def get_instantaneous_power(self, accel, speed, grade): + """See parent class.""" + fc = self.toyota_energy(accel, speed, grade) + return fc From 9f30c08150f0cec5d5597553868deac124d3d077 Mon Sep 17 00:00:00 2001 From: liljonnystyle Date: Mon, 6 Jul 2020 19:39:22 -0700 Subject: [PATCH 02/14] fix mistakes from interactive patch merge --- flow/core/kernel/vehicle/base.py | 81 ------------------------- flow/core/kernel/vehicle/traci.py | 92 +---------------------------- flow/core/params.py | 17 +----- flow/core/rewards.py | 9 +-- flow/energy_models/toyota_energy.py | 54 ----------------- 5 files changed, 8 insertions(+), 245 deletions(-) delete mode 100644 flow/energy_models/toyota_energy.py diff --git a/flow/core/kernel/vehicle/base.py b/flow/core/kernel/vehicle/base.py index 2ca51a187..808c3a53a 100644 --- a/flow/core/kernel/vehicle/base.py +++ b/flow/core/kernel/vehicle/base.py @@ -131,23 +131,6 @@ def remove(self, veh_id): def apply_acceleration(self, veh_id, acc): """Apply the acceleration requested by a vehicle in the simulator. - In SUMO, this function applies slowDown method which applies smoothing. - - Parameters - ---------- - veh_id : str or list of str - list of vehicle identifiers - acc : float or array_like - requested accelerations from the vehicles - """ - raise NotImplementedError - - def apply_acceleration_not_smooth(self, veh_id, acc): - """Apply the acceleration requested by a vehicle in the simulator. - - In SUMO, this function applies setSpeed method which doesn't apply - smoothing. - Parameters ---------- veh_id : str or list of str @@ -772,67 +755,3 @@ def get_max_speed(self, veh_id, error): float """ pass - - ########################################################################### - # Methods for Datapipeline # - ########################################################################### - - @abstractmethod - def get_accel(self, veh_id): - """Return the acceleration of vehicle with veh_id.""" - pass - - @abstractmethod - def update_accel_no_noise_no_failsafe(self, veh_id, accel_no_noise_no_failsafe): - """Update stored acceleration without noise without failsafe of vehicle with veh_id.""" - pass - - @abstractmethod - def update_accel_no_noise_with_failsafe(self, veh_id, accel_no_noise_with_failsafe): - """Update stored acceleration without noise with failsafe of vehicle with veh_id.""" - raise NotImplementedError - - @abstractmethod - def update_accel_with_noise_no_failsafe(self, veh_id, accel_with_noise_no_failsafe): - """Update stored acceleration with noise without failsafe of vehicle with veh_id.""" - pass - - @abstractmethod - def update_accel_with_noise_with_failsafe(self, veh_id, accel_with_noise_with_failsafe): - """Update stored acceleration with noise with failsafe of vehicle with veh_id.""" - pass - - @abstractmethod - def get_2d_position(self, veh_id, error=-1001): - """Return (x, y) position of vehicle with veh_id.""" - pass - - @abstractmethod - def get_accel_no_noise_no_failsafe(self, veh_id): - """Return the acceleration without noise without failsafe of vehicle with veh_id.""" - pass - - @abstractmethod - def get_accel_no_noise_with_failsafe(self, veh_id): - """Return the acceleration without noise with failsafe of vehicle with veh_id.""" - pass - - @abstractmethod - def get_accel_with_noise_no_failsafe(self, veh_id): - """Return the acceleration with noise without failsafe of vehicle with veh_id.""" - pass - - @abstractmethod - def get_accel_with_noise_with_failsafe(self, veh_id): - """Return the acceleration with noise with failsafe of vehicle with veh_id.""" - pass - - @abstractmethod - def get_realized_accel(self, veh_id): - """Return the acceleration that the vehicle actually make.""" - pass - - @abstractmethod - def get_road_grade(self, veh_id): - """Return the road-grade of the vehicle with veh_id.""" - pass diff --git a/flow/core/kernel/vehicle/traci.py b/flow/core/kernel/vehicle/traci.py index 00ee1aeac..920eddbea 100644 --- a/flow/core/kernel/vehicle/traci.py +++ b/flow/core/kernel/vehicle/traci.py @@ -87,8 +87,6 @@ def __init__(self, # old speeds used to compute accelerations self.previous_speeds = {} - # The time that previous speed is recorded, used to calculate realized_accel - self.previous_time = 0 def initialize(self, vehicles): """Initialize vehicle state information. @@ -107,7 +105,6 @@ def initialize(self, vehicles): self.num_vehicles = 0 self.num_rl_vehicles = 0 self.num_not_departed = 0 - self.__vehicles.clear() for typ in vehicles.initial: for i in range(typ['num_vehicles']): @@ -753,7 +750,7 @@ def _multi_lane_headways(self): edge_dict = dict.fromkeys(tot_list) # add the vehicles to the edge_dict element - for veh_id in self.get_ids(): + for veh_id in self.get_rl_ids(): edge = self.get_edge(veh_id) lane = self.get_lane(veh_id) pos = self.get_position(veh_id) @@ -974,32 +971,17 @@ def _prev_edge_followers(self, veh_id, edge_dict, lane, num_edges): def apply_acceleration(self, veh_ids, acc): """See parent class.""" - # to handle the case of a single vehicle + # to hand the case of a single vehicle if type(veh_ids) == str: veh_ids = [veh_ids] acc = [acc] for i, vid in enumerate(veh_ids): if acc[i] is not None and vid in self.get_ids(): - self.__vehicles[vid]["accel"] = acc[i] this_vel = self.get_speed(vid) next_vel = max([this_vel + acc[i] * self.sim_step, 0]) self.kernel_api.vehicle.slowDown(vid, next_vel, 1e-3) - def apply_acceleration_not_smooth(self, veh_ids, acc): - """See parent class.""" - # to handle the case of a single vehicle - if type(veh_ids) == str: - veh_ids = [veh_ids] - acc = [acc] - - for i, vid in enumerate(veh_ids): - if acc[i] is not None and vid in self.get_ids(): - self.__vehicles[vid]["accel"] = acc[i] - this_vel = self.get_speed(vid) - next_vel = max([this_vel + acc[i] * self.sim_step, 0]) - self.kernel_api.vehicle.setSpeed(vid, next_vel) - def apply_lane_change(self, veh_ids, direction): """See parent class.""" # to hand the case of a single vehicle @@ -1028,7 +1010,7 @@ def apply_lane_change(self, veh_ids, direction): # perform the requested lane action action in TraCI if target_lane != this_lane: self.kernel_api.vehicle.changeLane( - veh_id, int(target_lane), self.sim_step) + veh_id, int(target_lane), 100000) if veh_id in self.get_rl_ids(): self.prev_last_lc[veh_id] = \ @@ -1048,8 +1030,6 @@ def choose_routes(self, veh_ids, route_choices): def get_x_by_id(self, veh_id): """See parent class.""" - if isinstance(veh_id, (list, np.ndarray)): - return [self.get_x_by_id(vehID) for vehID in veh_id] if self.get_edge(veh_id) == '': # occurs when a vehicle crashes is teleported for some other reason return 0. @@ -1158,69 +1138,3 @@ def get_max_speed(self, veh_id, error=-1001): def set_max_speed(self, veh_id, max_speed): """See parent class.""" self.kernel_api.vehicle.setMaxSpeed(veh_id, max_speed) - - # add for data pipeline - def get_accel(self, veh_id): - """See parent class.""" - if "accel" not in self.__vehicles[veh_id]: - self.__vehicles[veh_id]["accel"] = None - return self.__vehicles[veh_id]["accel"] - - def update_accel_no_noise_no_failsafe(self, veh_id, accel_no_noise_no_failsafe): - """See parent class.""" - self.__vehicles[veh_id]["accel_no_noise_no_failsafe"] = accel_no_noise_no_failsafe - - def update_accel_no_noise_with_failsafe(self, veh_id, accel_no_noise_with_failsafe): - """See parent class.""" - self.__vehicles[veh_id]["accel_no_noise_with_failsafe"] = accel_no_noise_with_failsafe - - def update_accel_with_noise_no_failsafe(self, veh_id, accel_with_noise_no_failsafe): - """See parent class.""" - self.__vehicles[veh_id]["accel_with_noise_no_failsafe"] = accel_with_noise_no_failsafe - - def update_accel_with_noise_with_failsafe(self, veh_id, accel_with_noise_with_failsafe): - """See parent class.""" - self.__vehicles[veh_id]["accel_with_noise_with_failsafe"] = accel_with_noise_with_failsafe - - def get_accel_no_noise_no_failsafe(self, veh_id): - """See parent class.""" - if "accel_no_noise_no_failsafe" not in self.__vehicles[veh_id]: - self.__vehicles[veh_id]["accel_no_noise_no_failsafe"] = None - return self.__vehicles[veh_id]["accel_no_noise_no_failsafe"] - - def get_accel_no_noise_with_failsafe(self, veh_id): - """See parent class.""" - if "accel_no_noise_with_failsafe" not in self.__vehicles[veh_id]: - self.__vehicles[veh_id]["accel_no_noise_with_failsafe"] = None - return self.__vehicles[veh_id]["accel_no_noise_with_failsafe"] - - def get_accel_with_noise_no_failsafe(self, veh_id): - """See parent class.""" - if "accel_with_noise_no_failsafe" not in self.__vehicles[veh_id]: - self.__vehicles[veh_id]["accel_with_noise_no_failsafe"] = None - return self.__vehicles[veh_id]["accel_with_noise_no_failsafe"] - - def get_accel_with_noise_with_failsafe(self, veh_id): - """See parent class.""" - if "accel_with_noise_with_failsafe" not in self.__vehicles[veh_id]: - self.__vehicles[veh_id]["accel_with_noise_with_failsafe"] = None - return self.__vehicles[veh_id]["accel_with_noise_with_failsafe"] - - def get_realized_accel(self, veh_id): - """See parent class.""" - if self.get_distance(veh_id) == 0: - return 0 - return (self.get_speed(veh_id) - self.get_previous_speed(veh_id)) / self.sim_step - - def get_2d_position(self, veh_id, error=-1001): - """See parent class.""" - return self.__sumo_obs.get(veh_id, {}).get(tc.VAR_POSITION, error) - - def get_distance(self, veh_id, error=-1001): - """See parent class.""" - return self.__sumo_obs.get(veh_id, {}).get(tc.VAR_DISTANCE, error) - - def get_road_grade(self, veh_id): - """See parent class.""" - # TODO : Brent - return 0 diff --git a/flow/core/params.py b/flow/core/params.py index cfa2cf853..329ce3ed8 100755 --- a/flow/core/params.py +++ b/flow/core/params.py @@ -7,8 +7,6 @@ from flow.controllers.car_following_models import SimCarFollowingController from flow.controllers.rlcontroller import RLController from flow.controllers.lane_change_controllers import SimLaneChangeController -from flow.energy_models.toyota_energy import PriusEnergy -from flow.energy_models.toyota_energy import TacomaEnergy from flow.energy_models.power_demand import PDMCombustionEngine from flow.energy_models.power_demand import PDMElectric @@ -43,7 +41,7 @@ "only_right_drive_safe": 576 } -ENERGY_MODELS = set([PriusEnergy, TacomaEnergy, PDMCombustionEngine, PDMElectric]) +ENERGY_MODELS = set([PDMCombustionEngine, PDMElectric]) # Traffic light defaults PROGRAM_ID = 1 @@ -601,8 +599,6 @@ class SumoParams(SimParams): current time step use_ballistic: bool, optional If true, use a ballistic integration step instead of an euler step - disable_collisions: bool, optional - If true, disables explicit collision checking and teleporting in SUMO """ def __init__(self, @@ -624,8 +620,7 @@ def __init__(self, teleport_time=-1, num_clients=1, color_by_speed=False, - use_ballistic=False, - disable_collisions=False): + use_ballistic=False): """Instantiate SumoParams.""" super(SumoParams, self).__init__( sim_step, render, restart_instance, emission_path, save_render, @@ -640,7 +635,6 @@ def __init__(self, self.num_clients = num_clients self.color_by_speed = color_by_speed self.use_ballistic = use_ballistic - self.disable_collisions = disable_collisions class EnvParams: @@ -674,9 +668,6 @@ class EnvParams: specifies whether to clip actions from the policy by their range when they are inputted to the reward function. Note that the actions are still clipped before they are provided to `apply_rl_actions`. - done_at_exit : bool, optional - If true, done is returned as True when the vehicle exits. This is only - applied to multi-agent environments. """ def __init__(self, @@ -685,8 +676,7 @@ def __init__(self, warmup_steps=0, sims_per_step=1, evaluate=False, - clip_actions=True, - done_at_exit=True): + clip_actions=True): """Instantiate EnvParams.""" self.additional_params = \ additional_params if additional_params is not None else {} @@ -695,7 +685,6 @@ def __init__(self, self.sims_per_step = sims_per_step self.evaluate = evaluate self.clip_actions = clip_actions - self.done_at_exit = done_at_exit def get_additional_param(self, key): """Return a variable from additional_params.""" diff --git a/flow/core/rewards.py b/flow/core/rewards.py index 6825043a2..d2c10ec63 100755 --- a/flow/core/rewards.py +++ b/flow/core/rewards.py @@ -322,8 +322,6 @@ def energy_consumption(env, gain=.001): rho = 1.225 # air density (kg/m^3) A = 2.6 # vehicle cross sectional area (m^2) for veh_id in env.k.vehicle.get_ids(): - if veh_id not in env.k.vehicle.previous_speeds.keys(): - continue speed = env.k.vehicle.get_speed(veh_id) prev_speed = env.k.vehicle.get_previous_speed(veh_id) @@ -350,9 +348,6 @@ def veh_energy_consumption(env, veh_id, gain=.001): rho = 1.225 # air density (kg/m^3) A = 2.6 # vehicle cross sectional area (m^2) - if veh_id not in env.k.vehicle.previous_speeds: - return 0 - speed = env.k.vehicle.get_speed(veh_id) prev_speed = env.k.vehicle.get_previous_speed(veh_id) @@ -390,7 +385,7 @@ def miles_per_megajoule(env, veh_ids=None, gain=.001): speed = env.k.vehicle.get_speed(veh_id) # convert to be positive since the function called is a penalty power = -veh_energy_consumption(env, veh_id, gain=1.0) - if power > 0 and speed >= 0.1: + if power > 0 and speed >= 0.0: counter += 1 # meters / joule is (v * \delta t) / (power * \delta t) mpj += speed / power @@ -400,7 +395,7 @@ def miles_per_megajoule(env, veh_ids=None, gain=.001): # convert from meters per joule to miles per joule mpj /= 1609.0 # convert from miles per joule to miles per megajoule - mpj *= 10 ** 6 + mpj *= 10**6 return mpj * gain diff --git a/flow/energy_models/toyota_energy.py b/flow/energy_models/toyota_energy.py deleted file mode 100644 index 864dabd2b..000000000 --- a/flow/energy_models/toyota_energy.py +++ /dev/null @@ -1,54 +0,0 @@ -"""Script containing the Toyota energy classes.""" -import dill as pickle -import boto3 -from flow.energy_models.base_energy import BaseEnergyModel -import os -from abc import ABCMeta, abstractmethod - - -class ToyotaModel(BaseEnergyModel, metaclass=ABCMeta): - """Base Toyota Energy model class.""" - - def __init__(self, kernel, filename=None): - self.k = kernel - - # download file from s3 bucket - s3 = boto3.client('s3') - s3.download_file('toyota.restricted', filename, 'temp.pkl') - with open('temp.pkl', 'rb') as file: - self.toyota_energy = pickle.load(file) - - # delete pickle file - os.remove(file.pkl) - - @abstractmethod - def get_instantaneous_power(self, accel, speed, grade): - """See parent class.""" - pass - - -class PriusEnergy(ToyotaModel): - """Toyota Prius (EV) energy model class.""" - - def __init__(self, kernel, soc=0.9): - super(PriusEnergy, self).__init__(kernel, filename='prius_ev.pkl') - self.soc = soc - - def get_instantaneous_power(self, accel, speed, grade): - """See parent class.""" - socdot = self.toyota_energy(self.soc, accel, speed, grade) - self.soc -= socdot * self.k.env.sim_step - # FIXME (Joy): convert socdot to power - return socdot - - -class TacomaEnergy(ToyotaModel): - """Toyota Tacoma energy model class.""" - - def __init__(self, kernel): - super(TacomaEnergy, self).__init__(kernel, filename='tacoma.pkl') - - def get_instantaneous_power(self, accel, speed, grade): - """See parent class.""" - fc = self.toyota_energy(accel, speed, grade) - return fc From b8dc6cbf4fdebe6e627f7d5368b84331c336823e Mon Sep 17 00:00:00 2001 From: liljonnystyle Date: Mon, 6 Jul 2020 19:43:36 -0700 Subject: [PATCH 03/14] fix mistakes from interactive patch merge --- flow/core/kernel/vehicle/traci.py | 6 +++--- flow/core/rewards.py | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/flow/core/kernel/vehicle/traci.py b/flow/core/kernel/vehicle/traci.py index 920eddbea..9510a1cba 100644 --- a/flow/core/kernel/vehicle/traci.py +++ b/flow/core/kernel/vehicle/traci.py @@ -105,6 +105,7 @@ def initialize(self, vehicles): self.num_vehicles = 0 self.num_rl_vehicles = 0 self.num_not_departed = 0 + self.__vehicles.clear() for typ in vehicles.initial: for i in range(typ['num_vehicles']): @@ -112,7 +113,6 @@ def initialize(self, vehicles): self.__vehicles[veh_id] = dict() self.__vehicles[veh_id]['type'] = typ['veh_id'] self.__vehicles[veh_id]['initial_speed'] = typ['initial_speed'] - self.num_vehicles += 1 if typ['acceleration_controller'][0] == RLController: self.num_rl_vehicles += 1 @@ -750,7 +750,7 @@ def _multi_lane_headways(self): edge_dict = dict.fromkeys(tot_list) # add the vehicles to the edge_dict element - for veh_id in self.get_rl_ids(): + for veh_id in self.get_ids(): edge = self.get_edge(veh_id) lane = self.get_lane(veh_id) pos = self.get_position(veh_id) @@ -767,7 +767,7 @@ def _multi_lane_headways(self): for lane in range(max_lanes): edge_dict[edge][lane].sort(key=lambda x: x[1]) - for veh_id in self.get_ids(): + for veh_id in self.get_rl_ids(): # collect the lane leaders, followers, headways, and tailways for # each vehicle edge = self.get_edge(veh_id) diff --git a/flow/core/rewards.py b/flow/core/rewards.py index d2c10ec63..5d194f9f4 100755 --- a/flow/core/rewards.py +++ b/flow/core/rewards.py @@ -347,7 +347,6 @@ def veh_energy_consumption(env, veh_id, gain=.001): Ca = 0.3 # aerodynamic drag coefficient rho = 1.225 # air density (kg/m^3) A = 2.6 # vehicle cross sectional area (m^2) - speed = env.k.vehicle.get_speed(veh_id) prev_speed = env.k.vehicle.get_previous_speed(veh_id) From 35011fcf5a2c62881709ff0257c4962f6e22a44c Mon Sep 17 00:00:00 2001 From: liljonnystyle Date: Mon, 6 Jul 2020 22:06:55 -0700 Subject: [PATCH 04/14] rm change from unrelated diff --- flow/core/kernel/vehicle/traci.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/flow/core/kernel/vehicle/traci.py b/flow/core/kernel/vehicle/traci.py index 9510a1cba..677a05972 100644 --- a/flow/core/kernel/vehicle/traci.py +++ b/flow/core/kernel/vehicle/traci.py @@ -342,8 +342,7 @@ def _add_departed(self, veh_id, veh_type): tc.VAR_POSITION, tc.VAR_ANGLE, tc.VAR_SPEED_WITHOUT_TRACI, - tc.VAR_FUELCONSUMPTION, - tc.VAR_DISTANCE + tc.VAR_FUELCONSUMPTION ]) self.kernel_api.vehicle.subscribeLeader(veh_id, 2000) From 4b6237e8d82c83fbc1a3bed52026f126cae53171 Mon Sep 17 00:00:00 2001 From: liljonnystyle Date: Tue, 7 Jul 2020 13:07:30 -0700 Subject: [PATCH 05/14] change error and default handling --- flow/core/kernel/vehicle/base.py | 4 +++- flow/core/kernel/vehicle/traci.py | 12 ++++++------ flow/core/params.py | 5 +++-- flow/core/rewards.py | 27 +++++++++++++++++++-------- 4 files changed, 31 insertions(+), 17 deletions(-) diff --git a/flow/core/kernel/vehicle/base.py b/flow/core/kernel/vehicle/base.py index 808c3a53a..98b543306 100644 --- a/flow/core/kernel/vehicle/base.py +++ b/flow/core/kernel/vehicle/base.py @@ -347,13 +347,15 @@ def get_fuel_consumption(self, veh_id, error=-1001): pass @abstractmethod - def get_energy_model(self, veh_id): + def get_energy_model(self, veh_id, error=""): """Return the energy model class object of the specified vehicle. Parameters ---------- veh_id : str or list of str vehicle id, or list of vehicle ids + error : str + value that is returned if the vehicle is not found Returns ------- subclass of BaseEnergyModel diff --git a/flow/core/kernel/vehicle/traci.py b/flow/core/kernel/vehicle/traci.py index 677a05972..1ee68d7ee 100644 --- a/flow/core/kernel/vehicle/traci.py +++ b/flow/core/kernel/vehicle/traci.py @@ -552,15 +552,15 @@ def get_fuel_consumption(self, veh_id, error=-1001): return [self.get_fuel_consumption(vehID, error) for vehID in veh_id] return self.__sumo_obs.get(veh_id, {}).get(tc.VAR_FUELCONSUMPTION, error) * ml_to_gallons - def get_energy_model(self, veh_id): + def get_energy_model(self, veh_id, error=""): """See parent class.""" if isinstance(veh_id, (list, np.ndarray)): return [self.get_energy_model(vehID) for vehID in veh_id] - - if "energy_model" in self.__vehicles.get(veh_id, {}): - return self.__vehicles.get(veh_id, {})["energy_model"] - else: - raise KeyError("Energy model not set for {}".format(veh_id)) + try: + return self.__vehicles.get(veh_id, {'energy_model': error})['energy_model'] + except KeyError: + print("Energy model not specified for vehicle {}".format(veh_id)) + raise def get_previous_speed(self, veh_id, error=-1001): """See parent class.""" diff --git a/flow/core/params.py b/flow/core/params.py index 329ce3ed8..4e7483dcd 100755 --- a/flow/core/params.py +++ b/flow/core/params.py @@ -42,6 +42,7 @@ } ENERGY_MODELS = set([PDMCombustionEngine, PDMElectric]) +DEFAULT_ENERGY_MODEL = PDMCombustionEngine # Traffic light defaults PROGRAM_ID = 1 @@ -266,7 +267,7 @@ def add(self, num_vehicles=0, car_following_params=None, lane_change_params=None, - energy_model=PDMCombustionEngine, + energy_model=DEFAULT_ENERGY_MODEL, color=None): """Add a sequence of vehicles to the list of vehicles in the network. @@ -304,7 +305,7 @@ def add(self, lane_change_params = SumoLaneChangeParams() if energy_model not in ENERGY_MODELS: - energy_model = PDMCombustionEngine + energy_model = DEFAULT_ENERGY_MODEL type_params = {} type_params.update(car_following_params.controller_params) diff --git a/flow/core/rewards.py b/flow/core/rewards.py index 5d194f9f4..9d5a11390 100755 --- a/flow/core/rewards.py +++ b/flow/core/rewards.py @@ -438,7 +438,7 @@ def miles_per_gallon(env, veh_ids=None, gain=.001): return mpg * gain -def instantaneous_power(env, veh_id): +def instantaneous_power(env, veh_ids=None, gain=.001): """Calculate the instantaneous power for every simulation step specific to the vehicle type. Parameters @@ -446,12 +446,23 @@ def instantaneous_power(env, veh_id): env : flow.envs.Env the environment variable, which contains information on the current state of the system. - veh_id : str - veh_id to compute the reward for + veh_ids : [list] or str + list of veh_ids or single veh_id to compute the reward over + gain : float + scaling factor for the reward """ - speed = env.k.vehicle.get_speed(veh_id) - accel = env.k.vehicle.get_accel_no_noise_with_failsafe(veh_id) - grade = env.k.vehicle.get_road_grade(veh_id) - inst_power = env.k.vehicle.get_energy_model(veh_id).get_instantaneous_power(accel, speed, grade) + if veh_ids is None: + veh_ids = env.k.vehicle.get_ids() + elif not isinstance(veh_ids, list): + veh_ids = [veh_ids] - return inst_power + inst_power = 0 + for veh_id in veh_ids: + energy_model = env.k.vehicle.get_energy_model(veh_id) + if energy_model != "": + speed = env.k.vehicle.get_speed(veh_id) + accel = env.k.vehicle.get_accel_no_noise_with_failsafe(veh_id) + grade = env.k.vehicle.get_road_grade(veh_id) + inst_power += energy_model.get_instantaneous_power(accel, speed, grade) + + return inst_power * gain From a36c3d3d63bbf870f26dae82e1d216ef3fe24ef7 Mon Sep 17 00:00:00 2001 From: liljonnystyle Date: Tue, 7 Jul 2020 13:23:20 -0700 Subject: [PATCH 06/14] add temporary ray test fix --- tests/fast_tests/test_examples.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/fast_tests/test_examples.py b/tests/fast_tests/test_examples.py index b5faf6517..8e871afb4 100644 --- a/tests/fast_tests/test_examples.py +++ b/tests/fast_tests/test_examples.py @@ -168,6 +168,7 @@ def test_parse_args(self): self.assertDictEqual(vars(args), { 'exp_config': 'exp_config', + 'local_mode': False, 'rl_trainer': 'rllib', 'num_cpus': 1, 'num_steps': 5000, @@ -188,6 +189,7 @@ def test_parse_args(self): self.assertDictEqual(vars(args), { 'checkpoint_path': '5', 'exp_config': 'exp_config', + 'local_mode': False, 'num_cpus': 1, 'num_steps': 3, 'rl_trainer': 'h-baselines', @@ -409,7 +411,7 @@ def run_exp(flow_params, **kwargs): alg_run, env_name, config = setup_rllib_exps(flow_params, 1, 1, **kwargs) try: - ray.init(num_cpus=1) + ray.init(num_cpus=1, local_mode=True) except Exception as e: print("ERROR", e) config['train_batch_size'] = 50 From 59b26659804075752d54006657151abe8737cbe9 Mon Sep 17 00:00:00 2001 From: liljonnystyle Date: Tue, 7 Jul 2020 18:49:55 -0700 Subject: [PATCH 07/14] implement true mpg correction and mpg reward --- flow/core/rewards.py | 151 +++-------------------------- flow/energy_models/base_energy.py | 23 +++++ flow/energy_models/power_demand.py | 42 ++++++-- 3 files changed, 72 insertions(+), 144 deletions(-) diff --git a/flow/core/rewards.py b/flow/core/rewards.py index 9d5a11390..b4af4c5bc 100755 --- a/flow/core/rewards.py +++ b/flow/core/rewards.py @@ -306,140 +306,8 @@ def punish_rl_lane_changes(env, penalty=1): return total_lane_change_penalty -def energy_consumption(env, gain=.001): - """Calculate power consumption of a vehicle. - - Assumes vehicle is an average sized vehicle. - The power calculated here is the lower bound of the actual power consumed - by a vehicle. - """ - power = 0 - - M = 1200 # mass of average sized vehicle (kg) - g = 9.81 # gravitational acceleration (m/s^2) - Cr = 0.005 # rolling resistance coefficient - Ca = 0.3 # aerodynamic drag coefficient - rho = 1.225 # air density (kg/m^3) - A = 2.6 # vehicle cross sectional area (m^2) - for veh_id in env.k.vehicle.get_ids(): - speed = env.k.vehicle.get_speed(veh_id) - prev_speed = env.k.vehicle.get_previous_speed(veh_id) - - accel = abs(speed - prev_speed) / env.sim_step - - power += M * speed * accel + M * g * Cr * speed + 0.5 * rho * A * Ca * speed ** 3 - - return -gain * power - - -def veh_energy_consumption(env, veh_id, gain=.001): - """Calculate power consumption of a vehicle. - - Assumes vehicle is an average sized vehicle. - The power calculated here is the lower bound of the actual power consumed - by a vehicle. - """ - power = 0 - - M = 1200 # mass of average sized vehicle (kg) - g = 9.81 # gravitational acceleration (m/s^2) - Cr = 0.005 # rolling resistance coefficient - Ca = 0.3 # aerodynamic drag coefficient - rho = 1.225 # air density (kg/m^3) - A = 2.6 # vehicle cross sectional area (m^2) - speed = env.k.vehicle.get_speed(veh_id) - prev_speed = env.k.vehicle.get_previous_speed(veh_id) - - accel = abs(speed - prev_speed) / env.sim_step - - power += M * speed * accel + M * g * Cr * speed + 0.5 * rho * A * Ca * speed ** 3 - - return -gain * power - - -def miles_per_megajoule(env, veh_ids=None, gain=.001): - """Calculate miles per mega-joule of either a particular vehicle or the total average of all the vehicles. - - Assumes vehicle is an average sized vehicle. - The power calculated here is the lower bound of the actual power consumed - by a vehicle. - - Parameters - ---------- - env : flow.envs.Env - the environment variable, which contains information on the current - state of the system. - veh_ids : [list] - list of veh_ids to compute the reward over - gain : float - scaling factor for the reward - """ - mpj = 0 - counter = 0 - if veh_ids is None: - veh_ids = env.k.vehicle.get_ids() - elif not isinstance(veh_ids, list): - veh_ids = [veh_ids] - for veh_id in veh_ids: - speed = env.k.vehicle.get_speed(veh_id) - # convert to be positive since the function called is a penalty - power = -veh_energy_consumption(env, veh_id, gain=1.0) - if power > 0 and speed >= 0.0: - counter += 1 - # meters / joule is (v * \delta t) / (power * \delta t) - mpj += speed / power - if counter > 0: - mpj /= counter - - # convert from meters per joule to miles per joule - mpj /= 1609.0 - # convert from miles per joule to miles per megajoule - mpj *= 10**6 - - return mpj * gain - - -def miles_per_gallon(env, veh_ids=None, gain=.001): - """Calculate mpg of either a particular vehicle or the total average of all the vehicles. - - Assumes vehicle is an average sized vehicle. - The power calculated here is the lower bound of the actual power consumed - by a vehicle. - - Parameters - ---------- - env : flow.envs.Env - the environment variable, which contains information on the current - state of the system. - veh_ids : [list] - list of veh_ids to compute the reward over - gain : float - scaling factor for the reward - """ - mpg = 0 - counter = 0 - if veh_ids is None: - veh_ids = env.k.vehicle.get_ids() - elif not isinstance(veh_ids, list): - veh_ids = [veh_ids] - for veh_id in veh_ids: - speed = env.k.vehicle.get_speed(veh_id) - gallons_per_s = env.k.vehicle.get_fuel_consumption(veh_id) - if gallons_per_s > 0 and speed >= 0.0: - counter += 1 - # meters / gallon is (v * \delta t) / (gallons_per_s * \delta t) - mpg += speed / gallons_per_s - if counter > 0: - mpg /= counter - - # convert from meters per gallon to miles per gallon - mpg /= 1609.0 - - return mpg * gain - - -def instantaneous_power(env, veh_ids=None, gain=.001): - """Calculate the instantaneous power for every simulation step specific to the vehicle type. +def instantaneous_mpg(env, veh_ids=None, gain=.001): + """Calculate the instantaneous mpg for every simulation step specific to the vehicle type. Parameters ---------- @@ -456,13 +324,22 @@ def instantaneous_power(env, veh_ids=None, gain=.001): elif not isinstance(veh_ids, list): veh_ids = [veh_ids] - inst_power = 0 + cumulative_gallons = 0 + cumulative_distance = 0 for veh_id in veh_ids: energy_model = env.k.vehicle.get_energy_model(veh_id) if energy_model != "": speed = env.k.vehicle.get_speed(veh_id) accel = env.k.vehicle.get_accel_no_noise_with_failsafe(veh_id) grade = env.k.vehicle.get_road_grade(veh_id) - inst_power += energy_model.get_instantaneous_power(accel, speed, grade) + gallons_per_hr = energy_model.get_instantaneous_fuel_consumption(accel, speed, grade) + if gallons_per_hr > 0 and speed >= 0.0: + cumulative_gallons += gallons_per_hr + cumulative_distance += speed + + cumulative_gallons /= 3600.0 + cumulative_distance /= 1609.0 + # miles / gallon is (distance_dot * \delta t) / (gallons_dot * \delta t) + mpg = cumulative_distance / cumulative_gallons - return inst_power * gain + return mpg * gain diff --git a/flow/energy_models/base_energy.py b/flow/energy_models/base_energy.py index 6c10d1eeb..bf1e16e09 100644 --- a/flow/energy_models/base_energy.py +++ b/flow/energy_models/base_energy.py @@ -15,6 +15,9 @@ class BaseEnergyModel(metaclass=ABCMeta): def __init__(self, kernel): self.k = kernel + # 15 kilowatts = 1 gallon/hour conversion factor + self.conversion = 15e3 + @abstractmethod def get_instantaneous_power(self, accel, speed, grade): """Calculate the instantaneous power consumption of a vehicle. @@ -34,3 +37,23 @@ def get_instantaneous_power(self, accel, speed, grade): float """ pass + + def get_instantaneous_fuel_consumption(self, accel, speed, grade): + """Calculate the instantaneous fuel consumption of a vehicle. + + Fuel consumption is reported in gallons per hour, with the conversion + rate of 15kW = 1 gallon/hour. + + Parameters + ---------- + accel : float + Instantaneous acceleration of the vehicle + speed : float + Instantaneous speed of the vehicle + grade : float + Instantaneous road grade of the vehicle + Returns + ------- + float + """ + return self.get_instantaneous_power(accel, speed, grade) * self.conversion diff --git a/flow/energy_models/power_demand.py b/flow/energy_models/power_demand.py index 03e859c33..9b16845eb 100644 --- a/flow/energy_models/power_demand.py +++ b/flow/energy_models/power_demand.py @@ -11,18 +11,28 @@ class PowerDemandModel(BaseEnergyModel, metaclass=ABCMeta): Calculate power consumption of a vehicle based on physics derivation. Assumes some vehicle characteristics. The power calculated here is the lower bound of the actual - power consumed by the vehicle. + power consumed by the vehicle plus a bilinear polynomial + function used as a correction factor. """ - def __init__(self, kernel, mass=2041, area=3.2, rolling_res_coeff=0.0027, aerodynamic_drag_coeff=0.4): + def __init__(self, + kernel, + mass=2041, + area=3.2, + rolling_res_coeff=0.0027, + aerodynamic_drag_coeff=0.4, + p1_correction=4598.7155, + p3_correction=975.12719): self.k = kernel self.g = 9.807 self.rho_air = 1.225 + self.gamma = 1 self.mass = mass + self.cross_area = area self.rolling_res_coeff = rolling_res_coeff self.aerodynamic_drag_coeff = aerodynamic_drag_coeff - self.cross_area = area - self.gamma = 1 + self.p1_correction = p1_correction + self.p3_correction = p3_correction def calculate_power_at_the_wheels(self, accel, speed, grade): """Calculate the instantaneous power required. @@ -40,7 +50,7 @@ def calculate_power_at_the_wheels(self, accel, speed, grade): float """ accel_slope_forces = self.mass * speed * ((np.heaviside(accel, 0.5) * (1 - self.gamma) + self.gamma)) * accel - accel_slope_forces += + self.g * math.sin(grade) + accel_slope_forces += self.g * math.sin(grade) rolling_friction = self.mass * self.g * self.rolling_res_coeff * speed air_drag = 0.5 * self.rho_air * self.cross_area * self.aerodynamic_drag_coeff * speed**3 power = accel_slope_forces + rolling_friction + air_drag @@ -66,6 +76,23 @@ def get_regen_cap(self, accel, speed, grade): """ pass + def get_power_correction_factor(self, accel, speed, grade): + """Calculate the instantaneous power correction of a vehicle. + + Parameters + ---------- + accel : float + Instantaneous acceleration of the vehicle + speed : float + Instantaneous speed of the vehicle + grade : float + Instantaneous road grade of the vehicle + Returns + ------- + float + """ + return self.p1_correction * accel + self.p3_correction * accel * speed + def get_instantaneous_power(self, accel, speed, grade): """Apply the regenerative braking cap to the modelled power demand. @@ -82,8 +109,9 @@ def get_instantaneous_power(self, accel, speed, grade): float """ regen_cap = self.get_regen_cap(accel, speed, grade) - power_at_the_wheels = self.calculate_power_at_the_wheels(accel, speed, grade) - return max(regen_cap, power_at_the_wheels) + power_at_the_wheels = max(regen_cap, self.calculate_power_at_the_wheels(accel, speed, grade)) + correction_factor = max(regen_cap, self.get_power_correction_factor(accel, speed, grade)) + return power_at_the_wheels + correction_factor class PDMCombustionEngine(PowerDemandModel): From b718ac4c24208d0812c8f654351ab940517df80c Mon Sep 17 00:00:00 2001 From: liljonnystyle Date: Tue, 7 Jul 2020 20:33:05 -0700 Subject: [PATCH 08/14] add print statement for defaulted energy model --- flow/core/params.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/flow/core/params.py b/flow/core/params.py index 4e7483dcd..67cd800ef 100755 --- a/flow/core/params.py +++ b/flow/core/params.py @@ -305,6 +305,9 @@ def add(self, lane_change_params = SumoLaneChangeParams() if energy_model not in ENERGY_MODELS: + print('{} for vehicle {} is not a valid energy model. Defaulting to {}\n'.format(energy_model, + veh_id, + DEFAULT_ENERGY_MODEL)) energy_model = DEFAULT_ENERGY_MODEL type_params = {} From 92aa0c562fb2efcbb6922a35c348e546ffa5b6d2 Mon Sep 17 00:00:00 2001 From: liljonnystyle Date: Wed, 8 Jul 2020 16:04:57 -0700 Subject: [PATCH 09/14] reflect changes in 995 to correct pdmcombustion implementation --- flow/core/params.py | 4 +- flow/energy_models/base_energy.py | 4 +- flow/energy_models/power_demand.py | 63 ++++++++++++++++++++++++------ 3 files changed, 54 insertions(+), 17 deletions(-) diff --git a/flow/core/params.py b/flow/core/params.py index 67cd800ef..862b34b4c 100755 --- a/flow/core/params.py +++ b/flow/core/params.py @@ -306,8 +306,8 @@ def add(self, if energy_model not in ENERGY_MODELS: print('{} for vehicle {} is not a valid energy model. Defaulting to {}\n'.format(energy_model, - veh_id, - DEFAULT_ENERGY_MODEL)) + veh_id, + DEFAULT_ENERGY_MODEL)) energy_model = DEFAULT_ENERGY_MODEL type_params = {} diff --git a/flow/energy_models/base_energy.py b/flow/energy_models/base_energy.py index bf1e16e09..a16c84694 100644 --- a/flow/energy_models/base_energy.py +++ b/flow/energy_models/base_energy.py @@ -12,9 +12,7 @@ class BaseEnergyModel(metaclass=ABCMeta): to be an averaged-size vehicle. """ - def __init__(self, kernel): - self.k = kernel - + def __init__(self): # 15 kilowatts = 1 gallon/hour conversion factor self.conversion = 15e3 diff --git a/flow/energy_models/power_demand.py b/flow/energy_models/power_demand.py index 9b16845eb..2e8593ecd 100644 --- a/flow/energy_models/power_demand.py +++ b/flow/energy_models/power_demand.py @@ -16,14 +16,12 @@ class PowerDemandModel(BaseEnergyModel, metaclass=ABCMeta): """ def __init__(self, - kernel, mass=2041, area=3.2, rolling_res_coeff=0.0027, aerodynamic_drag_coeff=0.4, p1_correction=4598.7155, p3_correction=975.12719): - self.k = kernel self.g = 9.807 self.rho_air = 1.225 self.gamma = 1 @@ -31,8 +29,7 @@ def __init__(self, self.cross_area = area self.rolling_res_coeff = rolling_res_coeff self.aerodynamic_drag_coeff = aerodynamic_drag_coeff - self.p1_correction = p1_correction - self.p3_correction = p3_correction + self.power_correction_coeffs = np.array([p1_correction, p3_correction]) def calculate_power_at_the_wheels(self, accel, speed, grade): """Calculate the instantaneous power required. @@ -91,7 +88,8 @@ def get_power_correction_factor(self, accel, speed, grade): ------- float """ - return self.p1_correction * accel + self.p3_correction * accel * speed + state_variables = np.array([accel, accel * speed]) + return max(0, np.dot(self.power_correction_coeffs, state_variables)) def get_instantaneous_power(self, accel, speed, grade): """Apply the regenerative braking cap to the modelled power demand. @@ -110,27 +108,68 @@ def get_instantaneous_power(self, accel, speed, grade): """ regen_cap = self.get_regen_cap(accel, speed, grade) power_at_the_wheels = max(regen_cap, self.calculate_power_at_the_wheels(accel, speed, grade)) - correction_factor = max(regen_cap, self.get_power_correction_factor(accel, speed, grade)) + correction_factor = self.get_power_correction_factor(accel, speed, grade) return power_at_the_wheels + correction_factor class PDMCombustionEngine(PowerDemandModel): """Power Demand Model for a combustion engine vehicle.""" + def __init__(self, + idle_coeff=3405.5481762, + linear_friction_coeff=83.123929917, + quadratic_friction_coeff=6.7650718327, + drag_coeff=0.7041355229, + p1_correction=4598.7155, + p3_correction=975.12719): + super(PDMCombustionEngine, self).__init__() + self.fuel_consumption_power_coeffs = np.array([idle_coeff, + linear_friction_coeff, + quadratic_friction_coeff, + drag_coeff]) + def get_regen_cap(self, accel, speed, grade): """See parent class.""" return 0 + def calculate_fuel_consumption_power(self, accel, speed, grade): + """Calculate the instantaneous power from a fitted function to Toyota Tacoma fuel consumption. + + Parameters + ---------- + accel : float + Instantaneous acceleration of the vehicle + speed : float + Instantaneous speed of the vehicle + grade : float + Instantaneous road grade of the vehicle + Returns + ------- + float + """ + state_variables = np.array([1, speed, speed**2, speed**3]) + power_0 = np.dot(self.fuel_consumption_power_coeffs, state_variables) + return max(self.mass * accel * speed + power_0, 0) + + def get_instantaneous_power(self, accel, speed, grade): + """See parent class.""" + fuel_consumption_power = self.calculate_fuel_consumption_power(accel, speed, grade) + power_correction_factor = self.get_power_correction_factor(accel, speed, grade) + return fuel_consumption_power + power_correction_factor + class PDMElectric(PowerDemandModel): """Power Demand Model for an electric vehicle.""" - def __init__(self, kernel): - super(PDMElectric, self).__init__(kernel, - mass=1663, - area=2.4, - rolling_res_coeff=0.007, - aerodynamic_drag_coeff=0.24) + def __init__(self, + mass=1663, + area=2.4, + rolling_res_coeff=0.007, + aerodynamic_drag_coeff=0.24): + super(PDMElectric, self).__init__(mass=mass, + area=area, + rolling_res_coeff=rolling_res_coeff, + aerodynamic_drag_coeff=aerodynamic_drag_coeff) def get_regen_cap(self, accel, speed, grade): """See parent class.""" From 76cd8c2c3a876f3274bbb7538f60a909a5ffc7c8 Mon Sep 17 00:00:00 2001 From: liljonnystyle Date: Sat, 11 Jul 2020 01:27:14 -0700 Subject: [PATCH 10/14] fix how energy_model is added to params --- flow/core/kernel/vehicle/traci.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/flow/core/kernel/vehicle/traci.py b/flow/core/kernel/vehicle/traci.py index 1ee68d7ee..099bc43db 100644 --- a/flow/core/kernel/vehicle/traci.py +++ b/flow/core/kernel/vehicle/traci.py @@ -291,10 +291,8 @@ def _add_departed(self, veh_id, veh_type): self.__vehicles[veh_id]["type"] = veh_type # specify energy model - energy_model = \ - self.type_parameters[veh_type]["energy_model"] - self.__vehicles[veh_id]["energy_model"] = \ - energy_model[0](veh_id, **energy_model[1]) + self.__vehicles[veh_id]["energy_model"] = self.type_parameters[ + veh_type]["energy_model"]() car_following_params = \ self.type_parameters[veh_type]["car_following_params"] From d620c327804e93d761da6527bd182ee99ba7c60e Mon Sep 17 00:00:00 2001 From: liljonnystyle Date: Sat, 11 Jul 2020 01:28:11 -0700 Subject: [PATCH 11/14] Use 1609.34 meters per mile conversion --- flow/core/rewards.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flow/core/rewards.py b/flow/core/rewards.py index b4af4c5bc..e2e1fff88 100755 --- a/flow/core/rewards.py +++ b/flow/core/rewards.py @@ -338,7 +338,7 @@ def instantaneous_mpg(env, veh_ids=None, gain=.001): cumulative_distance += speed cumulative_gallons /= 3600.0 - cumulative_distance /= 1609.0 + cumulative_distance /= 1609.34 # miles / gallon is (distance_dot * \delta t) / (gallons_dot * \delta t) mpg = cumulative_distance / cumulative_gallons From ff818fd52af51e685806a8ff9003a41d4f1f760c Mon Sep 17 00:00:00 2001 From: liljonnystyle Date: Sat, 11 Jul 2020 01:29:56 -0700 Subject: [PATCH 12/14] add veh/energy_consumption back and update --- flow/core/rewards.py | 55 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/flow/core/rewards.py b/flow/core/rewards.py index e2e1fff88..78892bbb5 100755 --- a/flow/core/rewards.py +++ b/flow/core/rewards.py @@ -306,6 +306,61 @@ def punish_rl_lane_changes(env, penalty=1): return total_lane_change_penalty +def energy_consumption(env, gain=.001): + """Calculate power consumption for all vehicle. + + Assumes vehicle is an average sized vehicle. + The power calculated here is the lower bound of the actual power consumed + by a vehicle. + + Parameters + ---------- + env : flow.envs.Env + the environment variable, which contains information on the current + state of the system. + gain : float + scaling factor for the reward + """ + veh_ids = env.k.vehicle.get_ids() + return veh_energy_consumption(env, veh_ids, gain) + + +def veh_energy_consumption(env, veh_ids=None, gain=.001): + """Calculate power consumption of a vehicle. + + Assumes vehicle is an average sized vehicle. + The power calculated here is the lower bound of the actual power consumed + by a vehicle. + + Parameters + ---------- + env : flow.envs.Env + the environment variable, which contains information on the current + state of the system. + veh_ids : [list] or str + list of veh_ids or single veh_id to compute the reward over + gain : float + scaling factor for the reward + """ + if veh_ids is None: + veh_ids = env.k.vehicle.get_ids() + elif not isinstance(veh_ids, list): + veh_ids = [veh_ids] + + power = 0 + for veh_id in veh_ids: + if veh_id not in env.k.vehicle.previous_speeds: + continue + energy_model = env.k.vehicle.get_energy_model(veh_id) + if energy_model != "": + speed = env.k.vehicle.get_speed(veh_id) + accel = env.k.vehicle.get_accel(veh_id, noise=False, failsafe=True) + grade = env.k.vehicle.get_road_grade(veh_id) + power += energy_model.get_instantaneous_power(accel, speed, grade) + + return -gain * power + + def instantaneous_mpg(env, veh_ids=None, gain=.001): """Calculate the instantaneous mpg for every simulation step specific to the vehicle type. From 91ea39bd9f68480d8252555816d5b23b344bd3c7 Mon Sep 17 00:00:00 2001 From: liljonnystyle Date: Sat, 11 Jul 2020 01:31:12 -0700 Subject: [PATCH 13/14] fix unit conversion --- flow/energy_models/base_energy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flow/energy_models/base_energy.py b/flow/energy_models/base_energy.py index a16c84694..910ab8c88 100644 --- a/flow/energy_models/base_energy.py +++ b/flow/energy_models/base_energy.py @@ -54,4 +54,4 @@ def get_instantaneous_fuel_consumption(self, accel, speed, grade): ------- float """ - return self.get_instantaneous_power(accel, speed, grade) * self.conversion + return self.get_instantaneous_power(accel, speed, grade) / self.conversion From f6e06fe5128a467a939126c51fb9d068e0afbf04 Mon Sep 17 00:00:00 2001 From: liljonnystyle Date: Sat, 11 Jul 2020 01:35:25 -0700 Subject: [PATCH 14/14] revert local_mode change --- tests/fast_tests/test_examples.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/fast_tests/test_examples.py b/tests/fast_tests/test_examples.py index 8e871afb4..b5faf6517 100644 --- a/tests/fast_tests/test_examples.py +++ b/tests/fast_tests/test_examples.py @@ -168,7 +168,6 @@ def test_parse_args(self): self.assertDictEqual(vars(args), { 'exp_config': 'exp_config', - 'local_mode': False, 'rl_trainer': 'rllib', 'num_cpus': 1, 'num_steps': 5000, @@ -189,7 +188,6 @@ def test_parse_args(self): self.assertDictEqual(vars(args), { 'checkpoint_path': '5', 'exp_config': 'exp_config', - 'local_mode': False, 'num_cpus': 1, 'num_steps': 3, 'rl_trainer': 'h-baselines', @@ -411,7 +409,7 @@ def run_exp(flow_params, **kwargs): alg_run, env_name, config = setup_rllib_exps(flow_params, 1, 1, **kwargs) try: - ray.init(num_cpus=1, local_mode=True) + ray.init(num_cpus=1) except Exception as e: print("ERROR", e) config['train_batch_size'] = 50