A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-power-adaptation-distance.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2014 Universidad de la República - Uruguay
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Matias Richart <mrichart@fing.edu.uy>
18 */
19
87#include "ns3/command-line.h"
88#include "ns3/config.h"
89#include "ns3/double.h"
90#include "ns3/gnuplot.h"
91#include "ns3/internet-stack-helper.h"
92#include "ns3/ipv4-address-helper.h"
93#include "ns3/log.h"
94#include "ns3/mobility-helper.h"
95#include "ns3/mobility-model.h"
96#include "ns3/on-off-helper.h"
97#include "ns3/packet-sink-helper.h"
98#include "ns3/ssid.h"
99#include "ns3/uinteger.h"
100#include "ns3/wifi-mac-header.h"
101#include "ns3/wifi-mac.h"
102#include "ns3/wifi-net-device.h"
103#include "ns3/yans-wifi-channel.h"
104#include "ns3/yans-wifi-helper.h"
105
106using namespace ns3;
107
108NS_LOG_COMPONENT_DEFINE("PowerAdaptationDistance");
109
111static const uint32_t packetSize = 1420;
112
117{
118 public:
126
134 void PhyCallback(std::string path, Ptr<const Packet> packet, double powerW);
142 void RxCallback(std::string path, Ptr<const Packet> packet, const Address& from);
151 void PowerCallback(std::string path, double oldPower, double newPower, Mac48Address dest);
160 void RateCallback(std::string path, DataRate oldRate, DataRate newRate, Mac48Address dest);
167 void SetPosition(Ptr<Node> node, Vector position);
174 void AdvancePosition(Ptr<Node> node, int stepsSize, int stepsTime);
181 Vector GetPosition(Ptr<Node> node);
182
195
196 private:
198 typedef std::vector<std::pair<Time, DataRate>> TxTime;
204 void SetupPhy(Ptr<WifiPhy> phy);
212
213 std::map<Mac48Address, double> m_currentPower;
214 std::map<Mac48Address, DataRate> m_currentRate;
217 double m_totalTime;
221};
222
224{
225 Ptr<NetDevice> device = aps.Get(0);
226 Ptr<WifiNetDevice> wifiDevice = DynamicCast<WifiNetDevice>(device);
227 Ptr<WifiPhy> phy = wifiDevice->GetPhy();
228 SetupPhy(phy);
229 DataRate dataRate = DataRate(phy->GetDefaultMode().GetDataRate(phy->GetChannelWidth()));
230 double power = phy->GetTxPowerEnd();
231 for (uint32_t j = 0; j < stas.GetN(); j++)
232 {
233 Ptr<NetDevice> staDevice = stas.Get(j);
234 Ptr<WifiNetDevice> wifiStaDevice = DynamicCast<WifiNetDevice>(staDevice);
235 Mac48Address addr = wifiStaDevice->GetMac()->GetAddress();
236 m_currentPower[addr] = power;
237 m_currentRate[addr] = dataRate;
238 }
239 m_currentRate[Mac48Address("ff:ff:ff:ff:ff:ff")] = dataRate;
240 m_totalEnergy = 0;
241 m_totalTime = 0;
242 m_bytesTotal = 0;
243 m_output.SetTitle("Throughput Mbits/s");
244 m_output_power.SetTitle("Average Transmit Power");
245}
246
247void
249{
250 for (const auto& mode : phy->GetModeList())
251 {
252 WifiTxVector txVector;
253 txVector.SetMode(mode);
255 txVector.SetChannelWidth(phy->GetChannelWidth());
256 DataRate dataRate = DataRate(mode.GetDataRate(phy->GetChannelWidth()));
257 Time time = phy->CalculateTxDuration(packetSize, txVector, phy->GetPhyBand());
258 NS_LOG_DEBUG(mode.GetUniqueName() << " " << time.GetSeconds() << " " << dataRate);
259 m_timeTable.emplace_back(time, dataRate);
260 }
261}
262
263Time
265{
266 for (TxTime::const_iterator i = m_timeTable.begin(); i != m_timeTable.end(); i++)
267 {
268 if (rate == i->second)
269 {
270 return i->first;
271 }
272 }
273 NS_ASSERT(false);
274 return Seconds(0);
275}
276
277void
278NodeStatistics::PhyCallback(std::string path, Ptr<const Packet> packet, double powerW)
279{
280 WifiMacHeader head;
281 packet->PeekHeader(head);
282 Mac48Address dest = head.GetAddr1();
283
284 if (head.GetType() == WIFI_MAC_DATA)
285 {
286 m_totalEnergy += pow(10.0, m_currentPower[dest] / 10.0) *
289 }
290}
291
292void
293NodeStatistics::PowerCallback(std::string path, double oldPower, double newPower, Mac48Address dest)
294{
295 m_currentPower[dest] = newPower;
296}
297
298void
300 DataRate oldRate,
301 DataRate newRate,
302 Mac48Address dest)
303{
304 m_currentRate[dest] = newRate;
305}
306
307void
308NodeStatistics::RxCallback(std::string path, Ptr<const Packet> packet, const Address& from)
309{
310 m_bytesTotal += packet->GetSize();
311}
312
313void
315{
316 Ptr<MobilityModel> mobility = node->GetObject<MobilityModel>();
317 mobility->SetPosition(position);
318}
319
320Vector
322{
323 Ptr<MobilityModel> mobility = node->GetObject<MobilityModel>();
324 return mobility->GetPosition();
325}
326
327void
328NodeStatistics::AdvancePosition(Ptr<Node> node, int stepsSize, int stepsTime)
329{
330 Vector pos = GetPosition(node);
331 double mbs = ((m_bytesTotal * 8.0) / (1000000 * stepsTime));
332 m_bytesTotal = 0;
333 double atp = m_totalEnergy / stepsTime;
334 m_totalEnergy = 0;
335 m_totalTime = 0;
336 m_output_power.Add(pos.x, atp);
337 m_output.Add(pos.x, mbs);
338 pos.x += stepsSize;
339 SetPosition(node, pos);
340 NS_LOG_INFO("At time " << Simulator::Now().GetSeconds() << " sec; setting new position to "
341 << pos);
342 Simulator::Schedule(Seconds(stepsTime),
344 this,
345 node,
346 stepsSize,
347 stepsTime);
348}
349
352{
353 return m_output;
354}
355
358{
359 return m_output_power;
360}
361
370void
371PowerCallback(std::string path, double oldPower, double newPower, Mac48Address dest)
372{
373 NS_LOG_INFO((Simulator::Now()).GetSeconds()
374 << " " << dest << " Old power=" << oldPower << " New power=" << newPower);
375}
376
385void
386RateCallback(std::string path, DataRate oldRate, DataRate newRate, Mac48Address dest)
387{
388 NS_LOG_INFO((Simulator::Now()).GetSeconds()
389 << " " << dest << " Old rate=" << oldRate << " New rate=" << newRate);
390}
391
392int
393main(int argc, char* argv[])
394{
395 double maxPower = 17;
396 double minPower = 0;
397 uint32_t powerLevels = 18;
398
399 uint32_t rtsThreshold = 2346;
400 std::string manager = "ns3::ParfWifiManager";
401 std::string outputFileName = "parf";
402 int ap1_x = 0;
403 int ap1_y = 0;
404 int sta1_x = 5;
405 int sta1_y = 0;
406 uint32_t steps = 200;
407 uint32_t stepsSize = 1;
408 uint32_t stepsTime = 1;
409
410 CommandLine cmd(__FILE__);
411 cmd.AddValue("manager", "PRC Manager", manager);
412 cmd.AddValue("rtsThreshold", "RTS threshold", rtsThreshold);
413 cmd.AddValue("outputFileName", "Output filename", outputFileName);
414 cmd.AddValue("steps", "How many different distances to try", steps);
415 cmd.AddValue("stepsTime", "Time on each step", stepsTime);
416 cmd.AddValue("stepsSize", "Distance between steps", stepsSize);
417 cmd.AddValue("maxPower", "Maximum available transmission level (dbm).", maxPower);
418 cmd.AddValue("minPower", "Minimum available transmission level (dbm).", minPower);
419 cmd.AddValue("powerLevels",
420 "Number of transmission power levels available between "
421 "TxPowerStart and TxPowerEnd included.",
422 powerLevels);
423 cmd.AddValue("AP1_x", "Position of AP1 in x coordinate", ap1_x);
424 cmd.AddValue("AP1_y", "Position of AP1 in y coordinate", ap1_y);
425 cmd.AddValue("STA1_x", "Position of STA1 in x coordinate", sta1_x);
426 cmd.AddValue("STA1_y", "Position of STA1 in y coordinate", sta1_y);
427 cmd.Parse(argc, argv);
428
429 if (steps == 0)
430 {
431 std::cout << "Exiting without running simulation; steps value of 0" << std::endl;
432 }
433
434 uint32_t simuTime = (steps + 1) * stepsTime;
435
436 // Define the APs
437 NodeContainer wifiApNodes;
438 wifiApNodes.Create(1);
439
440 // Define the STAs
442 wifiStaNodes.Create(1);
443
445 wifi.SetStandard(WIFI_STANDARD_80211a);
446 WifiMacHelper wifiMac;
447 YansWifiPhyHelper wifiPhy;
449
450 wifiPhy.SetChannel(wifiChannel.Create());
451
452 NetDeviceContainer wifiApDevices;
453 NetDeviceContainer wifiStaDevices;
454 NetDeviceContainer wifiDevices;
455
456 // Configure the STA node
457 wifi.SetRemoteStationManager("ns3::MinstrelWifiManager",
458 "RtsCtsThreshold",
459 UintegerValue(rtsThreshold));
460 wifiPhy.Set("TxPowerStart", DoubleValue(maxPower));
461 wifiPhy.Set("TxPowerEnd", DoubleValue(maxPower));
462
463 Ssid ssid = Ssid("AP");
464 wifiMac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid));
465 wifiStaDevices.Add(wifi.Install(wifiPhy, wifiMac, wifiStaNodes.Get(0)));
466
467 // Configure the AP node
468 wifi.SetRemoteStationManager(manager,
469 "DefaultTxPowerLevel",
470 UintegerValue(powerLevels - 1),
471 "RtsCtsThreshold",
472 UintegerValue(rtsThreshold));
473 wifiPhy.Set("TxPowerStart", DoubleValue(minPower));
474 wifiPhy.Set("TxPowerEnd", DoubleValue(maxPower));
475 wifiPhy.Set("TxPowerLevels", UintegerValue(powerLevels));
476
477 ssid = Ssid("AP");
478 wifiMac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid));
479 wifiApDevices.Add(wifi.Install(wifiPhy, wifiMac, wifiApNodes.Get(0)));
480
481 wifiDevices.Add(wifiStaDevices);
482 wifiDevices.Add(wifiApDevices);
483
484 // Configure the mobility.
486 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
487 // Initial position of AP and STA
488 positionAlloc->Add(Vector(ap1_x, ap1_y, 0.0));
489 NS_LOG_INFO("Setting initial AP position to " << Vector(ap1_x, ap1_y, 0.0));
490 positionAlloc->Add(Vector(sta1_x, sta1_y, 0.0));
491 NS_LOG_INFO("Setting initial STA position to " << Vector(sta1_x, sta1_y, 0.0));
492 mobility.SetPositionAllocator(positionAlloc);
493 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
494 mobility.Install(wifiApNodes.Get(0));
495 mobility.Install(wifiStaNodes.Get(0));
496
497 // Statistics counter
498 NodeStatistics statistics = NodeStatistics(wifiApDevices, wifiStaDevices);
499
500 // Move the STA by stepsSize meters every stepsTime seconds
501 Simulator::Schedule(Seconds(0.5 + stepsTime),
503 &statistics,
504 wifiStaNodes.Get(0),
505 stepsSize,
506 stepsTime);
507
508 // Configure the IP stack
510 stack.Install(wifiApNodes);
511 stack.Install(wifiStaNodes);
513 address.SetBase("10.1.1.0", "255.255.255.0");
514 Ipv4InterfaceContainer i = address.Assign(wifiDevices);
515 Ipv4Address sinkAddress = i.GetAddress(0);
516 uint16_t port = 9;
517
518 // Configure the CBR generator
519 PacketSinkHelper sink("ns3::UdpSocketFactory", InetSocketAddress(sinkAddress, port));
520 ApplicationContainer apps_sink = sink.Install(wifiStaNodes.Get(0));
521
522 OnOffHelper onoff("ns3::UdpSocketFactory", InetSocketAddress(sinkAddress, port));
523 onoff.SetConstantRate(DataRate("54Mb/s"), packetSize);
524 onoff.SetAttribute("StartTime", TimeValue(Seconds(0.5)));
525 onoff.SetAttribute("StopTime", TimeValue(Seconds(simuTime)));
526 ApplicationContainer apps_source = onoff.Install(wifiApNodes.Get(0));
527
528 apps_sink.Start(Seconds(0.5));
529 apps_sink.Stop(Seconds(simuTime));
530
531 //------------------------------------------------------------
532 //-- Setup stats and data collection
533 //--------------------------------------------
534
535 // Register packet receptions to calculate throughput
536 Config::Connect("/NodeList/1/ApplicationList/*/$ns3::PacketSink/Rx",
538
539 // Register power and rate changes to calculate the Average Transmit Power
540 Config::Connect("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/RemoteStationManager/$" +
541 manager + "/PowerChange",
543 Config::Connect("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/RemoteStationManager/$" +
544 manager + "/RateChange",
546
547 Config::Connect("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxBegin",
549
550 // Callbacks to print every change of power and rate
551 Config::Connect("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/RemoteStationManager/$" +
552 manager + "/PowerChange",
554 Config::Connect("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/RemoteStationManager/$" +
555 manager + "/RateChange",
557
558 Simulator::Stop(Seconds(simuTime));
560
561 std::ofstream outfile("throughput-" + outputFileName + ".plt");
562 Gnuplot gnuplot = Gnuplot("throughput-" + outputFileName + ".eps", "Throughput");
563 gnuplot.SetTerminal("post eps color enhanced");
564 gnuplot.SetLegend("Time (seconds)", "Throughput (Mb/s)");
565 gnuplot.SetTitle("Throughput (AP to STA) vs time");
566 gnuplot.AddDataset(statistics.GetDatafile());
567 gnuplot.GenerateOutput(outfile);
568
569 if (manager == "ns3::ParfWifiManager" || manager == "ns3::AparfWifiManager" ||
570 manager == "ns3::RrpaaWifiManager")
571 {
572 std::ofstream outfile2("power-" + outputFileName + ".plt");
573 gnuplot = Gnuplot("power-" + outputFileName + ".eps", "Average Transmit Power");
574 gnuplot.SetTerminal("post eps color enhanced");
575 gnuplot.SetLegend("Time (seconds)", "Power (mW)");
576 gnuplot.SetTitle("Average transmit power (AP to STA) vs time");
577 gnuplot.AddDataset(statistics.GetPowerDatafile());
578 gnuplot.GenerateOutput(outfile2);
579 }
580
582
583 return 0;
584}
Class to collect node statistics.
void SetPosition(Ptr< Node > node, Vector position)
Set the Position of a node.
Gnuplot2dDataset m_output_power
Power output data.
Gnuplot2dDataset GetPowerDatafile()
Get the Power output data.
TxTime m_timeTable
Time, DataRate table.
void RateCallback(std::string path, DataRate oldRate, DataRate newRate, Mac48Address dest)
Callback called by WifiNetDevice/RemoteStationManager/x/RateChange.
Gnuplot2dDataset GetDatafile()
Get the Throughput output data.
void RxCallback(std::string path, Ptr< const Packet > packet, const Address &from)
Callback called by PacketSink/Rx.
NodeStatistics(NetDeviceContainer aps, NetDeviceContainer stas)
Constructor.
Time GetCalcTxTime(DataRate rate)
Get the time at which a given datarate has been recorded.
void PowerCallback(std::string path, double oldPower, double newPower, Mac48Address dest)
Callback called by WifiNetDevice/RemoteStationManager/x/PowerChange.
double m_totalTime
Time spent on a given state.
uint32_t m_bytesTotal
Number of received bytes on a given state.
void SetupPhy(Ptr< WifiPhy > phy)
Setup the WifiPhy object.
std::vector< std::pair< Time, DataRate > > TxTime
Time, DataRate pair vector.
Vector GetPosition(Ptr< Node > node)
Get the Position of a node.
std::map< Mac48Address, double > m_currentPower
Current Tx power for each sender.
double m_totalEnergy
Energy used on a given state.
Gnuplot2dDataset m_output
Throughput output data.
std::map< Mac48Address, DataRate > m_currentRate
Current Tx rate for each sender.
void AdvancePosition(Ptr< Node > node, int stepsSize, int stepsTime)
Move a node.
void PhyCallback(std::string path, Ptr< const Packet > packet, double powerW)
Callback called by WifiNetDevice/Phy/PhyTxBegin.
a polymophic address class
Definition: address.h:100
holds a vector of ns3::Application pointers.
void Start(Time start) const
Start all of the Applications in this container at the start time given as a parameter.
void Stop(Time stop) const
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
Parse command-line arguments.
Definition: command-line.h:232
Class for representing data rates.
Definition: data-rate.h:89
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
Class to represent a 2D points plot.
Definition: gnuplot.h:116
void Add(double x, double y)
Definition: gnuplot.cc:377
void SetTitle(const std::string &title)
Change line title.
Definition: gnuplot.cc:148
a simple class to generate gnuplot-ready plotting commands from a set of datasets.
Definition: gnuplot.h:370
void AddDataset(const GnuplotDataset &dataset)
Definition: gnuplot.cc:796
void SetLegend(const std::string &xLegend, const std::string &yLegend)
Definition: gnuplot.cc:776
void SetTerminal(const std::string &terminal)
Definition: gnuplot.cc:764
void GenerateOutput(std::ostream &os)
Writes gnuplot commands and data values to a single output stream.
Definition: gnuplot.cc:802
void SetTitle(const std::string &title)
Definition: gnuplot.cc:770
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
an EUI-48 address
Definition: mac48-address.h:46
Helper class used to assign positions and mobility models to nodes.
Keep track of the current position and velocity of an object.
holds a vector of ns3::NetDevice pointers
uint32_t GetN() const
Get the number of Ptr<NetDevice> stored in this container.
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
Definition: on-off-helper.h:44
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:140
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
static void Run()
Run the simulation.
Definition: simulator.cc:176
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:184
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
AttributeValue implementation for Ssid.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:402
AttributeValue implementation for Time.
Definition: nstime.h:1423
Hold an unsigned integer type.
Definition: uinteger.h:45
helps to create WifiNetDevice objects
Definition: wifi-helper.h:324
Implements the IEEE 802.11 MAC header.
Mac48Address GetAddr1() const
Return the address in the Address 1 field.
WifiMacType GetType() const
Return the type (WifiMacType)
create MAC layers for a ns3::WifiNetDevice.
void SetType(std::string type, Args &&... args)
void Set(std::string name, const AttributeValue &v)
Definition: wifi-helper.cc:163
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void SetChannelWidth(uint16_t channelWidth)
Sets the selected channelWidth (in MHz)
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
void SetPreambleType(WifiPreamble preamble)
Sets the preamble type.
manage and create wifi channel objects for the YANS model.
static YansWifiChannelHelper Default()
Create a channel helper in a default working state.
Ptr< YansWifiChannel > Create() const
Make it easy to create and manage PHY objects for the YANS model.
void SetChannel(Ptr< YansWifiChannel > channel)
uint16_t port
Definition: dsdv-manet.cc:44
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:975
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
@ WIFI_STANDARD_80211a
@ WIFI_PREAMBLE_LONG
ns address
Definition: first.py:40
ns stack
Definition: first.py:37
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:702
@ WIFI_MAC_DATA
ns cmd
Definition: second.py:33
ns wifi
Definition: third.py:88
ns ssid
Definition: third.py:86
ns mobility
Definition: third.py:96
ns wifiStaNodes
Definition: third.py:77
void RateCallback(std::string path, DataRate oldRate, DataRate newRate, Mac48Address dest)
Callback called by WifiNetDevice/RemoteStationManager/x/RateChange.
static const uint32_t packetSize
Packet size generated at the AP.
void PowerCallback(std::string path, double oldPower, double newPower, Mac48Address dest)
Callback called by WifiNetDevice/RemoteStationManager/x/PowerChange.
Ptr< PacketSink > sink
Pointer to the packet sink application.
Definition: wifi-tcp.cc:55