Пример #1
0
    def add_node(self, node=None, pos=None, ori=None, commRange=None):
        """
        Add node to network.

        Attributes:
          `node` -- node to add, default: new node is created
          `pos` -- position (x,y), default: random free position in environment
          `ori` -- orientation from 0 to 2*pi, default: random orientation

        """
        if (not node):
            node = Node(commRange=commRange)
        assert(isinstance(node, Node))
        if not node.network:
            node.network = self
        else:
            logger.warning('Node is already in another network, can\'t add.')
            return None

        pos = pos if pos is not None else self.find_random_pos(n=100)
        ori = ori if ori is not None else rand() * 2 * pi
        ori = ori % (2 * pi)

        if (self._environment.is_space(pos)):
            Graph.add_node(self, node)
            self.pos[node] = array(pos)
            self.ori[node] = ori
            self.labels[node] = str(node.id)
            logger.debug('Node %d is placed on position %s.' % (node.id, pos))
            self.recalculate_edges([node])
        else:
            logger.error('Given position is not free space.')
        return node
Пример #2
0
    def send(self, message):
        """
        Send a message to nodes listed in message's destination field.

        Note: Destination should be a list of nodes or one node.

        Update message's source field and  inserts in node's outbox one copy
        of it for each destination.

        """
        if not self.power.have_energy():
            self.n_transmitted_failed_power += 1
            self.energy.append(self.power.energy)
            logger.debug("Node %d doesn't have  enough energy to send message [energy=%5.3f]" %
                        (self.id, self.power.energy))
            return

        message.source = self
        message.destination = isinstance(message.destination, list) and\
                              message.destination or [message.destination]
        msg_len = message.message_length()

        for destination in message.destination:
            self.power.decrease_tx_energy(msg_len)
            self.energy.append(self.power.energy)
            self.n_transmitted += 1
            logger.debug('Node %d sent message %s [%d].' %
                         (self.id, message.data, msg_len))
            m = message.copy()
            m.destination = destination
            self.outbox.insert(0, m)
Пример #3
0
    def add_node(self, node=None, pos=None, ori=None, commRange=None):
        """
        Add node to network.

        Attributes:
          `node` -- node to add, default: new node is created
          `pos` -- position (x,y), default: random free position in environment
          `ori` -- orientation from 0 to 2*pi, default: random orientation

        """
        if (not node):
            node = Node(commRange=commRange)
        assert(isinstance(node, Node))
        if not node.network:
            node.network = self
        else:
            logger.warning('Node is already in another network, can\'t add.')
            return None

        pos = pos if pos is not None else self.find_random_pos(n=100)
        ori = ori if ori is not None else rand() * 2 * pi
        ori = ori % (2 * pi)

        if (self._environment.is_space(pos)):
            Graph.add_node(self, node)
            self.pos[node] = array(pos)
            self.ori[node] = ori
            self.labels[node] = str(node.id)
            logger.debug('Node %d is placed on position %s.' % (node.id, pos))
            self.recalculate_edges([node])
        else:
            logger.error('Given position is not free space.')
        return node
Пример #4
0
    def send(self, message):
        """
        Send a message to nodes listed in message's destination field.

        Note: Destination should be a list of nodes or one node.

        Update message's source field and  inserts in node's outbox one copy
        of it for each destination.

        """
        if not self.power.have_energy():
            self.n_transmitted_failed_power += 1
            self.energy.append(self.power.energy)
            logger.debug(
                "Node %d doesn't have  enough energy to send message [energy=%5.3f]"
                % (self.id, self.power.energy))
            return

        message.source = self
        message.destination = isinstance(message.destination, list) and\
                              message.destination or [message.destination]
        msg_len = message.message_length()

        for destination in message.destination:
            self.power.decrease_tx_energy(msg_len)
            self.energy.append(self.power.energy)
            self.n_transmitted += 1
            logger.debug('Node %d sent message %s [%d].' %
                         (self.id, message.data, msg_len))
            m = message.copy()
            m.destination = destination
            self.outbox.insert(0, m)
Пример #5
0
 def send(self, destination, message):
     logger.debug('Sending message from %s to %s.' %
                  (repr(message.source), destination))
     if destination in self.nodes():
         destination.push_to_inbox(message)
     else:
         raise PymoteMessageUndeliverable('Destination not in network.',
                                          message)
