Replace multi-rate-first.cc and multi-rate-second.cc with better example multirate.cc

This commit is contained in:
Duy Nguyen
2009-09-25 14:38:12 -07:00
parent 8c2d2cb0dd
commit 7ffc7371db
4 changed files with 525 additions and 662 deletions

View File

@@ -1,398 +0,0 @@
/**
*
* Instructions:
* ./waf --run multi-rate-first
* gnuplot multi-rate-first-scen*.plt
*
* Output:
* multi-rate-first-scen1.eps
* multi-rate-first-scen2.eps
* multi-rate-first-scen3.eps
* multi-rate-first-scen4.eps
*
* Side Note: It may take some time.
*/
#include "ns3/core-module.h"
#include "ns3/common-module.h"
#include "ns3/node-module.h"
#include "ns3/helper-module.h"
#include "ns3/mobility-module.h"
#include "ns3/contrib-module.h"
#include <iostream>
#include <fstream>
NS_LOG_COMPONENT_DEFINE ("Main");
using namespace ns3;
class Experiment
{
public:
Experiment ();
Experiment (std::string name);
Gnuplot2dDataset Run (const WifiHelper &wifi, const YansWifiPhyHelper &wifiPhy,
const NqosWifiMacHelper &wifiMac, const YansWifiChannelHelper &wifiChannel, const MobilityHelper &mobility, int positionStep);
private:
void ReceivePacket (Ptr<Socket> socket);
void SetPosition (Ptr<Node> node, Vector position);
Vector GetPosition (Ptr<Node> node);
void AdvancePosition (Ptr<Node> node);
void BackTrackPosition (Ptr<Node> node);
void StationaryPosition (Ptr<Node> node);
void MultiPosition (Ptr<Node> node1, Ptr<Node> node2);
Ptr<Socket> SetupPacketReceive (Ptr<Node> node);
uint32_t m_bytesTotal;
Gnuplot2dDataset m_output;
};
Experiment::Experiment ()
{}
Experiment::Experiment (std::string name)
: m_output (name)
{
m_output.SetStyle (Gnuplot2dDataset::LINES);
}
void
Experiment::SetPosition (Ptr<Node> node, Vector position)
{
Ptr<MobilityModel> mobility = node->GetObject<MobilityModel> ();
mobility->SetPosition (position);
}
Vector
Experiment::GetPosition (Ptr<Node> node)
{
Ptr<MobilityModel> mobility = node->GetObject<MobilityModel> ();
return mobility->GetPosition ();
}
void
Experiment::AdvancePosition (Ptr<Node> node)
{
Vector pos = GetPosition (node);
double mbs = ((m_bytesTotal * 8.0) / 1000000);
m_bytesTotal = 0;
m_output.Add ((Simulator::Now()).GetSeconds(), mbs);
pos.x += 1.0;
if (pos.x >= 210.0)
{
return;
}
SetPosition (node, pos);
//std::cout << "x="<<pos.x << std::endl;
Simulator::Schedule (Seconds (1.0), &Experiment::AdvancePosition, this, node);
}
void
Experiment::BackTrackPosition (Ptr<Node> node)
{
Vector pos = GetPosition (node);
double mbs = ((m_bytesTotal * 8.0) / 1000000);
m_bytesTotal = 0;
m_output.Add ((Simulator::Now()).GetSeconds(), mbs);
pos.x -= 1.0;
if (pos.x < 0)
{
return;
}
SetPosition (node, pos);
//std::cout << "x="<<pos.x << std::endl;
Simulator::Schedule (Seconds (1.0), &Experiment::BackTrackPosition, this, node);
}
void
Experiment::StationaryPosition (Ptr<Node> node)
{
double mbs = ((m_bytesTotal * 8.0) / 1000000);
m_bytesTotal = 0;
m_output.Add ((Simulator::Now()).GetSeconds(), mbs);
}
void
Experiment::MultiPosition (Ptr<Node> n1, Ptr<Node> n2)
{
Vector pos1 = GetPosition(n1);
Vector pos2 = GetPosition(n2);
double mbs = ((m_bytesTotal * 8.0) / 1000000);
m_bytesTotal = 0;
m_output.Add ((Simulator::Now()).GetSeconds(), mbs);
if( pos1.x < 230)
{
pos1.x += 1.0;
SetPosition (n1, pos1);
}
if( pos2.x > 0)
{
pos2.x -= 1.0;
SetPosition (n2, pos2);
}
}
void
Experiment::ReceivePacket (Ptr<Socket> socket)
{
Ptr<Packet> packet;
while (packet = socket->Recv ())
{
m_bytesTotal += packet->GetSize ();
}
}
Ptr<Socket>
Experiment::SetupPacketReceive (Ptr<Node> node)
{
TypeId tid = TypeId::LookupByName ("ns3::PacketSocketFactory");
Ptr<Socket> sink = Socket::CreateSocket (node, tid);
sink->Bind ();
sink->SetRecvCallback (MakeCallback (&Experiment::ReceivePacket, this));
return sink;
}
Gnuplot2dDataset
Experiment::Run (const WifiHelper &wifi, const YansWifiPhyHelper &wifiPhy,
const NqosWifiMacHelper &wifiMac, const YansWifiChannelHelper &wifiChannel, const MobilityHelper &mobility, int positionStep)
{
m_bytesTotal = 0;
NodeContainer c;
c.Create (2);
PacketSocketHelper packetSocket;
packetSocket.Install (c);
YansWifiPhyHelper phy = wifiPhy;
phy.SetChannel (wifiChannel.Create ());
NqosWifiMacHelper mac = wifiMac;
NetDeviceContainer devices = wifi.Install (phy, mac, c);
mobility.Install (c);
PacketSocketAddress socket;
socket.SetSingleDevice(devices.Get (0)->GetIfIndex ());
socket.SetPhysicalAddress (devices.Get (1)->GetAddress ());
socket.SetProtocol (1);
OnOffHelper onoff ("ns3::PacketSocketFactory", Address (socket));
onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (250)));
onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
onoff.SetAttribute ("DataRate", DataRateValue (DataRate (60000000)));
onoff.SetAttribute ("PacketSize", UintegerValue (2000));
ApplicationContainer apps = onoff.Install (c.Get (0));
apps.Start (Seconds (0.5));
apps.Stop (Seconds (250.0));
Ptr<Socket> recvSink = SetupPacketReceive (c.Get (1));
if (positionStep == 1)
{
Simulator::Schedule (Seconds (1.5), &Experiment::AdvancePosition, this, c.Get (1));
}
else if (positionStep == -1)
{
Simulator::Schedule (Seconds (1.5), &Experiment::BackTrackPosition, this, c.Get (1));
}
else if (positionStep == 0)
{
for(int i = 1; i <= 210; i++)
{
Simulator::Schedule (Seconds (i), &Experiment::StationaryPosition, this, c.Get (1));
}
}
else if (positionStep == 2)
{
for(int i = 1; i <= 210; i++)
{
Simulator::Schedule (Seconds (i), &Experiment::MultiPosition, this, c.Get(0), c.Get (1));
}
}
Simulator::Run ();
Simulator::Destroy ();
return m_output;
}
int main (int argc, char *argv[])
{
std::ofstream outfile ("multi-rate-first-scen1.plt");
std::ofstream outfile2 ("multi-rate-first-scen2.plt");
std::ofstream outfile3 ("multi-rate-first-scen3.plt");
std::ofstream outfile4 ("multi-rate-first-scen4.plt");
// disable fragmentation
Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("2200"));
Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("2200"));
CommandLine cmd;
cmd.Parse (argc, argv);
MobilityHelper mobility;
Experiment experiment;
Gnuplot gnuplot;
int myPositionStep;
Ptr<ListPositionAllocator> positionAlloc;
Gnuplot2dDataset dataset;
WifiHelper wifi = WifiHelper::Default ();
NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
// Scenario 1: two nodes within transmission range about 5 meters apart
// Fix a node stationary, move the second node away from it
// moving forward
myPositionStep = 1;
gnuplot = Gnuplot ("multi-rate-first-scen1.eps");
positionAlloc = CreateObject<ListPositionAllocator> ();
positionAlloc->Add (Vector (0.0, 0.0, 0.0));
positionAlloc->Add (Vector (5.0, 0.0, 0.0));
mobility.SetPositionAllocator (positionAlloc);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
wifiMac.SetType ("ns3::AdhocWifiMac");
wifi.SetStandard (WIFI_PHY_STANDARD_holland);
experiment = Experiment ("minstrel");
wifi.SetRemoteStationManager ("ns3::MinstrelWifiManager");
dataset = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel, mobility, myPositionStep);
gnuplot.AddDataset (dataset);
experiment = Experiment ("ideal");
wifi.SetRemoteStationManager ("ns3::IdealWifiManager");
dataset = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel, mobility, myPositionStep);
gnuplot.AddDataset (dataset);
gnuplot.SetTerminal ("postscript eps color enh \"Times-BoldItalic\"");
gnuplot.SetLegend ("Time (Seconds)", "Throughput(Mbps)");
gnuplot.SetExtra ("set xrange [0:250]");
gnuplot.SetTitle ("Throughput vs Time");
gnuplot.GenerateOutput (outfile);
outfile.close ();
// Scenario 2: two nodes out of transmission range about 230 meters apart
// Fix a node stationary, move the second node into transmission range
// moving backward
myPositionStep = -1;
gnuplot = Gnuplot ("multi-rate-first-scen2.eps");
positionAlloc = CreateObject<ListPositionAllocator> ();
positionAlloc->Add (Vector (0.0, 0.0, 0.0));
positionAlloc->Add (Vector (230.0, 0.0, 0.0));
mobility.SetPositionAllocator (positionAlloc);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
wifiMac.SetType ("ns3::AdhocWifiMac");
wifi.SetStandard (WIFI_PHY_STANDARD_holland);
experiment = Experiment ("minstrel");
wifi.SetRemoteStationManager ("ns3::MinstrelWifiManager");
dataset= experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel, mobility, myPositionStep);
gnuplot.AddDataset (dataset);
experiment = Experiment ("ideal");
wifi.SetRemoteStationManager ("ns3::IdealWifiManager");
dataset= experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel, mobility, myPositionStep);
gnuplot.AddDataset (dataset);
gnuplot.SetTerminal ("postscript eps color enh \"Times-BoldItalic\"");
gnuplot.SetLegend ("Time (Seconds)", "Throughput(Mbps)");
gnuplot.SetExtra ("set xrange [0:250]");
gnuplot.SetTitle ("Throughput vs Time");
gnuplot.GenerateOutput (outfile2);
outfile2.close ();
// Scenario 3: two nodes within transmission range 25 meters part
// Set both nodes stationary
// this is more like a sanity check
// Set position stationary
myPositionStep = 0;
gnuplot = Gnuplot ("multi-rate-first-scen3.eps");
positionAlloc = CreateObject<ListPositionAllocator> ();
positionAlloc->Add (Vector (0.0, 0.0, 0.0));
positionAlloc->Add (Vector (25.0, 0.0, 0.0));
mobility.SetPositionAllocator (positionAlloc);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
wifiMac.SetType ("ns3::AdhocWifiMac");
wifi.SetStandard (WIFI_PHY_STANDARD_holland);
experiment = Experiment ("minstrel");
wifi.SetRemoteStationManager ("ns3::MinstrelWifiManager");
dataset= experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel, mobility, myPositionStep);
gnuplot.AddDataset (dataset);
experiment = Experiment ("ideal");
wifi.SetRemoteStationManager ("ns3::IdealWifiManager");
dataset= experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel, mobility, myPositionStep);
gnuplot.AddDataset (dataset);
gnuplot.SetTerminal ("postscript eps color enh \"Times-BoldItalic\"");
gnuplot.SetLegend ("Time (Seconds)", "Throughput(Mbps)");
gnuplot.SetExtra ("set xrange [0:250]");
gnuplot.SetTitle ("Throughput vs Time");
gnuplot.GenerateOutput (outfile3);
outfile3.close ();
// Scenario 4: Two nodes in opposite direction about 230 meters apart
// moving into transmission range and out of transmission range
myPositionStep = 2;
gnuplot = Gnuplot ("multi-rate-first-scen4.eps");
positionAlloc = CreateObject<ListPositionAllocator> ();
// initial position of node 1
positionAlloc->Add (Vector (0.0, 25.0, 0.0));
// initial position of node 2
positionAlloc->Add (Vector (230.0, 0.0, 0.0));
mobility.SetPositionAllocator (positionAlloc);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
wifiMac.SetType ("ns3::AdhocWifiMac");
wifi.SetStandard (WIFI_PHY_STANDARD_holland);
experiment = Experiment ("minstrel");
wifi.SetRemoteStationManager ("ns3::MinstrelWifiManager");
dataset= experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel, mobility, myPositionStep);
gnuplot.AddDataset (dataset);
experiment = Experiment ("ideal");
wifi.SetRemoteStationManager ("ns3::IdealWifiManager");
dataset= experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel, mobility, myPositionStep);
gnuplot.AddDataset (dataset);
gnuplot.SetTerminal ("postscript eps color enh \"Times-BoldItalic\"");
gnuplot.SetLegend ("Time (Seconds)", "Throughput(Mbps)");
gnuplot.SetExtra ("set xrange [0:250]");
gnuplot.SetTitle ("Throughput vs Time");
gnuplot.GenerateOutput (outfile4);
outfile4.close ();
return 0;
}

