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);
72  void Receive (Ptr<Packet> p, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
73  Ptr<WifiPhy> m_tx;
74  struct Input m_input;
75  struct Output m_output;
76 };
77 
78 void
80 {
81  Ptr<Packet> p = Create<Packet> (m_input.packetSize);
82  WifiMode mode = WifiMode (m_input.txMode);
83  WifiTxVector txVector;
84  txVector.SetTxPowerLevel (m_input.txPowerLevel);
85  txVector.SetMode (mode);
87  m_tx->SendPacket (p, txVector);
88 }
89 
90 void
91 PsrExperiment::Receive (Ptr<Packet> p, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu)
92 {
93  m_output.received++;
94 }
95 
97 {
98 }
100  : distance (5.0),
101  txMode ("OfdmRate6Mbps"),
102  txPowerLevel (0),
103  packetSize (2304),
104  nPackets (400)
105 {
106 }
107 
109 PsrExperiment::Run (struct PsrExperiment::Input input)
110 {
111  m_output.received = 0;
112  m_input = input;
113 
114  Ptr<MobilityModel> posTx = CreateObject<ConstantPositionMobilityModel> ();
115  posTx->SetPosition (Vector (0.0, 0.0, 0.0));
116  Ptr<MobilityModel> posRx = CreateObject<ConstantPositionMobilityModel> ();
117  posRx->SetPosition (Vector (m_input.distance, 0.0, 0.0));
118 
119  Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel> ();
120  channel->SetPropagationDelayModel (CreateObject<ConstantSpeedPropagationDelayModel> ());
121  Ptr<LogDistancePropagationLossModel> log = CreateObject<LogDistancePropagationLossModel> ();
122  channel->SetPropagationLossModel (log);
123 
124  Ptr<YansWifiPhy> tx = CreateObject<YansWifiPhy> ();
125  Ptr<YansWifiPhy> rx = CreateObject<YansWifiPhy> ();
126  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
127  tx->SetErrorRateModel (error);
128  rx->SetErrorRateModel (error);
129  tx->SetChannel (channel);
130  rx->SetChannel (channel);
131  tx->SetMobility (posTx);
132  rx->SetMobility (posRx);
133 
135  rx->ConfigureStandard (WIFI_PHY_STANDARD_80211a);
136 
137  rx->SetReceiveOkCallback (MakeCallback (&PsrExperiment::Receive, this));
138 
139  for (uint32_t i = 0; i < m_input.nPackets; ++i)
140  {
141  Simulator::Schedule (Seconds (i), &PsrExperiment::Send, this);
142  }
143  m_tx = tx;
144  Simulator::Run ();
145  Simulator::Destroy ();
146  return m_output;
147 }
148 
151 {
152 public:
154  struct Input
155  {
156  Input ();
158  double xA;
159  double xB;
160  std::string txModeA;
161  std::string txModeB;
162  uint8_t txPowerLevelA;
163  uint8_t txPowerLevelB;
164  uint32_t packetSizeA;
165  uint32_t packetSizeB;
166  uint32_t nPackets;
167  };
169  struct Output
170  {
171  uint32_t receivedA;
172  uint32_t receivedB;
173  };
175 
182 private:
184  void SendA (void) const;
186  void SendB (void) const;
194  void Receive (Ptr<Packet> p, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
195  Ptr<WifiPhy> m_txA;
196  Ptr<WifiPhy> m_txB;
197  uint32_t m_flowIdA;
198  uint32_t m_flowIdB;
199  struct Input m_input;
200  struct Output m_output;
201 };
202 
203 void
205 {
206  Ptr<Packet> p = Create<Packet> (m_input.packetSizeA);
207  p->AddByteTag (FlowIdTag (m_flowIdA));
208  WifiTxVector txVector;
209  txVector.SetTxPowerLevel (m_input.txPowerLevelA);
210  txVector.SetMode (WifiMode (m_input.txModeA));
212  m_txA->SendPacket (p, txVector);
213 }
214 
215 void
217 {
218  Ptr<Packet> p = Create<Packet> (m_input.packetSizeB);
219  p->AddByteTag (FlowIdTag (m_flowIdB));
220  WifiTxVector txVector;
221  txVector.SetTxPowerLevel (m_input.txPowerLevelB);
222  txVector.SetMode (WifiMode (m_input.txModeB));
224  m_txB->SendPacket (p, txVector);
225 }
226 
227 void
228 CollisionExperiment::Receive (Ptr<Packet> p, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu)
229 {
230  FlowIdTag tag;
231  if (p->FindFirstMatchingByteTag (tag))
232  {
233  if (tag.GetFlowId () == m_flowIdA)
234  {
235  m_output.receivedA++;
236  }
237  else if (tag.GetFlowId () == m_flowIdB)
238  {
239  m_output.receivedB++;
240  }
241  }
242 }
243 
245 {
246 }
248  : interval (MicroSeconds (0)),
249  xA (-5),
250  xB (5),
251  txModeA ("OfdmRate6Mbps"),
252  txModeB ("OfdmRate6Mbps"),
253  txPowerLevelA (0),
254  txPowerLevelB (0),
255  packetSizeA (2304),
256  packetSizeB (2304),
257  nPackets (400)
258 {
259 }
260 
262 CollisionExperiment::Run (struct CollisionExperiment::Input input)
263 {
264  m_output.receivedA = 0;
265  m_output.receivedB = 0;
266  m_input = input;
267 
268  m_flowIdA = FlowIdTag::AllocateFlowId ();
269  m_flowIdB = FlowIdTag::AllocateFlowId ();
270 
271  Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel> ();
272  channel->SetPropagationDelayModel (CreateObject<ConstantSpeedPropagationDelayModel> ());
273  Ptr<LogDistancePropagationLossModel> log = CreateObject<LogDistancePropagationLossModel> ();
274  channel->SetPropagationLossModel (log);
275 
276  Ptr<MobilityModel> posTxA = CreateObject<ConstantPositionMobilityModel> ();
277  posTxA->SetPosition (Vector (input.xA, 0.0, 0.0));
278  Ptr<MobilityModel> posTxB = CreateObject<ConstantPositionMobilityModel> ();
279  posTxB->SetPosition (Vector (input.xB, 0.0, 0.0));
280  Ptr<MobilityModel> posRx = CreateObject<ConstantPositionMobilityModel> ();
281  posRx->SetPosition (Vector (0, 0.0, 0.0));
282 
283  Ptr<YansWifiPhy> txA = CreateObject<YansWifiPhy> ();
284  Ptr<YansWifiPhy> txB = CreateObject<YansWifiPhy> ();
285  Ptr<YansWifiPhy> rx = CreateObject<YansWifiPhy> ();
286 
287  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
288  txA->SetErrorRateModel (error);
289  txB->SetErrorRateModel (error);
290  rx->SetErrorRateModel (error);
291  txA->SetChannel (channel);
292  txB->SetChannel (channel);
293  rx->SetChannel (channel);
294  txA->SetMobility (posTxA);
295  txB->SetMobility (posTxB);
296  rx->SetMobility (posRx);
297 
299  txB->ConfigureStandard (WIFI_PHY_STANDARD_80211a);
300  rx->ConfigureStandard (WIFI_PHY_STANDARD_80211a);
301 
302  rx->SetReceiveOkCallback (MakeCallback (&CollisionExperiment::Receive, this));
303 
304  for (uint32_t i = 0; i < m_input.nPackets; ++i)
305  {
306  Simulator::Schedule (Seconds (i), &CollisionExperiment::SendA, this);
307  }
308  for (uint32_t i = 0; i < m_input.nPackets; ++i)
309  {
310  Simulator::Schedule (Seconds (i) + m_input.interval, &CollisionExperiment::SendB, this);
311  }
312  m_txA = txA;
313  m_txB = txB;
314  Simulator::Run ();
315  Simulator::Destroy ();
316  return m_output;
317 }
318 
319 
320 static void PrintPsr (int argc, char *argv[])
321 {
323  struct PsrExperiment::Input input;
324 
326  cmd.AddValue ("Distance", "The distance between two phys", input.distance);
327  cmd.AddValue ("PacketSize", "The size of each packet sent", input.packetSize);
328  cmd.AddValue ("TxMode", "The mode to use to send each packet", input.txMode);
329  cmd.AddValue ("NPackets", "The number of packets to send", input.nPackets);
330  cmd.AddValue ("TxPowerLevel", "The power level index to use to send each packet", input.txPowerLevel);
331  cmd.Parse (argc, argv);
332 
333  struct PsrExperiment::Output output;
334  output = experiment.Run (input);
335 
336  double psr = output.received;
337  psr /= input.nPackets;
338 
339  std::cout << psr << std::endl;
340 }
341 
342 double CalcPsr (struct PsrExperiment::Output output, struct PsrExperiment::Input input)
343 {
344  double psr = output.received;
345  psr /= input.nPackets;
346  return psr;
347 }
348 
349 static void PrintPsrVsDistance (int argc, char *argv[])
350 {
351  struct PsrExperiment::Input input;
353  cmd.AddValue ("TxPowerLevel", "The power level index to use to send each packet", input.txPowerLevel);
354  cmd.AddValue ("TxMode", "The mode to use to send each packet", input.txMode);
355  cmd.AddValue ("NPackets", "The number of packets to send", input.nPackets);
356  cmd.AddValue ("PacketSize", "The size of each packet sent", input.packetSize);
357  cmd.Parse (argc, argv);
358 
359  for (input.distance = 1.0; input.distance < 165; input.distance += 2.0)
360  {
361  std::cout << input.distance;
363  struct PsrExperiment::Output output;
364 
365  input.txMode = "OfdmRate6Mbps";
366  output = experiment.Run (input);
367  std::cout << " " << CalcPsr (output, input);
368 
369  input.txMode = "OfdmRate9Mbps";
370  output = experiment.Run (input);
371  std::cout << " " << CalcPsr (output, input);
372 
373  input.txMode = "OfdmRate12Mbps";
374  output = experiment.Run (input);
375  std::cout << " " << CalcPsr (output, input);
376 
377  input.txMode = "OfdmRate18Mbps";
378  output = experiment.Run (input);
379  std::cout << " " << CalcPsr (output, input);
380 
381  input.txMode = "OfdmRate24Mbps";
382  output = experiment.Run (input);
383  std::cout << " " << CalcPsr (output, input);
384 
385  input.txMode = "OfdmRate36Mbps";
386  output = experiment.Run (input);
387  std::cout << " " << CalcPsr (output, input);
388 
389  input.txMode = "OfdmRate48Mbps";
390  output = experiment.Run (input);
391  std::cout << " " << CalcPsr (output, input);
392 
393  input.txMode = "OfdmRate54Mbps";
394  output = experiment.Run (input);
395  std::cout << " " << CalcPsr (output, input);
396 
397  std::cout << std::endl;
398  }
399 }
400 
401 static void PrintSizeVsRange (int argc, char *argv[])
402 {
403  double targetPsr = 0.05;
404  struct PsrExperiment::Input input;
406  cmd.AddValue ("TxPowerLevel", "The power level index to use to send each packet", input.txPowerLevel);
407  cmd.AddValue ("TxMode", "The mode to use to send each packet", input.txMode);
408  cmd.AddValue ("NPackets", "The number of packets to send", input.nPackets);
409  cmd.AddValue ("TargetPsr", "The psr needed to assume that we are within range", targetPsr);
410  cmd.Parse (argc, argv);
411 
412  for (input.packetSize = 10; input.packetSize < 3000; input.packetSize += 40)
413  {
414  double precision = 0.1;
415  double low = 1.0;
416  double high = 200.0;
417  while (high - low > precision)
418  {
419  double middle = low + (high - low) / 2;
420  struct PsrExperiment::Output output;
422  input.distance = middle;
423  output = experiment.Run (input);
424  double psr = CalcPsr (output, input);
425  if (psr >= targetPsr)
426  {
427  low = middle;
428  }
429  else
430  {
431  high = middle;
432  }
433  }
434  std::cout << input.packetSize << " " << input.distance << std::endl;
435  }
436 }
437 
438 static void PrintPsrVsCollisionInterval (int argc, char *argv[])
439 {
441  input.nPackets = 100;
443  cmd.AddValue ("NPackets", "The number of packets to send for each transmitter", input.nPackets);
444  cmd.AddValue ("xA", "the position of transmitter A", input.xA);
445  cmd.AddValue ("xB", "the position of transmitter B", input.xB);
446  cmd.Parse (argc, argv);
447 
448  for (uint32_t i = 0; i < 100; i += 1)
449  {
452  input.interval = MicroSeconds (i);
453  output = experiment.Run (input);
454  double perA = (output.receivedA + 0.0) / (input.nPackets + 0.0);
455  double perB = (output.receivedB + 0.0) / (input.nPackets + 0.0);
456  std::cout << i << " " << perA << " " << perB << std::endl;
457  }
458  for (uint32_t i = 100; i < 4000; i += 50)
459  {
462  input.interval = MicroSeconds (i);
463  output = experiment.Run (input);
464  double perA = (output.receivedA + 0.0) / (input.nPackets + 0.0);
465  double perB = (output.receivedB + 0.0) / (input.nPackets + 0.0);
466  std::cout << i << " " << perA << " " << perB << std::endl;
467  }
468 }
469 
470 
471 int main (int argc, char *argv[])
472 {
473  if (argc <= 1)
474  {
475  std::cout << "Available experiments: "
476  << "Psr "
477  << "SizeVsRange "
478  << "PsrVsDistance "
479  << "PsrVsCollisionInterval "
480  << std::endl;
481  return 0;
482  }
483  std::string type = argv[1];
484  argc--;
485  argv[1] = argv[0];
486  argv++;
487  if (type == "Psr")
488  {
489  PrintPsr (argc, argv);
490  }
491  else if (type == "SizeVsRange")
492  {
493  PrintSizeVsRange (argc, argv);
494  }
495  else if (type == "PsrVsDistance")
496  {
497  PrintPsrVsDistance (argc, argv);
498  }
499  else if (type == "PsrVsCollisionInterval")
500  {
501  PrintPsrVsCollisionInterval (argc, argv);
502  }
503  else
504  {
505  std::cout << "Wrong arguments!" << std::endl;
506  }
507 
508  return 0;
509 }
Input structure.
bool FindFirstMatchingByteTag(Tag &tag) const
Finds the first tag matching the parameter Tag type.
Definition: packet.cc:846
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
void Receive(Ptr< Packet > p, double snr, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Send receive function.
uint32_t nPackets
number of packets
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition: wifi-phy.cc:743
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: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 SetErrorRateModel(const Ptr< ErrorRateModel > rate)
Sets the error rate model.
Definition: wifi-phy.cc:762
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.
void Receive(Ptr< Packet > p, double snr, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Receive function.
uint32_t received
received
void experiment(std::string queue_disc_type)
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:1062
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:1078
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:1217
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