以wifi-example-sim.cc为例说明NS3统计数据模型
2017-10-19 10:39
1121 查看
利用NS3已有的Trace系统或者Log机制收集记录和统计数据,例如MAC层收发帧数目,网络层以上收发包数目的跟踪与统计,这里选取example/stats/wifi-example-sim.cc为例来很好说明问题:
这个仿真程序是一个简单的实验,包括两个节点,基于AdhocMAC信道模型,包含NS3仿真所需常见模型如节点/网络设备/协议栈和应用进程,这里的应用进程Sender 和Receiver,基于UDP的不可靠连接。
一 给定本次仿真参数distance,format,experiment,strategy,runID在初始化的同时也可以通过命令行改变,这些参数用于从多次实验中快速区分和组合数据。
二 创建节点和网络模型
三 安装协议栈,并分配IP
四 设置移动模型,这里为静止,并给定初始位置
五 安装应用,这里安装Sender / Receiver,自定义的见examples/stats/wifi-example-apps.h|cc
六 数据统计与收集,这是本文重点,下面具体分析。
这里创建DataCollector对象来存储运行信息,并通过Trace机制记录收发端帧和分组传输情况。
1 记录发端帧传输(基WIFI MAC对界)
通过CounterCalculator(src/stats/model/basic-data-calculators.h )类实现计数,利用Trace机制,当节点0上wifiNetDevice/Mac/MacTx变化(source),通过Config::Connect关联,定义的TxCallback作为sink函数调用,导致CounterCalculator::update调用即m_count++从而起到计数功能;
2 记录收端帧传输(基WIFI MAC对界)
类似情况1,虽然这里的sink函数是PacketConterCalculator::PacketUpdate(src/network/utils/packet-data-calculators.cc),但是该函数仍然是通过CounterCalculator::update实现计数,即利用Trace机制,当节点1上wifiNetDevice/Mac/MacRx变化(source),通过Config::Connect关联;
3 记录发端分组传输
也是通过PacketConterCalculator::PacketUpdate实现计数,利用Trace机制,当节点0上/Application/*/$Sender/Tx变化(source),通过通过Config::Connect关联,定义的PacketConterCalculator::PacketUpdate作为sink函数调用;
4 记录收端分组接收
由于收端应用Receiver没有定义traced source,故这里没有采用Trace机制,而是直接利用Receiver:;SetCounter直接操作,通过SetCounter显示类型转换,j将appRx赋值给Receiver内部计数器,从而实现计数
以上均是通过PacketConterCalculator(src/network/utils/packet-data-calculators.cc)或者CounterCalculator(src/stats/model/basic-data-calculators.h )实现传输单元的计数,\下一个将通过引入PacketSizeMinMaxAvgTotalCalculator (src/network/utils/packet-data-calculators.h|cc)和MinMaxAvgTotalCalculator(src/stats/model/basic-data-calculators.h)实现单元内大小的记录。
5 记录发端分组大小
这里采用Trace机制,节点0上/Application/*/$Sender/Tx变化(source),通过通过Config::Connect关联,定义的PacketSizeMinMaxAvgTotalCalculator::PacketUpdate作为sink函数调用,从而MinMaxAvgTotalCalculator::Update实现大小的记录。
6 记录端到端产生分组时的延迟
类似情况4,不采用Trace机制,直接利用Receiver:;SetDelayTracker记录传世时延最值/平均值等
七 运行程序命令
八 统计结果输出
对于输出要么OMNet++(纯文本输出格式)要么SQLite(数据库格式输出),这取决于程序头部定义的参数format,并最终DataCollector对象进行存储。
九 控制脚本实现最后运行
通过 一个简单的控制脚本实现该仿真程序在不同距离下大量重复(作为输入)实验后运行画图。可参考example/stats/wifi-example-db.sh(以后自己写多个不同输入下重复仿真项目时可参考这个)。该运行脚本每次都是基于一个不同的距离作为输入,收集每次仿真结果到SQLite数据库,其中对于每个距离输入,进行5次重复实验以减小波动。全部仿真完成只需几十秒,在完成存储到数据库后,可通过SQLite命令行进行SQL查询。并调用 wifi-example.gnuplot画图
进入该目录
产生data.db数据库,wifi-default.data和wifi-default.eps图
图是对应距离下的丢包率以表征WiFi模型性能。
这个仿真程序是一个简单的实验,包括两个节点,基于AdhocMAC信道模型,包含NS3仿真所需常见模型如节点/网络设备/协议栈和应用进程,这里的应用进程Sender 和Receiver,基于UDP的不可靠连接。
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation; * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Authors: Joe Kopena <tjkopena@cs.drexel.edu> * * This program conducts a simple experiment: It places two nodes at a * parameterized distance apart. One node generates packets and the * other node receives. The stat framework collects data on packet * loss. Outside of this program, a control script uses that data to * produce graphs presenting performance at the varying distances. * This isn't a typical simulation but is a common "experiment" * performed in real life and serves as an accessible exemplar for the * stat framework. It also gives some intuition on the behavior and * basic reasonability of the NS-3 WiFi models. * * Applications used by this program are in test02-apps.h and * test02-apps.cc, which should be in the same place as this file. * */ #include <ctime> #include <sstream> #include "ns3/core-module.h" #includ 4000 e "ns3/network-module.h" #include "ns3/mobility-module.h" #include "ns3/wifi-module.h" #include "ns3/internet-module.h" #include "ns3/stats-module.h" #include "wifi-example-apps.h" using namespace ns3; using namespace std; NS_LOG_COMPONENT_DEFINE ("WiFiDistanceExperiment"); void TxCallback (Ptr<CounterCalculator<uint32_t> > datac, std::string path, Ptr<const Packet> packet) { NS_LOG_INFO ("Sent frame counted in " << datac->GetKey ()); datac->Update (); // end TxCallback } //---------------------------------------------------------------------- //-- main //---------------------------------------------- int main (int argc, char *argv[]) { double distance = 50.0; string format ("omnet"); string experiment ("wifi-distance-test"); string strategy ("wifi-default"); string input; string runID; { stringstream sstr; sstr << "run-" << time (NULL); runID = sstr.str (); } // Set up command line parameters used to control the experiment. CommandLine cmd; cmd.AddValue ("distance", "Distance apart to place nodes (in meters).", distance); cmd.AddValue ("format", "Format to use for data output.", format); cmd.AddValue ("experiment", "Identifier for experiment.", experiment); cmd.AddValue ("strategy", "Identifier for strategy.", strategy); cmd.AddValue ("run", "Identifier for run.", runID); cmd.Parse (argc, argv); if (format != "omnet" && format != "db") { NS_LOG_ERROR ("Unknown output format '" << format << "'"); return -1; } #ifndef STATS_HAS_SQLITE3 if (format == "db") { NS_LOG_ERROR ("sqlite support not compiled in."); return -1; } #endif { stringstream sstr (""); sstr << distance; input = sstr.str (); } //------------------------------------------------------------ //-- Create nodes and network stacks //-------------------------------------------- NS_LOG_INFO ("Creating nodes."); NodeContainer nodes; nodes.Create (2); NS_LOG_INFO ("Installing WiFi and Internet stack."); WifiHelper wifi; WifiMacHelper wifiMac; wifiMac.SetType ("ns3::AdhocWifiMac"); YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default (); YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default (); wifiPhy.SetChannel (wifiChannel.Create ()); NetDeviceContainer nodeDevices = wifi.Install (wifiPhy, wifiMac, nodes); InternetStackHelper internet; internet.Install (nodes); Ipv4AddressHelper ipAddrs; ipAddrs.SetBase ("192.168.0.0", "255.255.255.0"); ipAddrs.Assign (nodeDevices); //------------------------------------------------------------ //-- Setup physical layout //-------------------------------------------- NS_LOG_INFO ("Installing static mobility; distance " << distance << " ."); MobilityHelper mobility; Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>(); positionAlloc->Add (Vector (0.0, 0.0, 0.0)); positionAlloc->Add (Vector (0.0, distance, 0.0)); mobility.SetPositionAllocator (positionAlloc); mobility.Install (nodes); //------------------------------------------------------------ //-- Create a custom traffic source and sink //-------------------------------------------- NS_LOG_INFO ("Create traffic source & sink."); Ptr<Node> appSource = NodeList::GetNode (0); Ptr<Sender> sender = CreateObject<Sender>(); appSource->AddApplication (sender); sender->SetStartTime (Seconds (1)); Ptr<Node> appSink = NodeList::GetNode (1); Ptr<Receiver> receiver = CreateObject<Receiver>(); appSink->AddApplication (receiver); receiver->SetStartTime (Seconds (0)); Config::Set ("/NodeList/*/ApplicationList/*/$Sender/Destination", Ipv4AddressValue ("192.168.0.2")); //------------------------------------------------------------ //-- Setup stats and data collection //-------------------------------------------- // Create a DataCollector object to hold information about this run. DataCollector data; data.DescribeRun (experiment, strategy, input, runID); // Add any information we wish to record about this run. data.AddMetadata ("author", "tjkopena"); // Create a counter to track how many frames are generated. Updates // are triggered by the trace signal generated by the WiFi MAC model // object. Here we connect the counter to the signal via the simple // TxCallback() glue function defined above. Ptr<CounterCalculator<uint32_t> > totalTx = CreateObject<CounterCalculator<uint32_t> >(); totalTx->SetKey ("wifi-tx-frames"); totalTx->SetContext ("node[0]"); Config::Connect ("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Mac/MacTx", MakeBoundCallback (&TxCallback, totalTx)); data.AddDataCalculator (totalTx); // This is similar, but creates a counter to track how many frames // are received. Instead of our own glue function, this uses a // method of an adapter class to connect a counter directly to the // trace signal generated by the WiFi MAC. Ptr<PacketCounterCalculator> totalRx = CreateObject<PacketCounterCalculator>(); totalRx->SetKey ("wifi-rx-frames"); totalRx->SetContext ("node[1]"); Config::Connect ("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Mac/MacRx", MakeCallback (&PacketCounterCalculator::PacketUpdate, totalRx)); data.AddDataCalculator (totalRx); // This counter tracks how many packets---as opposed to frames---are // generated. This is connected directly to a trace signal provided // by our Sender class. Ptr<PacketCounterCalculator> appTx = CreateObject<PacketCounterCalculator>(); appTx->SetKey ("sender-tx-packets"); appTx->SetContext ("node[0]"); Config::Connect ("/NodeList/0/ApplicationList/*/$Sender/Tx", MakeCallback (&PacketCounterCalculator::PacketUpdate, appTx)); data.AddDataCalculator (appTx); // Here a counter for received packets is directly manipulated by // one of the custom objects in our simulation, the Receiver // Application. The Receiver object is given a pointer to the // counter and calls its Update() method whenever a packet arrives. Ptr<CounterCalculator<> > appRx = CreateObject<CounterCalculator<> >(); appRx->SetKey ("receiver-rx-packets"); appRx->SetContext ("node[1]"); receiver->SetCounter (appRx); data.AddDataCalculator (appRx); /** * Just to show this is here... Ptr<MinMaxAvgTotalCalculator<uint32_t> > test = CreateObject<MinMaxAvgTotalCalculator<uint32_t> >(); test->SetKey("test-dc"); data.AddDataCalculator(test); test->Update(4); test->Update(8); test->Update(24); test->Update(12); **/ // This DataCalculator connects directly to the transmit trace // provided by our Sender Application. It records some basic // statistics about the sizes of the packets received (min, max, // avg, total # bytes), although in this scenaro they're fixed. Ptr<PacketSizeMinMaxAvgTotalCalculator> appTxPkts = CreateObject<PacketSizeMinMaxAvgTotalCalculator>(); appTxPkts->SetKey ("tx-pkt-size"); appTxPkts->SetContext ("node[0]"); Config::Connect ("/NodeList/0/ApplicationList/*/$Sender/Tx", MakeCallback (&PacketSizeMinMaxAvgTotalCalculator::PacketUpdate, appTxPkts)); data.AddDataCalculator (appTxPkts); // Here we directly manipulate another DataCollector tracking min, // max, total, and average propagation delays. Check out the Sender // and Receiver classes to see how packets are tagged with // timestamps to do this. Ptr<TimeMinMaxAvgTotalCalculator> delayStat = CreateObject<TimeMinMaxAvgTotalCalculator>(); delayStat->SetKey ("delay"); delayStat->SetContext ("."); receiver->SetDelayTracker (delayStat); data.AddDataCalculator (delayStat); //------------------------------------------------------------ //-- Run the simulation //-------------------------------------------- NS_LOG_INFO ("Run Simulation."); Simulator::Run (); //------------------------------------------------------------ //-- Generate statistics output. //-------------------------------------------- // Pick an output writer based in the requested format. Ptr<DataOutputInterface> output = 0; if (format == "omnet") { NS_LOG_INFO ("Creating omnet formatted data output."); output = CreateObject<OmnetDataOutput>(); } else if (format == "db") { #ifdef STATS_HAS_SQLITE3 NS_LOG_INFO ("Creating sqlite formatted data output."); output = CreateObject<SqliteDataOutput>(); #endif } else { NS_LOG_ERROR ("Unknown output format " << format); } // Finally, have that writer interrogate the DataCollector and save // the results. if (output != 0) output->Output (data); // Free any memory here at the end of this example. Simulator::Destroy (); // end main }
一 给定本次仿真参数distance,format,experiment,strategy,runID在初始化的同时也可以通过命令行改变,这些参数用于从多次实验中快速区分和组合数据。
二 创建节点和网络模型
三 安装协议栈,并分配IP
四 设置移动模型,这里为静止,并给定初始位置
五 安装应用,这里安装Sender / Receiver,自定义的见examples/stats/wifi-example-apps.h|cc
六 数据统计与收集,这是本文重点,下面具体分析。
这里创建DataCollector对象来存储运行信息,并通过Trace机制记录收发端帧和分组传输情况。
1 记录发端帧传输(基WIFI MAC对界)
通过CounterCalculator(src/stats/model/basic-data-calculators.h )类实现计数,利用Trace机制,当节点0上wifiNetDevice/Mac/MacTx变化(source),通过Config::Connect关联,定义的TxCallback作为sink函数调用,导致CounterCalculator::update调用即m_count++从而起到计数功能;
2 记录收端帧传输(基WIFI MAC对界)
类似情况1,虽然这里的sink函数是PacketConterCalculator::PacketUpdate(src/network/utils/packet-data-calculators.cc),但是该函数仍然是通过CounterCalculator::update实现计数,即利用Trace机制,当节点1上wifiNetDevice/Mac/MacRx变化(source),通过Config::Connect关联;
3 记录发端分组传输
也是通过PacketConterCalculator::PacketUpdate实现计数,利用Trace机制,当节点0上/Application/*/$Sender/Tx变化(source),通过通过Config::Connect关联,定义的PacketConterCalculator::PacketUpdate作为sink函数调用;
4 记录收端分组接收
由于收端应用Receiver没有定义traced source,故这里没有采用Trace机制,而是直接利用Receiver:;SetCounter直接操作,通过SetCounter显示类型转换,j将appRx赋值给Receiver内部计数器,从而实现计数
以上均是通过PacketConterCalculator(src/network/utils/packet-data-calculators.cc)或者CounterCalculator(src/stats/model/basic-data-calculators.h )实现传输单元的计数,\下一个将通过引入PacketSizeMinMaxAvgTotalCalculator (src/network/utils/packet-data-calculators.h|cc)和MinMaxAvgTotalCalculator(src/stats/model/basic-data-calculators.h)实现单元内大小的记录。
5 记录发端分组大小
这里采用Trace机制,节点0上/Application/*/$Sender/Tx变化(source),通过通过Config::Connect关联,定义的PacketSizeMinMaxAvgTotalCalculator::PacketUpdate作为sink函数调用,从而MinMaxAvgTotalCalculator::Update实现大小的记录。
6 记录端到端产生分组时的延迟
类似情况4,不采用Trace机制,直接利用Receiver:;SetDelayTracker记录传世时延最值/平均值等
七 运行程序命令
八 统计结果输出
对于输出要么OMNet++(纯文本输出格式)要么SQLite(数据库格式输出),这取决于程序头部定义的参数format,并最终DataCollector对象进行存储。
九 控制脚本实现最后运行
通过 一个简单的控制脚本实现该仿真程序在不同距离下大量重复(作为输入)实验后运行画图。可参考example/stats/wifi-example-db.sh(以后自己写多个不同输入下重复仿真项目时可参考这个)。该运行脚本每次都是基于一个不同的距离作为输入,收集每次仿真结果到SQLite数据库,其中对于每个距离输入,进行5次重复实验以减小波动。全部仿真完成只需几十秒,在完成存储到数据库后,可通过SQLite命令行进行SQL查询。并调用 wifi-example.gnuplot画图
进入该目录
产生data.db数据库,wifi-default.data和wifi-default.eps图
图是对应距离下的丢包率以表征WiFi模型性能。
相关文章推荐
- 以wifi-example-sim.cc为例说明NS3统计数据模型
- 以wifi-example-sim.cc为例说明NS3统计数据模型
- 数据集市 数据仓库 Immon Kimball模型的概念说明
- SPSS统计分析过程包括描述性统计、均值比较、一般线性模型、相关分析、回归分析、对数线性模型、聚类分析、数据简化、生存分析、时间序列分析、多重响应等几大类
- Mob统计分析数据模型理解
- 数据集市 数据仓库 Immon Kimball模型的概念说明
- SPSS统计分析过程包括描述性统计、均值比较、一般线性模型、相关分析、回归分析、对数线性模型、聚类分析、数据简化、生存分析、时间序列分析、多重响应等几大类
- 试给出数据通信系统的模型并说明其主要组成构建的作用。
- Oracle AWR报告及统计数据之DB Time说明
- 可观测统计数据上因果推断----因果图模型
- NS3 seventh.cc为例说明Probe< 一>
- Oracle AWR报告及统计数据之DB Time说明
- Mob统计分析数据模型理解
- NS3 seventh.cc为例说明Probe<二>
- 【Scikit-Learn 中文文档】四十八:数据转换和预测变量的组合模型- 关于科学数据处理的统计学习教程 - scikit-learn 教程 | ApacheCN
- Oracle AWR报告及统计数据之DB Time说明
- Oracle AWR报告及统计数据之DB Time说明
- Mapreduce读取和写入Hbase(从A表读取数据,统计结果放入B表,非常详细,附有代码说明以及流程)
- 机房收费系统重构(4)——.NET数据提供程序模型的四个核心元素
- 数据同步利器-otter的搭建使用说明