Exemple #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
Exemple #2
0
    def _setup(self, settings_module=None):
        """
        Load the settings module pointed to by the environment variable.

        This is used the first time we need any settings at all, if the user
        has not previously configured the settings manually.

        """
        if settings_module is None:
            try:
                settings_module = os.environ[ENVIRONMENT_VARIABLE]
                if not settings_module:  # If it's set but is an empty string.
                    raise KeyError
            except KeyError:
                settings_module = None
                logger.warning("Environment variable %s is undefined, using "
                               "global_settings." % ENVIRONMENT_VARIABLE)
            else:
                logger.info("Settings module is specified in environment"
                            "variable %s." % (ENVIRONMENT_VARIABLE))

        if settings_module is not None:
            logger.info("Using module %s to override global_settings."\
                         % (settings_module))

        self._wrapped = Settings(settings_module)
Exemple #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
Exemple #4
0
    def _setup(self, settings_module=None):
        """
        Load the settings module pointed to by the environment variable.

        This is used the first time we need any settings at all, if the user
        has not previously configured the settings manually.

        """
        if settings_module is None:
            try:
                settings_module = os.environ[ENVIRONMENT_VARIABLE]
                if not settings_module:  # If it's set but is an empty string.
                    raise KeyError
            except KeyError:
                settings_module = None
                logger.warning("Environment variable %s is undefined, using "
                               "global_settings." % ENVIRONMENT_VARIABLE)
            else:
                logger.info("Settings module is specified in environment"
                            "variable %s." % (ENVIRONMENT_VARIABLE))

        if settings_module is not None:
            logger.info("Using module %s to override global_settings."\
                         % (settings_module))

        self._wrapped = Settings(settings_module)
Exemple #5
0
 def environment(self, environment):
     """ If net environment is changed all nodes are moved into and
         corresponding channelType environment must be changed also. """
     self._environment = environment
     self.channelType.environment = environment
     for node in self.nodes():
         self.remove_node(node)
         self.add_node(node)
     logger.warning('All nodes are moved into new environment.')
Exemple #6
0
    def __init__(self, n_count=None, n_min=0, n_max=Inf, connected=True,
                 degree=None, comm_range=None, method="random_network",
                 **kwargs):
        """
        Arguments:
            n_count (int):
                number of nodes, if None settings.N_COUNT is used
            n_min (int):
                minimum number of nodes
            n_max (int):
                maximum number of nodes
            connected (bool):
                if True network must be fully connected
            degree (int):
                average number of neighbors per node
            comm_range (int):
                nodes communication range, if None settings.COMM_RANGE is used
                and it is a signal that this value can be changed if needed to
                satisfy other wanted properties (connected and degree)
            method (str):
                sufix of the name of the method used to generate network
        kwargs can be network and node __init__ kwargs i.e.:
            environment (:class:`Environment`):
                environment in which the network should be created, if None
                settings.ENVIRONMENT is used
            channelType (:class:`ChannelType`)
            algorithms (tuple)
            commRange (int):
                overrides `comm_range`
            sensors (tuple)

        Basic usage:

        >>> net_gen = NetworkGenerator()
        >>> net = net_gen.generate()

        """
        self.n_count=n_count if n_count else settings.N_COUNT
        if self.n_count<n_min or self.n_count>n_max:
            raise NetworkGeneratorException('Number of nodes must be between '
                                            'n_min and n_max.')
        if degree and degree>=n_max:
            raise NetworkGeneratorException('Degree % d must be smaller than '
                                            'maximum number of nodes %d.'
                                            % (degree, n_max))
        #TODO: optimize recalculation of edges on bigger commRanges
        if degree and degree>16 and n_count!=Inf:
            logger.warning("Generation could be slow for large degree"
                           "parameter with bounded n_max.")
        self.n_min = n_min
        self.n_max = n_max
        self.connected = connected
        self.degree = degree
        self.comm_range = kwargs.pop('commRange', comm_range)
        #TODO: use subclass based generators instead of method based
        self.generate = self.__getattribute__("generate_" + method)
        self.kwargs = kwargs
Exemple #7
0
 def environment(self, environment):
     """ If net environment is changed all nodes are moved into and
         corresponding channelType environment must be changed also. """
     self._environment = environment
     self.channelType.environment = environment
     for node in self.nodes():
         self.remove_node(node)
         self.add_node(node)
     logger.warning('All nodes are moved into new environment.')