Пример #6
0
 def send(self, destination, message):
     logger.debug('Sending message from %s to %s.' %
                   (repr(message.source), destination))
     if destination in self.nodes():
         destination.push_to_inbox(message)
     else:
         raise PymoteMessageUndeliverable('Destination not in network.',
                                          message)
Пример #7
0
 def remove_node(self, node):
     """ Remove node from network. """
     if node not in self.nodes():
         logger.error("Node not in network")
         return
     Graph.remove_node(self, node)
     del self.pos[node]
     del self.labels[node]
     node.network = None
     logger.debug('Node with id %d is removed.' % node.id)
Пример #8
0
 def remove_node(self, node):
     """ Remove node from network. """
     if node not in self.nodes():
         logger.error("Node not in network")
         return
     Graph.remove_node(self, node)
     del self.pos[node]
     del self.labels[node]
     node.network = None
     logger.debug('Node with id %d is removed.' % node.id)
Пример #9
0
    def add_node(self,
                 node=None,
                 pos=None,
                 ori=None,
                 commRange=None,
                 find_random=False):
        """
        Add node to network.

        Attributes:
          `node` -- node to add, default: new node is created
          `pos` -- position (x,y), default: random free position in environment
          `ori` -- orientation from 0 to 2*pi, default: random orientation

        """
        if (not node):
            node = Node(commRange=commRange or self.comm_range)
        if not node.commRange:
            node.commRange = commRange or self.comm_range

        assert (isinstance(node, Node))
        if not node.network:
            node.network = self
        else:
            logger.warning('Node is already in another network, can\'t add.')
            return None

        pos = pos if (pos is not None
                      and not isnan(pos[0])) else self.find_random_pos(n=100)
        ori = ori if ori is not None else rand() * 2 * pi
        ori = ori % (2 * pi)

        got_random = False
        if find_random and not self._environment.is_space(pos):
            pos = self.find_random_pos(n=100)
            got_random = True

        if (self._environment.is_space(pos)):
            Graph.add_node(self, node)
            self.pos[node] = array(pos)
            self.ori[node] = ori
            self.labels[node] = ('C' if node.type == 'C' else "") + str(
                node.id)
            logger.debug('Node %d is placed on position %s %s %s' %
                         (node.id, pos, '[energy=%5.3f]' % node.power.energy
                          if node.power.energy != EnergyModel.E_INIT else '',
                          'Random' if got_random else ''))
            self.recalculate_edges([node])
        else:
            Node.cid -= 1
            logger.error('Given position is not free space. [%s] %s' %
                         (Node.cid, pos))
            node = None
        return node
Пример #10
0
 def _are_conditions_satisfied(self, net):
     cr = net.nodes()[0].commRange
     if self.connected and not is_connected(net):
         logger.debug("Not connected")
         return round(0.2 * cr)
     elif self.degree:
         logger.debug("Degree not satisfied %f" % net.avg_degree())
         diff = self.degree - net.avg_degree()
         diff = sign(diff) * min(abs(diff), 7)
         return round((sign(diff) * (round(diff))**2) * cr / 100)
     return 0
Пример #11
0
 def _are_conditions_satisfied(self, net):
     cr = net.nodes()[0].commRange
     if self.connected and not is_connected(net):
         logger.debug("Not connected")
         return round(0.2*cr)
     elif self.degree:
         logger.debug("Degree not satisfied %f" % net.avg_degree())
         diff = self.degree-net.avg_degree()
         diff = sign(diff)*min(abs(diff), 7)
         return round((sign(diff)*(round(diff))**2)*cr/100)
     return 0
Пример #12
0
    def send(self, destination, message):
        logger.debug('Sending message from %s to %s (%s).' %
                      (repr(message.source), destination, message.data))

        if destination in self.nodes():
            destination.push_to_inbox(message)
            #if message.source:
                #message.source.power.decrease_tx_energy(message.message_length())  # TODO
        else:
            raise PymoteMessageUndeliverable('Destination not in network.',
                                             message)
Пример #13
0
    def send(self, destination, message):
        logger.debug('Sending message from %s to %s (%s).' %
                     (repr(message.source), destination, message.data))

        if destination in self.nodes():
            destination.push_to_inbox(message)
            #if message.source:
            #message.source.power.decrease_tx_energy(message.message_length())  # TODO
        else:
            raise PymoteMessageUndeliverable('Destination not in network.',
                                             message)
