Пример #1
0
    def compute_nprb_NR(self, data_rate, rsrp):
        #compute SINR
        interference = 0
        for elem in rsrp:
            if elem != self.bs_id and util.find_bs_by_id(
                    elem).bs_type != "sat" and util.find_bs_by_id(
                        elem).carrier_frequency == self.carrier_frequency:
                total, used = util.find_bs_by_id(elem).get_state()
                interference = interference + (10**(rsrp[elem] / 10)) * (
                    used / total) * (self.allocated_prb / self.total_prb)

        #thermal noise is computed as k_b*T*delta_f, where k_b is the Boltzmann's constant, T is the temperature in kelvin and delta_f is the bandwidth
        #thermal_noise = constants.Boltzmann*293.15*list(NRbandwidth_prb_lookup[self.numerology][self.fr].keys())[list(NRbandwidth_prb_lookup[self.numerology][self.fr].values()).index(self.total_prb / (10 * 2**self.numerology))]*1000000*(self.compute_rbur()+0.001)
        thermal_noise = constants.Boltzmann * 293.15 * 15 * (
            2**self.numerology
        ) * 1000  # delta_F = 15*2^mu KHz each subcarrier since we are considering measurements at subcarrirer level (like RSRP)
        sinr = (10**(rsrp[self.bs_id] / 10)) / (thermal_noise + interference)

        r = self.prb_bandwidth_size * 1000 * math.log2(
            1 + sinr)  #bandwidth is in kHz
        #based on the numerology choosen and considered the frame duration of 10ms, we transmit 1ms for mu = 0, 0.5ms for mu = 1, 0.25ms for mu = 2, 0.125ms for mu = 3 for each PRB each 10ms
        #print(r)
        r = r / (10 * (2**self.numerology))
        #print(r)
        N_prb = math.ceil(data_rate * 1000000 / r)  #data rate is in Mbps
        return N_prb, r
 def disconnect_from_bs(self, bs_id):
     if bs_id in self.current_bs:
         util.find_bs_by_id(bs_id).request_disconnection(self.ue_id)
         #print("[CONNECTION_TERMINATED]: User ID %s is now disconnected from base_station %s" %(self.ue_id, bs_id))
         self.actual_data_rate -= self.current_bs[bs_id]
         del self.current_bs[bs_id]
     return
Пример #3
0
 def compute_rsrp_drone(self, ue):
     #relay rsrp depends from the signal received by the BS and by the re-amp made by the drone
     print(
         util.compute_rsrp(self, util.find_bs_by_id(self.linked_bs),
                           self.env))
     return self.amplification + util.compute_rsrp(
         self, util.find_bs_by_id(self.linked_bs), self.env
     ) + self.antenna_gain - self.feeder_loss - util.compute_path_loss_cost_hata(
         ue, self, self.env)
