00001 #include "wifi-net-device.h" 00002 #include "yans-wifi-channel.h" 00003 #include "yans-wifi-phy.h" 00004 #include "propagation-loss-model.h" 00005 #include "propagation-delay-model.h" 00006 #include "error-rate-model.h" 00007 #include "yans-error-rate-model.h" 00008 #include "ns3/ptr.h" 00009 #include "ns3/mobility-model.h" 00010 #include "ns3/static-mobility-model.h" 00011 #include "ns3/vector.h" 00012 #include "ns3/packet.h" 00013 #include "ns3/simulator.h" 00014 #include "ns3/nstime.h" 00015 #include "ns3/command-line.h" 00016 #include "ns3/flow-id-tag.h" 00017 00018 using namespace ns3; 00019 00020 class PsrExperiment 00021 { 00022 public: 00023 struct Input 00024 { 00025 Input (); 00026 double distance; 00027 std::string txMode; 00028 uint8_t txPowerLevel; 00029 uint32_t packetSize; 00030 uint32_t nPackets; 00031 }; 00032 struct Output 00033 { 00034 uint32_t received; 00035 }; 00036 PsrExperiment (); 00037 00038 struct PsrExperiment::Output Run (struct PsrExperiment::Input input); 00039 00040 private: 00041 void Send (void); 00042 void Receive (Ptr<Packet> p); 00043 Ptr<WifiPhy> m_tx; 00044 struct Input m_input; 00045 struct Output m_output; 00046 }; 00047 00048 void 00049 PsrExperiment::Send (void) 00050 { 00051 Ptr<Packet> p = Create<Packet> (m_input.packetSize); 00052 WifiMode mode = WifiMode (m_input.txMode); 00053 m_tx->SendPacket (p, mode, WIFI_PREAMBLE_SHORT, m_input.txPowerLevel); 00054 } 00055 00056 void 00057 PsrExperiment::Receive (Ptr<Packet> p) 00058 { 00059 m_output.received++; 00060 } 00061 00062 PsrExperiment::PsrExperiment () 00063 {} 00064 PsrExperiment::Input::Input () 00065 : distance (5.0), 00066 txMode ("wifia-6mbs"), 00067 txPowerLevel (0), 00068 packetSize (2304), 00069 nPackets (400) 00070 {} 00071 00072 struct PsrExperiment::Output 00073 PsrExperiment::Run (struct PsrExperiment::Input input) 00074 { 00075 m_output.received = 0; 00076 m_input = input; 00077 00078 Ptr<MobilityModel> posTx = CreateObject<StaticMobilityModel> (); 00079 posTx->SetPosition (Vector (0.0, 0.0, 0.0)); 00080 Ptr<MobilityModel> posRx = CreateObject<StaticMobilityModel> (); 00081 posRx->SetPosition (Vector (m_input.distance, 0.0, 0.0)); 00082 00083 Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel> (); 00084 channel->SetPropagationDelayModel (CreateObject<ConstantSpeedPropagationDelayModel> ()); 00085 Ptr<LogDistancePropagationLossModel> log = CreateObject<LogDistancePropagationLossModel> (); 00086 channel->SetPropagationLossModel (log); 00087 00088 Ptr<YansWifiPhy> tx = CreateObject<YansWifiPhy> (); 00089 Ptr<YansWifiPhy> rx = CreateObject<YansWifiPhy> (); 00090 Ptr<ErrorRateModel> error = CreateObject<YansErrorRateModel> (); 00091 tx->SetErrorRateModel (error); 00092 rx->SetErrorRateModel (error); 00093 tx->SetChannel (channel); 00094 rx->SetChannel (channel); 00095 tx->SetMobility (posTx); 00096 rx->SetMobility (posRx); 00097 00098 rx->SetReceiveOkCallback (MakeCallback (&PsrExperiment::Receive, this)); 00099 00100 for (uint32_t i = 0; i < m_input.nPackets; ++i) 00101 { 00102 Simulator::Schedule (Seconds (i), &PsrExperiment::Send, this); 00103 } 00104 m_tx = tx; 00105 Simulator::Run (); 00106 return m_output; 00107 } 00108 00109 00110 class CollisionExperiment 00111 { 00112 public: 00113 struct Input 00114 { 00115 Input (); 00116 Time interval; 00117 double xA; 00118 double xB; 00119 std::string txModeA; 00120 std::string txModeB; 00121 uint8_t txPowerLevelA; 00122 uint8_t txPowerLevelB; 00123 uint32_t packetSizeA; 00124 uint32_t packetSizeB; 00125 uint32_t nPackets; 00126 }; 00127 struct Output 00128 { 00129 uint32_t receivedA; 00130 uint32_t receivedB; 00131 }; 00132 CollisionExperiment (); 00133 00134 struct CollisionExperiment::Output Run (struct CollisionExperiment::Input input); 00135 private: 00136 void SendA (void) const; 00137 void SendB (void) const; 00138 void Receive (Ptr<Packet> p); 00139 Ptr<WifiPhy> m_txA; 00140 Ptr<WifiPhy> m_txB; 00141 uint32_t m_flowIdA; 00142 uint32_t m_flowIdB; 00143 struct Input m_input; 00144 struct Output m_output; 00145 }; 00146 00147 void 00148 CollisionExperiment::SendA (void) const 00149 { 00150 Ptr<Packet> p = Create<Packet> (m_input.packetSizeA); 00151 p->AddTag (FlowIdTag (m_flowIdA)); 00152 m_txA->SendPacket (p, WifiMode (m_input.txModeA), 00153 WIFI_PREAMBLE_SHORT, m_input.txPowerLevelA); 00154 } 00155 00156 void 00157 CollisionExperiment::SendB (void) const 00158 { 00159 Ptr<Packet> p = Create<Packet> (m_input.packetSizeB); 00160 p->AddTag (FlowIdTag (m_flowIdB)); 00161 m_txB->SendPacket (p, WifiMode (m_input.txModeB), 00162 WIFI_PREAMBLE_SHORT, m_input.txPowerLevelB); 00163 } 00164 00165 void 00166 CollisionExperiment::Receive (Ptr<Packet> p) 00167 { 00168 FlowIdTag tag; 00169 p->FindFirstMatchingTag (tag); 00170 if (tag.GetFlowId () == m_flowIdA) 00171 { 00172 m_output.receivedA++; 00173 } 00174 else if (tag.GetFlowId () == m_flowIdB) 00175 { 00176 m_output.receivedB++; 00177 } 00178 } 00179 00180 CollisionExperiment::CollisionExperiment () 00181 {} 00182 CollisionExperiment::Input::Input () 00183 : interval (MicroSeconds (0)), 00184 xA (-5), 00185 xB (5), 00186 txModeA ("wifia-6mbs"), 00187 txModeB ("wifia-6mbs"), 00188 txPowerLevelA (0), 00189 txPowerLevelB (0), 00190 packetSizeA (2304), 00191 packetSizeB (2304), 00192 nPackets (400) 00193 {} 00194 00195 struct CollisionExperiment::Output 00196 CollisionExperiment::Run (struct CollisionExperiment::Input input) 00197 { 00198 m_output.receivedA = 0; 00199 m_output.receivedB = 0; 00200 m_input = input; 00201 00202 m_flowIdA = FlowIdTag::AllocateFlowId (); 00203 m_flowIdB = FlowIdTag::AllocateFlowId (); 00204 00205 Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel> (); 00206 channel->SetPropagationDelayModel (CreateObject<ConstantSpeedPropagationDelayModel> ()); 00207 Ptr<LogDistancePropagationLossModel> log = CreateObject<LogDistancePropagationLossModel> (); 00208 channel->SetPropagationLossModel (log); 00209 00210 Ptr<MobilityModel> posTxA = CreateObject<StaticMobilityModel> (); 00211 posTxA->SetPosition (Vector (input.xA, 0.0, 0.0)); 00212 Ptr<MobilityModel> posTxB = CreateObject<StaticMobilityModel> (); 00213 posTxB->SetPosition (Vector (input.xB, 0.0, 0.0)); 00214 Ptr<MobilityModel> posRx = CreateObject<StaticMobilityModel> (); 00215 posRx->SetPosition (Vector (0, 0.0, 0.0)); 00216 00217 Ptr<YansWifiPhy> txA = CreateObject<YansWifiPhy> (); 00218 Ptr<YansWifiPhy> txB = CreateObject<YansWifiPhy> (); 00219 Ptr<YansWifiPhy> rx = CreateObject<YansWifiPhy> (); 00220 00221 Ptr<ErrorRateModel> error = CreateObject<YansErrorRateModel> (); 00222 txA->SetErrorRateModel (error); 00223 txB->SetErrorRateModel (error); 00224 rx->SetErrorRateModel (error); 00225 txA->SetChannel (channel); 00226 txB->SetChannel (channel); 00227 rx->SetChannel (channel); 00228 txA->SetMobility (posTxA); 00229 txB->SetMobility (posTxB); 00230 rx->SetMobility (posRx); 00231 00232 00233 rx->SetReceiveOkCallback (MakeCallback (&CollisionExperiment::Receive, this)); 00234 00235 for (uint32_t i = 0; i < m_input.nPackets; ++i) 00236 { 00237 Simulator::Schedule (Seconds (i), &CollisionExperiment::SendA, this); 00238 } 00239 for (uint32_t i = 0; i < m_input.nPackets; ++i) 00240 { 00241 Simulator::Schedule (Seconds (i) + m_input.interval, &CollisionExperiment::SendB, this); 00242 } 00243 m_txA = txA; 00244 m_txB = txB; 00245 Simulator::Run (); 00246 return m_output; 00247 } 00248 00249 00250 static void PrintPsr (int argc, char *argv[]) 00251 { 00252 PsrExperiment experiment; 00253 struct PsrExperiment::Input input; 00254 00255 CommandLine cmd; 00256 cmd.AddValue ("Distance", "The distance between two phys", input.distance); 00257 cmd.AddValue ("PacketSize", "The size of each packet sent", input.packetSize); 00258 cmd.AddValue ("TxMode", "The mode to use to send each packet", input.txMode); 00259 cmd.AddValue ("NPackets", "The number of packets to send", input.nPackets); 00260 cmd.AddValue ("TxPowerLevel", "The power level index to use to send each packet", input.txPowerLevel); 00261 cmd.Parse (argc, argv); 00262 00263 struct PsrExperiment::Output output; 00264 output = experiment.Run (input); 00265 00266 double psr = output.received; 00267 psr /= input.nPackets ; 00268 00269 std::cout << psr << std::endl; 00270 } 00271 00272 double CalcPsr (struct PsrExperiment::Output output, struct PsrExperiment::Input input) 00273 { 00274 double psr = output.received; 00275 psr /= input.nPackets ; 00276 return psr; 00277 } 00278 00279 static void PrintPsrVsDistance (int argc, char *argv[]) 00280 { 00281 struct PsrExperiment::Input input; 00282 CommandLine cmd; 00283 cmd.AddValue ("TxPowerLevel", "The power level index to use to send each packet", input.txPowerLevel); 00284 cmd.AddValue ("TxMode", "The mode to use to send each packet", input.txMode); 00285 cmd.AddValue ("NPackets", "The number of packets to send", input.nPackets); 00286 cmd.AddValue ("PacketSize", "The size of each packet sent", input.packetSize); 00287 cmd.Parse (argc, argv); 00288 for (input.distance = 1.0; input.distance < 165; input.distance += 2.0) 00289 { 00290 std::cout << input.distance; 00291 PsrExperiment experiment; 00292 struct PsrExperiment::Output output; 00293 00294 input.txMode = "wifia-6mbs"; 00295 output = experiment.Run (input); 00296 std::cout << " " << CalcPsr (output, input); 00297 00298 input.txMode = "wifia-9mbs"; 00299 output = experiment.Run (input); 00300 std::cout << " " << CalcPsr (output, input); 00301 00302 input.txMode = "wifia-12mbs"; 00303 output = experiment.Run (input); 00304 std::cout << " " << CalcPsr (output, input); 00305 00306 input.txMode = "wifia-18mbs"; 00307 output = experiment.Run (input); 00308 std::cout << " " << CalcPsr (output, input); 00309 00310 input.txMode = "wifia-24mbs"; 00311 output = experiment.Run (input); 00312 std::cout << " " << CalcPsr (output, input); 00313 00314 input.txMode = "wifia-36mbs"; 00315 output = experiment.Run (input); 00316 std::cout << " " << CalcPsr (output, input); 00317 00318 input.txMode = "wifia-48mbs"; 00319 output = experiment.Run (input); 00320 std::cout << " " << CalcPsr (output, input); 00321 00322 input.txMode = "wifia-54mbs"; 00323 output = experiment.Run (input); 00324 std::cout << " " << CalcPsr (output, input); 00325 00326 std::cout << std::endl; 00327 } 00328 } 00329 00330 static void PrintSizeVsRange (int argc, char *argv[]) 00331 { 00332 double targetPsr = 0.05; 00333 struct PsrExperiment::Input input; 00334 CommandLine cmd; 00335 cmd.AddValue ("TxPowerLevel", "The power level index to use to send each packet", input.txPowerLevel); 00336 cmd.AddValue ("TxMode", "The mode to use to send each packet", input.txMode); 00337 cmd.AddValue ("NPackets", "The number of packets to send", input.nPackets); 00338 cmd.AddValue ("TargetPsr", "The psr needed to assume that we are within range", targetPsr); 00339 cmd.Parse (argc, argv); 00340 for (input.packetSize = 10; input.packetSize < 3000; input.packetSize += 40) 00341 { 00342 double precision = 0.1; 00343 double low = 1.0; 00344 double high = 200.0; 00345 while (high - low > precision) 00346 { 00347 double middle = low + (high - low) / 2; 00348 struct PsrExperiment::Output output; 00349 PsrExperiment experiment; 00350 input.distance = middle; 00351 output = experiment.Run (input); 00352 double psr = CalcPsr (output, input); 00353 if (psr >= targetPsr) 00354 { 00355 low = middle; 00356 } 00357 else 00358 { 00359 high = middle; 00360 } 00361 } 00362 std::cout << input.packetSize << " " << input.distance << std::endl; 00363 } 00364 } 00365 00366 static void PrintPsrVsCollisionInterval (int argc, char *argv[]) 00367 { 00368 CollisionExperiment::Input input; 00369 input.nPackets = 100; 00370 CommandLine cmd; 00371 cmd.AddValue ("NPackets", "The number of packets to send for each transmitter", input.nPackets); 00372 cmd.AddValue ("xA", "the position of transmitter A", input.xA); 00373 cmd.AddValue ("xB", "the position of transmitter B", input.xB); 00374 for (uint32_t i = 0; i < 100; i += 1) 00375 { 00376 CollisionExperiment experiment; 00377 CollisionExperiment::Output output; 00378 input.interval = MicroSeconds (i); 00379 output = experiment.Run (input); 00380 double perA = (output.receivedA+0.0) / (input.nPackets+0.0); 00381 double perB = (output.receivedB+0.0) / (input.nPackets+0.0); 00382 std::cout << i << " " << perA << " " << perB << std::endl; 00383 } 00384 for (uint32_t i = 100; i < 4000; i += 50) 00385 { 00386 CollisionExperiment experiment; 00387 CollisionExperiment::Output output; 00388 input.interval = MicroSeconds (i); 00389 output = experiment.Run (input); 00390 double perA = (output.receivedA+0.0) / (input.nPackets+0.0); 00391 double perB = (output.receivedB+0.0) / (input.nPackets+0.0); 00392 std::cout << i << " " << perA << " " << perB << std::endl; 00393 } 00394 } 00395 00396 00397 00398 int main (int argc, char *argv[]) 00399 { 00400 if (argc <= 1) 00401 { 00402 std::cout << "Available experiments: " 00403 << "Psr " 00404 << "SizeVsRange " 00405 << "PsrVsDistance " 00406 << "PsrVsCollisionInterval " 00407 << std::endl; 00408 return -1; 00409 } 00410 std::string type = argv[1]; 00411 argc--; 00412 argv[1] = argv[0]; 00413 argv++; 00414 if (type == "Psr") 00415 { 00416 PrintPsr (argc, argv); 00417 } 00418 else if (type == "SizeVsRange") 00419 { 00420 PrintSizeVsRange (argc, argv); 00421 } 00422 else if (type == "PsrVsDistance") 00423 { 00424 PrintPsrVsDistance (argc, argv); 00425 } 00426 else if (type == "PsrVsCollisionInterval") 00427 { 00428 PrintPsrVsCollisionInterval (argc, argv); 00429 } 00430 00431 return 0; 00432 }