Пример #14
0
    def estimate_position(self, node):
        TRESHOLD = .1
        MAX_ITER = 10
        landmarks = []

        # get landmarks with hopsize data
        if self.dataKey in node.memory:
            landmarks = node.memory[self.dataKey].keys()
        # calculate estimated distances
        if len(landmarks) >= 3:
            dist = lambda x, y: sqrt(dot(x - y, x - y))
            landmark_max_positions = [
                array(node.memory[self.dataKey][lm][:2]) for lm in landmarks
            ]
            # take centroid as initial estimation
            pos = average(landmark_max_positions, axis=0)
            landmark_distances = []
            landmark_positions = []
            # only reliable anchors
            for lp in node.memory[self.dataKey].values():
                threshold = FloodingUpdate.lookup.get(lp[2],
                                                      0.75) * node.commRange
                hl = dist(lp[:2], pos) / lp[2]
                logger.debug("Node=%s, Hop=%s, threshold=%s, hoplen=%s" %
                             (node.id, lp[2], threshold, hl))
                if hl > threshold and self.hopsizeKey in node.memory:  # reliable
                    landmark_distances.append(
                        lp[2] * (node.memory[self.hopsizeKey] or 1))
                    landmark_positions.append(array(lp[:2]))

            # take centroid as initial estimation
            W = diag(ones(len(landmark_positions)))
            counter = 0
            while True:
                J = array([(lp - pos) / dist(lp, pos)
                           for lp in landmark_positions])
                range_correction = array([
                    dist(landmark_positions[li], pos) - landmark_distances[li]
                    for li, lm in enumerate(landmark_positions)
                ])
                pos_correction = dot(linalg.inv(dot(dot(J.T, W), J)),
                                     dot(dot(J.T, W), range_correction))
                logger.debug("Est. %s, %s, %s" %
                             (node.id, pos, pos_correction))
                pos = pos + pos_correction
                counter += 1
                if sqrt(sum(pos_correction ** 2)) < \
                   TRESHOLD or counter >= MAX_ITER:
                    logger.info("Trilaterate break %s" % counter)
                    break
            if counter <= MAX_ITER:
                node.memory[self.positionKey] = pos
                node.memory['reliable'] = landmark_positions
Пример #15
0
    def estimate_position(self, node):
        TRESHOLD = .1
        MAX_ITER = 10
        landmarks = []

        # get landmarks with hopsize data
        if self.dataKey in node.memory:
            landmarks = node.memory[self.dataKey].keys()
        # calculate estimated distances
        if len(landmarks) >= 3:
            landmark_distances = []
            landmark_positions = []
            try:
                landmark_distances = [
                    node.memory[self.dataKey][lm][2] *
                    node.memory[self.hopsizeKey] for lm in landmarks
                ]
                landmark_positions = [
                    array(node.memory[self.dataKey][lm][:2])
                    for lm in landmarks
                ]
            except:
                pass
            # take centroid as initial estimation
            pos = average(landmark_positions, axis=0)
            W = diag(ones(len(landmarks)))
            counter = 0
            dist = lambda x, y: sqrt(dot(x - y, x - y))
            while pos.any() != nan:
                J = array([(lp - pos) / dist(lp, pos)
                           for lp in landmark_positions])
                range_correction = array([
                    dist(landmark_positions[li], pos) - landmark_distances[li]
                    for li, lm in enumerate(landmarks)
                ])
                pos_correction = dot(linalg.inv(dot(dot(J.T, W), J)),
                                     dot(dot(J.T, W), range_correction))
                pos = pos + pos_correction
                logger.debug("Est. %s, %s, %s" %
                             (node.id, pos, pos_correction))
                counter += 1
                if sqrt(sum(pos_correction ** 2)) < \
                   TRESHOLD or counter >= MAX_ITER:
                    logger.info("Trilaterate break %s" % counter)
                    break
            if counter <= MAX_ITER:
                node.memory[self.positionKey] = pos
                node.memory['reliable'] = landmark_positions
Пример #16
0
    def _are_conditions_satisfied(self, net):
        cr = net.nodes()[0].commRange
        if self.connected and not is_connected(net):
            logger.debug("Not connected")
            return round(0.2*cr)
        elif self.degree:
            diff = (self.degree-net.avg_degree())/self.degree
            if (abs(diff)<0.1):
                return 0

            #diff = sign(diff)*min(abs(diff), 7)
            #adj = round((sign(diff)*(round(diff))**2)*cr/35)
            adj = sign(diff)/5.0
            logger.debug("Degree not satisfied %f, %s, %s" % (net.avg_degree(), diff, adj))
            return adj
        return 0