Пример #4
0
    def compute_sinr(self, rsrp):
        interference = 0

        for elem in rsrp:
            if elem != self.bs_id and util.find_bs_by_id(
                    elem).bs_type == "sat":
                interference = interference + (
                    10**(rsrp[elem] /
                         10)) * util.find_bs_by_id(elem).compute_rbur()

        thermal_noise = constants.Boltzmann * 290 * self.carrier_bnd * 1000000
        sinr = (10**(rsrp[self.bs_id] / 10)) / (thermal_noise + interference)
        return sinr
    def next_timestep(self):
        self.old_position = self.current_position
        self.move()

        #compute the next state variable x^i_p[k+1], considering the visible base stations
        rsrp = self.env.discover_bs(self.ue_id)

        #remove the old BSs that are out of visibility
        for elem in self.bs_bitrate_allocation:
            if elem not in rsrp:
                del self.bs_bitrate_allocation[elem]

        #add the new BSs
        for elem in rsrp:
            if elem not in self.bs_bitrate_allocation:
                self.bs_bitrate_allocation[elem] = 0

        #core of the Wardrop algorithm
        for p in self.bs_bitrate_allocation:
            for q in self.bs_bitrate_allocation:
                if p != q:
                    bs_p = util.find_bs_by_id(p)
                    l_p = bs_p.compute_latency(self.ue_id)

                    bs_q = util.find_bs_by_id(q)
                    l_q = bs_q.compute_latency(self.ue_id)

                    mu_pq = 1
                    if (
                            l_p - l_q
                    ) < self.env.wardrop_epsilon or bs_q.allocated_bitrate >= bs_q.total_bitrate - (
                            self.env.wardrop_epsilon /
                        (2 * self.env.wardrop_beta)):
                        mu_pq = 0

                    mu_qp = 1
                    if (
                            l_q - l_p
                    ) < self.env.wardrop_epsilon or bs_p.allocated_bitrate >= bs_p.total_bitrate - (
                            self.env.wardrop_epsilon /
                        (2 * self.env.wardrop_beta)):
                        mu_qp = 0

                    r_pq = self.bs_bitrate_allocation[
                        p] * mu_pq * self.wardrop_sigma
                    r_qp = self.bs_bitrate_allocation[
                        q] * mu_qp * self.wardrop_sigma

                    self.bs_bitrate_allocation[p] += self.env.sampling_time * (
                        r_qp - r_pq)
        return
 def compute_reward(self, state, action, bitrate, desired_data_rate, rsrp,
                    ue_id):
     if action in rsrp:
         allocated, total = util.find_bs_by_id(action).get_connection_info(
             ue_id)
         alpha = 0
         if util.find_ue_by_id(ue_id).service_class == 0:
             alpha = 3
         else:
             alpha = 1
         if bitrate > desired_data_rate:
             # in case the DQN made a correct allocation I do not want the user occupies too much resources, so if the allocated resources
             # for the users are too much I will discount the reward of a proportional value
             return alpha * desired_data_rate / (allocated / total)
         else:
             if allocated > 0:
                 # in case of a bad allocation, I do not want again that the user occupies too much resources (better if it is allocated to
                 # one of its neighbor base stations)
                 return alpha * (desired_data_rate**
                                 2) * (bitrate - desired_data_rate
                                       )  #* (allocated/total) * 100
             else:
                 return alpha * (desired_data_rate**
                                 2) * (bitrate - desired_data_rate)
     else:
         # it should never go here (there are checks on actions in the argmax)
         return -10000
 def initial_timestep(self):
     #compute beta value:
     #beta, by definition, is max{1/r}, where r is the data rate of a single resource block (or symbol) seen by a certain UE
     self.wardrop_beta = 0
     for ue in self.ue_list:
         rsrp = self.discover_bs(ue.ue_id)
         for elem in rsrp:
             r = util.find_bs_by_id(elem).compute_r(ue.ue_id, rsrp)
             if util.find_bs_by_id(elem).wardrop_alpha / (
                     r /
                     1000000) > self.wardrop_beta:  #we convert r in Mbps
                 self.wardrop_beta = util.find_bs_by_id(
                     elem).wardrop_alpha / (r / 1000000)
     #now call each initial_timestep function in order to set the initial conditions for each commodity in terms of bitrate
     #to be requested to each BS
     for ue in self.ue_list:
         ue.initial_timestep()
     return
    def request_connection(self, ue_id, requested_bitrate, available_bs):

        bs = max(available_bs, key=available_bs.get)
        data_rate = util.find_bs_by_id(bs).request_connection(
            ue_id, requested_bitrate, available_bs)
        reward = self.compute_reward(None, bs, data_rate, requested_bitrate,
                                     available_bs, ue_id)
        self.cumulative_reward += reward
        return bs, data_rate
Пример #9
0
 def update_connection(self, ue_id, data_rate, available_bs):
     rsrp = available_bs.copy()
     if self.bs_id in rsrp:
         value = rsrp[self.bs_id]
         del rsrp[self.bs_id]
         if self.linked_bs in rsrp:
             del rsrp[self.linked_bs]
         rsrp[self.linked_bs] = value
     return util.find_bs_by_id(self.linked_bs).update_connection(
         ue_id, data_rate, rsrp)
