spectrum, propagation: Fix the way channel condition is saved and checked if equal
It seems that is not the best way to save in the structure the pointer to the channel condition model because the underlying condition, and later when we compare the new condition with the old one, we are basically comparing the underlying object with itself, because we saved the pointer to it in the structure. Instead we should save the concrete values of LOS and O2I condition in the 3gpp structure, and then once the ChannelCondition state changes, we can compare these saved values against the new once. This could not be done when the pointer was being changed because pointer was pointing to the same object. This fixes basically the condition in 3gpp whether th channel needs to be updated when condition changes.
This commit is contained in:
committed by
Biljana Bojovic
parent
2f0a4c9957
commit
f53c28229d
@@ -30,6 +30,13 @@ NS_LOG_COMPONENT_DEFINE ("PhasedArrayModel");
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (PhasedArrayModel);
|
||||
|
||||
/**
|
||||
* Prints to the output stream the vector of complex numbers
|
||||
*
|
||||
* \param os output stream
|
||||
* \param cv the vector of complex numbers
|
||||
* \return ostream the output stream
|
||||
*/
|
||||
std::ostream&
|
||||
operator<< (std::ostream& os, const PhasedArrayModel::ComplexVector& cv)
|
||||
{
|
||||
|
||||
@@ -47,7 +47,9 @@ public:
|
||||
virtual ~PhasedArrayModel (void);
|
||||
|
||||
|
||||
// inherited from Object
|
||||
/**
|
||||
* Inherited from Object
|
||||
*/
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
|
||||
@@ -67,7 +69,7 @@ public:
|
||||
/**
|
||||
* Returns the location of the antenna element with the specified
|
||||
* index, normalized with respect to the wavelength.
|
||||
* \param idx index of the antenna element
|
||||
* \param index the index of the antenna element
|
||||
* \return the 3D vector that represents the position of the element
|
||||
*/
|
||||
virtual Vector GetElementLocation (uint64_t index) const = 0;
|
||||
@@ -123,6 +125,12 @@ public:
|
||||
*/
|
||||
Ptr<const AntennaModel> GetAntennaElement (void) const;
|
||||
|
||||
/**
|
||||
* Returns the ID of this antenna array instance
|
||||
* \return the ID value
|
||||
*/
|
||||
uint32_t GetId () const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Utility method to compute the euclidean norm of a ComplexVector
|
||||
@@ -134,6 +142,8 @@ protected:
|
||||
ComplexVector m_beamformingVector; //!< the beamforming vector in use
|
||||
Ptr<AntennaModel> m_antennaElement; //!< the model of the antenna element in use
|
||||
bool m_isBfVectorValid; //!< ensures the validity of the beamforming vector
|
||||
static uint32_t m_idCounter; //!< the ID counter that is used to determine the unique antenna array ID
|
||||
uint32_t m_id {0}; //!< the ID of this antenna array instance
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -117,10 +117,9 @@ ChannelCondition::IsI2i () const
|
||||
}
|
||||
|
||||
bool
|
||||
ChannelCondition::IsEqual (Ptr<const ChannelCondition> otherCondition) const
|
||||
ChannelCondition::IsEqual (LosConditionValue losCondition, O2iConditionValue o2iCondition) const
|
||||
{
|
||||
return (m_o2iCondition == otherCondition->GetO2iCondition ()
|
||||
&& m_losCondition == otherCondition->GetLosCondition ());
|
||||
return (m_losCondition == losCondition && m_o2iCondition == o2iCondition);
|
||||
}
|
||||
|
||||
std::ostream& operator<< (std::ostream& os, ChannelCondition::LosConditionValue cond)
|
||||
|
||||
@@ -100,7 +100,7 @@ public:
|
||||
* Set the LosConditionValue with the information about the LOS/NLOS
|
||||
* state of the channel
|
||||
*
|
||||
* \param the LosConditionValue
|
||||
* \param losCondition the LosConditionValue
|
||||
*/
|
||||
void SetLosCondition (LosConditionValue losCondition);
|
||||
|
||||
@@ -169,10 +169,11 @@ public:
|
||||
/**
|
||||
* Return true if this instance is equivalent to the one passed as argument
|
||||
*
|
||||
* \param otherCondition the other instance to compare with this instance
|
||||
* \return true if this instance is equivalent to the one passed as argument
|
||||
* \param losCondition the LOS condition of the other channel condition instance
|
||||
* \param o2iCondition the 02I condition of the other channel condition instance
|
||||
* \return true if the channel LOS and O2i conditions of the instance are equivalent to those passed as arguments
|
||||
*/
|
||||
bool IsEqual (Ptr<const ChannelCondition> otherCondition) const;
|
||||
bool IsEqual (LosConditionValue losCondition, O2iConditionValue o2iCondition) const;
|
||||
|
||||
private:
|
||||
LosConditionValue m_losCondition; //!< contains the information about the LOS state of the channel
|
||||
|
||||
@@ -55,14 +55,21 @@ public:
|
||||
typedef std::vector<Complex2DVector> Complex3DVector; //!< type definition for complex 3D matrices
|
||||
typedef std::pair<Ptr<const PhasedArrayModel>, Ptr<const PhasedArrayModel>> PhasedAntennaPair; //!< the antenna pair for which is generated the specific instance of the channel
|
||||
|
||||
/**
|
||||
* Data structure that implements the hash function for the key made of the pair of Ptrs
|
||||
*/
|
||||
struct PhasedAntennaPairHashXor
|
||||
{
|
||||
/**
|
||||
* Operator () definition to support the call of the hash function
|
||||
* \param pair the pair of pointers to PhasedArrayModel that will be used to calculate the hash value
|
||||
* \return returns the hash function value of the PhasedAntennaPair
|
||||
*/
|
||||
std::size_t operator() (const PhasedAntennaPair &pair) const
|
||||
{
|
||||
return std::hash<const PhasedArrayModel*>()(PeekPointer (pair.first)) ^ std::hash<const PhasedArrayModel*>()(PeekPointer (pair.second));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Data structure that stores a channel realization
|
||||
*/
|
||||
@@ -132,6 +139,14 @@ public:
|
||||
Ptr<const PhasedArrayModel> aAntenna,
|
||||
Ptr<const PhasedArrayModel> bAntenna) = 0;
|
||||
|
||||
/**
|
||||
* Returns a channel parameters structure used to obtain the channel between
|
||||
* the nodes with mobility objects passed as input parameters.
|
||||
*
|
||||
* \param aMob mobility model of the a device
|
||||
* \param bMob mobility model of the b device
|
||||
* \return the channel matrix
|
||||
*/
|
||||
virtual Ptr<const ChannelParams> GetParams (Ptr<const MobilityModel> aMob,
|
||||
Ptr<const MobilityModel> bMob) const = 0;
|
||||
|
||||
@@ -147,6 +162,11 @@ public:
|
||||
return (uint64_t) std::min (a, b) << 32 | std::max (a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Put in ascending order the provided pair, if already in ascending order it returns it.
|
||||
* \param pair the pair to be sorted in ascending order
|
||||
* \return the pair in ascending order
|
||||
*/
|
||||
static PhasedAntennaPair GetOrderedPhasedAntennaPair (const PhasedAntennaPair &pair)
|
||||
{
|
||||
return (pair.first < pair.second) ? pair : PhasedAntennaPair (pair.second, pair.first);
|
||||
|
||||
@@ -1039,7 +1039,7 @@ ThreeGppChannelModel::ChannelParamsNeedsUpdate (Ptr<const ThreeGppChannelParams>
|
||||
bool update = false;
|
||||
|
||||
// if the channel condition is different the channel has to be updated
|
||||
if (!channelParams->m_channelCondition->IsEqual (channelCondition))
|
||||
if (!channelCondition->IsEqual (channelParams->m_losCondition, channelParams->m_o2iCondition))
|
||||
{
|
||||
NS_LOG_DEBUG ("Update the channel condition");
|
||||
update = true;
|
||||
@@ -1200,12 +1200,13 @@ ThreeGppChannelModel::GenerateChannelParameters (const Ptr<const ChannelConditio
|
||||
// create a channel matrix instance
|
||||
Ptr<ThreeGppChannelParams> channelParams = Create<ThreeGppChannelParams> ();
|
||||
channelParams->m_generatedTime = Simulator::Now ();
|
||||
channelParams->m_channelCondition = channelCondition; // TODO check if this need to be assigned each time, because the pointer does not change
|
||||
channelParams->m_losCondition = channelCondition->GetLosCondition ();
|
||||
channelParams->m_o2iCondition = channelCondition->GetO2iCondition ();
|
||||
|
||||
//Step 4: Generate large scale parameters. All LSPS are uncorrelated.
|
||||
DoubleVector LSPsIndep, LSPs;
|
||||
uint8_t paramNum = 6;
|
||||
if (channelCondition->IsLos ())
|
||||
if (channelParams->m_losCondition == ChannelCondition::LOS)
|
||||
{
|
||||
paramNum = 7;
|
||||
}
|
||||
@@ -1227,7 +1228,7 @@ ThreeGppChannelModel::GenerateChannelParameters (const Ptr<const ChannelConditio
|
||||
|
||||
// NOTE the shadowing is generated in the propagation loss model
|
||||
double DS, ASD, ASA, ZSA, ZSD, kFactor = 0;
|
||||
if (channelCondition->IsLos())
|
||||
if (channelParams->m_losCondition == ChannelCondition::LOS)
|
||||
{
|
||||
kFactor = LSPs[1] * table3gpp->m_sigK + table3gpp->m_uK;
|
||||
DS = pow (10, LSPs[2] * table3gpp->m_sigLgDS + table3gpp->m_uLgDS);
|
||||
@@ -1297,7 +1298,7 @@ ThreeGppChannelModel::GenerateChannelParameters (const Ptr<const ChannelConditio
|
||||
}
|
||||
|
||||
DoubleVector clusterPowerForAngles; // this power is only for equation (7.5-9) and (7.5-14), not for (7.5-22)
|
||||
if (channelCondition->IsLos())
|
||||
if (channelParams->m_losCondition == ChannelCondition::LOS)
|
||||
{
|
||||
double kLinear = pow (10, kFactor / 10);
|
||||
|
||||
@@ -1346,7 +1347,7 @@ ThreeGppChannelModel::GenerateChannelParameters (const Ptr<const ChannelConditio
|
||||
NS_ASSERT (channelParams->m_clusterPower.size () < UINT8_MAX);
|
||||
channelParams->m_reducedClusterNumber = channelParams->m_clusterPower.size ();
|
||||
// Resume step 5 to compute the delay for LoS condition.
|
||||
if (channelCondition->IsLos())
|
||||
if (channelParams->m_losCondition == ChannelCondition::LOS)
|
||||
{
|
||||
double cTau = 0.7705 - 0.0433 * kFactor + 2e-4 * pow (kFactor,2) + 17e-6 * pow (kFactor,3); //(7.5-3)
|
||||
for (uint8_t cIndex = 0; cIndex < channelParams->m_reducedClusterNumber; cIndex++)
|
||||
@@ -1401,7 +1402,7 @@ ThreeGppChannelModel::GenerateChannelParameters (const Ptr<const ChannelConditio
|
||||
|
||||
double cPhi = cNlos;
|
||||
|
||||
if (channelCondition->IsLos())
|
||||
if (channelParams->m_losCondition == ChannelCondition::LOS)
|
||||
{
|
||||
cPhi *= (1.1035 - 0.028 * kFactor - 2e-3 * pow (kFactor, 2) + 1e-4 * pow (kFactor, 3)); //(7.5-10))
|
||||
}
|
||||
@@ -1471,7 +1472,7 @@ ThreeGppChannelModel::GenerateChannelParameters (const Ptr<const ChannelConditio
|
||||
clusterZod[cIndex] = clusterZod[cIndex] * Xn + (m_normalRv->GetValue () * ZSD / 7) + RadiansToDegrees (sAngle.GetInclination ()) + table3gpp->m_offsetZOD; //(7.5-19)
|
||||
}
|
||||
|
||||
if (channelCondition->IsLos())
|
||||
if (channelParams->m_losCondition == ChannelCondition::LOS)
|
||||
{
|
||||
// The 7.5-12 can be rewrite as Theta_n,ZOA = Theta_n,ZOA - (Theta_1,ZOA - Theta_LOS,ZOA) = Theta_n,ZOA - diffZOA,
|
||||
// Similar as AOD, ZSA and ZSD.
|
||||
@@ -1860,7 +1861,7 @@ ThreeGppChannelModel::GetNewChannel (Ptr<const ThreeGppChannelParams> channelPar
|
||||
|
||||
}
|
||||
}
|
||||
if (channelParams->m_channelCondition->IsLos ()) //(7.5-29) && (7.5-30)
|
||||
if (channelParams->m_losCondition == ChannelCondition::LOS) //(7.5-29) && (7.5-30)
|
||||
{
|
||||
std::complex<double> ray (0, 0);
|
||||
double rxPhaseDiff = 2 * M_PI * (sin (uAngle.GetInclination ()) * cos (uAngle.GetAzimuth ()) * uLoc.x
|
||||
@@ -1990,7 +1991,7 @@ ThreeGppChannelModel::CalcAttenuationOfBlockage (const Ptr<ThreeGppChannelModel:
|
||||
}
|
||||
else
|
||||
{
|
||||
if (channelParams->m_channelCondition->IsO2i ()) // outdoor to indoor
|
||||
if (channelParams->m_o2iCondition == ChannelCondition::O2I) // outdoor to indoor
|
||||
{
|
||||
corrDis = 5;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
|
||||
/**
|
||||
* Set the channel condition model
|
||||
* \param model pointer to the ChannelConditionModel object
|
||||
* \param model a pointer to the ChannelConditionModel object
|
||||
*/
|
||||
void SetChannelConditionModel (Ptr<ChannelConditionModel> model);
|
||||
|
||||
@@ -103,7 +103,7 @@ public:
|
||||
std::string GetScenario (void) const;
|
||||
|
||||
/**
|
||||
* Looks for the channel matrix associated to the aMob and bMob pair in m_channelMap.
|
||||
* Looks for the channel matrix associated to the aMob and bMob pair in m_channelMatrixMap.
|
||||
* If found, it checks if it has to be updated. If not found or if it has to
|
||||
* be updated, it generates a new uncorrelated channel matrix using the
|
||||
* method GetNewChannel and updates m_channelMap.
|
||||
@@ -120,6 +120,14 @@ public:
|
||||
Ptr<const PhasedArrayModel> bAntenna) override;
|
||||
|
||||
|
||||
/**
|
||||
* Looks for the channel params associated to the aMob and bMob pair in
|
||||
* m_channelParamsMap. If not found it will return a nullptr.
|
||||
*
|
||||
* \param aMob mobility model of the a device
|
||||
* \param bMob mobility model of the b device
|
||||
* \return the channel params
|
||||
*/
|
||||
Ptr<const ChannelParams> GetParams (Ptr<const MobilityModel> aMob,
|
||||
Ptr<const MobilityModel> bMob) const override;
|
||||
/**
|
||||
@@ -160,7 +168,8 @@ private:
|
||||
*/
|
||||
struct ThreeGppChannelParams : public MatrixBasedChannelModel::ChannelParams
|
||||
{
|
||||
Ptr<const ChannelCondition> m_channelCondition; //!< the channel condition
|
||||
ChannelCondition:: LosConditionValue m_losCondition; //!< contains the information about the LOS state of the channel
|
||||
ChannelCondition::O2iConditionValue m_o2iCondition; //!< contains the information about the O2I state of the channel
|
||||
// TODO these are not currently used, they have to be correctly set when including the spatial consistent update procedure
|
||||
/*The following parameters are stored for spatial consistent updating. The notation is
|
||||
that of 3GPP technical reports, but it can apply also to other channel realizations*/
|
||||
|
||||
@@ -150,8 +150,8 @@ private:
|
||||
* \param aId id of the first node
|
||||
* \param bId id of the second node
|
||||
* \param channelMatrix the channel matrix
|
||||
* \param aW the beamforming vector of the first device
|
||||
* \param bW the beamforming vector of the second device
|
||||
* \param aPhasedArrayModel the antenna array of the first device
|
||||
* \param bPhasedArrayModel the antenna array of the second device
|
||||
* \return vector containing the long term compoenent for each cluster
|
||||
*/
|
||||
PhasedArrayModel::ComplexVector GetLongTerm (uint32_t aId, uint32_t bId,
|
||||
@@ -173,7 +173,8 @@ private:
|
||||
* Computes the beamforming gain and applies it to the tx PSD
|
||||
* \param txPsd the tx PSD
|
||||
* \param longTerm the long term component
|
||||
* \param params The channel matrix
|
||||
* \param channelMatrix The channel matrix structure
|
||||
* \param channelParams The channel params structure
|
||||
* \param sSpeed speed of the first node
|
||||
* \param uSpeed speed of the second node
|
||||
* \return the rx PSD
|
||||
|
||||
Reference in New Issue
Block a user