channel-condition-model: Calculate new 02I losses only when channel condition changes
This commit is contained in:
committed by
Tom Henderson
parent
7846b267c6
commit
a9daf34daa
@@ -62,6 +62,10 @@ ThreeGppPropagationLossModel::GetTypeId (void)
|
||||
BooleanValue (false),
|
||||
MakeBooleanAccessor (&ThreeGppPropagationLossModel::m_enforceRanges),
|
||||
MakeBooleanChecker ())
|
||||
.AddAttribute ("BuildingPenetrationLossesEnabled", "Enable/disable Building Penetration Losses.",
|
||||
BooleanValue (true),
|
||||
MakeBooleanAccessor (&ThreeGppPropagationLossModel::m_buildingPenLossesEnabled),
|
||||
MakeBooleanChecker ())
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
@@ -162,6 +166,23 @@ ThreeGppPropagationLossModel::DoCalcRxPower (double txPowerDbm,
|
||||
rxPow -= GetShadowing (a, b, cond->GetLosCondition ());
|
||||
}
|
||||
|
||||
//get o2i losses
|
||||
if (cond->GetO2iCondition () == ChannelCondition::O2iConditionValue::O2I && m_buildingPenLossesEnabled)
|
||||
{
|
||||
if (cond->GetO2iLowHighCondition () == ChannelCondition::O2iLowHighConditionValue::LOW)
|
||||
{
|
||||
rxPow -= GetO2iLowPenetrationLoss (a, b, cond->GetLosCondition ());
|
||||
}
|
||||
else if (cond->GetO2iLowHighCondition () == ChannelCondition::O2iLowHighConditionValue::HIGH)
|
||||
{
|
||||
rxPow -= GetO2iHighPenetrationLoss (a, b, cond->GetLosCondition ());
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ABORT_MSG ("If we have set the O2I condition, we shouldn't be here");
|
||||
}
|
||||
}
|
||||
|
||||
return rxPow;
|
||||
}
|
||||
|
||||
@@ -188,81 +209,145 @@ ThreeGppPropagationLossModel::GetLoss (Ptr<ChannelCondition> cond, double distan
|
||||
NS_FATAL_ERROR ("Unknown channel condition");
|
||||
}
|
||||
|
||||
if (cond->GetO2iCondition () == ChannelCondition::O2iConditionValue::O2I)
|
||||
{
|
||||
if (cond->GetO2iLowHighCondition () == ChannelCondition::O2iLowHighConditionValue::LOW)
|
||||
{
|
||||
loss += GetO2iLowPenetrationLoss ();
|
||||
}
|
||||
else if (cond->GetO2iLowHighCondition () == ChannelCondition::O2iLowHighConditionValue::HIGH)
|
||||
{
|
||||
loss += GetO2iHighPenetrationLoss ();
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ABORT_MSG ("If we have set the O2I condition, we shouldn't be here");
|
||||
}
|
||||
}
|
||||
|
||||
return loss;
|
||||
}
|
||||
|
||||
double
|
||||
ThreeGppPropagationLossModel::GetO2iLowPenetrationLoss () const
|
||||
ThreeGppPropagationLossModel::GetO2iLowPenetrationLoss (Ptr<MobilityModel> a,
|
||||
Ptr<MobilityModel> b,
|
||||
ChannelCondition::LosConditionValue cond) const
|
||||
{
|
||||
double lowLossTw = 0;
|
||||
double lossIn = 0;
|
||||
double lowlossStdDeviation = 0;
|
||||
double lGlass = 0;
|
||||
double lConcrete = 0;
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
// distance2dIn is minimum of two independently generated uniformly distributed
|
||||
// variables between 0 and 25 m for UMa and UMi-Street Canyon, and between 0 and
|
||||
// 10 m for RMa. 2D−in d shall be UT-specifically generated.
|
||||
double distance2dIn = GetO2iDistance2dIn ();
|
||||
double o2iLossValue = 0;
|
||||
double lowLossTw = 0;
|
||||
double lossIn = 0;
|
||||
double lowlossNormalVariate = 0;
|
||||
double lGlass = 0;
|
||||
double lConcrete = 0;
|
||||
|
||||
// calculate material penetration losses, see Table 7.4.3-1
|
||||
lGlass = 2 + 0.2 * m_frequency/1e9; // m_frequency is operation frequency in Hz
|
||||
lConcrete = 5 + 4 * m_frequency/1e9;
|
||||
// compute the channel key
|
||||
uint32_t key = GetKey (a, b);
|
||||
|
||||
lowLossTw = 5 - 10 * log10 (0.3 * std::pow (10, -lGlass/10) + 0.7 * std::pow (10, -lConcrete/10));
|
||||
bool notFound = false; // indicates if the o2iLoss value has not been computed yet
|
||||
bool newCondition = false; // indicates if the channel condition has changed
|
||||
|
||||
// calculate indoor loss
|
||||
lossIn = 0.5 * distance2dIn;
|
||||
auto it = m_o2iLossMap.end (); // the o2iLoss map iterator
|
||||
if (m_o2iLossMap.find (key) != m_o2iLossMap.end ())
|
||||
{
|
||||
// found the o2iLoss value in the map
|
||||
it = m_o2iLossMap.find (key);
|
||||
newCondition = (it->second.m_condition != cond); // true if the condition changed
|
||||
}
|
||||
else
|
||||
{
|
||||
notFound = true;
|
||||
// add a new entry in the map and update the iterator
|
||||
O2iLossMapItem newItem;
|
||||
it = m_o2iLossMap.insert (it, std::make_pair (key, newItem));
|
||||
}
|
||||
|
||||
// calculate low loss standard deviation
|
||||
lowlossStdDeviation = m_normalO2iLowLossVar->GetValue ();
|
||||
if (notFound || newCondition)
|
||||
{
|
||||
// distance2dIn is minimum of two independently generated uniformly distributed
|
||||
// variables between 0 and 25 m for UMa and UMi-Street Canyon, and between 0 and
|
||||
// 10 m for RMa. 2D−in d shall be UT-specifically generated.
|
||||
double distance2dIn = GetO2iDistance2dIn ();
|
||||
|
||||
return lowLossTw + lossIn + lowlossStdDeviation;
|
||||
// calculate material penetration losses, see Table 7.4.3-1
|
||||
lGlass = 2 + 0.2 * m_frequency/1e9; // m_frequency is operation frequency in Hz
|
||||
lConcrete = 5 + 4 * m_frequency/1e9;
|
||||
|
||||
lowLossTw = 5 - 10 * log10 (0.3 * std::pow (10, -lGlass/10) + 0.7 * std::pow (10, -lConcrete/10));
|
||||
|
||||
// calculate indoor loss
|
||||
lossIn = 0.5 * distance2dIn;
|
||||
|
||||
// calculate low loss standard deviation
|
||||
lowlossNormalVariate = m_normalO2iLowLossVar->GetValue ();
|
||||
|
||||
o2iLossValue = lowLossTw + lossIn + lowlossNormalVariate;
|
||||
}
|
||||
else
|
||||
{
|
||||
o2iLossValue = it->second.m_o2iLoss;
|
||||
}
|
||||
|
||||
// update the entry in the map
|
||||
it->second.m_o2iLoss = o2iLossValue;
|
||||
it->second.m_condition = cond;
|
||||
|
||||
return o2iLossValue;
|
||||
}
|
||||
|
||||
double
|
||||
ThreeGppPropagationLossModel::GetO2iHighPenetrationLoss () const
|
||||
ThreeGppPropagationLossModel::GetO2iHighPenetrationLoss (Ptr<MobilityModel> a,
|
||||
Ptr<MobilityModel> b,
|
||||
ChannelCondition::LosConditionValue cond) const
|
||||
{
|
||||
double highLossTw = 0;
|
||||
double lossIn = 0;
|
||||
double highlossStdDeviation = 0;
|
||||
double lIIRGlass = 0;
|
||||
double lConcrete = 0;
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
// distance2dIn is minimum of two independently generated uniformly distributed
|
||||
// variables between 0 and 25 m for UMa and UMi-Street Canyon, and between 0 and
|
||||
// 10 m for RMa. 2D−in d shall be UT-specifically generated.
|
||||
double distance2dIn = GetO2iDistance2dIn ();
|
||||
double o2iLossValue = 0;
|
||||
double highLossTw = 0;
|
||||
double lossIn = 0;
|
||||
double highlossNormalVariate = 0;
|
||||
double lIIRGlass = 0;
|
||||
double lConcrete = 0;
|
||||
|
||||
// calculate material penetration losses, see Table 7.4.3-1
|
||||
lIIRGlass = 23 + 0.3 * m_frequency/1e9;
|
||||
lConcrete = 5 + 4 * m_frequency/1e9;
|
||||
// compute the channel key
|
||||
uint32_t key = GetKey (a, b);
|
||||
|
||||
highLossTw = 5 - 10 * log10 (0.7 * std::pow (10, -lIIRGlass/10) + 0.3 * std::pow (10, -lConcrete/10));
|
||||
bool notFound = false; // indicates if the o2iLoss value has not been computed yet
|
||||
bool newCondition = false; // indicates if the channel condition has changed
|
||||
|
||||
// calculate indoor loss
|
||||
lossIn = 0.5 * distance2dIn;
|
||||
auto it = m_o2iLossMap.end (); // the o2iLoss map iterator
|
||||
if (m_o2iLossMap.find (key) != m_o2iLossMap.end ())
|
||||
{
|
||||
// found the o2iLoss value in the map
|
||||
it = m_o2iLossMap.find (key);
|
||||
newCondition = (it->second.m_condition != cond); // true if the condition changed
|
||||
}
|
||||
else
|
||||
{
|
||||
notFound = true;
|
||||
// add a new entry in the map and update the iterator
|
||||
O2iLossMapItem newItem;
|
||||
it = m_o2iLossMap.insert (it, std::make_pair (key, newItem));
|
||||
}
|
||||
|
||||
// calculate low loss standard deviation
|
||||
highlossStdDeviation = m_normalO2iHighLossVar->GetValue ();
|
||||
if (notFound || newCondition)
|
||||
{
|
||||
// generate a new independent realization
|
||||
|
||||
return highLossTw + lossIn + highlossStdDeviation;
|
||||
// distance2dIn is minimum of two independently generated uniformly distributed
|
||||
// variables between 0 and 25 m for UMa and UMi-Street Canyon, and between 0 and
|
||||
// 10 m for RMa. 2D−in d shall be UT-specifically generated.
|
||||
double distance2dIn = GetO2iDistance2dIn ();
|
||||
|
||||
// calculate material penetration losses, see Table 7.4.3-1
|
||||
lIIRGlass = 23 + 0.3 * m_frequency/1e9;
|
||||
lConcrete = 5 + 4 * m_frequency/1e9;
|
||||
|
||||
highLossTw = 5 - 10 * log10 (0.7 * std::pow (10, -lIIRGlass/10) + 0.3 * std::pow (10, -lConcrete/10));
|
||||
|
||||
// calculate indoor loss
|
||||
lossIn = 0.5 * distance2dIn;
|
||||
|
||||
// calculate low loss standard deviation
|
||||
highlossNormalVariate = m_normalO2iHighLossVar->GetValue ();
|
||||
|
||||
o2iLossValue = highLossTw + lossIn + highlossNormalVariate;
|
||||
}
|
||||
else
|
||||
{
|
||||
o2iLossValue = it->second.m_o2iLoss;
|
||||
}
|
||||
|
||||
// update the entry in the map
|
||||
it->second.m_o2iLoss = o2iLossValue;
|
||||
it->second.m_condition = cond;
|
||||
|
||||
return o2iLossValue;
|
||||
}
|
||||
|
||||
double
|
||||
|
||||
@@ -120,9 +120,31 @@ private:
|
||||
virtual double GetO2iDistance2dIn () const = 0;
|
||||
|
||||
// TODO all child classes should implement this function and this function should be purely virtual
|
||||
virtual double GetO2iLowPenetrationLoss () const;
|
||||
/**
|
||||
* \brief Retrieves the o2i Loss value by looking at m_o2iLossMap.
|
||||
* If not found or if the channel condition changed it generates a new
|
||||
* independent realization and stores it in the map, otherwise it calculates
|
||||
* a new value as defined in 3GPP TR38.901 7.4.3.
|
||||
* \param a tx mobility model (used for the key calculation)
|
||||
* \param b rx mobility model (used for the key calculation)
|
||||
* \param cond the LOS/NLOS channel condition
|
||||
* \return o2iLoss
|
||||
*/
|
||||
virtual double GetO2iLowPenetrationLoss (Ptr<MobilityModel> a, Ptr<MobilityModel> b,
|
||||
ChannelCondition::LosConditionValue cond) const;
|
||||
|
||||
virtual double GetO2iHighPenetrationLoss () const;
|
||||
/**
|
||||
* \brief Retrieves the o2i Loss value by looking at m_o2iLossMap.
|
||||
* If not found or if the channel condition changed it generates a new
|
||||
* independent realization and stores it in the map, otherwise it calculates
|
||||
* a new value as defined in 3GPP TR38.901 7.4.3.
|
||||
* \param a tx mobility model (used for the key calculation)
|
||||
* \param b rx mobility model (used for the key calculation)
|
||||
* \param cond the LOS/NLOS channel condition
|
||||
* \return o2iLoss
|
||||
*/
|
||||
virtual double GetO2iHighPenetrationLoss (Ptr<MobilityModel> a, Ptr<MobilityModel> b,
|
||||
ChannelCondition::LosConditionValue cond) const;
|
||||
|
||||
/**
|
||||
* \brief Computes the pathloss between a and b considering that the line of
|
||||
@@ -226,6 +248,7 @@ protected:
|
||||
double m_frequency; //!< operating frequency in Hz
|
||||
bool m_shadowingEnabled; //!< enable/disable shadowing
|
||||
bool m_enforceRanges; //!< strictly enforce TR 38.901 parameter ranges
|
||||
bool m_buildingPenLossesEnabled; //!< enable/disable building penetration losses
|
||||
Ptr<NormalRandomVariable> m_normRandomVariable; //!< normal random variable
|
||||
|
||||
/** Define a struct for the m_shadowingMap entries */
|
||||
@@ -238,6 +261,16 @@ protected:
|
||||
|
||||
mutable std::unordered_map<uint32_t, ShadowingMapItem> m_shadowingMap; //!< map to store the shadowing values
|
||||
|
||||
/** Define a struct for the m_o2iLossMap entries */
|
||||
struct O2iLossMapItem
|
||||
{
|
||||
double m_o2iLoss; //!< the o2i loss in dB
|
||||
ChannelCondition::LosConditionValue m_condition; //!< the LOS/NLOS condition
|
||||
};
|
||||
|
||||
mutable std::unordered_map<uint32_t, O2iLossMapItem> m_o2iLossMap; //!< map to store the o2i Loss values
|
||||
|
||||
|
||||
Ptr<UniformRandomVariable> m_randomO2iVar1; //!< a uniform random variable for the calculation of the indoor loss, see TR38.901 Table 7.4.3-2
|
||||
Ptr<UniformRandomVariable> m_randomO2iVar2; //!< a uniform random variable for the calculation of the indoor loss, see TR38.901 Table 7.4.3-2
|
||||
Ptr<NormalRandomVariable> m_normalO2iLowLossVar; //!< a normal random variable for the calculation of 02i low loss, see TR38.901 Table 7.4.3-2
|
||||
|
||||
Reference in New Issue
Block a user