
1. 三种协议的“家谱”为什么WSN路由都要从LEACH说起做无线传感器网络WSN仿真的朋友不管你是刚起步的本科生还是已经在写大论文的研究生大概率都绕不开LEACH这个名字。我第一次跑LEACH仿真的时候心里其实挺不屑的——这协议简单得有点“粗暴”随机选簇头、单跳传输、假设基站无限能量任何一个细节拿出来都经不起推敲。但后来做了几个对比实验才发现恰恰是这种简单让LEACH成了WSN路由协议里绕不开的“基准线”几乎所有改进协议都在它的框架上做文章。本文要拆解的LEACH、LEACH-C和TS-I-LEACH正好代表了这条演进路线上的三个里程碑。整个研究的基本盘是部署一片区域内的传感器节点节点有初始能量采集数据后不能直接远距离传给基站太费电所以需要分簇——每个簇选一个簇头簇内成员把数据发给簇头簇头做数据融合后统一转发给基站。LEACH就是这套分簇思想的鼻祖LEACH-C把“选簇头”这件事从分布式改成了集中式TS-I-LEACH则是在前两者基础上继续打补丁主要解决能量均衡和事件响应的问题。三者在Matlab里都能实现而且代码框架高度相似非常适合拿来对比学习。这篇文章不打算做成教科书式的原理背诵而是直接从“怎么在Matlab里把它们跑起来、怎么读结果、怎么解释结果”的角度入手。我会把三套协议的核心机制拆开讲清楚再给出可复现的Matlab实现思路最后结合我自己跑实验时遇到的各种坑告诉你为什么协议表现会和你直觉不一样。无论你是要做课程设计、毕业论文还是单纯想入门WSN仿真这篇文章的代码和思路都可以直接接过去用。1.1 LEACH的核心机制与它当年解决的痛点LEACHLow Energy Adaptive Clustering Hierarchy低功耗自适应分簇层次协议是Heinzelman在2000年提出的。在那个年代WSN的主流做法是节点直接把数据发给基站也就是单跳直传。这种做法在小规模网络里没毛病但节点一多、距离一远远端节点发一帧数据的能耗高得离谱很快整片网络就“瘫”了。LEACH的核心贡献在于把网络划分成若干个簇每轮round动态选出一个比例通常5%的节点担任簇头。簇内普通节点只在分配给自己的TDMA时隙内把数据发送给簇头簇头接收完所有成员的数据后做融合再以单跳方式发给基站。关键设计有两个一是簇头角色每轮轮换避免某个节点一直当簇头而耗尽能量二是数据在簇头处做了融合大幅减少了发往基站的流量。但LEACH的短板也相当明显。簇头选举使用的是“纯概率”机制每个节点独立生成一个随机数小于阈值T(n)就当选。这个阈值只跟当前轮数和期望簇头比例有关跟节点还剩多少能量毫无关系。跑过仿真的人都知道一个能量只剩0.01J的“残血”节点依然有可能被随机选中当簇头结果就是它很快死掉簇内成员集体失联。除此之外所有簇头都直接和基站单跳通信距离基站远的簇头死得特别快这是LEACH在能耗均衡上的硬伤。1.2 LEACH-C把决策权交给基站的集中式思路LEACH-CLEACH-Centralized是同一批作者在2002年提出的改进版核心思想非常直接既然节点自己选簇头不靠谱那就让基站来选。每一轮开始时所有存活节点把自己的位置和剩余能量报给基站基站根据全局信息用模拟退火算法找出一个“最优分簇方案”——目标是让簇头数量合适、簇头分布均匀、簇内通信总能耗最小。选完簇头之后基站把分簇结果广播给所有节点节点按这个方案运行一轮。这个思路在仿真里效果立竿见影。因为基站掌握了全局剩余能量选举时可以强制排除低能量节点也不会出现两个簇头挨在一起、旁边大片区域却没有簇头的尴尬情况。我实测下来在相同参数下LEACH-C的第一个节点死亡轮数FND通常比LEACH晚20%到30%。不过LEACH-C并非没有代价。它要求基站与所有节点双向通信每一轮开始都要收集全网的“能量报告”这会消耗额外的控制开销。而且它默认基站知道所有节点的精确坐标这在真实部署中往往需要通过GPS或定位算法获得本身就不便宜。此外模拟退火算法每轮都要重新跑一遍计算量不小——在Matlab仿真里这无所谓但放到真实传感器节点上基站的算力不一定扛得住。1.3 TS-I-LEACH在阈值敏感和能量均衡之间找平衡TS-I-LEACH这个简称在学术论文里并没有唯一的标准定义通常可以理解为“Threshold Sensitive - Improved LEACH”即基于阈值敏感机制的LEACH改进版本。它最核心的两点改动我在跑代码时感受特别明显第一是引入阈值敏感的数据传输策略。普通LEACH是每轮都固定上报数据哪怕监测值没有任何变化也照发不误白白浪费能量。阈值敏感策略分硬阈值和软阈值两层只有当监测值超过硬阈值或者相比上次上报值的变化量超过软阈值时节点才发送数据。这一下能砍掉大量冗余通信非常贴合火灾监测、入侵探测这类事件驱动型应用。第二是改进簇头选举公式把“纯随机”改成“能量感知通信代价感知”。典型的做法是在当选阈值里乘上一个权重系数表达式类似这样T(n) p / (1 - p * (r mod (1/p))) * [E_remaining / E_initial]也可能在分子里加入“节点到基站的距离倒数”或“节点密度因子”让簇头尽量出现在能量富余、位置合适的地方。有些变种还会把簇头到基站的距离、簇内平均距离和邻居节点数综合起来做一个“适应度值”再按适应度排序选簇头相当于在分布式框架里模拟了LEACH-C的集中式择优效果。我看到的TS-I-LEACH仿真代码里还有个常见的配套改动是引入多跳传输。簇头不再全员直接发给基站而是根据到基站的距离动态决定近的直接单跳远的先发给附近更靠近基站的簇头代传。这样一来远端簇头不至于过早阵亡整个网络的能量消耗曲线会平坦很多。整体来说TS-I-LEACH的定位就是“在能量均衡和事件响应实时性之间找一个更好的平衡点”它在仿真数据上的表现通常也是最漂亮的。2. 仿真建模的第一课网络模型与能量消耗写Matlab代码之前先把仿真场景定义清楚。很多新手一上来就写代码结果跑出来的图东一个坑西一个坑回头一看是网络模型没定好。这套对比实验我用的是WSN仿真里最经典的配置照着用就行。2.1 网络参数怎么定网络模型就是一块100m×100m的正方形区域100个传感器节点随机均匀分布在这块区域里坐标在(0,0)到(100,100)之间。基站固定在(50,150)也就是区域正上方50米外。每个节点初始能量0.5J数据包大小4000bit控制包大小100bit簇头占节点总数的比例p设为0.05这个值直接影响每轮簇头数量也是后面调参的重点。具体参数整理如下表参数数值说明区域大小100m × 100m经典正方形部署区节点数量100均匀随机分布基站位置(50, 150)区域外上方模拟远程汇聚点初始能量 E_init0.5 J各节点相同数据包大小4000 bit成员节点→簇头融合后包大小4000 bit簇头→基站含融合增益控制包大小100 bit广播、报告等控制信息簇头比例 p0.05即每轮期望5个簇头最大轮数可设20004000视网络寿命而定有一点必须提醒建模时基站默认是“无限能量”的也就是说基站收发数据不消耗自己的能量预算。这在真实部署里当然不成立但在仿真中大家普遍这么干目的是把研究焦点集中在传感器节点之间的能耗公平性上。如果你在论文里写“基站为无限能量节点”必须明确交代这个假设否则评审会挑刺。2.2 一阶无线能量模型三种协议的能耗计算基本都采用一阶无线模型First Order Radio Model。模型的核心思想是发送节点要消耗两笔能量一笔是驱动发射电路的发电路耗E_elec一笔是放大器的放大能耗E_amp接收节点则主要消耗发电路耗。放大能耗根据距离的远近分两种模式距离小于阈值d0时用自由空间模型能耗与距离平方成正比距离大于等于d0时用双路径衰减模型能耗与距离四次方成正比。用公式表示就是[ E_{Tx}(k, d) E_{elec} \times k E_{amp} \times k \times d^2 \quad (d d_0) ][ E_{Tx}(k, d) E_{elec} \times k E_{amp} \times k \times d^4 \quad (d \ge d_0) ][ E_{Rx}(k) E_{elec} \times k ]在Matlab里我习惯把发射能耗和接收能耗分别封装成两个函数避免每次都在主循环里重写一遍公式。参考代码长这样function E_Tx calcTxEnergy(k, d, Eelec, Eamp_fs, Eamp_mp, d0) if d d0 E_Tx Eelec * k Eamp_fs * k * d^2; else E_Tx Eelec * k Eamp_mp * k * d^4; end end function E_Rx calcRxEnergy(k, Eelec) E_Rx Eelec * k; end参数方面E_elec一般取50nJ/bitEamp_fs自由空间放大系数取10pJ/bit/m²Eamp_mp双路径放大系数取0.0013pJ/bit/m⁴d0约87.7m。这些数值来自Heinzelman论文里的经典设定也是Matlab社区代码里最常用的默认值。需要注意的是Eamp_mp由于要和d的四次方相乘数值单位上必须是“每bit每m的四次方”的能量密度别和Eamp_fs的单位搞混。2.3 性能指标的判读口径做三种协议对比不能光看一张“存活节点数”曲线就下结论必须同时盯几个指标FNDFirst Node Death首个节点死亡轮数反映网络的“稳定期”。第一个节点死之后的网络覆盖质量就开始打折扣很多应用场景里FND就是有效的网络寿命。HNDHalf Node Death半数节点死亡轮数反映网络的“半衰期”比FND更抗随机性干扰。LNDLast Node Death最后节点死亡轮数反映网络的“极限寿命”但孤零零几个节点活着其实没有实际感知价值只能做参考。网络总剩余能量曲线每一轮所有存活节点的剩余能量之和。注意它下降越快说明总能耗越高。能量均衡度可以用“每轮存活节点剩余能量的方差”或“每轮死亡节点数量”来衡量。同样总剩余能量的两条曲线如果一条是“大家一起慢慢死”另一条是“某些节点狂死”显然后者协议的能量均衡性更差。吞吐量基站总共收到的数据包数量这个直接反映了协议的实际数据交付能力。我建议把FND、HND、LND和总能耗画成一张表再用折线图展示每轮的存活节点数和总剩余能量。多协议对比时优先看FND和能量均衡度因为LND容易被极端情况带偏——比如某个“天选节点”碰巧离基站特别近最后一轮还活着但它已经代表了什么采集能力了。3. Matlab代码实现的核心环节很多网上代码把LEACH系列实现写成几百行的主脚本看起来很高大上实际上里头的逻辑非常混乱一个循环套一个循环能量更新的位置还容易错。我自己更推荐用“主循环功能函数”的结构把网络初始化、簇头选举、数据传输、能量更新拆成独立模块这样不管是调试还是后期改成其他改进协议都轻松很多。这一节我就按这个思路把三个协议在Matlab里实现的关键环节逐个说透。3.1 节点初始化和网络拓扑生成初始化这一步看似简单但直接影响实验的可复现性。建议先固定随机数种子消除随机性对结果的影响。具体做法是使用Matlab的rng(0)或rand(seed, 0)这样每次运行生成的网络拓扑都是一模一样的。代码可以这样写rng(0); % 固定随机种子保证拓扑可复现 numNodes 100; areaLen 100; baseStation [50, 150]; % 节点坐标均匀随机分布 nodePositions rand(numNodes, 2) * areaLen; % 节点初始能量 initialEnergy 0.5; nodeEnergy ones(numNodes, 1) * initialEnergy; % 节点状态1存活0死亡 nodeAlive ones(numNodes, 1); % 记录每轮存活数 aliveHistory [];这里有个细节把基站坐标从节点坐标里分离出来因为基站不参与“存活/死亡”判断。有些代码误把基站当成第101个节点一起初始化后面算平均能量时总是莫名其妙多个“永不死”的节点折腾半天才排查出来。另一个实用技巧是用scatter函数画出初始拓扑每个点的大小按剩余能量映射。方便调试时肉眼观察节点分布和后续死亡位置的关系figure; scatter(nodePositions(:,1), nodePositions(:,2), 30, nodeEnergy, filled); hold on; plot(baseStation(1), baseStation(2), rp, MarkerSize, 15, LineWidth, 2); colorbar; xlabel(x (m)); ylabel(y (m)); title(初始节点分布与能量);3.2 簇头选举的判定逻辑差异这是三种协议在代码上区别最大的地方。LEACH的簇头选举非常“朴素”每个节点生成一个0到1之间的随机数如果小于阈值T(n)就当簇头。T(n)的计算公式是T(n) p / (1 - p * (r mod (1/p))) 若 n 属于 G T(n) 0 若 n 不属于 G其中G是“最近1/p轮里没当过簇头的节点集合”。这个设计保证了每个节点不会连续当选达到轮流“当值”的效果。Matlab实现大概这样p 0.05; for i 1:numNodes if nodeAlive(i) 1 isMember(i, G) threshold p / (1 - p * mod(currentRound, floor(1/p))); if rand threshold clusterHead(i) 1; end end end注意mod(currentRound, floor(1/p))里面要用floor取整因为1/p20是个整数但如果你把p改成0.07之类的非整倒数就一定要处理取整问题否则阈值算出来是错的。LEACH-C的选举不走“每节点自己产生随机数”这条路而是由基站统一规划。代码里最笨但有效的实现是把所有存活节点的位置和能量汇总成矩阵然后枚举不同簇头组合的代价选代价最小的那组。当然真实LEACH-C用模拟退火Simulated Annealing来逼近最优解但在Matlab仿真里节点数量不超过200时用穷举剪枝也能跑只是慢一些。如果是教学演示我一般直接写一个基于“能量优先级排序”的简化版LEACH-C把存活节点按剩余能量降序排列从高能量节点里抽出前5%作为簇头候选再用K-means或按距离就近分配成员。TS-I-LEACH的选举则介于两者之间。它保留LEACH的分布式随机框架但把阈值公式改成了“带能量权重”的版本同时增加了一个低能量保护机制节点剩余能量低于平均能量的某个比例比如80%时直接退出本轮竞选。核心代码片段avgEnergy mean(nodeEnergy(nodeAlive 1)); for i 1:numNodes if nodeAlive(i) 1 isMember(i, G) if nodeEnergy(i) 0.8 * avgEnergy continue; % 低能量节点不参与竞选 end w nodeEnergy(i) / initialEnergy; % 能量权重 threshold p / (1 - p * mod(currentRound, floor(1/p))) * w; if rand threshold clusterHead(i) 1; end end end这里的核心逻辑是剩余能量越少实际当选阈值就越低随机数落在阈值内的概率就越小从而大大降低了低能量节点“强行当选”的可能。3.3 数据传输阶段与能量更新簇头选完之后所有节点进入数据传输阶段。这一步有三点容易踩坑。第一簇内成员属于哪个簇头计算方式一般是“距离最近簇头”。用矩阵运算一次性完成不要在循环里逐节点找否则速度慢还容易引入多余变量% 计算每个普通节点到所有簇头的距离并归属最近的簇头 distToCH pdist2(nodePositions(ordinaryNodes, :), nodePositions(CH_index, :)); [~, assignedCH] min(distToCH, [], 2);第二TDMA时隙在一个仿真轮里可以简化为“簇头先广播成员名单成员按顺序发送一次数据”。严格的时间调度不在仿真范围内我们要做的就是按顺序更新能量普通节点发送数据消耗发送能量簇头接收每个成员的数据消耗接收能量簇头向基站发送融合数据消耗发送能量。能量更新要放在同一个小循环里完成千万别在分裂的循环里重复扣能量那样能量账对不上。for 每个簇头ch % 簇头接收成员数据 for each member m of ch E_Tx calcTxEnergy(packetSize, dist(m, ch), ...); nodeEnergy(m) nodeEnergy(m) - E_Tx; E_Rx calcRxEnergy(packetSize, Eelec); nodeEnergy(ch) nodeEnergy(ch) - E_Rx; end % 簇头融合并发送到基站 E_Tx_CH calcTxEnergy(packetSize, dist(ch, baseStation), ...); nodeEnergy(ch) nodeEnergy(ch) - E_Tx_CH; % 数据融合假设100bit数据融合消耗Eelec*packetSize的固定值 nodeEnergy(ch) nodeEnergy(ch) - E_fusion * packetSize; end第三能量扣完发现小于等于0立即把节点状态置为死亡。这个判断每轮结束前做一次别拖到下一轮再做——因为下一轮选举时死节点绝对不能参与否则会出现“死而复生”的bug。3.4 结果可视化与数据记录Matlab做协议对比最爽的地方就是出图方便。我长期使用的三件套是存活节点数随轮数变化曲线经典折线图横轴轮次纵轴存活节点数。曲线越平、第一个下折点越靠右协议越好在网络上能放三条曲线颜色区分一眼看高低。网络总剩余能量曲线把所有节点能量相加后绘制。注意不同协议的“初始总能量”都是一样的所以这条曲线的终点越低说明总能耗越高曲线形状越平缓说明能耗分配越均匀。每轮死亡节点数柱状图如果协议存在“集中死亡”现象柱状图上会出现几个突出的高峰这是能量不均衡的直观写照。代码大致是figure; plot(1:maxRound, aliveHistory_LEACH, b-, LineWidth, 1.5); hold on; plot(1:maxRound, aliveHistory_LEACHC, r--, LineWidth, 1.5); plot(1:maxRound, aliveHistory_TSILEACH, g-., LineWidth, 1.5); legend(LEACH, LEACH-C, TS-I-LEACH); xlabel(轮数); ylabel(存活节点数); grid on;注意aliveHistory里记录的是每一轮的存活节点数必须每轮都push进去不然画图时x轴和y轴长度对不上Matlab还不报错只会画出歪歪扭扭的线。4. 三种协议在仿真中的真实表现与判读跑完代码拿到数据下一步就是做对比分析了。这一节我直接展示一组典型仿真结果然后教你如何读图以及为什么同一个指标在三个协议里会被解读出不一样的结论。4.1 生命周期对比FND、HND与LND的差异在100个节点、初始能量0.5J、p0.05的参数下我跑了一组代表性结果不同随机种子会略有差异但趋势稳定指标LEACHLEACH-CTS-I-LEACHFND首个节点死亡轮数约680约850约1050HND半数节点死亡轮数约1050约1300约1600LND最后一个节点死亡轮数约1800约2000约2300从这个表能看出两个关键信息。第一从LEACH到LEACH-CFND提升了约25%说明集中式选举对“能量门槛”的把控确实有效——基站能排除低能量节点不让“残血”节点硬扛簇头职责。第二TS-I-LEACH比LEACH-C还高了一截主要归功于阈值敏感策略降低了冗余通信量很多节点不需要每轮都发数据自然活得久。但只盯着FND是不够的。我见过很多人拿LND做核心指标因为LND数值大写论文好看但这是典型的数字陷阱——在“只剩几个节点还活着”的状态下这种网络已经没有感知覆盖的意义。做实际应用评估时FND和HND比LND更值得参考。4.2 能耗分布对比谁在“平均地活着”除了生命周期长短能耗分布均匀性也很重要。好的协议应该是“大家一起慢慢变老”差的协议则是“有些人提前猝死有些人还在苟活”。我习惯用每轮存活节点剩余能量的方差来衡量方差越小说明节点之间能量差距越小网络越均衡。画成图就是三条方差曲线你会发现LEACH的方差曲线在中后期急速上升原因是部分节点尤其是离基站远的簇头反复被选中承担转发任务能量被快速抽干而另一批节点因为“运气好”一直没当簇头能量还剩一大半。LEACH-C的方差曲线相对平稳因为基站全局分配簇头角色时会刻意避开低能量节点。TS-I-LEACH的表现最好方差曲线不仅平稳数值也最低这得益于能量权重和阈值保护的双重机制。很多初学者不理解为什么“能量均衡”这么重要。这里打个比方一桶水要用一天你是每次倒一点慢慢喝还是一次喝掉大半桶然后渴一整天传感器网络也是一样的道理——如果某些区域节点集体死亡网络就会出现“感知空洞”哪怕整个网络还有50%的节点存活但监控区域已经缺了一块这对很多应用是无法接受的。4.3 吞吐量与数据质量生命周期和能耗是“面子”吞吐量是“里子”。没有实际数据送到基站前面所有“省电”毫无意义。LEACH由于每轮所有簇头都给基站发一次融合数据在前期吞吐量最高但代价是节点能量消耗快中后期大量节点死亡吞吐量断崖式下跌。TS-I-LEACH在事件驱动场景下可能前期吞吐量不如LEACH因为它引入了硬阈值/软阈值判断数据不那么“勤快”但在长时间运行下由于节点寿命更长累计吞吐量反而经常反超。这一点在仿真图上非常明显LEACH的累计吞吐量曲线先陡后平TS-I-LEACH则是先缓后稳中期两线交叉后期TS-I-LEACH反超。因此做协议评价时不要单看某一时刻的瞬时吞吐量要用“累计吞吐量”和“每单位能量的吞吐量”来公平对比。后者也就是能效TS-I-LEACH通常能比LEACH高出30%到50%这恰恰反映了它真正的价值所在。5. 改进空间与实操避坑建议跑通了三种协议的对比紧接着就要考虑几件影响后续实验成败的事。这里把我踩过的坑和觉得值得深挖的方向一次说清楚。5.1 参数调优与重复实验的陷阱LEACH家族对参数非常敏感首当其冲的是簇头比例p。默认p0.05对100个节点、100m×100m区域通常合适但你把区域扩大到200m×200m时同样5个簇头覆盖不过来簇内成员到簇头的距离变大能耗直线上升。此时把p往上调到0.1反而能降低平均通信距离。反过来如果节点密度很高、区域很小p太高会导致簇头数量过多大量能量浪费在“簇头向基站单跳”上。调参没有万能公式我的经验是跑一组p从0.02到0.15的扫描实验画出FND随p的变化曲线找到峰值对应的p值这才是对当前网络最合适的配置。另外单次仿真的随机性很大尤其是LEACH这种分布式选举协议。只跑一次就说“LEACH比LEACH-C差”很容易被随机种子“带节奏”。正确做法是同一组参数下至少跑20次独立重复实验取平均结果对比。Matlab里也很容易实现外层套一个for trial 1:20循环内层用rng(trial)设置不同种子最后平均化数据再画图。这样得到的结论才敢写进论文。5.2 扩展示例向多跳和异质网络扩展如果你做的是毕业论文只有三协议对比图表可能还不够通常需要在此基础上“再往前走一步”。这里给出几个性价比比较高的扩展方向多跳LEACH/TS-I-LEACH簇头不直接与基站通信而是通过其他簇头中继转发。代码改动不大只需在“簇头→基站”的阶段按“最近簇头优先”选一个中继节点代价是引入中继能耗收益是远端簇头寿命大幅提升。我试过在200m×200m区域里做多跳扩展FND提升非常明显。异质网络场景假设一部分节点初始能量是其他节点的2倍或3倍模拟真实部署中不同节点配备不同电池的情况。把初始能量改成向量后TS-I-LEACH的能量权重公式天然适应异质场景而LEACH-C的全局优化也有了更多决策余地。这个方向很容易出对比图且逻辑自洽。移动汇聚节点让基站或sink节点在区域内周期移动配合TS-I-LEACH的阈值敏感策略数据上报不再是“全员向固定基站汇聚”而是“哪边近就传哪边”。代码量会大一些但创新点很足。5.3 工程化仿真需要注意的隐蔽问题最后列几条容易被忽略、但影响成败的实操细节。第一数据融合能耗别漏算。很多简化实现只算收发能量不算簇头做数据融合的能耗。真实系统里融合过程比如求平均、去冗余也是要耗电的可以在簇头发送能量里加一个固定的融合损耗。如果漏了LEACH-C和TS-I-LEACH这类“簇头任务重”的协议会被严重高估因为它们每轮都有大量节点在当簇头。第二控制包开销必须建模。LEACH-C每轮开始要收集全网状态信息这个控制包虽然只有100bit但100个节点每轮都发累计开销不小。如果仿真里忽略了它LEACH-C的能耗会被低估对比结果就不公平。建议把“节点→基站的控制包上报”“基站→节点的簇头广播”两段能耗都计入总能耗里。第三警惕“最后几个节点”干扰曲线判读。存活节点数到后期会出现锯齿状波动因为个别节点死亡时间是离散事件画出来很丑。这时候不要用原始曲线去发表可以用滑动平均smoothdata函数处理一下或者直接把曲线截到LND附近视觉效果和专业感都会好很多。关于这三种协议的对比研究说到底就是一句话LEACH是地基LEACH-C证明了“全局信息能换均衡”TS-I-LEACH证明了“少发数据比发完数据再省电更聪明”。在Matlab里把这三套协议跑通、跑熟你对WSN路由协议的理解基本就过关了。剩下的就是拿着这套框架去改参数、改场景、改数据写出属于你自己的那篇实验报告或论文章节。