def get_relocation_distance(self, vehicle_relocation): distance = get_od_distance(self.simInput.grid, vehicle_relocation["start_zone_id"], vehicle_relocation["end_zone_id"]) if distance == 0: distance = self.simInput.sim_general_conf["bin_side_length"] return distance
def get_cr_soc_delta(self, origin_id, destination_id, vehicle): distance = get_od_distance(self.simInput.grid, origin_id, destination_id) if distance == 0: distance = self.simInput.sim_general_conf["bin_side_length"] return vehicle.consumption_to_percentage( vehicle.distance_to_consumption(distance / 1000))
def get_distance(self, origin_id, destination_id): """ Compute a trip's haversine distance (m) within the simulated grid. """ distance = get_od_distance(self.simInput.grid, origin_id, destination_id) if distance == 0: distance = self.simInput.demand_model_config["bin_side_length"] return distance
def get_timeout(self, origin_id, destination_id): """ Compute the time (s) required to cover a given trip's distance. """ distance = get_od_distance(self.simInput.grid, origin_id, destination_id) if distance == 0: distance = self.simInput.demand_model_config["bin_side_length"] return distance / 1000 / self.simInput.avg_speed_kmh_mean * 3600
def get_cr_soc_delta(self, origin_id, destination_id, vehicle): """ Compute the consumption rate from a trip's equivalent SoC delta. """ distance = get_od_distance(self.simInput.grid, origin_id, destination_id) if distance == 0: distance = self.simInput.demand_model_config["bin_side_length"] return vehicle.consumption_to_percentage( vehicle.distance_to_consumption(distance / 1000))
def _update_booking_request(self, pick_up_action, drop_off_action): update_end_time = False if pick_up_action != NOP: new_pick_up_zone = get_zone_id_from_action( action=pick_up_action, no_op_zone_id=self.booking_request['origin_id'], neighbors_dict=self.neighbors_dict) self.booking_request['origin_id'] = \ new_pick_up_zone update_end_time = True if drop_off_action != NOP: new_drop_off_zone = get_zone_id_from_action( action=drop_off_action, no_op_zone_id=self.booking_request['destination_id'], neighbors_dict=self.neighbors_dict) self.booking_request['destination_id'] = \ new_drop_off_zone euclidean_distance_org = self.booking_request['euclidean_distance'] euclidean_distance_new = get_od_distance( self.simInput.grid, self.booking_request['origin_id'], new_drop_off_zone) if euclidean_distance_new > euclidean_distance_org: self.booking_request['euclidean_distance'] = \ euclidean_distance_new # Ratio of 1.4 taken from T. Damoulas, et al., Road Distance and Travel Time # for an Improved House Price Kriging Predictor, 2018 self.booking_request['driving_distance'] = \ euclidean_distance_new * 1.4 update_end_time = True if update_end_time: # Perturbate the end time by at most 10 minutes, # not to introduce too much noise within # the distribution of ODySSEUS bookings self.booking_request['end_time'] += \ datetime.timedelta(seconds=np.random.uniform(0, 600)) self.booking_request['duration'] = \ (self.booking_request['end_time'] - self.booking_request['start_time']).total_seconds()
def make_booking_request(self, data: t.Dict): P_zone = int(data['P_zone']) D_zone = int(data['D_zone']) booking_request = { 'origin_id': P_zone, 'destination_id': D_zone, 'euclidean_distance': get_od_distance(self.simInput.grid, P_zone, D_zone) } # Ratio of 1.4 taken from T. Damoulas, et al., Road Distance and Travel Time # for an Improved House Price Kriging Predictor, 2018 booking_request['driving_distance'] = \ booking_request['euclidean_distance'] * 1.4 return booking_request
def relocate_scooter_multiple_zones(self, scheduled_relocation, collection_path, distribution_path, worker): with self.relocation_workers_resource.request( ) as relocation_worker_request: yield relocation_worker_request worker.start_working() total_distance = 0 total_duration = 0 picked_vehicles = [] relocated_vehicles = [] # Navigate through collection path for j in range(1, len(collection_path)): # Step definition step_start = collection_path[j - 1] step_end = collection_path[j] distance = get_od_distance(self.simInput.grid, step_start, step_end) total_distance += distance self.sim_metrics.update_metrics("avg_relocation_step_distance", distance) duration = distance / 1000 / self.simInput.supply_model_conf[ "avg_relocation_speed"] * 3600 total_duration += duration # Simulate step navigation time yield self.env.timeout(duration) worker.update_position(step_end) # Pick up programmed scooters where available current_time = self.start + datetime.timedelta( seconds=self.env.now) actual_n_picked_vehicles = min( scheduled_relocation["pick_up"][step_end], len(self.available_vehicles_dict[step_end])) for k in range(actual_n_picked_vehicles): picked_vehicle = self.available_vehicles_dict[ step_end].pop() picked_vehicles.append(picked_vehicle) self.pick_up_scooter(step_end, current_time) self.n_scooters_relocating += actual_n_picked_vehicles # Prosecute navigation through distribution path for j in range(1, len(distribution_path)): # Step definition step_start = distribution_path[j - 1] step_end = distribution_path[j] distance = get_od_distance(self.simInput.grid, step_start, step_end) total_distance += distance self.sim_metrics.update_metrics("avg_relocation_step_distance", distance) duration = distance / 1000 / self.simInput.supply_model_conf[ "avg_relocation_speed"] * 3600 total_duration += duration # Simulate step navigation time yield self.env.timeout(duration) worker.update_position(step_end) # Drop off programmed scooters while available current_time = self.start + datetime.timedelta( seconds=self.env.now) actual_n_dropped_vehicles = min( scheduled_relocation["drop_off"][step_end], len(picked_vehicles)) for k in range(actual_n_dropped_vehicles): dropped_vehicle = picked_vehicles.pop() relocated_vehicles.append(dropped_vehicle) self.available_vehicles_dict[step_end].append( dropped_vehicle) self.drop_off_scooter(step_end, current_time) self.n_scooters_relocating -= actual_n_dropped_vehicles worker.stop_working() # Save cumulative relocation stats scooter_relocation = init_scooter_relocation(relocated_vehicles, current_time, collection_path[1:], distribution_path[1:], total_distance, total_duration, worker_id=worker.id) self.update_relocation_stats(scooter_relocation)
def get_timeout(self, origin_id, destination_id): distance = get_od_distance(self.simInput.grid, origin_id, destination_id) if distance == 0: distance = self.simInput.sim_general_conf["bin_side_length"] return distance / 1000 / self.simInput.avg_speed_kmh_mean * 3600
def get_cr_soc_delta(self, origin_id, destination_id): distance = get_od_distance(self.simInput.grid, origin_id, destination_id) if distance == 0: distance = self.simInput.demand_model_config["bin_side_length"] return get_soc_delta(distance / 1000)
def create_booking_request(self, timeout): booking_request = {} booking_request["ia_timeout"] = timeout booking_request["start_time"] = self.current_datetime booking_request["date"] = self.current_datetime.date() booking_request["weekday"] = self.current_weekday booking_request["daytype"] = self.current_daytype booking_request["hour"] = self.current_hour def base_round(x, base): if x < 0: return 0 elif x > base: return base else: return round(x) trip_sample = self.current_trip_kde.sample() origin_i = base_round(trip_sample[0][0], len(self.simInput.grid_matrix.index) - 1) origin_j = base_round(trip_sample[0][1], len(self.simInput.grid_matrix.columns) - 1) destination_i = base_round(trip_sample[0][2], len(self.simInput.grid_matrix.index) - 1) destination_j = base_round(trip_sample[0][3], len(self.simInput.grid_matrix.columns) - 1) booking_request["origin_id"] = self.simInput.grid_matrix.loc[origin_i, origin_j] booking_request["destination_id"] = self.simInput.grid_matrix.loc[ destination_i, destination_j] booking_request["origin_id"] = self.closest_valid_zone.loc[ booking_request["origin_id"]] booking_request["destination_id"] = self.closest_valid_zone.loc[ booking_request["destination_id"]] booking_request["euclidean_distance"] = get_od_distance( self.simInput.grid, booking_request["origin_id"], booking_request["destination_id"]) if booking_request["euclidean_distance"] == 0: booking_request[ "euclidean_distance"] = self.simInput.demand_model_config[ "bin_side_length"] booking_request[ "driving_distance"] = booking_request["euclidean_distance"] * 1.4 booking_request["duration"] = abs( booking_request["driving_distance"] / ((self.simInput.avg_speed_kmh_mean) / 3.6 # + np.random.normal( # self.simInput.avg_speed_kmh_std, self.simInput.avg_speed_kmh_std / 2 # )) / 3.6 )) booking_request[ "end_time"] = self.current_datetime + datetime.timedelta( seconds=booking_request["duration"]) # booking_request["soc_delta"] = -Vehicle.consumption_to_percentage(Vehicle.distance_to_consumption(booking_request["driving_distance"] / 1000)) # booking_request["soc_delta_kwh"] = soc_to_kwh(booking_request["soc_delta"]) self.process_booking_request(booking_request)