TvSpectrumTransmitter classes to create television transmitter(s) that transmit PSD spectrums customized by attributes such as modulation type, power, antenna type, channel frequency, etc.

This commit is contained in:
Benjamin Cizdziel
2015-04-08 19:45:39 -07:00
parent 6c8d39f935
commit 7e795e2891
13 changed files with 8008 additions and 0 deletions

View File

@@ -250,6 +250,9 @@ SOURCEFIGS = \
$(SRC)/spectrum/doc/spectrum-channel-phy-interface.png \
$(SRC)/spectrum/doc/spectrum-channel-phy-interface.pdf \
$(SRC)/spectrum/doc/spectrum-analyzer-example.eps \
$(SRC)/spectrum/doc/spectrum-tv-rand-geo-points.eps \
$(SRC)/spectrum/doc/spectrum-tv-8vsb.png \
$(SRC)/spectrum/doc/spectrum-tv-cofdm.png \
$(SRC)/lr-wpan/doc/lr-wpan-arch.dia \
$(SRC)/lr-wpan/doc/lr-wpan-data-example.dia \
$(SRC)/lr-wpan/doc/lr-wpan-primitives.dia \

File diff suppressed because it is too large Load Diff

View File

@@ -437,3 +437,168 @@ following conditions are satisfied:
Additional Models
*****************
TV Transmitter Model
====================
A TV Transmitter model is implemented by the ``TvSpectrumTransmitter`` class.
This model enables transmission of realistic TV signals to be simulated and can
be used for interference modeling. It provides a customizable power spectral
density (PSD) model, with configurable attributes including the type of
modulation (with models for analog, 8-VSB, and COFDM), signal bandwidth,
power spectral density level, frequency, and transmission duration. A helper
class, ``TvSpectrumTransmitterHelper``, is also provided to assist users in
setting up simulations.
Main Model Class
################
The main TV Transmitter model class, ``TvSpectrumTransmitter``, provides a
user-configurable PSD model that can be transmitted on the ``SpectrumChannel``.
It inherits from ``SpectrumPhy`` and is comprised of attributes and methods to
create and transmit the signal on the channel.
.. _spectrum-tv-cofdm:
.. figure:: figures/spectrum-tv-cofdm.*
:align: center
8K COFDM signal spectrum generated from ``TvSpectrumTransmitter`` (Left) and
theoretical COFDM signal spectrum [KoppCOFDM] (Right)
One of the user-configurable attributes is the type of modulation for the TV
transmitter to use. The options are 8-VSB (Eight-Level Vestigial Sideband
Modulation) which is notably used in the North America ATSC digital television
standard, COFDM (Coded Orthogonal Frequency Division Multiplexing) which is
notably used in the DVB-T and ISDB-T digital television standards adopted by
various countries around the world, and analog modulation which is a legacy
technology but is still being used by some countries today. To accomplish
realistic PSD models for these modulation types, the signals PSDs were
approximated from real standards and developed into models that are scalable by
frequency and power. The COFDM PSD is approximated from Figure 12 (8k mode) of
[KoppCOFDM], the 8-VSB PSD is approximated from Figure 3 of [Baron8VSB], and the
analog PSD is approximated from Figure 4 of [QualcommAnalog]. Note that the
analog model is approximated from the NTSC standard, but other analog modulation
standards such as PAL have similar signals. The approximated COFDM PSD model is
in 8K mode. The other configurable attributes are the start frequency,
signal/channel bandwidth, channel number, base PSD, antenna type, starting time,
and transmit duration.
``TvSpectrumTransmitter`` uses ``IsotropicAntennaModel`` as its antenna model by
default, but any model that inherits from ``AntennaModel`` is selectable, so
directional antenna models can also be used. The propagation loss models used
in simulation are configured in the ``SpectrumChannel`` that the user chooses to
use. Terrain and spherical Earth/horizon effects may be supported in future ns-3
propagation loss models.
After the attributes are set, along with the ``SpectrumChannel``,
``MobilityModel``, and node locations, the PSD of the TV transmitter signal can
be created and transmitted on the channel.
.. _sec-tv-helper-class:
Helper Class
############
The helper class, ``TvSpectrumTransmitterHelper``, consists of features to
assist users in setting up TV transmitters for their simulations. Functionality
is also provided to easily simulate real-world scenarios.
.. _spectrum-tv-8vsb:
.. figure:: figures/spectrum-tv-8vsb.*
:align: center
North America ATSC channel 19 & 20 signals generated using
``TvSpectrumTransmitterHelper`` (Left) and theoretical 8-VSB signal
[Baron8VSB] (Right). Note that the theoretical signal is not shown in dB
while the ns-3 generated signals are.
Using this helper class, users can easily set up TV transmitters right after
configuring attributes. Multiple transmitters can be created at a time. Also
included are real characteristics of specific geographic regions that can be
used to run realistic simulations. The regions currently included are
North America, Europe, and Japan. The frequencies and bandwidth of each TV
channel for each these regions are provided.
.. _spectrum-tv-rand-geo-points:
.. figure:: figures/spectrum-tv-rand-geo-points.*
:align: center
Plot from MATLAB implementation of CreateRegionalTvTransmitters method in
``TvSpectrumTransmitterHelper``. Shows 100 random points on Earths surface
(with altitude 0) corresponding to TV transmitter locations within a 2000 km
radius of 35° latitude and -100° longitude.
A method (CreateRegionalTvTransmitters) is provided that enables users to
randomly generate multiple TV transmitters from a specified region with a given
density within a chosen radius around a point on Earths surface. The region,
which determines the channel frequencies of the generated TV transmitters, can
be specified to be one of the three provided, while the density determines the
amount of transmitters generated. The TV transmitters' antenna heights
(altitude) above Earth's surface can also be randomly generated to be within a
given maximum altitude. This method models Earth as a perfect sphere, and
generated location points are referenced accordingly in Earth-Centered
Earth-Fixed Cartesian coordinates. Note that bodies of water on Earth are not
considered in location point generation--TV transmitters can be generated
anywhere on Earth around the origin point within the chosen maximum radius.
Examples
########
Two example simulations are provided that demonstrate the functionality of the
TV transmitter model. ``tv-trans-example`` simulates two 8-VSB TV transmitters
with adjacent channel frequencies. ``tv-trans-regional-example`` simulates
randomly generated COFDM TV transmitters (modeling the DVB-T standard)
located around the Paris, France area with channel frequencies and bandwidths
corresponding to the European television channel allocations.
Testing
#######
The ``tv-spectrum-transmitter`` test suite verifies the accuracy of the
spectrum/PSD model in ``TvSpectrumTransmitter`` by testing if the maximum power
spectral density, start frequency, and end frequency comply with expected values
for various test cases.
The ``tv-helper-distribution`` test suite verifies the functionality of the
method in ``TvSpectrumTransmitterHelper`` that generates a random number of TV
transmitters based on the given density (low, medium, or high) and maximum
number of TV channels. It verifies that the number of TV transmitters generated
does not exceed the expected bounds.
The CreateRegionalTvTransmitters method in ``TvSpectrumTransmitterHelper``
described in :ref:`sec-tv-helper-class` uses two methods from the
``GeographicPositions`` class in the Mobility module to generate the random
Cartesian points on or above earth's surface around an origin point which
correspond to TV transmitter positions. The first method converts Earth
geographic coordinates to Earth-Centered Earth-Fixed (ECEF) Cartesian
coordinates, and is tested in the ``geo-to-cartesian`` test suite by comparing
(with 10 meter tolerance) its output with the output of the geographic to ECEF
conversion function [MatlabGeo] of the MATLAB Mapping Toolbox for numerous
test cases. The other used method generates random ECEF Cartesian points around
the given geographic origin point, and is tested in the ``rand-cart-around-geo``
test suite by verifying that the generated points do not exceed the given
maximum distance radius from the origin point.
References
##########
.. [Baron8VSB] Baron, Stanley. "First-Hand:Digital Television: The Digital
Terrestrial Television Broadcasting (DTTB) Standard." IEEE Global History
Network. <http://www.ieeeghn.org/wiki/index.php/First-Hand:Digital_Television:_The_Digital_Terrestrial_Television_Broadcasting_(DTTB)_Standard>.
.. [KoppCOFDM] Kopp, Carlo. "High Definition Television." High Definition
Television. Air Power Australia. <http://www.ausairpower.net/AC-1100.html>.
.. [MatlabGeo] "Geodetic2ecef." Convert Geodetic to Geocentric (ECEF)
Coordinates. The MathWorks, Inc.
<http://www.mathworks.com/help/map/ref/geodetic2ecef.html>.
.. [QualcommAnalog] Stephen Shellhammer, Ahmed Sadek, and Wenyi Zhang.
"Technical Challenges for Cognitive Radio in the TV White Space Spectrum."
Qualcomm Incorporated.

View File

