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/yans-wifi-channel.h"
22 #include "ns3/propagation-loss-model.h"
23 #include "ns3/propagation-delay-model.h"
24 #include "ns3/nist-error-rate-model.h"
25 #include "ns3/constant-position-mobility-model.h"
26 #include "ns3/simulator.h"
27 #include "ns3/command-line.h"
28 #include "ns3/flow-id-tag.h"
29 
30 using namespace ns3;
31 
34 {
35 public:
37  struct Input
38  {
39  Input ();
40  double distance;
41  std::string txMode;
42  uint8_t txPowerLevel;
43  uint32_t packetSize;
44  uint32_t nPackets;
45  };
47  struct Output
48  {
49  uint32_t received;
50  };
51  PsrExperiment ();
52 
58  struct PsrExperiment::Output Run (struct PsrExperiment::Input input);
59 
60 private:
62  void Send (void);
69  void Receive (Ptr<Packet> p, double snr, WifiTxVector txVector);
70  Ptr<WifiPhy> m_tx;
71  struct Input m_input;
72  struct Output m_output;
73 };
74 
75 void
77 {
78  Ptr<Packet> p = Create<Packet> (m_input.packetSize);
79  WifiMode mode = WifiMode (m_input.txMode);
80  WifiTxVector txVector;
81  txVector.SetTxPowerLevel (m_input.txPowerLevel);
82  txVector.SetMode (mode);
84  m_tx->SendPacket (p, txVector);
85 }
86 
87 void
89 {
90  m_output.received++;
91 }
92 
94 {
95 }
97  : distance (5.0),
98  txMode ("OfdmRate6Mbps"),
99  txPowerLevel (0),
100  packetSize (2304),
101  nPackets (400)
102 {
103 }
104 
106 PsrExperiment::Run (struct PsrExperiment::Input input)
107 {
108  m_output.received = 0;
109  m_input = input;
110 
111  Ptr<MobilityModel> posTx = CreateObject<ConstantPositionMobilityModel> ();
112  posTx->SetPosition (Vector (0.0, 0.0, 0.0));
113  Ptr<MobilityModel> posRx = CreateObject<ConstantPositionMobilityModel> ();
114  posRx->SetPosition (Vector (m_input.distance, 0.0, 0.0));
115 
116  Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel> ();
117  channel->SetPropagationDelayModel (CreateObject<ConstantSpeedPropagationDelayModel> ());
118  Ptr<LogDistancePropagationLossModel> log = CreateObject<LogDistancePropagationLossModel> ();
119  channel->SetPropagationLossModel (log);
120 
121  Ptr<YansWifiPhy> tx = CreateObject<YansWifiPhy> ();
122  Ptr<YansWifiPhy> rx = CreateObject<YansWifiPhy> ();
123  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
124  tx->SetErrorRateModel (error);
125  rx->SetErrorRateModel (error);
126  tx->SetChannel (channel);
127  rx->SetChannel (channel);
128  tx->SetMobility (posTx);
129  rx->SetMobility (posRx);
130 
132  rx->ConfigureStandard (WIFI_PHY_STANDARD_80211a);
133 
134  rx->SetReceiveOkCallback (MakeCallback (&PsrExperiment::Receive, this));
135 
136  for (uint32_t i = 0; i < m_input.nPackets; ++i)
137  {
138  Simulator::Schedule (Seconds (i), &PsrExperiment::Send, this);
139  }
140  m_tx = tx;
141  Simulator::Run ();
142  Simulator::Destroy ();
143  return m_output;
144 }
145 
148 {
149 public:
151  struct Input
152  {
153  Input ();
155  double xA;
156  double xB;
157  std::string txModeA;
158  std::string txModeB;
159  uint8_t txPowerLevelA;
160  uint8_t txPowerLevelB;
161  uint32_t packetSizeA;
162  uint32_t packetSizeB;
163  uint32_t nPackets;
164  };
166  struct Output
167  {
168  uint32_t receivedA;
169  uint32_t receivedB;
170  };
172 
179 private:
181  void SendA (void) const;
183  void SendB (void) const;
190  void Receive (Ptr<Packet> p, double snr, WifiTxVector txVector);
191  Ptr<WifiPhy> m_txA;
192  Ptr<WifiPhy> m_txB;
193  uint32_t m_flowIdA;
194  uint32_t m_flowIdB;
195  struct Input m_input;
196  struct Output m_output;
197 };
198 
199 void
201 {
202  Ptr<Packet> p = Create<Packet> (m_input.packetSizeA);
203  p->AddByteTag (FlowIdTag (m_flowIdA));
204  WifiTxVector txVector;
205  txVector.SetTxPowerLevel (m_input.txPowerLevelA);
206  txVector.SetMode (WifiMode (m_input.txModeA));
208  m_txA->SendPacket (p, txVector);
209 }
210 
211 void
213 {
214  Ptr<Packet> p = Create<Packet> (m_input.packetSizeB);
215  p->AddByteTag (FlowIdTag (m_flowIdB));
216  WifiTxVector txVector;
217  txVector.SetTxPowerLevel (m_input.txPowerLevelB);
218  txVector.SetMode (WifiMode (m_input.txModeB));
220  m_txB->SendPacket (p, txVector);
221 }
222 
223 void
225 {
226  FlowIdTag tag;
227  if (p->FindFirstMatchingByteTag (tag))
228  {
229  if (tag.GetFlowId () == m_flowIdA)
230  {
231  m_output.receivedA++;
232  }
233  else if (tag.GetFlowId () == m_flowIdB)
234  {
235  m_output.receivedB++;
236  }
237  }
238 }
239 
241 {
242 }
244  : interval (MicroSeconds (0)),
245  xA (-5),
246  xB (5),
247  txModeA ("OfdmRate6Mbps"),
248  txModeB ("OfdmRate6Mbps"),
249  txPowerLevelA (0),
250  txPowerLevelB (0),
251  packetSizeA (2304),
252  packetSizeB (2304),
253  nPackets (400)
254 {
255 }
256 
258 CollisionExperiment::Run (struct CollisionExperiment::Input input)
259 {
260  m_output.receivedA = 0;
261  m_output.receivedB = 0;
262  m_input = input;
263 
264  m_flowIdA = FlowIdTag::AllocateFlowId ();
265  m_flowIdB = FlowIdTag::AllocateFlowId ();
266 
267  Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel> ();
268  channel->SetPropagationDelayModel (CreateObject<ConstantSpeedPropagationDelayModel> ());
269  Ptr<LogDistancePropagationLossModel> log = CreateObject<LogDistancePropagationLossModel> ();
270  channel->SetPropagationLossModel (log);
271 
272  Ptr<MobilityModel> posTxA = CreateObject<ConstantPositionMobilityModel> ();
273  posTxA->SetPosition (Vector (input.xA, 0.0, 0.0));
274  Ptr<MobilityModel> posTxB = CreateObject<ConstantPositionMobilityModel> ();
275  posTxB->SetPosition (Vector (input.xB, 0.0, 0.0));
276  Ptr<MobilityModel> posRx = CreateObject<ConstantPositionMobilityModel> ();
277  posRx->SetPosition (Vector (0, 0.0, 0.0));
278 
279  Ptr<YansWifiPhy> txA = CreateObject<YansWifiPhy> ();
280  Ptr<YansWifiPhy> txB = CreateObject<YansWifiPhy> ();
281  Ptr<YansWifiPhy> rx = CreateObject<YansWifiPhy> ();
282 
283  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
284  txA->SetErrorRateModel (error);
285  txB->SetErrorRateModel (error);
286  rx->SetErrorRateModel (error);
287  txA->SetChannel (channel);
288  txB->SetChannel (channel);
289  rx->SetChannel (channel);
290  txA->SetMobility (posTxA);
291  txB->SetMobility (posTxB);
292  rx->SetMobility (posRx);
293 
295  txB->ConfigureStandard (WIFI_PHY_STANDARD_80211a);
296  rx->ConfigureStandard (WIFI_PHY_STANDARD_80211a);
297 
298  rx->SetReceiveOkCallback (MakeCallback (&CollisionExperiment::Receive, this));
299 
300  for (uint32_t i = 0; i < m_input.nPackets; ++i)
301  {
302  Simulator::Schedule (Seconds (i), &CollisionExperiment::SendA, this);
303  }
304  for (uint32_t i = 0; i < m_input.nPackets; ++i)
305  {
306  Simulator::Schedule (Seconds (i) + m_input.interval, &CollisionExperiment::SendB, this);
307  }
308  m_txA = txA;
309  m_txB = txB;
310  Simulator::Run ();
311  Simulator::Destroy ();
312  return m_output;
313 }
314 
315 
316 static void PrintPsr (int argc, char *argv[])
317 {
319  struct PsrExperiment::Input input;
320 
322  cmd.AddValue ("Distance", "The distance between two phys", input.distance);
323  cmd.AddValue ("PacketSize", "The size of each packet sent", input.packetSize);
324  cmd.AddValue ("TxMode", "The mode to use to send each packet", input.txMode);
325  cmd.AddValue ("NPackets", "The number of packets to send", input.nPackets);
326  cmd.AddValue ("TxPowerLevel", "The power level index to use to send each packet", input.txPowerLevel);
327  cmd.Parse (argc, argv);
328 
329  struct PsrExperiment::Output output;
330  output = experiment.Run (input);
331 
332  double psr = output.received;
333  psr /= input.nPackets;
334 
335  std::cout << psr << std::endl;
336 }
337 
338 double CalcPsr (struct PsrExperiment::Output output, struct PsrExperiment::Input input)
339 {
340  double psr = output.received;
341  psr /= input.nPackets;
342  return psr;
343 }
344 
345 static void PrintPsrVsDistance (int argc, char *argv[])
346 {
347  struct PsrExperiment::Input input;
349  cmd.AddValue ("TxPowerLevel", "The power level index to use to send each packet", input.txPowerLevel);
350  cmd.AddValue ("TxMode", "The mode to use to send each packet", input.txMode);
351  cmd.AddValue ("NPackets", "The number of packets to send", input.nPackets);
352  cmd.AddValue ("PacketSize", "The size of each packet sent", input.packetSize);
353  cmd.Parse (argc, argv);
354 
355  for (input.distance = 1.0; input.distance < 165; input.distance += 2.0)
356  {
357  std::cout << input.distance;
359  struct PsrExperiment::Output output;
360 
361  input.txMode = "OfdmRate6Mbps";
362  output = experiment.Run (input);
363  std::cout << " " << CalcPsr (output, input);
364 
365  input.txMode = "OfdmRate9Mbps";
366  output = experiment.Run (input);
367  std::cout << " " << CalcPsr (output, input);
368 
369  input.txMode = "OfdmRate12Mbps";
370  output = experiment.Run (input);
371  std::cout << " " << CalcPsr (output, input);
372 
373  input.txMode = "OfdmRate18Mbps";
374  output = experiment.Run (input);
375  std::cout << " " << CalcPsr (output, input);
376 
377  input.txMode = "OfdmRate24Mbps";
378  output = experiment.Run (input);
379  std::cout << " " << CalcPsr (output, input);
380 
381  input.txMode = "OfdmRate36Mbps";
382  output = experiment.Run (input);
383  std::cout << " " << CalcPsr (output, input);
384 
385  input.txMode = "OfdmRate48Mbps";
386  output = experiment.Run (input);
387  std::cout << " " << CalcPsr (output, input);
388 
389  input.txMode = "OfdmRate54Mbps";
390  output = experiment.Run (input);
391  std::cout << " " << CalcPsr (output, input);
392 
393  std::cout << std::endl;
394  }
395 }
396 
397 static void PrintSizeVsRange (int argc, char *argv[])
398 {
399  double targetPsr = 0.05;
400  struct PsrExperiment::Input input;
402  cmd.AddValue ("TxPowerLevel", "The power level index to use to send each packet", input.txPowerLevel);
403  cmd.AddValue ("TxMode", "The mode to use to send each packet", input.txMode);
404  cmd.AddValue ("NPackets", "The number of packets to send", input.nPackets);
405  cmd.AddValue ("TargetPsr", "The psr needed to assume that we are within range", targetPsr);
406  cmd.Parse (argc, argv);
407 
408  for (input.packetSize = 10; input.packetSize < 3000; input.packetSize += 40)
409  {
410  double precision = 0.1;
411  double low = 1.0;
412  double high = 200.0;
413  while (high - low > precision)
414  {
415  double middle = low + (high - low) / 2;
416  struct PsrExperiment::Output output;
418  input.distance = middle;
419  output = experiment.Run (input);
420  double psr = CalcPsr (output, input);
421  if (psr >= targetPsr)
422  {
423  low = middle;
424  }
425  else
426  {
427  high = middle;
428  }
429  }
430  std::cout << input.packetSize << " " << input.distance << std::endl;
431  }
432 }
433 
434 static void PrintPsrVsCollisionInterval (int argc, char *argv[])
435 {
437  input.nPackets = 100;
439  cmd.AddValue ("NPackets", "The number of packets to send for each transmitter", input.nPackets);
440  cmd.AddValue ("xA", "the position of transmitter A", input.xA);
441  cmd.AddValue ("xB", "the position of transmitter B", input.xB);
442  cmd.Parse (argc, argv);
443 
444  for (uint32_t i = 0; i < 100; i += 1)
445  {
448  input.interval = MicroSeconds (i);
449  output = experiment.Run (input);
450  double perA = (output.receivedA + 0.0) / (input.nPackets + 0.0);
451  double perB = (output.receivedB + 0.0) / (input.nPackets + 0.0);
452  std::cout << i << " " << perA << " " << perB << std::endl;
453  }
454  for (uint32_t i = 100; i < 4000; i += 50)
455  {
458  input.interval = MicroSeconds (i);
459  output = experiment.Run (input);
460  double perA = (output.receivedA + 0.0) / (input.nPackets + 0.0);
461  double perB = (output.receivedB + 0.0) / (input.nPackets + 0.0);
462  std::cout << i << " " << perA << " " << perB << std::endl;
463  }
464 }
465 
466 
467 int main (int argc, char *argv[])
468 {
469  if (argc <= 1)
470  {
471  std::cout << "Available experiments: "
472  << "Psr "
473  << "SizeVsRange "
474  << "PsrVsDistance "
475  << "PsrVsCollisionInterval "
476  << std::endl;
477  return 0;
478  }
479  std::string type = argv[1];
480  argc--;
481  argv[1] = argv[0];
482  argv++;
483  if (type == "Psr")
484  {
485  PrintPsr (argc, argv);
486  }
487  else if (type == "SizeVsRange")
488  {
489  PrintSizeVsRange (argc, argv);
490  }
491  else if (type == "PsrVsDistance")
492  {
493  PrintPsrVsDistance (argc, argv);
494  }
495  else if (type == "PsrVsCollisionInterval")
496  {
497  PrintPsrVsCollisionInterval (argc, argv);
498  }
499  else
500  {
501  std::cout << "Wrong arguments!" << std::endl;
502  }
503 
504  return 0;
505 }
Input structure.
tuple channel
Definition: third.py:85
bool FindFirstMatchingByteTag(Tag &tag) const
Finds the first tag matching the parameter Tag type.
Definition: packet.cc:797
void experiment(bool enableCtsRts)
Run single 10 seconds experiment with enabled or disabled RTS/CTS mechanism.
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
void SetPropagationLossModel(const Ptr< PropagationLossModel > loss)
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
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 Receive(Ptr< Packet > p, double snr, WifiTxVector txVector)
Receive 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:682
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
tuple cmd
Definition: second.py:35
static void PrintPsrVsDistance(int argc, char *argv[])
void SetPropagationDelayModel(const Ptr< PropagationDelayModel > delay)
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:1489
uint32_t GetFlowId(void) const
Gets the flow id for the tag.
Definition: flow-id-tag.cc:88
uint32_t m_flowIdB
flow ID B
static void PrintPsr(int argc, char *argv[])
void SendA(void) const
Send A function.
Parse command-line arguments.
Definition: command-line.h:205
uint32_t packetSize
packet size
void Receive(Ptr< Packet > p, double snr, WifiTxVector txVector)
Send receive function.
void SetErrorRateModel(const Ptr< ErrorRateModel > rate)
Sets the error rate model.
Definition: wifi-phy.cc:701
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 AddValue(const std::string &name, const std::string &help, T &value)
Add a program argument, assigning to POD.
Definition: command-line.h:498
std::string txModeB
transmit mode B
struct Input m_input
input
Introspection did not find any typical Config paths.
Definition: flow-id-tag.h:27
Ptr< WifiPhy > m_tx
transmit
void SendB(void) const
Send B function.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:993
std::string txModeA
transmit mode A
struct CollisionExperiment::Output Run(struct CollisionExperiment::Input input)
Run function.
static void PrintSizeVsRange(int argc, char *argv[])
void Parse(int argc, char *argv[])
Parse the program arguments.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1009
static const uint32_t packetSize
virtual void ConfigureStandard(WifiPhyStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:1147
uint8_t txPowerLevel
transmit power level
struct Input m_input
input
void AddByteTag(const Tag &tag) const
Tag each byte included in this packet with a new byte tag.
Definition: packet.cc:781