Example #1
0
    def get_avg_speed_at_edge(self,
                              start,
                              end,
                              attr,
                              sensor_data=None,
                              time_window=None):
        tmc_id = None
        length = None
        # See JOURNAL_localdata_generator notebook
        time_traversed = 10.791

        if 0 not in attr:
            key = random.choice(list(attr))
            tmc_id = attr[key]['tmc_id']
            length = attr[key]['length']
        else:
            if 0 in attr:
                if 'tmc_id' in attr[0]:
                    tmc_id = attr[0]['tmc_id']
                if 'length' in attr[0]:
                    length = attr[0]['length']

        if tmc_id and tmc_id in sensor_data:
            # TODO: Check if tmc_id is within the local data
            # Give some delay if not the local, depends on distance from optimal rsu
            # For now just give a delay of 1 hour
            parent_grid = GRID_ID
            for k, v in LOCAL_RSU_VARS.SUB_GRIDS.items():
                if GRID_ID in v:
                    parent_grid = k

            if tmc_id in LOCAL_RSU_VARS.TMC_DICT[parent_grid]:
                actual_time_window = time_window
            else:
                # Get the grid_id where this tmc_id is from
                for k, v in LOCAL_RSU_VARS.TMC_DICT.items():
                    if tmc_id in v:
                        other_rsu = k
                        break

                # Use manhattan distance as the delay
                r1 = geo_utils.get_rsu_by_grid_id(self.rsu_arr, parent_grid)
                r2 = geo_utils.get_rsu_by_grid_id(self.rsu_arr, other_rsu)
                delay = r1.get_manhattan_distance(r2)

                # TODO: Fix this hardcoded
                if GLOBAL_VARS.NEIGHBOR_LEVEL == 0:
                    delay = 0
                actual_time_window = (time_window - delay) % 24

            average_speed_at_time_window = sensor_data[tmc_id]['speeds'][
                actual_time_window]
            time_traversed = length / average_speed_at_time_window

        return time_traversed
def get_dataframe_historical_data(grid, rsu_arr, with_neighbors=True):
    # utils.print_log("get_speeds_hash_for_grid({})".format(grid))
    # print("RSU_ID:", RSU_ID, "GRID_ID:", GRID_ID)

    if not os.path.exists(os.path.join(os.getcwd(), 'data')):
        raise OSError("Must first download data, see README.md")
    data_dir = os.path.join(os.getcwd(), 'data')

    if not os.path.exists(os.path.join(data_dir, 'historical_speeds')):
        os.mkdir(os.path.join(data_dir, 'historical_speeds'))
    historical_speeds_dir = os.path.join(data_dir, 'historical_speeds')

    if with_neighbors and rsu_arr:
        r = geo_utils.get_rsu_by_grid_id(rsu_arr, grid)
        d = r.get_neighbors(rsu_arr)

        hist_dfs = []
        for _, n in d.items():
            if n:
                if n.grid_id != GRID_ID:
                    # print("Must get old data for {}".format(n.grid_id))
                    name = "{}_historical_speeds.pkl".format(n.grid_id)
                    hist_df = get_pickled_df(historical_speeds_dir, name)
                    # print(hist_df.head())
                    # print(hist_df.shape)
                    hist_dfs.append(hist_df)

        all_hist_dfs = pd.concat(hist_dfs, ignore_index=True)
        # print(all_hist_dfs)
        # print(all_hist_dfs.shape)

    return all_hist_dfs