@@ -0,0 +1,110 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014 University of Washington
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Benjamin Cizdziel <ben.cizdziel@gmail.com>
*/
#include <iostream>
#include <stdlib.h>
#include <ns3/core-module.h>
#include <ns3/mobility-module.h>
#include <ns3/spectrum-helper.h>
#include <ns3/spectrum-analyzer-helper.h>
#include <ns3/tv-spectrum-transmitter-helper.h>
using namespace ns3;
/**
* This example uses the TvSpectrumTransmitterHelper class to set up two 8-VSB
* TV transmitters with adjacent channels. Each transmitter's spectrum has a
* bandwidth of 6 MHz. The first TV transmitter has a start frequency of
* 524 MHz while the second has a start frequency of 530 MHz. These transmitters
* model ATSC (North American digital TV standard) channels 23 and 24.
*
* A spectrum analyzer is used to measure the transmitted spectra from the
* TV transmitters. The file "spectrum-analyzer-tv-sim-2-0.tr" contains its
* output post simulation (and can be plotted with Gnuplot or MATLAB).
*/
int main (int argc, char** argv)
{
/* nodes and positions */
NodeContainer tvTransmitterNodes;
NodeContainer spectrumAnalyzerNodes;
NodeContainer allNodes;
tvTransmitterNodes.Create (2);
spectrumAnalyzerNodes.Create (1);
allNodes.Add (tvTransmitterNodes);
allNodes.Add (spectrumAnalyzerNodes);
MobilityHelper mobility;
Ptr<ListPositionAllocator> nodePositionList = CreateObject<ListPositionAllocator> ();
nodePositionList->Add (Vector (128000.0, 0.0, 0.0)); // TV Transmitter 1; 128 km away from spectrum analyzer
nodePositionList->Add (Vector (0.0, 24000.0, 0.0)); // TV Transmitter 2; 24 km away from spectrum analyzer
nodePositionList->Add (Vector (0.0, 0.0, 0.0)); // Spectrum Analyzer
mobility.SetPositionAllocator (nodePositionList);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (allNodes);
/* channel and propagation */
SpectrumChannelHelper channelHelper = SpectrumChannelHelper::Default ();
channelHelper.SetChannel ("ns3::MultiModelSpectrumChannel");
// constant path loss added just to show capability to set different propagation loss models
// FriisSpectrumPropagationLossModel already added by default in SpectrumChannelHelper
channelHelper.AddSpectrumPropagationLoss ("ns3::ConstantSpectrumPropagationLossModel");
Ptr<SpectrumChannel> channel = channelHelper.Create ();
/* TV transmitter setup */
TvSpectrumTransmitterHelper tvTransHelper;
tvTransHelper.SetChannel (channel);
tvTransHelper.SetAttribute ("StartFrequency", DoubleValue (524e6));
tvTransHelper.SetAttribute ("ChannelBandwidth", DoubleValue (6e6));
// channel number not required in this example but shown for clarity
tvTransHelper.SetAttribute ("ChannelNumber", UintegerValue (23));
tvTransHelper.SetAttribute ("StartingTime", TimeValue (Seconds (0)));
tvTransHelper.SetAttribute ("TransmitDuration", TimeValue (Seconds (0.2)));
// 22.22 dBm/Hz from 1000 kW ERP transmit power, flat 6 MHz PSD spectrum assumed for this approximation
tvTransHelper.SetAttribute ("BasePsd", DoubleValue (22.22));
tvTransHelper.SetAttribute ("TvType", EnumValue (TvSpectrumTransmitter::TVTYPE_8VSB));
tvTransHelper.SetAttribute ("Antenna", StringValue ("ns3::IsotropicAntennaModel"));
tvTransHelper.InstallAdjacent (tvTransmitterNodes);
/* frequency range for spectrum analyzer */
std::vector<double> freqs;
for (int i = 0; i < 200; ++i)
{
freqs.push_back ((i + 5200) * 1e5);
}
Ptr<SpectrumModel> spectrumAnalyzerFreqModel = Create<SpectrumModel> (freqs);
/* spectrum analyzer setup */
SpectrumAnalyzerHelper spectrumAnalyzerHelper;
spectrumAnalyzerHelper.SetChannel (channel);
spectrumAnalyzerHelper.SetRxSpectrumModel (spectrumAnalyzerFreqModel);
spectrumAnalyzerHelper.SetPhyAttribute ("NoisePowerSpectralDensity", DoubleValue (1e-15)); // -120 dBm/Hz
spectrumAnalyzerHelper.EnableAsciiAll ("spectrum-analyzer-tv-sim");
NetDeviceContainer spectrumAnalyzerDevices = spectrumAnalyzerHelper.Install (spectrumAnalyzerNodes);
Simulator::Stop (Seconds (0.4));
Simulator::Run ();
Simulator::Destroy ();
std::cout << "simulation done!" << std::endl;
std::cout << "see spectrum analyzer output file" << std::endl;
return 0;
}

View File

@@ -0,0 +1,111 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014 University of Washington
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Benjamin Cizdziel <ben.cizdziel@gmail.com>
*/
#include <iostream>
#include <stdlib.h>
#include <ns3/core-module.h>
#include <ns3/mobility-module.h>
#include <ns3/spectrum-helper.h>
#include <ns3/spectrum-analyzer-helper.h>
#include <ns3/tv-spectrum-transmitter-helper.h>
using namespace ns3;
/**
* This example uses the TvSpectrumTransmitterHelper class to generate a random
* number of COFDM TV transmitters within a 250 km radius around latitude
* 48.86 degrees and longitude 2.35 degrees (Paris, France). The transmitters'
* frequencies and bandwidths correspond to the European TV channel allocations.
* These TV transmitters model the digital DVB-T standard.
*
* A spectrum analyzer is used to measure the transmitted spectra from the
* TV transmitters. The file "spectrum-analyzer-tv-sim-regional-0-0.tr" contains
* its output post simulation (and can be plotted with Gnuplot or MATLAB).
*/
int main (int argc, char** argv)
{
/* random seed and run number; adjust these to change random draws */
RngSeedManager::SetSeed(1);
RngSeedManager::SetRun(3);
/* nodes and positions */
NodeContainer spectrumAnalyzerNodes;
spectrumAnalyzerNodes.Create (1);
MobilityHelper mobility;
Ptr<ListPositionAllocator> nodePositionList = CreateObject<ListPositionAllocator> ();
Vector coordinates = GeographicPositions::GeographicToCartesianCoordinates (48.86,
2.35,
0,
GeographicPositions::SPHERE);
nodePositionList->Add (coordinates); // spectrum analyzer
mobility.SetPositionAllocator (nodePositionList);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (spectrumAnalyzerNodes);
/* channel and propagation */
SpectrumChannelHelper channelHelper = SpectrumChannelHelper::Default ();
channelHelper.SetChannel ("ns3::MultiModelSpectrumChannel");
Ptr<SpectrumChannel> channel = channelHelper.Create ();
/* TV transmitter setup */
TvSpectrumTransmitterHelper tvTransHelper;
tvTransHelper.SetChannel (channel);
tvTransHelper.SetAttribute ("StartingTime", TimeValue (Seconds (0.1)));
tvTransHelper.SetAttribute ("TransmitDuration", TimeValue (Seconds (0.1)));
// 7.96 dBm/Hz from 50 kW ERP transmit power, flat 8 MHz PSD spectrum assumed for this approximation
tvTransHelper.SetAttribute ("BasePsd", DoubleValue (7.96));
tvTransHelper.SetAttribute ("TvType", EnumValue (TvSpectrumTransmitter::TVTYPE_COFDM));
tvTransHelper.SetAttribute ("Antenna", StringValue ("ns3::IsotropicAntennaModel"));
tvTransHelper.AssignStreams (300);
tvTransHelper.CreateRegionalTvTransmitters(TvSpectrumTransmitterHelper::REGION_EUROPE,
TvSpectrumTransmitterHelper::DENSITY_MEDIUM,
48.86,
2.35,
0,
250000);
/* frequency range for spectrum analyzer */
std::vector<double> freqs;
for (int i = 0; i < 6860; i = i + 5)
{
freqs.push_back ((i + 1740) * 1e5);
}
Ptr<SpectrumModel> spectrumAnalyzerFreqModel = Create<SpectrumModel> (freqs);
/* spectrum analyzer setup */
SpectrumAnalyzerHelper spectrumAnalyzerHelper;
spectrumAnalyzerHelper.SetChannel (channel);
spectrumAnalyzerHelper.SetRxSpectrumModel (spectrumAnalyzerFreqModel);
spectrumAnalyzerHelper.SetPhyAttribute ("NoisePowerSpectralDensity", DoubleValue (4.14e-21)); // approx -174 dBm/Hz
spectrumAnalyzerHelper.EnableAsciiAll ("spectrum-analyzer-tv-sim-regional");
NetDeviceContainer spectrumAnalyzerDevices = spectrumAnalyzerHelper.Install (spectrumAnalyzerNodes);
Simulator::Stop (Seconds (0.4));
Simulator::Run ();
Simulator::Destroy ();
std::cout << "simulation done!" << std::endl;
std::cout << "see spectrum analyzer output file" << std::endl;
return 0;
}

View File

@@ -13,4 +13,10 @@ def build(bld):
['spectrum', 'mobility', 'internet', 'applications'])
obj.source = 'adhoc-aloha-ideal-phy-with-microwave-oven.cc'
obj = bld.create_ns3_program('tv-trans-example',
['spectrum', 'mobility', 'core'])
obj.source = 'tv-trans-example.cc'
obj = bld.create_ns3_program('tv-trans-regional-example',
['spectrum', 'mobility', 'core'])
obj.source = 'tv-trans-regional-example.cc'

View File

