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/wifi-net-device.h"
22 #include "ns3/yans-wifi-channel.h"
23 #include "ns3/yans-wifi-phy.h"
24 #include "ns3/propagation-loss-model.h"
25 #include "ns3/propagation-delay-model.h"
26 #include "ns3/error-rate-model.h"
27 #include "ns3/yans-error-rate-model.h"
28 #include "ns3/ptr.h"
29 #include "ns3/mobility-model.h"
30 #include "ns3/constant-position-mobility-model.h"
31 #include "ns3/vector.h"
32 #include "ns3/packet.h"
33 #include "ns3/simulator.h"
34 #include "ns3/nstime.h"
35 #include "ns3/command-line.h"
36 #include "ns3/flow-id-tag.h"
37 #include "ns3/wifi-tx-vector.h"
38 
39 using namespace ns3;
40 
42 {
43 public:
44  struct Input
45  {
46  Input ();
47  double distance;
48  std::string txMode;
49  uint8_t txPowerLevel;
50  uint32_t packetSize;
51  uint32_t nPackets;
52  };
53  struct Output
54  {
55  uint32_t received;
56  };
57  PsrExperiment ();
58 
59  struct PsrExperiment::Output Run (struct PsrExperiment::Input input);
60 
61 private:
62  void Send (void);
63  void Receive (Ptr<Packet> p, double snr, WifiTxVector txVector, enum WifiPreamble preamble);
64  Ptr<WifiPhy> m_tx;
65  struct Input m_input;
66  struct Output m_output;
67 };
68 
69 void
71 {
72  Ptr<Packet> p = Create<Packet> (m_input.packetSize);
73  WifiMode mode = WifiMode (m_input.txMode);
74  WifiTxVector txVector;
75  txVector.SetTxPowerLevel (m_input.txPowerLevel);
76  txVector.SetMode (mode);
77  m_tx->SendPacket (p, txVector, WIFI_PREAMBLE_LONG);
78 }
79 
80 void
81 PsrExperiment::Receive (Ptr<Packet> p, double snr, WifiTxVector txVector, enum WifiPreamble preamble)
82 {
83  m_output.received++;
84 }
85 
87 {
88 }
90  : distance (5.0),
91  txMode ("OfdmRate6Mbps"),
92  txPowerLevel (0),
93  packetSize (2304),
94  nPackets (400)
95 {
96 }
97 
99 PsrExperiment::Run (struct PsrExperiment::Input input)
100 {
101  m_output.received = 0;
102  m_input = input;
103 
104  Ptr<MobilityModel> posTx = CreateObject<ConstantPositionMobilityModel> ();
105  posTx->SetPosition (Vector (0.0, 0.0, 0.0));
106  Ptr<MobilityModel> posRx = CreateObject<ConstantPositionMobilityModel> ();
107  posRx->SetPosition (Vector (m_input.distance, 0.0, 0.0));
108 
109  Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel> ();
110  channel->SetPropagationDelayModel (CreateObject<ConstantSpeedPropagationDelayModel> ());
111  Ptr<LogDistancePropagationLossModel> log = CreateObject<LogDistancePropagationLossModel> ();
112  channel->SetPropagationLossModel (log);
113 
114  Ptr<YansWifiPhy> tx = CreateObject<YansWifiPhy> ();
115  Ptr<YansWifiPhy> rx = CreateObject<YansWifiPhy> ();
116  Ptr<ErrorRateModel> error = CreateObject<YansErrorRateModel> ();
117  tx->SetErrorRateModel (error);
118  rx->SetErrorRateModel (error);
119  tx->SetChannel (channel);
120  rx->SetChannel (channel);
121  tx->SetMobility (posTx);
122  rx->SetMobility (posRx);
123 
125  rx->ConfigureStandard (WIFI_PHY_STANDARD_80211a);
126 
127  rx->SetReceiveOkCallback (MakeCallback (&PsrExperiment::Receive, this));
128 
129  for (uint32_t i = 0; i < m_input.nPackets; ++i)
130  {
131  Simulator::Schedule (Seconds (i), &PsrExperiment::Send, this);
132  }
133  m_tx = tx;
134  Simulator::Run ();
135  Simulator::Destroy ();
136  return m_output;
137 }
138 
139 
141 {
142 public:
143  struct Input
144  {
145  Input ();
147  double xA;
148  double xB;
149  std::string txModeA;
150  std::string txModeB;
151  uint8_t txPowerLevelA;
152  uint8_t txPowerLevelB;
153  uint32_t packetSizeA;
154  uint32_t packetSizeB;
155  uint32_t nPackets;
156  };
157  struct Output
158  {
159  uint32_t receivedA;
160  uint32_t receivedB;
161  };
163 
165 private:
166  void SendA (void) const;
167  void SendB (void) const;
168  void Receive (Ptr<Packet> p, double snr, WifiTxVector txVector, enum WifiPreamble preamble);
169  Ptr<WifiPhy> m_txA;
170  Ptr<WifiPhy> m_txB;
171  uint32_t m_flowIdA;
172  uint32_t m_flowIdB;
173  struct Input m_input;
174  struct Output m_output;
175 };
176 
177 void
179 {
180  Ptr<Packet> p = Create<Packet> (m_input.packetSizeA);
181  p->AddByteTag (FlowIdTag (m_flowIdA));
182  WifiTxVector txVector;
183  txVector.SetTxPowerLevel (m_input.txPowerLevelA);
184  txVector.SetMode (WifiMode (m_input.txModeA));
185  m_txA->SendPacket (p, txVector, WIFI_PREAMBLE_LONG);
186 }
187 
188 void
190 {
191  Ptr<Packet> p = Create<Packet> (m_input.packetSizeB);
192  p->AddByteTag (FlowIdTag (m_flowIdB));
193  WifiTxVector txVector;
194  txVector.SetTxPowerLevel (m_input.txPowerLevelB);
195  txVector.SetMode (WifiMode (m_input.txModeB));
196  m_txB->SendPacket (p, txVector, WIFI_PREAMBLE_LONG);
197 }
198 
199 void
200 CollisionExperiment::Receive (Ptr<Packet> p, double snr, WifiTxVector txVector, enum WifiPreamble preamble)
201 {
202  FlowIdTag tag;
203  if (p->FindFirstMatchingByteTag (tag))
204  {
205  if (tag.GetFlowId () == m_flowIdA)
206  {
207  m_output.receivedA++;
208  }
209  else if (tag.GetFlowId () == m_flowIdB)
210  {
211  m_output.receivedB++;
212  }
213  }
214 }
215 
217 {
218 }
220  : interval (MicroSeconds (0)),
221  xA (-5),
222  xB (5),
223  txModeA ("OfdmRate6Mbps"),
224  txModeB ("OfdmRate6Mbps"),
225  txPowerLevelA (0),
226  txPowerLevelB (0),
227  packetSizeA (2304),
228  packetSizeB (2304),
229  nPackets (400)
230 {
231 }
232 
234 CollisionExperiment::Run (struct CollisionExperiment::Input input)
235 {
236  m_output.receivedA = 0;
237  m_output.receivedB = 0;
238  m_input = input;
239 
240  m_flowIdA = FlowIdTag::AllocateFlowId ();
241  m_flowIdB = FlowIdTag::AllocateFlowId ();
242 
243  Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel> ();
244  channel->SetPropagationDelayModel (CreateObject<ConstantSpeedPropagationDelayModel> ());
245  Ptr<LogDistancePropagationLossModel> log = CreateObject<LogDistancePropagationLossModel> ();
246  channel->SetPropagationLossModel (log);
247 
248  Ptr<MobilityModel> posTxA = CreateObject<ConstantPositionMobilityModel> ();
249  posTxA->SetPosition (Vector (input.xA, 0.0, 0.0));
250  Ptr<MobilityModel> posTxB = CreateObject<ConstantPositionMobilityModel> ();
251  posTxB->SetPosition (Vector (input.xB, 0.0, 0.0));
252  Ptr<MobilityModel> posRx = CreateObject<ConstantPositionMobilityModel> ();
253  posRx->SetPosition (Vector (0, 0.0, 0.0));
254 
255  Ptr<YansWifiPhy> txA = CreateObject<YansWifiPhy> ();
256  Ptr<YansWifiPhy> txB = CreateObject<YansWifiPhy> ();
257  Ptr<YansWifiPhy> rx = CreateObject<YansWifiPhy> ();
258 
259  Ptr<ErrorRateModel> error = CreateObject<YansErrorRateModel> ();
260  txA->SetErrorRateModel (error);
261  txB->SetErrorRateModel (error);
262  rx->SetErrorRateModel (error);
263  txA->SetChannel (channel);
264  txB->SetChannel (channel);
265  rx->SetChannel (channel);
266  txA->SetMobility (posTxA);
267  txB->SetMobility (posTxB);
268  rx->SetMobility (posRx);
269 
271  txB->ConfigureStandard (WIFI_PHY_STANDARD_80211a);
272  rx->ConfigureStandard (WIFI_PHY_STANDARD_80211a);
273 
274  rx->SetReceiveOkCallback (MakeCallback (&CollisionExperiment::Receive, this));
275 
276  for (uint32_t i = 0; i < m_input.nPackets; ++i)
277  {
278  Simulator::Schedule (Seconds (i), &CollisionExperiment::SendA, this);
279  }
280  for (uint32_t i = 0; i < m_input.nPackets; ++i)
281  {
282  Simulator::Schedule (Seconds (i) + m_input.interval, &CollisionExperiment::SendB, this);
283  }
284  m_txA = txA;
285  m_txB = txB;
286  Simulator::Run ();
287  Simulator::Destroy ();
288  return m_output;
289 }
290 
291 
292 static void PrintPsr (int argc, char *argv[])
293 {
295  struct PsrExperiment::Input input;
296 
298  cmd.AddValue ("Distance", "The distance between two phys", input.distance);
299  cmd.AddValue ("PacketSize", "The size of each packet sent", input.packetSize);
300  cmd.AddValue ("TxMode", "The mode to use to send each packet", input.txMode);
301  cmd.AddValue ("NPackets", "The number of packets to send", input.nPackets);
302  cmd.AddValue ("TxPowerLevel", "The power level index to use to send each packet", input.txPowerLevel);
303  cmd.Parse (argc, argv);
304 
305  struct PsrExperiment::Output output;
306  output = experiment.Run (input);
307 
308  double psr = output.received;
309  psr /= input.nPackets;
310 
311  std::cout << psr << std::endl;
312 }
313 
314 double CalcPsr (struct PsrExperiment::Output output, struct PsrExperiment::Input input)
315 {
316  double psr = output.received;
317  psr /= input.nPackets;
318  return psr;
319 }
320 
321 static void PrintPsrVsDistance (int argc, char *argv[])
322 {
323  struct PsrExperiment::Input input;
325  cmd.AddValue ("TxPowerLevel", "The power level index to use to send each packet", input.txPowerLevel);
326  cmd.AddValue ("TxMode", "The mode to use to send each packet", input.txMode);
327  cmd.AddValue ("NPackets", "The number of packets to send", input.nPackets);
328  cmd.AddValue ("PacketSize", "The size of each packet sent", input.packetSize);
329  cmd.Parse (argc, argv);
330 
331  for (input.distance = 1.0; input.distance < 165; input.distance += 2.0)
332  {
333  std::cout << input.distance;
335  struct PsrExperiment::Output output;
336 
337  input.txMode = "OfdmRate6Mbps";
338  output = experiment.Run (input);
339  std::cout << " " << CalcPsr (output, input);
340 
341  input.txMode = "OfdmRate9Mbps";
342  output = experiment.Run (input);
343  std::cout << " " << CalcPsr (output, input);
344 
345  input.txMode = "OfdmRate12Mbps";
346  output = experiment.Run (input);
347  std::cout << " " << CalcPsr (output, input);
348 
349  input.txMode = "OfdmRate18Mbps";
350  output = experiment.Run (input);
351  std::cout << " " << CalcPsr (output, input);
352 
353  input.txMode = "OfdmRate24Mbps";
354  output = experiment.Run (input);
355  std::cout << " " << CalcPsr (output, input);
356 
357  input.txMode = "OfdmRate36Mbps";
358  output = experiment.Run (input);
359  std::cout << " " << CalcPsr (output, input);
360 
361  input.txMode = "OfdmRate48Mbps";
362  output = experiment.Run (input);
363  std::cout << " " << CalcPsr (output, input);
364 
365  input.txMode = "OfdmRate54Mbps";
366  output = experiment.Run (input);
367  std::cout << " " << CalcPsr (output, input);
368 
369  std::cout << std::endl;
370  }
371 }
372 
373 static void PrintSizeVsRange (int argc, char *argv[])
374 {
375  double targetPsr = 0.05;
376  struct PsrExperiment::Input input;
378  cmd.AddValue ("TxPowerLevel", "The power level index to use to send each packet", input.txPowerLevel);
379  cmd.AddValue ("TxMode", "The mode to use to send each packet", input.txMode);
380  cmd.AddValue ("NPackets", "The number of packets to send", input.nPackets);
381  cmd.AddValue ("TargetPsr", "The psr needed to assume that we are within range", targetPsr);
382  cmd.Parse (argc, argv);
383 
384  for (input.packetSize = 10; input.packetSize < 3000; input.packetSize += 40)
385  {
386  double precision = 0.1;
387  double low = 1.0;
388  double high = 200.0;
389  while (high - low > precision)
390  {
391  double middle = low + (high - low) / 2;
392  struct PsrExperiment::Output output;
394  input.distance = middle;
395  output = experiment.Run (input);
396  double psr = CalcPsr (output, input);
397  if (psr >= targetPsr)
398  {
399  low = middle;
400  }
401  else
402  {
403  high = middle;
404  }
405  }
406  std::cout << input.packetSize << " " << input.distance << std::endl;
407  }
408 }
409 
410 static void PrintPsrVsCollisionInterval (int argc, char *argv[])
411 {
413  input.nPackets = 100;
415  cmd.AddValue ("NPackets", "The number of packets to send for each transmitter", input.nPackets);
416  cmd.AddValue ("xA", "the position of transmitter A", input.xA);
417  cmd.AddValue ("xB", "the position of transmitter B", input.xB);
418  cmd.Parse (argc, argv);
419 
420  for (uint32_t i = 0; i < 100; i += 1)
421  {
424  input.interval = MicroSeconds (i);
425  output = experiment.Run (input);
426  double perA = (output.receivedA + 0.0) / (input.nPackets + 0.0);
427  double perB = (output.receivedB + 0.0) / (input.nPackets + 0.0);
428  std::cout << i << " " << perA << " " << perB << std::endl;
429  }
430  for (uint32_t i = 100; i < 4000; i += 50)
431  {
434  input.interval = MicroSeconds (i);
435  output = experiment.Run (input);
436  double perA = (output.receivedA + 0.0) / (input.nPackets + 0.0);
437  double perB = (output.receivedB + 0.0) / (input.nPackets + 0.0);
438  std::cout << i << " " << perA << " " << perB << std::endl;
439  }
440 }
441 
442 
443 int main (int argc, char *argv[])
444 {
445  if (argc <= 1)
446  {
447  std::cout << "Available experiments: "
448  << "Psr "
449  << "SizeVsRange "
450  << "PsrVsDistance "
451  << "PsrVsCollisionInterval "
452  << std::endl;
453  return 0;
454  }
455  std::string type = argv[1];
456  argc--;
457  argv[1] = argv[0];
458  argv++;
459  if (type == "Psr")
460  {
461  PrintPsr (argc, argv);
462  }
463  else if (type == "SizeVsRange")
464  {
465  PrintSizeVsRange (argc, argv);
466  }
467  else if (type == "PsrVsDistance")
468  {
469  PrintPsrVsDistance (argc, argv);
470  }
471  else if (type == "PsrVsCollisionInterval")
472  {
473  PrintPsrVsCollisionInterval (argc, argv);
474  }
475  else
476  {
477  std::cout << "Wrong arguments!" << std::endl;
478  }
479 
480  return 0;
481 }
tuple channel
Definition: third.py:85
bool FindFirstMatchingByteTag(Tag &tag) const
Finds the first tag matching the parameter Tag type.
Definition: packet.cc:807
void experiment(bool enableCtsRts)
Run single 10 seconds experiment with enabled or disabled RTS/CTS mechanism.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
struct Output m_output
void SetPropagationLossModel(Ptr< PropagationLossModel > loss)
void SetPropagationDelayModel(Ptr< PropagationDelayModel > delay)
struct Output m_output
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:99
tuple cmd
Definition: second.py:35
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
Definition: wifi-preamble.h:30
void Receive(Ptr< Packet > p, double snr, WifiTxVector txVector, enum WifiPreamble preamble)
static void PrintPsrVsDistance(int argc, char *argv[])
static void PrintPsrVsCollisionInterval(int argc, char *argv[])
double CalcPsr(struct PsrExperiment::Output output, struct PsrExperiment::Input input)
Ptr< WifiPhy > m_txA
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
static void PrintPsr(int argc, char *argv[])
void SendA(void) const
Parse command-line arguments.
Definition: command-line.h:205
void SetChannel(Ptr< YansWifiChannel > channel)
Set the YansWifiChannel this YansWifiPhy is to be connected to.
OFDM PHY for the 5 GHz band (Clause 17)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void SetMobility(Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition: wifi-phy.cc:610
void SetTxPowerLevel(uint8_t powerlevel)
Sets the selected transmission power level.
void Send(void)
struct PsrExperiment::Output Run(struct PsrExperiment::Input input)
void SetPosition(const Vector &position)
Ptr< WifiPhy > m_txB
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
virtual void ConfigureStandard(enum WifiPhyStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:1026
void Receive(Ptr< Packet > p, double snr, WifiTxVector txVector, enum WifiPreamble preamble)
void AddValue(const std::string &name, const std::string &help, T &value)
Add a program argument, assigning to POD.
Definition: command-line.h:495
struct Input m_input
Introspection did not find any typical Config paths.
Definition: flow-id-tag.h:27
Ptr< WifiPhy > m_tx
void SendB(void) const
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:895
struct CollisionExperiment::Output Run(struct CollisionExperiment::Input input)
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:911
static const uint32_t packetSize
struct Input m_input
void SetErrorRateModel(Ptr< ErrorRateModel > rate)
Sets the error rate model.
Definition: wifi-phy.cc:629
void AddByteTag(const Tag &tag) const
Tag each byte included in this packet with a new byte tag.
Definition: packet.cc:791