NS-3 和Aqua-sim-ng 学习笔记(一)
因为要搞水下网络,OMNET++不太合适,就转Aqua-sim。这是基于NS-2上的模型,NS-2需要额外学一门tcl脚本语言。
正好查到它的一个升级版Aqua-sim-NG,在github上,https://github.com/rmartin5/aqua-sim-ng是基于NS-3的,只需要基本的C++,不用学tcl语言。美滋滋。
装好ubuntu之后,安装NS-3和Aqua-sim。
注意:NS-3安装前有一下依赖包,需要安装。
NS-3安装教程:https://blog.csdn.net/rical730/article/details/71504169
https://blog.csdn.net/xiao_sheng_jun/article/details/83628692
http://134.74.112.6/mediawiki/index.php/Install_and_run_Aqua-Sim-NG_code
建议bake查看NS-3的依赖,(也可以使用他安装)
开始提示我没有 Cmake 安装教程 :https://www.cnblogs.com/photo520/p/9486144.html
最后一步出错,提示intall fail 教程:https://blog.csdn.net/u010668907/article/details/50000527/
ubuntu解压+安装+卸载
sudo dpkg -i [deb文件名] sudo apt-get install -f 依赖关系错误,修复安装 sudo dpkg -l 查看已经安装的软件 sudo dpkg -r [软件名] 卸载
NS-3入门:https://www.nsnam.org/docs/release/3.29/tutorial/html/getting-started.html
Aqua-sim-ng的入门程序----【broadcastMAC_example】
文件在 aquasim-ng/examples文件夹下的 broadcastMAC_example
源代码:
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2016 University of Connecticut * * 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 * * Author: Robert Martin <robert.martin@engr.uconn.edu> */ #include "ns3/core-module.h" #include "ns3/network-module.h" #include "ns3/mobility-module.h" #include "ns3/aqua-sim-ng-module.h" #include "ns3/applications-module.h" #include "ns3/log.h" #include "ns3/callback.h" /* * BroadCastMAC * * String topology: * N ----> N -----> N -----> N* -----> S * */ using namespace ns3; ///*定义日志 NS_LOG_COMPONENT_DEFINE("ASBroadcastMac"); int main (int argc, char *argv[]) { double simStop = 100; ///*运行时间 int nodes = 3; int sinks = 1; uint32_t m_dataRate = 128;///*传输速率 uint32_t m_packetSize = 40;///*dataRate是以Bps为单位的,而packetSize是以字节为单位。 因此,对于我们的应用程序流量生成,dataRate将为1 Mib,而我们的packetSize将为320位。 //double range = 20; //默认情况下,Aqua-Sim NG将记录脚本中的所有组件,而无需用户将其定义为参数。 这是由于以下行 LogComponentEnable ("ASBroadcastMac", LOG_LEVEL_INFO); //to change on the fly CommandLine cmd; cmd.AddValue ("simStop", "Length of simulation", simStop); cmd.AddValue ("nodes", "Amount of regular underwater nodes", nodes); cmd.AddValue ("sinks", "Amount of underwater sinks", sinks); cmd.Parse(argc,argv); std::cout << "-----------Initializing simulation-----------\n"; NodeContainer nodesCon; NodeContainer sinksCon; nodesCon.Create(nodes); sinksCon.Create(sinks); PacketSocketHelper socketHelper; socketHelper.Install(nodesCon); socketHelper.Install(sinksCon); //establish layers using helper's pre-build settings AquaSimChannelHelper channel = AquaSimChannelHelper::Default(); //channel.SetPropagation("ns3::AquaSimRangePropagation"); AquaSimHelper asHelper = AquaSimHelper::Default(); asHelper.SetChannel(channel.Create()); asHelper.SetMac("ns3::AquaSimBroadcastMac"); asHelper.SetRouting("ns3::AquaSimRoutingDummy"); /* * Set up mobility model for nodes and sinks */ MobilityHelper mobility; NetDeviceContainer devices; Ptr<ListPositionAllocator> position = CreateObject<ListPositionAllocator> (); Vector boundry = Vector(0,0,0); std::cout << "Creating Nodes\n"; for (NodeContainer::Iterator i = nodesCon.Begin(); i != nodesCon.End(); i++) { Ptr<AquaSimNetDevice> newDevice = CreateObject<AquaSimNetDevice>(); position->Add(boundry); devices.Add(asHelper.Create(*i, newDevice)); NS_LOG_DEBUG("Node:" << newDevice->GetAddress() << " position(x):" << boundry.x); boundry.x += 100; //newDevice->GetPhy()->SetTransRange(range); } for (NodeContainer::Iterator i = sinksCon.Begin(); i != sinksCon.End(); i++) { Ptr<AquaSimNetDevice> newDevice = CreateObject<AquaSimNetDevice>(); position->Add(boundry); devices.Add(asHelper.Create(*i, newDevice)); NS_LOG_DEBUG("Sink:" << newDevice->GetAddress() << " position(x):" << boundry.x); boundry.x += 100; //newDevice->GetPhy()->SetTransRange(range); } mobility.SetPositionAllocator(position); mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel"); mobility.Install(nodesCon); mobility.Install(sinksCon); PacketSocketAddress socket; socket.SetAllDevices(); socket.SetPhysicalAddress (devices.Get(nodes)->GetAddress()); //Set dest to first sink (nodes+1 device) socket.SetProtocol (0); OnOffHelper app ("ns3::PacketSocketFactory", Address (socket)); app.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]")); app.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]")); app.SetAttribute ("DataRate", DataRateValue (m_dataRate)); app.SetAttribute ("PacketSize", UintegerValue (m_packetSize)); ApplicationContainer apps = app.Install (nodesCon); apps.Start (Seconds (0.5)); apps.Stop (Seconds (simStop + 1)); Ptr<Node> sinkNode = sinksCon.Get(0); TypeId psfid = TypeId::LookupByName ("ns3::PacketSocketFactory"); Ptr<Socket> sinkSocket = Socket::CreateSocket (sinkNode, psfid); sinkSocket->Bind (socket); /* * For channel trace driven simulation */ /* AquaSimTraceReader tReader; tReader.SetChannel(asHelper.GetChannel()); if (tReader.ReadFile("channelTrace.txt")) NS_LOG_DEBUG("Trace Reader Success"); else NS_LOG_DEBUG("Trace Reader Failure"); */ Packet::EnablePrinting (); //for debugging purposes std::cout << "-----------Running Simulation-----------\n"; Simulator::Stop(Seconds(simStop)); Simulator::Run(); Simulator::Destroy(); std::cout << "fin.\n"; return 0; }
解析:
确保定义日志文件:
NS_LOG_COMPONENT_DEFINE(“ASBroadcastMac”);
默认记录所有组件(main函数内):
LogComponentEnable ("ASBroadcastMac", LOG_LEVEL_INFO);
定义仿真参数:
double simStop = 100; int nodes = 3; int sinks = 1; uint32_t m_dataRate = 128; uint32_t m_packetSize = 40;
保证可以通过NS-3的API直接修改参数(为此,在运行示例脚本时使用关键字(第一个条件),这将覆盖指定变量的提供值(第三个条件))
CommandLine cmd; cmd.AddValue ("simStop", "Length of simulation", simStop); cmd.AddValue ("nodes", "Amount of regular underwater nodes", nodes); cmd.AddValue ("sinks", "Amount of underwater sinks", sinks); cmd.Parse(argc,argv);
初始化模拟:本节的主要目的是在每个节点上创建模拟节点和相关协议栈。 此外,在此部分中包含了频道设置和属性分配。 开始我们创建两个不同的容器,一个用于节点,另一个用于接收器:
使用NS-3提供的一个帮助程序类NodeContainer。 通过调用此类的create函数,我们可以获得传递给定大小的特定容器。
NodeContainer nodesCon;
NodeContainer sinksCon;
nodesCon.Create(nodes);
sinksCon.Create(sinks);
接下来,我们为每个容器设置套接字。 这是为了协助数据包处理。
PacketSocketHelper socketHelper;
socketHelper.Install(nodesCon);
socketHelper.Install(sinksCon);
接下来,我们建立了用于仿真的信道和协议栈。注意,这是一个简化的示例,可以扩展到支持不同节点和多个水下通道上的不同协议栈。我们首先设置了如下通道
AquaSimChannelHelper channel = AquaSimChannelHelper::Default(); //channel.SetPropagation("ns3::AquaSimRangePropagation");
由于我们正在使用Aqua-Sim NG s通道助手,这个过程是相当直接的。helper类将把默认组件分配给这个新创建的通道helper。这个默认设置包括一个常量噪声发生器,默认为零,以及一个简单的传播模型。相反,我们可以通过应用注释掉行来重载传播模型,这将把通道s传播模型设置为range。此外,我们还可以在这个设置阶段包含属性。这方面的一个例子是分配温度和水的盐度,同时分配范围传播到我们的通道模型。
channel.SetPropagation(“ns3::AquaSimRangePropagation”, “Temperature”, DoubleValue(20),“Salinty”, DoubleValue(30));
接下来,使用AquaSimHelper为协议栈和通道分配分配所有标准设置。 这可以通过以下方式完成:
AquaSimHelper asHelper = AquaSimHelper::Default(); asHelper.SetChannel(channel.Create()); asHelper.SetMac("ns3::AquaSimBroadcastMac"); asHelper.SetRouting("ns3::AquaSimRoutingDummy");
Default()函数的作用是:不改变辅助变量
它允许在标准构造函数属性之外更容易地分配和更改用户创建。在创建AquaSimHelper时,我们自动为协议栈分配标准特性,允许普通物理层设置,并避免为上层协议层提供任何可能的空指针。通过在这个helper的默认()函数中重载这些特性,或者设置与前面提到的传播示例类似的新属性,可以很容易地更改这些特性。为通道调用Create()的过程允许通道助手分配前面定义的所有属性,并返回一个填充的AquaSimChannel指针。在本例中,所有节点都将分配给这个单一通道,因此我们通过AquaSimHelper SetChannel()函数设置这个指针。为了证明概念和简单性,我们还设置了新的MAC和路由层协议。为了实现这一点,我们使用唯一定义的组件名,它可以在每个协议的源文件下找到(例如NS_LOG_COMPONENT_DEFINE(AquaSimBroadcastMac);)
解压+