Пример #17
0
    def _are_conditions_satisfied(self, net):
        cr = net.nodes()[0].commRange
        if self.connected and not is_connected(net):
            logger.debug("Not connected")
            return round(0.2*cr)
        elif self.degree:
            diff = (self.degree-net.avg_degree())/self.degree
            if (abs(diff)<0.1):
                return 0

            #diff = sign(diff)*min(abs(diff), 7)
            #adj = round((sign(diff)*(round(diff))**2)*cr/35)
            adj = sign(diff)/5.0
            logger.debug("Degree not satisfied %f, %s, %s" % (net.avg_degree(), diff, adj))
            return adj
        return 0
Пример #18
0
    def __init__(self, network, **kwargs):
        self.network = network
        self.name = self.__class__.__name__
        logger.debug('Instance of %s class has been initialized.' % self.name)

        for required_param in self.required_params:
            if required_param not in kwargs.keys():
                raise PymoteAlgorithmException('Missing required param.')

        # set default params
        for dp, val in self.default_params.items():
            self.__setattr__(dp, val)

        # override default params
        for kw, arg in kwargs.items():
            self.__setattr__(kw, arg)
Пример #19
0
    def __init__(self, network, **kwargs):
        self.network = network
        self.name = self.__class__.__name__
        logger.debug('Instance of %s class has been initialized.' % self.name)

        for required_param in self.required_params:
            if required_param not in kwargs.keys():
                raise PymoteAlgorithmException('Missing required param.')

        # set default params
        for dp, val in self.default_params.items():
            self.__setattr__(dp, val)

        # override default params
        for kw, arg in kwargs.items():
            self.__setattr__(kw, arg)
Пример #20
0
    def estimate_position(self, node):
        TRESHOLD = .1
        MAX_ITER = 10
        landmarks = []

        # get landmarks with hopsize data
        if self.dataKey in node.memory:
            landmarks = node.memory[self.dataKey].keys()
        # calculate estimated distances
        if len(landmarks) >= 3:
            dist = lambda x, y: sqrt(dot(x - y, x - y))
            landmark_max_positions = [array(node.memory[self.dataKey][lm][:2])
                                  for lm in landmarks]
            # take centroid as initial estimation
            pos = average(landmark_max_positions, axis=0)
            landmark_distances = []
            landmark_positions = []
            # only reliable anchors
            for lp in node.memory[self.dataKey].values():
                 threshold = FloodingUpdate.lookup.get(lp[2], 0.75) * node.commRange
                 hl = dist(lp[:2], pos)/lp[2]
                 logger.debug("Node=%s, Hop=%s, threshold=%s, hoplen=%s" %(node.id, lp[2], threshold, hl))
                 if hl > threshold and self.hopsizeKey in node.memory:  # reliable
                    landmark_distances.append(lp[2] * (node.memory[self.hopsizeKey] or 1))
                    landmark_positions.append(array(lp[:2]))

            # take centroid as initial estimation
            W = diag(ones(len(landmark_positions)))
            counter = 0
            while True:
                J = array([(lp - pos) / dist(lp, pos)
                           for lp in landmark_positions])
                range_correction = array([dist(landmark_positions[li], pos) -
                                          landmark_distances[li]
                                          for li, lm in enumerate(landmark_positions)])
                pos_correction = dot(linalg.inv(dot(dot(J.T, W), J)),
                                     dot(dot(J.T, W), range_correction))
                logger.debug("Est. %s, %s, %s" %(node.id, pos, pos_correction))
                pos = pos + pos_correction
                counter += 1
                if sqrt(sum(pos_correction ** 2)) < \
                   TRESHOLD or counter >= MAX_ITER:
                    logger.info("Trilaterate break %s" % counter)
                    break
            if counter <= MAX_ITER:
                node.memory[self.positionKey] = pos
                node.memory['reliable'] = landmark_positions