Exemple #8
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
Exemple #9
0
 def get_current_algorithm(self):
     """ Try to return current algorithm based on algorithmState. """
     if len(self.algorithms) == 0:
         logger.warning('There is no algorithm defined in a network.')
         return None
     if self.algorithmState['finished']:
         if len(self.algorithms) > self.algorithmState['index'] + 1:
             self.algorithmState['index'] += 1
             self.algorithmState['step'] = 1
             self.algorithmState['finished'] = False
         else:
             return None
     return self.algorithms[self.algorithmState['index']]
Exemple #10
0
 def get_current_algorithm(self):
     """ Try to return current algorithm based on algorithmState. """
     if len(self.algorithms) == 0:
         logger.warning('There is no algorithm defined in a network.')
         return None
     if self.algorithmState['finished']:
         if len(self.algorithms) > self.algorithmState['index'] + 1:
             self.algorithmState['index'] += 1
             self.algorithmState['step'] = 1
             self.algorithmState['finished'] = False
         else:
             return None
     return self.algorithms[self.algorithmState['index']]
Exemple #11
0
 def get_current_algorithm(self):
     """ Try to return current algorithm based on algorithmState. """
     if len(self.algorithms) == 0:
         logger.warning("There is no algorithm defined in a network.")
         return None
     if self.algorithmState["finished"]:
         if len(self.algorithms) > self.algorithmState["index"] + 1:
             self.algorithmState["index"] += 1
             self.algorithmState["step"] = 1
             self.algorithmState["finished"] = False
         else:
             return None
     return self.algorithms[self.algorithmState["index"]]
Exemple #12
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
Exemple #13
0
def get_crb(net, sensor, compass='******', loc_type='anchor-free', anchors=[]):
    """
    Calculates Cramer-Rao lower bound on covariance matrix of unbiased multihop
    location estimator based on sensor (distance/angle) measurement between
    in-commrange neighbors.

    POS is n by 2 matrix of X and Y coordinates of n nodes
    SIGMA is standard deviation on measurement vector.

    Arguments:
     `compass` -- 'off' (default) or 'on' which means all nodes have compass
     `loc_type` -- 'anchor-free' (default) or 'anchored'
     `anchors` -- list of anchor nodes, used only when loc_type is 'anchored'

    References:
        Savvides2003 - Savvides et al,
                        On the Error Characteristics of Multihop Node
                        Localization in Ad-Hoc Sensor Networks, 2003
        Patwari2005 - Patwari et al,
                        Locating the nodes: cooperative localization in
                        wireless sensor networks
        Chang2006 - Chen Chang et al,
                        Cramer-Rao-Type Bounds for Localization, 2006
    """

    if loc_type == 'anchored' and not anchors:
        raise Exception('Anchors not defined.')
    if loc_type == 'anchor-free' and anchors:
        logger.warning('Anchors are ignored')
        anchors = []

    nodes = [node for node in net.nodes() if node not in anchors]

    if sensor.name()=='AoASensor' and compass=='off':
        u = 3  # x, y, theta
    else:  # DistSensor or AoASensor with compass on
        u = 2  # x, y

    G = construct_G(net.pos, net.edges(), u, sensor.name())

    for s in nodes[0].compositeSensor.sensors:
        if s.name() == sensor.name():
            sigma = s.probabilityFunction.scale
            break
    else:
        raise Exception('Sensor not found in nodes')

    J = (dot(G.T, G)) / sigma ** 2

    #print matrix_rank(J)

    if loc_type == 'anchor-free':
        cov = pinv(J)
    elif loc_type=='anchored':
        cov = inv(J)

    # Chang2006 (28)
    di = diag(cov)
    # extract only position from cov
    di = concatenate((di[::3], di[1::3]))

    #return is lower bound on rms -> sqrt(1/n*sum_i^n((x_i'-x_i)^2+(y_i'-y_i)^2))
    return sqrt(2*mean(di))