@@ -0,0 +1,448 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014 University of Washington
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Benjamin Cizdziel <ben.cizdziel@gmail.com>
*/
#include <ns3/log.h>
#include <cmath>
#include <list>
#include <vector>
#include <ns3/uinteger.h>
#include <ns3/double.h>
#include <ns3/isotropic-antenna-model.h>
#include <ns3/mobility-helper.h>
#include <ns3/position-allocator.h>
#include <ns3/geographic-positions.h>
#include "tv-spectrum-transmitter-helper.h"
namespace ns3 {
NS_LOG_COMPONENT_DEFINE ("TvSpectrumTransmitterHelper");
// NORTH AMERICA: 84 elements (index 0 - 83); valid channels = 2 - 83
const int northAmericaArrayLength = 84;
const double northAmericaStartFrequencies[84] = {0, 0, 54e6, 60e6, 66e6, 76e6,
82e6, 174e6, 180e6, 186e6, 192e6, 198e6, 204e6, 210e6, 470e6, 476e6, 482e6,
488e6, 494e6, 500e6, 506e6, 512e6, 518e6, 524e6, 530e6, 536e6, 542e6, 548e6,
554e6, 560e6, 566e6, 572e6, 578e6, 584e6, 590e6, 596e6, 602e6, 608e6, 614e6,
620e6, 626e6, 632e6, 638e6, 644e6, 650e6, 656e6, 662e6, 668e6, 674e6, 680e6,
686e6, 692e6, 698e6, 704e6, 710e6, 716e6, 722e6, 728e6, 734e6, 740e6, 746e6,
752e6, 758e6, 764e6, 770e6, 776e6, 782e6, 788e6, 794e6, 800e6, 806e6, 812e6,
818e6, 824e6, 830e6, 836e6, 842e6, 848e6, 854e6, 860e6, 866e6, 872e6, 878e6,
884e6};
const double northAmericaEndFrequencies[84] = {0, 0, 60e6, 66e6, 72e6, 82e6,
88e6, 180e6, 186e6, 192e6, 198e6, 204e6, 210e6, 216e6, 476e6, 482e6, 488e6,
494e6, 500e6, 506e6, 512e6, 518e6, 524e6, 530e6, 536e6, 542e6, 548e6, 554e6,
560e6, 566e6, 572e6, 578e6, 584e6, 590e6, 596e6, 602e6, 608e6, 614e6, 620e6,
626e6, 632e6, 638e6, 644e6, 650e6, 656e6, 662e6, 668e6, 674e6, 680e6, 686e6,
692e6, 698e6, 704e6, 710e6, 716e6, 722e6, 728e6, 734e6, 740e6, 746e6, 752e6,
758e6, 764e6, 770e6, 776e6, 782e6, 788e6, 794e6, 800e6, 806e6, 812e6, 818e6,
824e6, 830e6, 836e6, 842e6, 848e6, 854e6, 860e6, 866e6, 872e6, 878e6, 884e6,
890e6};
// EUROPE: 70 elements (index 0 - 69); valid channels = 5 - 12, 21 - 69
const int europeArrayLength = 70;
const double europeStartFrequencies[70] = {0, 0, 0, 0, 0, 174e6, 181e6, 188e6,
195e6, 202e6, 209e6, 216e6, 223e6, 0, 0, 0, 0, 0, 0, 0, 0, 470e6, 478e6,
486e6, 494e6, 502e6, 510e6, 518e6, 526e6, 534e6, 542e6, 550e6, 558e6, 566e6,
574e6, 582e6, 590e6, 598e6, 606e6, 614e6, 622e6, 630e6, 638e6, 646e6, 654e6,
662e6, 670e6, 678e6, 686e6, 694e6, 702e6, 710e6, 718e6, 726e6, 734e6, 742e6,
750e6, 758e6, 766e6, 774e6, 782e6, 790e6, 798e6, 806e6, 814e6, 822e6, 830e6,
838e6, 846e6, 854e6};
const double europeEndFrequencies[70] = {0, 0, 0, 0, 0, 181e6, 188e6, 195e6,
202e6, 209e6, 216e6, 223e6, 230e6, 0, 0, 0, 0, 0, 0, 0, 0, 478e6, 486e6,
494e6, 502e6, 510e6, 518e6, 526e6, 534e6, 542e6, 550e6, 558e6, 566e6, 574e6,
582e6, 590e6, 598e6, 606e6, 614e6, 622e6, 630e6, 638e6, 646e6, 654e6, 662e6,
670e6, 678e6, 686e6, 694e6, 702e6, 710e6, 718e6, 726e6, 734e6, 742e6, 750e6,
758e6, 766e6, 774e6, 782e6, 790e6, 798e6, 806e6, 814e6, 822e6, 830e6, 838e6,
846e6, 854e6, 862e6};
// JAPAN: 63 elements (index 0 - 62); valid channels = 1 - 62
const int japanArrayLength = 63;
const double japanStartFrequencies[63] = {0, 90e6, 96e6, 102e6, 170e6, 176e6,
182e6, 188e6, 192e6, 198e6, 204e6, 210e6, 216e6, 470e6, 476e6, 482e6, 488e6,
494e6, 500e6, 506e6, 512e6, 518e6, 524e6, 530e6, 536e6, 542e6, 548e6, 554e6,
560e6, 566e6, 572e6, 578e6, 584e6, 590e6, 596e6, 602e6, 608e6, 614e6, 620e6,
626e6, 632e6, 638e6, 644e6, 650e6, 656e6, 662e6, 668e6, 674e6, 680e6, 686e6,
692e6, 698e6, 704e6, 710e6, 716e6, 722e6, 728e6, 734e6, 740e6, 746e6, 752e6,
758e6, 764e6};
const double japanEndFrequencies[63] = {0, 96e6, 102e6, 108e6, 176e6, 182e6,
188e6, 194e6, 198e6, 204e6, 210e6, 216e6, 222e6, 476e6, 482e6, 488e6, 494e6,
500e6, 506e6, 512e6, 518e6, 524e6, 530e6, 536e6, 542e6, 548e6, 554e6, 560e6,
566e6, 572e6, 578e6, 584e6, 590e6, 596e6, 602e6, 608e6, 614e6, 620e6, 626e6,
632e6, 638e6, 644e6, 650e6, 656e6, 662e6, 668e6, 674e6, 680e6, 686e6, 692e6,
698e6, 704e6, 710e6, 716e6, 722e6, 728e6, 734e6, 740e6, 746e6, 752e6, 758e6,
764e6, 770e6};
TvSpectrumTransmitterHelper::TvSpectrumTransmitterHelper ()
: m_channel (0),
m_channelNumber (0),
m_uniRand (CreateObject<UniformRandomVariable> ())
{
NS_LOG_FUNCTION (this);
m_factory.SetTypeId ("ns3::TvSpectrumTransmitter");
}
TvSpectrumTransmitterHelper::~TvSpectrumTransmitterHelper ()
{
m_channel = 0;
m_uniRand = 0;
NS_LOG_FUNCTION (this);
}
void
TvSpectrumTransmitterHelper::SetChannel (Ptr<SpectrumChannel> c)
{
NS_LOG_FUNCTION (this << c);
m_channel = c;
}
void
TvSpectrumTransmitterHelper::SetAttribute (std::string name, const AttributeValue &val)
{
m_factory.Set (name, val);
if (name.compare ("ChannelNumber") == 0)
{
const AttributeValue * aval = &val;
const UintegerValue * ival;
ival = dynamic_cast<const UintegerValue *> (aval);
m_channelNumber = (uint16_t) ival->Get (); // store channel number
}
}
NetDeviceContainer
TvSpectrumTransmitterHelper::Install (NodeContainer nodeCont)
{
NS_LOG_FUNCTION (this);
NetDeviceContainer devCont;
//iterate over node container to make one transmitter for each given node
for (NodeContainer::Iterator i = nodeCont.Begin (); i != nodeCont.End (); ++i)
{
Ptr<Node> node = *i;
Ptr<TvSpectrumTransmitter> phy = m_factory.Create ()->GetObject<TvSpectrumTransmitter> ();
phy->CreateTvPsd ();
Ptr<NonCommunicatingNetDevice> dev = CreateObject<NonCommunicatingNetDevice> ();
NS_ASSERT (phy);
dev->SetPhy (phy);
NS_ASSERT (node);
phy->SetMobility (node->GetObject<MobilityModel> ());
NS_ASSERT (dev);
phy->SetDevice (dev);
NS_ASSERT (m_channel);
phy->SetChannel (m_channel);
dev->SetChannel (m_channel);
node->AddDevice (dev);
devCont.Add (dev);
phy->Start ();
}
return devCont;
}
NetDeviceContainer
TvSpectrumTransmitterHelper::Install (NodeContainer nodeCont, Region region)
{
NS_LOG_FUNCTION (this);
NetDeviceContainer devCont;
double startFrequency;
double channelBandwidth;
if (region == REGION_NORTH_AMERICA)
{
startFrequency = northAmericaStartFrequencies[m_channelNumber];
channelBandwidth = northAmericaEndFrequencies[m_channelNumber] -
northAmericaStartFrequencies[m_channelNumber];
}
else if (region == REGION_EUROPE)
{
startFrequency = europeStartFrequencies[m_channelNumber];
channelBandwidth = europeEndFrequencies[m_channelNumber] -
europeStartFrequencies[m_channelNumber];
}
else if (region == REGION_JAPAN)
{
startFrequency = japanStartFrequencies[m_channelNumber];
channelBandwidth = japanEndFrequencies[m_channelNumber] -
japanStartFrequencies[m_channelNumber];
}
//iterate over node container to make one transmitter for each given node
for (NodeContainer::Iterator i = nodeCont.Begin (); i != nodeCont.End (); ++i)
{
Ptr<Node> node = *i;
Ptr<TvSpectrumTransmitter> phy = m_factory.Create ()->GetObject<TvSpectrumTransmitter> ();
phy->SetAttribute ("StartFrequency", DoubleValue (startFrequency));
phy->SetAttribute ("ChannelBandwidth", DoubleValue (channelBandwidth));
phy->CreateTvPsd ();
Ptr<NonCommunicatingNetDevice> dev = CreateObject<NonCommunicatingNetDevice> ();
NS_ASSERT (phy);
dev->SetPhy (phy);
NS_ASSERT (node);
phy->SetMobility (node->GetObject<MobilityModel> ());
NS_ASSERT (dev);
phy->SetDevice (dev);
NS_ASSERT (m_channel);
phy->SetChannel (m_channel);
dev->SetChannel (m_channel);
node->AddDevice (dev);
devCont.Add (dev);
phy->Start ();
}
return devCont;
}
NetDeviceContainer
TvSpectrumTransmitterHelper::InstallAdjacent (NodeContainer nodeCont)
{
NS_LOG_FUNCTION (this);
NetDeviceContainer devCont;
int index = 0;
DoubleValue startFrequency;
DoubleValue channelBandwidth;
//iterate over node container to make one transmitter for each given node
for (NodeContainer::Iterator i = nodeCont.Begin (); i != nodeCont.End (); ++i)
{
Ptr<Node> node = *i;
Ptr<TvSpectrumTransmitter> phy = m_factory.Create ()->GetObject<TvSpectrumTransmitter> ();
phy->GetAttribute ("StartFrequency", startFrequency);
phy->GetAttribute ("ChannelBandwidth", channelBandwidth);
phy->SetAttribute ("StartFrequency", DoubleValue (startFrequency.Get () +
(index * channelBandwidth.Get ())));
phy->SetAttribute ("ChannelNumber", UintegerValue (m_channelNumber + index));
phy->CreateTvPsd ();
Ptr<NonCommunicatingNetDevice> dev = CreateObject<NonCommunicatingNetDevice> ();
NS_ASSERT (phy);
dev->SetPhy (phy);
NS_ASSERT (node);
phy->SetMobility (node->GetObject<MobilityModel> ());
NS_ASSERT (dev);
phy->SetDevice (dev);
NS_ASSERT (m_channel);
phy->SetChannel (m_channel);
dev->SetChannel (m_channel);
node->AddDevice (dev);
devCont.Add (dev);
phy->Start ();
index++;
}
return devCont;
}
NetDeviceContainer
TvSpectrumTransmitterHelper::InstallAdjacent (NodeContainer nodeCont, Region region)
{
NS_LOG_FUNCTION (this);
NetDeviceContainer devCont;
double startFrequency;
double channelBandwidth;
int index = 0;
//iterate over node container to make one transmitter for each given node
for (NodeContainer::Iterator i = nodeCont.Begin (); i != nodeCont.End (); ++i)
{
if (region == REGION_NORTH_AMERICA)
{
startFrequency = northAmericaStartFrequencies[m_channelNumber + index];
channelBandwidth = northAmericaEndFrequencies[m_channelNumber + index]
- northAmericaStartFrequencies[m_channelNumber + index];
}
else if (region == REGION_EUROPE)
{
startFrequency = europeStartFrequencies[m_channelNumber + index];
channelBandwidth = europeEndFrequencies[m_channelNumber + index] -
europeStartFrequencies[m_channelNumber + index];
}
else if (region == REGION_JAPAN)
{
startFrequency = japanStartFrequencies[m_channelNumber + index];
channelBandwidth = japanEndFrequencies[m_channelNumber + index] -
japanStartFrequencies[m_channelNumber + index];
}
Ptr<Node> node = *i;
Ptr<TvSpectrumTransmitter> phy = m_factory.Create ()->GetObject<TvSpectrumTransmitter> ();
phy->SetAttribute ("StartFrequency", DoubleValue (startFrequency));
phy->SetAttribute ("ChannelBandwidth", DoubleValue (channelBandwidth));
phy->SetAttribute ("ChannelNumber", UintegerValue (m_channelNumber + index));
phy->CreateTvPsd ();
Ptr<NonCommunicatingNetDevice> dev = CreateObject<NonCommunicatingNetDevice> ();
NS_ASSERT (phy);
dev->SetPhy (phy);
NS_ASSERT (node);
phy->SetMobility (node->GetObject<MobilityModel> ());
NS_ASSERT (dev);
phy->SetDevice (dev);
NS_ASSERT (m_channel);
phy->SetChannel (m_channel);
dev->SetChannel (m_channel);
node->AddDevice (dev);
devCont.Add (dev);
phy->Start ();
index++;
}
return devCont;
}
int64_t
TvSpectrumTransmitterHelper::AssignStreams (int64_t streamNum)
{
m_uniRand->SetStream (streamNum);
return 1;
}
void
TvSpectrumTransmitterHelper::CreateRegionalTvTransmitters (Region region,
Density density,
double originLatitude,
double originLongitude,
double maxAltitude,
double maxRadius)
{
NS_LOG_FUNCTION (this);
std::list<int> transmitterIndicesToCreate;
if (region == REGION_NORTH_AMERICA)
{
transmitterIndicesToCreate = GenerateRegionalTransmitterIndices
(northAmericaStartFrequencies,
northAmericaArrayLength,
density);
}
else if (region == REGION_EUROPE)
{
transmitterIndicesToCreate = GenerateRegionalTransmitterIndices
(europeStartFrequencies,
europeArrayLength,
density);
}
else if (region == REGION_JAPAN)
{
transmitterIndicesToCreate = GenerateRegionalTransmitterIndices
(japanStartFrequencies,
japanArrayLength,
density);
}
std::list<Vector> tvTransmitterLocations =
GeographicPositions::RandCartesianPointsAroundGeographicPoint (originLatitude,
originLongitude,
maxAltitude,
transmitterIndicesToCreate.size(),
maxRadius,
m_uniRand);
InstallRandomRegionalTransmitters (region,
transmitterIndicesToCreate,
tvTransmitterLocations);
}
std::list<int>
TvSpectrumTransmitterHelper::GenerateRegionalTransmitterIndices (const double startFrequencies[],
const int startFrequenciesLength,
Density density)
{
std::vector<double> startFreqVector; //stores all non-zero start frequencies
for (int i = 0; i < startFrequenciesLength; i++)
{
double element = startFrequencies[i];
//add all non-zero frequencies to vector (0 means unused channel)
if (element != 0) startFreqVector.push_back(element);
}
//randomly generate number of transmitters to create based on density
uint32_t freqVectorSize = startFreqVector.size();
int randNumTransmitters = GetRandomNumTransmitters (density, freqVectorSize);
//stores start frequencies that transmitters will be created to transmit
std::vector<double> transmitterStartFreqsToCreate;
for (int i = 0; i < randNumTransmitters; i++)
{
//get random index from start frequency vector
uint32_t randIndex = m_uniRand->GetInteger (0, startFreqVector.size () - 1);
//add start frequency corresponding to random index to vector
transmitterStartFreqsToCreate.push_back(startFreqVector[randIndex]);
//remove selected start frequency from vector so it is not selected again
startFreqVector.erase(startFreqVector.begin() + randIndex);
}
//find indices on startFrequencies[] containing each start frequency that is
//selected to be transmitted and add to list
std::list<int> transmitterIndicesToCreate;
for (int i = 0; i < (int)transmitterStartFreqsToCreate.size(); i++)
{
for (int channelNumberIndex = 0;
channelNumberIndex < startFrequenciesLength; channelNumberIndex++)
{
if (startFrequencies[channelNumberIndex] == transmitterStartFreqsToCreate[i])
{
transmitterIndicesToCreate.push_back(channelNumberIndex);
break;
}
}
}
return transmitterIndicesToCreate;
}
int
TvSpectrumTransmitterHelper::GetRandomNumTransmitters (Density density,
uint32_t numChannels)
{
int numTransmitters;
if (density == DENSITY_LOW)
{
numTransmitters = m_uniRand->GetInteger (1, ceil (0.33 * numChannels));
}
else if (density == DENSITY_MEDIUM)
{
numTransmitters = m_uniRand->GetInteger (ceil (0.33 * numChannels) + 1, ceil (0.66 * numChannels));
}
else
{
numTransmitters = m_uniRand->GetInteger (ceil (0.66 * numChannels) + 1, numChannels);
}
return numTransmitters;
}
void
TvSpectrumTransmitterHelper::InstallRandomRegionalTransmitters (Region region,
std::list<int> transmitterIndicesToCreate,
std::list<Vector> transmitterLocations)
{
int numTransmitters = (int)transmitterIndicesToCreate.size();
for (int transNum = 0; transNum < numTransmitters; transNum++)
{
Ptr<ListPositionAllocator> nodePosition = CreateObject<ListPositionAllocator> ();
// add generated coordinate point to node position
nodePosition->Add (transmitterLocations.front());
MobilityHelper mobility;
mobility.SetPositionAllocator (nodePosition);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
NodeContainer tvNode; // contains position of transmitter to be created
tvNode.Create (1);
mobility.Install (tvNode);
// set channel number for this transmitter
m_channelNumber = (uint16_t) transmitterIndicesToCreate.front();
Install (tvNode, region); //install tv transmitter
transmitterLocations.pop_front(); // remove created transmitter location
transmitterIndicesToCreate.pop_front(); // remove created transmitter index
}
}
} // namespace ns3