Пример #21
0
    def add_node(self, node=None, pos=None, ori=None, commRange=None, find_random=False):
        """
        Add node to network.

        Attributes:
          `node` -- node to add, default: new node is created
          `pos` -- position (x,y), default: random free position in environment
          `ori` -- orientation from 0 to 2*pi, default: random orientation

        """
        if (not node):
            node = Node(commRange=commRange or self.comm_range)
        if not node.commRange:
            node.commRange = commRange or self.comm_range

        assert(isinstance(node, Node))
        if not node.network:
            node.network = self
        else:
            logger.warning('Node is already in another network, can\'t add.')
            return None

        pos = pos if (pos is not None and not isnan(pos[0])) else self.find_random_pos(n=100)
        ori = ori if ori is not None else rand() * 2 * pi
        ori = ori % (2 * pi)

        got_random = False
        if find_random and not self._environment.is_space(pos):
            pos = self.find_random_pos(n=100)
            got_random = True

        if (self._environment.is_space(pos)):
            Graph.add_node(self, node)
            self.pos[node] = array(pos)
            self.ori[node] = ori
            self.labels[node] = ('C' if node.type == 'C' else "") + str(node.id)
            logger.debug('Node %d is placed on position %s %s %s'
                         % (node.id, pos,
                            '[energy=%5.3f]' %node.power.energy
                                    if node.power.energy != EnergyModel.E_INIT  else '',
                            'Random' if got_random else ''))
            self.recalculate_edges([node])
        else:
            Node.cid -= 1
            logger.error('Given position is not free space. [%s] %s' % (Node.cid, pos))
            node = None
        return node
Пример #22
0
 def modify_avg_degree(self, value):
     """
     Modifies (increases) average degree based on given value by
     modifying nodes commRange."""
     # assert all nodes have same commRange
     assert allclose([n.commRange for n in self], self.nodes()[0].commRange)
     #TODO: implement decreasing of degree, preserve connected network
     assert value + settings.DEG_ATOL > self.avg_degree()  # only increment
     step_factor = 7.
     steps = [0]
     #TODO: while condition should call validate
     while not allclose(self.avg_degree(), value, atol=settings.DEG_ATOL):
         steps.append((value - self.avg_degree()) * step_factor)
         for node in self:
             node.commRange += steps[-1]
         # variable step_factor for step size for over/undershoot cases
         if len(steps) > 2 and sign(steps[-2]) != sign(steps[-1]):
             step_factor /= 2
     logger.debug("Modified degree to %f" % self.avg_degree())
Пример #23
0
    def send(self, message):
        """
        Send a message to nodes listed in message's destination field.

        Note: Destination should be a list of nodes or one node.

        Update message's source field and  inserts in node's outbox one copy
        of it for each destination.

        """
        message.source = self
        if not isinstance(message.destination, collections.Iterable):
            message.destination = [message.destination]
        for destination in message.destination:
            logger.debug('Node %d sent message %s.' %
                         (self.id, message.__repr__()))
            m = message.copy()
            m.destination = destination
            self.outbox.insert(0, m)
Пример #24
0
 def modify_avg_degree(self, value):
     """
     Modifies (increases) average degree based on given value by
     modifying nodes commRange."""
     # assert all nodes have same commRange
     assert allclose([n.commRange for n in self], self.nodes()[0].commRange)
     #TODO: implement decreasing of degree, preserve connected network
     assert value + settings.DEG_ATOL > self.avg_degree()  # only increment
     step_factor = 7.
     steps = [0]
     #TODO: while condition should call validate
     while not allclose(self.avg_degree(), value, atol=settings.DEG_ATOL):
         steps.append((value - self.avg_degree())*step_factor)
         for node in self:
             node.commRange += steps[-1]
         # variable step_factor for step size for over/undershoot cases
         if len(steps)>2 and sign(steps[-2])!=sign(steps[-1]):
             step_factor /= 2
     logger.debug("Modified degree to %f" % self.avg_degree())
Пример #25
0
    def send(self, message):
        """
        Send a message to nodes listed in message's destination field.

        Note: Destination should be a list of nodes or one node.

        Update message's source field and  inserts in node's outbox one copy
        of it for each destination.

        """
        message.source = self
        if not isinstance(message.destination, collections.Iterable):
            message.destination = [message.destination]
        for destination in message.destination:
            logger.debug('Node %d sent message %s.' %
                         (self.id, message.__repr__()))
            m = message.copy()
            m.destination = destination
            self.outbox.insert(0, m)
