def getPeerAround(self, nodePosition, targetPosition): """ Return the peer that is the closest to a target position and that is in the right half plane. nodePosition : position of the node asking for a peer around targetPosition : target position which we are looking around Return : a peer or None if there is no peer in the right half plane """ found = False around = None distClosest = 0 for p in self.peers.values(): if Geometry.inHalfPlane(nodePosition, targetPosition, p.position): # first entity in right half-plane if not found: found = True around = p distClosest = Geometry.distance(targetPosition, p.position) else: dist = Geometry.distance(targetPosition, p.position) # this peer is closer if dist < distClosest: around = p distClosest = dist return around
def isCloser(self, peerB, targetPosition): """ Return True if this peer is closer than peerB to targetPosition """ d1 = Geometry.distance(self.position, targetPosition) d2 = Geometry.distance(peerB.position, targetPosition) print "isCloser d1= %s d2= %s" %(str(d1), str(d2)) return ( Geometry.distance(self.position, targetPosition) < Geometry.distance(peerB.position, targetPosition) )
def getWorstPeer(self): """ Choose a peer for removal. Removing this must NOT break the global connectivity rule. """ # filter list of neighbors # keep only entities not in Awareness Area which do not provoke mis-respect # of Global Connectivity Rule FilterList = [] endFilter = 1 indexFilter = self.distPeers.length - 1 nodePos = self.node.position while endFilter and indexFilter > 0: ent = self.distPeers.ll[indexFilter] distEnt = Geometry.distance(ent.position, nodePos) # first, verify that ent is not in Awareness Area if distEnt > self.node.awarenessRadius : if distEnt > ent.awarenessRadius: indInCcw = self.ccwPeers.ll.index(ent) successor = self.ccwPeers.ll[(indInCcw + 1) % self.ccwPeers.length] predecessor = self.ccwPeers.ll[indInCcw - 1] # then verify that ent is not mandatory for Rule respect if Geometry.inHalfPlane(predecessor.position, nodePos, successor.position): FilterList.append(ent) else: # stop iteration because all following entities are in Awareness Radius endFilter = 0 indexFilter -= 1 if FilterList <> []: # there is a posibility to remove any entity in FilterList. # By default, we decide to remove the farthest entity. # In article presented at RESH'02, we proposed several other possibilities # for more efficient choice. result = FilterList[0] else: result = 0 return result
def OnBest(self, peer): self.state.neighbours = [peer] # while turning, we found a closer entity : go back to moving state if( self.state.name == "TURNING" ): self.state.name = "MOVING" msg = self.FindnearestMsg() self.node.send(peer, msg) # we found the closest entity, we now have to turn around this entity elif ( self.state.name == "MOVING" ): self.state.name = "TURNING" distance = Geometry.distance(peer.position, self.node.position) msg = self.QueryaroundMsg(peer.id, distance) self.node.send(peer, msg)
def OnQueryaround(self, peer, idNearest, distNearest): manager = self.node.getPeersManager() target = peer.position closest = manager.getClosestPeer(target) # found a closest peer and this peer is a new one (it isn't idNearest moving # toward target position). if ( (Geometry.distance(closest.position, target) < distNearest) and closest.id <> idNearest ): # send a nearest message msg = self.NearestMsg(closest) self.node.send(peer, msg) # search for a peer around target position else: around = manager.getPeerAround(self.node.position, target) if around: msg = self.AroundMsg(around) self.node.send(peer, msg)
def OnAround(self, peer): nbNeighbours = len(self.state.neighbours) # last neighbour found last = self.state.neighbours[nbNeighbours-1] # best neighbour best = self.state.neighbours[0] peerPosition = Geometry.relativePosition(peer.position, self.node.position) # check if turn ends : we have at least 3 neighbours and either we got back # to the first peer (=> turn completed) or our last neighbour was in the left # half plane and this peer is in the right half plane if ( nbNeighbours > 2 ) and (peer.id == best.id) or ( not Geometry.inHalfPlane(best.position, self.node.position, last.position) and Geometry.inHalfPlane(best.position, self.node.position, peerPosition) ): self.state.name = "CONNECTING" # Our awarenesse radius is the distance between us and our closest neighbour, # because we are sure to know all the entities between us and the best. bestRelativePos = Geometry.relativePosition(best.position, self.node.position) minDistance = Geometry.distance(bestRelativePos, self.node.position) self.node.updateAr(minDistance) # register these peers with the peerManager and connect ! manager = self.node.getPeersManager() for p in self.state.neighbours: manager.addPeer(p) msg = self.HelloMsg() self.node.send(p, msg) else: # add this peer to our list of neighbours self.state.neighbours.append(peer) bestDist = Geometry.distance(best.position, self.node.position) msg = self.QueryaroundMsg(best.id, bestDist) # send this peer a queryaround message self.node.send(peer, msg)
def setLocalPosition(self, nodePosition): """ Set the local position in the coordinate system with origin nodePosition nodePoistion: position of the node, e.g. [12,56] """ self.localPosition = Geometry.localPosition(self.position, nodePosition)