View File

@@ -0,0 +1,328 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014 University of Washington
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Benjamin Cizdziel <ben.cizdziel@gmail.com>
*/
#ifndef TV_SPECTRUM_TRANSMITTER_HELPER_H
#define TV_SPECTRUM_TRANSMITTER_HELPER_H
#include <ns3/spectrum-value.h>
#include <ns3/spectrum-phy.h>
#include <ns3/spectrum-channel.h>
#include <ns3/antenna-model.h>
#include <ns3/spectrum-signal-parameters.h>
#include <ns3/mobility-model.h>
#include <ns3/net-device.h>
#include <ns3/net-device-container.h>
#include <ns3/node-container.h>
#include <ns3/non-communicating-net-device.h>
#include <ns3/random-variable-stream.h>
#include <ns3/tv-spectrum-transmitter.h>
#include "ns3/object-factory.h"
namespace ns3
{
/**
* \ingroup spectrum
*
* Helper class which uses TvSpectrumTransmitter class to create customizable
* TV transmitter(s) that transmit PSD spectrum specified by user-set attributes.
* Has functionality to create TV transmitter(s) with actual frequencies of
* specific geographic regions.
* Provides method to create a random set of transmitters within a given region
* and location.
*
* Here is an example of how to use this class:
*
* TvSpectrumTransmitterHelper tvTransHelper;
* tvTransHelper.SetChannel (channel); // provided that user has a Ptr<SpectrumChannel> ready.
* tvTransHelper.SetAttribute ("StartFrequency", DoubleValue (524e6));
* tvTransHelper.SetAttribute ("ChannelBandwidth", DoubleValue (6e6));
* tvTransHelper.SetAttribute ("StartingTime", TimeValue (Seconds (0)));
* tvTransHelper.SetAttribute ("TransmitDuration", TimeValue (Seconds (0.2)));
* tvTransHelper.SetAttribute ("BasePsd", DoubleValue (22.22));
* tvTransHelper.SetAttribute ("TvType", EnumValue (TvSpectrumTransmitter::TVTYPE_8VSB));
* tvTransHelper.SetAttribute ("Antenna", StringValue ("ns3::IsotropicAntennaModel"));
* tvTransHelper.Install (tvTransmitterNode); //provided that user has a NodeContainer ready.
*/
class TvSpectrumTransmitterHelper
{
public:
/**
* geographical region that TV transmitters are being set up in
*/
enum Region
{
REGION_NORTH_AMERICA,
REGION_JAPAN,
REGION_EUROPE
};
/**
* density of location that TV transmitters are being set up in
*/
enum Density
{
DENSITY_LOW,
DENSITY_MEDIUM,
DENSITY_HIGH
};
TvSpectrumTransmitterHelper (); //!< Default constructor
virtual ~TvSpectrumTransmitterHelper (); //!< Destructor
/**
* Set the spectrum channel for the device(s) to transmit on
*
* @param c a pointer to the spectrum channel
*/
void SetChannel (Ptr<SpectrumChannel> c);
/**
* Set attribute for each TvSpectrumTransmitter instance to be created
*
* @param name the name of the attribute to set
* @param val the value of the attribute to set
*/
void SetAttribute (std::string name, const AttributeValue &val);
/**
* Set up and start the TV Transmitter's transmission on the spectrum channel.
* Creates one TV Transmitter for each node given as an input, with settings
* selected from attributes.
* Use SetAttribute() to select settings for the TV Transmitter(s).
* If multiple transmitters created, all will have same settings (frequency,
* PSD, etc.) except for position/location, which depends on the positions
* in the input NodeContainer.
*
* @param nodes a container containing the node(s) which the TV
* transmitter(s) will be attached to
*
* @return a device container which contains all the devices created by this
* method
*/
NetDeviceContainer Install (NodeContainer nodes);
/**
* Set up and start the TV Transmitter's transmission on the spectrum channel.
* Creates one TV Transmitter for each node given as an input, with settings
* selected from attributes.
* Use SetAttribute() to select settings for the TV Transmitter(s).
* Must set ChannelNumber attribute to select the TV channel in the
* user-selected region that the transmitter(s) will be modeled after.
* If ChannelNumber attribute is not set by the user, it defaults to 5.
* If multiple transmitters created, all will have same settings (frequency,
* PSD, etc.) except for position/location, which depends on the positions
* in the input NodeContainer.
* Transmitter(s) will be created with the frequencies corresponding to the
* channel numbers of the user-selected region.
*
* @param nodes a container containing the node(s) which the TV
* transmitter(s) will be attached to
* @param region the region of which the transmitter(s) will be characterized
*
* @return a device container which contains all the devices created by this
* method
*/
NetDeviceContainer Install (NodeContainer nodes, Region region);
/**
* Set up and start the TV Transmitter's transmission on the spectrum channel.
* Consecutively created transmitters (consecutive in input NodeContainer)
* will have adjacent channels, i.e. a transmitter's frequency spectrum will
* border (but not overlap) the frequency spectrum of the transmitter created
* directly before it and the transmitter created directly after it.
* Creates one TV Transmitter for each node given as an input, with settings
* selected from attributes.
* Use SetAttribute() to select settings for the TV Transmitter(s).
* If multiple transmitters created, they will have same settings except for
* frequency, channel number, and position/location.
* Channel number will be incremented by 1 for each node, and start frequency
* will be incremented by the channel bandwidth that is set.
* For example, if two nodes are given as inputs to InstallAdjacent with
* start frequency set to 500 MHz, channel bandwidth set to 6 MHz, and
* channel number set to 19, the first node will be a transmitter set as
* channel 19 ranging from 500 MHz to 506 MHz and the second node will be a
* transmitter set as channel 20 ranging from 506 MHz to 512 MHz.
*
* @param nodes a container containing the node(s) which the TV
* transmitter(s) will be attached to
*
* @return a device container which contains all the devices created by this
* method
*/
NetDeviceContainer InstallAdjacent (NodeContainer nodes);
/**
* Set up and start the TV Transmitter's transmission on the spectrum channel.
* Consecutively created transmitters (consecutive in input NodeContainer)
* will have adjacent channels, with the frequency spectrum and bandwidth of
* each channel determined by the user-selected region.
* Creates one TV Transmitter for each node given as an input, with settings
* selected from attributes.
* Use SetAttribute() to select settings for the TV Transmitter(s).
* Must set ChannelNumber attribute to select the TV channel in the
* user-selected region that the first created transmitter will be modeled
* after.
* Each subsequently created transmitter will be modeled after the channel
* number following the previous one, for example if the first created
* transmitter is modeled after channel 1, the next one created will be
* modeled after channel 2.
* If ChannelNumber attribute is not set by the user, it defaults to 5.
* If multiple transmitters created, they will have same settings except for
* frequency, channel number, and position/location.
* Channel number will be incremented by 1 for each node, and start frequency
* will be incremented by the channel bandwidth according to the
* user-selected region.
* Transmitter(s) will be created with the frequencies corresponding to the
* channel numbers of the user-selected region.
*
* @param nodes a container containing the node(s) which the TV
* transmitter(s) will be attached to
* @param region the region of which the transmitter(s) will be characterized
*
* @return a device container which contains all the devices created by this
* method
*/
NetDeviceContainer InstallAdjacent (NodeContainer nodes, Region region);
/**
* Assigns the stream number for the uniform random number generator to use
*
* @param stream first stream index to use
* @return the number of stream indices assigned by this helper
*/
int64_t AssignStreams (int64_t streamNum);
/**
* Generates and installs (starts transmission on the spectrum channel) a
* random number of TV transmitters with channel frequencies corresponding
* to the given region at random locations on or above earth.
* The generated transmitters are located at randomly selected points within a
* given altitude above earth's surface centered around a given origin point
* (on earth's surface) within a given distance radius, corresponding to a
* uniform distribution.
* Distance radius is measured as if all points are on earth's surface
* (with altitude = 0).
* Assumes earth is a perfect sphere.
* The given region's channel numbers that the generated TV transmitters'
* frequency spectra are modeled after are uniformly selected at random.
* These channel numbers are never repeated.
* The number of transmitters generated is uniformly random based on given
* density.
* Each transmitter has BasePsd and TvType set from SetAttribute(), which
* should be set before calling this method.
*
* @param region the region that the transmitters are in
* @param density the density (high, medium, or low) of the location being
* simulated, which determines how many transmitters are created and how many
* channels are occupied. Low density will generate between one and one third
* of the number of TV channels in the given region, medium density will
* generate between one third and two thirds, and high density will generate
* between two thirds and all of the channels.
* @param originLatitude origin point latitude in degrees
* @param originLongitude origin point longitude in degrees
* @param maxAltitude maximum altitude in meters above earth's surface with
* which random points can be generated
* @param maxRadius max distance in meters from origin with which random
* transmitters can be generated (all transmitters are less than or equal to
* this distance from the origin, relative to points being on earth's surface)
*/
void CreateRegionalTvTransmitters (Region region,
Density density,
double originLatitude,
double originLongitude,
double maxAltitude,
double maxRadius);
private:
Ptr<SpectrumChannel> m_channel; //!< Pointer to spectrum channel object
/**
* Generates random indices of given region frequency array (ignoring indices
* referring to invalid channels).
* Number of indices generated (which is number of TV transmitters to be
* created) is random based on given density.
* Indices generated refer to frequencies that TV transmitters will be
* created with.
*
* @param startFrequencies array containing all channel start frequencies for
* a particular region
* @param startFrequenciesLength number of elements in startFrequencies array
* @param density the density (high, medium, or low) of the location being
* simulated, which determines how many transmitters are created
*
* @return a list contaning the indices in startFrequencies that transmitters
* will be created for
*/
std::list<int> GenerateRegionalTransmitterIndices (const double startFrequencies[],
const int startFrequenciesLength,
Density density);
/**
* Randomly generates the number of TV transmitters to be created based on
* given density and number of possible TV channels.
* Low density will generate a transmitter for between one (a single
* transmitter) and one third of the number of possible channels, medium
* density will generate a transmitter for between one third and two thirds,
* and high density will generate a transmitter for between two thirds and all
* of the possible channels.
* These ratios are approximated in the implementation, but there is no
* overlap possible in the number of transmitters generated between adjacent
* densities.
* For example, given 60 possible channels, for low density between 1 and 20
* transmitters can be created, for medium density between 21 and 40
* transmitters can be created, and for high density between 41 and 60
* transmitters can be created (all inclusive).
*
* @param density the density (high, medium, or low) of the location being
* simulated
* @param numChannels the number of possible TV channels in the region being
* simulated
*
* @return the number of TV transmitters that will be created
*/
int GetRandomNumTransmitters (Density density, uint32_t numChannels);
/**
* Installs each randomly generated regional TV transmitter
*
* @param region the region that the transmitters are in
* @param transmitterIndicesToCreate a list contaning the channel number
* indices (for region's start frequencies array) that transmitters will be
* created for; this is returned from GenerateRegionalTransmitterIndices()
* @param transmitterLocations a list containing the vectors
* (x, y, z location) of each TV transmitter to be generated; this is
* returned from RandGeographicCoordsAroundPoint()
*/
void InstallRandomRegionalTransmitters (Region region,
std::list<int> transmitterIndicesToCreate,
std::list<Vector> transmitterLocations);
ObjectFactory m_factory; //!< Object factory for attribute setting
uint16_t m_channelNumber; //!< Channel number of TV transmitter to be created
Ptr<UniformRandomVariable> m_uniRand; //!< Object to generate uniform random numbers
};
} // namespace ns3
#endif /* TV_SPECTRUM_TRANSMITTER_HELPER_H */

