Simulation of Simple 3D FANET with TCP flows under ns-3
In this example, we simulate TCP flows in a FANET scenario, but the same idea can be implemented on a MANET or VANET or WSN and other scenarios also. This simulation is an example TCP simulation with some modifications that we did for simulating TCP flows under a 3D FANET scenario.
The following is the expected final output that will be visualized under NetSimulyzer. If you notice the right side windows, you can see the graphs of cwnd dynamics and rtt dynamics of one selected TCP flow. As usual, in the left side window of NetSimulyzer, we can see the simulated FANET scene.
This is only a prototype simulation to make one to understand the TCP dynamics with some visualization. But a practical analysis will need more nodes and more cross-traffic to really understand the change in behaviour of TCP. To study the fairness of different TCP flows and congestion mechanisms, a more suitable “bottleneck” scenario such as “Dumbbell scenario” should be used.
TCP Congestion Control Algorithms available under ns-3.
In this simulation, we used only TcpWestwood as the TCP congestion control algorithm but it is possible to use the following algorithms in this simulation.
- Tcp NewReno,
- Tcp CUBIC,
- Tcp Linux Reno,
- Tcp HighSpeed,
- Tcp Hybla,
- Tcp Vegas,
- Tcp Scalable,
- Tcp Veno,
- Tcp BIC,
- Tcp YeAH,
- Tcp Illinois,
- H-TCP,
- Tcp LEDBAT,
- TCP-LP,
- Data Center TCP (DCTCP)
- and , Tcp BBR
Important Code Segments of the Proposed Simulation
The following code segment presents the important components of the ns-3 simulation script which is used to simulate and demonstrate the real-time visualization of TCP dynamics along with the 3D FANET simulation itself. In this simulation, four aeroplane nodes will use the circle mobility model and we can simulate TCP flows between them. (or between the aeroplanes and a node at the ground station).
Include the header files Needed
The following lines include the necessary header files. The Netsimulyzer ns-3 module should be installed in the ns-3 directory tree.
#include “ns3/core-module.h”
#include “ns3/network-module.h”
#include “ns3/applications-module.h”
#include “ns3/log.h”
#include “ns3/callback.h”
#include “ns3/mobility-module.h”
#include “ns3/netanim-module.h”
#include “ns3/netsimulyzer-module.h”
#include “ns3/internet-module.h”
#include “ns3/flow-monitor-module.h”
#include “ns3/config-store-module.h”
#include “ns3/wifi-module.h”
#include “ns3/aodv-module.h”
#include “ns3/dsdv-helper.h”
#include “ns3/dsr-module.h”
#include “ns3/olsr-module.h”
#include
The following lines show the creation of nodes for this FANET network simulation and setting up the communicaiton channel in it.
///////////////////////// Creating the FANET ///////////////////////////////////////// NodeContainer CirclesUAV; std::cout<<“\nsetting the Wifi Phy and channel parameters\n”; WifiHelper wifi; std::cout<<“\tsetting up the Yans Wifi Channel in the WifiPhy Device\n”; YansWifiChannelHelper wifiChannel; wifiChannel.SetPropagationDelay (“ns3::ConstantSpeedPropagationDelayModel”); wifiPhy.Set (“RxGain”, DoubleValue (0.0)); std::cout<<“\tSetting up the Wifi Adhoc Mac\n”; WifiMacHelper wifiMac;
std::cout<<“\nCreating “<
CirclesUAV.Create (NoFanetNodes);
NetDeviceContainer allDevices;
wifi.SetStandard (WIFI_PHY_STANDARD_80211b);
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
wifiChannel.AddPropagationLoss (“ns3::RangePropagationLossModel”, “MaxRange”, DoubleValue (txpDistance));
wifiPhy.SetChannel (wifiChannel.Create ());
wifiPhy.Set (“RxNoiseFigure”, DoubleValue (0.0));
wifiPhy.Set (“EnergyDetectionThreshold”, DoubleValue (-110.0));
wifiPhy.Set (“CcaMode1Threshold”, DoubleValue (-110.0));
wifi.SetRemoteStationManager (“ns3::ConstantRateWifiManager”, “DataMode”, StringValue (dataMode), “ControlMode”, StringValue (phyMode));
wifiMac.SetType (“ns3::AdhocWifiMac”);
allDevices = wifi.Install (wifiPhy, wifiMac, CirclesUAV);
Simulate Circle Mobility in nodes
The following section of code will do the important part of adding mobility model in the FANET nodes. We setup CircleMobilityModel in the four FANET nodes.
My previous article “Implementation of Circle Mobility Model for ns-3 and Visualizing it in 3D” shows the way of implementing CircleMobility Model.
///////////////////////// Setting Mobility Model /////////////////////////////////////////
std::cout<<“\nSetting Mobility Parameters\n”;
MobilityHelper CircleMobility;
MobilityHelper mobility;
CircleMobility.SetPositionAllocator (“ns3::RandomBoxPositionAllocator”,
“X”, StringValue (“ns3::UniformRandomVariable[Min=200.0|Max=250.0]”),
“Y”, StringValue (“ns3::UniformRandomVariable[Min=200.0|Max=250.0]”),
“Z”, StringValue (“ns3::UniformRandomVariable[Min=0.0|Max=250.0]”));
CircleMobility.SetMobilityModel (“ns3::CircleMobilityModel”);
CircleMobility.Install (CirclesUAV);
CirclesUAV.Get (0)->GetObject
CirclesUAV.Get (1)->GetObject
CirclesUAV.Get (2)->GetObject
CirclesUAV.Get (3)->GetObject
Installing Routing Protocol And Internet Stack in the Simulated FANET nodes
///////////////////////// Installing Routing Protocol And Internet Stack /////////////////////////////////////////
InternetStackHelper internet;
AodvHelper aodv;
internet.SetRoutingHelper (aodv);
internet.Install (CirclesUAV);
std::cout<<“Assigning ip address To Nodes\n”;
Ipv4AddressHelper address;
address.SetBase (“10.1.1.0”, “255.255.255.0”);
Ipv4InterfaceContainer allInterfaces;
allInterfaces = address.Assign (allDevices);
Setting FTP Flows in the Simulated FANET nodes
///////////////////////// Setting FTP Flows /////////////////////////////////////////
Address sinkLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), TcpPort));
PacketSinkHelper sinkHelper (“ns3::TcpSocketFactory”, sinkLocalAddress);
sinkHelper.SetAttribute (“Protocol”, TypeIdValue (TcpSocketFactory::GetTypeId ()));
for (uint32_t i = 0; i < NoTcpFlows; ++i)
{
// Create a FTP Application and install it on one node
BulkSendHelper sourceFTP (“ns3::TcpSocketFactory”, InetSocketAddress (allInterfaces.GetAddress (i ), FtpPort));
sourceFTP.SetAttribute (“MaxBytes”, UintegerValue (FtpPayloadSize));
ApplicationContainer sourceAppsFTP = sourceFTP.Install (CirclesUAV.Get (i+ NoFanetNodes – NoTcpFlows));
sourceAppsFTP.Start (Seconds (TcpFlowStartTime));
sourceAppsFTP.Stop (Seconds (TotalSimulationTime));
// Create a PacketSinkApplication and install it on another node
PacketSinkHelper sink (“ns3::TcpSocketFactory”, InetSocketAddress (Ipv4Address::GetAny (), FtpPort));
ApplicationContainer sinkAppsFTP = sink.Install (CirclesUAV.Get (i ));
sinkAppsFTP.Start (Seconds (TcpFlowStartTime));
sinkAppsFTP.Stop (Seconds (TotalSimulationTime));
}
Specify the Trace output Files and Schedule Recording Events for them.
std::cout << “Setting up Tcp Dynamics Tracing\n”;
std::cout << “\t” << MobilityScenarioFileNamePrefix << TraceFileNamePrefix << “-cwnd.dat\n”;
std::cout << “\t” << MobilityScenarioFileNamePrefix << TraceFileNamePrefix << “-rtt.dat\n”;
std::cout << “\t” << MobilityScenarioFileNamePrefix << TraceFileNamePrefix << “-rto.dat\n”;
std::cout << “\t” << MobilityScenarioFileNamePrefix << TraceFileNamePrefix << “-ssth.dat\n”;
Simulator::Schedule (Seconds (0.00001), &TraceCwnd, MobilityScenarioFileNamePrefix + TraceFileNamePrefix + “-cwnd.dat”);
Simulator::Schedule (Seconds (0.00001), &TraceRtt, MobilityScenarioFileNamePrefix + TraceFileNamePrefix + “-rtt.dat”);
Simulator::Schedule (Seconds (0.00001), &TraceRto, MobilityScenarioFileNamePrefix + TraceFileNamePrefix + “-rto.dat”);
Simulator::Schedule (Seconds (0.00001), &TraceSsThresh, MobilityScenarioFileNamePrefix + TraceFileNamePrefix + “-ssth.dat”);
Specify the output File and Set 3D model for the Simulated FANET nodes
Specify the output File and Set 3D model for the Simulated FANET nodes
auto orchestrator = CreateObject
// Use helper to define model for visualizing nodes and aggregate to Node object
netsimulyzer::NodeConfigurationHelper CirclesUAVHelper{orchestrator};
CirclesUAVHelper.Set (“Model”, netsimulyzer::models::QC_AIRPLANE_VALUE);
CirclesUAVHelper.Install(CirclesUAV);
Add 3D Model of House as a Ground Decoration
auto decoration1 = CreateObject
decoration1->SetAttribute (“Model”, StringValue(“HouseAndRoad.obj”));
decoration1->SetPosition ({0,0,0});
Create 4 XY Series that will be used to display different TCP Dynomics Graphs
// Create XYSeries that will be used to display different TCP Dynomics Graphs on NetSimulyzer Visualiztion Tool
cwndSeries = CreateObject
cwndSeries->SetAttribute (“Name”, StringValue(“Cwnd Dynamics”));
cwndSeries->SetAttribute (“LabelMode”, StringValue(“Hidden”));
cwndSeries->SetAttribute (“Color”, netsimulyzer::BLUE_VALUE);
cwndSeries->GetXAxis ()->SetAttribute (“Name”, StringValue(“Time (s)”));
cwndSeries->GetYAxis ()->SetAttribute (“Name”, StringValue(“Cwnd “));
ssThreshSeries = CreateObject
ssThreshSeries->SetAttribute (“Name”, StringValue(“ssThreshold Dynamics”));
ssThreshSeries->SetAttribute (“LabelMode”, StringValue(“Hidden”));
ssThreshSeries->SetAttribute (“Color”, netsimulyzer::BLUE_VALUE);
ssThreshSeries->GetXAxis ()->SetAttribute (“Name”, StringValue(“Time (s)”));
ssThreshSeries->GetYAxis ()->SetAttribute (“Name”, StringValue(“ssThresh “));
rttSeries = CreateObject
rttSeries->SetAttribute (“Name”, StringValue(“RTT Dynamics”));
rttSeries->SetAttribute (“LabelMode”, StringValue(“Hidden”));
rttSeries->SetAttribute (“Color”, netsimulyzer::BLUE_VALUE);
rttSeries->GetXAxis ()->SetAttribute (“Name”, StringValue(“Time (s)”));
rttSeries->GetYAxis ()->SetAttribute (“Name”, StringValue(“rtt “));
rtoSeries = CreateObject
rtoSeries->SetAttribute (“Name”, StringValue(“RTO Dynamics”));
rtoSeries->SetAttribute (“LabelMode”, StringValue(“Hidden”));
rtoSeries->SetAttribute (“Color”, netsimulyzer::BLUE_VALUE);
rtoSeries->GetXAxis ()->SetAttribute (“Name”, StringValue(“Time (s)”));
rtoSeries->GetYAxis ()->SetAttribute (“Name”, StringValue(“rto “));
The Callback Functions Used to Store TCP Dynomics
///////////////////////// The Callback Functions /////////////////////////////////////////
static void
CwndTracer (uint32_t oldval, uint32_t newval)
{
if (CwindFirstlineFlag)
{
*cWndStream->GetStream () << “0.0, ” << oldval << std::endl;
CwindFirstlineFlag = false;
}
*cWndStream->GetStream () << Simulator::Now ().GetSeconds () << “, ” << newval << std::endl;
cwndSeries->Append ( Simulator::Now ().GetSeconds () , newval);
}
static void
SsThreshTracer (uint32_t oldval, uint32_t newval)
{
if (SshThrFirstlineFlag)
{
*ssThreshStream->GetStream () << “0.0, ” << oldval << std::endl;
SshThrFirstlineFlag = false;
}
*ssThreshStream->GetStream () << Simulator::Now ().GetSeconds () << “, ” << newval << std::endl;
ssThreshSeries->Append ( Simulator::Now ().GetSeconds () , newval);
}
static void
RttTracer (Time oldval, Time newval)
{
if (RttFirstlineFlag)
{
*rttStream->GetStream () << “0.0, ” << oldval.GetSeconds () << std::endl;
RttFirstlineFlag = false;
}
*rttStream->GetStream () << Simulator::Now ().GetSeconds () << “, ” << newval.GetSeconds () << std::endl;
rttSeries->Append ( Simulator::Now ().GetSeconds () , newval.GetSeconds ());
}
static void
RtoTracer (Time oldval, Time newval)
{
if (RtoFirstlineFlag)
{
*rtoStream->GetStream () << “0.0, ” << oldval.GetSeconds () << std::endl;
RtoFirstlineFlag = false;
}
*rtoStream->GetStream () << Simulator::Now ().GetSeconds () << “, ” << newval.GetSeconds () << std::endl;
rtoSeries->Append ( Simulator::Now ().GetSeconds () , newval.GetSeconds ());
}
static void
TraceCwnd (std::string cwnd_tr_file_name)
{
AsciiTraceHelper ascii;
cWndStream = ascii.CreateFileStream (cwnd_tr_file_name.c_str ());
Config::ConnectWithoutContext (“/NodeList/3/$ns3::TcpL4Protocol/SocketList/0/CongestionWindow”, MakeCallback (&CwndTracer));
}
static void
TraceSsThresh (std::string ssthresh_tr_file_name)
{
AsciiTraceHelper ascii;
ssThreshStream = ascii.CreateFileStream (ssthresh_tr_file_name.c_str ());
Config::ConnectWithoutContext (“/NodeList/3/$ns3::TcpL4Protocol/SocketList/0/SlowStartThreshold”, MakeCallback (&SsThreshTracer));
}
static void
TraceRtt (std::string rtt_tr_file_name)
{
AsciiTraceHelper ascii;
rttStream = ascii.CreateFileStream (rtt_tr_file_name.c_str ());
Config::ConnectWithoutContext (“/NodeList/3/$ns3::TcpL4Protocol/SocketList/0/RTT”, MakeCallback (&RttTracer));
}
static void
TraceRto (std::string rto_tr_file_name)
{
AsciiTraceHelper ascii;
rtoStream = ascii.CreateFileStream (rto_tr_file_name.c_str ());
Config::ConnectWithoutContext (“/NodeList/3/$ns3::TcpL4Protocol/SocketList/0/RTO”, MakeCallback (&RtoTracer));
}
Configure standard NetAnim file and end the simulation
For comparison purposes, we may create a NetAnim simulation file, which will only be capable of showing 2D of this 3D FANET scenario.
AnimationInterface anim (“SimpleNS3FANETCircleMobility3D-withTCPGraph.xml”);
Simulator::Stop (Seconds (200));
Simulator::Run ();
Simulator::Destroy ();
The 3D View of the simulated FANET in NetSimulyzer.
The following output shows the status of the four TCP dynamics graphs at the end of the simulation. In the middle, we are seeing the simulated FANET scenario.
The 3D Circle Mobility Model Demo
The following video shows the 3D output of the FANET simulation with CircleMobilityModel and the TCP dynamics graphs on NetSimulyzer. Under this real-time visualization, we can understand the cwnd, rtt, rto and ssThreshold dynamics of a selected TCP flow. For better visibility, we are showing cwnd and rtt dynamics only.
Note: The visualization of Packet Transmission and wave Propagation on Medium are not yet implemented in NetSimulyzer. Further, the movement tracking using lines is also not yet implemented in NetSimulizer. So we can only see the movement of nodes. But we can add “log events” to understand the events of transmission and reception through some text messages that will be displayed in a separate text window of NetSimulyzer.