Пример #26
0
    def estimate_position(self, node):
        TRESHOLD = .1
        MAX_ITER = 10
        landmarks = []

        # get landmarks with hopsize data
        if self.dataKey in node.memory:
            landmarks = node.memory[self.dataKey].keys()
        # calculate estimated distances
        if len(landmarks) >= 3:
            landmark_distances = []
            landmark_positions = []
            try :
                landmark_distances = [node.memory[self.dataKey][lm][2] *
                                  node.memory[self.hopsizeKey]
                                  for lm in landmarks]
                landmark_positions = [array(node.memory[self.dataKey][lm][:2])
                                  for lm in landmarks]
            except:
                pass
            # take centroid as initial estimation
            pos = average(landmark_positions, axis=0)
            W = diag(ones(len(landmarks)))
            counter = 0
            dist = lambda x, y: sqrt(dot(x - y, x - y))
            while pos.any() != nan:
                J = array([(lp - pos) / dist(lp, pos)
                           for lp in landmark_positions])
                range_correction = array([dist(landmark_positions[li], pos) -
                                          landmark_distances[li]
                                          for li, lm in enumerate(landmarks)])
                pos_correction = dot(linalg.inv(dot(dot(J.T, W), J)),
                                     dot(dot(J.T, W), range_correction))
                pos = pos + pos_correction
                logger.debug("Est. %s, %s, %s" %(node.id, pos, pos_correction))
                counter += 1
                if sqrt(sum(pos_correction ** 2)) < \
                   TRESHOLD or counter >= MAX_ITER:
                    logger.info("Trilaterate break %s" % counter)
                    break
            if counter <= MAX_ITER:
                node.memory[self.positionKey] = pos
                node.memory['reliable'] = landmark_positions
Пример #27
0
    def receive(self):
        """
        Pop message from inbox but only if it has been there at least one step.

        Messages should be delayed for one step for visualization purposes.
        Messages are processed without delay only if they are pushed into empty
        inbox. So if inbox is empty when push_to_inbox is called _inboxDelay is
        set to True.

        This method is used only internally and is not supposed to be used
        inside algorithms.

        """
        if self._inbox and not self._inboxDelay:
            message = self._inbox.pop()
            logger.debug('Node %d received message %s' %
                         (self.id, message.__repr__()))
        else:
            message = None
        self._inboxDelay = False
        return message
Пример #28
0
    def receive(self):
        """
        Pop message from inbox but only if it has been there at least one step.

        Messages should be delayed for one step for visualization purposes.
        Messages are processed without delay only if they are pushed into empty
        inbox. So if inbox is empty when push_to_inbox is called _inboxDelay is
        set to True.

        This method is used only internally and is not supposed to be used
        inside algorithms.

        """
        if self._inbox and not self._inboxDelay:
            message = self._inbox.pop()
            logger.debug('Node %d received message %s' %
                         (self.id, message.__repr__()))
        else:
            message = None
        self._inboxDelay = False
        return message
Пример #29
0
 def recalculate_hopsize(self, node):
     pos = node.memory[self.truePositionKey]
     try:
         landmarks_count = len(node.memory[self.dataKey])
     except KeyError:
         pass
     else:
         if landmarks_count > 0:
             dist = lambda x, y: sqrt(dot(x - y, x - y))
             dt = 0.0
             ht = 0.0
             for lp in node.memory[self.dataKey].values():
                 threshold = FloodingUpdate.lookup.get(
                     lp[2], 0.75) * node.commRange
                 hl = dist(lp[:2], pos) / lp[2]
                 logger.debug("node=%s, hop=%s, threshold=%s, hoplen=%s" %
                              (node.id, lp[2], threshold, hl))
                 if hl > threshold:  # reliable
                     dt += hl
                     ht += lp[2]
             if ht > 0.01:
                 node.memory[self.hopsizeKey] = dt / ht
Пример #30
0
    def _create_modify_network(self, net=None, step=1):
        """Helper method for creating new or modifying given network.

        Arguments:
            net (int):
                network to modify, if None create from scratch
            step:
                if >0 new network should be more dense for <0 less dense

        """
        if net is None:
            net = Network(**self.kwargs)
            for _n in range(self.n_count):
                node = Node(commRange=self.comm_range, **self.kwargs)
                net.add_node(node)
        else:
            print "here2-" + str(step)
            if step>0:
                if len(net)<self.n_max:
                    node = Node(**self.kwargs)
                    net.add_node(node)
                    logger.debug("Added node, number of nodes: %d (%d)"
                                 % (len(net), int(self.n_max)))
                elif not self.comm_range:
                    for node in net.nodes():
                        node.commRange += step
                    logger.debug("Increased commRange to %d"
                                 % node.commRange)
                else:
                    return None
            else:
                print "here3-" + str(self.n_min)
                if len(net) > self.n_min and len(net) > 1:
                    net.remove_node(net.nodes()[0])
                    logger.debug("Removed node, nodes left: %d"
                                 % len(net))
                elif not self.comm_range:
                    if abs(step) >= net.nodes()[0].commRange:
                        step /= 4
                    for node in net:
                        node.commRange += step
                    logger.debug("Decreased commRange to %d"
                                 % net.nodes()[0].commRange)
                else:
                    return None
        return net