Example #3
0
def generate_RSU_arr(x, y):
    target_area = GLOBAL_VARS.EXTENDED_DOWNTOWN_NASH_POLY
    # Polys are just the larger boundaries to be used to "decrease" the number since we still use geohashing and it is still limited.
    polys = gb.divide_grid(target_area, (x, y))
    rsu_arr = []
    for i in range(x):
        for j in range(y):
            idx = j + (i * y)
            p = polys[idx]
            gid = ghh.encode(p.centroid.x, p.centroid.y, precision=6)
            r = ag.adjustable_RSU(gid, p, (i, j))
            r.set_max_size(x, y)
            rsu_arr.append(r)

    if not os.path.exists(os.path.join(os.getcwd(), 'data')):
        raise OSError("Must first download data, see README.md")
    data_dir = os.path.join(os.getcwd(), 'data')

    file_path = os.path.join(data_dir, '{}-{}-grids_df.pkl'.format(x, y))
    with open(file_path, 'rb') as handle:
        df = pd.read_pickle(handle)

    sub_grid_rsus = []
    TMC_THRESH = df['tmc_count'].quantile(0.75)
    DIV_X, DIV_Y = 2, 2
    for i, row in df.iterrows():
        gid = row['grid_id']
        tmc_count = row['tmc_count']
        if tmc_count > TMC_THRESH:
            # BUG: If DIV_X and DIV_Y are odd, the central grid has the same gid as the parent grid
            #         if tmc_count / (DIV_X * DIV_Y) > TMC_THRESH:
            #             DIV_X, DIV_Y = 3, 3

            r = geo_utils.get_rsu_by_grid_id(rsu_arr, gid)
            r_poly = r.poly
            sub_polys = divide_grid_temp(r_poly, (DIV_X, DIV_Y))

            for p in sub_polys:
                new_gid = ghh.encode(p.centroid.x, p.centroid.y, precision=6)
                new_r = ag.adjustable_RSU(new_gid, p, (1000, 1000))
                new_r.queue_limit = GLOBAL_VARS.QUEUE_THRESHOLD
                new_r.set_max_size(x, y)
                sub_grid_rsus.append(new_r)
                # print("Adding: {}".format(new_gid))
                r.add_sub_grid(new_r)

    # main_no_sub_polys = [r.poly for r in rsu_arr if not r.get_sub_grids()]
    # sub_grid_polys = [r.poly for r in sub_grid_rsus]

    # SUB_GRIDS_DICT = {}
    # for r in rsu_arr:
    #     if r.get_sub_grids():
    #         SUB_GRIDS_DICT[r.grid_id] = [sg.grid_id for sg in r.get_sub_grids()]

    file_path = os.path.join(data_dir, "{}-{}-rsu_arr.pkl".format(x, y))
    with open(file_path, 'wb') as handle:
        pickle.dump(rsu_arr, handle)

    utils.print_log("Generated rsu_arr for broker.")
Example #4
0
    def get_dataframe_historical_data(self, grid, with_neighbors=True):
        print("get_dataframe_historical_data({})".format(grid))
        if with_neighbors and self.rsu_arr:
            r = geo_utils.get_rsu_by_grid_id(self.rsu_arr, grid)
            d = r.get_neighbors(self.rsu_arr)

            hist_dfs = []
            for _, n in d.items():
                if n:
                    if n.grid_id != GRID_ID:
                        # print("Must get old data for {}".format(n.grid_id))
                        name = "{}_historical_speeds.pkl".format(n.grid_id)
                        hist_df = self.get_pickled_df(
                            self.historical_speeds_dir, name)
                        hist_dfs.append(hist_df)

            all_hist_dfs = pd.concat(hist_dfs, ignore_index=True)

        return all_hist_dfs
