def getAngleUEBSHex(BSPosition, hexCenter, mobilePosition): """ Returns the angle of the vectors between BS and mobile as well as BS and hex""" #print BSPosition, hexCenter, mobilePosition P12 = hexfuns.distance(BSPosition, hexCenter) P13 = hexfuns.distance(BSPosition, mobilePosition) P23 = hexfuns.distance(hexCenter, mobilePosition) if P12 < 1e-5: # BS is in the hex center. This is omnidirectional case. angle = 0 else: angle = arccos((power(P12,2) + power(P13,2) - power(P23,2))/(2 * P12 * P13)) angle = angle*180/pi if angle > 180: raise ValueError('Angle larger than realistically possible.') return angle
def getAngleUEBSHex(BSPosition, hexCenter, mobilePosition): """ Returns the angle of the vectors between BS and mobile as well as BS and hex""" #print BSPosition, hexCenter, mobilePosition P12 = hexfuns.distance(BSPosition, hexCenter) P13 = hexfuns.distance(BSPosition, mobilePosition) P23 = hexfuns.distance(hexCenter, mobilePosition) if P12 < 1e-5: # BS is in the hex center. This is omnidirectional case. angle = 0 else: angle = arccos( (power(P12, 2) + power(P13, 2) - power(P23, 2)) / (2 * P12 * P13)) angle = angle * 180 / pi if angle > 180: raise ValueError('Angle larger than realistically possible.') return angle
def uniformMobilePosition(self, tiers): """Find mobile position via uniform distribution obeying hexagon borders and minimum distance.""" outerRadius = self.interHexDistance / math.sqrt( 3) # TODO: ISD should not be here innerRadius = hexfuns.outer2InnerRadius(outerRadius) while True: xmin = -innerRadius * (2 * tiers + 1) ymin = -outerRadius * (1.5 * tiers + 1) xmax = innerRadius * (2 * tiers + 1) ymax = outerRadius * (1.5 * tiers + 1) position = [ xmin + (xmax - xmin) * random.random(), ymin + (ymax - ymin) * random.random() ] # If the mobile is too close to a BS, we reroll. If it isn't and is contained in a hex, we break (success). if ([ bs for bs in self.baseStations if hexfuns.distance( position, bs.position) < self.forbiddenDistance ]): continue # mobile too close to a BS if ([ hexa for hexa in self.hexagons if hexfuns.pointInHex(position, hexa) ]): # implicit booleanness break # at least one hexagon contains the point return position
def test_baseStationUnique(self): """Are any BS in the same location?""" world1 = world.World(self.wconf, self.phy) for bs1 in world1.baseStations: for bs2 in world1.baseStations[:]: if bs1 != bs2: self.assertTrue(hexfuns.distance(bs1.position,bs2.position)>1e-2)
def assign_cell_neighbors(self): """Inform cells about their neighbors""" for cll in self.cells: s = set() for cl in self.cells: dist = hexfuns.distance(cll._center, cl._center) if dist < self.interHexDistance + 1 and dist > 1: s.add(cl) cll.neighbors |= s
def associatePathloss(self, mob, indexmob): """Associate pathloss for one mobile""" for indexbs, bs in enumerate(self.baseStations): # 1. store LNS value, so it's safe... LNS = self.LNSMap[indexmob, indexbs] mob.setLNS(LNS, bs) # 2. store distance value distance = hexfuns.distance(mob.position, bs.position) mob.setDistance(distance, bs) # 3. from distance, LNS calc fading # The mobile has one LNS per BS, but one pathgain per cell for cell in bs.cells: mob.setPathloss(pathloss.pathloss(mob, bs, cell), bs, cell, enablefsf=self.wconf.enableFrequencySelectiveFading)
def placeBaseStations(self): """Place the base stations on the map. If the number of sectors is 1, the BS sits in the middle of a hexagon. If it is three, then it is located on the edge.""" listOfBaseStations = [] if self.sectorsPerBS == 1: # Only useful for debugging. Produces incorrect SINR profiles. for hexa in self.hexagons: bs = basestation.BaseStation(hexa.center, p0=self.wconf.p0, m=self.wconf.m, pS=self.wconf.pS) listOfBaseStations.append(bs) bs.cells.append(cell.Cell(hexa.center, self.PHY, direction=None, sleep_alignment=self.wconf.sleep_alignment)) elif self.sectorsPerBS == 3: """1. Build several large NS hexagons (one per tier), possibly with multiple vertices on the edges. 2. Remove those BS that are further out than some large EWHexagon.""" centerHex = next((hexa for hexa in self.hexagons if abs(linalg.norm(hexa.center-array([0,0]))<1)), 'None') # working around a rounding error centralBS = basestation.BaseStation(centerHex.center+[0,centerHex.outerRadius], p0=self.wconf.p0, m=self.wconf.m, pS=self.wconf.pS) listOfBaseStations.append(centralBS) for tier in range(1,self.tiers+1): # build NS hex with outer radius = 3*R*tier tempHex = hexagon.NSHexagon(centralBS.position, 3*centerHex.outerRadius*tier) for coords in tempHex.vertices(): listOfBaseStations.append(basestation.BaseStation(coords, p0=self.wconf.p0, m=self.wconf.m, pS=self.wconf.pS)) pointList = tempHex.border() for currentPoint in pointList[0:-1]: #ignore the last one ## get pieces of the lines connecting two border points ## add those points to the listOfBaseStations for subpointIter in range(1,tier): index = pointList.index(currentPoint) x,y,d,theta = lineDivider(currentPoint, pointList[index+1],tier,subpointIter) listOfBaseStations.append(basestation.BaseStation([x,y], p0=self.wconf.p0, m=self.wconf.m, pS=self.wconf.pS)) # remove BS that are too far out overall inclusionDistance = (( self.tiers * 2 + 2) * centerHex.innerRadius) origin = [0,0] for baseStation in listOfBaseStations[:]: if not(hexfuns.pointInHex(baseStation.position, hexagon.EWHexagon(origin, inclusionDistance))): listOfBaseStations.remove(baseStation) for baseStation in listOfBaseStations: for hexa in self.hexagons: if hexfuns.distance(hexa.center, baseStation.position)<hexa.outerRadius+1: baseStation.cells.append(cell.Cell(hexa.center, self.PHY, initial_power=self.wconf.initial_power, sleep_alignment=self.wconf.sleep_alignment)) # This is the place where cells are filled TODO: fill direction return listOfBaseStations
def placeHexagons(self): """Place the basic hexagons on the map""" outerRadius = self.interHexDistance / math.sqrt(3) hexagonCoordinates = hexfuns.hexmap(self.tiers, self.interHexDistance) listOfHexagons = [] for hexagonCoord in hexagonCoordinates: listOfHexagons.append(hexagon.NSHexagon(hexagonCoord, outerRadius)) # not all hexagons are later used for data collection self._consideredHexagons = [ hexa for hexa in listOfHexagons if hexfuns.distance([0,0], hexa.center)<hexa.innerRadius*(2*self.consideredTiers) + 1 ] return listOfHexagons
def uniformMobilePosition(self, tiers): """Find mobile position via uniform distribution obeying hexagon borders and minimum distance.""" outerRadius = self.interHexDistance / math.sqrt(3) # TODO: ISD should not be here innerRadius = hexfuns.outer2InnerRadius(outerRadius) while True: xmin = -innerRadius*(2*tiers + 1) ymin = -outerRadius*(1.5*tiers + 1) xmax = innerRadius*(2*tiers + 1) ymax = outerRadius*(1.5*tiers + 1) position = [ xmin + (xmax-xmin)*random.random(), ymin + (ymax-ymin)*random.random() ] # If the mobile is too close to a BS, we reroll. If it isn't and is contained in a hex, we break (success). if ([ bs for bs in self.baseStations if hexfuns.distance(position, bs.position)<self.forbiddenDistance]): continue # mobile too close to a BS if ([ hexa for hexa in self.hexagons if hexfuns.pointInHex(position, hexa) ]): # implicit booleanness break # at least one hexagon contains the point return position
def associatePathloss(self, mob, indexmob): """Associate pathloss for one mobile""" for indexbs, bs in enumerate(self.baseStations): # 1. store LNS value, so it's safe... LNS = self.LNSMap[indexmob, indexbs] mob.setLNS(LNS, bs) # 2. store distance value distance = hexfuns.distance(mob.position, bs.position) mob.setDistance(distance, bs) # 3. from distance, LNS calc fading # The mobile has one LNS per BS, but one pathgain per cell for cell in bs.cells: mob.setPathloss( pathloss.pathloss(mob, bs, cell), bs, cell, enablefsf=self.wconf.enableFrequencySelectiveFading)
def placeHexagons(self): """Place the basic hexagons on the map""" outerRadius = self.interHexDistance / math.sqrt(3) hexagonCoordinates = hexfuns.hexmap(self.tiers, self.interHexDistance) listOfHexagons = [] for hexagonCoord in hexagonCoordinates: listOfHexagons.append(hexagon.NSHexagon(hexagonCoord, outerRadius)) # not all hexagons are later used for data collection self._consideredHexagons = [ hexa for hexa in listOfHexagons if hexfuns.distance([0, 0], hexa.center) < hexa.innerRadius * (2 * self.consideredTiers) + 1 ] return listOfHexagons
def center_cell(self): """The center cell""" for cell in self.cells: if hexfuns.distance([0,0], cell.center)<1: return cell return None
def center_cell(self): """The center cell""" for cell in self.cells: if hexfuns.distance([0, 0], cell.center) < 1: return cell return None
def placeBaseStations(self): """Place the base stations on the map. If the number of sectors is 1, the BS sits in the middle of a hexagon. If it is three, then it is located on the edge.""" listOfBaseStations = [] if self.sectorsPerBS == 1: # Only useful for debugging. Produces incorrect SINR profiles. for hexa in self.hexagons: bs = basestation.BaseStation(hexa.center, p0=self.wconf.p0, m=self.wconf.m, pS=self.wconf.pS) listOfBaseStations.append(bs) bs.cells.append( cell.Cell(hexa.center, self.PHY, direction=None, sleep_alignment=self.wconf.sleep_alignment)) elif self.sectorsPerBS == 3: """1. Build several large NS hexagons (one per tier), possibly with multiple vertices on the edges. 2. Remove those BS that are further out than some large EWHexagon.""" centerHex = next( (hexa for hexa in self.hexagons if abs(linalg.norm(hexa.center - array([0, 0])) < 1)), 'None') # working around a rounding error centralBS = basestation.BaseStation(centerHex.center + [0, centerHex.outerRadius], p0=self.wconf.p0, m=self.wconf.m, pS=self.wconf.pS) listOfBaseStations.append(centralBS) for tier in range(1, self.tiers + 1): # build NS hex with outer radius = 3*R*tier tempHex = hexagon.NSHexagon(centralBS.position, 3 * centerHex.outerRadius * tier) for coords in tempHex.vertices(): listOfBaseStations.append( basestation.BaseStation(coords, p0=self.wconf.p0, m=self.wconf.m, pS=self.wconf.pS)) pointList = tempHex.border() for currentPoint in pointList[0:-1]: #ignore the last one ## get pieces of the lines connecting two border points ## add those points to the listOfBaseStations for subpointIter in range(1, tier): index = pointList.index(currentPoint) x, y, d, theta = lineDivider(currentPoint, pointList[index + 1], tier, subpointIter) listOfBaseStations.append( basestation.BaseStation([x, y], p0=self.wconf.p0, m=self.wconf.m, pS=self.wconf.pS)) # remove BS that are too far out overall inclusionDistance = ((self.tiers * 2 + 2) * centerHex.innerRadius) origin = [0, 0] for baseStation in listOfBaseStations[:]: if not (hexfuns.pointInHex( baseStation.position, hexagon.EWHexagon(origin, inclusionDistance))): listOfBaseStations.remove(baseStation) for baseStation in listOfBaseStations: for hexa in self.hexagons: if hexfuns.distance( hexa.center, baseStation.position) < hexa.outerRadius + 1: baseStation.cells.append( cell.Cell( hexa.center, self.PHY, initial_power=self.wconf.initial_power, sleep_alignment=self.wconf.sleep_alignment) ) # This is the place where cells are filled TODO: fill direction return listOfBaseStations