View File

@@ -0,0 +1,591 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014 University of Washington
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Benjamin Cizdziel <ben.cizdziel@gmail.com>
*/
#include <ns3/log.h>
#include <ns3/simulator.h>
#include <ns3/enum.h>
#include <ns3/uinteger.h>
#include <ns3/double.h>
#include <ns3/integer.h>
#include <ns3/string.h>
#include <ns3/pointer.h>
#include <ns3/isotropic-antenna-model.h>
#include <ns3/antenna-model.h>
#include <cmath>
#include "tv-spectrum-transmitter.h"
namespace ns3 {
NS_LOG_COMPONENT_DEFINE ("TvSpectrumTransmitter");
NS_OBJECT_ENSURE_REGISTERED (TvSpectrumTransmitter);
TvSpectrumTransmitter::TvSpectrumTransmitter ()
: m_mobility (0),
m_antenna (CreateObject<IsotropicAntennaModel> ()),
m_netDevice (0),
m_channel (0),
m_tvType (TVTYPE_8VSB),
m_startFrequency (500e6),
m_channelBandwidth (6e6),
m_channelNumber (0),
m_basePsd (20),
m_txPsd (0),
m_startingTime (Seconds (0)),
m_transmitDuration (Seconds (0.2)),
m_active (false)
{
NS_LOG_FUNCTION (this);
}
TvSpectrumTransmitter::~TvSpectrumTransmitter ()
{
m_mobility = 0;
m_antenna = 0;
m_netDevice = 0;
m_channel = 0;
m_txPsd = 0;
NS_LOG_FUNCTION (this);
}
TypeId
TvSpectrumTransmitter::GetTypeId(void)
{
static TypeId tid = TypeId("ns3::TvSpectrumTransmitter")
.SetParent<SpectrumPhy> ()
.AddConstructor<TvSpectrumTransmitter> ()
.AddAttribute ("TvType",
"The type of TV transmitter/modulation to be used.",
EnumValue (TvSpectrumTransmitter::TVTYPE_8VSB),
MakeEnumAccessor (&TvSpectrumTransmitter::m_tvType),
MakeEnumChecker (TvSpectrumTransmitter::TVTYPE_8VSB, "8vsb",
TvSpectrumTransmitter::TVTYPE_COFDM, "cofdm",
TvSpectrumTransmitter::TVTYPE_ANALOG, "analog"))
.AddAttribute ("StartFrequency",
"The lower end frequency (in Hz) of the TV transmitter's "
"signal. Must be greater than or equal to 0.",
DoubleValue (500e6),
MakeDoubleAccessor (&TvSpectrumTransmitter::m_startFrequency),
MakeDoubleChecker<double> (0, std::numeric_limits<double>::max ()))
.AddAttribute ("ChannelBandwidth",
"The bandwidth (in Hz) of the TV transmitter's signal. Must "
"be greater than or equal to 0.",
DoubleValue (6e6),
MakeDoubleAccessor (&TvSpectrumTransmitter::m_channelBandwidth),
MakeDoubleChecker<double> (0, std::numeric_limits<double>::max ()))
.AddAttribute ("ChannelNumber",
"The channel number to name the TV transmitter (channel 0, "
"1, 2, 3, etc.). Must be greater than or equal to 0. This "
"is only required to be set when setting up regional "
"transmitters from TvSpectrumTransmitterHelper class using "
"methods that take Region as an argument (i.e. the "
"TvSpectrumTransmitterHelper::CreateRegionalTvTransmitters method).",
UintegerValue (5),
MakeUintegerAccessor (&TvSpectrumTransmitter::m_channelNumber),
MakeUintegerChecker<uint16_t> (0, std::numeric_limits<uint16_t>::max ()))
.AddAttribute ("BasePsd",
"The base power spectral density (in dBm/Hz) of the TV "
"transmitter's transmitted spectrum. Base PSD is the "
"maximum PSD of the spectrum excluding pilots. For analog "
"and COFDM transmitters this is the maximum PSD, but for "
"8-VSB transmitters this is the maximum PSD of the main "
"signal spectrum (flat-top segment) since the pilot "
"actually has the maximum PSD overall.",
DoubleValue (20),
MakeDoubleAccessor (&TvSpectrumTransmitter::m_basePsd),
MakeDoubleChecker<double> ())
.AddAttribute ("Antenna",
"The AntennaModel to be used. Allows classes inherited "
"from ns3::AntennaModel. Defaults to ns3::IsotropicAntennaModel.",
StringValue ("ns3::IsotropicAntennaModel"),
MakePointerAccessor (&TvSpectrumTransmitter::m_antenna),
MakePointerChecker<AntennaModel> ())
.AddAttribute ("StartingTime",
"The time point after the simulation begins in which the TV "
"transmitter will begin transmitting.",
TimeValue (Seconds (0)),
MakeTimeAccessor (&TvSpectrumTransmitter::m_startingTime),
MakeTimeChecker ())
.AddAttribute ("TransmitDuration",
"The duration of time that the TV transmitter will transmit for.",
TimeValue (Seconds (0.2)),
MakeTimeAccessor (&TvSpectrumTransmitter::m_transmitDuration),
MakeTimeChecker ())
;
return tid;
}
void
TvSpectrumTransmitter::SetChannel (Ptr<SpectrumChannel> c)
{
NS_LOG_FUNCTION (this << c);
m_channel = c;
}
void
TvSpectrumTransmitter::SetMobility (Ptr<MobilityModel> m)
{
NS_LOG_FUNCTION (this << m);
m_mobility = m;
}
void
TvSpectrumTransmitter::SetDevice (Ptr<NetDevice> d)
{
NS_LOG_FUNCTION (this << d);
m_netDevice = d;
}
Ptr<MobilityModel>
TvSpectrumTransmitter::GetMobility ()
{
NS_LOG_FUNCTION (this);
return m_mobility;
}
Ptr<NetDevice>
TvSpectrumTransmitter::GetDevice ()
{
NS_LOG_FUNCTION (this);
return m_netDevice;
}
Ptr<const SpectrumModel>
TvSpectrumTransmitter::GetRxSpectrumModel () const
{
NS_LOG_FUNCTION (this);
return 0;
}
Ptr<AntennaModel>
TvSpectrumTransmitter::GetRxAntenna ()
{
NS_LOG_FUNCTION (this);
return m_antenna;
}
void
TvSpectrumTransmitter::StartRx (Ptr<SpectrumSignalParameters> params)
{
NS_LOG_FUNCTION (this << params);
}
Ptr<SpectrumChannel>
TvSpectrumTransmitter::GetChannel () const
{
NS_LOG_FUNCTION (this);
return m_channel;
}
// Used as key for map containing created spectrum models
struct TvSpectrumModelId
{
TvSpectrumModelId (double stFreq, double bwidth);
double startFrequency;
double bandwidth;
};
TvSpectrumModelId::TvSpectrumModelId (double stFreq, double bwidth)
: startFrequency (stFreq),
bandwidth (bwidth)
{
}
bool
operator < (const TvSpectrumModelId& a, const TvSpectrumModelId& b)
{
return ( (a.startFrequency < b.startFrequency) ||
( (a.startFrequency == b.startFrequency) && (a.bandwidth < b.bandwidth) ) );
}
// Stores created spectrum models
static std::map<TvSpectrumModelId, Ptr<SpectrumModel> > g_tvSpectrumModelMap;
/**
* 8-VSB PSD approximated from Figure 3 of the following article:
* Baron, Stanley. "First-Hand:Digital Television: The Digital Terrestrial
* Television Broadcasting (DTTB) Standard." IEEE Global History Network.
* <http://www.ieeeghn.org/wiki/index.php/First-Hand:Digital_Television:_The_
* Digital_Terrestrial_Television_Broadcasting_(DTTB)_Standard>.
*
* COFDM PSD approximated from Figure 12 (8k mode) of the following article:
* Kopp, Carlo. "High Definition Television." High Definition Television. Air
* Power Australia. <http://www.ausairpower.net/AC-1100.html>.
*
* Analog PSD approximated from Figure 4 of the following paper:
* Stephen Shellhammer, Ahmed Sadek, and Wenyi Zhang. "Technical Challenges for
* Cognitive Radio in the TV White Space Spectrum." Qualcomm Incorporated.
*/
void
TvSpectrumTransmitter::CreateTvPsd ()
{
NS_LOG_FUNCTION (this);
NS_ASSERT (m_channelBandwidth != 0);
Ptr<SpectrumModel> model;
TvSpectrumModelId key (m_startFrequency, m_channelBandwidth);
std::map<TvSpectrumModelId, Ptr<SpectrumModel> >::iterator iter = g_tvSpectrumModelMap.find (key);
if (iter != g_tvSpectrumModelMap.end ())
{
model = iter->second; //set SpectrumModel to previously created one
}
else // no previously created SpectrumModel with same frequency and bandwidth
{
Bands bands;
double halfSubBand = 0.5 * (m_channelBandwidth / 100);
for (double fl = m_startFrequency - halfSubBand; fl <= (m_startFrequency -
halfSubBand) + m_channelBandwidth; fl += m_channelBandwidth / 100)
{
BandInfo bi;
bi.fl = fl;
bi.fc = fl + halfSubBand;
bi.fh = fl + (2 * halfSubBand);
bands.push_back (bi);
}
model = Create<SpectrumModel> (bands);
g_tvSpectrumModelMap.insert (std::pair<TvSpectrumModelId, Ptr<SpectrumModel> > (key, model));
}
Ptr<SpectrumValue> psd = Create<SpectrumValue> (model);
double basePsdWattsHz = pow (10.0, (m_basePsd - 30) / 10.0); //convert dBm to W/Hz
switch (m_tvType)
{
case TVTYPE_8VSB:
{
for (int i = 0; i <= 100; i++)
{
switch (i)
{
case 0:
case 100:
(*psd) [i] = 0.015 * basePsdWattsHz;
break;
case 1:
case 99:
(*psd) [i] = 0.019 * basePsdWattsHz;
break;
case 2:
case 98:
(*psd) [i] = 0.034 * basePsdWattsHz;
break;
case 3:
case 97:
(*psd) [i] = 0.116 * basePsdWattsHz;
break;
case 4:
case 96:
(*psd) [i] = 0.309 * basePsdWattsHz;
break;
case 5:
(*psd) [i] = (0.502 * basePsdWattsHz) + (21.577 * basePsdWattsHz); //pilot
break;
case 6:
case 94:
(*psd) [i] = 0.696 * basePsdWattsHz;
break;
case 7:
case 93:
(*psd) [i] = 0.913 * basePsdWattsHz;
break;
case 8:
case 92:
(*psd) [i] = 0.978 * basePsdWattsHz;
break;
case 9:
case 91:
(*psd) [i] = 0.990 * basePsdWattsHz;
break;
case 95:
(*psd) [i] = 0.502 * basePsdWattsHz;
break;
default:
(*psd) [i] = basePsdWattsHz;
break;
}
}
break;
}
case TVTYPE_COFDM:
{
for (int i = 0; i <= 100; i++)
{
switch (i)
{
case 0:
case 100:
(*psd) [i] = 1.52e-4 * basePsdWattsHz;
break;
case 1:
case 99:
(*psd) [i] = 2.93e-4 * basePsdWattsHz;
break;
case 2:
case 98:
(*psd) [i] = 8.26e-4 * basePsdWattsHz;
break;
case 3:
case 97:
(*psd) [i] = 0.0927 * basePsdWattsHz;
break;
default:
(*psd) [i] = basePsdWattsHz;
break;
}
}
break;
}
case TVTYPE_ANALOG:
{
for (int i = 0; i <= 100; i++)
{
switch (i)
{
case 0:
case 1:
case 2:
case 3:
(*psd) [i] = 27.07946e-08 * basePsdWattsHz;
break;
case 4:
case 5:
case 6:
(*psd) [i] = 2.51189e-07 * basePsdWattsHz;
break;
case 7:
case 8:
case 9:
(*psd) [i] = 1e-06 * basePsdWattsHz;
break;
case 10:
case 11:
case 12:
(*psd) [i] = 2.39883e-06 * basePsdWattsHz;
break;
case 13:
case 14:
case 15:
(*psd) [i] = 5.62341e-06 * basePsdWattsHz;
break;
case 16:
case 17:
case 18:
(*psd) [i] = 6.68344e-06 * basePsdWattsHz;
break;
case 19:
case 20:
case 21:
(*psd) [i] = 1.25893e-05 * basePsdWattsHz;
break;
case 22:
case 23:
case 24:
(*psd) [i] = 3.16228e-05 * basePsdWattsHz;
break;
case 25:
(*psd) [i] = 0.000158489 * basePsdWattsHz;
break;
case 26:
(*psd) [i] = basePsdWattsHz;
break;
case 27:
(*psd) [i] = 7.49894e-05 * basePsdWattsHz;
break;
case 28:
case 29:
case 30:
(*psd) [i] = 2.37137e-05 * basePsdWattsHz;
break;
case 31:
case 32:
case 33:
(*psd) [i] = 1.14815e-05 * basePsdWattsHz;
break;
case 34:
case 35:
case 36:
(*psd) [i] = 7.49894e-06 * basePsdWattsHz;
break;
case 37:
case 38:
case 39:
(*psd) [i] = 5.62341e-06 * basePsdWattsHz;
break;
case 40:
case 41:
case 42:
(*psd) [i] = 4.21697e-06 * basePsdWattsHz;
break;
case 43:
case 44:
case 45:
(*psd) [i] = 3.16228e-06 * basePsdWattsHz;
break;
case 46:
case 47:
case 48:
(*psd) [i] = 1.99526e-06 * basePsdWattsHz;
break;
case 49:
case 50:
case 51:
(*psd) [i] = 1.25893e-06 * basePsdWattsHz;
break;
case 52:
case 53:
case 54:
(*psd) [i] = 8.41395e-07 * basePsdWattsHz;
break;
case 55:
case 56:
case 57:
(*psd) [i] = 6.30957e-07 * basePsdWattsHz;
break;
case 58:
case 59:
case 60:
(*psd) [i] = 5.88844e-07 * basePsdWattsHz;
break;
case 61:
case 62:
case 63:
(*psd) [i] = 5.62341e-07 * basePsdWattsHz;
break;
case 64:
case 65:
case 66:
(*psd) [i] = 5.30884e-07 * basePsdWattsHz;
break;
case 67:
case 68:
case 69:
(*psd) [i] = 5.01187e-07 * basePsdWattsHz;
break;
case 70:
case 71:
case 72:
(*psd) [i] = 5.30884e-07 * basePsdWattsHz;
break;
case 73:
case 74:
case 75:
(*psd) [i] = 7.49894e-07 * basePsdWattsHz;
break;
case 76:
case 77:
case 78:
(*psd) [i] = 1.77828e-06 * basePsdWattsHz;
break;
case 79:
(*psd) [i] = 5.62341e-06 * basePsdWattsHz;
break;
case 80:
(*psd) [i] = 0.000177828 * basePsdWattsHz;
break;
case 81:
(*psd) [i] = 4.21697e-06 * basePsdWattsHz;
break;
case 82:
case 83:
case 84:
(*psd) [i] = 3.16228e-06 * basePsdWattsHz;
break;
case 85:
case 86:
case 87:
(*psd) [i] = 3.16228e-06 * basePsdWattsHz;
break;
case 88:
case 89:
case 90:
(*psd) [i] = 4.73151e-06 * basePsdWattsHz;
break;
case 91:
case 92:
case 93:
(*psd) [i] = 7.49894e-06 * basePsdWattsHz;
break;
case 94:
(*psd) [i] = 7.49894e-05 * basePsdWattsHz;
break;
case 95:
(*psd) [i] = 0.1 * basePsdWattsHz;
break;
case 96:
(*psd) [i] = 7.49894e-05 * basePsdWattsHz;
break;
case 97:
case 98:
case 99:
case 100:
(*psd) [i] = 1.77828e-06 * basePsdWattsHz;
break;
}
}
break;
}
default:
{
NS_LOG_ERROR ("no valid TvType selected");
break;
}
}
m_txPsd = psd;
}
Ptr<SpectrumValue>
TvSpectrumTransmitter::GetTxPsd () const
{
NS_LOG_FUNCTION (this);
return m_txPsd;
}
void
TvSpectrumTransmitter::SetupTx ()
{
NS_LOG_FUNCTION (this);
NS_ASSERT (m_txPsd);
Ptr<SpectrumSignalParameters> signal = Create<SpectrumSignalParameters> ();
signal->duration = m_transmitDuration;
signal->psd = m_txPsd;
signal->txPhy = GetObject<SpectrumPhy> ();
signal->txAntenna = m_antenna;
m_channel->StartTx (signal);
}
void
TvSpectrumTransmitter::Start ()
{
NS_LOG_FUNCTION (this);
if (!m_active)
{
NS_LOG_LOGIC ("starting TV transmitter");
m_active = true;
Simulator::Schedule (m_startingTime, &TvSpectrumTransmitter::SetupTx, this);
}
}
void
TvSpectrumTransmitter::Stop ()
{
NS_LOG_FUNCTION (this);
m_active = false;
}
} // namespace ns3

