27#include "ns3/double.h" 
   29#include "ns3/net-device.h" 
   31#include "ns3/pointer.h" 
   32#include "ns3/simulator.h" 
   33#include "ns3/string.h" 
   66        TypeId(
"ns3::ThreeGppSpectrumPropagationLossModel")
 
   68            .SetGroupName(
"Spectrum")
 
   72                "The channel model. It needs to implement the MatrixBasedChannelModel interface",
 
   76                MakePointerChecker<MatrixBasedChannelModel>());
 
  122    uint16_t sAntenna = 
static_cast<uint16_t
>(sW.size());
 
  123    uint16_t uAntenna = 
static_cast<uint16_t
>(uW.size());
 
  125    NS_ASSERT(uAntenna == params->m_channel.size());
 
  126    NS_ASSERT(sAntenna == params->m_channel.at(0).size());
 
  128    NS_LOG_DEBUG(
"CalcLongTerm with sAntenna " << sAntenna << 
" uAntenna " << uAntenna);
 
  133    uint8_t numCluster = 
static_cast<uint8_t
>(params->m_channel[0][0].size());
 
  135    NS_ASSERT(uAntenna == params->m_channel.size());
 
  136    NS_ASSERT(sAntenna == params->m_channel.at(0).size());
 
  138    for (uint8_t cIndex = 0; cIndex < numCluster; cIndex++)
 
  140        std::complex<double> txSum(0, 0);
 
  141        for (uint16_t sIndex = 0; sIndex < sAntenna; sIndex++)
 
  143            std::complex<double> rxSum(0, 0);
 
  144            for (uint16_t uIndex = 0; uIndex < uAntenna; uIndex++)
 
  146                rxSum = rxSum + uW[uIndex] * params->m_channel[uIndex][sIndex][cIndex];
 
  148            txSum = txSum + sW[sIndex] * rxSum;
 
  150        longTerm.push_back(txSum);
 
  161    const ns3::Vector& sSpeed,
 
  162    const ns3::Vector& uSpeed)
 const 
  169    uint8_t numCluster = 
static_cast<uint8_t
>(channelMatrix->m_channel[0][0].size());
 
  175    double factor = 2 * M_PI * slotTime * 
