A Discrete-Event Network Simulator
API
tv-spectrum-transmitter-helper.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 University of Washington
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Benjamin Cizdziel <ben.cizdziel@gmail.com>
18  */
19 
21 
22 #include <ns3/double.h>
23 #include <ns3/geographic-positions.h>
24 #include <ns3/isotropic-antenna-model.h>
25 #include <ns3/log.h>
26 #include <ns3/mobility-helper.h>
27 #include <ns3/position-allocator.h>
28 #include <ns3/uinteger.h>
29 
30 #include <cmath>
31 #include <list>
32 #include <vector>
33 
34 namespace ns3
35 {
36 
37 NS_LOG_COMPONENT_DEFINE("TvSpectrumTransmitterHelper");
38 
40 const int northAmericaArrayLength = 84;
42 const double northAmericaStartFrequencies[84] = {
43  0, 0, 54e6, 60e6, 66e6, 76e6, 82e6, 174e6, 180e6, 186e6, 192e6, 198e6,
44  204e6, 210e6, 470e6, 476e6, 482e6, 488e6, 494e6, 500e6, 506e6, 512e6, 518e6, 524e6,
45  530e6, 536e6, 542e6, 548e6, 554e6, 560e6, 566e6, 572e6, 578e6, 584e6, 590e6, 596e6,
46  602e6, 608e6, 614e6, 620e6, 626e6, 632e6, 638e6, 644e6, 650e6, 656e6, 662e6, 668e6,
47  674e6, 680e6, 686e6, 692e6, 698e6, 704e6, 710e6, 716e6, 722e6, 728e6, 734e6, 740e6,
48  746e6, 752e6, 758e6, 764e6, 770e6, 776e6, 782e6, 788e6, 794e6, 800e6, 806e6, 812e6,
49  818e6, 824e6, 830e6, 836e6, 842e6, 848e6, 854e6, 860e6, 866e6, 872e6, 878e6, 884e6,
50 };
52 const double northAmericaEndFrequencies[84] = {
53  0, 0, 60e6, 66e6, 72e6, 82e6, 88e6, 180e6, 186e6, 192e6, 198e6, 204e6,
54  210e6, 216e6, 476e6, 482e6, 488e6, 494e6, 500e6, 506e6, 512e6, 518e6, 524e6, 530e6,
55  536e6, 542e6, 548e6, 554e6, 560e6, 566e6, 572e6, 578e6, 584e6, 590e6, 596e6, 602e6,
56  608e6, 614e6, 620e6, 626e6, 632e6, 638e6, 644e6, 650e6, 656e6, 662e6, 668e6, 674e6,
57  680e6, 686e6, 692e6, 698e6, 704e6, 710e6, 716e6, 722e6, 728e6, 734e6, 740e6, 746e6,
58  752e6, 758e6, 764e6, 770e6, 776e6, 782e6, 788e6, 794e6, 800e6, 806e6, 812e6, 818e6,
59  824e6, 830e6, 836e6, 842e6, 848e6, 854e6, 860e6, 866e6, 872e6, 878e6, 884e6, 890e6,
60 };
61 
63 const int europeArrayLength = 70;
65 const double europeStartFrequencies[70] = {
66  0, 0, 0, 0, 0, 174e6, 181e6, 188e6, 195e6, 202e6, 209e6, 216e6,
67  223e6, 0, 0, 0, 0, 0, 0, 0, 0, 470e6, 478e6, 486e6,
68  494e6, 502e6, 510e6, 518e6, 526e6, 534e6, 542e6, 550e6, 558e6, 566e6, 574e6, 582e6,
69  590e6, 598e6, 606e6, 614e6, 622e6, 630e6, 638e6, 646e6, 654e6, 662e6, 670e6, 678e6,
70  686e6, 694e6, 702e6, 710e6, 718e6, 726e6, 734e6, 742e6, 750e6, 758e6, 766e6, 774e6,
71  782e6, 790e6, 798e6, 806e6, 814e6, 822e6, 830e6, 838e6, 846e6, 854e6,
72 };
74 const double europeEndFrequencies[70] = {
75  0, 0, 0, 0, 0, 181e6, 188e6, 195e6, 202e6, 209e6, 216e6, 223e6,
76  230e6, 0, 0, 0, 0, 0, 0, 0, 0, 478e6, 486e6, 494e6,
77  502e6, 510e6, 518e6, 526e6, 534e6, 542e6, 550e6, 558e6, 566e6, 574e6, 582e6, 590e6,
78  598e6, 606e6, 614e6, 622e6, 630e6, 638e6, 646e6, 654e6, 662e6, 670e6, 678e6, 686e6,
79  694e6, 702e6, 710e6, 718e6, 726e6, 734e6, 742e6, 750e6, 758e6, 766e6, 774e6, 782e6,
80  790e6, 798e6, 806e6, 814e6, 822e6, 830e6, 838e6, 846e6, 854e6, 862e6,
81 };
82 
84 const int japanArrayLength = 63;
86 const double japanStartFrequencies[63] = {
87  0, 90e6, 96e6, 102e6, 170e6, 176e6, 182e6, 188e6, 192e6, 198e6, 204e6, 210e6, 216e6,
88  470e6, 476e6, 482e6, 488e6, 494e6, 500e6, 506e6, 512e6, 518e6, 524e6, 530e6, 536e6, 542e6,
89  548e6, 554e6, 560e6, 566e6, 572e6, 578e6, 584e6, 590e6, 596e6, 602e6, 608e6, 614e6, 620e6,
90  626e6, 632e6, 638e6, 644e6, 650e6, 656e6, 662e6, 668e6, 674e6, 680e6, 686e6, 692e6, 698e6,
91  704e6, 710e6, 716e6, 722e6, 728e6, 734e6, 740e6, 746e6, 752e6, 758e6, 764e6,
92 };
94 const double japanEndFrequencies[63] = {
95  0, 96e6, 102e6, 108e6, 176e6, 182e6, 188e6, 194e6, 198e6, 204e6, 210e6, 216e6, 222e6,
96  476e6, 482e6, 488e6, 494e6, 500e6, 506e6, 512e6, 518e6, 524e6, 530e6, 536e6, 542e6, 548e6,
97  554e6, 560e6, 566e6, 572e6, 578e6, 584e6, 590e6, 596e6, 602e6, 608e6, 614e6, 620e6, 626e6,
98  632e6, 638e6, 644e6, 650e6, 656e6, 662e6, 668e6, 674e6, 680e6, 686e6, 692e6, 698e6, 704e6,
99  710e6, 716e6, 722e6, 728e6, 734e6, 740e6, 746e6, 752e6, 758e6, 764e6, 770e6,
100 };
101 
103  : m_channel(nullptr),
104  m_uniRand(CreateObject<UniformRandomVariable>())
105 {
106  NS_LOG_FUNCTION(this);
107  m_factory.SetTypeId("ns3::TvSpectrumTransmitter");
108 }
109 
111 {
112  m_channel = nullptr;
113  m_uniRand = nullptr;
114  NS_LOG_FUNCTION(this);
115 }
116 
117 void
119 {
120  NS_LOG_FUNCTION(this << c);
121  m_channel = c;
122 }
123 
124 void
126 {
127  m_factory.Set(name, val);
128 }
129 
132 {
133  NS_LOG_FUNCTION(this);
134  NetDeviceContainer devCont;
135  // iterate over node container to make one transmitter for each given node
136  for (auto i = nodeCont.Begin(); i != nodeCont.End(); ++i)
137  {
138  Ptr<Node> node = *i;
140  phy->CreateTvPsd();
141  Ptr<NonCommunicatingNetDevice> dev = CreateObject<NonCommunicatingNetDevice>();
142  NS_ASSERT(phy);
143  dev->SetPhy(phy);
144  NS_ASSERT(node);
145  phy->SetMobility(node->GetObject<MobilityModel>());
146  NS_ASSERT(dev);
147  phy->SetDevice(dev);
149  phy->SetChannel(m_channel);
150  dev->SetChannel(m_channel);
151  node->AddDevice(dev);
152  devCont.Add(dev);
153  phy->Start();
154  }
155  return devCont;
156 }
157 
159 TvSpectrumTransmitterHelper::Install(NodeContainer nodeCont, Region region, uint16_t channelNumber)
160 {
161  NS_LOG_FUNCTION(this);
162  NetDeviceContainer devCont;
163  double startFrequency;
164  double channelBandwidth;
165  if (region == REGION_NORTH_AMERICA)
166  {
167  NS_ASSERT_MSG(channelNumber < northAmericaArrayLength,
168  "channel number " << channelNumber << " does not exist for this region");
169  NS_ASSERT_MSG(northAmericaStartFrequencies[channelNumber] != 0,
170  "channel number " << channelNumber << " does not exist for this region");
171  startFrequency = northAmericaStartFrequencies[channelNumber];
172  channelBandwidth =
173  northAmericaEndFrequencies[channelNumber] - northAmericaStartFrequencies[channelNumber];
174  }
175  else if (region == REGION_EUROPE)
176  {
177  NS_ASSERT_MSG(channelNumber < europeArrayLength,
178  "channel number " << channelNumber << " does not exist for this region");
179  NS_ASSERT_MSG(europeStartFrequencies[channelNumber] != 0,
180  "channel number " << channelNumber << " does not exist for this region");
181  startFrequency = europeStartFrequencies[channelNumber];
182  channelBandwidth =
183  europeEndFrequencies[channelNumber] - europeStartFrequencies[channelNumber];
184  }
185  else if (region == REGION_JAPAN)
186  {
187  NS_ASSERT_MSG(channelNumber < japanArrayLength,
188  "channel number " << channelNumber << " does not exist for this region");
189  NS_ASSERT_MSG(japanStartFrequencies[channelNumber] != 0,
190  "channel number " << channelNumber << " does not exist for this region");
191  startFrequency = japanStartFrequencies[channelNumber];
192  channelBandwidth =
193  japanEndFrequencies[channelNumber] - japanStartFrequencies[channelNumber];
194  }
195  // iterate over node container to make one transmitter for each given node
196  for (auto i = nodeCont.Begin(); i != nodeCont.End(); ++i)
197  {
198  Ptr<Node> node = *i;
200  phy->SetAttribute("StartFrequency", DoubleValue(startFrequency));
201  phy->SetAttribute("ChannelBandwidth", DoubleValue(channelBandwidth));
202  phy->CreateTvPsd();
203  Ptr<NonCommunicatingNetDevice> dev = CreateObject<NonCommunicatingNetDevice>();
204  NS_ASSERT(phy);
205  dev->SetPhy(phy);
206  NS_ASSERT(node);
207  phy->SetMobility(node->GetObject<MobilityModel>());
208  NS_ASSERT(dev);
209  phy->SetDevice(dev);
211  phy->SetChannel(m_channel);
212  dev->SetChannel(m_channel);
213  node->AddDevice(dev);
214  devCont.Add(dev);
215  phy->Start();
216  }
217  return devCont;
218 }
219 
222 {
223  NS_LOG_FUNCTION(this);
224  NetDeviceContainer devCont;
225  int index = 0;
226  DoubleValue startFrequency;
227  DoubleValue channelBandwidth;
228  // iterate over node container to make one transmitter for each given node
229  for (auto i = nodeCont.Begin(); i != nodeCont.End(); ++i)
230  {
231  Ptr<Node> node = *i;
233  phy->GetAttribute("StartFrequency", startFrequency);
234  phy->GetAttribute("ChannelBandwidth", channelBandwidth);
235  phy->SetAttribute("StartFrequency",
236  DoubleValue(startFrequency.Get() + (index * channelBandwidth.Get())));
237  phy->CreateTvPsd();
238  Ptr<NonCommunicatingNetDevice> dev = CreateObject<NonCommunicatingNetDevice>();
239  NS_ASSERT(phy);
240  dev->SetPhy(phy);
241  NS_ASSERT(node);
242  phy->SetMobility(node->GetObject<MobilityModel>());
243  NS_ASSERT(dev);
244  phy->SetDevice(dev);
246  phy->SetChannel(m_channel);
247  dev->SetChannel(m_channel);
248  node->AddDevice(dev);
249  devCont.Add(dev);
250  phy->Start();
251  index++;
252  }
253  return devCont;
254 }
255 
258  Region region,
259  uint16_t channelNumber)
260 {
261  NS_LOG_FUNCTION(this);
262  NetDeviceContainer devCont;
263  double startFrequency;
264  double channelBandwidth;
265  uint16_t currChannelNumber;
266  int index = 0;
267  // iterate over node container to make one transmitter for each given node
268  for (auto i = nodeCont.Begin(); i != nodeCont.End(); ++i)
269  {
270  currChannelNumber = channelNumber + index;
271  if (region == REGION_NORTH_AMERICA)
272  {
273  NS_ASSERT_MSG(currChannelNumber < northAmericaArrayLength,
274  "channel number " << currChannelNumber
275  << " does not exist for this region");
276  NS_ASSERT_MSG(northAmericaStartFrequencies[currChannelNumber] != 0,
277  "channel number " << currChannelNumber
278  << " does not exist for this region");
279  startFrequency = northAmericaStartFrequencies[currChannelNumber];
280  channelBandwidth = northAmericaEndFrequencies[currChannelNumber] -
281  northAmericaStartFrequencies[currChannelNumber];
282  }
283  else if (region == REGION_EUROPE)
284  {
285  NS_ASSERT_MSG(currChannelNumber < europeArrayLength,
286  "channel number " << currChannelNumber
287  << " does not exist for this region");
288  NS_ASSERT_MSG(europeStartFrequencies[currChannelNumber] != 0,
289  "channel number " << currChannelNumber
290  << " does not exist for this region");
291  startFrequency = europeStartFrequencies[currChannelNumber];
292  channelBandwidth =
293  europeEndFrequencies[currChannelNumber] - europeStartFrequencies[currChannelNumber];
294  }
295  else if (region == REGION_JAPAN)
296  {
297  NS_ASSERT_MSG(currChannelNumber < japanArrayLength,
298  "channel number " << currChannelNumber
299  << " does not exist for this region");
300  NS_ASSERT_MSG(japanStartFrequencies[currChannelNumber] != 0,
301  "channel number " << currChannelNumber
302  << " does not exist for this region");
303  startFrequency = japanStartFrequencies[currChannelNumber];
304  channelBandwidth =
305  japanEndFrequencies[currChannelNumber] - japanStartFrequencies[currChannelNumber];
306  }
307  Ptr<Node> node = *i;
309  phy->SetAttribute("StartFrequency", DoubleValue(startFrequency));
310  phy->SetAttribute("ChannelBandwidth", DoubleValue(channelBandwidth));
311  phy->CreateTvPsd();
312  Ptr<NonCommunicatingNetDevice> dev = CreateObject<NonCommunicatingNetDevice>();
313  NS_ASSERT(phy);
314  dev->SetPhy(phy);
315  NS_ASSERT(node);
316  phy->SetMobility(node->GetObject<MobilityModel>());
317  NS_ASSERT(dev);
318  phy->SetDevice(dev);
320  phy->SetChannel(m_channel);
321  dev->SetChannel(m_channel);
322  node->AddDevice(dev);
323  devCont.Add(dev);
324  phy->Start();
325  index++;
326  }
327  return devCont;
328 }
329 
330 int64_t
332 {
333  m_uniRand->SetStream(streamNum);
334  return 1;
335 }
336 
337 void
339  Density density,
340  double originLatitude,
341  double originLongitude,
342  double maxAltitude,
343  double maxRadius)
344 {
345  NS_LOG_FUNCTION(this);
346  std::list<int> transmitterIndicesToCreate;
347  if (region == REGION_NORTH_AMERICA)
348  {
349  transmitterIndicesToCreate =
352  density);
353  }
354  else if (region == REGION_EUROPE)
355  {
356  transmitterIndicesToCreate =
358  }
359  else if (region == REGION_JAPAN)
360  {
361  transmitterIndicesToCreate =
363  }
364  std::list<Vector> tvTransmitterLocations =
366  originLatitude,
367  originLongitude,
368  maxAltitude,
369  transmitterIndicesToCreate.size(),
370  maxRadius,
371  m_uniRand);
372  InstallRandomRegionalTransmitters(region, transmitterIndicesToCreate, tvTransmitterLocations);
373 }
374 
375 std::list<int>
377  const int startFrequenciesLength,
378  Density density)
379 {
380  std::vector<double> startFreqVector; // stores all non-zero start frequencies
381  for (int i = 0; i < startFrequenciesLength; i++)
382  {
383  double element = startFrequencies[i];
384  // add all non-zero frequencies to vector (0 means unused channel)
385  if (element != 0)
386  {
387  startFreqVector.push_back(element);
388  }
389  }
390 
391  // randomly generate number of transmitters to create based on density
392  uint32_t freqVectorSize = startFreqVector.size();
393  int randNumTransmitters = GetRandomNumTransmitters(density, freqVectorSize);
394 
395  // stores start frequencies that transmitters will be created to transmit
396  std::vector<double> transmitterStartFreqsToCreate;
397  for (int i = 0; i < randNumTransmitters; i++)
398  {
399  // get random index from start frequency vector
400  uint32_t randIndex = m_uniRand->GetInteger(0, startFreqVector.size() - 1);
401  // add start frequency corresponding to random index to vector
402  transmitterStartFreqsToCreate.push_back(startFreqVector[randIndex]);
403  // remove selected start frequency from vector so it is not selected again
404  startFreqVector.erase(startFreqVector.begin() + randIndex);
405  }
406 
407  // find indices on startFrequencies[] containing each start frequency that is
408  // selected to be transmitted and add to list
409  std::list<int> transmitterIndicesToCreate;
410  for (int i = 0; i < (int)transmitterStartFreqsToCreate.size(); i++)
411  {
412  for (int channelNumberIndex = 0; channelNumberIndex < startFrequenciesLength;
413  channelNumberIndex++)
414  {
415  if (startFrequencies[channelNumberIndex] == transmitterStartFreqsToCreate[i])
416  {
417  transmitterIndicesToCreate.push_back(channelNumberIndex);
418  break;
419  }
420  }
421  }
422  return transmitterIndicesToCreate;
423 }
424 
425 int
427 {
428  int numTransmitters;
429  if (density == DENSITY_LOW)
430  {
431  numTransmitters = m_uniRand->GetInteger(1, ceil(0.33 * numChannels));
432  }
433  else if (density == DENSITY_MEDIUM)
434  {
435  numTransmitters =
436  m_uniRand->GetInteger(ceil(0.33 * numChannels) + 1, ceil(0.66 * numChannels));
437  }
438  else
439  {
440  numTransmitters = m_uniRand->GetInteger(ceil(0.66 * numChannels) + 1, numChannels);
441  }
442  return numTransmitters;
443 }
444 
445 void
447  Region region,
448  std::list<int> transmitterIndicesToCreate,
449  std::list<Vector> transmitterLocations)
450 {
451  int numTransmitters = (int)transmitterIndicesToCreate.size();
452  for (int transNum = 0; transNum < numTransmitters; transNum++)
453  {
454  Ptr<ListPositionAllocator> nodePosition = CreateObject<ListPositionAllocator>();
455  // add generated coordinate point to node position
456  nodePosition->Add(transmitterLocations.front());
458  mobility.SetPositionAllocator(nodePosition);
459  mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
460  NodeContainer tvNode; // contains position of transmitter to be created
461  tvNode.Create(1);
462  mobility.Install(tvNode);
463  // set channel number for this transmitter
464  auto channelNumber = (uint16_t)transmitterIndicesToCreate.front();
465  Install(tvNode, region, channelNumber); // install tv transmitter
466  transmitterLocations.pop_front(); // remove created transmitter location
467  transmitterIndicesToCreate.pop_front(); // remove created transmitter index
468  }
469 }
470 
471 } // namespace ns3
Hold a value for an Attribute.
Definition: attribute.h:70
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
double Get() const
Definition: double.cc:37
static std::list< Vector > RandCartesianPointsAroundGeographicPoint(double originLatitude, double originLongitude, double maxAltitude, int numPoints, double maxDistFromOrigin, Ptr< UniformRandomVariable > uniRand)
Generates uniformly distributed random points (in ECEF Cartesian coordinates) within a given altitude...
Helper class used to assign positions and mobility models to nodes.
Keep track of the current position and velocity of an object.
holds a vector of ns3::NetDevice pointers
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
keep track of a set of node pointers.
Iterator End() const
Get an iterator which indicates past-the-last Node in the container.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Iterator Begin() const
Get an iterator which refers to the first Node in the container.
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:138
Ptr< Object > Create() const
Create an Object instance of the configured TypeId.
void Set(const std::string &name, const AttributeValue &value, Args &&... args)
Set an attribute to be set during construction.
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
std::list< int > GenerateRegionalTransmitterIndices(const double startFrequencies[], const int startFrequenciesLength, Density density)
Generates random indices of given region frequency array (ignoring indices referring to invalid chann...
void SetChannel(Ptr< SpectrumChannel > c)
Set the spectrum channel for the device(s) to transmit on.
NetDeviceContainer InstallAdjacent(NodeContainer nodes)
Set up and start the TV Transmitter's transmission on the spectrum channel.
Density
density of location that TV transmitters are being set up in
void InstallRandomRegionalTransmitters(Region region, std::list< int > transmitterIndicesToCreate, std::list< Vector > transmitterLocations)
Installs each randomly generated regional TV transmitter.
Region
geographical region that TV transmitters are being set up in
int GetRandomNumTransmitters(Density density, uint32_t numChannels)
Randomly generates the number of TV transmitters to be created based on given density and number of p...
Ptr< UniformRandomVariable > m_uniRand
Object to generate uniform random numbers.
int64_t AssignStreams(int64_t streamNum)
Assigns the stream number for the uniform random number generator to use.
ObjectFactory m_factory
Object factory for attribute setting.
void CreateRegionalTvTransmitters(Region region, Density density, double originLatitude, double originLongitude, double maxAltitude, double maxRadius)
Generates and installs (starts transmission on the spectrum channel) a random number of TV transmitte...
void SetAttribute(std::string name, const AttributeValue &val)
Set attribute for each TvSpectrumTransmitter instance to be created.
NetDeviceContainer Install(NodeContainer nodes)
Set up and start the TV Transmitter's transmission on the spectrum channel.
Ptr< SpectrumChannel > m_channel
Pointer to spectrum channel object.
SpectrumPhy implementation that creates a customizable TV transmitter which transmits a PSD spectrum ...
The uniform distribution Random Number Generator (RNG).
uint32_t GetInteger(uint32_t min, uint32_t max)
Get the next random value drawn from the distribution.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition: object.h:579
Every class exported by the ns3 library is enclosed in the ns3 namespace.
const double northAmericaEndFrequencies[84]
NORTH AMERICA end frequencies.
const int japanArrayLength
JAPAN: 63 elements (index 0 - 62); valid channels = 1 - 62.
const double europeEndFrequencies[70]
EUROPE end frequencies.
const int northAmericaArrayLength
NORTH AMERICA: 84 elements (index 0 - 83); valid channels = 2 - 83.
const double japanStartFrequencies[63]
JAPAN start frequencies.
const double europeStartFrequencies[70]
EUROPE start frequencies.
const double japanEndFrequencies[63]
JAPAN end frequencies.
const double northAmericaStartFrequencies[84]
NORTH AMERICA start frequencies.
const int europeArrayLength
EUROPE: 70 elements (index 0 - 69); valid channels = 5 - 12, 21 - 69.
mobility
Definition: third.py:105
phy
Definition: third.py:89