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 
32 using namespace ns3;
33 
36 {
37 public:
39  struct Input
40  {
41  Input ();
42  double distance;
43  std::string txMode;
44  uint8_t txPowerLevel;
45  uint32_t packetSize;
46  uint32_t nPackets;
47  };
49  struct Output
50  {
51  uint32_t received;
52  };
53  PsrExperiment ();
54 
60  struct PsrExperiment::Output Run (struct PsrExperiment::Input input);
61 
62 private:
64  void Send (void);
71  void Receive (Ptr<Packet> p, double snr, WifiTxVector txVector);
72  Ptr<WifiPhy> m_tx;
73  struct Input m_input;
74  struct Output m_output;
75 };
76 
77 void
79 {
80  Ptr<Packet> p = Create<Packet> (m_input.packetSize);
81  WifiMode mode = WifiMode (m_input.txMode);
82  WifiTxVector txVector;
83  txVector.SetTxPowerLevel (m_input.txPowerLevel);
84  txVector.SetMode (mode);
86  m_tx->SendPacket (p, txVector);
87 }
88 
89 void
91 {
92  m_output.received++;
93 }
94 
96 {
97 }
99  : distance (5.0),
100  txMode ("OfdmRate6Mbps"),
101  txPowerLevel (0),
102  packetSize (2304),
103  nPackets (400)
104 {
105 }
106 
108 PsrExperiment::Run (struct PsrExperiment::Input input)
109 {
110  m_output.received = 0;
111  m_input = input;
112 
113  Ptr<MobilityModel> posTx = CreateObject<ConstantPositionMobilityModel> ();
114  posTx->SetPosition (Vector (0.0, 0.0, 0.0));
115  Ptr<MobilityModel> posRx = CreateObject<ConstantPositionMobilityModel> ();
116  posRx->SetPosition (Vector (m_input.distance, 0.0, 0.0));
117 
118  Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel> ();
119  channel->SetPropagationDelayModel (CreateObject<ConstantSpeedPropagationDelayModel> ());
120  Ptr<LogDistancePropagationLossModel> log = CreateObject<LogDistancePropagationLossModel> ();
121  channel->SetPropagationLossModel (log);
122 
123  Ptr<YansWifiPhy> tx = CreateObject<YansWifiPhy> ();
124  Ptr<YansWifiPhy> rx = CreateObject<YansWifiPhy> ();
125  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
126  tx->SetErrorRateModel (error);
127  rx->SetErrorRateModel (error);
128  tx->SetChannel (channel);
129  rx->SetChannel (channel);
130  tx->SetMobility (posTx);
131  rx->SetMobility (posRx);
132 
134  rx->ConfigureStandard (WIFI_PHY_STANDARD_80211a);
135 
136  rx->SetReceiveOkCallback (MakeCallback (&PsrExperiment::Receive, this));
137 
138  for (uint32_t i = 0; i < m_input.nPackets; ++i)
139  {
140  Simulator::Schedule (Seconds (i), &PsrExperiment::Send, this);
141  }
142  m_tx = tx;
143  Simulator::Run ();
144  Simulator::Destroy ();
145  return m_output;
146 }
147 
150 {
151 public:
153  struct Input
154  {
155  Input ();
157  double xA;
158  double xB;
159  std::string txModeA;
160  std::string txModeB;
161  uint8_t txPowerLevelA;
162  uint8_t txPowerLevelB;
163  uint32_t packetSizeA;
164  uint32_t packetSizeB;
165  uint32_t nPackets;
166  };
168  struct Output
169  {
170  uint32_t receivedA;
171  uint32_t receivedB;
172  };
174 
181 private:
183  void SendA (void) const;
185  void SendB (void) const;
192  void Receive (Ptr<Packet> p, double snr, WifiTxVector txVector);
193  Ptr<WifiPhy> m_txA;
194  Ptr<WifiPhy> m_txB;
195  uint32_t m_flowIdA;
196  uint32_t m_flowIdB;
197  struct Input m_input;
198  struct Output m_output;
199 };
200 
201 void
203 {
204  Ptr<Packet> p = Create<Packet> (m_input.packetSizeA);
205  p->AddByteTag (FlowIdTag (m_flowIdA));
206  WifiTxVector txVector;
207  txVector.SetTxPowerLevel (m_input.txPowerLevelA);
208  txVector.SetMode (WifiMode (m_input.txModeA));
210  m_txA->SendPacket (p, txVector);
211 }
212 
213 void
215 {
216  Ptr<Packet> p = Create<Packet> (m_input.packetSizeB);
217  p->AddByteTag (FlowIdTag (m_flowIdB));
218  WifiTxVector txVector;
219  txVector.SetTxPowerLevel (m_input.txPowerLevelB);
220  txVector.SetMode (WifiMode (m_input.txModeB));
222  m_txB->SendPacket (p, txVector);
223 }
224 
225 void
227 {
228  FlowIdTag tag;
229  if (p->FindFirstMatchingByteTag (tag))
230  {
231  if (tag.GetFlowId () == m_flowIdA)
232  {
233  m_output.receivedA++;
234  }
235  else if (tag.GetFlowId () == m_flowIdB)
236  {
237  m_output.receivedB++;
238  }
239  }
240 }
241 
243 {
244 }
246  : interval (MicroSeconds (0)),
247  xA (-5),
248  xB (5),
249  txModeA ("OfdmRate6Mbps"),
250  txModeB ("OfdmRate6Mbps"),
251  txPowerLevelA (0),
252  txPowerLevelB (0),
253  packetSizeA (2304),
254  packetSizeB (2304),
255  nPackets (400)
256 {
257 }
258 
260 CollisionExperiment::Run (struct CollisionExperiment::Input input)
261 {
262  m_output.receivedA = 0;
263  m_output.receivedB = 0;
264  m_input = input;
265 
266  m_flowIdA = FlowIdTag::AllocateFlowId ();
267  m_flowIdB = FlowIdTag::AllocateFlowId ();
268 
269  Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel> ();
270  channel->SetPropagationDelayModel (CreateObject<ConstantSpeedPropagationDelayModel> ());
271  Ptr<LogDistancePropagationLossModel> log = CreateObject<LogDistancePropagationLossModel> ();
272  channel->SetPropagationLossModel (log);
273 
274  Ptr<MobilityModel> posTxA = CreateObject<ConstantPositionMobilityModel> ();
275  posTxA->SetPosition (Vector (input.xA, 0.0, 0.0));
276  Ptr<MobilityModel> posTxB = CreateObject<ConstantPositionMobilityModel> ();
277  posTxB->SetPosition (Vector (input.xB, 0.0, 0.0));
278  Ptr<MobilityModel> posRx = CreateObject<ConstantPositionMobilityModel> ();
279  posRx->SetPosition (Vector (0, 0.0, 0.0));
280 
281  Ptr<YansWifiPhy> txA = CreateObject<YansWifiPhy> ();
282  Ptr<YansWifiPhy> txB = CreateObject<YansWifiPhy> ();
283  Ptr<YansWifiPhy> rx = CreateObject<YansWifiPhy> ();
284 
285  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
286  txA->SetErrorRateModel (error);
287  txB->SetErrorRateModel (error);
288  rx->SetErrorRateModel (error);
289  txA->SetChannel (channel);
290  txB->SetChannel (channel);
291  rx->SetChannel (channel);
292  txA->SetMobility (posTxA);
293  txB->SetMobility (posTxB);
294  rx->SetMobility (posRx);
295 
297  txB->ConfigureStandard (WIFI_PHY_STANDARD_80211a);
298  rx->ConfigureStandard (WIFI_PHY_STANDARD_80211a);
299 
300  rx->SetReceiveOkCallback (MakeCallback (&CollisionExperiment::Receive, this));
301 
302  for (uint32_t i = 0; i < m_input.nPackets; ++i)
303  {
304  Simulator::Schedule (Seconds (i), &CollisionExperiment::SendA, this);
305  }
306  for (uint32_t i = 0; i < m_input.nPackets; ++i)
307  {
308  Simulator::Schedule (Seconds (i) + m_input.interval, &CollisionExperiment::SendB, this);
309  }
310  m_txA = txA;
311  m_txB = txB;
312  Simulator::Run ();
313  Simulator::Destroy ();
314  return m_output;
315 }
316 
317 
318 static void PrintPsr (int argc, char *argv[])
319 {
321  struct PsrExperiment::Input input;
322 
324  cmd.AddValue ("Distance", "The distance between two phys", input.distance);
325  cmd.AddValue ("PacketSize", "The size of each packet sent", input.packetSize);
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 ("TxPowerLevel", "The power level index to use to send each packet", input.txPowerLevel);
329  cmd.Parse (argc, argv);
330 
331  struct PsrExperiment::Output output;
332  output = experiment.Run (input);
333 
334  double psr = output.received;
335  psr /= input.nPackets;
336 
337  std::cout << psr << std::endl;
338 }
339 
340 double CalcPsr (struct PsrExperiment::Output output, struct PsrExperiment::Input input)
341 {
342  double psr = output.received;
343  psr /= input.nPackets;
344  return psr;
345 }
346 
347 static void PrintPsrVsDistance (int argc, char *argv[])
348 {
349  struct PsrExperiment::Input input;
351  cmd.AddValue ("TxPowerLevel", "The power level index to use to send each packet", input.txPowerLevel);
352  cmd.AddValue ("TxMode", "The mode to use to send each packet", input.txMode);
353  cmd.AddValue ("NPackets", "The number of packets to send", input.nPackets);
354  cmd.AddValue ("PacketSize", "The size of each packet sent", input.packetSize);
355  cmd.Parse (argc, argv);
356 
357  for (input.distance = 1.0; input.distance < 165; input.distance += 2.0)
358  {
359  std::cout << input.distance;
361  struct PsrExperiment::Output output;
362 
363  input.txMode = "OfdmRate6Mbps";
364  output = experiment.Run (input);
365  std::cout << " " << CalcPsr (output, input);
366 
367  input.txMode = "OfdmRate9Mbps";
368  output = experiment.Run (input);
369  std::cout << " " << CalcPsr (output, input);
370 
371  input.txMode = "OfdmRate12Mbps";
372  output = experiment.Run (input);
373  std::cout << " " << CalcPsr (output, input);
374 
375  input.txMode = "OfdmRate18Mbps";
376  output = experiment.Run (input);
377  std::cout << " " << CalcPsr (output, input);
378 
379  input.txMode = "OfdmRate24Mbps";
380  output = experiment.Run (input);
381  std::cout << " " << CalcPsr (output, input);
382 
383  input.txMode = "OfdmRate36Mbps";
384  output = experiment.Run (input);
385  std::cout << " " << CalcPsr (output, input);
386 
387  input.txMode = "OfdmRate48Mbps";
388  output = experiment.Run (input);
389  std::cout << " " << CalcPsr (output, input);
390 
391  input.txMode = "OfdmRate54Mbps";
392  output = experiment.Run (input);
393  std::cout << " " << CalcPsr (output, input);
394 
395  std::cout << std::endl;
396  }
397 }
398 
399 static void PrintSizeVsRange (int argc, char *argv[])
400 {
401  double targetPsr = 0.05;
402  struct PsrExperiment::Input input;
404  cmd.AddValue ("TxPowerLevel", "The power level index to use to send each packet", input.txPowerLevel);
405  cmd.AddValue ("TxMode", "The mode to use to send each packet", input.txMode);
406  cmd.AddValue ("NPackets", "The number of packets to send", input.nPackets);
407  cmd.AddValue ("TargetPsr", "The psr needed to assume that we are within range", targetPsr);
408  cmd.Parse (argc, argv);
409 
410  for (input.packetSize = 10; input.packetSize < 3000; input.packetSize += 40)
411  {
412  double precision = 0.1;
413  double low = 1.0;
414  double high = 200.0;
415  while (high - low > precision)
416  {
417  double middle = low + (high - low) / 2;
418  struct PsrExperiment::Output output;
420  input.distance = middle;
421  output = experiment.Run (input);
422  double psr = CalcPsr (output, input);
423  if (psr >= targetPsr)
424  {
425  low = middle;
426  }
427  else
428  {
429  high = middle;
430  }
431  }
432  std::cout << input.packetSize << " " << input.distance << std::endl;
433  }
434 }
435 
436 static void PrintPsrVsCollisionInterval (int argc, char *argv[])
437 {
439  input.nPackets = 100;
441  cmd.AddValue ("NPackets", "The number of packets to send for each transmitter", input.nPackets);
442  cmd.AddValue ("xA", "the position of transmitter A", input.xA);
443  cmd.AddValue ("xB", "the position of transmitter B", input.xB);
444  cmd.Parse (argc, argv);
445 
446  for (uint32_t i = 0; i < 100; i += 1)
447  {
450  input.interval = MicroSeconds (i);
451  output = experiment.Run (input);
452  double perA = (output.receivedA + 0.0) / (input.nPackets + 0.0);
453  double perB = (output.receivedB + 0.0) / (input.nPackets + 0.0);
454  std::cout << i << " " << perA << " " << perB << std::endl;
455  }
456  for (uint32_t i = 100; i < 4000; i += 50)
457  {
460  input.interval = MicroSeconds (i);
461  output = experiment.Run (input);
462  double perA = (output.receivedA + 0.0) / (input.nPackets + 0.0);
463  double perB = (output.receivedB + 0.0) / (input.nPackets + 0.0);
464  std::cout << i << " " << perA << " " << perB << std::endl;
465  }
466 }
467 
468 
469 int main (int argc, char *argv[])
470 {
471  if (argc <= 1)
472  {
473  std::cout << "Available experiments: "
474  << "Psr "
475  << "SizeVsRange "
476  << "PsrVsDistance "
477  << "PsrVsCollisionInterval "
478  << std::endl;
479  return 0;
480  }
481  std::string type = argv[1];
482  argc--;
483  argv[1] = argv[0];
484  argv++;
485  if (type == "Psr")
486  {
487  PrintPsr (argc, argv);
488  }
489  else if (type == "SizeVsRange")
490  {
491  PrintSizeVsRange (argc, argv);
492  }
493  else if (type == "PsrVsDistance")
494  {
495  PrintPsrVsDistance (argc, argv);
496  }
497  else if (type == "PsrVsCollisionInterval")
498  {
499  PrintPsrVsCollisionInterval (argc, argv);
500  }
501  else
502  {
503  std::cout << "Wrong arguments!" << std::endl;
504  }
505 
506  return 0;
507 }
Input structure.
bool FindFirstMatchingByteTag(Tag &tag) const
Finds the first tag matching the parameter Tag type.
Definition: packet.cc:835
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
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.
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:662
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:85
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:1489
uint32_t m_flowIdB
flow ID B
static void PrintPsr(int argc, char *argv[])
Parse command-line arguments.
Definition: command-line.h:213
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:681
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
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
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1014
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:1030
static const uint32_t packetSize
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:1119
uint8_t txPowerLevel
transmit power level
void AddByteTag(const Tag &tag) const
Tag each byte included in this packet with a new byte tag.
Definition: packet.cc:819
struct Input m_input
input
void experiment(bool enableCtsRts, std::string wifiManager)
Run single 10 seconds experiment.