Пример #31
0
    def receive(self):
        """
        Pop message from inbox but only if it has been there at least one step.

        Messages should be delayed for one step for visualization purposes.
        Messages are processed without delay only if they are pushed into empty
        inbox. So if inbox is empty when push_to_inbox is called _inboxDelay is
        set to True.

        This method is used only internally and is not supposed to be used
        inside algorithms.

        """
        if self._inbox and not self._inboxDelay:

            message = self._inbox.pop()
            if not message:
                return message
            msg_len = message.message_length()
            if not self.power.have_energy():
                self.n_received_failed_power += 1
                logger.debug(
                    "Node %d doesn't have enough energy to receive message [energy=%5.3f]"
                    % (self.id, self.power.energy))
            else:
                self.power.decrease_rx_energy(msg_len)

                if not message.source:
                    message.source = self
                p1 = self.network.pos[message.source]
                p2 = self.network.pos[message.destination]
                d = sqrt(sum(pow(p1 - p2, 2)))
                self.distance.append(d)
                prt = self.network.propagation.get_power_ratio(d=d)
                self.snr.append(PropagationModel.pw_to_dbm(prt))
                rx_ok = self.network.propagation.is_rx_ok(d=d, prt=prt)

                logger.debug('Node %d received message %s [%d] - %s m (%s)' %
                             (self.id, message.data, msg_len, d,
                              PropagationModel.pw_to_dbm(prt)))

                if rx_ok:
                    self.n_received += 1
                    if message.header not in self.memory:
                        self.memory[message.header] = []
                    self.memory[message.header].append(message.data)
                else:
                    self.n_received_failed_loss += 1
                    logger.debug("Receive Failed due to signal loss: %s" %
                                 self.network.propagation.get_power_ratio(d=d))
            self.energy.append(self.power.energy)
        else:
            message = None
        self._inboxDelay = False

        return message
Пример #32
0
    def receive(self):
        """
        Pop message from inbox but only if it has been there at least one step.

        Messages should be delayed for one step for visualization purposes.
        Messages are processed without delay only if they are pushed into empty
        inbox. So if inbox is empty when push_to_inbox is called _inboxDelay is
        set to True.

        This method is used only internally and is not supposed to be used
        inside algorithms.

        """
        if self._inbox and not self._inboxDelay:

            message = self._inbox.pop()
            if not message:
                return message
            msg_len = message.message_length()
            if not self.power.have_energy():
                self.n_received_failed_power += 1
                logger.debug("Node %d doesn't have enough energy to receive message [energy=%5.3f]" %
                         (self.id, self.power.energy))
            else:
                self.power.decrease_rx_energy(msg_len)

                if not message.source:
                    message.source = self
                p1 = self.network.pos[message.source]
                p2 = self.network.pos[message.destination]
                d = sqrt(sum(pow(p1 - p2, 2)))
                self.distance.append(d)
                prt = self.network.propagation.get_power_ratio(d=d)
                self.snr.append(PropagationModel.pw_to_dbm(prt))
                rx_ok = self.network.propagation.is_rx_ok(d=d, prt=prt)

                logger.debug('Node %d received message %s [%d] - %s m (%s)' %
                             (self.id, message.data, msg_len, d, PropagationModel.pw_to_dbm(prt)))

                if rx_ok:
                    self.n_received += 1
                    if message.header not in self.memory:
                        self.memory[message.header] = []
                    self.memory[message.header].append(message.data)
                else:
                    self.n_received_failed_loss += 1
                    logger.debug("Receive Failed due to signal loss: %s" %
                                 self.network.propagation.get_power_ratio(d=d))
            self.energy.append(self.power.energy)
        else:
            message = None
        self._inboxDelay = False

        return message