View File

@@ -0,0 +1,153 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014 University of Washington
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Benjamin Cizdziel <ben.cizdziel@gmail.com>
*/
#ifndef TV_SPECTRUM_TRANSMITTER_H
#define TV_SPECTRUM_TRANSMITTER_H
#include <ns3/spectrum-value.h>
#include <ns3/spectrum-phy.h>
#include <ns3/spectrum-channel.h>
#include <ns3/antenna-model.h>
#include <ns3/spectrum-signal-parameters.h>
#include <ns3/mobility-model.h>
#include <ns3/net-device.h>
namespace ns3
{
/**
* \ingroup spectrum
*
* SpectrumPhy implementation that creates a customizable TV transmitter which
* transmits a PSD spectrum specified by user-set attributes.
*
*
* This PHY model supports a single antenna model instance which is
* used for transmission (this PHY model never receives).
*/
class TvSpectrumTransmitter : public SpectrumPhy
{
public:
/**
* types of TV transmitters: analog, digital 8-VSB, or digital COFDM
*/
enum TvType
{
TVTYPE_ANALOG,
TVTYPE_8VSB,
TVTYPE_COFDM
};
TvSpectrumTransmitter (); //!< Default constructor
virtual ~TvSpectrumTransmitter (); //!< Destructor
/**
* Register this type.
* \return The object TypeId.
*/
static TypeId GetTypeId (void);
// inherited from SpectrumPhy
void SetChannel (Ptr<SpectrumChannel> c);
void SetMobility (Ptr<MobilityModel> m);
void SetDevice (Ptr<NetDevice> d);
Ptr<MobilityModel> GetMobility ();
Ptr<NetDevice> GetDevice ();
// device does not use Rx but these pure virtual methods must be implemented
Ptr<const SpectrumModel> GetRxSpectrumModel () const;
Ptr<AntennaModel> GetRxAntenna ();
void StartRx (Ptr<SpectrumSignalParameters> params);
/**
* Get the spectrum channel
*
* @return a pointer to the assigned spectrum channel
*/
Ptr<SpectrumChannel> GetChannel () const;
/**
* Creates power spectral density (PSD) spectrum of the TV transmitter and
* sets it for transmission.
* Before calling this method, must set attributes and parameters that are
* applicable to your transmitter.
*
* 8-VSB PSD approximated from Figure 3 of the following article:
* Baron, Stanley. "First-Hand:Digital Television: The Digital Terrestrial
* Television Broadcasting (DTTB) Standard." IEEE Global History Network.
* <http://www.ieeeghn.org/wiki/index.php/First-Hand:Digital_Television:_The_
* Digital_Terrestrial_Television_Broadcasting_(DTTB)_Standard>.
*
* COFDM PSD approximated from Figure 12 (8k mode) of the following article:
* Kopp, Carlo. "High Definition Television." High Definition Television. Air
* Power Australia. <http://www.ausairpower.net/AC-1100.html>.
*
* Analog PSD approximated from Figure 4 of the following paper:
* Stephen Shellhammer, Ahmed Sadek, and Wenyi Zhang. "Technical Challenges
* for Cognitive Radio in the TV White Space Spectrum." Qualcomm Incorporated.
*
*
* @return a pointer to the power spectral density of the TV transmitter
*/
virtual void CreateTvPsd ();
/**
* Get the power spectral density of the TV transmitter's signal
*
* @return a pointer to the PSD
*/
Ptr<SpectrumValue> GetTxPsd () const;
/**
* Starts the TV Transmitter's transmission on the spectrum channel
*/
virtual void Start ();
/**
* Stops the TV Transmitter's transmission on the spectrum channel
*/
virtual void Stop ();
private:
Ptr<MobilityModel> m_mobility; //!< Pointer to mobility model object
Ptr<AntennaModel> m_antenna; //!< Pointer to antenna model object
Ptr<NetDevice> m_netDevice; //!< Pointer to net device object
Ptr<SpectrumChannel> m_channel; //!< Pointer to spectrum channel object
/** Sets up signal to be transmitted */
virtual void SetupTx ();
int m_tvType; //!< Type of TV transmitter
double m_startFrequency; //!< Start frequency (in Hz) of TV transmitter's signal
double m_channelBandwidth; //!< Bandwidth (in Hz) of TV transmitter's signal
uint16_t m_channelNumber; //!< Channel number of TV transmitter
double m_basePsd; //!< Base power spectral density value (in dBm/Hz) of TV transmitter's signal
Ptr<SpectrumValue> m_txPsd; //!< Pointer to power spectral density of TV transmitter's signal
Time m_startingTime; //!< Timepoint after simulation begins that TV transmitter will begin transmitting
Time m_transmitDuration; //!< Length of time that TV transmitter will transmit for
bool m_active; //!< True if TV transmitter is transmitting
};
} // namespace ns3
#endif /* TV_SPECTRUM_TRANSMITTER_H */

