摘要:在无线传感器网络的规划和设计中,减少节点的能量消耗、延长其工作时间并最大化网络的生命周期是首先要解决的重要问题。本文设计了一种基于节点能量水平的拓扑控制策略,该策略针对汇聚节点附近节点的能量消耗过多而设计,避免了这些节点因能量过早耗尽而导致的网络失效,该机制使网络中的节点能量消耗更加均衡,延长了网络的寿命。最后通过程序仿真验证了该方法的有效性。
关键词:无线传感器网络,能量水平,网络拓扑
这是我上物联网的一个课程作业,但我不是物联网方向的,最近偶然找了出来看了看,既然已经写了就把发出来供有需要的参考,文章比较简单没有什么好说的,主要是仿真程序花了我一些时间,本来使用C++面向过程的思想编写的,这次简单的改成了面向对象的思想,大家也可以先运行下程序,然后觉得有需要再看下文。
最小能量消耗路由是从数据源到汇聚节点的所有路径中选择节点能耗之和最少的路径;最少跳数路由是选取从数据源到汇聚节点跳数最少的路径。但在无线传感器网络中,如果频繁使用同一条路径传输数据,就会造成该路径上的节点因能量消耗过快而过早失效,从而使整个网络分割成互不相连的孤立部分,减少整个网络的生存期。为了平衡网络负载和节点能耗,当某些节点的能耗较大,而另外一些节点几乎没有什么能耗时,应采用相应措施使节点的能耗相对平均,避免由于某些能耗较大的关键节点(如sink节点或簇头节点)失效而导致整个网络瘫痪。为此,很多研究者从均衡节点能量消耗的角度给出了大量的拓扑控制算法。
本文设计了一种基于节点能量水平的拓扑控制策略, 避免了这些节点因能量过早耗尽而导致的网络失效, 延长了网络的寿命。
本文中N个传感器节点随机分布在一个方形区域A内,并且该传感器网络具有以下性质:
(1) 惟一的基站部署在区域A以外的较远的位置;
(2) 每个节点有惟一的标识;
(3) 每个节点的初始能量基本相同;
(4) 传感器节点部署后不再移动;
(5) 节点的地理位置信息可知;
(6) 发射节点与不同距离的接收节点通信时,可以调整发射功率;
(7) 每轮中节点的能量消耗不统一。
本文中,采用目前比较常用的一阶无线能量模型:融合N个Kbit信息再传输到d远处,所消耗的能量为:
(1)接收数据耗费能量为:
(2)发送数据耗费能量为:
此外,大部分协议和算法都采用了数据聚合技术来减少发送和接收的数据量,从而达到节省能量的目的。本文的策略同样采用数据聚合技术来减少能量损耗。
同时,本文假设无线信道是对称的,即从节点口传送消息加到节点b消耗的能量等于从节点b传送消息m到节点口消耗的能量。
该策略将传感器网络中的所有节点按距离基站的远近分层,在系统初始化时为每个节点设定一个层ID。具有相同层ID的节点处于同一层,它们到基站的距离基本上相同,与基站通信的能量开销也相近。距离基站越近则节点的层ID越小,在策略中,层ID小的节点称为上层节点,层ID大的节点称为下层节点,层ID相同的节点称为同层节点。系统在初始化时将整个网络中的传感器节点根据到基站的距离远近划分为多个层次。在分层过程中,基站首先向网络中所有节点发送LAYER消息。每个节点根据LAYER消息的信号强弱来确定自己距离基站的远近。本文采用自由空间的衰减模型:
其中,为基站发送功率,为接收到信号的功率,d为发送距离,是衰减系数,通常设置为常量,因此传感器节点到基站的距离可以用式计算:
则节点将自己的ID层记为k。
对任意节点的基本信息包括节点ID、层ID、剩余能量ResEnergy、能量门限值ThresEnegry和下一个节点NextNode,即五元组:
broadcast(NodeID,LayerID,ResEnergy,ThresEnegry,NextNode)
节点ID是统一编码的。层ID表示节点距离基站的距离,在系统初始化时设定。剩余能量则记录节点当前剩余的能量。能量门限值用于判断节点是否具备充足的能量用来作为本层的leader节点。节点ID、层ID和NextNode在传感器节点生命周期里都不改变。剩余能量将随节点的能量消耗动态改变,能量门限值则由基站不定期广播。
层ID确定后,每层中的所有节点向本层节点广播broadcast,从而确定本层中能量最高的节点作为本层的第一个leader节点并初始化节点信息,节点发送消息broadcast(NodeID,LayerID,ResEnergy, ThresEnegry, NextNode),本层中距离最近节点接受此报文,并反馈自己的节点标识NodeID信息,这时节点再初始化其NextNode节点为的NodeID。同样,节点也向距离自己最近的节点发送broadcast,收到信息的节点也同样反馈其NodeID为的NextNode,以此类推,直到链接本层的所有节点,需要注意的是,本层的最后一个节点没有下一个节点,因此其NextNode为空。
网络连接信息记录与上层leader传感器节点的链接的基本信息,包括节点ID,层ID及剩余能量ResEnergy。连接信息用3个队列表示:父节点队列(parents)、兄弟节点队列(siblings)和子节点队列(children)。这3个队列在系统初始化时构建,父队列存放层ID比自己小的上层邻接节点,兄弟队列存放层ID和自己相同的同层邻接节点,子队列存放层ID比自己大的下层邻接节点。
每层的所有节点都把传感器收集的信息发送给本层的leader节点。同时,也收集下层节点的leader节点融合的数据,然后把数据融合起来发送给上层节点。以此类推,直到把数据发送给sink节点。可想而知,由于leader节点接受和发送大量的数据,故能量将消耗的更快。
为了能量的均衡消耗,当leader节点的剩余能量ResEnergy小于ThresEnegry时,本层的leader节点将换为NextNode节点。
随着节点能量消耗,当本层中所有节点的剩余能量都小于ThresEnegry时,层leader节点将于下层的leader节点逻辑上兑换顺序,即把本层的节点收集的传感器信号发送给下层节点,本层的下层leader节点将发送数据给本层的上层的leader节点。
与sink节点直接通信的节点称为顶层节点。顶层节点同时满足下列两个条件:
1)父节点队列为空;
2)节点本身剩余能量大于预设定的阈值。
因为顶层节点直接和基站通信,其能量消耗比非顶层节点快。当顶层节点中leader节点的能量小于预先设定的阈值ThresEnegry时,它不再具备和基站通信的资格。在这种情况下,该策略把与基站通信的任务转交给距离基站稍远但能量充足的leader节点,这种机制称为顶层节点迁移。通过顶层节点迁移,系统能够均匀地把能量损耗分布到网络中所有节点。在顶层节点迁移的情况下,顶层节点将自己与下层邻接节点的父子对换。节点先接收来自子节点的数据,然后将所接收到的数据与自身数据聚合。
如果节点收到多个HEADER消息,则选择能量水平最高的消息转发,将能量水平低的消息丢弃。当某项层节点的能量不足,并且其兄弟队列中所有邻接节点的能量也都小于设定的阈值时,该节点需要与邻接的下层节点对换父子关系:
(1) 将该节点子队列中的邻接下层节点转移到父队列中;
(2) 将该节点从对应下层节点的父队列中转移到子队列中。
当节点本身或兄弟队列中的同层节点能量充足时,数据在本层节点平行传递;当节点本身及兄弟队列中的同层节点能量不足时,对换本节点与下层节点的父子关系。
随着网络能量不断消耗,顶层节点将由最靠近基站的节点迁移到最远离基站的节点。最后,系统中所有节点的能量都小于能量门限值ThresEnegry。因为在发送给基站的数据包中包含发送节点的剩余能量值,当基站发现发送节点的能量值小于ThresEnegry时,将ThresEnegry乘:
然后基站将新的门限值广播给所有节点,所有节点将自己的ThresEnegry乘。距离基站0层节点重新变回顶层节点。系统又开始下一轮的顶层节点迁移,直到网络能量耗尽。
1):每个节点初始化层ID,剩余能量ResEnergy。根据距离获取每个的所在层LayerID。
2):每个节点在本层广播一个broadcast(NodeID,LayerID,ResEnergy,NULL,NULL)信息,获得本层的最高能量节点作为本层的leader节点。
3):以leader节点为链头,以最短距离为尺度把本层的所有节点连接成链。
4):各leader节点接收下层leader节点的数据并与自身在本层获取的数据进行融合后传向上一层的leader节点。
5): 当与sink节点直接通信的顶层leader节点的剩余能量ResEnergy低于ThresEnegry时,通过顶层迁移节点交换顶层leader节点和下层leader节点的父子关系。如果所有leader节点的剩余能量ResEnergy都低于ThresEnegry,则,转到4)。
本仿真程序平台:Window7+VS2012+OpenCV2.4.4。OpenCV2.4.4的具体配置方法请参考官网:http://wiki.opencv.org.cn/index.php 。
1) 在600*600像素图片中随机生成NODENUM=100个节点,其中左上角的点为sink节点,其坐标为(0,0)。如图1:
图1
2)根据与sink节点的距离获取每个的所在层LayerID。
图2
3)获得每层的leader节点,本程序以每层最左边的节点作为层leader节点,应该可以假设开始所以节点的能量基本相同。如图3(左边的5个绿色节点代表每层的leader节点):
图3
4) 以每层的leader节点为链头,以最短距离为尺度把本层的所有节点连接成链,如图4:
图4
5) leader节点在本层中迁移。假设每层中发送信号消耗的能量与距离成平方关系。
图5 图6
图7 图8
图9 图10
其中,节点的颜色表示节点的剩余能量ResEnergy:
蓝色: ResEnergy > 80%
黄色: 80% > ResEnergy > 60%
橙色: 60% > ResEnergy > 40%
红色: 40% > ResEnergy > 20%
灰色: 20% > ResEnergy > 10%
黑色: 10% > ResEnergy > 0
大黑点代表最先电量耗尽的传感器节点。
4.3 结果比较
变功率发送信号(图10)和恒定功率发送信号(图11)的比较:
图10 图11
可以看出:图10顶层能量基本耗尽,而图11的能量消耗不均匀,还有很多橙色节点和黄色节点。
从图12与图13比较可知,变功率发送信号的层leader节点迁移更能节省能量。
图12 图13
下面是wsnnode的头文件,cpp文件没有贴出来了。
1 // wsnnode.h 2 #pragma once 3 #include <math.h> 4 5 #include "opencv2/opencv.hpp" 6 7 using namespace cv; 8 9 class WSNNode 10 { 11 public: 12 //构造函数 13 WSNNode(); 14 WSNNode(int ); 15 WSNNode(int ,int ); 16 WSNNode(int _x,int _y,int _number,double _energy); 17 WSNNode(int _x,int _y,int _number,double _energy,Scalar _color); 18 //析构函数 19 ~WSNNode(void); 20 //到sink节点的距离 21 float distance()const{return sqrt(float(x*x+y*y));} 22 //节点所在层 23 int layer (); 24 //节点的颜色 25 Scalar NodeColor(); 26 //节点的id号 27 int GetNodeID()const; 28 //节点的颜色 29 Scalar GetNodeColor()const; 30 31 public: 32 //坐标(x,y) 33 int x,y; 34 //当前剩余能量 35 double energy; 36 37 private: 38 //当前层的Leader节点的ID号 39 int leaderID; 40 //当前节点的id号 41 int id; 42 // 节点的颜色 43 Scalar color; 44 };
接着是wsntopologybasedenergy.h头文件,wsntopologybasedenergy.cpp文件的实现也省略了。
1 #include <ctime> 2 #include <vector> 3 4 #include <opencv2\opencv.hpp> 5 #include "wsnnode.h" 6 7 using namespace std; 8 using namespace cv; 9 10 class WSNTopologyBasedEnergy 11 { 12 public: 13 enum TransportType 14 { 15 ConstPowertoLeader = 0, 16 VarPowertoLeaderAndSinkShift = 1, 17 }; 18 19 public: 20 //构造函数 21 WSNTopologyBasedEnergy(TransportType type = ConstPowertoLeader); 22 //随机生成点 23 int InitNode(int width, int heigth, int NodeNum); 24 //找到每个点的所在层 25 void ClassifyNode(); 26 //画出每一层(以面积) 27 void DrawWSNLayer(); 28 //找到左边第一个连接点 29 void FindLayerFirstLinkNode(); 30 //每一层链接成链 31 void LinkNodeEachLayer(); 32 //WSN网络的终止时间 33 int WSNLifeTime(); 34 35 private: 36 //标记生成的点 37 void drawCrossNode(Mat &img, WSNNode node, Scalar color); 38 //两点间的距离 39 double DistanceBetweenNodes(WSNNode node1,WSNNode node2); 40 //两点间的距离的平方 41 double SDistanceBetweenNodes(WSNNode node1,WSNNode node2); 42 //随机选择1-10个结点传送数据。 43 vector<int> SelectServalNode(); 44 //选择leader节点 45 void SelectLeaderID(); 46 //0层为顶层直接与sink节点发送信号 47 void TopLayer0SentSink(); 48 //1层为顶层直接与sink节点发送信号 49 void TopLayer1SentSink(); 50 //2层为顶层直接与sink节点发送信号 51 void TopLayer2SentSink(); 52 //3层为顶层直接与sink节点发送信号 53 void TopLayer3SentSink(); 54 //4层为顶层直接与sink节点发送信号 55 void TopLayer4SentSink(); 56 57 int MinMark(); 58 //显示随机选择的1-10个点并发送信号显示能量变化。以变功率发送信号 59 void NodeSentSignalVarPower(); 60 //以恒定功率发送信号 61 void NodeSentSignalSamePower(); 62 63 private: 64 //模拟图像 65 Mat img; 66 //测试 67 bool Test; 68 //发送类型 69 char type_; 70 //汇聚节点 71 WSNNode sink; 72 //能量传送系数 73 double alpha; 74 //直接与sink节点通信的层号 75 int TopLayer; 76 //节点的个数 77 static const int NODENUM = 100; 78 //层数 79 static const int LayerNum = 5; 80 //节点能量初始值 81 double ENERGY; 82 //整个网络的能力阈值 83 double NetThresEnergy; 84 //标记 85 int Mark[LayerNum]; 86 //每层的能量阈值 87 double ThresEnergy[LayerNum]; 88 //初始化的节点 89 WSNNode node[NODENUM]; 90 //每层的第一个链接节点 91 WSNNode LayerFirstLinkNode[LayerNum]; 92 //每层的容器数组 93 vector<WSNNode> layer[LayerNum]; 94 //每层的链接顺序容器 95 vector<WSNNode> LayerLeaderSeq[LayerNum]; 96 //每层的Leader节点 97 WSNNode LayerLeaderNode[LayerNum]; 98 };
本章借鉴了LEACH算法、TEEN算法、PEGASIS算法、PEDAP算法等几种经典算法的优点,给出了基于节点能量水平的拓扑控制策略,该策略将网络中的节点按照距离sink节点的远近划分成不同的层次,每层中选择能量水平高的节点和相邻层间进行通信,然后选择距离sink节点最近的且剩余能量大于给定阀值的节点直接和sink节点通信,从而避免sink节点附近的节点过早死亡,而导致网络死亡。该策略使网络中的节点能量消耗更加均衡,从而延长网络的寿命。