spectrum: Support passing the TX and RX PhasedArrayModel objects to spectrum model

This possibility is needed for the types of spectrum propagation models that need to have a pointer
to the TX and RX antenna arrays to perform calculations, such as e.g.,
ThreeGppSpectrumPropagationLossModel, which currently has hard limitation of having a maximum of 1
antenna array instance per device. ThreeGppSpectrumPropagationLossModel now inherits a new class
PhasedArraySpectrumPropagationLossModel. Its DoCalcRxPowerSpectralDensity function has now two
additional parameters: TX and RX antenna arrays. Also, AddDevice function is removed from
ThreeGppSpectrumPropagationLossModel, because it is not anymore needed to specify for each
device its TX/RX antenna, since these are now passed as parameters. Hence, to use
ThreeGppSpectrumPropagationLossModel, when implementing Spectrum PHY features,
modules should implement the function of SpectrumPhy GetAntenna to return the instance of
PhasedArrayModel of that SpectrumPhy. These instances will be passed by MultiModelSpectrumChannel
(one of the core classes in the spectrum module) to propagation classes, children of
PhasedArraySpectrumPropagationLossModel, when it is necessary to DoCalcRxPowerSpectralDensity to
callculate the propagation loss.

Additionally: Fixed pair key generation for 3gpp channel model: Previous implementation was
using a cantor function of two integer of 32 bits and as a results was giving a unique
representatio of 32 bits. This is wrong, because such function needed even more than 64
bits to represent that value. Even if in ns-3 simulation we are not going to have such large
node numbers, we should fix this. Instead of just changing 64 bits from cantor function, I propose to
replace the cantor function with just simple concatenation of two 32 bits.

I also propose moving min and max inside of the function, to prevent some eventual future errors
in using GetKey, because with the previous implementation there was assumption that who calls GetKey
will previously sort its parameters, and first provide the min value, and then the max value,
and this was not even documented.
This commit is contained in:
bbojovic
2021-07-01 08:44:46 +02:00
committed by Biljana Bojovic
parent 33f2ee841b
commit 4ca8b12ea0
21 changed files with 565 additions and 120 deletions

View File

@@ -56,11 +56,15 @@ us a note on ns-developers mailing list.</p>
<ul>
<li>The helpers of the NetDevices supporting flow control (PointToPointHelper, CsmaHelper, SimpleNetDeviceHelper, WifiHelper) now provide a <b>DisableFlowControl</b> method to disable flow control. If flow control is disabled, the Traffic Control layer forwards packets down to the NetDevice even if there is no room for them in the NetDevice queue(s)</li>
<li>Added a new trace source <b>TcDrop</b> in TrafficControlLayer for tracing packets that have been dropped because no queue disc is installed on the device, the device supports flow control and the device queue is full.</li>
<li>Added a new class <b>PhasedArraySpectrumPropagationLossModel</b>, and its <b>DoCalcRxPowerSpectralDensity</b> function has two additional parameters: TX and RX antenna arrays. Should be inherited by models that need to know antenna arrays in order to calculate RX PSD.</li>
</ul>
<h2>Changes to existing API:</h2>
<ul>
<li>internet: Support for Network Simulation Cradle (NSC) TCP has been removed.</li>
<li>fd-net-device: Support for PlanetLabFdNetDeviceHelper has been removed.</li>
<li><b>ThreeGppSpectrumPropagationLossModel</b> now inherits <b>PhasedArraySpectrumPropagationLossModel</b>. The modules that use <b>ThreeGppSpectrumPropagationLossModel</b> should implement <b>SpectrumPhy::GetAntenna</b> that will return the instance of <b>PhasedArrayModel</b>.</li>
<li><b>AddDevice</b> function is removed from <b>ThreeGppSpectrumPropagationLossModel</b> to support multiple arrays per device.</li>
<li><b>SpectrumPhy</b> function <b>GetRxAntenna</b> is renamed to <b>GetAntenna</b>, and its return value is changed to <b>Ptr<Object></b> instead of <b>Ptr<AntennaModel></b> to support also <b>PhasedArrayModel</b> type of antenna.</li>
</ul>
<h2>Changes to build system:</h2>
<ul>

View File

@@ -26,8 +26,11 @@ requirements (Note: not all ns-3 features are available on all systems):
### New user-visible features
- (spectrum) ThreeGppSpectrumPropagationLossModel and ThreeGppChannelModel now support multiple PhasedArrayModel instances per device. This feature can be used to implement MIMO.
### Bugs fixed
- (spectrum) Fix condition for channel matrix update in ThreeGppChannelModel (left and right operand were pointing to the same object)
- (spectrum) Assign stream to random variable for doppler term in ThreeGppChannelModel (moved from ThreeGppSpectrumPropagationLossModel)
- (wifi) #467 - WiFi: Failed association process
- (wifi) #468 - WiFi: Wrong txDuration for trigger frame
- (wifi) #475 - Wi-Fi: Assert when sending OFDMA DL to STAs with different TIDs

View File

