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