A Discrete-Event Network Simulator
API
wifi-phy-test.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005,2006 INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 
21 #include "ns3/packet.h"
22 #include "ns3/constant-position-mobility-model.h"
23 #include "ns3/simulator.h"
24 #include "ns3/command-line.h"
25 #include "ns3/flow-id-tag.h"
26 #include "ns3/yans-wifi-channel.h"
27 #include "ns3/yans-wifi-phy.h"
28 #include "ns3/propagation-loss-model.h"
29 #include "ns3/propagation-delay-model.h"
30 #include "ns3/nist-error-rate-model.h"
31 #include "ns3/wifi-psdu.h"
32 
33 using namespace ns3;
34 
37 {
38 public:
40  struct Input
41  {
42  Input ();
43  double distance;
44  std::string txMode;
45  uint8_t txPowerLevel;
46  uint32_t packetSize;
47  uint32_t nPackets;
48  };
50  struct Output
51  {
52  uint32_t received;
53  };
54  PsrExperiment ();
55 
61  struct PsrExperiment::Output Run (struct PsrExperiment::Input input);
62 
63 private:
65  void Send (void);
73  void Receive (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
74  Ptr<WifiPhy> m_tx;
75  struct Input m_input;
76  struct Output m_output;
77 };
78 
79 void
81 {
82  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (Create<Packet> (m_input.packetSize), WifiMacHeader ());
83  WifiMode mode = WifiMode (m_input.txMode);
84  WifiTxVector txVector;
85  txVector.SetTxPowerLevel (m_input.txPowerLevel);
86  txVector.SetMode (mode);
88  m_tx->Send (psdu, txVector);
89 }
90 
91 void
92 PsrExperiment::Receive (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu)
93 {
94  m_output.received++;
95 }
96 
98 {
99 }
101  : distance (5.0),
102  txMode ("OfdmRate6Mbps"),
103  txPowerLevel (0),
104  packetSize (2304),
105  nPackets (400)
106 {
107 }
108 
110 PsrExperiment::Run (struct PsrExperiment::Input input)
111 {
112  m_output.received = 0;
113  m_input = input;
114 
115  Ptr<MobilityModel> posTx = CreateObject<ConstantPositionMobilityModel> ();
116  posTx->SetPosition (Vector (0.0, 0.0, 0.0));
117  Ptr<MobilityModel> posRx = CreateObject<ConstantPositionMobilityModel> ();
118  posRx->SetPosition (Vector (m_input.distance, 0.0, 0.0));
119 
120  Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel> ();
121  channel->SetPropagationDelayModel (CreateObject<ConstantSpeedPropagationDelayModel> ());
122  Ptr<LogDistancePropagationLossModel> log = CreateObject<LogDistancePropagationLossModel> ();
123  channel->SetPropagationLossModel (log);
124 
125  Ptr<YansWifiPhy> tx = CreateObject<YansWifiPhy> ();
126  Ptr<YansWifiPhy> rx = CreateObject<YansWifiPhy> ();
127  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
128  tx->SetErrorRateModel (error);
129  rx->SetErrorRateModel (error);
130  tx->SetChannel (channel);
131  rx->SetChannel (channel);
132  tx->SetMobility (posTx);
133  rx->SetMobility (posRx);
134 
136  rx->ConfigureStandard (WIFI_PHY_STANDARD_80211a);
137 
138  rx->SetReceiveOkCallback (MakeCallback (&PsrExperiment::Receive, this));
139 
140  for (uint32_t i = 0; i < m_input.nPackets; ++i)
141  {
142  Simulator::Schedule (Seconds (i), &PsrExperiment::Send, this);
143  }
144  m_tx = tx;
145  Simulator::Run ();
146  Simulator::Destroy ();
147  return m_output;
148 }
149 
152 {
153 public:
155  struct Input
156  {
157  Input ();
159  double xA;
160  double xB;
161  std::string txModeA;
162  std::string txModeB;
163  uint8_t txPowerLevelA;
164  uint8_t txPowerLevelB;
165  uint32_t packetSizeA;
166  uint32_t packetSizeB;
167  uint32_t nPackets;
168  };
170  struct Output
171  {
172  uint32_t receivedA;
173  uint32_t receivedB;
174  };
176 
183 private:
185  void SendA (void) const;
187  void SendB (void) const;
195  void Receive (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
196  Ptr<WifiPhy> m_txA;
197  Ptr<WifiPhy> m_txB;
198  uint32_t m_flowIdA;
199  uint32_t m_flowIdB;
200  struct Input m_input;
201  struct Output m_output;
202 };
203 
204 void
206 {
207  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (Create<Packet> (m_input.packetSizeA), WifiMacHeader ());
208  (*psdu->begin ())->GetPacket ()->AddByteTag (FlowIdTag (m_flowIdA));
209  WifiTxVector txVector;
210  txVector.SetTxPowerLevel (m_input.txPowerLevelA);
211  txVector.SetMode (WifiMode (m_input.txModeA));
213  m_txA->Send (psdu, txVector);
214 }
215 
216 void
218 {
219  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (Create<Packet> (m_input.packetSizeB), WifiMacHeader ());
220  (*psdu->begin ())->GetPacket ()->AddByteTag (FlowIdTag (m_flowIdB));
221  WifiTxVector txVector;
222  txVector.SetTxPowerLevel (m_input.txPowerLevelB);
223  txVector.SetMode (WifiMode (m_input.txModeB));
225  m_txB->Send (psdu, txVector);
226 }
227 
228 void
229 CollisionExperiment::Receive (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu)
230 {
231  FlowIdTag tag;
232  if ((*psdu->begin ())->GetPacket ()->FindFirstMatchingByteTag (tag))
233  {
234  if (tag.GetFlowId () == m_flowIdA)
235  {
236  m_output.receivedA++;
237  }
238  else if (tag.GetFlowId () == m_flowIdB)
239  {
240  m_output.receivedB++;
241  }
242  }
243 }
244 
246 {
247 }
249  : interval (MicroSeconds (0)),
250  xA (-5),
251  xB (5),
252  txModeA ("OfdmRate6Mbps"),
253  txModeB ("OfdmRate6Mbps"),
254  txPowerLevelA (0),
255  txPowerLevelB (0),
256  packetSizeA (2304),
257  packetSizeB (2304),
258  nPackets (400)
259 {
260 }
261 
263 CollisionExperiment::Run (struct CollisionExperiment::Input input)
264 {
265  m_output.receivedA = 0;
266  m_output.receivedB = 0;
267  m_input = input;
268 
269  m_flowIdA = FlowIdTag::AllocateFlowId ();
270  m_flowIdB = FlowIdTag::AllocateFlowId ();
271 
272  Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel> ();
273  channel->SetPropagationDelayModel (CreateObject<ConstantSpeedPropagationDelayModel> ());
274  Ptr<LogDistancePropagationLossModel> log = CreateObject<LogDistancePropagationLossModel> ();
275  channel->SetPropagationLossModel (log);
276 
277  Ptr<MobilityModel> posTxA = CreateObject<ConstantPositionMobilityModel> ();
278  posTxA->SetPosition (Vector (input.xA, 0.0, 0.0));
279  Ptr<MobilityModel> posTxB = CreateObject<ConstantPositionMobilityModel> ();
280  posTxB->SetPosition (Vector (input.xB, 0.0, 0.0));
281  Ptr<MobilityModel> posRx = CreateObject<ConstantPositionMobilityModel> ();
282  posRx->SetPosition (Vector (0, 0.0, 0.0));
283 
284  Ptr<YansWifiPhy> txA = CreateObject<YansWifiPhy> ();
285  Ptr<YansWifiPhy> txB = CreateObject<YansWifiPhy> ();
286  Ptr<YansWifiPhy> rx = CreateObject<YansWifiPhy> ();
287 
288  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
289  txA->SetErrorRateModel (error);
290  txB->SetErrorRateModel (error);
291  rx->SetErrorRateModel (error);
292  txA->SetChannel (channel);
293  txB->SetChannel (channel);
294  rx->SetChannel (channel);
295  txA->SetMobility (posTxA);
296  txB->SetMobility (posTxB);
297  rx->SetMobility (posRx);
298 
300  txB->ConfigureStandard (WIFI_PHY_STANDARD_80211a);
301  rx->ConfigureStandard (WIFI_PHY_STANDARD_80211a);
302 
303  rx->SetReceiveOkCallback (MakeCallback (&CollisionExperiment::Receive, this));
304 
305  for (uint32_t i = 0; i < m_input.nPackets; ++i)
306  {
307  Simulator::Schedule (Seconds (i), &CollisionExperiment::SendA, this);
308  }
309  for (uint32_t i = 0; i < m_input.nPackets; ++i)
310  {
311  Simulator::Schedule (Seconds (i) + m_input.interval, &CollisionExperiment::SendB, this);
312  }
313  m_txA = txA;
314  m_txB = txB;
315  Simulator::Run ();
316  Simulator::Destroy ();
317  return m_output;
318 }
319 
320 
321 static void PrintPsr (int argc, char *argv[])
322 {
324  struct PsrExperiment::Input input;
325 
327  cmd.AddValue ("Distance", "The distance between two phys", input.distance);
328  cmd.AddValue ("PacketSize", "The size of each packet sent", input.packetSize);
329  cmd.AddValue ("TxMode", "The mode to use to send each packet", input.txMode);
330  cmd.AddValue ("NPackets", "The number of packets to send", input.nPackets);
331  cmd.AddValue ("TxPowerLevel", "The power level index to use to send each packet", input.txPowerLevel);
332  cmd.Parse (argc, argv);
333 
334  struct PsrExperiment::Output output;
335  output = experiment.Run (input);
336 
337  double psr = output.received;
338  psr /= input.nPackets;
339 
340  std::cout << psr << std::endl;
341 }
342 
343 double CalcPsr (struct PsrExperiment::Output output, struct PsrExperiment::Input input)
344 {
345  double psr = output.received;
346  psr /= input.nPackets;
347  return psr;
348 }
349 
350 static void PrintPsrVsDistance (int argc, char *argv[])
351 {
352  struct PsrExperiment::Input input;
354  cmd.AddValue ("TxPowerLevel", "The power level index to use to send each packet", input.txPowerLevel);
355  cmd.AddValue ("TxMode", "The mode to use to send each packet", input.txMode);
356  cmd.AddValue ("NPackets", "The number of packets to send", input.nPackets);
357  cmd.AddValue ("PacketSize", "The size of each packet sent", input.packetSize);
358  cmd.Parse (argc, argv);
359 
360  for (input.distance = 1.0; input.distance < 165; input.distance += 2.0)
361  {
362  std::cout << input.distance;
364  struct PsrExperiment::Output output;
365 
366  input.txMode = "OfdmRate6Mbps";
367  output = experiment.Run (input);
368  std::cout << " " << CalcPsr (output, input);
369 
370  input.txMode = "OfdmRate9Mbps";
371  output = experiment.Run (input);
372  std::cout << " " << CalcPsr (output, input);
373 
374  input.txMode = "OfdmRate12Mbps";
375  output = experiment.Run (input);
376  std::cout << " " << CalcPsr (output, input);
377 
378  input.txMode = "OfdmRate18Mbps";
379  output = experiment.Run (input);
380  std::cout << " " << CalcPsr (output, input);
381 
382  input.txMode = "OfdmRate24Mbps";
383  output = experiment.Run (input);
384  std::cout << " " << CalcPsr (output, input);
385 
386  input.txMode = "OfdmRate36Mbps";
387  output = experiment.Run (input);
388  std::cout << " " << CalcPsr (output, input);
389 
390  input.txMode = "OfdmRate48Mbps";
391  output = experiment.Run (input);
392  std::cout << " " << CalcPsr (output, input);
393 
394  input.txMode = "OfdmRate54Mbps";
395  output = experiment.Run (input);
396  std::cout << " " << CalcPsr (output, input);
397 
398  std::cout << std::endl;
399  }
400 }
401 
402 static void PrintSizeVsRange (int argc, char *argv[])
403 {
404  double targetPsr = 0.05;
405  struct PsrExperiment::Input input;
407  cmd.AddValue ("TxPowerLevel", "The power level index to use to send each packet", input.txPowerLevel);
408  cmd.AddValue ("TxMode", "The mode to use to send each packet", input.txMode);
409  cmd.AddValue ("NPackets", "The number of packets to send", input.nPackets);
410  cmd.AddValue ("TargetPsr", "The psr needed to assume that we are within range", targetPsr);
411  cmd.Parse (argc, argv);
412 
413  for (input.packetSize = 10; input.packetSize < 3000; input.packetSize += 40)
414  {
415  double precision = 0.1;
416  double low = 1.0;
417  double high = 200.0;
418  while (high - low > precision)
419  {
420  double middle = low + (high - low) / 2;
421  struct PsrExperiment::Output output;
423  input.distance = middle;
424  output = experiment.Run (input);
425  double psr = CalcPsr (output, input);
426  if (psr >= targetPsr)
427  {
428  low = middle;
429  }
430  else
431  {
432  high = middle;
433  }
434  }
435  std::cout << input.packetSize << " " << input.distance << std::endl;
436  }
437 }
438 
439 static void PrintPsrVsCollisionInterval (int argc, char *argv[])
440 {
442  input.nPackets = 100;
444  cmd.AddValue ("NPackets", "The number of packets to send for each transmitter", input.nPackets);
445  cmd.AddValue ("xA", "the position of transmitter A", input.xA);
446  cmd.AddValue ("xB", "the position of transmitter B", input.xB);
447  cmd.Parse (argc, argv);
448 
449  for (uint32_t i = 0; i < 100; i += 1)
450  {
453  input.interval = MicroSeconds (i);
454  output = experiment.Run (input);
455  double perA = (output.receivedA + 0.0) / (input.nPackets + 0.0);
456  double perB = (output.receivedB + 0.0) / (input.nPackets + 0.0);
457  std::cout << i << " " << perA << " " << perB << std::endl;
458  }
459  for (uint32_t i = 100; i < 4000; i += 50)
460  {
463  input.interval = MicroSeconds (i);
464  output = experiment.Run (input);
465  double perA = (output.receivedA + 0.0) / (input.nPackets + 0.0);
466  double perB = (output.receivedB + 0.0) / (input.nPackets + 0.0);
467  std::cout << i << " " << perA << " " << perB << std::endl;
468  }
469 }
470 
471 
472 int main (int argc, char *argv[])
473 {
474  if (argc <= 1)
475  {
476  std::cout << "Available experiments: "
477  << "Psr "
478  << "SizeVsRange "
479  << "PsrVsDistance "
480  << "PsrVsCollisionInterval "
481  << std::endl;
482  return 0;
483  }
484  std::string type = argv[1];
485  argc--;
486  argv[1] = argv[0];
487  argv++;
488  if (type == "Psr")
489  {
490  PrintPsr (argc, argv);
491  }
492  else if (type == "SizeVsRange")
493  {
494  PrintSizeVsRange (argc, argv);
495  }
496  else if (type == "PsrVsDistance")
497  {
498  PrintPsrVsDistance (argc, argv);
499  }
500  else if (type == "PsrVsCollisionInterval")
501  {
502  PrintPsrVsCollisionInterval (argc, argv);
503  }
504  else
505  {
506  std::cout << "Wrong arguments!" << std::endl;
507  }
508 
509  return 0;
510 }
Input structure.
Output structure.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
uint32_t packetSizeA
packet size A
uint32_t nPackets
number of packets
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
PsrExperiment.
uint8_t txPowerLevelA
transmit power level A
static const uint32_t packetSize
void SetChannel(const Ptr< YansWifiChannel > channel)
Set the YansWifiChannel this YansWifiPhy is to be connected to.
struct Output m_output
output
uint8_t txPowerLevelB
transmit power level B
uint32_t packetSizeB
packet size B
std::string txMode
transmit mode
void SendB(void) const
Send B function.
struct Output m_output
output
uint32_t nPackets
number of packets
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition: wifi-phy.cc:752
cmd
Definition: second.py:35
uint32_t m_flowIdA
flow ID A
uint32_t receivedA
received A
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:97
void SendA(void) const
Send A function.
channel
Definition: third.py:92
static void PrintPsrVsDistance(int argc, char *argv[])
static void PrintPsrVsCollisionInterval(int argc, char *argv[])
double CalcPsr(struct PsrExperiment::Output output, struct PsrExperiment::Input input)
uint32_t receivedB
received B
Ptr< WifiPhy > m_txA
transmit A
double distance
distance
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1610
uint32_t m_flowIdB
flow ID B
static void PrintPsr(int argc, char *argv[])
Parse command-line arguments.
Definition: command-line.h:212
uint32_t packetSize
packet size
void SetErrorRateModel(const Ptr< ErrorRateModel > rate)
Sets the error rate model.
Definition: wifi-phy.cc:771
OFDM PHY for the 5 GHz band (Clause 17)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void SetPreambleType(WifiPreamble preamble)
Sets the preamble type.
void SetTxPowerLevel(uint8_t powerlevel)
Sets the selected transmission power level.
void Send(void)
Send function.
struct PsrExperiment::Output Run(struct PsrExperiment::Input input)
Run function.
void SetPosition(const Vector &position)
Ptr< WifiPhy > m_txB
transmit B
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
CollisionExperiment.
uint32_t received
received
void experiment(std::string queue_disc_type)
std::string txModeB
transmit mode B
struct Input m_input
input
void Receive(Ptr< WifiPsdu > psdu, double snr, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Receive function.
Introspection did not find any typical Config paths.
Definition: flow-id-tag.h:27
Ptr< WifiPhy > m_tx
transmit
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1070
std::vector< Ptr< WifiMacQueueItem > >::const_iterator begin(void) const
Return a const iterator to the first MPDU.
Definition: wifi-psdu.cc:325
std::string txModeA
transmit mode A
struct CollisionExperiment::Output Run(struct CollisionExperiment::Input input)
Run function.
static void PrintSizeVsRange(int argc, char *argv[])
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1086
uint32_t GetFlowId(void) const
Gets the flow id for the tag.
Definition: flow-id-tag.cc:88
virtual void ConfigureStandard(WifiPhyStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:1252
void Receive(Ptr< WifiPsdu > psdu, double snr, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Send receive function.
uint8_t txPowerLevel
transmit power level
struct Input m_input
input
Implements the IEEE 802.11 MAC header.