@@ -54,6 +54,42 @@ static Ptr<ThreeGppPropagationLossModel> m_propagationLossModel; //!< the Propag
static Ptr<ThreeGppSpectrumPropagationLossModel> m_spectrumLossModel; //!< the SpectrumPropagationLossModel object
static Ptr<ChannelConditionModel> m_condModel; //!< the ChannelConditionModel object
/*
* \brief A structure that holds the parameters for the ComputeSnr
* function. In this way the problem with the limited
* number of parameters of method Schedule is avoided.
*/
struct ComputeSnrParams
{
Ptr<MobilityModel> txMob; //!< the tx mobility model
Ptr<MobilityModel> rxMob; //!< the rx mobility model
Ptr<SpectrumValue> txPsd; //!< the PSD of the tx signal
double noiseFigure; //!< the noise figure in dB
Ptr<PhasedArrayModel> txAntenna; //!< the tx antenna array
Ptr<PhasedArrayModel> rxAntenna; //!< the rx antenna array
/**
* \brief Constructor
* \param pTxMob the tx mobility model
* \param pRxMob the rx mobility model
* \param pTxPsd the PSD of the tx signal
* \param pNoiseFigure the noise figure in dB
* \param pTxAntenna the tx antenna array
* \param pRxAntenna the rx antenna array
*/
ComputeSnrParams (Ptr<MobilityModel> pTxMob, Ptr<MobilityModel> pRxMob,
Ptr<SpectrumValue> pTxPsd, double pNoiseFigure,
Ptr<PhasedArrayModel> pTxAntenna, Ptr<PhasedArrayModel> pRxAntenna)
{
txMob = pTxMob;
rxMob = pRxMob;
txPsd = pTxPsd;
noiseFigure = pNoiseFigure;
txAntenna = pTxAntenna;
rxAntenna = pRxAntenna;
}
};
/**
* Perform the beamforming using the DFT beamforming method
* \param thisDevice the device performing the beamforming
@@ -78,36 +114,33 @@ DoBeamforming (Ptr<NetDevice> thisDevice, Ptr<PhasedArrayModel> thisAntenna, Ptr
/**
* Compute the average SNR
* \param txMob the tx mobility model
* \param rxMob the rx mobility model
* \param txPsd the PSD of the transmitting signal
* \param noiseFigure the noise figure in dB
* \param params A structure that holds a bunch of parameters needed by ComputSnr function to calculate the average SNR
*/
static void
ComputeSnr (Ptr<MobilityModel> txMob, Ptr<MobilityModel> rxMob, Ptr<const SpectrumValue> txPsd, double noiseFigure)
ComputeSnr (ComputeSnrParams& params)
{
Ptr<SpectrumValue> rxPsd = txPsd->Copy ();
Ptr<SpectrumValue> rxPsd = params.txPsd->Copy ();
// check the channel condition
Ptr<ChannelCondition> cond = m_condModel->GetChannelCondition (txMob, rxMob);
Ptr<ChannelCondition> cond = m_condModel->GetChannelCondition (params.txMob, params.rxMob);
// apply the pathloss
double propagationGainDb = m_propagationLossModel->CalcRxPower (0, txMob, rxMob);
double propagationGainDb = m_propagationLossModel->CalcRxPower (0, params.txMob, params.rxMob);
NS_LOG_DEBUG ("Pathloss " << -propagationGainDb << " dB");
double propagationGainLinear = std::pow (10.0, (propagationGainDb) / 10.0);
*(rxPsd) *= propagationGainLinear;
// apply the fast fading and the beamforming gain
rxPsd = m_spectrumLossModel->CalcRxPowerSpectralDensity (rxPsd, txMob, rxMob);
rxPsd = m_spectrumLossModel->CalcRxPowerSpectralDensity (rxPsd, params.txMob, params.rxMob, params.txAntenna, params.rxAntenna);
NS_LOG_DEBUG ("Average rx power " << 10 * log10 (Sum (*rxPsd) * 180e3) << " dB");
// create the noise psd
// taken from lte-spectrum-value-helper
const double kT_dBm_Hz = -174.0; // dBm/Hz
double kT_W_Hz = std::pow (10.0, (kT_dBm_Hz - 30) / 10.0);
double noiseFigureLinear = std::pow (10.0, noiseFigure / 10.0);
double noiseFigureLinear = std::pow (10.0, params.noiseFigure / 10.0);
double noisePowerSpectralDensity = kT_W_Hz * noiseFigureLinear;
Ptr<SpectrumValue> noisePsd = Create <SpectrumValue> (txPsd->GetSpectrumModel ());
Ptr<SpectrumValue> noisePsd = Create <SpectrumValue> (params.txPsd->GetSpectrumModel ());
(*noisePsd) = noisePowerSpectralDensity;
// compute the SNR
@@ -117,10 +150,10 @@ ComputeSnr (Ptr<MobilityModel> txMob, Ptr<MobilityModel> rxMob, Ptr<const Spectr
std::ofstream f;
f.open ("example-output.txt", std::ios::out | std::ios::app);
f << Simulator::Now ().GetSeconds () << " " // time [s]
<< txMob->GetPosition ().x << " "
<< txMob->GetPosition ().y << " "
<< rxMob->GetPosition ().x << " "
<< rxMob->GetPosition ().y << " "
<< params.txMob->GetPosition ().x << " "
<< params.txMob->GetPosition ().y << " "
<< params.rxMob->GetPosition ().x << " "
<< params.rxMob->GetPosition ().y << " "
<< cond->GetLosCondition () << " " // channel state
<< 10 * log10 (Sum (*rxPsd) / Sum (*noisePsd)) << " " // SNR [dB]
<< -propagationGainDb << std::endl; // pathloss [dB]
@@ -301,10 +334,6 @@ main (int argc, char *argv[])
m_spectrumLossModel = CreateObjectWithAttributes<ThreeGppSpectrumPropagationLossModel> ("ChannelModel", PointerValue (channelModel));
m_spectrumLossModel->SetAttribute ("vScatt", DoubleValue (vScatt));
// initialize the devices in the ThreeGppSpectrumPropagationLossModel
m_spectrumLossModel->AddDevice (txDev, txAntenna);
m_spectrumLossModel->AddDevice (rxDev, rxAntenna);
BuildingsHelper::Install (nodes);
// set the beamforming vectors
@@ -332,7 +361,7 @@ main (int argc, char *argv[])
for (int i = 0; i < simTime / timeRes; i++)
{
Simulator::Schedule (timeRes * i, &ComputeSnr, txMob, rxMob, txPsd, noiseFigure);
Simulator::Schedule (timeRes * i, &ComputeSnr, ComputeSnrParams (txMob, rxMob, txPsd, noiseFigure, txAntenna, rxAntenna));
}
// initialize the output file

View File

@@ -27,6 +27,7 @@ set(source_files
model/spectrum-model.cc
model/spectrum-phy.cc
model/spectrum-propagation-loss-model.cc
model/phased-array-spectrum-propagation-loss-model.cc
model/spectrum-signal-parameters.cc
model/spectrum-value.cc
model/three-gpp-channel-model.cc
@@ -64,6 +65,7 @@ set(header_files
model/spectrum-model.h
model/spectrum-phy.h
model/spectrum-propagation-loss-model.h
model/phased-array-spectrum-propagation-loss-model.h
model/spectrum-signal-parameters.h
model/spectrum-value.h
model/three-gpp-channel-model.h

View File

@@ -123,7 +123,7 @@ The module provides two ``SpectrumChannel`` implementations:
``SingleModelSpectrumChannel`` and ``MultiModelSpectrumChannel``. They
both provide this functionality:
* Propagation loss modeling, in two forms:
* Propagation loss modeling, in three forms:
- you can plug models based on ``PropagationLossModel`` on these
channels. Only linear models (where the loss value does not
@@ -136,6 +136,14 @@ both provide this functionality:
a separate loss value is calculated and applied to each component
of the power spectral density.
- you can plug models based on ``PhasedArraySpectrumPropagationLossModel``
on these channels. These models can have frequency-dependent loss, i.e.,
a separate loss value is calculated and applied to each component
of the power spectral density. Additionally, these models support
the phased antenna array at the transmitter and the receiver, i.e.,
ns-3 antenna type ``PhasedArrayModel``.
* Propagation delay modeling, by plugging a model based on
``PropagationDelayModel``. The delay is independent of frequency and
applied to the signal as a whole. Delay modeling is implemented by
@@ -642,26 +650,24 @@ ThreeGppChannelModel and ThreeGppSpectrumPropagationLossModel.
ThreeGppSpectrumPropagationLossModel
####################################
The class ThreeGppSpectrumPropagationLossModel extends the SpectrumPropagationLossModel
interface and enables the modeling of frequency
dependent propagation phenomena. The main method is DoCalcRxPowerSpectralDensity,
which takes as input the power spectral density (PSD) of the transmitted signal,
the mobility models of the transmitting node and receiving node, and
returns the PSD of the received signal.
The class ThreeGppSpectrumPropagationLossModel implements the
PhasedArraySpectrumPropagationLossModel interface and enables the modeling of frequency
dependent propagation phenomena while taking into account the specific pair of the
antenna array at the transmitter and the receiver. The main method is
DoCalcRxPowerSpectralDensity, which takes as input the power spectral density (PSD)
of the transmitted signal, the mobility models of the transmitting node and receiving node,
and the antenna array of the transmitting node, and of the receiving node.
Finally, it returns the PSD of the received signal.
Procedure used to compute the PSD of to compute the PSD of the received signal:
1. Retrieve the beamforming vectors
To account for the beamforming, ThreeGppSpectrumPropagationLossModel has to
retrieve the beamforming vectors of the transmitting and receiving antennas.
The method DoCalcRxPowerSpectralDensity uses m_deviceAntennaMap to obtain the
antenna objects associated to the transmitting and receiving devices, and calls
the method GetCurrentBeamformingVector to retrieve the beamforming vectors.
For each device using the channel, the m_deviceAntennaMap contains the associated
antenna object of type PhasedArrayModel. Since the mapping is one-to-one,
the model supports a single antenna object for each device.
The m_deviceAntennaMap has to be initialized by inserting the device-antenna
pairs using the method AddDevice.
The method DoCalcRxPowerSpectralDensity uses the antenna objects
that are passed as parameters for both the transmitting and receiving devices,
and calls the method GetCurrentBeamformingVector to retrieve the beamforming vectors
of these antenna objects.
2. Retrieve the channel matrix
The ThreeGppSpectrumPropagationLossModel relies on the ThreeGppChannelModel class

View File

@@ -50,6 +50,41 @@ using namespace ns3;
static Ptr<ThreeGppPropagationLossModel> m_propagationLossModel; //!< the PropagationLossModel object
static Ptr<ThreeGppSpectrumPropagationLossModel> m_spectrumLossModel; //!< the SpectrumPropagationLossModel object
/**
* \brief A structure that holds the parameters for the
* ComputeSnr function. In this way the problem with the limited
* number of parameters of method Schedule is avoided.
*/
struct ComputeSnrParams
{
Ptr<MobilityModel> txMob; //!< the tx mobility model
Ptr<MobilityModel> rxMob; //!< the rx mobility model
double txPow; //!< the tx power in dBm
double noiseFigure; //!< the noise figure in dB
Ptr<PhasedArrayModel> txAntenna; //!< the tx antenna array
Ptr<PhasedArrayModel> rxAntenna; //!< the rx antenna array
/**
* \brief Constructor
* \param pTxMob the tx mobility model
* \param pRxMob the rx mobility model
* \param pTxPow the tx power in dBm
* \param pNoiseFigure the noise figure in dB
* \param pTxAntenna the tx antenna array
* \param pRxAntenna the rx antenna array
*/
ComputeSnrParams (Ptr<MobilityModel> pTxMob, Ptr<MobilityModel> pRxMob, double pTxPow, double pNoiseFigure,
Ptr<PhasedArrayModel> pTxAntenna, Ptr<PhasedArrayModel> pRxAntenna)
{
txMob = pTxMob;
rxMob = pRxMob;
txPow = pTxPow;
noiseFigure = pNoiseFigure;
txAntenna = pTxAntenna;
rxAntenna = pRxAntenna;
}
};
/**
* Perform the beamforming using the DFT beamforming method
* \param thisDevice the device performing the beamforming
@@ -93,13 +128,10 @@ DoBeamforming (Ptr<NetDevice> thisDevice, Ptr<PhasedArrayModel> thisAntenna, Ptr
/**
* Compute the average SNR
* \param txMob the tx mobility model
* \param rxMob the rx mobility model
* \param txPow the transmitting power in dBm
* \param noiseFigure the noise figure in dB
* \param params A structure that holds the parameters that are needed to perform calculations in ComputeSnr
*/
static void
ComputeSnr (Ptr<MobilityModel> txMob, Ptr<MobilityModel> rxMob, double txPow, double noiseFigure)
ComputeSnr (ComputeSnrParams& params)
{
// Create the tx PSD using the LteSpectrumValueHelper
// 100 RBs corresponds to 18 MHz (1 RB = 180 kHz)
@@ -109,23 +141,39 @@ ComputeSnr (Ptr<MobilityModel> txMob, Ptr<MobilityModel> rxMob, double txPow, do
{
activeRbs0[i] = i;
}
Ptr<SpectrumValue> txPsd = LteSpectrumValueHelper::CreateTxPowerSpectralDensity (2100, 100, txPow, activeRbs0);
Ptr<SpectrumValue> txPsd = LteSpectrumValueHelper::CreateTxPowerSpectralDensity (2100, 100, params.txPow, activeRbs0);
Ptr<SpectrumValue> rxPsd = txPsd->Copy ();
NS_LOG_DEBUG ("Average tx power " << 10*log10(Sum (*txPsd) * 180e3) << " dB");
// create the noise PSD
Ptr<SpectrumValue> noisePsd = LteSpectrumValueHelper::CreateNoisePowerSpectralDensity (2100, 100, noiseFigure);
Ptr<SpectrumValue> noisePsd = LteSpectrumValueHelper::CreateNoisePowerSpectralDensity (2100, 100, params.noiseFigure);
NS_LOG_DEBUG ("Average noise power " << 10*log10 (Sum (*noisePsd) * 180e3) << " dB");
// apply the pathloss
double propagationGainDb = m_propagationLossModel->CalcRxPower (0, txMob, rxMob);
double propagationGainDb = m_propagationLossModel->CalcRxPower (0, params.txMob, params.rxMob);
NS_LOG_DEBUG ("Pathloss " << -propagationGainDb << " dB");
double propagationGainLinear = std::pow (10.0, (propagationGainDb) / 10.0);
*(rxPsd) *= propagationGainLinear;
if (params.txAntenna == nullptr)
{
NS_ABORT_MSG("params.txAntenna is nullptr!");
}
else if (params.rxAntenna == nullptr)
{
NS_ABORT_MSG("params.rxAntenna is nullptr!");
}
Ptr<const PhasedArrayModel> a = params.txAntenna;
if (a == nullptr)
{
NS_ABORT_MSG("params.txAntenna is nullptr!");
}
// apply the fast fading and the beamforming gain
rxPsd = m_spectrumLossModel->CalcRxPowerSpectralDensity (rxPsd, txMob, rxMob);
NS_LOG_DEBUG ("Average rx power " << 10*log10 (Sum (*rxPsd) * 180e3) << " dB");
rxPsd = m_spectrumLossModel->CalcRxPowerSpectralDensity (rxPsd, params.txMob, params.rxMob, params.txAntenna, params.rxAntenna);
NS_LOG_DEBUG ("Average rx power " << 10 * log10 (Sum (*rxPsd) * 180e3) << " dB");
// compute the SNR
NS_LOG_DEBUG ("Average SNR " << 10 * log10 (Sum (*rxPsd) / Sum (*noisePsd)) << " dB");
@@ -231,17 +279,13 @@ main (int argc, char *argv[])
Ptr<PhasedArrayModel> txAntenna = CreateObjectWithAttributes<UniformPlanarArray> ("NumColumns", UintegerValue (2), "NumRows", UintegerValue (2));
Ptr<PhasedArrayModel> rxAntenna = CreateObjectWithAttributes<UniformPlanarArray> ("NumColumns", UintegerValue (2), "NumRows", UintegerValue (2));
// initialize the devices in the ThreeGppSpectrumPropagationLossModel
m_spectrumLossModel->AddDevice (txDev, txAntenna);
m_spectrumLossModel->AddDevice (rxDev, rxAntenna);
// set the beamforming vectors
DoBeamforming (txDev, txAntenna, rxDev);
DoBeamforming (rxDev, rxAntenna, txDev);
for (int i = 0; i < floor (simTime / timeRes); i++)
{
Simulator::Schedule (MilliSeconds (timeRes*i), &ComputeSnr, txMob, rxMob, txPow, noiseFigure);
Simulator::Schedule (MilliSeconds (timeRes*i), &ComputeSnr, ComputeSnrParams (txMob, rxMob, txPow, noiseFigure, txAntenna, rxAntenna));
}
Simulator::Run ();

View File

@@ -112,14 +112,15 @@ public:
Ptr<const PhasedArrayModel> bAntenna) = 0;
/**
* Calculate the channel key using the Cantor function
* \param x1 first value
* \param x2 second value
* \return \f$ (((x1 + x2) * (x1 + x2 + 1))/2) + x2; \f$
* Generate a unique value for the pair of unsigned integer of 32 bits,
* where the order does not matter, i.e., the same value will be returned for (a,b) and (b,a).
* \param a the first value
* \param b the second value
* \return return an integer representing a unique value for the pair of values
*/
static constexpr uint32_t GetKey (uint32_t x1, uint32_t x2)
static uint64_t GetKey (uint32_t a, uint32_t b)
{
return (((x1 + x2) * (x1 + x2 + 1)) / 2) + x2;
return (uint64_t) std::min (a, b) << 32 | std::max (a, b);
}
static const uint8_t AOA_INDEX = 0; //!< index of the AOA value in the m_angle array

View File

@@ -269,6 +269,19 @@ MultiModelSpectrumChannel::StartTx (Ptr<SpectrumSignalParameters> txParams)
if ((*rxPhyIterator) != txParams->txPhy)
{
Ptr<NetDevice> rxNetDevice = (*rxPhyIterator)->GetDevice ();
Ptr<NetDevice> txNetDevice = txParams->txPhy->GetDevice ();
if (rxNetDevice && txNetDevice)
{
// we assume that devices are attached to a node
if (rxNetDevice->GetNode()->GetId() == txNetDevice->GetNode()->GetId())
{
NS_LOG_DEBUG ("Skipping the pathloss calculation among different antennas of the same node, not supported yet by any pathloss model in ns-3.");
continue;
}
}
NS_LOG_LOGIC ("copying signal parameters " << txParams);
Ptr<SpectrumSignalParameters> rxParams = txParams->Copy ();
rxParams->psd = Copy<SpectrumValue> (convertedTxPowerSpectrum);
@@ -320,6 +333,21 @@ MultiModelSpectrumChannel::StartTx (Ptr<SpectrumSignalParameters> txParams)
{
rxParams->psd = m_spectrumPropagationLoss->CalcRxPowerSpectralDensity (rxParams->psd, txMobility, receiverMobility);
}
else if (m_phasedArraySpectrumPropagationLoss)
{
// they cannot be combined, this case is not supported yet by any propagation model in ns-3
NS_ASSERT_MSG (rxParams->txAntenna == nullptr && rxAntenna == nullptr, " Either AntennaModel or PhasedArrayModel can be used on a pair of TX/RX device");
Ptr<PhasedArraySpectrumPhy> txPhasedArraySpectrumPhy = DynamicCast<PhasedArraySpectrumPhy> (txParams->txPhy);
Ptr<PhasedArraySpectrumPhy> rxPhasedArraySpectrumPhy = DynamicCast<PhasedArraySpectrumPhy> (*rxPhyIterator);
NS_ASSERT_MSG (txPhasedArraySpectrumPhy && rxPhasedArraySpectrumPhy, "PhasedArraySpectrumPhy should be installed at both TX and RX in order to use PhasedArraySpectrumPropagationLoss.");
Ptr<const PhasedArrayModel> txPhasedArrayModel = txPhasedArraySpectrumPhy->GetPhasedArrayModel ();
Ptr<const PhasedArrayModel> rxPhasedArrayModel = rxPhasedArraySpectrumPhy->GetPhasedArrayModel ();
NS_ASSERT_MSG (txPhasedArrayModel && rxPhasedArrayModel, "PhasedArrayModel instances should be installed at both TX and RX SpectrumPhy in order to use PhasedArraySpectrumPropagationLoss.");
rxParams->psd = m_phasedArraySpectrumPropagationLoss->CalcRxPowerSpectralDensity (rxParams->psd, txMobility, receiverMobility, txPhasedArrayModel, rxPhasedArrayModel);
}
if (m_propagationDelay)
{
@@ -327,11 +355,10 @@ MultiModelSpectrumChannel::StartTx (Ptr<SpectrumSignalParameters> txParams)
}
}
Ptr<NetDevice> netDev = (*rxPhyIterator)->GetDevice ();
if (netDev)
if (rxNetDevice)
{
// the receiver has a NetDevice, so we expect that it is attached to a Node
uint32_t dstNode = netDev->GetNode ()->GetId ();
uint32_t dstNode = rxNetDevice->GetNode ()->GetId ();
Simulator::ScheduleWithContext (dstNode, delay, &MultiModelSpectrumChannel::StartRx, this,
rxParams, *rxPhyIterator);
}

View File

@@ -0,0 +1,80 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2021 CTTC
*
* 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
*
*/
#include "phased-array-spectrum-propagation-loss-model.h"
#include <ns3/log.h>
#include <ns3/phased-array-model.h>
namespace ns3 {
NS_LOG_COMPONENT_DEFINE ("PhasedArraySpectrumPropagationLossModel");
NS_OBJECT_ENSURE_REGISTERED (PhasedArraySpectrumPropagationLossModel);
PhasedArraySpectrumPropagationLossModel::PhasedArraySpectrumPropagationLossModel ()
: m_next (0)
{
}
PhasedArraySpectrumPropagationLossModel::~PhasedArraySpectrumPropagationLossModel ()
{
}
void
PhasedArraySpectrumPropagationLossModel::DoDispose ()
{
m_next = 0;
}
TypeId
PhasedArraySpectrumPropagationLossModel::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::PhasedArraySpectrumPropagationLossModel")
.SetParent<Object> ()
.SetGroupName ("Spectrum")
;
return tid;
}
void PhasedArraySpectrumPropagationLossModel::SetNext (Ptr<PhasedArraySpectrumPropagationLossModel> next)
{
m_next = next;
}
Ptr<SpectrumValue>
PhasedArraySpectrumPropagationLossModel::CalcRxPowerSpectralDensity (Ptr<const SpectrumValue> txPsd,
Ptr<const MobilityModel> a,
Ptr<const MobilityModel> b,
Ptr<const PhasedArrayModel> aPhasedArrayModel,
Ptr<const PhasedArrayModel> bPhasedArrayModel) const
{
// Here we assume that all the models in the chain of models are of type
// PhasedArraySpectrumPropagationLossModel that provides the implementation of
// this function, i.e. has phased array model of TX and RX as parameters
Ptr<SpectrumValue> rxPsd = DoCalcRxPowerSpectralDensity (txPsd, a, b, aPhasedArrayModel, bPhasedArrayModel);
if (m_next != 0)
{
rxPsd = m_next->CalcRxPowerSpectralDensity (rxPsd, a, b, aPhasedArrayModel, bPhasedArrayModel);
}
return rxPsd;
}
} // namespace ns3

View File

@@ -0,0 +1,120 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2021 CTTC
*
* 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
*
*/
#ifndef PHASED_ARRAY_SPECTRUM_PROPAGATION_LOSS_MODEL_H
#define PHASED_ARRAY_SPECTRUM_PROPAGATION_LOSS_MODEL_H
#include <ns3/object.h>
#include <ns3/mobility-model.h>
#include <ns3/spectrum-value.h>
#include <ns3/phased-array-model.h>
namespace ns3 {
/**
* \ingroup spectrum
*
* \brief spectrum-aware propagation loss model that is
* compatible with PhasedArrayModel type of ns-3 antenna
*
* Interface for propagation loss models to be adopted when
* transmissions are modeled with a power spectral density by means of
* the SpectrumValue class, and when PhasedArrayModel type of atenna
* is being used for TX and RX.
*
*/
class PhasedArraySpectrumPropagationLossModel : public Object
{
public:
PhasedArraySpectrumPropagationLossModel ();
virtual ~PhasedArraySpectrumPropagationLossModel ();
/**
* \brief Get the type ID.
* \return the object TypeId
*/
static TypeId GetTypeId ();
/**
* Used to chain various instances of PhasedArraySpectrumPropagationLossModel
*
* @param next
*/
void SetNext (Ptr<PhasedArraySpectrumPropagationLossModel> next);
/**
* This method is to be called to calculate
*
* @param txPsd the SpectrumValue representing the power spectral
* density of the transmission. Watt units are to be used for radio
* communications, and Pascal units for acoustic communications
* (e.g., underwater).
*
* @param a sender mobility
* @param b receiver mobility
* @param aPhasedArrayModel the instance of the phased antenna array of the sender
* @param bPhasedArrayModel the instance of the phased antenna array of the receiver
*
* @return set of values Vs frequency representing the received
* power in the same units used for the txPower parameter.
*/
Ptr<SpectrumValue> CalcRxPowerSpectralDensity (Ptr<const SpectrumValue> txPsd,
Ptr<const MobilityModel> a,
Ptr<const MobilityModel> b,
Ptr<const PhasedArrayModel> aPhasedArrayModel,
Ptr<const PhasedArrayModel> bPhasedArrayModel) const;
protected:
virtual void DoDispose ();
private:
/**
*
* @param txPsd set of values Vs frequency representing the
* transmission power. See SpectrumChannel for details.
* @param a sender mobility
* @param b receiver mobility
* @param aPhasedArrayModel the instance of the phased antenna array of the sender
* @param bPhasedArrayModel the instance of the phased antenna array of the receiver
*
* @return set of values Vs frequency representing the received
* power in the same units used for the txPower parameter.
*/
virtual Ptr<SpectrumValue> DoCalcRxPowerSpectralDensity (Ptr<const SpectrumValue> txPsd,
Ptr<const MobilityModel> a,
Ptr<const MobilityModel> b,
Ptr<const PhasedArrayModel> aPhasedArrayModel,
Ptr<const PhasedArrayModel> bPhasedArrayModel) const = 0;
Ptr<PhasedArraySpectrumPropagationLossModel> m_next; //!< PhasedArraySpectrumPropagationLossModel chained to this one.
};
} // namespace ns3
#endif /* PHASED_ARRAY_SPECTRUM_PROPAGATION_LOSS_MODEL_H */

View File

@@ -110,6 +110,19 @@ SingleModelSpectrumChannel::StartTx (Ptr<SpectrumSignalParameters> txParams)
rxPhyIterator != m_phyList.end ();
++rxPhyIterator)
{
Ptr<NetDevice> rxNetDevice = (*rxPhyIterator)->GetDevice ();
Ptr<NetDevice> txNetDevice = txParams->txPhy->GetDevice ();
if (rxNetDevice && txNetDevice)
{
// we assume that devices are attached to a node
if (rxNetDevice->GetNode()->GetId() == txNetDevice->GetNode()->GetId())
{
NS_LOG_DEBUG ("Skipping the pathloss calculation among different antennas of the same node, not supported yet by any pathloss model in ns-3.");
continue;
}
}
if ((*rxPhyIterator) != txParams->txPhy)
{
Time delay = MicroSeconds (0);
@@ -170,11 +183,10 @@ SingleModelSpectrumChannel::StartTx (Ptr<SpectrumSignalParameters> txParams)
}
Ptr<NetDevice> netDev = (*rxPhyIterator)->GetDevice ();
if (netDev)
if (rxNetDevice)
{
// the receiver has a NetDevice, so we expect that it is attached to a Node
uint32_t dstNode = netDev->GetNode ()->GetId ();
uint32_t dstNode = rxNetDevice->GetNode ()->GetId ();
Simulator::ScheduleWithContext (dstNode, delay, &SingleModelSpectrumChannel::StartRx, this, rxParams, *rxPhyIterator);
}
else

View File

@@ -135,6 +135,18 @@ SpectrumChannel::AddSpectrumPropagationLossModel (Ptr<SpectrumPropagationLossMod
m_spectrumPropagationLoss = loss;
}
void
SpectrumChannel::AddPhasedArraySpectrumPropagationLossModel (Ptr<PhasedArraySpectrumPropagationLossModel> loss)
{
NS_LOG_FUNCTION (this << loss);
if (m_phasedArraySpectrumPropagationLoss)
{
loss->SetNext (m_phasedArraySpectrumPropagationLoss);
}
m_phasedArraySpectrumPropagationLoss = loss;
}
void
SpectrumChannel::SetPropagationDelayModel (Ptr<PropagationDelayModel> delay)
{
@@ -149,6 +161,13 @@ SpectrumChannel::GetSpectrumPropagationLossModel (void)
return m_spectrumPropagationLoss;
}
Ptr<PhasedArraySpectrumPropagationLossModel>
SpectrumChannel::GetPhasedArraySpectrumPropagationLossModel (void)
{
NS_LOG_FUNCTION (this);
return m_phasedArraySpectrumPropagationLoss;
}
Ptr<PropagationLossModel>
SpectrumChannel::GetPropagationLossModel ()
{

View File

@@ -27,6 +27,7 @@
#include <ns3/channel.h>
#include <ns3/spectrum-signal-parameters.h>
#include <ns3/spectrum-propagation-loss-model.h>
#include <ns3/phased-array-spectrum-propagation-loss-model.h>
#include <ns3/propagation-delay-model.h>
#include <ns3/propagation-loss-model.h>
#include <ns3/spectrum-phy.h>
@@ -83,6 +84,13 @@ public:
*/
void AddSpectrumPropagationLossModel (Ptr<SpectrumPropagationLossModel> loss);
/**
* Add the frequency-dependent propagation loss model
* that is compapatible with the phased antenna arrays at the TX and RX
* \param loss a pointer to the propagation loss model to be used.
*/
void AddPhasedArraySpectrumPropagationLossModel (Ptr<PhasedArraySpectrumPropagationLossModel> loss);
/**
* Set the propagation delay model to be used
* \param delay Ptr to the propagation delay model to be used.
@@ -95,6 +103,13 @@ public:
*/
Ptr<SpectrumPropagationLossModel> GetSpectrumPropagationLossModel (void);
/**
* Get the frequency-dependent propagation loss model that is
* compatible with the phased antenna arrays at TX and RX
* \returns a pointer to the propagation loss model.
*/
Ptr<PhasedArraySpectrumPropagationLossModel> GetPhasedArraySpectrumPropagationLossModel (void);
/**
* Get the propagation loss model.
* \returns a pointer to the propagation loss model.
@@ -198,6 +213,11 @@ protected:
*/
Ptr<SpectrumPropagationLossModel> m_spectrumPropagationLoss;
/**
* Frequency-dependent propagation loss model to be used with this channel.
*/
Ptr<PhasedArraySpectrumPropagationLossModel> m_phasedArraySpectrumPropagationLoss;
};

View File

@@ -52,5 +52,24 @@ SpectrumPhy::~SpectrumPhy ()
NS_LOG_FUNCTION (this);
}
TypeId
PhasedArraySpectrumPhy::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::PhasedArraySpectrumPhy")
.SetParent<SpectrumPhy> ()
.SetGroupName ("Spectrum")
;
return tid;
}
PhasedArraySpectrumPhy::PhasedArraySpectrumPhy ():SpectrumPhy ()
{
NS_LOG_FUNCTION (this);
}
PhasedArraySpectrumPhy::~PhasedArraySpectrumPhy ()
{
NS_LOG_FUNCTION (this);
}
} // namespace

View File

@@ -31,6 +31,7 @@ class PacketBurst;
class SpectrumChannel;
class MobilityModel;
class AntennaModel;
class PhasedArrayModel;
class SpectrumValue;
class SpectrumModel;
class NetDevice;
@@ -117,6 +118,49 @@ public:
virtual void StartRx (Ptr<SpectrumSignalParameters> params) = 0;
};
/**
* \ingroup spectrum
*
* Abstract base class for Spectrum-aware PHY layers that use
* PhasedArrayModel type of antenna for TX/RX
*
*/
class PhasedArraySpectrumPhy : public SpectrumPhy
{
public:
PhasedArraySpectrumPhy ();
virtual ~PhasedArraySpectrumPhy ();
/**
* \brief Get the type ID.
* \return the object TypeId
*/
static TypeId GetTypeId (void);
/**
* Get the PhasedArrayModel used by the NetDevice for TX/RX.
*
* @return a Ptr to the PhasedArrayModel used by the NetDevice for TX/RX
*/
virtual Ptr<const PhasedArrayModel> GetPhasedArrayModel () const = 0;
private:
/**
* \brief Copy constructor
*
* Defined and unimplemented to avoid misuse
*/
PhasedArraySpectrumPhy (PhasedArraySpectrumPhy const &);
/**
* \brief Copy constructor
*
* Defined and unimplemented to avoid misuse
* \returns
*/
PhasedArraySpectrumPhy& operator= (PhasedArraySpectrumPhy const &);
};
} // namespace ns3
#endif /* SPECTRUM_PHY_H */