Пример #10
0
    def compute_nsymb_SAT(self, data_rate, rsrp):

        #compute SINR
        interference = 0
        for elem in rsrp:
            if elem != self.bs_id and util.find_bs_by_id(
                    elem).bs_type == "sat":
                interference = interference + (10**(
                    rsrp[elem] / 10)) * util.find_bs_by_id(elem).compute_rbur(
                    ) * (self.frame_utilization / self.total_symbols)
        thermal_noise = constants.Boltzmann * 290 * self.carrier_bnd * 1000000
        sinr = (10**(rsrp[self.bs_id] / 10)) / (thermal_noise + interference)
        r = self.carrier_bnd * 1000000 * math.log2(1 + sinr)

        r = r / self.frame_length  # this is the data rate in [b/s] that is possible to obtains for a single symbol assigned every time frame

        r_64 = r * 64  # we can transmit in blocks of 64 symbols

        n_symb = math.ceil(data_rate * 1000000 / r_64)
        return n_symb, r
    def compute_nprb_LTE(self, data_rate, rsrp):

        #compute SINR
        interference = 0
        for elem in rsrp:
            if elem != self.bs_id and util.find_bs_by_id(
                    elem).bs_type != "sat" and util.find_bs_by_id(
                        elem).carrier_frequency == self.carrier_frequency:
                total, used = util.find_bs_by_id(elem).get_state()
                interference = interference + (10**(
                    rsrp[elem] / 10)) * util.find_bs_by_id(elem) * (
                        used / total) * (self.allocated_prb / self.total_prb)

        #thermal noise is computed as k_b*T*delta_f, where k_b is the Boltzmann's constant, T is the temperature in kelvin and delta_f is the bandwidth
        thermal_noise = constants.Boltzmann * 293.15 * 15 * 1000  # delta_F = 12*15KHz each resource block since we are considering resource block related measurements (like RSRP)
        sinr = (10**(rsrp[self.bs_id] / 10)) / (thermal_noise + interference)

        r = self.prb_bandwidth_size * 1000 * math.log2(
            1 + sinr)  #bandwidth is in kHz
        #with a single PRB we transmit just 1ms each 10ms (that is the frame lenght), so the actual rate is divided by 10
        r = r / 10
        N_prb = math.ceil(data_rate * 1000000 / r)  #data rate is in Mbps
        return N_prb, r
    def update_connection(self):
        if len(self.current_bs) == 0:
            self.connect_to_bs()
            print("UE_ID: ", self.ue_id, " NO CURRENT BS")
            return

        available_bs = self.env.discover_bs(self.ue_id)
        #print("UE_ID: ", self.ue_id, " AVAILABLE BS: ", available_bs)
        #print(available_bs)
        if len(available_bs) == 0:
            #print("[NO BASE STATION FOUND]: User ID %s has not found any base station during connection update" %(self.ue_id))
            #print("UE_ID: ", self.ue_id, " NO BS AVAILABLE")
            return

        for elem in self.current_bs:
            if elem in available_bs:
                if self.current_bs[elem] == 0:
                    #print("UE_ID: ", self.ue_id, " NO CONNECTION TO BS", elem)
                    self.connect_to_bs_id(elem)
                    continue
                data_rate = util.find_bs_by_id(elem).update_connection(
                    self.ue_id, self.bs_bitrate_allocation[elem], available_bs)

                self.actual_data_rate -= self.current_bs[elem]
                self.current_bs[elem] = data_rate
                self.actual_data_rate += self.current_bs[elem]

                #TODO update the connections according to the newly computed requested bitrates coming from the next_timestep() function
                '''
                if self.actual_data_rate < self.requested_bitrate:
                    print("[POOR BASE STATION]: User ID %s has a poor connection to its base station (actual data rate is %s/%s Mbps)" %(self.ue_id, self.actual_data_rate, self.requested_bitrate))
                    self.disconnect_from_bs(elem)
                    self.connect_to_bs()
                '''
                '''
                elif random.random() < self.epsilon:
                    print("[RANDOM DISCONNECTION]: User ID %s was randomly disconnected from its base station (actual data rate is %s/%s Mbps)" %(self.ue_id, self.actual_data_rate, self.requested_bitrate))
                    self.disconnect_from_bs()
                    self.connect_to_bs()
                '''
            else:
                #in this case no current base station is anymore visible
                #print("[BASE STATION LOST]: User ID %s has not found its base station during connection update" %(self.ue_id))
                self.disconnect_from_bs(elem)
                self.connect_to_bs()
 def connect_to_bs_id(self, bs_id):
     available_bs = self.env.discover_bs(self.ue_id)
     bs = None
     data_rate = None
     if bs_id not in available_bs:
         #print("[NO BASE STATION FOUND]: User ID %s has not found the selected base station (BS %s)" %(self.ue_id, bs_id))
         return
     else:
         if bs_id not in self.bs_bitrate_allocation:
             #print("[NO ALLOCATION FOR THIS BASE STATION FOUND]: User ID %s has not found any bitrate allocation for the selected base station (BS %s)" %(self.ue_id, bs_id))
             return
         elif self.bs_bitrate_allocation[bs_id] == 0:
             self.current_bs[bs_id] = 0
             return
         data_rate = util.find_bs_by_id(bs_id).request_connection(
             self.ue_id, self.bs_bitrate_allocation[bs_id], available_bs)
         self.current_bs[bs_id] = data_rate
         self.actual_data_rate += data_rate
    def connect_to_bs_random(self):
        available_bs = self.env.discover_bs(self.ue_id)
        bs = None
        data_rate = None
        if len(available_bs) == 0:
            print(
                "[NO BASE STATION FOUND]: User ID %s has not found any base station"
                % (self.ue_id))
            return
        elif len(available_bs) == 1:
            #this means there is only one available bs, so we have to connect to it
            #bs = list(available_bs.keys())[0]
            #self.actual_data_rate = util.find_bs_by_id(bs).request_connection(self.ue_id, self.requested_bitrate, available_bs)
            bs, data_rate = self.env.request_connection(
                self.ue_id, self.requested_bitrate, available_bs)
            self.current_bs[bs] = data_rate
            self.actual_data_rate += data_rate

        else:
            if self.MATLAB == 1:
                #import function from matlab, in order to select the best action

                #eng = matlab.engine.start_matlab()
                #ret = eng.nomefunzione(arg1, arg2,...,argn)
                return
            else:
                bs, rsrp = random.choice(list(available_bs.items()))
                data_rate = util.find_bs_by_id(bs).request_connection(
                    self.ue_id, self.requested_bitrate, available_bs)
                #self.current_bs, self.actual_data_rate = self.env.request_connection(self.ue_id, self.requested_bitrate, available_bs)
                self.current_bs[bs] = data_rate
                self.actual_data_rate += data_rate
        print(
            "[CONNECTION_ESTABLISHED]: User ID %s is now connected to base_station %s with a data rate of %s/%s Mbps"
            % (self.ue_id, self.current_bs[bs], data_rate,
               self.requested_bitrate))