GetFrequency() / 3e8;
 
  183    NS_ASSERT(numCluster <= channelParams->m_alpha.size());
 
  184    NS_ASSERT(numCluster <= channelParams->m_D.size());
 
  189    NS_ASSERT(numCluster <= longTerm.size());
 
  192    bool isSameDirection = (channelParams->m_nodeIds == channelMatrix->m_nodeIds);
 
  218    for (uint8_t cIndex = 0; cIndex < numCluster; cIndex++)
 
  231        double alpha = channelParams->m_alpha[cIndex];
 
  232        double D = channelParams->m_D[cIndex];
 
  236            factor * ((sin(zoa[cIndex] * M_PI / 180) * cos(aoa[cIndex] * M_PI / 180) * uSpeed.x +
 
  237                       sin(zoa[cIndex] * M_PI / 180) * sin(aoa[cIndex] * M_PI / 180) * uSpeed.y +
 
  238                       cos(zoa[cIndex] * M_PI / 180) * uSpeed.z) +
 
  239                      (sin(zod[cIndex] * M_PI / 180) * cos(aod[cIndex] * M_PI / 180) * sSpeed.x +
 
  240                       sin(zod[cIndex] * M_PI / 180) * sin(aod[cIndex] * M_PI / 180) * sSpeed.y +
 
  241                       cos(zod[cIndex] * M_PI / 180) * sSpeed.z) +
 
  243        doppler.emplace_back(cos(tempDoppler), sin(tempDoppler));
 
  256            std::complex<double> subsbandGain(0.0, 0.0);
 
  257            double fsb = (*sbit).fc; 
 
  258            for (uint8_t cIndex = 0; cIndex < numCluster; cIndex++)
 
  260                double delay = -2 * M_PI * fsb * (channelParams->m_delay[cIndex]);
 
  261                subsbandGain = subsbandGain + longTerm[cIndex] * doppler[cIndex] *
 
  262                                                  std::complex<double>(cos(delay), sin(delay));
 
  264            *vit = (*vit) * (
norm(subsbandGain));
 
  285    if (!channelMatrix->IsReverse(aPhasedArrayModel->GetId(), bPhasedArrayModel->GetId()))
 
  287        sW = aPhasedArrayModel->GetBeamformingVector();
 
  288        uW = bPhasedArrayModel->GetBeamformingVector();
 
  292        sW = bPhasedArrayModel->GetBeamformingVector();
 
  293        uW = aPhasedArrayModel->GetBeamformingVector();
 
  297    bool notFound = 
false; 
 
  300    uint64_t longTermId =
 
  306        NS_LOG_DEBUG(
"found the long term component in the map");
 
  312        update = (
m_longTermMap[longTermId]->m_channel->m_generatedTime !=
 
  313                      channelMatrix->m_generatedTime ||
 
  322    if (update || notFound)
 
  330        longTermItem->m_longTerm = longTerm;
 
  331        longTermItem->m_channel = channelMatrix;
 
  332        longTermItem->m_sW = sW;
 
  333        longTermItem->m_uW = uW;
 
  355                  "The position of a and b devices cannot be the same");
 
  360    NS_ASSERT_MSG(aPhasedArrayModel, 
"Antenna not found for node " << aId);
 
  361    NS_LOG_DEBUG(
"a node " << a->GetObject<
Node>() << 
" antenna " << aPhasedArrayModel);
 
  364    NS_ASSERT_MSG(bPhasedArrayModel, 
"Antenna not found for device " << bId);
 
  365    NS_LOG_DEBUG(
"b node " << bId << 
" antenna " << bPhasedArrayModel);
 
  368        m_channelModel->GetChannel(a, b, aPhasedArrayModel, bPhasedArrayModel);
 
  374        GetLongTerm(channelMatrix, aPhasedArrayModel, bPhasedArrayModel);
 
Hold a value for an Attribute.
 
This class can be used to hold variables of floating point type such as 'double' or 'float'.
 
static const uint8_t AOA_INDEX
index of the AOA value in the m_angle array
 
static const uint8_t ZOD_INDEX
index of the ZOD value in the m_angle array
 
static const uint8_t AOD_INDEX
index of the AOD value in the m_angle array
 
std::vector< double > DoubleVector
type definition for vectors of doubles
 
static const uint8_t ZOA_INDEX
index of the ZOA value in the m_angle array
 
static uint64_t GetKey(uint32_t a, uint32_t b)
Generate a unique value for the pair of unsigned integer of 32 bits, where the order does not matter,...
 
std::vector< std::complex< double > > ComplexVector
type definition for complex vectors
 
spectrum-aware propagation loss model that is compatible with PhasedArrayModel type of ns-3 antenna
 
Smart pointer class similar to boost::intrusive_ptr.
 
static Time Now()
Return the current simulation virtual time.
 
Values::iterator ValuesBegin()
 
Bands::const_iterator ConstBandsBegin() const
 
Values::iterator ValuesEnd()
 
Hold variables of type string.
 
3GPP Spectrum Propagation Loss Model
 
void GetChannelModelAttribute(const std::string &name, AttributeValue &value) const
Returns the value of an attribute belonging to the associated MatrixBasedChannelModel instance.
 
Ptr< SpectrumValue > DoCalcRxPowerSpectralDensity(Ptr< const SpectrumSignalParameters > params, Ptr< const MobilityModel > a, Ptr< const MobilityModel > b, Ptr< const PhasedArrayModel > aPhasedArrayModel, Ptr< const PhasedArrayModel > bPhasedArrayModel) const override
Computes the received PSD.
 
PhasedArrayModel::ComplexVector GetLongTerm(Ptr< const MatrixBasedChannelModel::ChannelMatrix > channelMatrix, Ptr< const PhasedArrayModel > aPhasedArrayModel, Ptr< const PhasedArrayModel > bPhasedArrayModel) const
Looks for the long term component in m_longTermMap.
 
Ptr< MatrixBasedChannelModel > m_channelModel
the model to generate the channel matrix
 
void SetChannelModel(Ptr< MatrixBasedChannelModel > channel)
Set the channel model object.
 
~ThreeGppSpectrumPropagationLossModel() override
Destructor.
 
std::unordered_map< uint64_t, Ptr< const LongTerm > > m_longTermMap
map containing the long term components
 
double GetFrequency() const
Get the operating frequency.
 
void SetChannelModelAttribute(const std::string &name, const AttributeValue &value)
Sets the value of an attribute belonging to the associated MatrixBasedChannelModel instance.
 
Ptr< MatrixBasedChannelModel > GetChannelModel() const
Get the channel model object.
 
Ptr< SpectrumValue > CalcBeamformingGain(Ptr< SpectrumValue > txPsd, PhasedArrayModel::ComplexVector longTerm, Ptr< const MatrixBasedChannelModel::ChannelMatrix > channelMatrix, Ptr< const MatrixBasedChannelModel::ChannelParams > channelParams, const Vector &sSpeed, const Vector &uSpeed) const
Computes the beamforming gain and applies it to the tx PSD.
 
PhasedArrayModel::ComplexVector CalcLongTerm(Ptr< const MatrixBasedChannelModel::ChannelMatrix > channelMatrix, const PhasedArrayModel::ComplexVector &sW, const PhasedArrayModel::ComplexVector &uW) const
Computes the long term component.
 
void DoDispose() override
Destructor implementation.
 
static TypeId GetTypeId()
Get the type ID.
 
ThreeGppSpectrumPropagationLossModel()
Constructor.
 
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
 
a unique identifier for an interface.
 
TypeId SetParent(TypeId tid)
Set the parent TypeId.
 
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
 
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
 
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
 
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
 
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
 
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
 
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
 
const double norm
Normalization to obtain randoms on [0,1).
 
Every class exported by the ns3 library is enclosed in the ns3 namespace.