diff --git a/src/propagation/model/channel-condition-model.cc b/src/propagation/model/channel-condition-model.cc index 7b4cd0a89..1e2cd43cb 100644 --- a/src/propagation/model/channel-condition-model.cc +++ b/src/propagation/model/channel-condition-model.cc @@ -20,6 +20,7 @@ #include "channel-condition-model.h" #include "ns3/log.h" #include "ns3/double.h" +#include "ns3/boolean.h" #include "ns3/mobility-model.h" #include #include "ns3/node.h" @@ -310,6 +311,12 @@ ThreeGppChannelConditionModel::GetTypeId (void) DoubleValue (1.0), MakeDoubleAccessor (&ThreeGppChannelConditionModel::m_o2iLowLossThreshold), MakeDoubleChecker (0, 1)) + .AddAttribute ("LinkO2iConditionToAntennaHeight", "Specifies whether the O2I condition will " + "be determined based on the UE height, i.e. if the UE height is 1.5 then it is O2O, " + "otherwise it is O2I.", + BooleanValue (false), + MakeBooleanAccessor (&ThreeGppChannelConditionModel::m_linkO2iConditionToAntennaHeight), + MakeBooleanChecker()) ; return tid; } @@ -383,26 +390,38 @@ ThreeGppChannelConditionModel::GetChannelCondition (Ptr a, } ChannelCondition::O2iConditionValue -ThreeGppChannelConditionModel::ComputeO2i (Ptr a, Ptr b) const +ThreeGppChannelConditionModel::ComputeO2i ([[maybe_unused]] Ptr a, + [[maybe_unused]] Ptr b) const { - NS_UNUSED (a); - NS_UNUSED (b); - // TODO this code should be changed to determine based on a and b positions, // whether they are indoor or outdoor the o2i condition // currently we just parametrize it double o2iProb = m_uniformVarO2i->GetValue (0, 1); - // TODO another thing to be done is to allow more states, not only O2i and O2o - if (o2iProb < m_o2iThreshold) //put 0.8 as a parameter + if (m_linkO2iConditionToAntennaHeight) { - NS_LOG_INFO ("Return O2i condition ...."); - return ChannelCondition::O2iConditionValue::O2I; + if (std::min (a->GetPosition().z, b->GetPosition().z) == 1.5) + { + return ChannelCondition::O2iConditionValue::O2O; + } + else + { + return ChannelCondition::O2iConditionValue::O2I; + } } else { - NS_LOG_INFO ("Return O2o condition ...."); - return ChannelCondition::O2iConditionValue::O2O; + // TODO another thing to be done is to allow more states, not only O2i and O2o + if (o2iProb < m_o2iThreshold) + { + NS_LOG_INFO ("Return O2i condition ...."); + return ChannelCondition::O2iConditionValue::O2I; + } + else + { + NS_LOG_INFO ("Return O2o condition ...."); + return ChannelCondition::O2iConditionValue::O2O; + } } } diff --git a/src/propagation/model/channel-condition-model.h b/src/propagation/model/channel-condition-model.h index 885467026..e2a6648a7 100644 --- a/src/propagation/model/channel-condition-model.h +++ b/src/propagation/model/channel-condition-model.h @@ -145,10 +145,10 @@ public: * Set the O2iLowHighConditionValue contaning the information about the O2I * penetration losses (low or high) * - * \param O2iLowHighConditionValue the O2iLowHighConditionValue + * \param o2iLowHighCondition the O2iLowHighConditionValue */ void SetO2iLowHighCondition (O2iLowHighConditionValue o2iLowHighCondition); - + /** * Return true if the channel condition is LOS * @@ -208,8 +208,8 @@ private: LosConditionValue m_losCondition; //!< contains the information about the LOS state of the channel O2iConditionValue m_o2iCondition; //!< contains the information about the O2I state of the channel O2iLowHighConditionValue m_o2iLowHighCondition; //!< contains the information about the O2I low-high penetration losses - - /** + + /** * Prints a LosConditionValue to output * \param os the output stream * \param cond the LosConditionValue @@ -519,6 +519,13 @@ private: virtual double ComputePlos (Ptr a, Ptr b) const = 0; // TODO make this purely abstract function and all child classes should implement this + /** + * Compute the O2I Penetration Loss + * + * \param a tx mobility model + * \param b rx mobility model + * \return the O2I channelcondition + */ virtual ChannelCondition::O2iConditionValue ComputeO2i (Ptr a, Ptr b) const; /** @@ -550,10 +557,9 @@ private: std::unordered_map m_channelConditionMap; //!< map to store the channel conditions Time m_updatePeriod; //!< the update period for the channel condition - // TODO review this description - double m_o2iThreshold {0}; //!< the threshold for determing what is the ration of channels with O2I + double m_o2iThreshold {0}; //!< the threshold for determing what is the ratio of channels with O2I double m_o2iLowLossThreshold {0}; //!< the threshold for determing what is the ratio of low - high O2I penetration losses - // TODO review this description + double m_linkO2iConditionToAntennaHeight {false}; //!< the indicator that determines whether the O2I/O2O condition is determined based on the UE height Ptr m_uniformVarO2i; //!< uniform random variable that is used for the generation of the O2i conditions Ptr m_uniformO2iLowHighLossVar; //!< a uniform random variable for the calculation of the low/high losses, see TR38.901 Table 7.4.3-2 diff --git a/src/propagation/model/three-gpp-propagation-loss-model.cc b/src/propagation/model/three-gpp-propagation-loss-model.cc index f5954a9fa..503717823 100644 --- a/src/propagation/model/three-gpp-propagation-loss-model.cc +++ b/src/propagation/model/three-gpp-propagation-loss-model.cc @@ -254,11 +254,12 @@ ThreeGppPropagationLossModel::GetO2iLowPenetrationLoss (Ptr a, // 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 - lGlass = 2 + 0.2 * m_frequency/1e9; // m_frequency is operation frequency in Hz - lConcrete = 5 + 4 * m_frequency/1e9; + // calculate material penetration losses, see TR38.901 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)); + 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; @@ -324,11 +325,12 @@ ThreeGppPropagationLossModel::GetO2iHighPenetrationLoss (Ptr a, // 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; + // calculate material penetration losses, see TR38.901 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)); + 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; diff --git a/src/propagation/model/three-gpp-propagation-loss-model.h b/src/propagation/model/three-gpp-propagation-loss-model.h index a2b2b72c9..1d6099ac7 100644 --- a/src/propagation/model/three-gpp-propagation-loss-model.h +++ b/src/propagation/model/three-gpp-propagation-loss-model.h @@ -116,7 +116,17 @@ private: */ virtual double GetLossLos (double distance2D, double distance3D, double hUt, double hBs) const = 0; - // TODO doxygen + /** + * \brief Returns the minimum of the two independently generated distances + * according to the uniform distribution between the minimum and the maximum + * value depending on the specific 3GPP scenario (UMa, UMi-Street Canyon, RMa), + * i.e., between 0 and 25 m for UMa and UMi-Street Canyon, and between 0 and 10 m + * for RMa. + * According to 3GPP R38.091 this 2D−in distance shall be UT-specifically + * generated. 2D−in distance is used for the low penetration losses + * calculation according to 3GPP TR38.091 7.4.3. + * \return the distance in m + */ virtual double GetO2iDistance2dIn () const = 0; // TODO all child classes should implement this function and this function should be purely virtual @@ -319,7 +329,17 @@ private: virtual double GetLossLos (double distance2D, double distance3D, double hUt, double hBs) const override; - // TODO doxygen + /** + * \brief Returns the minimum of the two independently generated distances + * according to the uniform distribution between the minimum and the maximum + * value depending on the specific 3GPP scenario (UMa, UMi-Street Canyon, RMa), + * i.e., between 0 and 25 m for UMa and UMi-Street Canyon, and between 0 and 10 m + * for RMa. + * According to 3GPP R38.091 this 2D−in distance shall be UT-specifically + * generated. 2D−in distance is used for the low penetration losses + * calculation according to 3GPP TR38.091 7.4.3. + * \return the distance in m + */ virtual double GetO2iDistance2dIn () const override; /** @@ -416,7 +436,17 @@ private: double GetLossLos (double distance2D, double distance3D, double hUt, double hBs) const override; - // TODO doxygen + /** + * \brief Returns the minimum of the two independently generated distances + * according to the uniform distribution between the minimum and the maximum + * value depending on the specific 3GPP scenario (UMa, UMi-Street Canyon, RMa), + * i.e., between 0 and 25 m for UMa and UMi-Street Canyon, and between 0 and 10 m + * for RMa. + * According to 3GPP R38.091 this 2D−in distance shall be UT-specifically + * generated. 2D−in distance is used for the low penetration losses + * calculation according to 3GPP TR38.091 7.4.3. + * \return the distance in m + */ double GetO2iDistance2dIn () const override; /** @@ -499,7 +529,17 @@ private: */ double GetLossLos (double distance2D, double distance3D, double hUt, double hBs) const override; - // TODO doxygen + /** + * \brief Returns the minimum of the two independently generated distances + * according to the uniform distribution between the minimum and the maximum + * value depending on the specific 3GPP scenario (UMa, UMi-Street Canyon, RMa), + * i.e., between 0 and 25 m for UMa and UMi-Street Canyon, and between 0 and 10 m + * for RMa. + * According to 3GPP R38.091 this 2D−in distance shall be UT-specifically + * generated. 2D−in distance is used for the low penetration losses + * calculation according to 3GPP TR38.091 7.4.3. + * \return the distance in m + */ virtual double GetO2iDistance2dIn () const override; /** @@ -588,7 +628,17 @@ private: */ double GetLossLos (double distance2D, double distance3D, double hUt, double hBs) const override; - // TODO doxygen + /** + * \brief Returns the minimum of the two independently generated distances + * according to the uniform distribution between the minimum and the maximum + * value depending on the specific 3GPP scenario (UMa, UMi-Street Canyon, RMa), + * i.e., between 0 and 25 m for UMa and UMi-Street Canyon, and between 0 and 10 m + * for RMa. + * According to 3GPP R38.091 this 2D−in distance shall be UT-specifically + * generated. 2D−in distance is used for the low penetration losses + * calculation according to 3GPP TR38.091 7.4.3. + * \return the distance in m + */ virtual double GetO2iDistance2dIn () const override; diff --git a/src/propagation/model/three-gpp-v2v-propagation-loss-model.h b/src/propagation/model/three-gpp-v2v-propagation-loss-model.h index b46ee6438..077dfd732 100644 --- a/src/propagation/model/three-gpp-v2v-propagation-loss-model.h +++ b/src/propagation/model/three-gpp-v2v-propagation-loss-model.h @@ -65,7 +65,17 @@ private: */ virtual double GetLossLos (double distance2D, double distance3D, double hUt, double hBs) const override; - // TODO doxygen + /** + * \brief Returns the minimum of the two independently generated distances + * according to the uniform distribution between the minimum and the maximum + * value depending on the specific 3GPP scenario (UMa, UMi-Street Canyon, RMa), + * i.e., between 0 and 25 m for UMa and UMi-Street Canyon, and between 0 and 10 m + * for RMa. + * According to 3GPP R38.091 this 2D−in distance shall be UT-specifically + * generated. 2D−in distance is used for the low penetration losses + * calculation according to 3GPP TR38.091 7.4.3. + * \return the distance in m + */ virtual double GetO2iDistance2dIn () const override;