A Discrete-Event Network Simulator
API
tv-spectrum-transmitter.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/antenna-model.h>
23 #include <ns3/double.h>
24 #include <ns3/enum.h>
25 #include <ns3/integer.h>
26 #include <ns3/isotropic-antenna-model.h>
27 #include <ns3/log.h>
28 #include <ns3/pointer.h>
29 #include <ns3/simulator.h>
30 #include <ns3/string.h>
31 #include <ns3/uinteger.h>
32 
33 #include <cmath>
34 
35 namespace ns3
36 {
37 
38 NS_LOG_COMPONENT_DEFINE("TvSpectrumTransmitter");
39 
40 NS_OBJECT_ENSURE_REGISTERED(TvSpectrumTransmitter);
41 
43  : m_mobility(nullptr),
44  m_antenna(CreateObject<IsotropicAntennaModel>()),
45  m_netDevice(nullptr),
46  m_channel(nullptr),
47  m_tvType(TVTYPE_8VSB),
48  m_startFrequency(500e6),
49  m_channelBandwidth(6e6),
50  m_basePsd(20),
51  m_txPsd(nullptr),
52  m_startingTime(Seconds(0)),
53  m_transmitDuration(Seconds(0.2)),
54  m_active(false)
55 {
56  NS_LOG_FUNCTION(this);
57 }
58 
60 {
61  m_mobility = nullptr;
62  m_antenna = nullptr;
63  m_netDevice = nullptr;
64  m_channel = nullptr;
65  m_txPsd = nullptr;
66  NS_LOG_FUNCTION(this);
67 }
68 
69 TypeId
71 {
72  static TypeId tid =
73  TypeId("ns3::TvSpectrumTransmitter")
75  .SetGroupName("Spectrum")
76  .AddConstructor<TvSpectrumTransmitter>()
77  .AddAttribute("TvType",
78  "The type of TV transmitter/modulation to be used.",
82  "8vsb",
84  "cofdm",
86  "analog"))
87  .AddAttribute("StartFrequency",
88  "The lower end frequency (in Hz) of the TV transmitter's "
89  "signal. Must be greater than or equal to 0.",
90  DoubleValue(500e6),
92  MakeDoubleChecker<double>(0, std::numeric_limits<double>::max()))
93  .AddAttribute("ChannelBandwidth",
94  "The bandwidth (in Hz) of the TV transmitter's signal. Must "
95  "be greater than or equal to 0.",
96  DoubleValue(6e6),
98  MakeDoubleChecker<double>(0, std::numeric_limits<double>::max()))
99  .AddAttribute("BasePsd",
100  "The base power spectral density (in dBm/Hz) of the TV "
101  "transmitter's transmitted spectrum. Base PSD is the "
102  "maximum PSD of the spectrum excluding pilots. For analog "
103  "and COFDM transmitters this is the maximum PSD, but for "
104  "8-VSB transmitters this is the maximum PSD of the main "
105  "signal spectrum (flat-top segment) since the pilot "
106  "actually has the maximum PSD overall.",
107  DoubleValue(20),
109  MakeDoubleChecker<double>())
110  .AddAttribute("Antenna",
111  "The AntennaModel to be used. Allows classes inherited "
112  "from ns3::AntennaModel. Defaults to ns3::IsotropicAntennaModel.",
113  StringValue("ns3::IsotropicAntennaModel"),
115  MakePointerChecker<AntennaModel>())
116  .AddAttribute("StartingTime",
117  "The time point after the simulation begins in which the TV "
118  "transmitter will begin transmitting.",
119  TimeValue(Seconds(0)),
121  MakeTimeChecker())
122  .AddAttribute("TransmitDuration",
123  "The duration of time that the TV transmitter will transmit for.",
124  TimeValue(Seconds(0.2)),
126  MakeTimeChecker());
127  return tid;
128 }
129 
130 void
132 {
133  NS_LOG_FUNCTION(this << c);
134  m_channel = c;
135 }
136 
137 void
139 {
140  NS_LOG_FUNCTION(this << m);
141  m_mobility = m;
142 }
143 
144 void
146 {
147  NS_LOG_FUNCTION(this << d);
148  m_netDevice = d;
149 }
150 
153 {
154  NS_LOG_FUNCTION(this);
155  return m_mobility;
156 }
157 
160 {
161  NS_LOG_FUNCTION(this);
162  return m_netDevice;
163 }
164 
167 {
168  NS_LOG_FUNCTION(this);
169  return nullptr;
170 }
171 
174 {
175  NS_LOG_FUNCTION(this);
176  return m_antenna;
177 }
178 
179 void
181 {
182  NS_LOG_FUNCTION(this << params);
183 }
184 
187 {
188  NS_LOG_FUNCTION(this);
189  return m_channel;
190 }
191 
194 {
200  TvSpectrumModelId(double stFreq, double bwidth);
201  double startFrequency;
202  double bandwidth;
203 };
204 
205 TvSpectrumModelId::TvSpectrumModelId(double stFreq, double bwidth)
206  : startFrequency(stFreq),
207  bandwidth(bwidth)
208 {
209 }
210 
218 bool
220 {
221  return ((a.startFrequency < b.startFrequency) ||
222  ((a.startFrequency == b.startFrequency) && (a.bandwidth < b.bandwidth)));
223 }
224 
226 static std::map<TvSpectrumModelId, Ptr<SpectrumModel>> g_tvSpectrumModelMap;
227 
242 void
244 {
245  NS_LOG_FUNCTION(this);
247  Ptr<SpectrumModel> model;
249  std::map<TvSpectrumModelId, Ptr<SpectrumModel>>::iterator iter = g_tvSpectrumModelMap.find(key);
250  if (iter != g_tvSpectrumModelMap.end())
251  {
252  model = iter->second; // set SpectrumModel to previously created one
253  }
254  else // no previously created SpectrumModel with same frequency and bandwidth
255  {
256  Bands bands;
257  double halfSubBand = 0.5 * (m_channelBandwidth / 100);
258  for (double fl = m_startFrequency - halfSubBand;
259  fl <= (m_startFrequency - halfSubBand) + m_channelBandwidth;
260  fl += m_channelBandwidth / 100)
261  {
262  BandInfo bi;
263  bi.fl = fl;
264  bi.fc = fl + halfSubBand;
265  bi.fh = fl + (2 * halfSubBand);
266  bands.push_back(bi);
267  }
268  model = Create<SpectrumModel>(bands);
269  g_tvSpectrumModelMap.insert(std::pair<TvSpectrumModelId, Ptr<SpectrumModel>>(key, model));
270  }
271  Ptr<SpectrumValue> psd = Create<SpectrumValue>(model);
272  double basePsdWattsHz = pow(10.0, (m_basePsd - 30) / 10.0); // convert dBm to W/Hz
273  switch (m_tvType)
274  {
275  case TVTYPE_8VSB: {
276  for (int i = 0; i <= 100; i++)
277  {
278  switch (i)
279  {
280  case 0:
281  case 100:
282  (*psd)[i] = 0.015 * basePsdWattsHz;
283  break;
284  case 1:
285  case 99:
286  (*psd)[i] = 0.019 * basePsdWattsHz;
287  break;
288  case 2:
289  case 98:
290  (*psd)[i] = 0.034 * basePsdWattsHz;
291  break;
292  case 3:
293  case 97:
294  (*psd)[i] = 0.116 * basePsdWattsHz;
295  break;
296  case 4:
297  case 96:
298  (*psd)[i] = 0.309 * basePsdWattsHz;
299  break;
300  case 5:
301  (*psd)[i] = (0.502 * basePsdWattsHz) + (21.577 * basePsdWattsHz); // pilot
302  break;
303  case 6:
304  case 94:
305  (*psd)[i] = 0.696 * basePsdWattsHz;
306  break;
307  case 7:
308  case 93:
309  (*psd)[i] = 0.913 * basePsdWattsHz;
310  break;
311  case 8:
312  case 92:
313  (*psd)[i] = 0.978 * basePsdWattsHz;
314  break;
315  case 9:
316  case 91:
317  (*psd)[i] = 0.990 * basePsdWattsHz;
318  break;
319  case 95:
320  (*psd)[i] = 0.502 * basePsdWattsHz;
321  break;
322  default:
323  (*psd)[i] = basePsdWattsHz;
324  break;
325  }
326  }
327  break;
328  }
329  case TVTYPE_COFDM: {
330  for (int i = 0; i <= 100; i++)
331  {
332  switch (i)
333  {
334  case 0:
335  case 100:
336  (*psd)[i] = 1.52e-4 * basePsdWattsHz;
337  break;
338  case 1:
339  case 99:
340  (*psd)[i] = 2.93e-4 * basePsdWattsHz;
341  break;
342  case 2:
343  case 98:
344  (*psd)[i] = 8.26e-4 * basePsdWattsHz;
345  break;
346  case 3:
347  case 97:
348  (*psd)[i] = 0.0927 * basePsdWattsHz;
349  break;
350  default:
351  (*psd)[i] = basePsdWattsHz;
352  break;
353  }
354  }
355  break;
356  }
357  case TVTYPE_ANALOG: {
358  for (int i = 0; i <= 100; i++)
359  {
360  switch (i)
361  {
362  case 0:
363  case 1:
364  case 2:
365  case 3:
366  (*psd)[i] = 27.07946e-08 * basePsdWattsHz;
367  break;
368  case 4:
369  case 5:
370  case 6:
371  (*psd)[i] = 2.51189e-07 * basePsdWattsHz;
372  break;
373  case 7:
374  case 8:
375  case 9:
376  (*psd)[i] = 1e-06 * basePsdWattsHz;
377  break;
378  case 10:
379  case 11:
380  case 12:
381  (*psd)[i] = 2.39883e-06 * basePsdWattsHz;
382  break;
383  case 13:
384  case 14:
385  case 15:
386  (*psd)[i] = 5.62341e-06 * basePsdWattsHz;
387  break;
388  case 16:
389  case 17:
390  case 18:
391  (*psd)[i] = 6.68344e-06 * basePsdWattsHz;
392  break;
393  case 19:
394  case 20:
395  case 21:
396  (*psd)[i] = 1.25893e-05 * basePsdWattsHz;
397  break;
398  case 22:
399  case 23:
400  case 24:
401  (*psd)[i] = 3.16228e-05 * basePsdWattsHz;
402  break;
403  case 25:
404  (*psd)[i] = 0.000158489 * basePsdWattsHz;
405  break;
406  case 26:
407  (*psd)[i] = basePsdWattsHz;
408  break;
409  case 27:
410  (*psd)[i] = 7.49894e-05 * basePsdWattsHz;
411  break;
412  case 28:
413  case 29:
414  case 30:
415  (*psd)[i] = 2.37137e-05 * basePsdWattsHz;
416  break;
417  case 31:
418  case 32:
419  case 33:
420  (*psd)[i] = 1.14815e-05 * basePsdWattsHz;
421  break;
422  case 34:
423  case 35:
424  case 36:
425  (*psd)[i] = 7.49894e-06 * basePsdWattsHz;
426  break;
427  case 37:
428  case 38:
429  case 39:
430  (*psd)[i] = 5.62341e-06 * basePsdWattsHz;
431  break;
432  case 40:
433  case 41:
434  case 42:
435  (*psd)[i] = 4.21697e-06 * basePsdWattsHz;
436  break;
437  case 43:
438  case 44:
439  case 45:
440  (*psd)[i] = 3.16228e-06 * basePsdWattsHz;
441  break;
442  case 46:
443  case 47:
444  case 48:
445  (*psd)[i] = 1.99526e-06 * basePsdWattsHz;
446  break;
447  case 49:
448  case 50:
449  case 51:
450  (*psd)[i] = 1.25893e-06 * basePsdWattsHz;
451  break;
452  case 52:
453  case 53:
454  case 54:
455  (*psd)[i] = 8.41395e-07 * basePsdWattsHz;
456  break;
457  case 55:
458  case 56:
459  case 57:
460  (*psd)[i] = 6.30957e-07 * basePsdWattsHz;
461  break;
462  case 58:
463  case 59:
464  case 60:
465  (*psd)[i] = 5.88844e-07 * basePsdWattsHz;
466  break;
467  case 61:
468  case 62:
469  case 63:
470  (*psd)[i] = 5.62341e-07 * basePsdWattsHz;
471  break;
472  case 64:
473  case 65:
474  case 66:
475  (*psd)[i] = 5.30884e-07 * basePsdWattsHz;
476  break;
477  case 67:
478  case 68:
479  case 69:
480  (*psd)[i] = 5.01187e-07 * basePsdWattsHz;
481  break;
482  case 70:
483  case 71:
484  case 72:
485  (*psd)[i] = 5.30884e-07 * basePsdWattsHz;
486  break;
487  case 73:
488  case 74:
489  case 75:
490  (*psd)[i] = 7.49894e-07 * basePsdWattsHz;
491  break;
492  case 76:
493  case 77:
494  case 78:
495  (*psd)[i] = 1.77828e-06 * basePsdWattsHz;
496  break;
497  case 79:
498  (*psd)[i] = 5.62341e-06 * basePsdWattsHz;
499  break;
500  case 80:
501  (*psd)[i] = 0.000177828 * basePsdWattsHz;
502  break;
503  case 81:
504  (*psd)[i] = 4.21697e-06 * basePsdWattsHz;
505  break;
506  case 82:
507  case 83:
508  case 84:
509  (*psd)[i] = 3.16228e-06 * basePsdWattsHz;
510  break;
511  case 85:
512  case 86:
513  case 87:
514  (*psd)[i] = 3.16228e-06 * basePsdWattsHz;
515  break;
516  case 88:
517  case 89:
518  case 90:
519  (*psd)[i] = 4.73151e-06 * basePsdWattsHz;
520  break;
521  case 91:
522  case 92:
523  case 93:
524  (*psd)[i] = 7.49894e-06 * basePsdWattsHz;
525  break;
526  case 94:
527  (*psd)[i] = 7.49894e-05 * basePsdWattsHz;
528  break;
529  case 95:
530  (*psd)[i] = 0.1 * basePsdWattsHz;
531  break;
532  case 96:
533  (*psd)[i] = 7.49894e-05 * basePsdWattsHz;
534  break;
535  case 97:
536  case 98:
537  case 99:
538  case 100:
539  (*psd)[i] = 1.77828e-06 * basePsdWattsHz;
540  break;
541  }
542  }
543  break;
544  }
545  default: {
546  NS_LOG_ERROR("no valid TvType selected");
547  break;
548  }
549  }
550  m_txPsd = psd;
551 }
552 
555 {
556  NS_LOG_FUNCTION(this);
557  return m_txPsd;
558 }
559 
560 void
562 {
563  NS_LOG_FUNCTION(this);
565  Ptr<SpectrumSignalParameters> signal = Create<SpectrumSignalParameters>();
566  signal->duration = m_transmitDuration;
567  signal->psd = m_txPsd;
568  signal->txPhy = GetObject<SpectrumPhy>();
569  signal->txAntenna = m_antenna;
570  m_channel->StartTx(signal);
571 }
572 
573 void
575 {
576  NS_LOG_FUNCTION(this);
577  if (!m_active)
578  {
579  NS_LOG_LOGIC("starting TV transmitter");
580  m_active = true;
582  }
583 }
584 
585 void
587 {
588  NS_LOG_FUNCTION(this);
589  m_active = false;
590 }
591 
592 } // namespace ns3
#define max(a, b)
Definition: 80211b.c:43
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
Hold variables of type enum.
Definition: enum.h:56
Isotropic antenna model.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
Abstract base class for Spectrum-aware PHY layers.
Definition: spectrum-phy.h:46
Hold variables of type string.
Definition: string.h:56
AttributeValue implementation for Time.
Definition: nstime.h:1423
SpectrumPhy implementation that creates a customizable TV transmitter which transmits a PSD spectrum ...
Ptr< AntennaModel > m_antenna
Pointer to antenna model object.
TvType m_tvType
Type of TV transmitter.
Ptr< MobilityModel > GetMobility() const override
Get the associated MobilityModel instance.
virtual void CreateTvPsd()
Creates power spectral density (PSD) spectrum of the TV transmitter and sets it for transmission.
double m_basePsd
Base power spectral density value (in dBm/Hz) of TV transmitter's signal.
Time m_transmitDuration
Length of time that TV transmitter will transmit for.
bool m_active
True if TV transmitter is transmitting.
Ptr< NetDevice > m_netDevice
Pointer to net device object.
virtual void Start()
Starts the TV Transmitter's transmission on the spectrum channel.
void SetDevice(Ptr< NetDevice > d) override
Set the associated NetDevice instance.
void SetMobility(Ptr< MobilityModel > m) override
Set the mobility model associated with this device.
double m_channelBandwidth
Bandwidth (in Hz) of TV transmitter's signal.
double m_startFrequency
Start frequency (in Hz) of TV transmitter's signal.
Time m_startingTime
Timepoint after simulation begins that TV transmitter will begin transmitting.
virtual void Stop()
Stops the TV Transmitter's transmission on the spectrum channel.
virtual void SetupTx()
Sets up signal to be transmitted.
Ptr< const SpectrumModel > GetRxSpectrumModel() const override
Ptr< SpectrumValue > GetTxPsd() const
Get the power spectral density of the TV transmitter's signal.
Ptr< SpectrumChannel > GetChannel() const
Get the spectrum channel.
Ptr< Object > GetAntenna() const override
Get the AntennaModel used by this SpectrumPhy instance for transmission and/or reception.
void SetChannel(Ptr< SpectrumChannel > c) override
Set the channel attached to this device.
static TypeId GetTypeId()
Register this type.
Ptr< SpectrumChannel > m_channel
Pointer to spectrum channel object.
void StartRx(Ptr< SpectrumSignalParameters > params) override
Notify the SpectrumPhy instance of an incoming signal.
Ptr< NetDevice > GetDevice() const override
Get the associated NetDevice instance.
Ptr< SpectrumValue > m_txPsd
Pointer to power spectral density of TV transmitter's signal.
Ptr< MobilityModel > m_mobility
Pointer to mobility model object.
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
#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
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: double.h:43
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: enum.h:205
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: pointer.h:231
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: nstime.h:1424
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#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
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::vector< BandInfo > Bands
Container of BandInfo.
Ptr< const AttributeChecker > MakeEnumChecker(int v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition: enum.h:163
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:535
bool operator<(const EventId &a, const EventId &b)
Definition: event-id.h:170
static std::map< TvSpectrumModelId, Ptr< SpectrumModel > > g_tvSpectrumModelMap
Stores created spectrum models.
params
Fit Fluctuating Two Ray model to the 3GPP TR 38.901 using the Anderson-Darling goodness-of-fit ##.
The building block of a SpectrumModel.
double fc
center frequency
double fl
lower limit of subband
double fh
upper limit of subband
Ptr< AntennaModel > txAntenna
The AntennaModel instance that was used to transmit this signal.
Time duration
The duration of the packet transmission.
Ptr< SpectrumPhy > txPhy
The SpectrumPhy instance that is making the transmission.
Ptr< SpectrumValue > psd
The Power Spectral Density of the waveform, in linear units.
Used as key for map containing created spectrum models.
TvSpectrumModelId(double stFreq, double bwidth)
Constructor.
double startFrequency
Start frequency [Hz].
double bandwidth
Bandwidth [Hz].