Пример #15
0
 def get_connection_info(self, ue_id):
     return util.find_bs_by_id(self.linked_bs).get_connection_info(ue_id)
Пример #16
0
 def get_state(self):
     return util.find_bs_by_id(self.linked_bs).get_state()
Пример #17
0
 def new_state(self):
     return util.find_bs_by_id(self.linked_bs).new_state()
Пример #18
0
 def request_disconnection(self, ue_id):
     util.find_bs_by_id(self.linked_bs).request_disconnection(ue_id)
Пример #19
0
 def compute_r(self, ue_id, rsrp):
     return util.find_bs_by_id(self.linked_bs).compute_r(ue_id, rsrp)
Пример #20
0
 def compute_latency(self, ue_id):
     return util.find_bs_by_id(self.linked_bs).compute_latency(ue_id)
 def disconnect_from_all_bs(self):
     for bs in self.current_bs:
         util.find_bs_by_id(bs).request_disconnection(self.ue_id)
         #print("[CONNECTION_TERMINATED]: User ID %s is now disconnected from base_station %s" %(self.ue_id, bs))
     self.actual_data_rate = 0
     self.current_bs.clear()
Пример #22
0
                prb_dict[elem] = util.find_bs_by_id(elem).ue_pb_allocation[SELECTED_UE]
            elif util.find_bs_by_id(elem).bs_type == "sat" and SELECTED_UE in util.find_bs_by_id(elem).ue_allocation:
                prb_dict[elem] = util.find_bs_by_id(elem).ue_allocation[SELECTED_UE]/64
        print("PRB: ",prb_dict)
        '''
        if i != 0:
            for elem in ue:
                phonex = util.find_ue_by_id(elem)
                for bsx in phonex.current_bs:
                    if phonex.current_bs[bsx] < phonex.bs_bitrate_allocation[
                            bsx]:
                        print("Warning: UE", elem, "has saturated BS ", bsx)
        #print(util.find_bs_by_id(2).ue_pb_allocation[SELECTED_UE])

        for bsi in bs:
            if util.find_bs_by_id(bsi).bs_type != "sat":
                print("BS ", bsi, " PRB: ",
                      util.find_bs_by_id(bsi).allocated_prb, "/",
                      util.find_bs_by_id(bsi).total_prb, " Bitrate: ",
                      util.find_bs_by_id(bsi).allocated_bitrate, "/",
                      util.find_bs_by_id(bsi).total_bitrate)
            else:
                print("BS ", bsi, " PRB: ",
                      util.find_bs_by_id(bsi).frame_utilization / 64, "/",
                      util.find_bs_by_id(bsi).total_symbols / 64, " Bitrate: ",
                      util.find_bs_by_id(bsi).allocated_bitrate, "/",
                      util.find_bs_by_id(bsi).total_bitrate)

    max_e = 0
    for phone in ue:
        #print(phone)
Пример #23
0
 def get_connected_users(self):
     return util.find_bs_by_id(self.linked_bs).get_connected_users()
Пример #24
0
 def reset(self):
     self.position = (self.starting_position[0], self.starting_position[1])
     self.current_position = self.position
     self.h_b = self.starting_position[2]
     self.h_m = self.starting_position[2]
     return util.find_bs_by_id(self.linked_bs).reset()
Пример #25
0
 def compute_rbur(self):
     return util.find_bs_by_id(self.linked_bs).compute_rbur()