Exemple #14
0
    def __init__(self, n_count=None, n_min=0, n_max=32000, connected=True,
                 degree=None, comm_range=None, method=None,
                 **kwargs):
        """
        Arguments:
            n_count (int):
                number of nodes, if None settings.N_COUNT is used
            n_min (int):
                minimum number of nodes
            n_max (int):
                maximum number of nodes
            connected (bool):
                if True network must be fully connected
            degree (int):
                average number of neighbors per node
            comm_range (int):
                nodes communication range, if None settings.COMM_RANGE is used
                and it is a signal that this value can be changed if needed to
                satisfy other wanted properties (connected and degree)
            method (str):
                sufix of the name of the method used to generate network
        kwargs can be network and node __init__ kwargs i.e.:
            environment (:class:`Environment`):
                environment in which the network should be created, if None
                settings.ENVIRONMENT is used
            channelType (:class:`ChannelType`)
            algorithms (tuple)
            commRange (int):
                overrides `comm_range`
            sensors (tuple)

        Basic usage:

        >>> net_gen = NetworkGenerator()
        >>> net = net_gen.generate()

        """
        self.name = "Unknown"
        self.n_count=n_count if n_count else settings.N_COUNT
        if self.n_count<n_min or self.n_count>n_max:
            raise NetworkGeneratorException('Number of nodes must be between '
                                            'n_min and n_max.')
        if degree and degree>=n_max:
            raise NetworkGeneratorException('Degree % d must be smaller than '
                                            'maximum number of nodes %d.'
                                            % (degree, n_max))
        #TODO: optimize recalculation of edges on bigger commRanges
        if degree and degree>16 and n_count!=Inf:
            logger.warning("Generation could be slow for large degree"
                           "parameter with bounded n_max.")
        self.n_min = n_min
        self.n_max = n_max
        self.connected = connected
        self.degree = degree
        self.comm_range = kwargs.pop('commRange', comm_range)

        #TODO: use subclass based generators instead of method based
        if (method):
            self.generate = self.__getattribute__("generate_" + method)
        self.kwargs = kwargs
        self.area = 0
        self.net_density = 0
Exemple #15
0
def get_crb(net, sensor, compass='******', loc_type='anchor-free', anchors=[]):
    """
    Calculates Cramer-Rao lower bound on covariance matrix of unbiased multihop
    location estimator based on sensor (distance/angle) measurement between
    in-commrange neighbors.

    POS is n by 2 matrix of X and Y coordinates of n nodes
    SIGMA is standard deviation on measurement vector.

    Arguments:
     `compass` -- 'off' (default) or 'on' which means all nodes have compass
     `loc_type` -- 'anchor-free' (default) or 'anchored'
     `anchors` -- list of anchor nodes, used only when loc_type is 'anchored'

    References:
        Savvides2003 - Savvides et al,
                        On the Error Characteristics of Multihop Node
                        Localization in Ad-Hoc Sensor Networks, 2003
        Patwari2005 - Patwari et al,
                        Locating the nodes: cooperative localization in
                        wireless sensor networks
        Chang2006 - Chen Chang et al,
                        Cramer-Rao-Type Bounds for Localization, 2006
    """

    if loc_type == 'anchored' and not anchors:
        raise Exception('Anchors not defined.')
    if loc_type == 'anchor-free' and anchors:
        logger.warning('Anchors are ignored')
        anchors = []

    nodes = [node for node in net.nodes() if node not in anchors]

    if sensor.name() == 'AoASensor' and compass == 'off':
        u = 3  # x, y, theta
    else:  # DistSensor or AoASensor with compass on
        u = 2  # x, y

    G = construct_G(net.pos, net.edges(), u, sensor.name())

    for s in nodes[0].compositeSensor.sensors:
        if s.name() == sensor.name():
            sigma = s.probabilityFunction.scale
            break
    else:
        raise Exception('Sensor not found in nodes')

    J = (dot(G.T, G)) / sigma**2

    #print matrix_rank(J)

    if loc_type == 'anchor-free':
        cov = pinv(J)
    elif loc_type == 'anchored':
        cov = inv(J)

    # Chang2006 (28)
    di = diag(cov)
    # extract only position from cov
    di = concatenate((di[::3], di[1::3]))

    #return is lower bound on rms -> sqrt(1/n*sum_i^n((x_i'-x_i)^2+(y_i'-y_i)^2))
    return sqrt(2 * mean(di))