简介:面向网络仿真研究人员与通信专业学生,提供基于OPNET Modeler的ALOHA协议与AODV路由协议联合仿真平台,可用于分析纯ALOHA/时隙ALOHA信道访问机制与AODV按需路由在无线自组网场景下的性能表现。资源包共36个文件,约93KB,包含.m网络模型源码、.pr/.c进程与程序代码、.seq/.ov场景与输出、.log运行日志、.prj工程文件以及编译生成的.obj/.dll/.lib等,目录结构完整,便于直接打开工程进行复现或二次修改。目前已有341人学习下载。通过该仿真平台,读者可以掌握OPNET中网络拓扑建模、ALOHA协议参数调整、AODV路由发现与维护流程配置、设备与QoS参数设置,以及吞吐量、丢包率、时延等性能指标设定方法,并依托配套代码与场景文件理解协议交互细节,适合作为课程设计、毕业设计或协议研究的参考资料。
1. 先把 ALOHA 协议仿真平台从文件堆里认出来
把 opnet_aloha.rar 解压之后,你会得到一大串后缀奇怪的家伙:.nd.m、.pr.m、.pr.c、.ef、.ov、.gdf,还有一堆 dev32.i0 的 .dll 和 .obj。第一次拿到的人很容易误以为这是源码包或者编译半成品,实际上这正是一个完整的 OPNET Modeler 协议仿真工程,里面包含 ALOHA 收发机进程模型、AODV 路由模块、两个已经配置好的场景(first_floor 和 expansion),以及作者跑仿真时留下的中间产物。它要解决的是 MANET 仿真的一个老问题:媒体接入层用 ALOHA 这种随机接入协议时,上层 AODV 的 RREQ 洪泛和端到端时延会受到多大影响。这个包适合做毕设、写论文对照实验、或者想快速搭一套纯 ALOHA/时隙 ALOHA 基线平台的从业者。先别急着双击 .prj 文件,把文件角色认清楚,后面排错会省很多时间。
2. 认识 OPNET 工程文件:哪些是模型,哪些是跑出来的垃圾
OPNET Modeler 的工程结构和普通源码项目不太一样,它沿用了“网络模型—节点模型—进程模型—外部代码”的四层建模思路。打开这个包,你看到的 .m 文件是模型源文件,.c 是生成的 C 代码,.obj/.dll 是平台相关的编译产物,.ef/.ov 是仿真输出。很多新手把这四类文件混在一起,结果随便删了一个 .obj,编译直接翻车;或者改了 .pr.m 忘了生成 .pr.c,跑完仿真发现行为没变。所以第一步,先给文件分个类。
2.1 文件清单与角色划分
| 文件类型 | 代表文件 | 在工程里的角色 |
|---|---|---|
| 项目入口 | test_Sm_Int.prj、cct_network.prj | 打开工程的入口,一个项目里可以挂多个场景 |
| 网络模型 | cct_network-aloha.nt.m、test_Sm_Int-first_floor.nt.m、test_Sm_Int-expansion.nt.m | 定义网络拓扑、节点摆放和场景范围 |
| 节点模型 | cct_rx.nd.m | 组合进程模型形成完整无线节点,是协议栈的载体 |
| 进程模型 | aloha_tx.pr.m、aloha_rx.pr.m | ALOHA 收发机的状态机与行为逻辑 |
| 链路模型 | cct_link.lk.m | 定义节点间物理连接和传输属性 |
| 编译产物 | aloha_tx.dev32.i0.pr.obj、cct_network-aloha.dev32.i0.nt.dll、.lib、.exp、.pdb | 平台相关的二进制文件,可删除并重新生成 |
| 生成代码 | aloha_tx.pr.c、aloha_rx.pr.c | 由进程模型生成的 C 源码,真正参与编译 |
| 仿真输出 | test_Sm_Int-first_floor.ef、test_Sm_Int-expansion.ov、.seq、.gdf | 事件记录、输出向量、节点位置,不需要手工编辑 |
| 编译日志 | cct_network-aloha.nt.log、test_Sm_Int-first_floor.nt.log | 编译和仿真报错第一眼要看的地方 |
| 系统接口 | aloha.os、aloha.cml | 操作系统抽象层和编译配置,一般不需要改 |
表格里最需要注意的就是 .nt.m 和 .nd.m 的区别。cct_network-aloha.nt.m 是网络模型,描述的是“一张网”,而 cct_rx.nd.m 才是节点模型。我见过有人把 cct_network-aloha.nt.m 当节点模型拖进节点编辑器,结果直接提示模型类型不匹配。另外,.pr.c 和 .pr.m 是配套的:.pr.m 是你在图形化进程模型编辑器里看到的可编辑状态图,.pr.c 是从它自动生成的 C 代码,仿真运行时实际执行的是 .pr.c。改任何进程逻辑,都要回到 .pr.m 里改,再重新生成。
2.2 导入工程的标准动作
把资源落地到自己的机器上,我建议先建一个干净的 workspace,不要直接把文件解压到桌面然后双击打开,否则 OPNET 的模型搜索路径会乱。
mkdir -p ~/opnet_workspace unrar x opnet_aloha.rar ~/opnet_workspace/ cd ~/opnet_workspace/opnet_aloha ls -la这段命令的含义是:先建 workspace 目录,再把压缩包完整解压进去。unrar 在 Debian/Ubuntu 上如果没装,需要先sudo apt install unrar;Windows 下用 7-Zip 右键解压效果一样。解压后尽量不要改目录名,因为 .prj 文件内部可能用相对路径记录 cct_network-aloha.nt.m、test_Sm_Int-first_floor.nt.m 等模型的位置,改目录名会触发一堆“Model not found”。
打开工程时,启动 OPNET Modeler,选择 File -> Project -> Open,定位到 test_Sm_Int.prj。第一次打开如果弹窗提示找不到 cct_rx.nd.m 或 aloha_tx.pr.m,通常就是模型搜索路径没指到这个 workspace。常见做法是在 Edit -> Preferences 里修改 Work 目录,或者把解压出来的整个 opnet_aloha 目录放到 OPNET 安装目录的 models 子目录下。打开工程后,左侧场景树里能看到 first_floor 和 expansion 两个场景,先切到 first_floor,这个场景规模小,适合验证模型能不能跑通。
2.3 重新编译进程模型:别让旧 .obj 坑你
包里带了一堆 aloha_tx.dev32.i0.pr.obj、cct_network-aloha.dev32.i0.nt.dll 之类的文件,看起来像是作者编译好的“成品”,但实际上它们只是作者那个机器上的 32 位开发目标产物。dev32 是 OPNET 常见的 Windows 编译目标标记,i0 是目标索引/版本标识。如果你的 Modeler 是 64 位,或者默认编译器是 MSVC 的不同版本,这些二进制文件直接加载会报错,甚至不报错但行为异常。
正确做法是让 Modeler 重新生成。双击 aloha_tx.pr.m 打开进程模型编辑器,在菜单里选择 Protocols -> Generate Proto-C,强制重新生成 aloha_tx.pr.c;然后执行 File -> Compile Process Model 编译成新的 .obj/.dll。aloha_rx.pr.m 同样操作。编译报错时,别盯着弹窗看,去打开对应场景的 .nt.log 或 .cml 文件,里面会写具体是哪个函数 undefined 或者哪个头文件缺失。
这里有一个最容易翻车的点:你改了 .pr.m 的状态转移图,但没有重新生成 .pr.c,仿真里走的还是旧逻辑。用下面命令对比时间戳:
ls -l --time-style=+%Y-%m-%d_%H:%M:%S aloha_tx.pr.m aloha_tx.pr.c如果 .pr.m 的时间戳比 .pr.c 新,说明模型改过但没重新生成。我一般会在每次修改进程模型后,强制走一遍 Generate Proto-C 再编译,宁可多花 30 秒,也不愿跑完一个 20 分钟的仿真后才发现用的是旧逻辑。至于 .ef、.ov、.gdf 这些文件,是作者上次跑完留下的数据,本地复现时可以直接删,仿真会重新生成。
3. ALOHA 收发机与网络建链:aloha_tx 和 aloha_rx 到底干了什么
ALOHA 是所有随机接入协议的祖宗。纯 ALOHA 的逻辑一句话就能说完:有数据就发,冲突了等随机时间再重传。时隙 ALOHA 稍微礼貌一点,把时间切成固定长度的槽,节点只能在槽边界开始发送。这个资源之所以值得拆,是因为它把 ALOHA 做成了 OPNET 的独立进程模型,并且架在 AODV 下面,你可以在同一个平台里研究两层协议的相互作用。打开 aloha_tx.pr.m 和 aloha_rx.pr.m,能看到的正是这套发送与冲突检测机制。
3.1 aloha_tx 进程模型:纯 ALOHA 的发送逻辑
aloha_tx 的状态机一般会包含 INIT、IDLE、TRANSMIT、COLLISION_CHECK、BACKOFF 这几个典型状态。数据包到达后,进程从 IDLE 进入 TRANSMIT,立即把包送上信道;如果发送期间收到冲突指示,或者上层给了 NAK,就进入 BACKOFF,随机等待一段时间再重试。在时隙 ALOHA 模式下,IDLE 状态还需要维护一个“时隙同步”逻辑,确保只在 SLOT_TIME 整数倍的时刻进入发送。
在 OPNET 的进程模型里,这些参数的属性名一般就是进程模型的属性表,我建议重点盯这几个:
| 参数 | 含义 | 示例值 |
|---|---|---|
| SLOT_TIME | 0 表示纯 ALOHA,大于 0 表示时隙 ALOHA | 0.01 s |
| MAX_RETRANSMIT | 单包最大重传次数,超过后丢弃 | 6 |
| BACKOFF_MIN | 退避随机区间下界 | 0.001 s |
| BACKOFF_MAX | 退避随机区间上界 | 0.02 s |
| COLLISION_THRESH | 判定冲突的干扰阈值 | 10 dB |
这里要注意,BACKOFF_MIN 和 BACKOFF_MAX 不是随便填的。如果退避区间太小,所有冲突节点会挤在同一个时间点重传,形成二次冲突;如果太大,端到端时延会被明显拉高。纯 ALOHA 场景我一般先把退避上界设为平均包传输时间的 5 到 10 倍,再根据丢包率逐步扩大。
aloha_tx.pr.c 里能看到 OPNET 的 KAL(Kernel Adaptive Layer)调用,比如 op_pk_send 负责把包发到接收机,op_intrpt_schedule_self 用来安排超时中断,op_stat_write 负责写统计量。这些代码不需要从头理解,但改进程模型时,一定要回 .pr.m 改转移条件里的 enter/exit 代码块,改完立刻重新生成 .pr.c。直接改 .pr.c 是给自己埋坑,下次 Generate Proto-C 会把你的手改冲掉。
3.2 aloha_rx 进程模型:冲突检测与丢弃
接收端的 aloha_rx 做的事情比发送端更关键。它要判断当前信道上有几个包在重叠,以及能不能正确解出其中一个。在 OPNET 里,接收机的物理层处理通常由管道阶段完成,aloha_rx 主要做的是协议层的冲突确认:收到一个包时,检查接收状态码,如果状态指示碰撞或接收出错,就把这个包丢弃,同时递增冲突计数;否则进入正常处理流程。
常见做法是在 aloha_rx 进程里维护两个统计变量:success_count 和 collision_count。每次接收完成,根据收包状态决定走成功分支还是冲突分支,并调用 op_stat_write 把计数写到输出向量。这样仿真结束后,你可以直接通过 OPNET 的向量数据画出冲突率曲线。如果这个资源里的 aloha_rx 没有暴露这些统计量,你就需要自己打开进程模型加上,这也是后面做结果验证的前提。
调这个进程时,COLLISION_THRESH 的语义要弄清楚:它比较的是接收机处两个包的功率比。阈值设得过高,轻微重叠也判冲突,丢包率虚高;设得过低,明显碰撞的包也可能被判断为“还能解出”,结果延迟特性失真。我的习惯是先跑一个两节点对发的场景,把阈值从 6 dB 调到 15 dB,看冲突计数变化趋势,选一个曲线不突变的值。
3.3 从 cct_link 到 cct_network-aloha:把节点串成网络
cct_link.lk.m 是链路模型,它定义了节点之间的物理连接方式。ALOHA 仿真里这个链路通常不单纯是一根线,而是承载着接收机功率、频率、传播时延等无线参数的抽象链路。打开 cct_network-aloha.nt.m,能看到网络里摆了多个 cct_rx 节点,这些节点通过 cct_link 建立通信关系。first_floor 和 expansion 两个场景,我理解前者是模拟一层楼内的有限节点,后者是更大范围的扩展部署,节点数量和分布密度不同,正好用来验证 ALOHA 在负载升高后的冲突变化。
cct_rx.nd.m 是协议栈的载体。打开它的节点模型,会看到应用层、AODV 路由层、ALOHA MAC 层从上到下排开。这里有一个关键的接口设计:AODV 层下发的 RREQ 包和普通数据包会一起进入 aloha_tx 的发送队列。如果不做优先级区分,RREQ 洪泛时,队列里全是控制包,普通数据包可能被长期饿死。常见做法是在包模型里设置一个字段标记是否为 RREQ,然后在 aloha_tx 进程里见到这个标记就把包插到队列头部。
在场景里修改节点属性时,右键节点进入 Edit Attributes,展开 aloha_tx 模块,就能看到上一节表格里的那些参数;AODV 模块的参数则在相邻的 aodv 层级里。改参数时注意不要同时改所有节点,先用一个节点做单点测试,确认没有异常再批量应用。ALOHA 对节点间距很敏感,因为传播时延直接决定冲突窗口,乱改节点位置可能导致时隙 ALOHA 的同步逻辑失效。
4. AODV 与 ALOHA 联合调参:时隙、重传退避与 RREQ 间隔的配合
很多人拿到这个平台后,把 ALOHA 参数和 AODV 参数分开调,Aloha 层单独测很漂亮,AODV 层单独测也正常,合在一起就跑不通。原因不复杂:AODV 是一个按需路由协议,RREQ 洪泛本质上是突发流量,而 ALOHA 最怕的就是突发。RREQ 一到,网络里几十个节点同时抢信道,ALOHA 的冲突率瞬间飙升。这一章就把两层的参数放到一张表里看。
4.1 AODV 在 OPNET 里的建模方式
AODV 的全称是 Ad hoc On-Demand Distance Vector,核心机制包括路由请求 RREQ、路由回复 RREP、路由错误 RERR 三个阶段。当某个节点要向目的地发送数据但找不到有效路由时,它会把 RREQ 广播给所有邻居;邻居再转发,直到命中一条路由,然后沿反向路径回 RREP。这个“洪泛—回复”过程完全寄托在 MAC 层的投递能力上。你用 ALOHA 作 MAC 层,就意味着每个 RREQ 包都可能和其他节点的包撞车。
OPNET Modeler 的 MANET 模型库自带 AODV 模型,这个资源里的 cct_rx 节点应该就是把自带的 aodv 进程挂到网络层,下面接 aloha_tx/aloha_rx。打开节点模型后,你能看到 aodv 模块和 mac 模块之间的包流线。需要确认两点:一是 RREQ 包是否被标记了优先级,二是 AODV 进程的仿真时间参数有没有被改过。如果 RREQ 没有优先级标记,它在 ALOHA 队列里和普通数据包平等排队,洪泛时大量 RREQ 会互相碰撞并重传,网络很快就进入拥塞崩溃。
4.2 关键参数搭配与互相影响
我的建议是不要单独调某一层,而是按下表的组合一起调,每次只改一个变量。
| 协议层 | 参数 | 作用 | 与另一层的联动 |
|---|---|---|---|
| ALOHA | SLOT_TIME | 时隙长度,0 为纯 ALOHA | 决定 AODV 控制包重传的时间相位 |
| ALOHA | MAX_RETRANSMIT | 最大重传次数 | 太小则 RREQ 直接丢包,路由发现失败 |
| ALOHA | BACKOFF_MIN / BACKOFF_MAX | 退避区间 | 决定碰撞后的时间分散程度 |
| AODV | RREQ_RETRIES | RREQ 重试次数 | 每次重试都是一次洪泛,直接抬高 ALOHA 负载 |
| AODV | RREQ_RATE_LIMIT | 每秒最多发出的 RREQ 数 | 限制洪泛风暴,保护 ALOHA 信道 |
| AODV | ACTIVE_ROUTE_TIMEOUT | 有效路由缓存时间 | ALOHA 丢包多时,路由频繁失效 |
联动的逻辑链大概是这样的:上层业务开始发包,AODV 发现没有路由,发出 RREQ;RREQ 进入 ALOHA 队列,与邻居的 RREQ 碰撞;接收端检测到冲突丢弃,发送端进入 BACKOFF;如果退避区间太小,重传又碰撞,反复几次后 MAX_RETRANSMIT 耗尽,RREQ 被丢弃;AODV 等不到 RREP,只好重发 RREQ,但此时网络负载已经更重。最终结果就是从表面看,AODV 参数很正常,但路由始终建立不起来。
所以 RREQ_RETRIES 这个值,在 ALOHA 信道下我一般不建议超过 2。因为 RREQ 洪泛本身就有大量冗余副本,副本之间已经体现了“重试”效果。把 RREQ_RETRIES 设成 5,实际上是在制造 5 轮洪泛风暴,每一轮都把 ALOHA 信道朝过载方向推一把。相反,RREQ_RATE_LIMIT 建议往低调,每秒钟允许的 RREQ 数量控制在个位数,让洪泛在时间上摊开。
4.3 一次可复现的调参流程
假设你手上就是这份资源,我建议按下面步骤跑一遍对照实验,不要一上来就动所有参数。
先在 first_floor 场景里打开节点属性,展开 aloha_tx,设置 SLOT_TIME=0.0(纯 ALOHA)、MAX_RETRANSMIT=5、BACKOFF_MIN=0.002、BACKOFF_MAX=0.02。然后展开 aodv,设置 RREQ_RETRIES=2、RREQ_RATE_LIMIT=5、ACTIVE_ROUTE_TIMEOUT=10。跑一次 200 秒仿真,记录端到端时延和丢包率。
接下来只改一个量:把 BACKOFF_MAX 从 0.02 改成 0.2,再跑一次。你会发现丢包率明显下降,但端到端时延上升,原因就是重传在时间上被分散了,信道冲突减少了,但每个包的交付周期变长。然后再把 SLOT_TIME 改成 0.01,切换成时隙 ALOHA,观察吞吐量是否向理论值靠拢。注意切换时隙模式后,BACKOFF 的随机起点必须对齐时隙边界,否则会出现“半槽发送”,效果比纯 ALOHA 还差,这个坑在第 5 章详细说。
换到 expansion 场景时节点数变多,负载更高,这时的常见做法是降低 RREQ_RATE_LIMIT 到 3,同时把 MAX_RETRANSMIT 降到 4。因为节点多了,RREQ 的副本总量已经足够,不需要靠单节点无限重传。调完后要重新编译 aloha_tx 进程模型,如果只改了属性值可以不重新编译,但改了 state transition 的代码块就必须重新 Generate Proto-C。跑完对比两个场景的冲突率曲线,你会发现负载越高,ALOHA 的冲突率越接近理论上的指数爆炸,这也是 AODV 在 MANET 里容易被低估的原因之一。
5. 踩坑排查:ALOHA 与 AODV 联合仿真最常见的五个报错
平台本身不复杂,但把别人的工程拿到自己机器上复现,总会撞见几堵墙。下面这五条是我的踩坑记录,每一条都按“现象、原因、解决”的顺序写,能帮你省下不少折腾时间。
5.1 模型打不开:提示 Model not found
现象:双击 test_Sm_Int.prj 后,OPNET 弹窗找不到 cct_rx.nd.m 或 aloha_tx.pr.m,工程打开一半就中断。原因:工程文件内部记录的模型路径是作者机器上的路径,你解压到新目录后路径对不上。解决:把整个解压目录移动到 OPNET 的 models 搜索路径下,或者通过 Edit -> Preferences 添加模型搜索目录;更直接的做法是在弹窗里手动定位一次 .nd.m 文件;如果已经打不开工程,用纯文本编辑器打开 .prj 看看它引用的是相对路径还是绝对路径,再调整自己的目录结构。
5.2 仿真中途崩掉:Event list overflow
现象:节点数超过 20,纯 ALOHA 场景跑一半卡住,控制台报 event list overflow 或者 infinite loop at module x。原因:退避区间太小,大量节点在同一时刻竞争信道,冲突后立即重传,重传又冲突,事件列表被不断膨胀,最终耗尽内存。解决:先把 BACKOFF_MAX 调大一个数量级,再把 MAX_RETRANSMIT 限制在 3 到 5 之间;如果必须跑长仿真,用 Batch Simulation 减少单次运行时间,或者切换成时隙 ALOHA 以减少随机冲突窗口。
5.3 仿真跑完了,图表全部空白
现象:仿真正常结束,但打开结果分析时 Vector 列表是空的,或者每个向量都为零。原因:进程模型里没有注册对应的统计量句柄,或者场景的 Probe 配置没被保存。aloha_tx 和 aloha_rx 默认可能只写包状态,没有写吞吐量、冲突计数等向量。解决:打开 aloha_rx.pr.m,在 Function Block 里用 op_stat_reg 注册一个全局统计句柄,然后用 op_stat_write 在接收状态中写入 success_count 和 collision_count;重新生成代码后,在仿真配置里勾选这两个统计量。如果不想改模型,也可以用 OPNET 的全局统计量方式,选中已有的向量名,但要确认它确实被写入了数据。
5.4 AODV 路由发现失败:所有节点 ping 不通
现象:应用层数据显示吞吐量几乎为零,查看 AODV 路由表为空,RREQ 一直在发但收不到 RREP。原因:RREQ 在 ALOHA 层反复冲突,重传耗尽后被丢弃;或者 RREQ 包在发送队列里和普通数据包混在一起,被大量业务包挤在队伍后面。解决:先暂停上层业务流量,只让 AODV 控制包跑一遍,确认基础洪泛能收敛;再把 RREQ_RETRIES 从默认值降小,RREQ_RATE_LIMIT 设到 5 以下;最后在 aloha_tx 队列里给 RREQ 包加高优先级,用包属性标记后插队发送。记住一个原则:ALOHA 信道不适合大规模洪泛,AODV 参数要围绕“减少 RREQ 数量”来调,而不是增加重试。
5.5 时隙 ALOHA 吞吐量反而低于纯 ALOHA
现象:把 SLOT_TIME 从 0 改成 0.01 后,端到端吞吐量不升反降,丢包率升高。原因:时隙边界没有对齐。如果所有节点都用全局仿真时间 0 作为起始时隙,但节点之间距离不同,传播时延不同,接收端看到的实际时隙起点会漂移;一个节点的时隙起点正好落在另一个节点时隙的中间,冲突窗口被拉大。解决:在 aloha_tx 进程里增加一个同步机制,让每个节点根据接收机收到的同步信号校准自己的时隙起点;或者把 SLOT_TIME 设为所有传播时延的整数倍,并预留一个保护时间。最省事的验证方式是先把节点间距缩到很小,看吞吐量是否恢复正常,如果恢复,那基本可以确定是时隙偏移问题。
6. 验证结果的一个实用技巧:用向量统计量找吞吐量拐点
ALOHA 协议最经典的结论是“负载超过一半后吞吐量滑坡”:纯 ALOHA 理论最大吞吐量只有 0.184,时隙 ALOHA 是 0.368。你拿到这个平台后,不要只看 OPNET 自带的时延曲线,应该自己把吞吐量和冲突率导出来,画一条 S-G 曲线,确认它和你调参后的行为一致。这一步能帮你快速判断:当前的“效果提升”到底来自协议优化,还是只是随机种子带来的波动。
具体做法是在 aloha_rx 进程里注册两个向量统计量,success_count 和 collision_count。仿真配置里同时勾选这两个向量,运行结束后,把结果导出为 CSV 或文本。用下面这段 Python 脚本处理,就能得到每个时隙的负载 G 和吞吐量 S:
import csv import matplotlib.pyplot as plt t, success, collision = [], [], [] with open('aloha_vectors.csv') as f: for row in csv.DictReader(f): t.append(float(row['time'])) success.append(float(row['packet_success_count'])) collision.append(float(row['packet_collision_count'])) slot = 0.01 G = [(s + c) * slot for s, c in zip(success, collision)] S = [s * slot for s in success] plt.plot(G, S, 'o-') plt.xlabel('offered load G (packets per slot)') plt.ylabel('throughput S (successful packets per slot)') plt.axvline(x=0.5, linestyle='--', color='gray') plt.axhline(y=0.184, linestyle='--', color='gray') plt.savefig('aloha_sg.png')这里的关键是理解 G 和 S 的物理含义。G 是每个时隙进入信道的数据包总数,包括成功和冲突的;S 是真正被正确接收的数据包数。纯 ALOHA 下,曲线在 G=0.5 附近到达顶点,之后下降;时隙 ALOHA 的顶点会移到 G=1 附近。如果画出来的曲线在 G 很小的时候就开始暴跌,说明你的节点移速过快或者时隙同步有问题。这张图配合 AODV 的端到端时延曲线,就能说清楚为什么 RREQ 洪泛会把网络压垮:洪泛把 G 推到拐点右侧,ALOHA 进入不稳定区,路由发现自然失败。
我自己的习惯是每次调完一组参数,固定跑 5 个随机种子,把 5 条 S-G 曲线叠加在一起看离散程度。有一回我觉得自己找到了最优退避参数,单次仿真效果比默认好 40%,结果换一个种子就崩了,纯粹是随机冲突带来的幻觉。从那以后,我每次做 ALOHA 相关仿真都强制走一遍多 seed 取均值,参数对比表里也专门加一列“标准差”,不再用单次结果给结论。这个包下载下来后,建议你先按第 2 章的流程把环境跑通,再用这套向量导出方法验证 ALOHA 逻辑,最后才动 AODV 的参数,顺序反了容易浪费一整天。希望帮到你。
本文还有配套的精品资源,点击获取