buildings: Include Low/High building penetration losses
This commit is contained in:
@@ -65,6 +65,7 @@ Changes from ns-3.38 to ns-3-dev
|
||||
|
||||
### Changed behavior
|
||||
|
||||
* (buildings) Calculation of the O2I Low/High Building Penetration Losses based on 3GPP 38.901 7.4.3.1 was missing. These losses are now included in the pathloss calculation when buildings are present.
|
||||
* (network) The function `Buffer::Allocate` will over-provision `ALLOC_OVER_PROVISION` bytes when allocating buffers for packets. `ALLOC_OVER_PROVISION` is currently set to 100 bytes.
|
||||
|
||||
Changes from ns-3.37 to ns-3.38
|
||||
|
||||
@@ -194,6 +194,14 @@ Building-aware channel condition models
|
||||
The class BuildingsChannelConditionModel implements a `channel condition model <propagation.html#channelconditionmodel>`_
|
||||
which determines the LOS/NLOS channel state based on the buildings deployed in
|
||||
the scenario.
|
||||
In addition, based on the wall material of the building, low/high building
|
||||
penetration losses are considered, as defined in 3GPP TS 38.901 7.4.3.1.
|
||||
In particular, for O2I condition, in case of Wood or ConcreteWithWindows material,
|
||||
low losses are considered in the pathloss calculation. In case the material has
|
||||
been set to ConcreteWithoutWindows or StoneBlocks, high losses are considered.
|
||||
Notice that in certain corner cases, such as the I2O2I interference, the model
|
||||
underestimates losses by applying either low or high losses based on the wall material
|
||||
of the involved nodes. For a more accurate estimation the model can be further extended.
|
||||
|
||||
The classes ``ThreeGppV2vUrbanChannelConditionModel`` and
|
||||
``ThreeGppV2vHighwayChannelConditionModel`` implement hybrid channel condition
|
||||
|
||||
@@ -99,6 +99,35 @@ BuildingsChannelConditionModel::GetChannelCondition(Ptr<const MobilityModel> a,
|
||||
{
|
||||
NS_LOG_DEBUG("a and b are indoor in different buildings");
|
||||
cond->SetLosCondition(ChannelCondition::LosConditionValue::NLOS);
|
||||
|
||||
ChannelCondition::O2iLowHighConditionValue lowHighLossConditionA1;
|
||||
ChannelCondition::O2iLowHighConditionValue lowHighLossConditionB1;
|
||||
|
||||
// Low losses considered for Wood or ConcreteWithWindows, while
|
||||
// high losses for ConcreteWithoutWindows and StoneBlocks
|
||||
lowHighLossConditionA1 =
|
||||
a1->GetBuilding()->GetExtWallsType() == Building::ExtWallsType_t::Wood ||
|
||||
a1->GetBuilding()->GetExtWallsType() ==
|
||||
Building::ExtWallsType_t::ConcreteWithWindows
|
||||
? ChannelCondition::O2iLowHighConditionValue::LOW
|
||||
: ChannelCondition::O2iLowHighConditionValue::HIGH;
|
||||
|
||||
lowHighLossConditionB1 =
|
||||
b1->GetBuilding()->GetExtWallsType() == Building::ExtWallsType_t::Wood ||
|
||||
b1->GetBuilding()->GetExtWallsType() ==
|
||||
Building::ExtWallsType_t::ConcreteWithWindows
|
||||
? ChannelCondition::O2iLowHighConditionValue::LOW
|
||||
: ChannelCondition::O2iLowHighConditionValue::HIGH;
|
||||
|
||||
if (lowHighLossConditionA1 == ChannelCondition::O2iLowHighConditionValue::HIGH ||
|
||||
lowHighLossConditionB1 == ChannelCondition::O2iLowHighConditionValue::HIGH)
|
||||
{
|
||||
cond->SetO2iLowHighCondition(ChannelCondition::O2iLowHighConditionValue::HIGH);
|
||||
}
|
||||
else
|
||||
{
|
||||
cond->SetO2iLowHighCondition(ChannelCondition::O2iLowHighConditionValue::LOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
else // outdoor to indoor case
|
||||
@@ -107,6 +136,31 @@ BuildingsChannelConditionModel::GetChannelCondition(Ptr<const MobilityModel> a,
|
||||
|
||||
NS_LOG_DEBUG("a is indoor and b outdoor or vice-versa");
|
||||
cond->SetLosCondition(ChannelCondition::LosConditionValue::NLOS);
|
||||
|
||||
ChannelCondition::O2iLowHighConditionValue lowHighLossCondition;
|
||||
if (isAIndoor)
|
||||
{
|
||||
// Low losses considered for Wood or ConcreteWithWindows, while
|
||||
// high losses for ConcreteWithoutWindows and StoneBlocks
|
||||
lowHighLossCondition =
|
||||
a1->GetBuilding()->GetExtWallsType() == Building::ExtWallsType_t::Wood ||
|
||||
a1->GetBuilding()->GetExtWallsType() ==
|
||||
Building::ExtWallsType_t::ConcreteWithWindows
|
||||
? ChannelCondition::O2iLowHighConditionValue::LOW
|
||||
: ChannelCondition::O2iLowHighConditionValue::HIGH;
|
||||
|
||||
cond->SetO2iLowHighCondition(lowHighLossCondition);
|
||||
}
|
||||
else
|
||||
{
|
||||
lowHighLossCondition =
|
||||
b1->GetBuilding()->GetExtWallsType() == Building::ExtWallsType_t::Wood ||
|
||||
b1->GetBuilding()->GetExtWallsType() ==
|
||||
Building::ExtWallsType_t::ConcreteWithWindows
|
||||
? ChannelCondition::O2iLowHighConditionValue::LOW
|
||||
: ChannelCondition::O2iLowHighConditionValue::HIGH;
|
||||
cond->SetO2iLowHighCondition(lowHighLossCondition);
|
||||
}
|
||||
}
|
||||
|
||||
return cond;
|
||||
|
||||
@@ -144,6 +144,12 @@ ThreeGppPropagationLossModel::GetFrequency() const
|
||||
return m_frequency;
|
||||
}
|
||||
|
||||
bool
|
||||
ThreeGppPropagationLossModel::IsO2iLowPenetrationLoss(Ptr<const ChannelCondition> cond) const
|
||||
{
|
||||
return DoIsO2iLowPenetrationLoss(cond);
|
||||
}
|
||||
|
||||
double
|
||||
ThreeGppPropagationLossModel::DoCalcRxPower(double txPowerDbm,
|
||||
Ptr<MobilityModel> a,
|
||||
@@ -179,17 +185,26 @@ ThreeGppPropagationLossModel::DoCalcRxPower(double txPowerDbm,
|
||||
if (cond->GetO2iCondition() == ChannelCondition::O2iConditionValue::O2I &&
|
||||
m_buildingPenLossesEnabled)
|
||||
{
|
||||
if (cond->GetO2iLowHighCondition() == ChannelCondition::O2iLowHighConditionValue::LOW)
|
||||
if (IsO2iLowPenetrationLoss(cond))
|
||||
{
|
||||
rxPow -= GetO2iLowPenetrationLoss(a, b, cond->GetLosCondition());
|
||||
}
|
||||
else if (cond->GetO2iLowHighCondition() == ChannelCondition::O2iLowHighConditionValue::HIGH)
|
||||
else
|
||||
{
|
||||
rxPow -= GetO2iHighPenetrationLoss(a, b, cond->GetLosCondition());
|
||||
}
|
||||
}
|
||||
else if (cond->GetO2iCondition() == ChannelCondition::O2iConditionValue::I2I &&
|
||||
cond->GetLosCondition() == ChannelCondition::LosConditionValue::NLOS &&
|
||||
m_buildingPenLossesEnabled)
|
||||
{
|
||||
if (IsO2iLowPenetrationLoss(cond))
|
||||
{
|
||||
rxPow -= GetO2iLowPenetrationLoss(a, b, cond->GetLosCondition());
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ABORT_MSG("If we have set the O2I condition, we shouldn't be here");
|
||||
rxPow -= GetO2iHighPenetrationLoss(a, b, cond->GetLosCondition());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,6 +383,23 @@ ThreeGppPropagationLossModel::GetO2iHighPenetrationLoss(
|
||||
return o2iLossValue;
|
||||
}
|
||||
|
||||
bool
|
||||
ThreeGppPropagationLossModel::DoIsO2iLowPenetrationLoss(Ptr<const ChannelCondition> cond) const
|
||||
{
|
||||
if (cond->GetO2iLowHighCondition() == ChannelCondition::O2iLowHighConditionValue::LOW)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (cond->GetO2iLowHighCondition() == ChannelCondition::O2iLowHighConditionValue::HIGH)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ABORT_MSG("If we have set the O2I condition, we shouldn't be here");
|
||||
}
|
||||
}
|
||||
|
||||
double
|
||||
ThreeGppPropagationLossModel::GetLossNlosv(double distance2D,
|
||||
double distance3D,
|
||||
@@ -547,6 +579,15 @@ ThreeGppRmaPropagationLossModel::GetO2iDistance2dIn() const
|
||||
return std::min(m_randomO2iVar1->GetValue(0, 10), m_randomO2iVar2->GetValue(0, 10));
|
||||
}
|
||||
|
||||
bool
|
||||
ThreeGppRmaPropagationLossModel::DoIsO2iLowPenetrationLoss(Ptr<const ChannelCondition> cond
|
||||
[[maybe_unused]]) const
|
||||
{
|
||||
// Based on 3GPP 38.901 7.4.3.1 in RMa only low losses are applied.
|
||||
// Therefore enforce low losses.
|
||||
return true;
|
||||
}
|
||||
|
||||
double
|
||||
ThreeGppRmaPropagationLossModel::GetLossLos(double distance2D,
|
||||
double distance3D,
|
||||
|
||||
@@ -78,6 +78,14 @@ class ThreeGppPropagationLossModel : public PropagationLossModel
|
||||
*/
|
||||
double GetFrequency() const;
|
||||
|
||||
/**
|
||||
* \brief Return true if the O2I Building Penetration loss
|
||||
* corresponds to a low loss condition.
|
||||
* \param cond The ptr to the channel condition model
|
||||
* \return True for low loss, false for high
|
||||
*/
|
||||
bool IsO2iLowPenetrationLoss(Ptr<const ChannelCondition> cond) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Computes the received power by applying the pathloss model described in
|
||||
@@ -173,6 +181,20 @@ class ThreeGppPropagationLossModel : public PropagationLossModel
|
||||
Ptr<MobilityModel> b,
|
||||
ChannelCondition::LosConditionValue cond) const;
|
||||
|
||||
/**
|
||||
* \brief Indicates the condition of the o2i building penetration loss
|
||||
* (defined in 3GPP TR 38.901 7.4.3.1).
|
||||
* The default implementation returns the condition as set
|
||||
* (either based on the buildings materials, or if the probabilistic
|
||||
* model is used in the ThreeGppChannelConditionModel, then
|
||||
* based on the result of a random variable).
|
||||
* The derived classes can change the default behavior by overriding
|
||||
* this method.
|
||||
* \param cond the ptr to the channel condition model
|
||||
* \return True for low losses, false for high losses
|
||||
*/
|
||||
virtual bool DoIsO2iLowPenetrationLoss(Ptr<const ChannelCondition> cond) const;
|
||||
|
||||
/**
|
||||
* \brief Computes the pathloss between a and b considering that the line of
|
||||
* sight is obstructed
|
||||
@@ -374,6 +396,14 @@ class ThreeGppRmaPropagationLossModel : public ThreeGppPropagationLossModel
|
||||
*/
|
||||
double GetO2iDistance2dIn() const override;
|
||||
|
||||
/**
|
||||
* \brief Indicates the condition of the o2i building penetration loss
|
||||
* (defined in 3GPP TR 38.901 7.4.3.1).
|
||||
* \param cond the ptr to the channel condition model
|
||||
* \return True for low losses, false for high losses
|
||||
*/
|
||||
bool DoIsO2iLowPenetrationLoss(Ptr<const ChannelCondition> cond) const override;
|
||||
|
||||
/**
|
||||
* \brief Computes the pathloss between a and b considering that the line of
|
||||
* sight is obstructed
|
||||
|
||||
Reference in New Issue
Block a user