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, txVector, WIFI_PREAMBLE_SHORT);
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, txVector, WIFI_PREAMBLE_SHORT);
182 }
183 
184 void
186 {
187  Ptr<Packet> p = Create<Packet> (m_input.packetSizeB);
188  p->AddByteTag (FlowIdTag (m_flowIdB));
189  WifiTxVector txVector;
190  txVector.SetTxPowerLevel (m_input.txPowerLevelB);
191  txVector.SetMode (WifiMode (m_input.txModeB));
192  m_txB->SendPacket (p, txVector, WIFI_PREAMBLE_SHORT);
193 }
194 
195 void
196 CollisionExperiment::Receive (Ptr<Packet> p, double snr, WifiMode mode, enum WifiPreamble preamble)
197 {
198  FlowIdTag tag;
199  if (p->FindFirstMatchingByteTag (tag))
200  {
201  if (tag.GetFlowId () == m_flowIdA)
202  {
203  m_output.receivedA++;
204  }
205  else if (tag.GetFlowId () == m_flowIdB)
206  {
207  m_output.receivedB++;
208  }
209  }
210 }
211 
213 {
214 }
216  : interval (MicroSeconds (0)),
217  xA (-5),
218  xB (5),
219  txModeA ("OfdmRate6Mbps"),
220  txModeB ("OfdmRate6Mbps"),
221  txPowerLevelA (0),
222  txPowerLevelB (0),
223  packetSizeA (2304),
224  packetSizeB (2304),
225  nPackets (400)
226 {
227 }
228 
230 CollisionExperiment::Run (struct CollisionExperiment::Input input)
231 {
232  m_output.receivedA = 0;
233  m_output.receivedB = 0;
234  m_input = input;
235 
236  m_flowIdA = FlowIdTag::AllocateFlowId ();
237  m_flowIdB = FlowIdTag::AllocateFlowId ();
238 
239  Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel> ();
240  channel->SetPropagationDelayModel (CreateObject<ConstantSpeedPropagationDelayModel> ());
241  Ptr<LogDistancePropagationLossModel> log = CreateObject<LogDistancePropagationLossModel> ();
242  channel->SetPropagationLossModel (log);
243 
244  Ptr<MobilityModel> posTxA = CreateObject<ConstantPositionMobilityModel> ();
245  posTxA->SetPosition (Vector (input.xA, 0.0, 0.0));
246  Ptr<MobilityModel> posTxB = CreateObject<ConstantPositionMobilityModel> ();
247  posTxB->SetPosition (Vector (input.xB, 0.0, 0.0));
248  Ptr<MobilityModel> posRx = CreateObject<ConstantPositionMobilityModel> ();
249  posRx->SetPosition (Vector (0, 0.0, 0.0));
250 
251  Ptr<YansWifiPhy> txA = CreateObject<YansWifiPhy> ();
252  Ptr<YansWifiPhy> txB = CreateObject<YansWifiPhy> ();
253  Ptr<YansWifiPhy> rx = CreateObject<YansWifiPhy> ();
254 
255  Ptr<ErrorRateModel> error = CreateObject<YansErrorRateModel> ();
256  txA->SetErrorRateModel (error);
257  txB->SetErrorRateModel (error);
258  rx->SetErrorRateModel (error);
259  txA->SetChannel (channel);
260  txB->SetChannel (channel);
261  rx->SetChannel (channel);
262  txA->SetMobility (posTxA);
263  txB->SetMobility (posTxB);
264  rx->SetMobility (posRx);
265 
266 
267  rx->SetReceiveOkCallback (MakeCallback (&CollisionExperiment::Receive, this));
268 
269  for (uint32_t i = 0; i < m_input.nPackets; ++i)
270  {
271  Simulator::Schedule (Seconds (i), &CollisionExperiment::SendA, this);
272  }
273  for (uint32_t i = 0; i < m_input.nPackets; ++i)
274  {
275  Simulator::Schedule (Seconds (i) + m_input.interval, &CollisionExperiment::SendB, this);
276  }
277  m_txA = txA;
278  m_txB = txB;
279  Simulator::Run ();
280  Simulator::Destroy();
281  return m_output;
282 }
283 
284 
285 static void PrintPsr (int argc, char *argv[])
286 {
288  struct PsrExperiment::Input input;
289 
290  CommandLine cmd;
291  cmd.AddValue ("Distance", "The distance between two phys", input.distance);
292  cmd.AddValue ("PacketSize", "The size of each packet sent", input.packetSize);
293  cmd.AddValue ("TxMode", "The mode to use to send each packet", input.txMode);
294  cmd.AddValue ("NPackets", "The number of packets to send", input.nPackets);
295  cmd.AddValue ("TxPowerLevel", "The power level index to use to send each packet", input.txPowerLevel);
296  cmd.Parse (argc, argv);
297 
298  struct PsrExperiment::Output output;
299  output = experiment.Run (input);
300 
301  double psr = output.received;
302  psr /= input.nPackets;
303 
304  std::cout << psr << std::endl;
305 }
306 
307 double CalcPsr (struct PsrExperiment::Output output, struct PsrExperiment::Input input)
308 {
309  double psr = output.received;
310  psr /= input.nPackets;
311  return psr;
312 }
313 
314 static void PrintPsrVsDistance (int argc, char *argv[])
315 {
316  struct PsrExperiment::Input input;
317  CommandLine cmd;
318  cmd.AddValue ("TxPowerLevel", "The power level index to use to send each packet", input.txPowerLevel);
319  cmd.AddValue ("TxMode", "The mode to use to send each packet", input.txMode);
320  cmd.AddValue ("NPackets", "The number of packets to send", input.nPackets);
321  cmd.AddValue ("PacketSize", "The size of each packet sent", input.packetSize);
322  cmd.Parse (argc, argv);
323  for (input.distance = 1.0; input.distance < 165; input.distance += 2.0)
324  {
325  std::cout << input.distance;
327  struct PsrExperiment::Output output;
328 
329  input.txMode = "OfdmRate6Mbps";
330  output = experiment.Run (input);
331  std::cout << " " << CalcPsr (output, input);
332 
333  input.txMode = "OfdmRate9Mbps";
334  output = experiment.Run (input);
335  std::cout << " " << CalcPsr (output, input);
336 
337  input.txMode = "OfdmRate12Mbps";
338  output = experiment.Run (input);
339  std::cout << " " << CalcPsr (output, input);
340 
341  input.txMode = "OfdmRate18Mbps";
342  output = experiment.Run (input);
343  std::cout << " " << CalcPsr (output, input);
344 
345  input.txMode = "OfdmRate24Mbps";
346  output = experiment.Run (input);
347  std::cout << " " << CalcPsr (output, input);
348 
349  input.txMode = "OfdmRate36Mbps";
350  output = experiment.Run (input);
351  std::cout << " " << CalcPsr (output, input);
352 
353  input.txMode = "OfdmRate48Mbps";
354  output = experiment.Run (input);
355  std::cout << " " << CalcPsr (output, input);
356 
357  input.txMode = "OfdmRate54Mbps";
358  output = experiment.Run (input);
359  std::cout << " " << CalcPsr (output, input);
360 
361  std::cout << std::endl;
362  }
363 }
364 
365 static void PrintSizeVsRange (int argc, char *argv[])
366 {
367  double targetPsr = 0.05;
368  struct PsrExperiment::Input input;
369  CommandLine cmd;
370  cmd.AddValue ("TxPowerLevel", "The power level index to use to send each packet", input.txPowerLevel);
371  cmd.AddValue ("TxMode", "The mode to use to send each packet", input.txMode);
372  cmd.AddValue ("NPackets", "The number of packets to send", input.nPackets);
373  cmd.AddValue ("TargetPsr", "The psr needed to assume that we are within range", targetPsr);
374  cmd.Parse (argc, argv);
375  for (input.packetSize = 10; input.packetSize < 3000; input.packetSize += 40)
376  {
377  double precision = 0.1;
378  double low = 1.0;
379  double high = 200.0;
380  while (high - low > precision)
381  {
382  double middle = low + (high - low) / 2;
383  struct PsrExperiment::Output output;
385  input.distance = middle;
386  output = experiment.Run (input);
387  double psr = CalcPsr (output, input);
388  if (psr >= targetPsr)
389  {
390  low = middle;
391  }
392  else
393  {
394  high = middle;
395  }
396  }
397  std::cout << input.packetSize << " " << input.distance << std::endl;
398  }
399 }
400 
401 static void PrintPsrVsCollisionInterval (int argc, char *argv[])
402 {
404  input.nPackets = 100;
405  CommandLine cmd;
406  cmd.AddValue ("NPackets", "The number of packets to send for each transmitter", input.nPackets);
407  cmd.AddValue ("xA", "the position of transmitter A", input.xA);
408  cmd.AddValue ("xB", "the position of transmitter B", input.xB);
409  for (uint32_t i = 0; i < 100; i += 1)
410  {
413  input.interval = MicroSeconds (i);
414  output = experiment.Run (input);
415  double perA = (output.receivedA + 0.0) / (input.nPackets + 0.0);
416  double perB = (output.receivedB + 0.0) / (input.nPackets + 0.0);
417  std::cout << i << " " << perA << " " << perB << std::endl;
418  }
419  for (uint32_t i = 100; i < 4000; i += 50)
420  {
423  input.interval = MicroSeconds (i);
424  output = experiment.Run (input);
425  double perA = (output.receivedA + 0.0) / (input.nPackets + 0.0);
426  double perB = (output.receivedB + 0.0) / (input.nPackets + 0.0);
427  std::cout << i << " " << perA << " " << perB << std::endl;
428  }
429 }
430 
431 
432 
433 int main (int argc, char *argv[])
434 {
435  if (argc <= 1)
436  {
437  std::cout << "Available experiments: "
438  << "Psr "
439  << "SizeVsRange "
440  << "PsrVsDistance "
441  << "PsrVsCollisionInterval "
442  << std::endl;
443  return 0;
444  }
445  std::string type = argv[1];
446  argc--;
447  argv[1] = argv[0];
448  argv++;
449  if (type == "Psr")
450  {
451  PrintPsr (argc, argv);
452  }
453  else if (type == "SizeVsRange")
454  {
455  PrintSizeVsRange (argc, argv);
456  }
457  else if (type == "PsrVsDistance")
458  {
459  PrintPsrVsDistance (argc, argv);
460  }
461  else if (type == "PsrVsCollisionInterval")
462  {
463  PrintPsrVsCollisionInterval (argc, argv);
464  }
465 
466  return 0;
467 }
bool FindFirstMatchingByteTag(Tag &tag) const
Finds the first tag matching the parameter Tag type.
Definition: packet.cc:824
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:95
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:60
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:1283
uint32_t GetFlowId(void) const
Gets the flow id for the tag.
Definition: flow-id-tag.cc:87
static void PrintPsr(int argc, char *argv[])
void SendA(void) const
Parse command-line arguments.
Definition: command-line.h:196
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:471
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
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:845
struct CollisionExperiment::Output Run(struct CollisionExperiment::Input input)
static void PrintSizeVsRange(int argc, char *argv[])
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:861
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