A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
tv-spectrum-transmitter.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2014 University of Washington
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Benjamin Cizdziel <ben.cizdziel@gmail.com>
7 */
8
10
11#include <ns3/antenna-model.h>
12#include <ns3/double.h>
13#include <ns3/enum.h>
14#include <ns3/integer.h>
15#include <ns3/isotropic-antenna-model.h>
16#include <ns3/log.h>
17#include <ns3/pointer.h>
18#include <ns3/simulator.h>
19#include <ns3/string.h>
20#include <ns3/uinteger.h>
21
22#include <cmath>
23
24namespace ns3
25{
26
27NS_LOG_COMPONENT_DEFINE("TvSpectrumTransmitter");
28
29NS_OBJECT_ENSURE_REGISTERED(TvSpectrumTransmitter);
30
32 : m_mobility(nullptr),
34 m_netDevice(nullptr),
35 m_channel(nullptr),
36 m_tvType(TVTYPE_8VSB),
37 m_startFrequency(500e6),
38 m_channelBandwidth(6e6),
39 m_basePsd(20),
40 m_txPsd(nullptr),
41 m_startingTime(Seconds(0)),
42 m_transmitDuration(Seconds(0.2)),
43 m_active(false)
44{
45 NS_LOG_FUNCTION(this);
46}
47
49{
50 m_mobility = nullptr;
51 m_antenna = nullptr;
52 m_netDevice = nullptr;
53 m_channel = nullptr;
54 m_txPsd = nullptr;
55 NS_LOG_FUNCTION(this);
56}
57
60{
61 static TypeId tid =
62 TypeId("ns3::TvSpectrumTransmitter")
64 .SetGroupName("Spectrum")
65 .AddConstructor<TvSpectrumTransmitter>()
66 .AddAttribute(
67 "TvType",
68 "The type of TV transmitter/modulation to be used.",
72 "8vsb",
74 "cofdm",
76 "analog"))
77 .AddAttribute("StartFrequency",
78 "The lower end frequency (in Hz) of the TV transmitter's "
79 "signal. Must be greater than or equal to 0.",
80 DoubleValue(500e6),
82 MakeDoubleChecker<double>(0, std::numeric_limits<double>::max()))
83 .AddAttribute("ChannelBandwidth",
84 "The bandwidth (in Hz) of the TV transmitter's signal. Must "
85 "be greater than or equal to 0.",
86 DoubleValue(6e6),
88 MakeDoubleChecker<double>(0, std::numeric_limits<double>::max()))
89 .AddAttribute("BasePsd",
90 "The base power spectral density (in dBm/Hz) of the TV "
91 "transmitter's transmitted spectrum. Base PSD is the "
92 "maximum PSD of the spectrum excluding pilots. For analog "
93 "and COFDM transmitters this is the maximum PSD, but for "
94 "8-VSB transmitters this is the maximum PSD of the main "
95 "signal spectrum (flat-top segment) since the pilot "
96 "actually has the maximum PSD overall.",
97 DoubleValue(20),
100 .AddAttribute("Antenna",
101 "The AntennaModel to be used. Allows classes inherited "
102 "from ns3::AntennaModel. Defaults to ns3::IsotropicAntennaModel.",
103 StringValue("ns3::IsotropicAntennaModel"),
106 .AddAttribute("StartingTime",
107 "The time point after the simulation begins in which the TV "
108 "transmitter will begin transmitting.",
109 TimeValue(Seconds(0)),
112 .AddAttribute("TransmitDuration",
113 "The duration of time that the TV transmitter will transmit for.",
114 TimeValue(Seconds(0.2)),
117 return tid;
118}
119
120void
126
127void
133
134void
140
143{
144 NS_LOG_FUNCTION(this);
145 return m_mobility;
146}
147
150{
151 NS_LOG_FUNCTION(this);
152 return m_netDevice;
153}
154
157{
158 NS_LOG_FUNCTION(this);
159 return nullptr;
160}
161
164{
165 NS_LOG_FUNCTION(this);
166 return m_antenna;
167}
168
169void
174
177{
178 NS_LOG_FUNCTION(this);
179 return m_channel;
180}
181
182/// Used as key for map containing created spectrum models
184{
185 /**
186 * Constructor
187 * \param stFreq Start frequency [Hz]
188 * \param bwidth Bandwidth [Hz]
189 */
190 TvSpectrumModelId(double stFreq, double bwidth);
191 double startFrequency; //!< Start frequency [Hz]
192 double bandwidth; //!< Bandwidth [Hz]
193};
194
195TvSpectrumModelId::TvSpectrumModelId(double stFreq, double bwidth)
196 : startFrequency(stFreq),
197 bandwidth(bwidth)
198{
199}
200
201/**
202 * Minus-than operator
203 * \param a left operand
204 * \param b right operand
205 * \returns true if the left operand has a lower starting frequency
206 * or a smaller bandwidth (if both have the same starting freq.)
207 */
208bool
210{
211 return ((a.startFrequency < b.startFrequency) ||
212 ((a.startFrequency == b.startFrequency) && (a.bandwidth < b.bandwidth)));
213}
214
215/// Stores created spectrum models
216static std::map<TvSpectrumModelId, Ptr<SpectrumModel>> g_tvSpectrumModelMap;
217
218/**
219 * 8-VSB PSD approximated from Figure 3 of the following article:
220 * Baron, Stanley. "First-Hand:Digital Television: The Digital Terrestrial
221 * Television Broadcasting (DTTB) Standard." IEEE Global History Network.
222 * <http://www.ieeeghn.org/wiki/index.php/First-Hand:Digital_Television:_The_Digital_Terrestrial_Television_Broadcasting_(DTTB)_Standard>.
223 *
224 * COFDM PSD approximated from Figure 12 (8k mode) of the following article:
225 * Kopp, Carlo. "High Definition Television." High Definition Television. Air
226 * Power Australia. <http://www.ausairpower.net/AC-1100.html>.
227 *
228 * Analog PSD approximated from Figure 4 of the following paper:
229 * Stephen Shellhammer, Ahmed Sadek, and Wenyi Zhang. "Technical Challenges for
230 * Cognitive Radio in the TV White Space Spectrum." Qualcomm Incorporated.
231 */
232void
234{
235 NS_LOG_FUNCTION(this);
237 Ptr<SpectrumModel> model;
239 auto iter = g_tvSpectrumModelMap.find(key);
240 if (iter != g_tvSpectrumModelMap.end())
241 {
242 model = iter->second; // set SpectrumModel to previously created one
243 }
244 else // no previously created SpectrumModel with same frequency and bandwidth
245 {
246 Bands bands;
247 double halfSubBand = 0.5 * (m_channelBandwidth / 100);
248 for (double fl = m_startFrequency - halfSubBand;
249 fl <= (m_startFrequency - halfSubBand) + m_channelBandwidth;
250 fl += m_channelBandwidth / 100)
251 {
252 BandInfo bi;
253 bi.fl = fl;
254 bi.fc = fl + halfSubBand;
255 bi.fh = fl + (2 * halfSubBand);
256 bands.push_back(bi);
257 }
258 model = Create<SpectrumModel>(bands);
259 g_tvSpectrumModelMap.insert(std::pair<TvSpectrumModelId, Ptr<SpectrumModel>>(key, model));
260 }
262 double basePsdWattsHz = pow(10.0, (m_basePsd - 30) / 10.0); // convert dBm to W/Hz
263 switch (m_tvType)
264 {
265 case TVTYPE_8VSB: {
266 for (int i = 0; i <= 100; i++)
267 {
268 switch (i)
269 {
270 case 0:
271 case 100:
272 (*psd)[i] = 0.015 * basePsdWattsHz;
273 break;
274 case 1:
275 case 99:
276 (*psd)[i] = 0.019 * basePsdWattsHz;
277 break;
278 case 2:
279 case 98:
280 (*psd)[i] = 0.034 * basePsdWattsHz;
281 break;
282 case 3:
283 case 97:
284 (*psd)[i] = 0.116 * basePsdWattsHz;
285 break;
286 case 4:
287 case 96:
288 (*psd)[i] = 0.309 * basePsdWattsHz;
289 break;
290 case 5:
291 (*psd)[i] = (0.502 * basePsdWattsHz) + (21.577 * basePsdWattsHz); // pilot
292 break;
293 case 6:
294 case 94:
295 (*psd)[i] = 0.696 * basePsdWattsHz;
296 break;
297 case 7:
298 case 93:
299 (*psd)[i] = 0.913 * basePsdWattsHz;
300 break;
301 case 8:
302 case 92:
303 (*psd)[i] = 0.978 * basePsdWattsHz;
304 break;
305 case 9:
306 case 91:
307 (*psd)[i] = 0.990 * basePsdWattsHz;
308 break;
309 case 95:
310 (*psd)[i] = 0.502 * basePsdWattsHz;
311 break;
312 default:
313 (*psd)[i] = basePsdWattsHz;
314 break;
315 }
316 }
317 break;
318 }
319 case TVTYPE_COFDM: {
320 for (int i = 0; i <= 100; i++)
321 {
322 switch (i)
323 {
324 case 0:
325 case 100:
326 (*psd)[i] = 1.52e-4 * basePsdWattsHz;
327 break;
328 case 1:
329 case 99:
330 (*psd)[i] = 2.93e-4 * basePsdWattsHz;
331 break;
332 case 2:
333 case 98:
334 (*psd)[i] = 8.26e-4 * basePsdWattsHz;
335 break;
336 case 3:
337 case 97:
338 (*psd)[i] = 0.0927 * basePsdWattsHz;
339 break;
340 default:
341 (*psd)[i] = basePsdWattsHz;
342 break;
343 }
344 }
345 break;
346 }
347 case TVTYPE_ANALOG: {
348 for (int i = 0; i <= 100; i++)
349 {
350 switch (i)
351 {
352 case 0:
353 case 1:
354 case 2:
355 case 3:
356 (*psd)[i] = 27.07946e-08 * basePsdWattsHz;
357 break;
358 case 4:
359 case 5:
360 case 6:
361 (*psd)[i] = 2.51189e-07 * basePsdWattsHz;
362 break;
363 case 7:
364 case 8:
365 case 9:
366 (*psd)[i] = 1e-06 * basePsdWattsHz;
367 break;
368 case 10:
369 case 11:
370 case 12:
371 (*psd)[i] = 2.39883e-06 * basePsdWattsHz;
372 break;
373 case 13:
374 case 14:
375 case 15:
376 (*psd)[i] = 5.62341e-06 * basePsdWattsHz;
377 break;
378 case 16:
379 case 17:
380 case 18:
381 (*psd)[i] = 6.68344e-06 * basePsdWattsHz;
382 break;
383 case 19:
384 case 20:
385 case 21:
386 (*psd)[i] = 1.25893e-05 * basePsdWattsHz;
387 break;
388 case 22:
389 case 23:
390 case 24:
391 (*psd)[i] = 3.16228e-05 * basePsdWattsHz;
392 break;
393 case 25:
394 (*psd)[i] = 0.000158489 * basePsdWattsHz;
395 break;
396 case 26:
397 (*psd)[i] = basePsdWattsHz;
398 break;
399 case 27:
400 (*psd)[i] = 7.49894e-05 * basePsdWattsHz;
401 break;
402 case 28:
403 case 29:
404 case 30:
405 (*psd)[i] = 2.37137e-05 * basePsdWattsHz;
406 break;
407 case 31:
408 case 32:
409 case 33:
410 (*psd)[i] = 1.14815e-05 * basePsdWattsHz;
411 break;
412 case 34:
413 case 35:
414 case 36:
415 (*psd)[i] = 7.49894e-06 * basePsdWattsHz;
416 break;
417 case 37:
418 case 38:
419 case 39:
420 (*psd)[i] = 5.62341e-06 * basePsdWattsHz;
421 break;
422 case 40:
423 case 41:
424 case 42:
425 (*psd)[i] = 4.21697e-06 * basePsdWattsHz;
426 break;
427 case 43:
428 case 44:
429 case 45:
430 (*psd)[i] = 3.16228e-06 * basePsdWattsHz;
431 break;
432 case 46:
433 case 47:
434 case 48:
435 (*psd)[i] = 1.99526e-06 * basePsdWattsHz;
436 break;
437 case 49:
438 case 50:
439 case 51:
440 (*psd)[i] = 1.25893e-06 * basePsdWattsHz;
441 break;
442 case 52:
443 case 53:
444 case 54:
445 (*psd)[i] = 8.41395e-07 * basePsdWattsHz;
446 break;
447 case 55:
448 case 56:
449 case 57:
450 (*psd)[i] = 6.30957e-07 * basePsdWattsHz;
451 break;
452 case 58:
453 case 59:
454 case 60:
455 (*psd)[i] = 5.88844e-07 * basePsdWattsHz;
456 break;
457 case 61:
458 case 62:
459 case 63:
460 (*psd)[i] = 5.62341e-07 * basePsdWattsHz;
461 break;
462 case 64:
463 case 65:
464 case 66:
465 (*psd)[i] = 5.30884e-07 * basePsdWattsHz;
466 break;
467 case 67:
468 case 68:
469 case 69:
470 (*psd)[i] = 5.01187e-07 * basePsdWattsHz;
471 break;
472 case 70:
473 case 71:
474 case 72:
475 (*psd)[i] = 5.30884e-07 * basePsdWattsHz;
476 break;
477 case 73:
478 case 74:
479 case 75:
480 (*psd)[i] = 7.49894e-07 * basePsdWattsHz;
481 break;
482 case 76:
483 case 77:
484 case 78:
485 (*psd)[i] = 1.77828e-06 * basePsdWattsHz;
486 break;
487 case 79:
488 (*psd)[i] = 5.62341e-06 * basePsdWattsHz;
489 break;
490 case 80:
491 (*psd)[i] = 0.000177828 * basePsdWattsHz;
492 break;
493 case 81:
494 (*psd)[i] = 4.21697e-06 * basePsdWattsHz;
495 break;
496 case 82:
497 case 83:
498 case 84:
499 case 85:
500 case 86:
501 case 87:
502 (*psd)[i] = 3.16228e-06 * basePsdWattsHz;
503 break;
504 case 88:
505 case 89:
506 case 90:
507 (*psd)[i] = 4.73151e-06 * basePsdWattsHz;
508 break;
509 case 91:
510 case 92:
511 case 93:
512 (*psd)[i] = 7.49894e-06 * basePsdWattsHz;
513 break;
514 case 94:
515 (*psd)[i] = 7.49894e-05 * basePsdWattsHz;
516 break;
517 case 95:
518 (*psd)[i] = 0.1 * basePsdWattsHz;
519 break;
520 case 96:
521 (*psd)[i] = 7.49894e-05 * basePsdWattsHz;
522 break;
523 case 97:
524 case 98:
525 case 99:
526 case 100:
527 (*psd)[i] = 1.77828e-06 * basePsdWattsHz;
528 break;
529 }
530 }
531 break;
532 }
533 default: {
534 NS_LOG_ERROR("no valid TvType selected");
535 break;
536 }
537 }
538 m_txPsd = psd;
539}
540
543{
544 NS_LOG_FUNCTION(this);
545 return m_txPsd;
546}
547
548void
550{
551 NS_LOG_FUNCTION(this);
554 signal->duration = m_transmitDuration;
555 signal->psd = m_txPsd;
556 signal->txPhy = GetObject<SpectrumPhy>();
557 signal->txAntenna = m_antenna;
558 m_channel->StartTx(signal);
559}
560
561void
563{
564 NS_LOG_FUNCTION(this);
565 if (!m_active)
566 {
567 NS_LOG_LOGIC("starting TV transmitter");
568 m_active = true;
570 }
571}
572
573void
575{
576 NS_LOG_FUNCTION(this);
577 m_active = false;
578}
579
580} // namespace ns3
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
Hold variables of type enum.
Definition enum.h:52
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition object.h:511
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
Abstract base class for Spectrum-aware PHY layers.
Hold variables of type string.
Definition string.h:45
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:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
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:248
Ptr< AttributeChecker > MakePointerChecker()
Create a PointerChecker for a type.
Definition pointer.h:269
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition log.h:243
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#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:619
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition nstime.h:1396
Ptr< const AttributeChecker > MakeDoubleChecker()
Definition double.h:82
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:179
bool operator<(const EventId &a, const EventId &b)
Definition event-id.h:168
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition double.h:32
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Definition enum.h:221
static std::map< TvSpectrumModelId, Ptr< SpectrumModel > > g_tvSpectrumModelMap
Stores created spectrum models.
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition nstime.h:1416
The building block of a SpectrumModel.
double fc
center frequency
double fl
lower limit of subband
double fh
upper limit of subband
Used as key for map containing created spectrum models.
TvSpectrumModelId(double stFreq, double bwidth)
Constructor.
double startFrequency
Start frequency [Hz].
double bandwidth
Bandwidth [Hz].