From 4ca8b12ea0d732b45b66eebf6b8bb1946eea5324 Mon Sep 17 00:00:00 2001
From: bbojovic
Date: Thu, 1 Jul 2021 08:44:46 +0200
Subject: [PATCH] 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.
---
CHANGES.html | 4 +
RELEASE_NOTES.md | 3 +
.../three-gpp-v2v-channel-example.cc | 69 +++++++---
src/spectrum/CMakeLists.txt | 2 +
src/spectrum/doc/spectrum.rst | 36 +++---
.../examples/three-gpp-channel-example.cc | 74 ++++++++---
.../model/matrix-based-channel-model.h | 13 +-
.../model/multi-model-spectrum-channel.cc | 33 ++++-
...d-array-spectrum-propagation-loss-model.cc | 80 ++++++++++++
...ed-array-spectrum-propagation-loss-model.h | 120 ++++++++++++++++++
.../model/single-model-spectrum-channel.cc | 18 ++-
src/spectrum/model/spectrum-channel.cc | 19 +++
src/spectrum/model/spectrum-channel.h | 20 +++
src/spectrum/model/spectrum-phy.cc | 19 +++
src/spectrum/model/spectrum-phy.h | 44 +++++++
src/spectrum/model/three-gpp-channel-model.cc | 5 +-
src/spectrum/model/three-gpp-channel-model.h | 2 +-
...ree-gpp-spectrum-propagation-loss-model.cc | 35 ++---
...hree-gpp-spectrum-propagation-loss-model.h | 21 ++-
.../test/three-gpp-channel-test-suite.cc | 66 +++++++---
src/spectrum/wscript | 2 +
21 files changed, 565 insertions(+), 120 deletions(-)
create mode 100644 src/spectrum/model/phased-array-spectrum-propagation-loss-model.cc
create mode 100644 src/spectrum/model/phased-array-spectrum-propagation-loss-model.h
diff --git a/CHANGES.html b/CHANGES.html
index 3928c8df4..1b800e4c9 100644
--- a/CHANGES.html
+++ b/CHANGES.html
@@ -56,11 +56,15 @@ us a note on ns-developers mailing list.
The helpers of the NetDevices supporting flow control (PointToPointHelper, CsmaHelper, SimpleNetDeviceHelper, WifiHelper) now provide a DisableFlowControl 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)
Added a new trace source TcDrop 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.
+
Added a new class PhasedArraySpectrumPropagationLossModel, and its DoCalcRxPowerSpectralDensity 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.
Changes to existing API:
internet: Support for Network Simulation Cradle (NSC) TCP has been removed.
fd-net-device: Support for PlanetLabFdNetDeviceHelper has been removed.
+
ThreeGppSpectrumPropagationLossModel now inherits PhasedArraySpectrumPropagationLossModel. The modules that use ThreeGppSpectrumPropagationLossModel should implement SpectrumPhy::GetAntenna that will return the instance of PhasedArrayModel.
+
AddDevice function is removed from ThreeGppSpectrumPropagationLossModel to support multiple arrays per device.
+
SpectrumPhy function GetRxAntenna is renamed to GetAntenna, and its return value is changed to Ptr instead of Ptr to support also PhasedArrayModel type of antenna.
Changes to build system:
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index 0c49654e1..0426f9e1b 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -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
diff --git a/examples/channel-models/three-gpp-v2v-channel-example.cc b/examples/channel-models/three-gpp-v2v-channel-example.cc
index cb0b10c9b..15ab147eb 100644
--- a/examples/channel-models/three-gpp-v2v-channel-example.cc
+++ b/examples/channel-models/three-gpp-v2v-channel-example.cc
@@ -54,6 +54,42 @@ static Ptr m_propagationLossModel; //!< the Propag
static Ptr m_spectrumLossModel; //!< the SpectrumPropagationLossModel object
static Ptr 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 txMob; //!< the tx mobility model
+ Ptr rxMob; //!< the rx mobility model
+ Ptr txPsd; //!< the PSD of the tx signal
+ double noiseFigure; //!< the noise figure in dB
+ Ptr txAntenna; //!< the tx antenna array
+ Ptr 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 pTxMob, Ptr pRxMob,
+ Ptr pTxPsd, double pNoiseFigure,
+ Ptr pTxAntenna, Ptr 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 thisDevice, Ptr 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 txMob, Ptr rxMob, Ptr txPsd, double noiseFigure)
+ComputeSnr (ComputeSnrParams& params)
{
- Ptr rxPsd = txPsd->Copy ();
+ Ptr rxPsd = params.txPsd->Copy ();
// check the channel condition
- Ptr cond = m_condModel->GetChannelCondition (txMob, rxMob);
+ Ptr 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 noisePsd = Create (txPsd->GetSpectrumModel ());
+ Ptr noisePsd = Create (params.txPsd->GetSpectrumModel ());
(*noisePsd) = noisePowerSpectralDensity;
// compute the SNR
@@ -117,10 +150,10 @@ ComputeSnr (Ptr txMob, Ptr rxMob, PtrGetPosition ().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 ("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
diff --git a/src/spectrum/CMakeLists.txt b/src/spectrum/CMakeLists.txt
index 072952b12..72e387b2a 100644
--- a/src/spectrum/CMakeLists.txt
+++ b/src/spectrum/CMakeLists.txt
@@ -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
diff --git a/src/spectrum/doc/spectrum.rst b/src/spectrum/doc/spectrum.rst
index cba0ce038..b97912665 100644
--- a/src/spectrum/doc/spectrum.rst
+++ b/src/spectrum/doc/spectrum.rst
@@ -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
diff --git a/src/spectrum/examples/three-gpp-channel-example.cc b/src/spectrum/examples/three-gpp-channel-example.cc
index bbeb6c2eb..12cb5bac8 100644
--- a/src/spectrum/examples/three-gpp-channel-example.cc
+++ b/src/spectrum/examples/three-gpp-channel-example.cc
@@ -50,6 +50,41 @@ using namespace ns3;
static Ptr m_propagationLossModel; //!< the PropagationLossModel object
static Ptr 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 txMob; //!< the tx mobility model
+ Ptr rxMob; //!< the rx mobility model
+ double txPow; //!< the tx power in dBm
+ double noiseFigure; //!< the noise figure in dB
+ Ptr txAntenna; //!< the tx antenna array
+ Ptr 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 pTxMob, Ptr pRxMob, double pTxPow, double pNoiseFigure,
+ Ptr pTxAntenna, Ptr 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 thisDevice, Ptr 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 txMob, Ptr 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 txMob, Ptr rxMob, double txPow, do
{
activeRbs0[i] = i;
}
- Ptr txPsd = LteSpectrumValueHelper::CreateTxPowerSpectralDensity (2100, 100, txPow, activeRbs0);
+ Ptr txPsd = LteSpectrumValueHelper::CreateTxPowerSpectralDensity (2100, 100, params.txPow, activeRbs0);
Ptr rxPsd = txPsd->Copy ();
NS_LOG_DEBUG ("Average tx power " << 10*log10(Sum (*txPsd) * 180e3) << " dB");
// create the noise PSD
- Ptr noisePsd = LteSpectrumValueHelper::CreateNoisePowerSpectralDensity (2100, 100, noiseFigure);
+ Ptr 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 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 txAntenna = CreateObjectWithAttributes ("NumColumns", UintegerValue (2), "NumRows", UintegerValue (2));
Ptr rxAntenna = CreateObjectWithAttributes ("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 ();
diff --git a/src/spectrum/model/matrix-based-channel-model.h b/src/spectrum/model/matrix-based-channel-model.h
index 37bccff96..85f6ff63a 100644
--- a/src/spectrum/model/matrix-based-channel-model.h
+++ b/src/spectrum/model/matrix-based-channel-model.h
@@ -112,14 +112,15 @@ public:
Ptr 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
diff --git a/src/spectrum/model/multi-model-spectrum-channel.cc b/src/spectrum/model/multi-model-spectrum-channel.cc
index de746186d..7017a26c6 100644
--- a/src/spectrum/model/multi-model-spectrum-channel.cc
+++ b/src/spectrum/model/multi-model-spectrum-channel.cc
@@ -269,6 +269,19 @@ MultiModelSpectrumChannel::StartTx (Ptr txParams)
if ((*rxPhyIterator) != txParams->txPhy)
{
+ Ptr rxNetDevice = (*rxPhyIterator)->GetDevice ();
+ Ptr 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 rxParams = txParams->Copy ();
rxParams->psd = Copy (convertedTxPowerSpectrum);
@@ -320,6 +333,21 @@ MultiModelSpectrumChannel::StartTx (Ptr 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 txPhasedArraySpectrumPhy = DynamicCast (txParams->txPhy);
+ Ptr rxPhasedArraySpectrumPhy = DynamicCast (*rxPhyIterator);
+
+ NS_ASSERT_MSG (txPhasedArraySpectrumPhy && rxPhasedArraySpectrumPhy, "PhasedArraySpectrumPhy should be installed at both TX and RX in order to use PhasedArraySpectrumPropagationLoss.");
+ Ptr txPhasedArrayModel = txPhasedArraySpectrumPhy->GetPhasedArrayModel ();
+ Ptr 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 txParams)
}
}
- Ptr 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);
}
diff --git a/src/spectrum/model/phased-array-spectrum-propagation-loss-model.cc b/src/spectrum/model/phased-array-spectrum-propagation-loss-model.cc
new file mode 100644
index 000000000..703b1e2a1
--- /dev/null
+++ b/src/spectrum/model/phased-array-spectrum-propagation-loss-model.cc
@@ -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
+#include
+
+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