View File

@@ -1064,9 +1064,7 @@ ThreeGppChannelModel::GetChannel (Ptr<const MobilityModel> aMob,
NS_LOG_FUNCTION (this);
// Compute the channel key. The key is reciprocal, i.e., key (a, b) = key (b, a)
uint32_t x1 = std::min (aMob->GetObject<Node> ()->GetId (), bMob->GetObject<Node> ()->GetId ());
uint32_t x2 = std::max (aMob->GetObject<Node> ()->GetId (), bMob->GetObject<Node> ()->GetId ());
uint32_t channelId = GetKey (x1, x2);
uint32_t channelId = GetKey (aMob->GetObject<Node> ()->GetId (), bMob->GetObject<Node> ()->GetId ());
// retrieve the channel condition
Ptr<const ChannelCondition> condition = m_channelConditionModel->GetChannelCondition (aMob, bMob);
@@ -1647,6 +1645,7 @@ ThreeGppChannelModel::GetNewChannel (Vector locUT, Ptr<const ChannelCondition> c
std::tie (rxFieldPatternPhi, rxFieldPatternTheta) = uAntenna->GetElementFieldPattern (Angles (rayAoaRadian[nIndex][mIndex], rayZoaRadian[nIndex][mIndex]));
std::tie (txFieldPatternPhi, txFieldPatternTheta) = sAntenna->GetElementFieldPattern (Angles (rayAodRadian[nIndex][mIndex], rayZodRadian[nIndex][mIndex]));
NS_ASSERT (4 <= initialPhase.size ());
rays += (std::complex<double> (cos (initialPhase[0]), sin (initialPhase[0])) * rxFieldPatternTheta * txFieldPatternTheta +
std::complex<double> (cos (initialPhase[1]), sin (initialPhase[1])) * std::sqrt (1 / k) * rxFieldPatternTheta * txFieldPatternPhi +
std::complex<double> (cos (initialPhase[2]), sin (initialPhase[2])) * std::sqrt (1 / k) * rxFieldPatternPhi * txFieldPatternTheta +

View File

@@ -256,7 +256,7 @@ private:
*/
bool ChannelMatrixNeedsUpdate (Ptr<const ThreeGppChannelMatrix> channelMatrix, Ptr<const ChannelCondition> channelCondition) const;
std::unordered_map<uint32_t, Ptr<ThreeGppChannelMatrix> > m_channelMap; //!< map containing the channel realizations
std::unordered_map<uint64_t, Ptr<ThreeGppChannelMatrix> > m_channelMap; //!< map containing the channel realizations
Time m_updatePeriod; //!< the channel update period
double m_frequency; //!< the operating frequency
std::string m_scenario; //!< the 3GPP scenario

View File

@@ -52,7 +52,6 @@ ThreeGppSpectrumPropagationLossModel::~ThreeGppSpectrumPropagationLossModel ()
void
ThreeGppSpectrumPropagationLossModel::DoDispose ()
{
m_deviceAntennaMap.clear ();
m_longTermMap.clear ();
m_channelModel->Dispose ();
m_channelModel = nullptr;
@@ -62,7 +61,7 @@ TypeId
ThreeGppSpectrumPropagationLossModel::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::ThreeGppSpectrumPropagationLossModel")
.SetParent<SpectrumPropagationLossModel> ()
.SetParent<PhasedArraySpectrumPropagationLossModel> ()
.SetGroupName ("Spectrum")
.AddConstructor<ThreeGppSpectrumPropagationLossModel> ()
.AddAttribute ("ChannelModel",
@@ -94,14 +93,6 @@ ThreeGppSpectrumPropagationLossModel::GetChannelModel () const
return m_channelModel;
}
void
ThreeGppSpectrumPropagationLossModel::AddDevice (Ptr<NetDevice> n, Ptr<const PhasedArrayModel> a)
{
NS_ASSERT_MSG (m_deviceAntennaMap.find (n->GetNode ()->GetId ()) == m_deviceAntennaMap.end (),
"Device is already present in the map");
m_deviceAntennaMap.insert (std::make_pair (n->GetNode ()->GetId (), a));
}
double
ThreeGppSpectrumPropagationLossModel::GetFrequency () const
{
@@ -253,9 +244,7 @@ ThreeGppSpectrumPropagationLossModel::GetLongTerm (uint32_t aId, uint32_t bId,
}
// compute the long term key, the key is unique for each tx-rx pair
uint32_t x1 = std::min (aId, bId);
uint32_t x2 = std::max (aId, bId);
uint32_t longTermId = MatrixBasedChannelModel::GetKey (x1, x2);
uint64_t longTermId = MatrixBasedChannelModel::GetKey (aId, bId);
bool update = false; // indicates whether the long term has to be updated
bool notFound = false; // indicates if the long term has not been computed yet
@@ -302,7 +291,9 @@ ThreeGppSpectrumPropagationLossModel::GetLongTerm (uint32_t aId, uint32_t bId,
Ptr<SpectrumValue>
ThreeGppSpectrumPropagationLossModel::DoCalcRxPowerSpectralDensity (Ptr<const SpectrumValue> txPsd,
Ptr<const MobilityModel> a,
Ptr<const MobilityModel> b) const
Ptr<const MobilityModel> b,
Ptr<const PhasedArrayModel> aPhasedArrayModel,
Ptr<const PhasedArrayModel> bPhasedArrayModel) const
{
NS_LOG_FUNCTION (this);
uint32_t aId = a->GetObject<Node> ()->GetId (); // id of the node a
@@ -314,20 +305,18 @@ ThreeGppSpectrumPropagationLossModel::DoCalcRxPowerSpectralDensity (Ptr<const Sp
Ptr<SpectrumValue> rxPsd = Copy<SpectrumValue> (txPsd);
// retrieve the antenna of device a
NS_ASSERT_MSG (m_deviceAntennaMap.find (aId) != m_deviceAntennaMap.end (), "Antenna not found for node " << aId);
Ptr<const PhasedArrayModel> aAntenna = m_deviceAntennaMap.at (aId);
NS_LOG_DEBUG ("a node " << a->GetObject<Node> () << " antenna " << aAntenna);
NS_ASSERT_MSG (aPhasedArrayModel, "Antenna not found for node " << aId);
NS_LOG_DEBUG ("a node " << a->GetObject<Node> () << " antenna " << aPhasedArrayModel);
// retrieve the antenna of the device b
NS_ASSERT_MSG (m_deviceAntennaMap.find (bId) != m_deviceAntennaMap.end (), "Antenna not found for device " << bId);
Ptr<const PhasedArrayModel> bAntenna = m_deviceAntennaMap.at (bId);
NS_LOG_DEBUG ("b node " << bId << " antenna " << bAntenna);
NS_ASSERT_MSG (bPhasedArrayModel, "Antenna not found for device " << bId);
NS_LOG_DEBUG ("b node " << bId << " antenna " << bPhasedArrayModel);
Ptr<const MatrixBasedChannelModel::ChannelMatrix> channelMatrix = m_channelModel->GetChannel (a, b, aAntenna, bAntenna);
Ptr<const MatrixBasedChannelModel::ChannelMatrix> channelMatrix = m_channelModel->GetChannel (a, b, aPhasedArrayModel, bPhasedArrayModel);
// get the precoding and combining vectors
PhasedArrayModel::ComplexVector aW = aAntenna->GetBeamformingVector ();
PhasedArrayModel::ComplexVector bW = bAntenna->GetBeamformingVector ();
PhasedArrayModel::ComplexVector aW = aPhasedArrayModel->GetBeamformingVector ();
PhasedArrayModel::ComplexVector bW = bPhasedArrayModel->GetBeamformingVector ();
// retrieve the long term component
PhasedArrayModel::ComplexVector longTerm = GetLongTerm (aId, bId, channelMatrix, aW, bW);

View File

@@ -22,7 +22,7 @@
#ifndef THREE_GPP_SPECTRUM_PROPAGATION_LOSS_H
#define THREE_GPP_SPECTRUM_PROPAGATION_LOSS_H
#include "ns3/spectrum-propagation-loss-model.h"
#include "ns3/phased-array-spectrum-propagation-loss-model.h"
#include <complex.h>
#include <map>
#include <unordered_map>
@@ -49,7 +49,7 @@ class ChannelCondition;
* \see PhasedArrayModel
* \see ChannelCondition
*/
class ThreeGppSpectrumPropagationLossModel : public SpectrumPropagationLossModel
class ThreeGppSpectrumPropagationLossModel : public PhasedArraySpectrumPropagationLossModel
{
public:
/**
@@ -82,13 +82,6 @@ public:
*/
Ptr<MatrixBasedChannelModel> GetChannelModel () const;
/**
* Add a device-antenna pair
* \param n a pointer to the NetDevice
* \param a a pointer to the associated PhasedArrayModel
*/
void AddDevice (Ptr<NetDevice> n, Ptr<const PhasedArrayModel> a);
/**
* Sets the value of an attribute belonging to the associated
* MatrixBasedChannelModel instance
@@ -122,12 +115,15 @@ public:
* \param txPsd tx PSD
* \param a first node mobility model
* \param b second node mobility model
*
* \param aPhasedArrayModel the antenna array of the first node
* \param bPhasedArrayModel the antenna array of the second node
* \return the received PSD
*/
Ptr<SpectrumValue> DoCalcRxPowerSpectralDensity (Ptr<const SpectrumValue> txPsd,
Ptr<const MobilityModel> a,
Ptr<const MobilityModel> b) const override;
Ptr<const MobilityModel> b,
Ptr<const PhasedArrayModel> aPhasedArrayModel,
Ptr<const PhasedArrayModel> bPhasedArrayModel) const override;
private:
/**
@@ -188,8 +184,7 @@ private:
Ptr<const MatrixBasedChannelModel::ChannelMatrix> params,
const Vector &sSpeed, const Vector &uSpeed) const;
std::unordered_map <uint32_t, Ptr<const PhasedArrayModel> > m_deviceAntennaMap; //!< map containig the <node, antenna> associations
mutable std::unordered_map < uint32_t, Ptr<const LongTerm> > m_longTermMap; //!< map containing the long term components
mutable std::unordered_map < uint64_t, Ptr<const LongTerm> > m_longTermMap; //!< map containing the long term components
Ptr<MatrixBasedChannelModel> m_channelModel; //!< the model to generate the channel matrix
// Variable used to compute the additional Doppler contribution for the delayed

View File

@@ -345,6 +345,45 @@ ThreeGppChannelMatrixUpdateTest::DoRun (void)
Simulator::Destroy ();
}
/**
* \brief A structure that holds the parameters for the function
* CheckLongTermUpdate. In this way the problem with the limited
* number of parameters of method Schedule is avoided.
*/
struct CheckLongTermUpdateParams
{
Ptr<ThreeGppSpectrumPropagationLossModel> lossModel; //!< the ThreeGppSpectrumPropagationLossModel object used to compute the rx PSD
Ptr<SpectrumValue> txPsd; //!< the PSD of the tx signal
Ptr<MobilityModel> txMob; //!< the mobility model of the tx device
Ptr<MobilityModel> rxMob; //!< the mobility model of the rx device
Ptr<SpectrumValue> rxPsdOld; //!< the previously received PSD
Ptr<PhasedArrayModel> txAntenna; //!< the antenna array of the tx device
Ptr<PhasedArrayModel> rxAntenna; //!< the antenna array of the rx device
/**
* \brief Constructor
* \param pLossModel the ThreeGppSpectrumPropagationLossModel object used to compute the rx PSD
* \param pTxPsd the PSD of the tx signal
* \param pTxMob the tx mobility model
* \param pRxMob the rx mobility model
* \param pRxPsdOld the previously received PSD
* \param pTxAntenna the tx antenna array
* \param pRxAntenna the rx antenna array
*/
CheckLongTermUpdateParams (Ptr<ThreeGppSpectrumPropagationLossModel> pLossModel, Ptr<SpectrumValue> pTxPsd,
Ptr<MobilityModel> pTxMob, Ptr<MobilityModel> pRxMob, Ptr<SpectrumValue> pRxPsdOld,
Ptr<PhasedArrayModel> pTxAntenna, Ptr<PhasedArrayModel> pRxAntenna)
{
lossModel = pLossModel;
txPsd = pTxPsd;
txMob = pTxMob;
rxMob = pRxMob;
rxPsdOld = pRxPsdOld;
txAntenna = pTxAntenna;
rxAntenna = pRxAntenna;
}
};
/**
* Test case for the ThreeGppSpectrumPropagationLossModelTest class.
* 1) checks if the long term components for the direct and the reverse link
@@ -384,14 +423,9 @@ private:
/**
* Test of the long term component is correctly updated when the channel
* matrix is recomputed
* \param lossModel the ThreeGppSpectrumPropagationLossModel object used to
* compute the rx PSD
* \param txPsd the PSD of the transmitted signal
* \param txMob the mobility model of the tx device
* \param rxMob the mobility model of the rx device
* \param rxPsdOld the previously received PSD
* \param params a structure that contains the set of parameters needed by CheckLongTermUpdate in order to perform calculations
*/
void CheckLongTermUpdate (Ptr<ThreeGppSpectrumPropagationLossModel> lossModel, Ptr<SpectrumValue> txPsd, Ptr<MobilityModel> txMob, Ptr<MobilityModel> rxMob, Ptr<SpectrumValue> rxPsdOld);
void CheckLongTermUpdate (CheckLongTermUpdateParams &params);
/**
* Checks if two PSDs are equal
@@ -440,10 +474,10 @@ ThreeGppSpectrumPropagationLossModelTest::ArePsdEqual (Ptr<SpectrumValue> first,
}
void
ThreeGppSpectrumPropagationLossModelTest::CheckLongTermUpdate (Ptr<ThreeGppSpectrumPropagationLossModel> lossModel, Ptr<SpectrumValue> txPsd, Ptr<MobilityModel> txMob, Ptr<MobilityModel> rxMob, Ptr<SpectrumValue> rxPsdOld)
ThreeGppSpectrumPropagationLossModelTest::CheckLongTermUpdate (CheckLongTermUpdateParams &params)
{
Ptr<SpectrumValue> rxPsdNew = lossModel->DoCalcRxPowerSpectralDensity (txPsd, txMob, rxMob);
NS_TEST_ASSERT_MSG_EQ (ArePsdEqual (rxPsdOld, rxPsdNew), false, "The long term is not updated when the channel matrix is recomputed");
Ptr<SpectrumValue> rxPsdNew = params.lossModel->DoCalcRxPowerSpectralDensity (params.txPsd, params.txMob, params.rxMob, params.txAntenna, params.rxAntenna);
NS_TEST_ASSERT_MSG_EQ (ArePsdEqual (params.rxPsdOld, rxPsdNew), false, "The long term is not updated when the channel matrix is recomputed");
}
void
@@ -498,10 +532,6 @@ ThreeGppSpectrumPropagationLossModelTest::DoRun ()
"NumRows", UintegerValue (rxAntennaElements [1]),
"AntennaElement", PointerValue(CreateObject<IsotropicAntennaModel> ()));
// initialize ThreeGppSpectrumPropagationLossModel
lossModel->AddDevice (txDev, txAntenna);
lossModel->AddDevice (rxDev, rxAntenna);
// set the beamforming vectors
DoBeamforming (txDev, txAntenna, rxDev, rxAntenna);
DoBeamforming (rxDev, rxAntenna, txDev, txAntenna);
@@ -513,10 +543,10 @@ ThreeGppSpectrumPropagationLossModelTest::DoRun ()
Ptr<SpectrumValue> txPsd = sf.CreateTxPowerSpectralDensity (txPower, channelNumber);
// compute the rx psd
Ptr<SpectrumValue> rxPsdOld = lossModel->DoCalcRxPowerSpectralDensity (txPsd, txMob, rxMob);
Ptr<SpectrumValue> rxPsdOld = lossModel->DoCalcRxPowerSpectralDensity (txPsd, txMob, rxMob, txAntenna, rxAntenna);
// 1) check that the rx PSD is equal for both the direct and the reverse channel
Ptr<SpectrumValue> rxPsdNew = lossModel->DoCalcRxPowerSpectralDensity (txPsd, rxMob, txMob);
Ptr<SpectrumValue> rxPsdNew = lossModel->DoCalcRxPowerSpectralDensity (txPsd, rxMob, txMob, rxAntenna, txAntenna);
NS_TEST_ASSERT_MSG_EQ (ArePsdEqual (rxPsdOld, rxPsdNew), true, "The long term for the direct and the reverse channel are different");
// 2) check if the long term is updated when changing the BF vector
@@ -526,7 +556,7 @@ ThreeGppSpectrumPropagationLossModelTest::DoRun ()
txBfVector [0] = std::complex<double> (0.0, 0.0);
txAntenna->SetBeamformingVector (txBfVector);
rxPsdNew = lossModel->DoCalcRxPowerSpectralDensity (txPsd, rxMob, txMob);
rxPsdNew = lossModel->DoCalcRxPowerSpectralDensity (txPsd, rxMob, txMob, rxAntenna, txAntenna);
NS_TEST_ASSERT_MSG_EQ (ArePsdEqual (rxPsdOld, rxPsdNew), false, "Changing the BF vectors the rx PSD does not change");
// update rxPsdOld
@@ -534,7 +564,7 @@ ThreeGppSpectrumPropagationLossModelTest::DoRun ()
// 3) check if the long term is updated when the channel matrix is recomputed
Simulator::Schedule (MilliSeconds (101), &ThreeGppSpectrumPropagationLossModelTest::CheckLongTermUpdate,
this, lossModel, txPsd, txMob, rxMob, rxPsdOld);
this, CheckLongTermUpdateParams (lossModel, txPsd, txMob, rxMob, rxPsdOld, txAntenna, rxAntenna));
Simulator::Run ();
Simulator::Destroy ();

View File

@@ -9,6 +9,7 @@ def build(bld):
'model/spectrum-converter.cc',
'model/spectrum-signal-parameters.cc',
'model/spectrum-propagation-loss-model.cc',
'model/phased-array-spectrum-propagation-loss-model.cc',
'model/friis-spectrum-propagation-loss.cc',
'model/constant-spectrum-propagation-loss.cc',
'model/spectrum-phy.cc',
@@ -65,6 +66,7 @@ def build(bld):
'model/spectrum-converter.h',
'model/spectrum-signal-parameters.h',
'model/spectrum-propagation-loss-model.h',
'model/phased-array-spectrum-propagation-loss-model.h',
'model/friis-spectrum-propagation-loss.h',
'model/constant-spectrum-propagation-loss.h',
'model/spectrum-phy.h',