Example #5
0
    def get_speeds_hash_for_grid(self, grid_id, with_neighbors=False):
        G = {}
        file_path = os.path.join(
            self.avg_speeds_dir,
            f'one_minute/{grid_id}_dict_avg_speeds_minute.pkl')
        # file_path = os.path.join(self.avg_speeds_dir, '5x5/{}-avg_speeds.pkl'.format(grid_id))
        with open(file_path, 'rb') as handle:
            g = pickle.load(handle)
            G = {**G, **g}

        if with_neighbors and self.rsu_arr:
            r = geo_utils.get_rsu_by_grid_id(self.rsu_arr, grid_id)
            d = r.get_neighbors(self.rsu_arr)

            for _, n in d.items():
                if n:
                    file_path = os.path.join(
                        self.avg_speeds_dir,
                        f'one_minute/{n.grid_id}_dict_avg_speeds_minute.pkl')
                    # file_path = os.path.join(self.avg_speeds_dir, '5x5/{}-avg_speeds.pkl'.format(n.grid_id))
                    with open(file_path, 'rb') as handle:
                        g = pickle.load(handle)
                        G = {**G, **g}
        return G
    def subtask_allocation(self, nlevel, subtask):
        data = subtask.get_json()
        gridA = data['gridA']
        gridB = data['gridB']

        if isinstance(gridA, int):
            optimal_rsu = gridB
        else:
            optimal_rsu = gridA

        if DEBUG == 1:
            print("Checking for: {}".format(optimal_rsu))

        if nlevel == 0:
            self._mongodb_c._db.tasks.update_one({"_id": data['_id']}, {
                '$set': {
                    'rsu_assigned_to': optimal_rsu,
                    'allocation_time': utils.time_print(int)
                }
            })
            return

        if nlevel > 0:
            r = geo_utils.get_rsu_by_grid_id(self._rsu_arr, optimal_rsu)
            nn = geo_utils.get_neighbors_level(self._rsu_arr, r.get_idx(),
                                               nlevel)

            nn.insert(0, r.get_idx())
            found = False
            candidate_rsus = []

            # Arranges the neighbors by distance from the most optimal grid in question
            # DEBUG: This will cause some additional delays
            nn = geo_utils.sort_idx_by_distance(GLOBAL_VARS.X_AXIS,
                                                GLOBAL_VARS.Y_AXIS,
                                                r.get_idx(), nn)
            nn.sort(key=lambda x: x[1])
            nn = [n[0] for n in nn]

            for n in nn:
                rsu = self._rsu_arr[n]
                candidate_rsus.append(rsu)

                res, gid = rsu.add_task(
                    self._nxg,
                    self._rsu_arr,
                    subtask,
                    use_sub_grids=GLOBAL_VARS.USE_SUB_GRIDS)
                if res:
                    found = True
                    self._mongodb_c._db.tasks.update_one(
                        {"_id": data['_id']}, {
                            '$set': {
                                'rsu_assigned_to': gid,
                                'allocation_time': utils.time_print(int)
                            }
                        })
                    # utils.print_log("Assigned to: {}".format(gid))
                    break
                '''
                If not ok, move to the next one (keep which has lowest number)
                '''
            # Get RSU with least number of queue
            if not found:
                if DEBUG == 1:
                    print("Not found by looking, must force...")
                # NOTE: Just shuffling so there is a chance that subtasks will be assigned to different RSUs and not just in the order they come in (if they are both tied for minimum queue lengths)
                # IDEA: Check if this has an effect
                # Right now as the last resort, it appends to the RSU with least queue length
                # If i don't randomize this, then it will assign to the least distance, which is just the most optimal one (may cause delay)
                random.shuffle(candidate_rsus)
                candidate_rsus = sorted(candidate_rsus,
                                        key=lambda rsu: len(rsu.queue),
                                        reverse=False)

                if DEBUG == 1:
                    [print(r) for r in candidate_rsus]
                    if candidate_rsus[0]._sub_grids:
                        [print(r) for r in candidate_rsus[0]._sub_grids]
                        print("\n")

                _, gid = candidate_rsus[0].add_task_forced(
                    subtask, use_sub_grids=GLOBAL_VARS.USE_SUB_GRIDS)
                # utils.print_log("Forced to: {}".format(gid))
                self._mongodb_c._db.tasks.update_one({"_id": data['_id']}, {
                    '$set': {
                        'rsu_assigned_to': gid,
                        'allocation_time': utils.time_print(int)
                    }
                })

            return
Example #7
0
    def add_task(self,
                 G,
                 rsu_arr,
                 task,
                 use_sub_grids=True,
                 constraints='queue'):
        if DEBUG == 1:
            print("Trying to add task {} to {} with q[{}/{}]".format(
                task._id, self.grid_id, len(self.queue), self.queue_limit))

        ideal_grid = task.gridA

        if isinstance(task.gridA, int):
            ideal_grid = task.gridB
        elif isinstance(task.gridA, str):
            ideal_grid = task.gridA

        if isinstance(task.gridB, int):
            next_grid = geo_utils.get_grid_id_from_node(G, task.gridB)
        elif isinstance(task.gridB, str):
            next_grid = task.gridB
        elif task.gridB is None:
            next_grid = ideal_grid

        ideal_rsu = geo_utils.get_rsu_by_grid_id(rsu_arr, ideal_grid)
        next_rsu = geo_utils.get_rsu_by_grid_id(rsu_arr, next_grid)

        # Not affected by change in actual grid
        delay_ideal = self.get_manhattan_distance(ideal_rsu)
        delay_next = self.get_manhattan_distance(next_rsu)
        total_delay = delay_ideal + delay_next

        # constraints
        met_delay_constraint = True
        met_queue_constraint = True

        use_delay_constraint = False
        use_queue_constraint = False

        constraint_arr = constraints.split("|")
        if 'delay' in constraint_arr:
            use_delay_constraint = True
        if 'queue' in constraint_arr:
            use_queue_constraint = True

        if use_delay_constraint:
            if total_delay > self.delay_threshold:
                met_delay_constraint = False

        if use_queue_constraint:
            if (len(self.queue) + 1) > self.queue_limit:
                met_queue_constraint = False

        if met_delay_constraint and met_queue_constraint:
            if DEBUG == 1:
                print("{} Adding task: {}".format(self.grid_id, task._id))

            # This will fill up the parent rsu first before moving on to subgrids
            if (len(self.queue) + 1) < self.queue_limit:
                self.queue.append(task)
                res = True
                grid_id = self.grid_id
                return res, grid_id
            elif use_sub_grids and len(self._sub_grids) > 0:
                res, grid_id = self.add_task_to_sub_grids(G,
                                                          rsu_arr,
                                                          task,
                                                          constraints='queue')
                return res, grid_id
            else:
                self.queue.append(task)
                res = True
                grid_id = self.grid_id
                return res, grid_id

        else:
            return False, ""