View File

@@ -0,0 +1,142 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014 University of Washington
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Benjamin Cizdziel <ben.cizdziel@gmail.com>
*/
#define private public //to make private method testable
#include <ns3/test.h>
#include <ns3/log.h>
#include <ns3/tv-spectrum-transmitter-helper.h>
/**
* This test verifies the accuracy of the private GetRandomNumTransmitters()
* method in the TvSpectrumTransmitterHelper class. The method generates a
* random number corresponding to the number of TV transmitters to create based
* on the given location density (low, medium, or high) and maximum possible
* number of TV channels. Low density will generate a transmitter for between
* one (a single transmitter) and one third of the number of possible channels,
* medium density will generate a transmitter for between one third and two
* thirds, and high density will generate a transmitter for between two thirds
* and all of the possible channels. In this test, it is verified that the
* lower (1) and upper (max number of possible channels input) bounds are not
* exceeded and that the number of transmitters to be generated does not overlap
* between adjacent densities. For example, given 60 possible channels, for low
* density between 1 and 20 transmitters can be created, for medium density
* between 21 and 40 transmitters can be created, and for high density between
* 41 and 60 transmitters can be created (all inclusive). This is tested with
* various cases.
*/
NS_LOG_COMPONENT_DEFINE ("TvHelperDistributionTest");
using namespace ns3;
class TvHelperDistributionTestCase : public TestCase
{
public:
TvHelperDistributionTestCase (uint32_t maxNumTransmitters);
virtual ~TvHelperDistributionTestCase ();
private:
virtual void DoRun (void);
static std::string Name (uint32_t maxNumTransmitters);
uint32_t m_maxNumTransmitters;
};
std::string
TvHelperDistributionTestCase::Name (uint32_t maxNumTransmitters)
{
std::ostringstream oss;
oss << "Max Number of Transmitters = " << maxNumTransmitters;
return oss.str();
}
TvHelperDistributionTestCase::TvHelperDistributionTestCase (uint32_t maxNumTransmitters)
: TestCase (Name (maxNumTransmitters)),
m_maxNumTransmitters (maxNumTransmitters)
{
}
TvHelperDistributionTestCase::~TvHelperDistributionTestCase ()
{
}
void
TvHelperDistributionTestCase::DoRun (void)
{
NS_LOG_FUNCTION (m_maxNumTransmitters);
TvSpectrumTransmitterHelper tvTransHelper;
uint32_t rand;
uint32_t maxLow = 0;
uint32_t minMid = m_maxNumTransmitters;
uint32_t maxMid = 0;
uint32_t minHigh = m_maxNumTransmitters;
for (int i = 0; i < 30; i ++)
{
rand = tvTransHelper.GetRandomNumTransmitters (TvSpectrumTransmitterHelper::DENSITY_LOW, m_maxNumTransmitters);
NS_TEST_ASSERT_MSG_GT (rand, 0, "lower bound exceeded");
if (rand > maxLow)
{
maxLow = rand;
}
}
for (int i = 0; i < 30; i ++)
{
rand = tvTransHelper.GetRandomNumTransmitters (TvSpectrumTransmitterHelper::DENSITY_MEDIUM, m_maxNumTransmitters);
if (rand < minMid)
{
minMid = rand;
}
if (rand > maxMid)
{
maxMid = rand;
}
}
for (int i = 0; i < 30; i ++)
{
rand = tvTransHelper.GetRandomNumTransmitters (TvSpectrumTransmitterHelper::DENSITY_HIGH, m_maxNumTransmitters);
NS_TEST_ASSERT_MSG_LT (rand, m_maxNumTransmitters + 1, "upper bound exceeded");
if (rand < minHigh)
{
minHigh = rand;
}
}
NS_TEST_ASSERT_MSG_LT (maxLow, minMid, "low density overlaps with medium density");
NS_TEST_ASSERT_MSG_LT (maxMid, minHigh, "medium density overlaps with high density");
}
class TvHelperDistributionTestSuite : public TestSuite
{
public:
TvHelperDistributionTestSuite ();
};
TvHelperDistributionTestSuite::TvHelperDistributionTestSuite ()
: TestSuite ("tv-helper-distribution", UNIT)
{
NS_LOG_INFO ("creating TvHelperDistributionTestSuite");
for (uint32_t maxNumTransmitters = 3; maxNumTransmitters <= 203; maxNumTransmitters+= 10)
{
AddTestCase (new TvHelperDistributionTestCase (maxNumTransmitters),
TestCase::QUICK);
}
}
static TvHelperDistributionTestSuite g_TvHelperDistributionTestSuite;

