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:
@@ -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 \
|
||||
|
||||
5740
src/spectrum/doc/spectrum-tv-rand-geo-points.eps
Normal file
5740
src/spectrum/doc/spectrum-tv-rand-geo-points.eps
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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 Earth’s 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 Earth’s 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.
|
||||
|
||||
|
||||
110
src/spectrum/examples/tv-trans-example.cc
Normal file
110
src/spectrum/examples/tv-trans-example.cc
Normal 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;
|
||||
}
|
||||
111
src/spectrum/examples/tv-trans-regional-example.cc
Normal file
111
src/spectrum/examples/tv-trans-regional-example.cc
Normal 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;
|
||||
}
|
||||
@@ -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'
|
||||
|
||||
448
src/spectrum/helper/tv-spectrum-transmitter-helper.cc
Normal file
448
src/spectrum/helper/tv-spectrum-transmitter-helper.cc
Normal 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
|
||||
|
||||
328
src/spectrum/helper/tv-spectrum-transmitter-helper.h
Normal file
328
src/spectrum/helper/tv-spectrum-transmitter-helper.h
Normal 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 */
|
||||
591
src/spectrum/model/tv-spectrum-transmitter.cc
Normal file
591
src/spectrum/model/tv-spectrum-transmitter.cc
Normal 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
|
||||
|
||||
153
src/spectrum/model/tv-spectrum-transmitter.h
Normal file
153
src/spectrum/model/tv-spectrum-transmitter.h
Normal 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 */
|
||||
142
src/spectrum/test/tv-helper-distribution-test.cc
Normal file
142
src/spectrum/test/tv-helper-distribution-test.cc
Normal 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;
|
||||
205
src/spectrum/test/tv-spectrum-transmitter-test.cc
Normal file
205
src/spectrum/test/tv-spectrum-transmitter-test.cc
Normal 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;
|
||||
@@ -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',
|
||||
]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user