26 #include "ns3/net-device.h"
28 #include "ns3/double.h"
29 #include "ns3/string.h"
30 #include "ns3/simulator.h"
31 #include "ns3/pointer.h"
61 static TypeId tid =
TypeId (
"ns3::ThreeGppSpectrumPropagationLossModel")
63 .SetGroupName (
"Spectrum")
65 .AddAttribute(
"ChannelModel",
66 "The channel model. It needs to implement the MatrixBasedChannelModel interface",
70 MakePointerChecker<MatrixBasedChannelModel> ())
114 uint16_t sAntenna =
static_cast<uint16_t
> (sW.size ());
115 uint16_t uAntenna =
static_cast<uint16_t
> (uW.size ());
117 NS_ASSERT (uAntenna == params->m_channel.size ());
118 NS_ASSERT (sAntenna == params->m_channel.at (0).size());
120 NS_LOG_DEBUG (
"CalcLongTerm with sAntenna " << sAntenna <<
" uAntenna " << uAntenna);
124 uint8_t numCluster =
static_cast<uint8_t
> (params->m_channel[0][0].size ());
126 NS_ASSERT (uAntenna == params->m_channel.size ());
127 NS_ASSERT (sAntenna == params->m_channel.at (0).size());
129 for (uint8_t cIndex = 0; cIndex < numCluster; cIndex++)
131 std::complex<double> txSum (0, 0);
132 for (uint16_t sIndex = 0; sIndex < sAntenna; sIndex++)
134 std::complex<double> rxSum (0, 0);
135 for (uint16_t uIndex = 0; uIndex < uAntenna; uIndex++)
137 rxSum = rxSum + uW[uIndex] * params->m_channel[uIndex][sIndex][cIndex];
139 txSum = txSum + sW[sIndex] * rxSum;
141 longTerm.push_back (txSum);
151 const ns3::Vector &sSpeed,
const ns3::Vector &uSpeed)
const
158 uint8_t numCluster =
static_cast<uint8_t
> (channelMatrix->m_channel[0][0].size ());
164 double factor = 2 * M_PI * slotTime *
GetFrequency () / 3e8;
172 NS_ASSERT (numCluster <= channelParams->m_alpha.size ());
173 NS_ASSERT (numCluster <= channelParams->m_D.size());
178 NS_ASSERT (numCluster <= longTerm.size());
181 bool isSameDirection = (channelParams->m_nodeIds == channelMatrix->m_nodeIds);
207 for (uint8_t cIndex = 0; cIndex < numCluster; cIndex++)
220 double alpha = channelParams->m_alpha [cIndex];
221 double D = channelParams->m_D [cIndex];
224 double tempDoppler = factor * ((sin (zoa [cIndex] * M_PI / 180) * cos (aoa [cIndex] * M_PI / 180) * uSpeed.x
225 + sin (zoa [cIndex] * M_PI / 180) * sin (aoa [cIndex] * M_PI / 180) * uSpeed.y
226 + cos (zoa [cIndex] * M_PI / 180) * uSpeed.z)
227 + (sin (zod [cIndex] * M_PI / 180) * cos (aod [cIndex] * M_PI / 180) * sSpeed.x
228 + sin (zod [cIndex] * M_PI / 180) * sin (aod [cIndex] * M_PI / 180) * sSpeed.y
229 + cos (zod [cIndex] * M_PI / 180) * sSpeed.z) + 2 *
alpha * D);
230 doppler.push_back (std::complex<double> (cos (tempDoppler), sin (tempDoppler)));
233 NS_ASSERT (numCluster <= doppler.size());
243 std::complex<double> subsbandGain (0.0, 0.0);
244 double fsb = (*sbit).fc;
245 for (uint8_t cIndex = 0; cIndex < numCluster; cIndex++)
247 double delay = -2 * M_PI * fsb * (channelParams->m_delay[cIndex]);
248 subsbandGain = subsbandGain + longTerm[cIndex] * doppler[cIndex] * std::complex<double> (cos (delay), sin (delay));
250 *vit = (*vit) * (
norm (subsbandGain));
268 if (!channelMatrix->IsReverse (aPhasedArrayModel->GetId (), bPhasedArrayModel->GetId ()))
270 sW = aPhasedArrayModel->GetBeamformingVector ();
271 uW = bPhasedArrayModel->GetBeamformingVector ();
275 sW = bPhasedArrayModel->GetBeamformingVector ();
276 uW = aPhasedArrayModel->GetBeamformingVector ();
280 bool notFound =
false;
288 NS_LOG_DEBUG (
"found the long term component in the map");
294 update = (
m_longTermMap[longTermId]->m_channel->m_generatedTime != channelMatrix->m_generatedTime
305 if (update || notFound)
313 longTermItem->m_longTerm = longTerm;
314 longTermItem->m_channel = channelMatrix;
315 longTermItem->m_sW = sW;
316 longTermItem->m_uW = uW;
332 uint32_t aId = a->GetObject<
Node> ()->GetId ();
333 uint32_t bId = b->GetObject<
Node> ()->GetId ();
336 NS_ASSERT_MSG (a->GetDistanceFrom (b) > 0.0,
"The position of a and b devices cannot be the same");
341 NS_ASSERT_MSG (aPhasedArrayModel,
"Antenna not found for node " << aId);
342 NS_LOG_DEBUG (
"a node " << a->GetObject<
Node> () <<
" antenna " << aPhasedArrayModel);
345 NS_ASSERT_MSG (bPhasedArrayModel,
"Antenna not found for device " << bId);
346 NS_LOG_DEBUG (
"b node " << bId <<
" antenna " << bPhasedArrayModel);
355 rxPsd =
CalcBeamformingGain (rxPsd, longTerm, channelMatrix, channelParams, a->GetVelocity (), b->GetVelocity ());
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(void)
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 SpectrumValue > txPsd, 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.
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.
~ThreeGppSpectrumPropagationLossModel()
Destructor.
double GetSeconds(void) 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)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
#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.
float alpha
Plot alpha value (transparency)