关于 matlab-simulate-wireless-network
为 MATLAB 系统级无线网络仿真提供基础模式,面向构建网络仿真的用户。涵盖节点、流量、移动性、仿真运行与观测,并包含自定义节点和信道的实现指导。
主要功能
- 01初始化并运行网络仿真
- 02创建与批量添加节点
- 03配置流量源和节点移动性
- 04记录事件、IQ 样本与 PCAP
- 05安排仿真动作及参数扫描
- 06实现自定义节点与信道模型
适用场景
- 01模拟无线节点间的系统级通信
- 02为节点配置移动路径和流量
- 03捕获仿真事件或数据包
- 04比较不同仿真参数的结果
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ matlab/ matlab-agentic-toolkit --skill matlab-simulate-wireless-network安装后在 Claude Code 中输入/matlab-simulate-wireless-network确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
manifest.yamlreferences/bluetooth-capture.mdcustom-node.mdevent-tracing-iq-logging.mdmobility-models.mdparametric-sweep-pattern.mdtraffic-models.md详细介绍
无线网络仿真基础
系统级无线仿真的基础模式。各技术专属技能以此为基础,构建节点、配置连接并提取 KPI。
适用场景
- 使用
wirelessNetworkSimulator创建系统级无线网络仿真 - 添加业务源(
networkTrafficOnOff、networkTrafficFTP、networkTrafficVoIP、networkTrafficVideoConference) - 配置节点移动性(随机航点、自定义模型)
- 使用
wirelessNetworkEventTracer或 IQ 记录器记录事件或 IQ 样本 - 使用
wirelessTrafficViewer可视化流量,使用wirelessNetworkViewer查看网络布局 - 使用
scheduleAction在仿真期间安排操作 - 对仿真参数执行参数扫描
- 使用
pcapWriter或技术专属 PCAP 写入器创建 PCAP 文件 - 通过继承
wnet.Node创建自定义节点 - 在无线节点上注册事件回调
不适用场景
- 不使用
wirelessNetworkSimulator的 PHY 层或链路级仿真 - Bluetooth 专属拓扑设置(改用
matlab-simulate-bluetooth-network) - WLAN 专属或 5G NR 专属配置(使用相应的技术专属技能)
- 信号处理或波形生成任务
创建节点
仿真器中的所有节点都继承自 wnet.Node。请选择正确的节点类型:
| 技术 | 节点构造函数 | 备注 |
|---|---|---|
| Bluetooth LE | bluetoothLENode("central") / bluetoothLENode("peripheral") | 使用 matlab-simulate-bluetooth-network 技能 |
| Classic Bluetooth BR/EDR | bluetoothNode("central") / bluetoothNode("peripheral") | 使用 matlab-simulate-bluetooth-network 技能 |
| WLAN | wlanNode(...) | 需要 WLAN Toolbox |
| 5G NR | nrGNB(...) / nrUE(...) | 需要 5G Toolbox |
| 其他技术 / 自定义 | 继承 wnet.Node 创建子类 | 参见 references/custom-node.md |
wnet.Node 是抽象类,绝不能直接实例化。 如果场景未使用上述特定技术,则必须创建一个继承自 wnet.Node 的自定义节点类。技术节点(bluetoothLENode、bluetoothNode、wlanNode、nrGNB、nrUE)在内部实现了 wnet.Node 接口;Position、ID、Name、Velocity、addMobility、registerEventCallback 和 statistics 等属性和方法适用于所有节点类型。
工作流
每个系统级仿真都按以下顺序进行:
wirelessNetworkSimulator.init(必须首先调用)- 创建节点——若有可用的技术专属构造函数,则使用该函数;否则继承
wnet.Node创建子类(参见references/custom-node.md) - 配置连接(技术专属)
addTrafficSource(仅适用于技术节点;面向多个目标时使用向量化方式;自定义节点在run()中生成流量)addMobility(可选)- 配置监测——事件跟踪器、IQ 记录器、流量查看器(可选)
addNodes(sim, nodes)(批量添加,每种技术调用一次)run(sim, duration),或使用IsLastStep=false分多步运行statistics()或技术专属 KPI 函数
仿真器初始化
wirelessNetworkSimulator.init 必须是第一个可执行语句。仿真器是单例——调用 .init 会重新初始化仿真器。切勿使用构造函数(wirelessNetworkSimulator() 不存在)。
clearvars;
rng("default");
sim = wirelessNetworkSimulator.init;
自定义节点(wnet.Node 子类)
重写 5 个方法:run、pullTransmittedPacket、pushReceivedPacket、isPacketRelevant、statistics。始终使用 pkt = wirelessPacket 创建数据包结构——这会初始化所有必需字段,包括 Metadata.Channel(信道模型需要此字段)。TechnologyType 字段请使用 wnet.TechnologyType.Custom1–Custom9。有关完整的方法表、数据包字段、接收缓冲模式和示例,请参阅 references/custom-node.md。
访问权限说明符: 所有重写的方法必须与父类 wnet.Node 的访问权限说明符一致。在 R2026a 中,wnet.Node 中的 run、pullTransmittedPacket、pushReceivedPacket、isPacketRelevant 和 statistics 均为 public。请将它们与构造函数放在同一个 methods 代码块中(默认是 public)。使用不同的访问权限说明符(例如 protected)会导致 MATLAB 错误。
关键事项: run() 必须使用 NextTxTime 和 round(..., 9) 控制传输——模拟器在传递接收数据包后,会以相同的 currentTime 再次调用 run()。如果没有此控制,2 个或更多节点会导致无限循环。
故障排除: 如果创建自定义节点时遇到错误,请参考内置示例中的可用实现:openExample("wnet/CreateAndSimulateWirelessNetworkOfCustomNodesExample")。检查自定义节点类代码,确认方法签名和访问权限说明符正确。
向量化创建节点
任何受支持的节点类型都可以通过 Position=[N×3] 和 Name=[1×N string] 创建多个节点:
nodes = NodeConstructor(Position=[5 0 0; 0 5 0; -5 0 0], Name=["N1", "N2", "N3"]);
使用 nodePositionRandom 随机放置
region = nsidedpoly(6, Center=[0 0], SideLength=50);
positions = nodePositionRandom(region, NumNodes=10, ZCoordinate=0);
nodes = NodeConstructor(Position=positions, Name="N"+(1:10));
批量 addNodes
每种技术类型只调用一次 addNodes。切勿按节点逐个调用。
addNodes(sim, [sourceNode; destNodes(:)]); % same type
addNodes(sim, nodesTypeA); % mixed sim: separate calls
addNodes(sim, nodesTypeB);
流量源
addTrafficSource 仅适用于技术节点(BLE、BR/EDR、WLAN、NR),不适用于自定义 wnet.Node 子类。
networkTrafficOnOff 的 DataRate 单位为 Kbps(千比特/秒)。generate() 方法返回的数据包间隔时间单位为 ms。
traffic = networkTrafficOnOff(DataRate=100, PacketSize=50, OnTime=Inf);
常见错误: 将 100 Kbps 设置为 DataRate=100000——这实际上是 100 Mbps(高出 1000 倍)。运行时不会报错,但会产生不切实际的流量。有关所有流量源类型及其参数,请参阅 references/traffic-models.md。
相同流量可重复使用单个流量对象——DestinationNode 接受向量:
addTrafficSource(central, traffic, DestinationNode=[p1; p2; p3]);
向量化统计
对于技术节点(BLE、BR/EDR、WLAN、NR),向量化的 statistics 会返回 1×N 结构体数组:
allStats = statistics(nodes); % 1×N struct array (technology nodes)
rxBytes = [allStats.App]; % Concatenate sub-structs
对于自定义 wnet.Node 子类,向量化行为取决于 statistics() 方法的实现——如果返回的结构体因节点而异,请逐个节点调用。
移动性
直接对节点向量调用 addMobility(不要逐个节点调用)。边界 = [x_center, y_center, width, height](不是 [xmin, ymin, xmax, ymax])。
addMobility(nodes, MobilityModel="random-waypoint", SpeedRange=[1.0 1.5], Bounds=[10 0 12 4]);
模型:"random-waypoint"、"random-walk"、"constant-velocity"。每个节点都必须位于 x_center ±width/2 和 y_center ±height/2 的范围内。详细示例请参阅 references/mobility-models.md。
多步模拟
每次 run 指定的是额外时长(相对时长),而不是绝对结束时间:
run(sim, 0.3, IsLastStep=false); % Run 0.3s, keep state
stats_mid = statistics(node);
run(sim, 0.2); % Additional 0.2s (0.5s total)
计划操作
scheduleAction(sim, @myCallback, userData, 0.3); % one-shot at t=0.3s
scheduleAction(sim, @myCallback, userData, 0.1, 0.05); % periodic: start 0.1s, repeat 0.05s
回调签名——两个参数 (actionID, userData):
function myCallback(actionID, userData)
stats = statistics(userData.node);
end
模拟过程中允许的操作: statistics(node)、更改 node.Position、使用特定于技术类型的模拟中方法。run() 启动后,大多数 RF 属性都会被锁定。
自定义信道模型
addChannelModel(sim, @myChannelModel);
function txData = myChannelModel(rxInfo, txData)
dist = norm(rxInfo.Position - txData.TransmitterPosition);
fspl = 20*log10(dist) + 20*log10(txData.CenterFrequency) - 147.55;
txData.Metadata.Channel.PathDelays = 0;
txData.Metadata.Channel.PathGains = -fspl;
end
签名:function txData = fcn(rxInfo, txData)——两个输入,不是一个。
rxInfo 字段:ID、Position、Velocity、NumReceiveAntennas。
txData 的关键字段:Power、CenterFrequency、StartTime、TransmitterPosition、TransmitterVelocity、Bandwidth、Metadata.Channel(PathGains、PathDelays、PathFilters、SampleTimes)。
默认使用 FSPL。可使用 addChannelModel 实现依赖距离的衰落、多径或特定环境的传播。
参数扫描
每次循环迭代的开头都必须调用 wirelessNetworkSimulator.init(单例会保留状态)。多维和 parfor 模式请参阅 references/parametric-sweep-pattern.md。
仪器配置(R2026a)
所有工具都必须在调用 run()之前创建。完整详情请参阅 references/event-tracing-iq-logging.md。
eventTracer = wirelessNetworkEventTracer(FileName="events.mat");
addNodes(eventTracer, nodes, EventName=["TransmissionStarted", "ReceptionEnded"]);
iqLogger = wirelessIQLogger(receiverNodes, FileName="iq_samples.mat");
viewer = wirelessTrafficViewer;
addNodes(viewer, nodes);
- 事件跟踪器:适用于所有节点类型。
addNodes会针对每个指定的EventName,在每个节点上调用registerEventCallback——对于自定义wnet.Node子类,节点必须重写registerEventCallback才能支持这些事件名称(请参阅references/custom-node.md)。如果 MAT 文件已存在,则会报错。使用read(eventTracer, EventName=..., NodeName=..., TimeRange=...)读取。 - IQ 记录器:节点在构造时固定(不支持
addNodes)。在 80 MHz 下,每个节点每 0.1s 约占 4–5 MB。仅限技术节点——不支持自定义wnet.Node子类。 - 网络查看器:
wirelessNetworkViewer(NetworkSimulator=sim)+addNodes(viewer, nodes, Type="Transmitter"/"Receiver")+showBoundary(viewer, BoundaryShape="circle", Bounds=radius, Position=[x y z])。形状:"circle"、"rectangle"、"hexagon"。 - 流量查看器:实时状态转换和信道占用情况。仅限技术节点——不支持自定义
wnet.Node子类。
PCAP 捕获
通用 pcapWriter 适用于任何技术;特定技术的写入器(blePCAPWriter、wlanPCAPWriter、nrPCAPWriter)通过 Node= 属性从节点自动捕获。
% Generic (manual write)
pcapObj = pcapWriter(FileName="my_capture");
writeGlobalHeader(pcapObj, linkType);
write(pcapObj, packetBytes, round(simTime * 1e6)); % timestamp in microseconds (integer)
% Technology-specific (auto-capture, no write calls needed)
blePcap = blePCAPWriter(FileName="ble_capture", Node=[central; peripheral]);
常见链路类型:LINKTYPE_USER0(147)、LINKTYPE_IEEE802_11(105)。读取:readAll(pcapReader("file.pcap"))。
蓝牙专用 PCAP 捕获请参阅 references/bluetooth-capture.md。
事件回调(registerEventCallback)
在节点上注册回调,使其在特定事件发生时调用。回调接收单个参数(事件数据结构体)。
registerEventCallback(node, "ReceptionEnded", @myCallback);
function myCallback(eventData)
disp(eventData.Timestamp); % sim time (seconds)
disp(eventData.EventData.SINR); % technology-specific nested payload
end
技术节点(BLE、BR/EDR、WLAN、NR):调用 registerEventCallback 进行注册——节点的内部实现会在仿真的适当时机自动调用回调。
自定义 wnet.Node 子类:基类 wnet.Node.registerEventCallback 是一个空操作存根——它接受参数,但不会存储或触发回调。你必须在子类中重写 registerEventCallback 以存储回调,然后在适当的位置显式调用它们(例如,在 run() 中发送数据后,或在 pushReceivedPacket() 中接收数据后)。完整实现模式请参阅 references/custom-node.md。
顶层字段:EventName、NodeName、NodeID、Timestamp、TechnologyType、EventData(嵌套结构体)。
蓝牙专用事件数据字段请参阅 references/bluetooth-capture.md。
常见错误
| 错误 | 正确做法 |
|---|---|
node = wnet.Node(...) 或直接创建一个 wnet.Node | wnet.Node 是抽象类——应对其进行子类化:classdef MyNode < wnet.Node |
在非 Bluetooth 场景中使用 bluetoothLENode/bluetoothNode | 对于通用或自定义无线节点,请使用自定义的 wnet.Node 子类 |
TechnologyType = "custom"(字符串) | 使用 wnet.TechnologyType.Custom1(数值常量 101–109) |
将 Bounds=[0 0 20 20] 用作 [xmin,ymin,xmax,ymax] | Bounds=[x_center, y_center, width, height] |
为 scheduleAction 使用 function myFcn(userData) | function myFcn(actionID, userData)——2 个参数 |
为 addChannelModel 使用 function txData = fcn(txData) | function txData = fcn(rxInfo, txData)——2 个输入 |
addMobility(sim, nodes, ...) | addMobility(nodes, ...)——这是节点方法,不是仿真方法 |
将 DataRate=100000 用于 100 Kbps | DataRate=100——单位为 Kbps |
不调用 writeGlobalHeader 就使用 pcapWriter() | 必须在任何 write() 调用之前调用 writeGlobalHeader(pcapObj, linkType) |
| 为日志记录构建文件写入回调 | 改用 wirelessNetworkEventTracer |
在自定义节点上调用 registerEventCallback,但不重写该方法 | 基类 wnet.Node.registerEventCallback 不执行任何操作——应重写它以存储回调,并在 run()/pushReceivedPacket() 中手动触发回调 |
对自定义 wnet.Node 使用 addTrafficSource(customNode, traffic, ...) | addTrafficSource 仅适用于技术节点 |
在 pushReceivedPacket 中忽略接收到的数据包 | 使用 wnet.internal.interferenceBuffer 和 addPacket 存储接收到的数据包 |