View File

@@ -1,258 +0,0 @@
/*
* Instructions:
* ./waf --run multi-rate-second
* gnuplot multi-rate-second.plt
*
* Output: multi-rate-second.eps
*
*/
#include "ns3/core-module.h"
#include "ns3/common-module.h"
#include "ns3/node-module.h"
#include "ns3/helper-module.h"
#include "ns3/mobility-module.h"
#include "ns3/contrib-module.h"
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
NS_LOG_COMPONENT_DEFINE ("Main");
using namespace ns3;
class Experiment
{
public:
Experiment ();
Experiment (std::string name);
Gnuplot2dDataset Run (const WifiHelper &wifi, const YansWifiPhyHelper &wifiPhy,
const NqosWifiMacHelper &wifiMac, const YansWifiChannelHelper &wifiChannel);
private:
void ReceivePacket (Ptr<Socket> socket);
void SetPosition (Ptr<Node> node, Vector position);
Vector GetPosition (Ptr<Node> node);
Ptr<Socket> SetupPacketReceive (Ptr<Node> node);
void GenerateTraffic (Ptr<Socket> socket, uint32_t pktSize,
uint32_t pktCount, Time pktInterval , Ptr<Node> node);
uint32_t m_pktsTotal;
Gnuplot2dDataset m_output;
bool advanceStep;
};
Experiment::Experiment ()
{
advanceStep= true;
}
Experiment::Experiment (std::string name)
: m_output (name)
{
m_output.SetStyle (Gnuplot2dDataset::LINES);
}
void
Experiment::SetPosition (Ptr<Node> node, Vector position)
{
Ptr<MobilityModel> mobility = node->GetObject<MobilityModel> ();
mobility->SetPosition (position);
}
Vector
Experiment::GetPosition (Ptr<Node> node)
{
Ptr<MobilityModel> mobility = node->GetObject<MobilityModel> ();
return mobility->GetPosition ();
}
void
Experiment::ReceivePacket (Ptr<Socket> socket)
{
Ptr<Packet> packet;
while (packet = socket->Recv ())
{
m_pktsTotal ++;
}
}
Ptr<Socket>
Experiment::SetupPacketReceive (Ptr<Node> node)
{
TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
Ptr<Socket> sink = Socket::CreateSocket (node, tid);
InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), 80);
sink->Bind (local);
sink->SetRecvCallback (MakeCallback (&Experiment::ReceivePacket, this));
return sink;
}
void
Experiment::GenerateTraffic (Ptr<Socket> socket, uint32_t pktSize,
uint32_t pktCount, Time pktInterval, Ptr<Node> node )
{
Vector pos = GetPosition(node);
if (pktCount > 0)
{
///To simulate nodes moving in and out of transmission constantly
if(pos.x <= 230 && advanceStep)
{
///keep moving away
pos.x += .1;
SetPosition(node, pos);
}
else
{
if(pos.x < 150)
{
advanceStep=true;
}
else
{
advanceStep = false;
}
///moving back in
pos.x -= .1;
SetPosition(node, pos);
}
socket->Send (Create<Packet> (pktSize));
Simulator::Schedule (pktInterval, &Experiment::GenerateTraffic, this,
socket, pktSize,pktCount-1, pktInterval, node);
}
else
{
m_output.Add((Simulator::Now()).GetSeconds(), m_pktsTotal);
}
}
Gnuplot2dDataset
Experiment::Run (const WifiHelper &wifi, const YansWifiPhyHelper &wifiPhy,
const NqosWifiMacHelper &wifiMac, const YansWifiChannelHelper &wifiChannel)
{
m_pktsTotal = 0;
NodeContainer c;
c.Create (2);
YansWifiPhyHelper phy = wifiPhy;
phy.SetChannel (wifiChannel.Create ());
NqosWifiMacHelper mac = wifiMac;
NetDeviceContainer devices = wifi.Install (phy, mac, c);
MobilityHelper mobility;
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
positionAlloc->Add (Vector (0.0, 0.0, 0.0));
positionAlloc->Add (Vector (5.0, 0.0, 0.0));
mobility.SetPositionAllocator (positionAlloc);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (c);
InternetStackHelper internet;
internet.Install (c);
Ipv4AddressHelper ipv4;
NS_LOG_INFO ("Assign IP Addresses.");
ipv4.SetBase ("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer wifiNodesInterface = ipv4.Assign (devices);
Ptr<Socket> recvSink = SetupPacketReceive (c.Get (0));
TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
Ptr<Socket> source = Socket::CreateSocket (c.Get (1), tid);
InetSocketAddress remote = InetSocketAddress (Ipv4Address ("255.255.255.255"), 80);
source->Connect (remote);
uint32_t packetSize = 1014;
uint32_t maxPacketCount = 1000;
Time interPacketInterval = Seconds (1.);
Ptr<Node> n1 = c.Get(0);
Ptr<Ipv4> ipv41 = n1->GetObject<Ipv4> ();
// parameters for Ipv4::SetDown and SetUp
// The first ifIndex is 0 for loopback, then the first p2p is numbered 1,
// then the next p2p is numbered 2
double downTime = 0.0;
for (int i= 1; i <= 100; i++)
{
Simulator::Schedule (Seconds (i), &Experiment::GenerateTraffic,
this, source, packetSize, maxPacketCount,interPacketInterval, c.Get(1));
if ( i % 10 == 0 )
{
///bring a network interface down
Simulator::Schedule (Seconds (i+.1), &Ipv4::SetDown, ipv41, 1);
//duration of the down time
downTime += .1;
///bring a network interface up
Simulator::Schedule (Seconds (i + downTime), &Ipv4::SetUp, ipv41, 1);
}
}
Simulator::Run ();
Simulator::Destroy ();
return m_output;
}
int main (int argc, char *argv[])
{
std::ofstream outfile ("multi-rate-second.plt");
std::vector <std::string> ratesControl;
ratesControl.push_back ("Minstrel");
ratesControl.push_back ("Ideal");
std::vector <std::string> wifiManager;
wifiManager.push_back("ns3::MinstrelWifiManager");
wifiManager.push_back("ns3::IdealWifiManager");
// disable fragmentation
Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("2200"));
Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("2200"));
CommandLine cmd;
cmd.Parse (argc, argv);
Gnuplot gnuplot = Gnuplot ("multi-rate-second.eps");
for (uint32_t i = 0; i < ratesControl.size(); i++)
{
std::cout << ratesControl[i] << std::endl;
std::cout << wifiManager[i] << std::endl;
Gnuplot2dDataset dataset (ratesControl[i]);
dataset.SetStyle (Gnuplot2dDataset::LINES);
Experiment experiment;
WifiHelper wifi;
NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
wifiMac.SetType ("ns3::AdhocWifiMac");
NS_LOG_DEBUG (ratesControl[i]);
experiment = Experiment (ratesControl[i]);
wifi.SetStandard (WIFI_PHY_STANDARD_80211b);
wifi.SetRemoteStationManager (wifiManager[i]);
dataset = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel);
gnuplot.AddDataset (dataset);
}
gnuplot.SetTerminal ("postscript eps color enh \"Times-BoldItalic\"");
gnuplot.SetLegend ("Time ", "Number of packets received");
gnuplot.SetExtra ("set xrange [1000:1100]");
gnuplot.SetTitle ("Number of Packets Received vs Time");
gnuplot.GenerateOutput (outfile);
outfile.close ();
return 0;
}

