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