因為要搞水下網絡,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);)
解壓+