View File

@@ -0,0 +1,205 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014 University of Washington
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Benjamin Cizdziel <ben.cizdziel@gmail.com>
*/
#include <ns3/test.h>
#include <ns3/log.h>
#include <ns3/spectrum-value.h>
#include <ns3/enum.h>
#include <ns3/double.h>
#include <ns3/tv-spectrum-transmitter.h>
/**
* This test verifies the accuracy of the spectrum/PSD model in the
* TvSpectrumTransmitter class. To do so, it tests if the max power spectral
* density, start frequency, and end frequency comply with expected values.
* Values for TV/modulation type, start frequency, channel bandwidth, and
* base PSD are swept and tested for each case.
*/
NS_LOG_COMPONENT_DEFINE ("TvSpectrumTransmitterTest");
using namespace ns3;
const double TOLERANCE = 1e-15;
class TvSpectrumTransmitterTestCase : public TestCase
{
public:
TvSpectrumTransmitterTestCase (double startFrequency,
double channelBandwidth,
double basePsd,
TvSpectrumTransmitter::TvType tvType);
virtual ~TvSpectrumTransmitterTestCase ();
private:
virtual void DoRun (void);
static std::string Name (TvSpectrumTransmitter::TvType tvType,
double startFrequency,
double channelBandwidth,
double basePsd);
double m_startFrequency;
double m_channelBandwidth;
double m_basePsd;
TvSpectrumTransmitter::TvType m_tvType;
};
std::string
TvSpectrumTransmitterTestCase::Name (TvSpectrumTransmitter::TvType tvType,
double startFrequency,
double channelBandwidth,
double basePsd)
{
std::ostringstream oss;
oss << "TV type = " << tvType << ", "
<< "start frequency = " << startFrequency << " Hz, "
<< "channel bandwidth = " << channelBandwidth << " Hz, "
<< "base PSD = " << basePsd << " dBm per Hz";
return oss.str();
}
TvSpectrumTransmitterTestCase::TvSpectrumTransmitterTestCase (double startFrequency,
double channelBandwidth,
double basePsd,
TvSpectrumTransmitter::TvType tvType)
: TestCase (Name (tvType, startFrequency, channelBandwidth, basePsd)),
m_startFrequency (startFrequency),
m_channelBandwidth (channelBandwidth),
m_basePsd (basePsd),
m_tvType (tvType)
{
}
TvSpectrumTransmitterTestCase::~TvSpectrumTransmitterTestCase ()
{
}
void
TvSpectrumTransmitterTestCase::DoRun (void)
{
NS_LOG_FUNCTION (m_startFrequency << m_basePsd << m_tvType);
/* TV transmitter setup */
Ptr<TvSpectrumTransmitter> phy = CreateObject<TvSpectrumTransmitter>();
phy->SetAttribute ("StartFrequency", DoubleValue (m_startFrequency));
phy->SetAttribute ("ChannelBandwidth", DoubleValue (m_channelBandwidth));
phy->SetAttribute ("BasePsd", DoubleValue (m_basePsd));
phy->SetAttribute ("TvType", EnumValue (m_tvType));
phy->CreateTvPsd ();
/* Test max PSD value */
Ptr<SpectrumValue> psd = phy->GetTxPsd ();
Values::const_iterator psdIter = psd->ConstValuesBegin ();
double maxValue = 0;
while (psdIter != psd->ConstValuesEnd ())
{
if (*psdIter > maxValue)
{
maxValue = *psdIter;
}
++psdIter;
}
double basePsdWattsHz = pow (10.0, (m_basePsd - 30) / 10.0); // convert dBm to W/Hz
if (m_tvType == TvSpectrumTransmitter::TVTYPE_8VSB) // pilot has highest PSD
{
double expectedPsd = (0.502 * basePsdWattsHz) + (21.577 * basePsdWattsHz);
NS_TEST_ASSERT_MSG_EQ_TOL (maxValue,
expectedPsd,
TOLERANCE,
"peak PSD value (" << maxValue << ") is incorrect");
}
else // highest PSD is base PSD
{
NS_TEST_ASSERT_MSG_EQ_TOL (maxValue,
basePsdWattsHz,
TOLERANCE,
"peak PSD value (" << maxValue << ") is incorrect");
}
/* Test frequency range */
Bands::const_iterator bandStart = psd->ConstBandsBegin ();
Bands::const_iterator bandEnd = psd->ConstBandsEnd ();
NS_TEST_ASSERT_MSG_EQ_TOL ((*bandStart).fc,
m_startFrequency,
TOLERANCE,
"start frequency value (" << (*bandStart).fc << ") is incorrect");
NS_TEST_ASSERT_MSG_EQ_TOL ((*(bandEnd - 1)).fc,
m_startFrequency + m_channelBandwidth,
TOLERANCE,
"end frequency value (" << (*(bandEnd - 1)).fc << ") is incorrect");
}
class TvSpectrumTransmitterTestSuite : public TestSuite
{
public:
TvSpectrumTransmitterTestSuite ();
};
TvSpectrumTransmitterTestSuite::TvSpectrumTransmitterTestSuite ()
: TestSuite ("tv-spectrum-transmitter", UNIT)
{
NS_LOG_INFO ("creating TvSpectrumTransmitterTestSuite");
for (double startFreq = 100; startFreq < 1e15; startFreq *= 10)
{
for (double bandwidth = 100; bandwidth < 1e15; bandwidth *= 10)
{
for (double psd = -100; psd <= 100; psd += 20)
{
AddTestCase (new TvSpectrumTransmitterTestCase (startFreq,
bandwidth,
psd,
TvSpectrumTransmitter::TVTYPE_8VSB),
TestCase::QUICK);
}
}
}
for (double startFreq = 100; startFreq < 1e15; startFreq *= 10)
{
for (double bandwidth = 100; bandwidth < 1e15; bandwidth *= 10)
{
for (double psd = -100; psd <= 100; psd += 20)
{
AddTestCase (new TvSpectrumTransmitterTestCase (startFreq,
bandwidth,
psd,
TvSpectrumTransmitter::TVTYPE_COFDM),
TestCase::QUICK);
}
}
}
for (double startFreq = 100; startFreq < 1e15; startFreq *= 10)
{
for (double bandwidth = 100; bandwidth < 1e15; bandwidth *= 10)
{
for (double psd = -100; psd <= 100; psd += 20)
{
AddTestCase (new TvSpectrumTransmitterTestCase (startFreq,
bandwidth,
psd,
TvSpectrumTransmitter::TVTYPE_ANALOG),
TestCase::QUICK);
}
}
}
}
static TvSpectrumTransmitterTestSuite g_tvSpectrumTransmitterTestSuite;

View File

@@ -28,10 +28,12 @@ def build(bld):
'model/half-duplex-ideal-phy-signal-parameters.cc',
'model/non-communicating-net-device.cc',
'model/microwave-oven-spectrum-value-helper.cc',
'model/tv-spectrum-transmitter.cc',
'helper/spectrum-helper.cc',
'helper/adhoc-aloha-noack-ideal-phy-helper.cc',
'helper/waveform-generator-helper.cc',
'helper/spectrum-analyzer-helper.cc',
'helper/tv-spectrum-transmitter-helper.cc',
]
module_test = bld.create_ns3_module_test_library('spectrum')
@@ -40,6 +42,8 @@ def build(bld):
'test/spectrum-value-test.cc',
'test/spectrum-ideal-phy-test.cc',
'test/spectrum-waveform-generator-test.cc',
'test/tv-helper-distribution-test.cc',
'test/tv-spectrum-transmitter-test.cc',
]
headers = bld(features='ns3header')
@@ -69,10 +73,12 @@ def build(bld):
'model/half-duplex-ideal-phy-signal-parameters.h',
'model/non-communicating-net-device.h',
'model/microwave-oven-spectrum-value-helper.h',
'model/tv-spectrum-transmitter.h',
'helper/spectrum-helper.h',
'helper/adhoc-aloha-noack-ideal-phy-helper.h',
'helper/waveform-generator-helper.h',
'helper/spectrum-analyzer-helper.h',
'helper/tv-spectrum-transmitter-helper.h',
'test/spectrum-test.h',
]