523
examples/multirate.cc Normal file
View File

@@ -0,0 +1,523 @@
/* -*- 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
*
* Author: Duy Nguyen <duy@soe.ucsc.edu>
*/
/**
* Objective: Test multi-rate algorithms in varios scenarios and settings
*
* INSTRUCTIONS:
*
* To compile:
* ./waf --run multirate
*
* To compile with command input:
* ./waf --run "scratch/multirate.cc --packetSize=2000 --totalTime=50"
*
* To turn on NS_LOG:
* export NS_LOG=multirate=level_all
*
* To debug:
* /waf --shell
* gdb ./build/debug/scratch/multirate
*
* To view pcap files:
* tcpdump -nn -tt -r filename.pcap
*
* Sidenote: Simulation might take sometime
*/
#include "ns3/core-module.h"
#include "ns3/common-module.h"
#include "ns3/node-module.h"
#include "ns3/helper-module.h"
#include "ns3/mobility-module.h"
#include "ns3/contrib-module.h"
#include "ns3/random-variable.h"
#include "ns3/wifi-module.h"
#include <iostream>
#include <fstream>
NS_LOG_COMPONENT_DEFINE ("multirate");
using namespace ns3;
class Experiment
{
public:
Experiment ();
Experiment (std::string name);
Gnuplot2dDataset Run (const WifiHelper &wifi, const YansWifiPhyHelper &wifiPhy,
const NqosWifiMacHelper &wifiMac, const YansWifiChannelHelper &wifiChannel, const MobilityHelper &mobility);
bool CommandSetup (int argc, char **argv);
private:
Vector GetPosition (Ptr<Node> node);
Ptr<Socket> SetupPacketReceive (Ptr<Node> node);
void ApplicationSetup (Ptr<Node> client, Ptr<Node> server, double start, double stop);
void AssignNeighbors (NodeContainer c);
void SelectSrcDest (NodeContainer c);
void ReceivePacket (Ptr<Socket> socket);
void CheckThroughput ();
void SendMultiDestinations(Ptr<Node> sender, NodeContainer c);
Gnuplot2dDataset m_output;
uint32_t m_bytesTotal;
uint32_t packetSize;
uint32_t gridSize;
uint32_t nodeDistance;
uint32_t port;
uint32_t expMean;
double totalTime;
bool enablePcap;
bool enableTracing;
bool enableFlowMon;
bool enableRouting;
bool enableMobility;
NodeContainer containerA, containerB, containerC, containerD;
};
Experiment::Experiment ()
{}
Experiment::Experiment (std::string name) :
m_output (name),
m_bytesTotal(0),
packetSize (2000),
gridSize (10), //10x10 grid for a total of 100 nodes
nodeDistance (40),
port (5000),
expMean (4), //flows being exponentially distributed
totalTime (50),
enablePcap(false), // will flood the directory with *.pcap files
enableTracing(false),
enableFlowMon(true),
enableRouting(false),
enableMobility(false)
{
m_output.SetStyle (Gnuplot2dDataset::LINES);
}
Ptr<Socket>
Experiment::SetupPacketReceive (Ptr<Node> node)
{
TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
Ptr<Socket> sink = Socket::CreateSocket (node, tid);
InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), port);
sink->Bind (local);
sink->SetRecvCallback (MakeCallback (&Experiment::ReceivePacket, this));
return sink;
}
void
Experiment::ReceivePacket (Ptr<Socket> socket)
{
Ptr<Packet> packet;
while (packet = socket->Recv ())
{
m_bytesTotal += packet->GetSize();
}
}
void
Experiment::CheckThroughput()
{
double mbs = ((m_bytesTotal * 8.0) /1000000);
m_bytesTotal = 0;
m_output.Add ((Simulator::Now ()).GetSeconds (), mbs);
Simulator::Schedule (Seconds (1.0), &Experiment::CheckThroughput, this);
}
Vector
Experiment::GetPosition (Ptr<Node> node)
{
Ptr<MobilityModel> mobility = node->GetObject<MobilityModel> ();
return mobility->GetPosition ();
}
/**
*
* Take the grid map, divide it into 4 quadrants
* Assign all nodes from each quadrant to a specific container
*
*/
void
Experiment::AssignNeighbors (NodeContainer c)
{
uint32_t totalNodes = c.GetN ();
for (uint32_t i=0; i< totalNodes; i++)
{
if ( (i % gridSize) <= (gridSize/2 - 1))
{
//lower left quadrant
if ( i < totalNodes/2 )
{
containerA.Add(c.Get(i));
}
//upper left quadrant
if ( i >= (uint32_t)(4*totalNodes)/10 )
{
containerC.Add(c.Get(i));
}
}
if ( (i % gridSize) >= (gridSize/2 - 1))
{
//lower right quadrant
if ( i < totalNodes/2 )
{
containerB.Add(c.Get(i));
}
//upper right quadrant
if ( i >= (uint32_t)(4*totalNodes)/10 )
{
containerD.Add(c.Get(i));
}
}
}
}
/**
* Sources and destinations are randomly selected such that a node
* may be the source for multiple destinations and a node maybe a destination
* for multiple sources.
*/
void
Experiment::SelectSrcDest (NodeContainer c)
{
uint32_t totalNodes = c.GetN();
UniformVariable uvSrc (0, totalNodes/2 -1);
UniformVariable uvDest (totalNodes/2, totalNodes);
for (uint32_t i=0; i < totalNodes/3; i++)
{
ApplicationSetup (c.Get(uvSrc.GetValue()), c.Get(uvDest.GetValue()) , 1, totalTime);
}
}
/**
*
* A sender node will set up a flow to each of the its neighbors
* in its quadrant randomly. All the flows are exponentially distributed
*
*/
void
Experiment::SendMultiDestinations(Ptr<Node> sender, NodeContainer c)
{
// UniformVariable params: (Xrange, Yrange)
UniformVariable uv(0, c.GetN ());
// ExponentialVariable params: (mean, upperbound)
ExponentialVariable ev(expMean, totalTime);
double start=1, stop=totalTime;
uint32_t destIndex;
for (uint32_t i=0; i < c.GetN (); i++)
{
stop = start + ev.GetValue();
NS_LOG_DEBUG("Start=" << start << " Stop=" << stop);
do {
destIndex = (uint32_t) uv.GetValue();
} while ( (c.Get(destIndex))->GetId () == sender->GetId ());
ApplicationSetup (sender, c.Get(destIndex) , start, stop);
start = stop;
if(start > totalTime)
{
break;
}
}
}
void
Experiment::ApplicationSetup (Ptr<Node> client, Ptr<Node> server, double start, double stop)
{
Vector serverPos = GetPosition (server);
Vector clientPos = GetPosition (client);
Ptr<Ipv4> ipv4Server = server->GetObject<Ipv4>();
Ptr<Ipv4> ipv4Client = client->GetObject<Ipv4>();
Ipv4InterfaceAddress iaddrServer = ipv4Server->GetAddress(1,0);
Ipv4InterfaceAddress iaddrClient = ipv4Client->GetAddress(1,0);
Ipv4Address ipv4AddrServer = iaddrServer.GetLocal ();
Ipv4Address ipv4AddrClient = iaddrClient.GetLocal ();
NS_LOG_DEBUG("Set up Server Device " << (server->GetDevice(0))->GetAddress ()
<< " with ip " << ipv4AddrServer
<< " position (" << serverPos.x << "," << serverPos.y << "," << serverPos.z << ")");
NS_LOG_DEBUG("Set up Client Device " << (client->GetDevice(0))->GetAddress ()
<< " with ip " << ipv4AddrClient
<< " position (" << clientPos.x << "," << clientPos.y << "," << clientPos.z << ")"
<< "\n");
// Equipping the source node with OnOff Application used for sending
OnOffHelper onoff ("ns3::UdpSocketFactory", Address(InetSocketAddress(Ipv4Address("10.0.0.1"), port)));
onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
onoff.SetAttribute ("DataRate", DataRateValue (DataRate (60000000)));
onoff.SetAttribute ("PacketSize", UintegerValue (packetSize));
onoff.SetAttribute ("Remote", AddressValue(InetSocketAddress (ipv4AddrServer, port)));
ApplicationContainer apps = onoff.Install (client);
apps.Start (Seconds (start));
apps.Stop (Seconds (stop));
/*
// Select either Sink Method 1 or 2 for setting up sink
// one using a helper vs one without
// Sink: Method 1
Address sinkAddr(InetSocketAddress (Ipv4Address::GetAny (), port));
PacketSinkHelper sinkHelper ("ns3::UdpSocketFactory", sinkAddr);
ApplicationContainer sinkApp = sinkHelper.Install (server);
sinkApp.Start (Seconds (start));
sinkApp.Stop (Seconds (stop));
*/
// Sink: Method 2
Ptr<Socket> sink = SetupPacketReceive (server);
}
Gnuplot2dDataset
Experiment::Run (const WifiHelper &wifi, const YansWifiPhyHelper &wifiPhy,
const NqosWifiMacHelper &wifiMac, const YansWifiChannelHelper &wifiChannel, const MobilityHelper &mobility)
{
uint32_t nodeSize = gridSize*gridSize;
NodeContainer c;
c.Create (nodeSize);
YansWifiPhyHelper phy = wifiPhy;
phy.SetChannel (wifiChannel.Create ());
NqosWifiMacHelper mac = wifiMac;
NetDeviceContainer devices = wifi.Install (phy, mac, c);
OlsrHelper olsr;
Ipv4StaticRoutingHelper staticRouting;
Ipv4ListRoutingHelper list;
if (enableRouting)
{
list.Add (staticRouting, 0);
list.Add (olsr, 10);
}
InternetStackHelper internet;
if (enableRouting)
{
internet.SetRoutingHelper(list);
}
internet.Install (c);
Ipv4AddressHelper address;
address.SetBase ("10.0.0.0", "255.255.255.0");
Ipv4InterfaceContainer ipInterfaces;
ipInterfaces = address.Assign(devices);
MobilityHelper mobil= mobility;
mobil.SetPositionAllocator ("ns3::GridPositionAllocator",
"MinX", DoubleValue (0.0),
"MinY", DoubleValue (0.0),
"DeltaX", DoubleValue (nodeDistance),
"DeltaY", DoubleValue (nodeDistance),
"GridWidth", UintegerValue (gridSize),
"LayoutType", StringValue ("RowFirst"));
mobil.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
if (enableMobility && enableRouting)
{
//Rectangle (xMin, xMax, yMin, yMax)
mobil.SetMobilityModel ("ns3::RandomDirection2dMobilityModel",
"Bounds", RectangleValue (Rectangle (0, 500, 0, 500)),
"Speed", RandomVariableValue (ConstantVariable (10)),
"Pause", RandomVariableValue (ConstantVariable (0.2)));
}
mobil.Install (c);
if (enableRouting)
{
SelectSrcDest(c);
/*
//another setup
//All flows begin at the same time
for (uint32_t i = 0,j = 0; i < nodeSize - 1; i = i+2)
{
NS_LOG_DEBUG("Flow " << ++j);
ApplicationSetup (c.Get (i), c.Get (i+1), 1, totalTime);
}
*/
// NS_LOG_INFO ("Enabling global routing on all nodes");
// Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
}
else
{
AssignNeighbors(c);
//Note: these senders are hand-picked in order to ensure good coverage
//for 10x10 grid, basically one sender for each quadrant
//you might have to change these values for other grids
NS_LOG_DEBUG(">>>>>>>>>region A<<<<<<<<<");
SendMultiDestinations(c.Get(22), containerA);
NS_LOG_DEBUG(">>>>>>>>>region B<<<<<<<<<");
SendMultiDestinations(c.Get(26), containerB);
NS_LOG_DEBUG(">>>>>>>>>region C<<<<<<<<<");
SendMultiDestinations(c.Get(72), containerC);
NS_LOG_DEBUG(">>>>>>>>>region D<<<<<<<<<");
SendMultiDestinations(c.Get(76), containerD);
}
CheckThroughput ();
if (enablePcap)
{
phy.EnablePcapAll("multirate");
}
if (enableTracing)
{
std::ofstream ascii;
ascii.open ("multirate.tr");
phy.EnableAsciiAll (ascii);
}
Ptr<FlowMonitor> flowmon;
if (enableFlowMon)
{
FlowMonitorHelper flowmonHelper;
flowmon = flowmonHelper.InstallAll ();
}
Simulator::Stop (Seconds (totalTime));
Simulator::Run ();
if (enableFlowMon)
{
flowmon->SerializeToXmlFile ("multirate.flowmon", false, false);
}
Simulator::Destroy ();
return m_output;
}
bool
Experiment::CommandSetup (int argc, char **argv)
{
// for commandline input
CommandLine cmd;
cmd.AddValue ("packetSize", "packet size", packetSize);
cmd.AddValue ("totalTime", "simulation time", totalTime);
cmd.Parse (argc, argv);
return true;
}
int main (int argc, char *argv[])
{
std::ofstream outfile ("multirate.plt");
// disable fragmentation
Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("2200"));
//set value to 0 for enabling RTS/CTS
Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("2200"));
MobilityHelper mobility;
Experiment experiment;
Gnuplot gnuplot;
Gnuplot2dDataset dataset;
WifiHelper wifi = WifiHelper::Default ();
NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
Ssid ssid = Ssid ("Testbed");
wifiMac.SetType ("ns3::AdhocWifiMac", "Ssid", SsidValue(ssid));
wifi.SetStandard (WIFI_PHY_STANDARD_holland);
//To ensure repeatable experiment scenario
//for each multirate, please uncomment one at a time and obtain results
experiment = Experiment ("minstrel");
//experiment = Experiment ("ideal");
//for commandline input
if (!experiment.CommandSetup(argc, argv))
{
std::cout << "exiting ..." << std::endl;
exit(1);
}
wifi.SetRemoteStationManager ("ns3::MinstrelWifiManager");
dataset = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel, mobility);
gnuplot.AddDataset (dataset);
/*
wifi.SetRemoteStationManager ("ns3::IdealWifiManager");
dataset = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel, mobility);
gnuplot.AddDataset (dataset);
*/
gnuplot.GenerateOutput (outfile);
return 0;
}

View File

@@ -200,10 +200,6 @@ def build(bld):
['core', 'simulator', 'mobility', 'wifi'])
obj.source = 'simple-wifi-frame-aggregation.cc'
obj = bld.create_ns3_program('multi-rate-first',
obj = bld.create_ns3_program('multirate',
['core', 'simulator', 'mobility', 'wifi'])
obj.source = 'multi-rate-first.cc'
obj = bld.create_ns3_program('multi-rate-second',
['core', 'simulator', 'mobility', 'wifi'])
obj.source = 'multi-rate-second.cc'
obj.source = 'multirate.cc'