propagation, spectrum: Add 3GPP 38.811 NTN channel model

This commit is contained in:
pagmatt
2024-05-19 17:53:18 +02:00
committed by Tom Henderson
parent bf97cbf1d3
commit 9a725b5463
15 changed files with 4420 additions and 297 deletions

View File

@@ -40,5 +40,5 @@ build_lib(
test/probabilistic-v2v-channel-condition-model-test.cc
test/propagation-loss-model-test-suite.cc
test/three-gpp-propagation-loss-model-test-suite.cc
test/three-gpp-propagation-loss-model-test-suite.cc
test/three-gpp-ntn-propagation-loss-model-test-suite.cc
)

View File

@@ -42,6 +42,10 @@ The following propagation loss models are implemented:
* ThreeGppUMaPropagationLossModel
* ThreeGppUmiStreetCanyonPropagationLossModel
* ThreeGppIndoorOfficePropagationLossModel
* ThreeGppNTNDenseUrbanPropagationLossModel
* ThreeGppNTNUrbanPropagationLossModel
* ThreeGppNTNSuburbanPropagationLossModel
* ThreeGppNTNRuralPropagationLossModel
Other models could be available thanks to other modules, e.g., the ``building`` module.
@@ -746,6 +750,47 @@ The test cases :cpp:class:`ThreeGppRmaPropagationLossModelTestCase`,
:cpp:class:`ThreeGppIndoorOfficePropagationLossModelTestCase` compute the path loss between two nodes and compares it with the value obtained using the formulas in 3GPP TR 38.901 [38901]_, Table 7.4.1-1.
The test case :cpp:class:`ThreeGppShadowingTestCase` checks if the shadowing is correctly computed by testing the deviation of the overall propagation loss from the path loss. The test is carried out for all the scenarios, both in LOS and NLOS condition.
ThreeGppNTNPropagationLossModel
===============================
Four different classes have been derived from the base class :cpp:class:`ThreeGppPropagationLossModel`
to support Non-Terrestrial Networks, one for each scenario presented in 3GPP TR 38.811 [38811]_, i.e.,
dense urban, urban, suburban and rural.
*Implemented features:*
* Line of Sight and Not Line of Sight (LOS/NLOS) probability models (3GPP TR 38.811, Sec. 6.6.1)
* Path loss, shadowing models and clutter loss (3GPP TR 38.811, Sec. 6.6.2)
* Atmospheric absorption model (3GPP TR 38.811, Sec. 6.6.4)
* Ionospheric and tropospheric scintillation (3GPP TR 38.811, Sec. 6.6.6)
* All the features already implemented in `ThreeGppPropagationLossModel <index.html#threegpppropagationlossmodel>`_
ThreeGppNTNDenseUrbanPropagationLossModel
`````````````````````````````````````````
This class implements the LOS/NLOS path loss and shadow fading models described in 3GPP
TR 38.811 [38811]_, Table 6.6.2-1 for the Dense Urban scenario. It
supports frequencies between 0.5 and 100 GHz.
ThreeGppNTNUrbanPropagationLossModel
````````````````````````````````````
This class implements the LOS/NLOS path loss and shadow fading models described in 3GPP
TR 38.811 [38811]_, Table 6.6.2-2 for the Urban scenario. It
supports frequencies between 0.5 and 100 GHz.
ThreeGppNTNSuburbanPropagationLossModel
```````````````````````````````````````
This class implements the LOS/NLOS path loss and shadow fading models described in 3GPP
TR 38.811 [38811]_, Table 6.6.2-3 for the Suburban scenario. It
supports frequencies between 0.5 and 100 GHz.
ThreeGppNTNRuralPropagationLossModel
````````````````````````````````````
This class implements the LOS/NLOS path loss and shadow fading models described in 3GPP
TR 38.811 [38811]_, Table 6.6.2-3 for the Rural scenario. It
supports frequencies between 0.5 and 100 GHz.
ChannelConditionModel
*********************
@@ -778,30 +823,60 @@ The two approach are coded, respectively, in the classes:
ThreeGppChannelConditionModel
=============================
This is the base class for the 3GPP channel condition models.
It provides the possibility to updated the condition of each channel periodically,
It provides the possibility to update the condition of each channel periodically,
after a given time period which can be configured through the attribute "UpdatePeriod".
If "UpdatePeriod" is set to 0, the channel condition is never updated.
It has five derived classes implementing the channel condition models described in 3GPP TR 38.901 [38901]_ for different propagation scenarios.
ThreeGppRmaChannelConditionModel
````````````````````````````````
This implements the statistical channel condition model described in 3GPP TR 38.901 [38901]_, Table 7.4.2-1, for the RMa scenario.
This class implements the statistical channel condition model described in 3GPP TR 38.901 [38901]_, Table 7.4.2-1, for the RMa scenario.
ThreeGppUmaChannelConditionModel
````````````````````````````````
This implements the statistical channel condition model described in 3GPP TR 38.901 [38901]_, Table 7.4.2-1, for the UMa scenario.
This class implements the statistical channel condition model described in 3GPP TR 38.901 [38901]_, Table 7.4.2-1, for the UMa scenario.
ThreeGppUmiStreetCanyonChannelConditionModel
````````````````````````````````````````````
This implements the statistical channel condition model described in 3GPP TR 38.901 [38901]_, Table 7.4.2-1, for the UMi-Street Canyon scenario.
This class implements the statistical channel condition model described in 3GPP TR 38.901 [38901]_, Table 7.4.2-1, for the UMi-Street Canyon scenario.
ThreeGppIndoorMixedOfficeChannelConditionModel
``````````````````````````````````````````````
This implements the statistical channel condition model described in 3GPP TR 38.901 [38901]_, Table 7.4.2-1, for the Indoor-Mixed office scenario.
This class implements the statistical channel condition model described in 3GPP TR 38.901 [38901]_, Table 7.4.2-1, for the Indoor-Mixed office scenario.
ThreeGppIndoorOpenOfficeChannelConditionModel
`````````````````````````````````````````````
This implements the statistical channel condition model described in 3GPP TR 38.901 [38901]_, Table 7.4.2-1, for the Indoor-Open office scenario.
This class implements the statistical channel condition model described in 3GPP TR 38.901 [38901]_, Table 7.4.2-1, for the Indoor-Open office scenario.
ThreeGppNTNChannelConditionModel
================================
This is the base class for the 3GPP NTN channel condition models.
It provides the possibility to update the condition of each channel periodically,
after a given time period which can be configured through the attribute "UpdatePeriod".
If "UpdatePeriod" is set to 0, the channel condition is never updated.
It has four derived classes implementing the channel condition models described in 3GPP TR 38.811 [38811]_
for the different propagation scenarios. i.e., dense urban, urban, suburban and rural.
ThreeGppDenseUrbanChannelConditionModel
```````````````````````````````````````
This class implements the statistical channel condition model described in 3GPP TR 38.811 [38811]_,
Table 6.6.1-1, for the Dense Urban scenario.
ThreeGppUrbanChannelConditionModel
``````````````````````````````````
This class implements the statistical channel condition model described in 3GPP TR 38.811 [38811]_,
Table 6.6.1-1, for the Urban scenario.
ThreeGppSuburbanStreetCanyonChannelConditionModel
`````````````````````````````````````````````````
This class implements the statistical channel condition model described in 3GPP TR 38.811 [38811]_,
Table 6.6.1-1, for the Suburban scenario.
ThreeGppRuralChannelConditionModel
``````````````````````````````````
This class implements the statistical channel condition model described in 3GPP TR 38.811 [38811]_,
Table 6.6.1-1, for the Rural office scenario.
Testing
=======
@@ -1036,3 +1111,5 @@ References
.. [Boban2016Modeling] M. Boban, X. Gong, and W. Xu, “Modeling the evolution
of line-of-sight blockage for V2V channels,” in IEEE 84th Vehicular Technology
Conference (VTC-Fall), 2016.
.. [38811] 3GPP. 2018. TR 38.811, Study on New Radio (NR) to support non-terrestrial networks, V15.4.0. (2020-09).

View File

@@ -20,14 +20,60 @@
#include "ns3/boolean.h"
#include "ns3/double.h"
#include "ns3/geocentric-constant-position-mobility-model.h"
#include "ns3/log.h"
#include "ns3/mobility-model.h"
#include "ns3/node.h"
#include "ns3/pointer.h"
#include "ns3/simulator.h"
#include "ns3/string.h"
#include <cmath>
namespace
{
/// NTN Dense Urban LOS probabilities from table 6.6.1-1 of 3GPP 38.811
const std::map<int, double> DenseUrbanLOSProb{
{10, {28.2}},
{20, {33.1}},
{30, {39.8}},
{40, {46.8}},
{50, {53.7}},
{60, {61.2}},
{70, {73.8}},
{80, {82.0}},
{90, {98.1}},
};
/// NTN Urban LOS probabilities from table 6.6.1-1 of 3GPP 38.811
const std::map<int, double> UrbanLOSProb{
{10, {24.6}},
{20, {38.6}},
{30, {49.3}},
{40, {61.3}},
{50, {72.6}},
{60, {80.5}},
{70, {91.9}},
{80, {96.8}},
{90, {99.2}},
};
/// NTN Suburban LOS probabilities from table 6.6.1-1 of 3GPP 38.811
const std::map<int, double> SuburbanRuralLOSProb{
{10, {78.2}},
{20, {86.9}},
{30, {91.9}},
{40, {92.9}},
{50, {93.5}},
{60, {94.0}},
{70, {94.9}},
{80, {95.2}},
{90, {99.8}},
};
} // namespace
namespace ns3
{
@@ -537,6 +583,29 @@ ThreeGppChannelConditionModel::GetKey(Ptr<const MobilityModel> a, Ptr<const Mobi
return key;
}
std::tuple<double, double>
ThreeGppChannelConditionModel::GetQuantizedElevationAngle(Ptr<const MobilityModel> a,
Ptr<const MobilityModel> b)
{
Ptr<MobilityModel> aMobNonConst = ConstCast<MobilityModel>(a);
Ptr<MobilityModel> bMobNonConst = ConstCast<MobilityModel>(b);
// check if aMob and bMob are of type GeocentricConstantPositionMobilityModel
auto aNTNMob = DynamicCast<GeocentricConstantPositionMobilityModel>(aMobNonConst);
auto bNTNMob = DynamicCast<GeocentricConstantPositionMobilityModel>(bMobNonConst);
NS_ASSERT_MSG(aNTNMob && bNTNMob,
"Mobility Models need to be of type Geocentric for NTN scenarios");
double elevAngle = aNTNMob->GetElevationAngle(bNTNMob);
// Round the elevation angle into a two-digits integer between 10 and 90, as specified in
// Sec. 6.6.1, 3GPP TR 38.811 v15.4.0
int elevAngleQuantized = (elevAngle < 10) ? 10 : round(elevAngle / 10) * 10;
NS_ASSERT_MSG((elevAngleQuantized >= 10) && (elevAngleQuantized <= 90),
"Invalid elevation angle!");
return std::make_tuple(elevAngle, elevAngleQuantized);
};
// ------------------------------------------------------------------------- //
NS_OBJECT_ENSURE_REGISTERED(ThreeGppRmaChannelConditionModel);
@@ -829,4 +898,100 @@ ThreeGppIndoorOpenOfficeChannelConditionModel::ComputePlos(Ptr<const MobilityMod
return pLos;
}
// ------------------------------------------------------------------------- //
NS_OBJECT_ENSURE_REGISTERED(ThreeGppNTNDenseUrbanChannelConditionModel);
TypeId
ThreeGppNTNDenseUrbanChannelConditionModel::GetTypeId()
{
static TypeId tid = TypeId("ns3::ThreeGppNTNDenseUrbanChannelConditionModel")
.SetParent<ThreeGppChannelConditionModel>()
.SetGroupName("Propagation")
.AddConstructor<ThreeGppNTNDenseUrbanChannelConditionModel>();
return tid;
}
double
ThreeGppNTNDenseUrbanChannelConditionModel::ComputePlos(Ptr<const MobilityModel> a,
Ptr<const MobilityModel> b) const
{
// Compute the LOS probability (see 3GPP TR 38.811, Table 6.6.1-1).
// The elevation angle is first quantized to one of the reference angles.
auto [elevAngle, quantizedElevAngle] = GetQuantizedElevationAngle(a, b);
return DenseUrbanLOSProb.at(quantizedElevAngle);
}
// ------------------------------------------------------------------------- //
NS_OBJECT_ENSURE_REGISTERED(ThreeGppNTNUrbanChannelConditionModel);
TypeId
ThreeGppNTNUrbanChannelConditionModel::GetTypeId()
{
static TypeId tid = TypeId("ns3::ThreeGppNTNUrbanChannelConditionModel")
.SetParent<ThreeGppChannelConditionModel>()
.SetGroupName("Propagation")
.AddConstructor<ThreeGppNTNUrbanChannelConditionModel>();
return tid;
}
double
ThreeGppNTNUrbanChannelConditionModel::ComputePlos(Ptr<const MobilityModel> a,
Ptr<const MobilityModel> b) const
{
// Compute the LOS probability (see 3GPP TR 38.811, Table 6.6.1-1).
// The elevation angle is first quantized to one of the reference angles.
auto [elevAngle, quantizedElevAngle] = GetQuantizedElevationAngle(a, b);
return UrbanLOSProb.at(quantizedElevAngle);
}
// ------------------------------------------------------------------------- //
NS_OBJECT_ENSURE_REGISTERED(ThreeGppNTNSuburbanChannelConditionModel);
TypeId
ThreeGppNTNSuburbanChannelConditionModel::GetTypeId()
{
static TypeId tid = TypeId("ns3::ThreeGppNTNSuburbanChannelConditionModel")
.SetParent<ThreeGppChannelConditionModel>()
.SetGroupName("Propagation")
.AddConstructor<ThreeGppNTNSuburbanChannelConditionModel>();
return tid;
}
double
ThreeGppNTNSuburbanChannelConditionModel::ComputePlos(Ptr<const MobilityModel> a,
Ptr<const MobilityModel> b) const
{
// Compute the LOS probability (see 3GPP TR 38.811, Table 6.6.1-1).
// The elevation angle is first quantized to one of the reference angles.
auto [elevAngle, quantizedElevAngle] = GetQuantizedElevationAngle(a, b);
return SuburbanRuralLOSProb.at(quantizedElevAngle);
}
// ------------------------------------------------------------------------- //
NS_OBJECT_ENSURE_REGISTERED(ThreeGppNTNRuralChannelConditionModel);
TypeId
ThreeGppNTNRuralChannelConditionModel::GetTypeId()
{
static TypeId tid = TypeId("ns3::ThreeGppNTNRuralChannelConditionModel")
.SetParent<ThreeGppChannelConditionModel>()
.SetGroupName("Propagation")
.AddConstructor<ThreeGppNTNRuralChannelConditionModel>();
return tid;
}
double
ThreeGppNTNRuralChannelConditionModel::ComputePlos(Ptr<const MobilityModel> a,
Ptr<const MobilityModel> b) const
{
// Compute the LOS probability (see 3GPP TR 38.811, Table 6.6.1-1).
// The elevation angle is first quantized to one of the reference angles.
auto [elevAngle, quantizedElevAngle] = GetQuantizedElevationAngle(a, b);
return SuburbanRuralLOSProb.at(quantizedElevAngle);
}
} // end namespace ns3

View File

@@ -24,6 +24,7 @@
#include "ns3/random-variable-stream.h"
#include "ns3/vector.h"
#include <map>
#include <unordered_map>
namespace ns3
@@ -483,6 +484,27 @@ class ThreeGppChannelConditionModel : public ChannelConditionModel
*/
int64_t AssignStreams(int64_t stream) override;
/**
* Computes and quantizes the elevation angle to a two-digits integer in [10, 90].
* Asserts that the provided mobility models are of the expected type, i.e.,
* GeocentricConstantPositionMobilityModel, and that the quantized
* angle is in the expected range [10, 90].
*
* \param a mobility model
* \param b mobility model
* \return the tuple [elevation angle, quantized elevation angle] between a and b
*/
static std::tuple<double, double> GetQuantizedElevationAngle(Ptr<const MobilityModel> a,
Ptr<const MobilityModel> b);
/**
* \brief Computes the 2D distance between two 3D vectors
* \param a the first 3D vector
* \param b the second 3D vector
* \return the 2D distance between a and b
*/
static double Calculate2dDistance(const Vector& a, const Vector& b);
protected:
void DoDispose() override;
@@ -497,14 +519,6 @@ class ThreeGppChannelConditionModel : public ChannelConditionModel
INVALID
};
/**
* \brief Computes the 2D distance between two 3D vectors
* \param a the first 3D vector
* \param b the second 3D vector
* \return the 2D distance between a and b
*/
static double Calculate2dDistance(const Vector& a, const Vector& b);
Ptr<UniformRandomVariable> m_uniformVar; //!< uniform random variable
private:
@@ -782,6 +796,154 @@ class ThreeGppIndoorOpenOfficeChannelConditionModel : public ThreeGppChannelCond
double ComputePlos(Ptr<const MobilityModel> a, Ptr<const MobilityModel> b) const override;
};
/**
* \ingroup propagation
*
* \brief Computes the channel condition for the NTN Dense Urban Scenario
*
* Computes the channel condition following the specifications for the
* Indoor Mixed Office scenario reported in Table 6.6.1-1 of 3GPP TR 38.811
*/
class ThreeGppNTNDenseUrbanChannelConditionModel : public ThreeGppChannelConditionModel
{
public:
/**
* Register this type.
* \return The object TypeId.
*/
static TypeId GetTypeId();
/**
* Constructor for the ThreeGppNTNDenseUrbanChannelConditionModel class
*/
ThreeGppNTNDenseUrbanChannelConditionModel() = default;
/**
* Destructor for the ThreeGppNTNDenseUrbanChannelConditionModel class
*/
~ThreeGppNTNDenseUrbanChannelConditionModel() override = default;
private:
/**
* \copydoc ThreeGppChannelConditionModel::ComputePlos
*
* Compute the LOS probability as specified in Table 6.6.1-1 of 3GPP TR 38.811
* for the NTN Dense Urban scenario.
*/
double ComputePlos(Ptr<const MobilityModel> a, Ptr<const MobilityModel> b) const override;
};
/**
* \ingroup propagation
*
* \brief Computes the channel condition for the NTN Urban Scenario
*
* Computes the channel condition following the specifications for the
* Indoor Mixed Office scenario reported in Table 6.6.1-1 of 3GPP TR 38.811
*/
class ThreeGppNTNUrbanChannelConditionModel : public ThreeGppChannelConditionModel
{
public:
/**
* Register this type.
* \return The object TypeId.
*/
static TypeId GetTypeId();
/**
* Constructor for the ThreeGppNTNUrbanChannelConditionModel class
*/
ThreeGppNTNUrbanChannelConditionModel() = default;
/**
* Destructor for the ThreeGppNTNUrbanChannelConditionModel class
*/
~ThreeGppNTNUrbanChannelConditionModel() override = default;
private:
/**
* \copydoc ThreeGppChannelConditionModel::ComputePlos
*
* Compute the LOS probability as specified in Table 6.6.1-1 of 3GPP TR 38.811
* for the NTN Urban scenario.
*/
double ComputePlos(Ptr<const MobilityModel> a, Ptr<const MobilityModel> b) const override;
};
/**
* \ingroup propagation
*
* \brief Computes the channel condition for the NTN Suburban Scenario
*
* Computes the channel condition following the specifications for the
* Indoor Mixed Office scenario reported in Table 6.6.1-1 of 3GPP TR 38.811
*/
class ThreeGppNTNSuburbanChannelConditionModel : public ThreeGppChannelConditionModel
{
public:
/**
* Register this type.
* \return The object TypeId.
*/
static TypeId GetTypeId();
/**
* Constructor for the ThreeGppNTNSuburbanChannelConditionModel class
*/
ThreeGppNTNSuburbanChannelConditionModel() = default;
/**
* Destructor for the ThreeGppNTNSuburbanChannelConditionModel class
*/
~ThreeGppNTNSuburbanChannelConditionModel() override = default;
private:
/**
* \copydoc ThreeGppChannelConditionModel::ComputePlos
*
* Compute the LOS probability as specified in Table 6.6.1-1 of 3GPP TR 38.811
* for the NTN Suburban scenario.
*/
double ComputePlos(Ptr<const MobilityModel> a, Ptr<const MobilityModel> b) const override;
};
/**
* \ingroup propagation
*
* \brief Computes the channel condition for the NTN Rural Scenario
*
* Computes the channel condition following the specifications for the
* Indoor Mixed Office scenario reported in Table 6.6.1-1 of 3GPP TR 38.811
*/
class ThreeGppNTNRuralChannelConditionModel : public ThreeGppChannelConditionModel
{
public:
/**
* Register this type.
* \return The object TypeId.
*/
static TypeId GetTypeId();
/**
* Constructor for the ThreeGppNTNRuralChannelConditionModel class
*/
ThreeGppNTNRuralChannelConditionModel() = default;
/**
* Destructor for the ThreeGppNTNRuralChannelConditionModel class
*/
~ThreeGppNTNRuralChannelConditionModel() override = default;
private:
/**
* \copydoc ThreeGppChannelConditionModel::ComputePlos
*
* Compute the LOS probability as specified in Table 6.6.1-1 of 3GPP TR 38.811
* for the NTN Rural scenario.
*/
double ComputePlos(Ptr<const MobilityModel> a, Ptr<const MobilityModel> b) const override;
};
} // namespace ns3
#endif /* CHANNEL_CONDITION_MODEL_H */

File diff suppressed because it is too large Load Diff

View File

@@ -105,31 +105,29 @@ class ThreeGppPropagationLossModel : public PropagationLossModel
/**
* \brief Computes the pathloss between a and b
* \param cond the channel condition
* \param distance2D the 2D distance between tx and rx in meters
* \param distance3D the 3D distance between tx and rx in meters
* \param hUt the height of the UT in meters
* \param hBs the height of the BS in meters
* \param a tx mobility model
* \param b rx mobility model
* \return pathloss value in dB
*/
double GetLoss(Ptr<ChannelCondition> cond,
double distance2D,
double distance3D,
double hUt,
double hBs) const;
double GetLoss(Ptr<ChannelCondition> cond, Ptr<MobilityModel> a, Ptr<MobilityModel> b) const;
/**
* \brief Computes the pathloss between a and b considering that the line of
* sight is not obstructed
* \param distance2D the 2D distance between tx and rx in meters
* \param distance3D the 3D distance between tx and rx in meters
* \param hUt the height of the UT in meters
* \param hBs the height of the BS in meters
* \param a tx mobility model
* \param b rx mobility model
* \return pathloss value in dB
*/
virtual double GetLossLos(double distance2D,
double distance3D,
double hUt,
double hBs) const = 0;
virtual double GetLossLos(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const = 0;
/**
* \brief Computes the pathloss between a and b considering that the line of
* sight is obstructed
* \param a tx mobility model
* \param b rx mobility model
* \return pathloss value in dB
*/
virtual double GetLossNlos(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const = 0;
/**
* \brief Returns the minimum of the two independently generated distances
@@ -195,41 +193,15 @@ class ThreeGppPropagationLossModel : public PropagationLossModel
*/
virtual bool DoIsO2iLowPenetrationLoss(Ptr<const ChannelCondition> cond) const;
/**
* \brief Computes the pathloss between a and b considering that the line of
* sight is obstructed
* \param distance2D the 2D distance between tx and rx in meters
* \param distance3D the 3D distance between tx and rx in meters
* \param hUt the height of the UT in meters
* \param hBs the height of the BS in meters
* \return pathloss value in dB
*/
virtual double GetLossNlos(double distance2D,
double distance3D,
double hUt,
double hBs) const = 0;
/**
* \brief Computes the pathloss between a and b considering that the line of
* sight is obstructed by a vehicle. By default it raises an error to
* avoid misuse.
* \param distance2D the 2D distance between tx and rx in meters
* \param distance3D the 3D distance between tx and rx in meters
* \param hUt the height of the UT in meters
* \param hBs the height of the BS in meters
* \param a tx mobility model
* \param b rx mobility model
* \return pathloss value in dB
*/
virtual double GetLossNlosv(double distance2D, double distance3D, double hUt, double hBs) const;
/**
* \brief Determines hUT and hBS. The default implementation assumes that
* the tallest node is the BS and the smallest is the UT. The derived classes
* can change the default behavior by overriding this method.
* \param za the height of the first node in meters
* \param zb the height of the second node in meters
* \return std::pair of heights in meters, the first element is hUt and the second is hBs
*/
virtual std::pair<double, double> GetUtAndBsHeights(double za, double zb) const;
virtual double GetLossNlosv(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const;
/**
* \brief Retrieves the shadowing value by looking at m_shadowingMap.
@@ -374,13 +346,11 @@ class ThreeGppRmaPropagationLossModel : public ThreeGppPropagationLossModel
/**
* \brief Computes the pathloss between a and b considering that the line of
* sight is not obstructed
* \param distance2D the 2D distance between tx and rx in meters
* \param distance3D the 3D distance between tx and rx in meters
* \param hUt the height of the UT in meters
* \param hBs the height of the BS in meters
* \param a tx mobility model
* \param b rx mobility model
* \return pathloss value in dB
*/
double GetLossLos(double distance2D, double distance3D, double hUt, double hBs) const override;
double GetLossLos(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const override;
/**
* \brief Returns the minimum of the two independently generated distances
@@ -407,13 +377,11 @@ class ThreeGppRmaPropagationLossModel : public ThreeGppPropagationLossModel
/**
* \brief Computes the pathloss between a and b considering that the line of
* sight is obstructed
* \param distance2D the 2D distance between tx and rx in meters
* \param distance3D the 3D distance between tx and rx in meters
* \param hUt the height of the UT in meters
* \param hBs the height of the BS in meters
* \param a tx mobility model
* \param b rx mobility model
* \return pathloss value in dB
*/
double GetLossNlos(double distance2D, double distance3D, double hUt, double hBs) const override;
double GetLossNlos(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const override;
/**
* \brief Returns the shadow fading standard deviation
@@ -491,13 +459,11 @@ class ThreeGppUmaPropagationLossModel : public ThreeGppPropagationLossModel
/**
* \brief Computes the pathloss between a and b considering that the line of
* sight is not obstructed
* \param distance2D the 2D distance between tx and rx in meters
* \param distance3D the 3D distance between tx and rx in meters
* \param hUt the height of the UT in meters
* \param hBs the height of the BS in meters
* \param a tx mobility model
* \param b rx mobility model
* \return pathloss value in dB
*/
double GetLossLos(double distance2D, double distance3D, double hUt, double hBs) const override;
double GetLossLos(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const override;
/**
* \brief Returns the minimum of the two independently generated distances
@@ -516,13 +482,11 @@ class ThreeGppUmaPropagationLossModel : public ThreeGppPropagationLossModel
/**
* \brief Computes the pathloss between a and b considering that the line of
* sight is obstructed.
* \param distance2D the 2D distance between tx and rx in meters
* \param distance3D the 3D distance between tx and rx in meters
* \param hUt the height of the UT in meters
* \param hBs the height of the BS in meters
* \param a tx mobility model
* \param b rx mobility model
* \return pathloss value in dB
*/
double GetLossNlos(double distance2D, double distance3D, double hUt, double hBs) const override;
double GetLossNlos(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const override;
/**
* \brief Returns the shadow fading standard deviation
@@ -590,13 +554,11 @@ class ThreeGppUmiStreetCanyonPropagationLossModel : public ThreeGppPropagationLo
/**
* \brief Computes the pathloss between a and b considering that the line of
* sight is not obstructed
* \param distance2D the 2D distance between tx and rx in meters
* \param distance3D the 3D distance between tx and rx in meters
* \param hUt the height of the UT in meters
* \param hBs the height of the BS in meters
* \param a tx mobility model
* \param b rx mobility model
* \return pathloss value in dB
*/
double GetLossLos(double distance2D, double distance3D, double hUt, double hBs) const override;
double GetLossLos(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const override;
/**
* \brief Returns the minimum of the two independently generated distances
@@ -615,13 +577,11 @@ class ThreeGppUmiStreetCanyonPropagationLossModel : public ThreeGppPropagationLo
/**
* \brief Computes the pathloss between a and b considering that the line of
* sight is obstructed.
* \param distance2D the 2D distance between tx and rx in meters
* \param distance3D the 3D distance between tx and rx in meters
* \param hUt the height of the UT in meters
* \param hBs the height of the BS in meters
* \param a tx mobility model
* \param b rx mobility model
* \return pathloss value in dB
*/
double GetLossNlos(double distance2D, double distance3D, double hUt, double hBs) const override;
double GetLossNlos(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const override;
/**
* \brief Returns the shadow fading standard deviation
@@ -649,14 +609,6 @@ class ThreeGppUmiStreetCanyonPropagationLossModel : public ThreeGppPropagationLo
* \return the breakpoint distance in meters
*/
double GetBpDistance(double hUt, double hBs, double distance2D) const;
/**
* \brief Determines hUT and hBS. Overrides the default implementation.
* \param za the height of the first node in meters
* \param zb the height of the second node in meters
* \return std::pair, the first element is hUt and the second is hBs
*/
std::pair<double, double> GetUtAndBsHeights(double za, double zb) const override;
};
/**
@@ -694,13 +646,11 @@ class ThreeGppIndoorOfficePropagationLossModel : public ThreeGppPropagationLossM
/**
* \brief Computes the pathloss between a and b considering that the line of
* sight is not obstructed
* \param distance2D the 2D distance between tx and rx in meters
* \param distance3D the 3D distance between tx and rx in meters
* \param hUt the height of the UT in meters
* \param hBs the height of the BS in meters
* \param a tx mobility model
* \param b rx mobility model
* \return pathloss value in dB
*/
double GetLossLos(double distance2D, double distance3D, double hUt, double hBs) const override;
double GetLossLos(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const override;
/**
* \brief Returns the minimum of the two independently generated distances
@@ -719,13 +669,11 @@ class ThreeGppIndoorOfficePropagationLossModel : public ThreeGppPropagationLossM
/**
* \brief Computes the pathloss between a and b considering that the line of
* sight is obstructed
* \param distance2D the 2D distance between tx and rx in meters
* \param distance3D the 3D distance between tx and rx in meters
* \param hUt the height of the UT in meters
* \param hBs the height of the BS in meters
* \param a tx mobility model
* \param b rx mobility model
* \return pathloss value in dB
*/
double GetLossNlos(double distance2D, double distance3D, double hUt, double hBs) const override;
double GetLossNlos(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const override;
/**
* \brief Returns the shadow fading standard deviation
@@ -746,6 +694,260 @@ class ThreeGppIndoorOfficePropagationLossModel : public ThreeGppPropagationLossM
double GetShadowingCorrelationDistance(ChannelCondition::LosConditionValue cond) const override;
};
/**
* \ingroup propagation
*
* \brief Implements the pathloss model defined in 3GPP TR 38.811, Table ????
* for the NTN Dense Urban scenario.
*/
class ThreeGppNTNDenseUrbanPropagationLossModel : public ThreeGppPropagationLossModel
{
public:
/**
* \brief Get the type ID.
* \return the object TypeId
*/
static TypeId GetTypeId();
/**
* Constructor
*/
ThreeGppNTNDenseUrbanPropagationLossModel();
/**
* Destructor
*/
~ThreeGppNTNDenseUrbanPropagationLossModel() override;
/**
* \copydoc ThreeGppPropagationLossModel::GetO2iDistance2dIn
* Does nothing in NTN scenarios.
*/
double GetO2iDistance2dIn() const override;
/**
* \brief Copy constructor
*
* Deleted in base class
*/
ThreeGppNTNDenseUrbanPropagationLossModel(const ThreeGppNTNDenseUrbanPropagationLossModel&) =
delete;
/**
* \brief Copy constructor
*
* Deleted in base class
* \returns the ThreeGppNTNDenseUrbanPropagationLossModel instance
*/
ThreeGppNTNDenseUrbanPropagationLossModel& operator=(
const ThreeGppNTNDenseUrbanPropagationLossModel&) = delete;
private:
// Inherited
double GetLossLos(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const override;
double GetLossNlos(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const override;
double GetShadowingStd(Ptr<MobilityModel> a,
Ptr<MobilityModel> b,
ChannelCondition::LosConditionValue cond) const override;
double GetShadowingCorrelationDistance(ChannelCondition::LosConditionValue cond) const override;
/**
* \brief The nested map containing the Shadow Fading and
* Clutter Loss values for the NTN Dense Urban scenario
*/
const std::map<int, std::vector<float>>* m_SFCL_DenseUrban;
};
/**
* \ingroup propagation
*
* \brief Implements the pathloss model defined in 3GPP TR 38.811, Table ????
* for the NTN Urban scenario.
*/
class ThreeGppNTNUrbanPropagationLossModel : public ThreeGppPropagationLossModel
{
public:
/**
* \brief Get the type ID.
* \return the object TypeId
*/
static TypeId GetTypeId();
/**
* Constructor
*/
ThreeGppNTNUrbanPropagationLossModel();
/**
* Destructor
*/
~ThreeGppNTNUrbanPropagationLossModel() override;
/**
* \copydoc ThreeGppPropagationLossModel::GetO2iDistance2dIn
* Does nothing in NTN scenarios.
*/
double GetO2iDistance2dIn() const override;
/**
* \brief Copy constructor
*
* Deleted in base class
*/
ThreeGppNTNUrbanPropagationLossModel(const ThreeGppNTNUrbanPropagationLossModel&) = delete;
/**
* \brief Copy constructor
*
* Deleted in base class
* \returns the ThreeGppNTNUrbanPropagationLossModel instance
*/
ThreeGppNTNUrbanPropagationLossModel& operator=(const ThreeGppNTNUrbanPropagationLossModel&) =
delete;
private:
// Inherited
double GetLossLos(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const override;
double GetLossNlos(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const override;
double GetShadowingStd(Ptr<MobilityModel> a,
Ptr<MobilityModel> b,
ChannelCondition::LosConditionValue cond) const override;
double GetShadowingCorrelationDistance(ChannelCondition::LosConditionValue cond) const override;
/**
* \brief The nested map containing the Shadow Fading and
* Clutter Loss values for the NTN Urban scenario
*/
const std::map<int, std::vector<float>>* m_SFCL_Urban;
};
/**
* \ingroup propagation
*
* \brief Implements the pathloss model defined in 3GPP TR 38.811, Table ????
* for the NTN Suburban scenario.
*/
class ThreeGppNTNSuburbanPropagationLossModel : public ThreeGppPropagationLossModel
{
public:
/**
* \brief Get the type ID.
* \return the object TypeId
*/
static TypeId GetTypeId();
/**
* Constructor
*/
ThreeGppNTNSuburbanPropagationLossModel();
/**
* Destructor
*/
~ThreeGppNTNSuburbanPropagationLossModel() override;
/**
* \copydoc ThreeGppPropagationLossModel::GetO2iDistance2dIn
* Does nothing in NTN scenarios.
*/
double GetO2iDistance2dIn() const override;
/**
* \brief Copy constructor
*
* Deleted in base class
*/
ThreeGppNTNSuburbanPropagationLossModel(const ThreeGppNTNSuburbanPropagationLossModel&) =
delete;
/**
* \brief Copy constructor
*
* Deleted in base class
* \returns the ThreeGppNTNSuburbanPropagationLossModel instance
*/
ThreeGppNTNSuburbanPropagationLossModel& operator=(
const ThreeGppNTNSuburbanPropagationLossModel&) = delete;
private:
// Inherited
double GetLossLos(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const override;
double GetLossNlos(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const override;
double GetShadowingStd(Ptr<MobilityModel> a,
Ptr<MobilityModel> b,
ChannelCondition::LosConditionValue cond) const override;
double GetShadowingCorrelationDistance(ChannelCondition::LosConditionValue cond) const override;
/**
* \brief The nested map containing the Shadow Fading and
* Clutter Loss values for the NTN Suburban and Rural scenario
*/
const std::map<int, std::vector<float>>* m_SFCL_SuburbanRural;
};
/**
* \ingroup propagation
*
* \brief Implements the pathloss model defined in 3GPP TR 38.811, Table ????
* for the NTN Rural scenario.
*/
class ThreeGppNTNRuralPropagationLossModel : public ThreeGppPropagationLossModel
{
public:
/**
* \brief Get the type ID.
* \return the object TypeId
*/
static TypeId GetTypeId();
/**
* Constructor
*/
ThreeGppNTNRuralPropagationLossModel();
/**
* Destructor
*/
~ThreeGppNTNRuralPropagationLossModel() override;
/**
* \copydoc ThreeGppPropagationLossModel::GetO2iDistance2dIn
* Does nothing in NTN scenarios.
*/
double GetO2iDistance2dIn() const override;
/**
* \brief Copy constructor
*
* Deleted in base class
*/
ThreeGppNTNRuralPropagationLossModel(const ThreeGppNTNRuralPropagationLossModel&) = delete;
/**
* \brief Copy constructor
*
* Deleted in base class
* \returns the ThreeGppNTNRuralPropagationLossModel instance
*/
ThreeGppNTNRuralPropagationLossModel& operator=(const ThreeGppNTNRuralPropagationLossModel&) =
delete;
private:
// Inherited
double GetLossLos(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const override;
double GetLossNlos(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const override;
double GetShadowingStd(Ptr<MobilityModel> a,
Ptr<MobilityModel> b,
ChannelCondition::LosConditionValue cond) const override;
double GetShadowingCorrelationDistance(ChannelCondition::LosConditionValue cond) const override;
/**
* \brief The nested map containing the Shadow Fading and
* Clutter Loss values for the NTN Suburban and Rural scenario
*/
const std::map<int, std::vector<float>>* m_SFCL_SuburbanRural;
};
} // namespace ns3
#endif /* THREE_GPP_PROPAGATION_LOSS_MODEL_H */

View File

@@ -66,13 +66,12 @@ ThreeGppV2vUrbanPropagationLossModel::~ThreeGppV2vUrbanPropagationLossModel()
}
double
ThreeGppV2vUrbanPropagationLossModel::GetLossLos(double /* distance2D */,
double distance3D,
double /* hUt */,
double /* hBs */) const
ThreeGppV2vUrbanPropagationLossModel::GetLossLos(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const
{
NS_LOG_FUNCTION(this);
double distance3D = CalculateDistance(a->GetPosition(), b->GetPosition());
// compute the pathloss (see 3GPP TR 37.885, Table 6.2.1-1)
double loss = 38.77 + 16.7 * log10(distance3D) + 18.2 * log10(m_frequency / 1e9);
@@ -88,26 +87,25 @@ ThreeGppV2vUrbanPropagationLossModel::GetO2iDistance2dIn() const
}
double
ThreeGppV2vUrbanPropagationLossModel::GetLossNlosv(double distance2D,
double distance3D,
double hUt,
double hBs) const
ThreeGppV2vUrbanPropagationLossModel::GetLossNlosv(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const
{
NS_LOG_FUNCTION(this);
// compute the pathloss (see 3GPP TR 37.885, Table 6.2.1-1)
double loss =
GetLossLos(distance2D, distance3D, hUt, hBs) + GetAdditionalNlosvLoss(distance3D, hUt, hBs);
double loss = GetLossLos(a, b) + GetAdditionalNlosvLoss(a, b);
return loss;
}
double
ThreeGppV2vUrbanPropagationLossModel::GetAdditionalNlosvLoss(double distance3D,
double hUt,
double hBs) const
ThreeGppV2vUrbanPropagationLossModel::GetAdditionalNlosvLoss(Ptr<MobilityModel> a,
Ptr<MobilityModel> b) const
{
NS_LOG_FUNCTION(this);
double distance3D = CalculateDistance(a->GetPosition(), b->GetPosition());
double hBs = std::max(a->GetPosition().z, b->GetPosition().z);
double hUt = std::min(a->GetPosition().z, b->GetPosition().z);
// From TR 37.885 v15.2.0
// When a V2V link is in NLOSv, additional vehicle blockage loss is
// added as follows:
@@ -166,13 +164,12 @@ ThreeGppV2vUrbanPropagationLossModel::GetAdditionalNlosvLoss(double distance3D,
}
double
ThreeGppV2vUrbanPropagationLossModel::GetLossNlos(double /* distance2D */,
double distance3D,
double /* hUt */,
double /* hBs */) const
ThreeGppV2vUrbanPropagationLossModel::GetLossNlos(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const
{
NS_LOG_FUNCTION(this);
double distance3D = CalculateDistance(a->GetPosition(), b->GetPosition());
double loss = 36.85 + 30 * log10(distance3D) + 18.9 * log10(m_frequency / 1e9);
return loss;
@@ -266,13 +263,12 @@ ThreeGppV2vHighwayPropagationLossModel::~ThreeGppV2vHighwayPropagationLossModel(
}
double
ThreeGppV2vHighwayPropagationLossModel::GetLossLos(double /* distance2D */,
double distance3D,
double /* hUt */,
double /* hBs */) const
ThreeGppV2vHighwayPropagationLossModel::GetLossLos(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const
{
NS_LOG_FUNCTION(this);
double distance3D = CalculateDistance(a->GetPosition(), b->GetPosition());
// compute the pathloss (see 3GPP TR 37.885, Table 6.2.1-1)
double loss = 32.4 + 20 * log10(distance3D) + 20 * log10(m_frequency / 1e9);

View File

@@ -21,6 +21,9 @@
#include "three-gpp-propagation-loss-model.h"
#include "ns3/deprecated.h"
#include <ns3/mobility-model.h>
namespace ns3
{
@@ -49,7 +52,6 @@ class ThreeGppV2vUrbanPropagationLossModel : public ThreeGppPropagationLossModel
*/
~ThreeGppV2vUrbanPropagationLossModel() override;
// Delete copy constructor and assignment operator to avoid misuse
ThreeGppV2vUrbanPropagationLossModel(const ThreeGppV2vUrbanPropagationLossModel&) = delete;
ThreeGppV2vUrbanPropagationLossModel& operator=(const ThreeGppV2vUrbanPropagationLossModel&) =
delete;
@@ -58,13 +60,11 @@ class ThreeGppV2vUrbanPropagationLossModel : public ThreeGppPropagationLossModel
/**
* \brief Computes the pathloss between a and b considering that the line of
* sight is not obstructed
* \param distance2D the 2D distance between tx and rx in meters
* \param distance3D the 3D distance between tx and rx in meters
* \param hUt the height of the UT in meters
* \param hBs the height of the BS in meters
* \param a mobility model of one of the two communicating nodes
* \param b mobility model of one of the two communicating nodes
* \return pathloss value in dB
*/
double GetLossLos(double distance2D, double distance3D, double hUt, double hBs) const override;
double GetLossLos(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const override;
/**
* \brief Returns the minimum of the two independently generated distances
@@ -86,41 +86,33 @@ class ThreeGppV2vUrbanPropagationLossModel : public ThreeGppPropagationLossModel
/**
* \brief Computes the pathloss between a and b considering that the line of
* sight is obstructed by a vehicle
* \param distance2D the 2D distance between tx and rx in meters
* \param distance3D the 3D distance between tx and rx in meters
* \param hUt the height of the UT in meters
* \param hBs the height of the BS in meters
* \param a mobility model of one of the two communicating nodes
* \param b mobility model of one of the two communicating nodes
* \return pathloss value in dB
*/
double GetLossNlosv(double distance2D,
double distance3D,
double hUt,
double hBs) const override;
double GetLossNlosv(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const override;
/**
* \brief Computes the pathloss between a and b considering that the line of
* sight is obstructed by a building
* \param distance2D the 2D distance between tx and rx in meters
* \param distance3D the 3D distance between tx and rx in meters
* \param hUt the height of the UT in meters
* \param hBs the height of the BS in meters
* \param a mobility model of one of the two communicating nodes
* \param b mobility model of one of the two communicating nodes
* \return pathloss value in dB
*/
double GetLossNlos(double distance2D, double distance3D, double hUt, double hBs) const override;
double GetLossNlos(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const override;
/**
* \brief Computes the additional loss due to an obstruction caused by a vehicle
* \param distance3D the 3D distance between tx and rx in meters
* \param hUt the height of the UT in meters
* \param hBs the height of the BS in meters
* \param a mobility model of one of the two communicating nodes
* \param b mobility model of one of the two communicating nodes
* \return pathloss value in dB
*/
double GetAdditionalNlosvLoss(double distance3D, double hUt, double hBs) const;
double GetAdditionalNlosvLoss(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const;
/**
* \brief Returns the shadow fading standard deviation
* \param a tx mobility model
* \param b rx mobility model
* \param a mobility model of one of the two communicating nodes
* \param b mobility model of one of the two communicating nodes
* \param cond the LOS/NLOS channel condition
* \return shadowing std in dB
*/
@@ -171,13 +163,11 @@ class ThreeGppV2vHighwayPropagationLossModel : public ThreeGppV2vUrbanPropagatio
/**
* \brief Computes the pathloss between a and b considering that the line of
* sight is not obstructed
* \param distance2D the 2D distance between tx and rx in meters
* \param distance3D the 3D distance between tx and rx in meters
* \param hUt the height of the UT in meters
* \param hBs the height of the BS in meters
* \param a mobility model of one of the two communicating nodes
* \param b mobility model of one of the two communicating nodes
* \return pathloss value in dB
*/
double GetLossLos(double distance2D, double distance3D, double hUt, double hBs) const override;
double GetLossLos(Ptr<MobilityModel> a, Ptr<MobilityModel> b) const override;
};
} // namespace ns3

View File

@@ -0,0 +1,241 @@
/*
* Copyright (c) 2023 SIGNET Lab, Department of Information Engineering,
* University of Padova
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ns3/abort.h"
#include "ns3/boolean.h"
#include "ns3/channel-condition-model.h"
#include "ns3/config.h"
#include "ns3/constant-position-mobility-model.h"
#include "ns3/constant-velocity-mobility-model.h"
#include "ns3/double.h"
#include "ns3/geocentric-constant-position-mobility-model.h"
#include "ns3/log.h"
#include "ns3/mobility-helper.h"
#include "ns3/simulator.h"
#include "ns3/test.h"
#include "ns3/three-gpp-propagation-loss-model.h"
#include "ns3/three-gpp-v2v-propagation-loss-model.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE("ThreeGppNTNPropagationLossModelsTest");
/**
* \ingroup propagation-tests
*
* Test case for the ThreeGppNTNPropagationLossModel classes.
* It computes the path loss between two nodes and compares it with the value
* obtained using the results provided in 3GPP TR 38.821.
*/
class ThreeGppNTNPropagationLossModelTestCase : public TestCase
{
public:
ThreeGppNTNPropagationLossModelTestCase();
/**
* Description of a single test point
*/
struct TestPoint
{
/**
* @brief Constructor
*
* @param distance 2D distance between the test nodes
* @param isLos whether to compute the path loss for a channel LOS condition
* @param frequency carrier frequency in Hz
* @param pwrRxDbm expected received power in dBm
* @param lossModel the propagation loss model to test
*/
TestPoint(double distance,
bool isLos,
double frequency,
double pwrRxDbm,
Ptr<ThreeGppPropagationLossModel> lossModel)
: m_distance(distance),
m_isLos(isLos),
m_frequency(frequency),
m_pwrRxDbm(pwrRxDbm),
m_propagationLossModel(lossModel)
{
}
double m_distance; //!< 2D distance between test nodes, in meters
bool m_isLos; //!< if true LOS, if false NLOS
double m_frequency; //!< carrier frequency in Hz
double m_pwrRxDbm; //!< received power in dBm
Ptr<ThreeGppPropagationLossModel> m_propagationLossModel; //!< the path loss model to test
};
private:
/**
* Build the simulation scenario and run the tests
*/
void DoRun() override;
/**
* Test the channel gain for a specific parameter configuration,
* by comparing the antenna gain obtained using CircularApertureAntennaModel::GetGainDb
* and the one of manually computed test instances.
*
* @param testPoint the parameter configuration to be tested
*/
void TestChannelGain(TestPoint testPoint);
};
ThreeGppNTNPropagationLossModelTestCase::ThreeGppNTNPropagationLossModelTestCase()
: TestCase("Creating ThreeGppNTNPropagationLossModelTestCase")
{
}
void
ThreeGppNTNPropagationLossModelTestCase::DoRun()
{
// Create the PLMs and disable shadowing to obtain deterministic results
Ptr<ThreeGppNTNDenseUrbanPropagationLossModel> denseUrbanModel =
CreateObject<ThreeGppNTNDenseUrbanPropagationLossModel>();
denseUrbanModel->SetAttribute("ShadowingEnabled", BooleanValue(false));
Ptr<ThreeGppNTNUrbanPropagationLossModel> urbanModel =
CreateObject<ThreeGppNTNUrbanPropagationLossModel>();
urbanModel->SetAttribute("ShadowingEnabled", BooleanValue(false));
Ptr<ThreeGppNTNSuburbanPropagationLossModel> suburbanModel =
CreateObject<ThreeGppNTNSuburbanPropagationLossModel>();
suburbanModel->SetAttribute("ShadowingEnabled", BooleanValue(false));
Ptr<ThreeGppNTNRuralPropagationLossModel> ruralModel =
CreateObject<ThreeGppNTNRuralPropagationLossModel>();
ruralModel->SetAttribute("ShadowingEnabled", BooleanValue(false));
// Vector of test points
std::vector<TestPoint> testPoints = {
// LOS, test points are identical for all path loss models, since the LOS path loss
// is independent from the specific class.
// Dense-Urban LOS
{35786000, true, 20.0e9, -209.915, denseUrbanModel},
{35786000, true, 30.0e9, -213.437, denseUrbanModel},
{35786000, true, 2.0e9, -191.744, denseUrbanModel},
{600000, true, 20.0e9, -174.404, denseUrbanModel},
{600000, true, 30.0e9, -177.925, denseUrbanModel},
{600000, true, 2.0e9, -156.233, denseUrbanModel},
{1200000, true, 20.0e9, -180.424, denseUrbanModel},
{1200000, true, 30.0e9, -183.946, denseUrbanModel},
{1200000, true, 2.0e9, -162.253, denseUrbanModel},
// Urban LOS
{35786000, true, 20.0e9, -209.915, urbanModel},
{35786000, true, 30.0e9, -213.437, urbanModel},
{35786000, true, 2.0e9, -191.744, urbanModel},
{600000, true, 20.0e9, -174.404, urbanModel},
{600000, true, 30.0e9, -177.925, urbanModel},
{600000, true, 2.0e9, -156.233, urbanModel},
{1200000, true, 20.0e9, -180.424, urbanModel},
{1200000, true, 30.0e9, -183.946, urbanModel},
{1200000, true, 2.0e9, -162.253, urbanModel},
// Suburban LOS
{35786000, true, 20.0e9, -209.915, suburbanModel},
{35786000, true, 30.0e9, -213.437, suburbanModel},
{35786000, true, 2.0e9, -191.744, suburbanModel},
{600000, true, 20.0e9, -174.404, suburbanModel},
{600000, true, 30.0e9, -177.925, suburbanModel},
{600000, true, 2.0e9, -156.233, suburbanModel},
{1200000, true, 20.0e9, -180.424, suburbanModel},
{1200000, true, 30.0e9, -183.946, suburbanModel},
{1200000, true, 2.0e9, -162.253, suburbanModel},
// Rural LOS
{35786000, true, 20.0e9, -209.915, ruralModel},
{35786000, true, 30.0e9, -213.437, ruralModel},
{35786000, true, 2.0e9, -191.744, ruralModel},
{600000, true, 20.0e9, -174.404, ruralModel},
{600000, true, 30.0e9, -177.925, ruralModel},
{600000, true, 2.0e9, -156.233, ruralModel},
{1200000, true, 20.0e9, -180.424, ruralModel},
{1200000, true, 30.0e9, -183.946, ruralModel},
{1200000, true, 2.0e9, -162.253, ruralModel}};
// Call TestChannelGain on each test point
for (auto& point : testPoints)
{
TestChannelGain(point);
}
}
void
ThreeGppNTNPropagationLossModelTestCase::TestChannelGain(TestPoint testPoint)
{
// Create the nodes for BS and UT
NodeContainer nodes;
nodes.Create(2);
// Create the mobility models
Ptr<MobilityModel> a = CreateObject<GeocentricConstantPositionMobilityModel>();
nodes.Get(0)->AggregateObject(a);
Ptr<MobilityModel> b = CreateObject<GeocentricConstantPositionMobilityModel>();
nodes.Get(1)->AggregateObject(b);
// Set fixed position of one of the nodes
Vector posA = Vector(0.0, 0.0, 0.0);
a->SetPosition(posA);
Vector posB = Vector(0.0, 0.0, testPoint.m_distance);
b->SetPosition(posB);
// Declare condition model
Ptr<ChannelConditionModel> conditionModel;
// Set the channel condition using a deterministic channel condition model
if (testPoint.m_isLos)
{
conditionModel = CreateObject<AlwaysLosChannelConditionModel>();
}
else
{
conditionModel = CreateObject<NeverLosChannelConditionModel>();
}
testPoint.m_propagationLossModel->SetChannelConditionModel(conditionModel);
testPoint.m_propagationLossModel->SetAttribute("Frequency", DoubleValue(testPoint.m_frequency));
NS_TEST_EXPECT_MSG_EQ_TOL(testPoint.m_propagationLossModel->CalcRxPower(0.0, a, b),
testPoint.m_pwrRxDbm,
5e-3,
"Obtained unexpected received power");
Simulator::Destroy();
}
/**
* \ingroup propagation-tests
*
* \brief 3GPP NTN Propagation models TestSuite
*
* This TestSuite tests the following models:
* - ThreeGppNTNDenseUrbanPropagationLossModel
* - ThreeGppNTNUrbanPropagationLossModel
* - ThreeGppNTNSuburbanPropagationLossModel
* - ThreeGppNTNRuralPropagationLossModel
*/
class ThreeGppNTNPropagationLossModelsTestSuite : public TestSuite
{
public:
ThreeGppNTNPropagationLossModelsTestSuite();
};
ThreeGppNTNPropagationLossModelsTestSuite::ThreeGppNTNPropagationLossModelsTestSuite()
: TestSuite("three-gpp-ntn-propagation-loss-model", Type::UNIT)
{
AddTestCase(new ThreeGppNTNPropagationLossModelTestCase(), Duration::QUICK);
}
/// Static variable for test initialization
static ThreeGppNTNPropagationLossModelsTestSuite g_propagationLossModelsTestSuite;

View File

@@ -167,10 +167,8 @@ ThreeGppRmaPropagationLossModelTestCase::DoRun()
CreateObject<ThreeGppRmaPropagationLossModel>();
lossModel->SetAttribute("ShadowingEnabled", BooleanValue(false)); // disable the shadow fading
for (std::size_t i = 0; i < m_testVectors.GetN(); i++)
for (const auto& testVector : m_testVectors)
{
TestVector testVector = m_testVectors.Get(i);
Vector posBs = Vector(0.0, 0.0, 35.0);
Vector posUt = Vector(testVector.m_distance, 0.0, 1.5);

View File

@@ -1101,3 +1101,41 @@ References
Mattias Frenne, Farshid Ghasemzadeh, Måns Hagström et al. Advanced Antenna Systems
for 5G Network Deployments: Bridging the Gap Between Theory and Practice.
Academic Press, 2020.
3GPP TR 38.811 Non-Terrestrial Networks
=======================================
3GPP with [3GPPTR38811]_ has extended the channel model presented in [3GPPTR38901]_ to support the so called Non-Terrestrial Networks
(NTN), i.e. communication scenarios where the propagation of the signal travels through the atmosphere.
The channel spectrum estimation procedure is the same as the one described in [3GPPTR38901]_, with a new set of parameters.
Use-cases
#########
The use-cases for this channel model include simulations in 3D/vertical environments with communicating nodes placed
in different types of orbit, in the atmosphere and/or on the ground.
Implementation
##############
The channel spectrum estimation procedure is already implemented (as described in [ns3Zugno]_ ) into the classes
ThreeGppChannelModel and ThreeGppSpectrumPropagationLossModel, that have been extended to support NTN through the
introduction of the appropriate parameters.
3GPP considers two frequencies of interest: S-band (2GHz) and Ka-band (20/30GHz). Many channel parameters are dependent
on the frequency band in use, but no specific range of frequencies of these bands has been given by 3GPP. Hence, this
implementation considers S-band anything below 13GHz, and Ka-band anything above it.
Four propagation scenarios are identified, in decreasing order of building height and density: Dense Urban, Urban,
Suburban and Rural. Channel estimation parameters are scenario-dependent.
**Note**: For satellite, the parameters that describe the departure angle spread are 0. Thus, in the logarithmic scale
at which these parameters are represented is :math:`-\infty`.
References
##########
.. [ns3Zugno] Zugno Tommaso, Michele Polese, Natale Patriciello, Biljana Bojović,
Sandra Lagen, Michele Zorzi. "Implementation of a spatial channel model for ns-3."
In Proceedings of the 2020 Workshop on ns-3, pp. 49-56. 2020.
.. [3GPPTR38901] 3GPP. 2018. TR 38.901. Study on channel for frequencies from 0.5 to
100 GHz. V.15.0.0. (2018-06).
.. [3GPPTR38811] 3GPP. 2018. TR 38.811, Study on New Radio (NR) to support non-terrestrial networks, V15.4.0. (2020-09).

View File

@@ -65,3 +65,12 @@ build_lib_example(
${libmobility}
${libspectrum}
)
build_lib_example(
NAME three-gpp-ntn-channel-example
SOURCE_FILES three-gpp-ntn-channel-example.cc
LIBRARIES_TO_LINK
${libcore}
${libmobility}
${libspectrum}
)

View File

@@ -0,0 +1,503 @@
/*
* Copyright (c) 2023 SIGNET Lab, Department of Information Engineering,
* University of Padova
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**
* \file
* This example is a modified version of "three-gpp-channel-example", to include
* the 3GPP NTN channel model.
* Specifically, most changes (which are also highlighted throughout the code)
* impact the main method, and comprise:
* - the configuration of ad-hoc propagation and channel condition models;
* - the use of GeocentricConstantPositionMobilityModel for the nodes mobility.
* The pre-configured parameters are the one provided by 3GPP in TR 38.821,
* more specifically scenario 10 in down-link mode.
* Two static nodes, one on the ground and one in orbit, communicate with each other.
* The carrier frequency is set at 20GHz with 400MHz bandwidth.
* The result is the SNR of the signal and the path loss, saved in the ntn-snr-trace.txt file.
*/
#include "ns3/channel-condition-model.h"
#include "ns3/constant-position-mobility-model.h"
#include "ns3/core-module.h"
#include "ns3/geocentric-constant-position-mobility-model.h"
#include "ns3/isotropic-antenna-model.h"
#include "ns3/mobility-model.h"
#include "ns3/net-device.h"
#include "ns3/node-container.h"
#include "ns3/node.h"
#include "ns3/parabolic-antenna-model.h"
#include "ns3/simple-net-device.h"
#include "ns3/spectrum-signal-parameters.h"
#include "ns3/three-gpp-channel-model.h"
#include "ns3/three-gpp-propagation-loss-model.h"
#include "ns3/three-gpp-spectrum-propagation-loss-model.h"
#include "ns3/uniform-planar-array.h"
#include <ns3/antenna-model.h>
#include <fstream>
NS_LOG_COMPONENT_DEFINE("NTNChannelExample");
using namespace ns3;
static Ptr<ThreeGppPropagationLossModel>
m_propagationLossModel; //!< the PropagationLossModel object
static Ptr<ThreeGppSpectrumPropagationLossModel>
m_spectrumLossModel; //!< the SpectrumPropagationLossModel object
/**
* @brief Create the PSD for the TX
*
* @param fcHz the carrier frequency in Hz
* @param pwrDbm the transmission power in dBm
* @param bwHz the bandwidth in Hz
* @param rbWidthHz the Resource Block (RB) width in Hz
*
* @return the pointer to the PSD
*/
Ptr<SpectrumValue>
CreateTxPowerSpectralDensity(double fcHz, double pwrDbm, double bwHz, double rbWidthHz)
{
unsigned int numRbs = std::floor(bwHz / rbWidthHz);
double f = fcHz - (numRbs * rbWidthHz / 2.0);
double powerTx = pwrDbm; // dBm power
Bands rbs; // A vector representing each resource block
for (uint32_t numrb = 0; numrb < numRbs; ++numrb)
{
BandInfo rb;
rb.fl = f;
f += rbWidthHz / 2;
rb.fc = f;
f += rbWidthHz / 2;
rb.fh = f;
rbs.push_back(rb);
}
Ptr<SpectrumModel> model = Create<SpectrumModel>(rbs);
Ptr<SpectrumValue> txPsd = Create<SpectrumValue>(model);
double powerTxW = std::pow(10., (powerTx - 30) / 10); // Get Tx power in Watts
double txPowerDensity = (powerTxW / bwHz);
for (auto psd = txPsd->ValuesBegin(); psd != txPsd->ValuesEnd(); ++psd)
{
*psd = txPowerDensity;
}
return txPsd; // [W/Hz]
}
/**
* @brief Create the noise PSD for the
*
* @param fcHz the carrier frequency in Hz
* @param noiseFigureDb the noise figure in dB
* @param bwHz the bandwidth in Hz
* @param rbWidthHz the Resource Block (RB) width in Hz
*
* @return the pointer to the noise PSD
*/
Ptr<SpectrumValue>
CreateNoisePowerSpectralDensity(double fcHz, double noiseFigureDb, double bwHz, double rbWidthHz)
{
unsigned int numRbs = std::floor(bwHz / rbWidthHz);
double f = fcHz - (numRbs * rbWidthHz / 2.0);
Bands rbs; // A vector representing each resource block
std::vector<int> rbsId; // A vector representing the resource block IDs
for (uint32_t numrb = 0; numrb < numRbs; ++numrb)
{
BandInfo rb;
rb.fl = f;
f += rbWidthHz / 2;
rb.fc = f;
f += rbWidthHz / 2;
rb.fh = f;
rbs.push_back(rb);
rbsId.push_back(numrb);
}
Ptr<SpectrumModel> model = Create<SpectrumModel>(rbs);
Ptr<SpectrumValue> txPsd = Create<SpectrumValue>(model);
// see "LTE - From theory to practice"
// Section 22.4.4.2 Thermal Noise and Receiver Noise Figure
const double ktDbmHz = -174.0; // dBm/Hz
double ktWHz = std::pow(10.0, (ktDbmHz - 30) / 10.0); // W/Hz
double noiseFigureLinear = std::pow(10.0, noiseFigureDb / 10.0);
double noisePowerSpectralDensity = ktWHz * noiseFigureLinear;
for (auto rbId : rbsId)
{
(*txPsd)[rbId] = noisePowerSpectralDensity;
}
return txPsd; // W/Hz
}
/**
* \brief A structure that holds the parameters for the
* ComputeSnr function. In this way the problem with the limited
* number of parameters of method Schedule is avoided.
*/
struct ComputeSnrParams
{
Ptr<MobilityModel> txMob; //!< the tx mobility model
Ptr<MobilityModel> rxMob; //!< the rx mobility model
double txPow; //!< the tx power in dBm
double noiseFigure; //!< the noise figure in dB
Ptr<PhasedArrayModel> txAntenna; //!< the tx antenna array
Ptr<PhasedArrayModel> rxAntenna; //!< the rx antenna array
double frequency; //!< the carrier frequency in Hz
double bandwidth; //!< the total bandwidth in Hz
double resourceBlockBandwidth; //!< the Resource Block bandwidth in Hz
/**
* \brief Constructor
* \param pTxMob the tx mobility model
* \param pRxMob the rx mobility model
* \param pTxPow the tx power in dBm
* \param pNoiseFigure the noise figure in dB
* \param pTxAntenna the tx antenna array
* \param pRxAntenna the rx antenna array
* \param pFrequency the carrier frequency in Hz
* \param pBandwidth the total bandwidth in Hz
* \param pResourceBlockBandwidth the Resource Block bandwidth in Hz
*/
ComputeSnrParams(Ptr<MobilityModel> pTxMob,
Ptr<MobilityModel> pRxMob,
double pTxPow,
double pNoiseFigure,
Ptr<PhasedArrayModel> pTxAntenna,
Ptr<PhasedArrayModel> pRxAntenna,
double pFrequency,
double pBandwidth,
double pResourceBlockBandwidth)
{
txMob = pTxMob;
rxMob = pRxMob;
txPow = pTxPow;
noiseFigure = pNoiseFigure;
txAntenna = pTxAntenna;
rxAntenna = pRxAntenna;
frequency = pFrequency;
bandwidth = pBandwidth;
resourceBlockBandwidth = pResourceBlockBandwidth;
}
};
/**
* Perform the beamforming using the DFT beamforming method
* \param thisDevice the device performing the beamforming
* \param thisAntenna the antenna object associated to thisDevice
* \param otherDevice the device towards which point the beam
*/
static void
DoBeamforming(Ptr<NetDevice> thisDevice,
Ptr<PhasedArrayModel> thisAntenna,
Ptr<NetDevice> otherDevice)
{
// retrieve the position of the two devices
Vector aPos = thisDevice->GetNode()->GetObject<MobilityModel>()->GetPosition();
Vector bPos = otherDevice->GetNode()->GetObject<MobilityModel>()->GetPosition();
// compute the azimuth and the elevation angles
Angles completeAngle(bPos, aPos);
double hAngleRadian = completeAngle.GetAzimuth();
double vAngleRadian = completeAngle.GetInclination(); // the elevation angle
// retrieve the number of antenna elements and resize the vector
uint64_t totNoArrayElements = thisAntenna->GetNumElems();
PhasedArrayModel::ComplexVector antennaWeights(totNoArrayElements);
// the total power is divided equally among the antenna elements
double power = 1.0 / sqrt(totNoArrayElements);
// compute the antenna weights
const double sinVAngleRadian = sin(vAngleRadian);
const double cosVAngleRadian = cos(vAngleRadian);
const double sinHAngleRadian = sin(hAngleRadian);
const double cosHAngleRadian = cos(hAngleRadian);
for (uint64_t ind = 0; ind < totNoArrayElements; ind++)
{
Vector loc = thisAntenna->GetElementLocation(ind);
double phase = -2 * M_PI *
(sinVAngleRadian * cosHAngleRadian * loc.x +
sinVAngleRadian * sinHAngleRadian * loc.y + cosVAngleRadian * loc.z);
antennaWeights[ind] = exp(std::complex<double>(0, phase)) * power;
}
// store the antenna weights
thisAntenna->SetBeamformingVector(antennaWeights);
}
/**
* Compute the average SNR
* \param params A structure that holds the parameters that are needed to perform calculations in
* ComputeSnr
*/
static void
ComputeSnr(ComputeSnrParams& params)
{
Ptr<SpectrumValue> txPsd = CreateTxPowerSpectralDensity(params.frequency,
params.txPow,
params.bandwidth,
params.resourceBlockBandwidth);
Ptr<SpectrumValue> rxPsd = txPsd->Copy();
NS_LOG_DEBUG("Average tx power " << 10 * log10(Sum(*txPsd) * params.resourceBlockBandwidth)
<< " dB");
// create the noise PSD
Ptr<SpectrumValue> noisePsd = CreateNoisePowerSpectralDensity(params.frequency,
params.noiseFigure,
params.bandwidth,
params.resourceBlockBandwidth);
NS_LOG_DEBUG("Average noise power "
<< 10 * log10(Sum(*noisePsd) * params.resourceBlockBandwidth) << " dB");
// apply the pathloss
double propagationGainDb = m_propagationLossModel->CalcRxPower(0, params.txMob, params.rxMob);
NS_LOG_DEBUG("Pathloss " << -propagationGainDb << " dB");
double propagationGainLinear = std::pow(10.0, (propagationGainDb) / 10.0);
*(rxPsd) *= propagationGainLinear;
NS_ASSERT_MSG(params.txAntenna, "params.txAntenna is nullptr!");
NS_ASSERT_MSG(params.rxAntenna, "params.rxAntenna is nullptr!");
Ptr<SpectrumSignalParameters> rxSsp = Create<SpectrumSignalParameters>();
rxSsp->psd = rxPsd;
rxSsp->txAntenna =
ConstCast<AntennaModel, const AntennaModel>(params.txAntenna->GetAntennaElement());
// apply the fast fading and the beamforming gain
rxSsp = m_spectrumLossModel->CalcRxPowerSpectralDensity(rxSsp,
params.txMob,
params.rxMob,
params.txAntenna,
params.rxAntenna);
NS_LOG_DEBUG("Average rx power " << 10 * log10(Sum(*rxSsp->psd) * params.bandwidth) << " dB");
// compute the SNR
NS_LOG_DEBUG("Average SNR " << 10 * log10(Sum(*rxSsp->psd) / Sum(*noisePsd)) << " dB");
// print the SNR and pathloss values in the ntn-snr-trace.txt file
std::ofstream f;
f.open("ntn-snr-trace.txt", std::ios::out | std::ios::app);
f << Simulator::Now().GetSeconds() << " " << 10 * log10(Sum(*rxSsp->psd) / Sum(*noisePsd))
<< " " << propagationGainDb << std::endl;
f.close();
}
int
main(int argc, char* argv[])
{
uint32_t simTimeMs = 1000; // simulation time in milliseconds
uint32_t timeResMs = 10; // time resolution in milliseconds
// Start changes with respect to three-gpp-channel-example
// SCENARIO 10 DL of TR 38.321
// This parameters can be set accordingly to 3GPP TR 38.821 or arbitrarily modified
std::string scenario = "NTN-Suburban"; // 3GPP propagation scenario
// All available NTN scenarios: DenseUrban, Urban, Suburban, Rural.
double frequencyHz = 20e9; // operating frequency in Hz
double bandwidthHz = 400e6; // Hz
double RbBandwidthHz = 120e3; // Hz
// Satellite parameters
double satEIRPDensity = 40; // dBW/MHz
double satAntennaGainDb = 58.5; // dB
// UE Parameters
double vsatAntennaGainDb = 39.7; // dB
double vsatAntennaNoiseFigureDb = 1.2; // dB
// End changes with respect to three-gpp-channel-example
/* Command line argument parser setup. */
CommandLine cmd(__FILE__);
cmd.AddValue("scenario",
"The 3GPP NTN scenario to use. Valid options are: "
"NTN-DenseUrban, NTN-Urban, NTN-Suburban, and NTN-Rural",
scenario);
cmd.AddValue("frequencyHz", "The carrier frequency in Hz", frequencyHz);
cmd.AddValue("bandwidthHz", "The bandwidth in Hz", bandwidthHz);
cmd.AddValue("satEIRPDensity", "The satellite EIRP density in dBW/MHz", satEIRPDensity);
cmd.AddValue("satAntennaGainDb", "The satellite antenna gain in dB", satAntennaGainDb);
cmd.AddValue("vsatAntennaGainDb", "The UE VSAT antenna gain in dB", vsatAntennaGainDb);
cmd.AddValue("vsatAntennaNoiseFigureDb",
"The UE VSAT antenna noise figure in dB",
vsatAntennaNoiseFigureDb);
cmd.Parse(argc, argv);
// Calculate transmission power in dBm using EIRPDensity + 10*log10(Bandwidth) - AntennaGain +
// 30
double txPowDbm = (satEIRPDensity + 10 * log10(bandwidthHz / 1e6) - satAntennaGainDb) + 30;
NS_LOG_DEBUG("Transmitting power: " << txPowDbm << "dBm, (" << pow(10., (txPowDbm - 30) / 10)
<< "W)");
Config::SetDefault("ns3::ThreeGppChannelModel::UpdatePeriod",
TimeValue(MilliSeconds(10))); // update the channel at every 10 ms
Config::SetDefault("ns3::ThreeGppChannelConditionModel::UpdatePeriod",
TimeValue(MilliSeconds(0.0))); // do not update the channel condition
RngSeedManager::SetSeed(1);
RngSeedManager::SetRun(1);
// create and configure the factories for the channel condition and propagation loss models
ObjectFactory propagationLossModelFactory;
ObjectFactory channelConditionModelFactory;
// Start changes with respect to three-gpp-channel-example
if (scenario == "NTN-DenseUrban")
{
propagationLossModelFactory.SetTypeId(
ThreeGppNTNDenseUrbanPropagationLossModel::GetTypeId());
channelConditionModelFactory.SetTypeId(
ThreeGppNTNDenseUrbanChannelConditionModel::GetTypeId());
}
else if (scenario == "NTN-Urban")
{
propagationLossModelFactory.SetTypeId(ThreeGppNTNUrbanPropagationLossModel::GetTypeId());
channelConditionModelFactory.SetTypeId(ThreeGppNTNUrbanChannelConditionModel::GetTypeId());
}
else if (scenario == "NTN-Suburban")
{
propagationLossModelFactory.SetTypeId(ThreeGppNTNSuburbanPropagationLossModel::GetTypeId());
channelConditionModelFactory.SetTypeId(
ThreeGppNTNSuburbanChannelConditionModel::GetTypeId());
}
else if (scenario == "NTN-Rural")
{
propagationLossModelFactory.SetTypeId(ThreeGppNTNRuralPropagationLossModel::GetTypeId());
channelConditionModelFactory.SetTypeId(ThreeGppNTNRuralChannelConditionModel::GetTypeId());
}
else
{
NS_FATAL_ERROR("Unknown NTN scenario");
}
// End changes with respect to three-gpp-channel-example
// create the propagation loss model
m_propagationLossModel = propagationLossModelFactory.Create<ThreeGppPropagationLossModel>();
m_propagationLossModel->SetAttribute("Frequency", DoubleValue(frequencyHz));
m_propagationLossModel->SetAttribute("ShadowingEnabled", BooleanValue(true));
// create the spectrum propagation loss model
m_spectrumLossModel = CreateObject<ThreeGppSpectrumPropagationLossModel>();
m_spectrumLossModel->SetChannelModelAttribute("Frequency", DoubleValue(frequencyHz));
m_spectrumLossModel->SetChannelModelAttribute("Scenario", StringValue(scenario));
// create the channel condition model and associate it with the spectrum and
// propagation loss model
Ptr<ChannelConditionModel> condModel =
channelConditionModelFactory.Create<ThreeGppChannelConditionModel>();
m_spectrumLossModel->SetChannelModelAttribute("ChannelConditionModel", PointerValue(condModel));
m_propagationLossModel->SetChannelConditionModel(condModel);
// create the tx and rx nodes
NodeContainer nodes;
nodes.Create(2);
// create the tx and rx devices
Ptr<SimpleNetDevice> txDev = CreateObject<SimpleNetDevice>();
Ptr<SimpleNetDevice> rxDev = CreateObject<SimpleNetDevice>();
// associate the nodes and the devices
nodes.Get(0)->AddDevice(txDev);
txDev->SetNode(nodes.Get(0));
nodes.Get(1)->AddDevice(rxDev);
rxDev->SetNode(nodes.Get(1));
// Start changes with respect to three-gpp-channel-example, here a mobility model
// tailored to NTN scenarios is used (GeocentricConstantPositionMobilityModel)
// create the tx and rx mobility models, set the positions
Ptr<GeocentricConstantPositionMobilityModel> txMob =
CreateObject<GeocentricConstantPositionMobilityModel>();
Ptr<GeocentricConstantPositionMobilityModel> rxMob =
CreateObject<GeocentricConstantPositionMobilityModel>();
txMob->SetGeographicPosition(Vector(45.40869, 11.89448, 35786000)); // GEO over Padova
rxMob->SetGeographicPosition(Vector(45.40869, 11.89448, 14.0)); // Padova Coordinates
// This is not strictly necessary, but is useful to have "sensible" values when using
// GetPosition()
txMob->SetCoordinateTranslationReferencePoint(
Vector(45.40869, 11.89448, 0.0)); // Padova Coordinates without altitude
rxMob->SetCoordinateTranslationReferencePoint(
Vector(45.40869, 11.89448, 0.0)); // Padova Coordinates without altitude
// End changes with respect to three-gpp-channel-example,
NS_LOG_DEBUG("TX Position: " << txMob->GetPosition());
NS_LOG_DEBUG("RX Position: " << rxMob->GetPosition());
// assign the mobility models to the nodes
nodes.Get(0)->AggregateObject(txMob);
nodes.Get(1)->AggregateObject(rxMob);
// Start changes with respect to three-gpp-channel-example,
// Here antenna models mimic the gain achieved by the CircularApertureAntennaModel,
// which is not used to avoid inheriting the latter's dependence on either libstdc++
// or Boost.
Ptr<PhasedArrayModel> txAntenna = CreateObjectWithAttributes<UniformPlanarArray>(
"NumColumns",
UintegerValue(1),
"NumRows",
UintegerValue(1),
"AntennaElement",
PointerValue(
CreateObjectWithAttributes<IsotropicAntennaModel>("Gain",
DoubleValue(satAntennaGainDb))));
Ptr<PhasedArrayModel> rxAntenna = CreateObjectWithAttributes<UniformPlanarArray>(
"NumColumns",
UintegerValue(1),
"NumRows",
UintegerValue(1),
"AntennaElement",
PointerValue(
CreateObjectWithAttributes<IsotropicAntennaModel>("Gain",
DoubleValue(vsatAntennaGainDb))));
// End changes with respect to three-gpp-channel-example
// set the beamforming vectors
DoBeamforming(rxDev, rxAntenna, txDev);
DoBeamforming(txDev, txAntenna, rxDev);
for (int i = 0; i < floor(simTimeMs / timeResMs); i++)
{
Simulator::Schedule(MilliSeconds(timeResMs * i),
&ComputeSnr,
ComputeSnrParams(txMob,
rxMob,
txPowDbm,
vsatAntennaNoiseFigureDb,
txAntenna,
rxAntenna,
frequencyHz,
bandwidthHz,
RbBandwidthHz));
}
Simulator::Run();
Simulator::Destroy();
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -24,6 +24,7 @@
#include "matrix-based-channel-model.h"
#include "ns3/angles.h"
#include "ns3/deprecated.h"
#include <ns3/boolean.h>
#include <ns3/channel-condition-model.h>
@@ -250,11 +251,27 @@ class ThreeGppChannelModel : public MatrixBasedChannelModel
* \param hUT the height of the UT
* \param distance2D the 2D distance between tx and rx
* \return the parameters table
* \deprecated Use GetThreeGppTable(const Ptr<const MobilityModel> aMob, const Ptr<const
* MobilityModel> bMob, Ptr<const ChannelCondition> channelCondition) instead
*/
virtual Ptr<const ParamsTable> GetThreeGppTable(Ptr<const ChannelCondition> channelCondition,
double hBS,
double hUT,
double distance2D) const;
NS_DEPRECATED_3_41("Use GetThreeGppTable(const Ptr<const MobilityModel>, const Ptr<const "
"MobilityModel>, Ptr<const ChannelCondition>) instead")
Ptr<const ParamsTable> GetThreeGppTable(Ptr<const ChannelCondition> channelCondition,
double hBS,
double hUT,
double distance2D) const;
/**
* Get the parameters needed to apply the channel generation procedure
* \param aMob the mobility model of node A
* \param bMob the mobility model of node B
* \param channelCondition the channel condition
* \return the parameters table
*/
virtual Ptr<const ParamsTable> GetThreeGppTable(
const Ptr<const MobilityModel> aMob,
const Ptr<const MobilityModel> bMob,
Ptr<const ChannelCondition> channelCondition) const;
/**
* Prepare 3gpp channel parameters among the nodes a and b.
@@ -383,6 +400,71 @@ class ThreeGppChannelModel : public MatrixBasedChannelModel
2; //!< index of the THETA value in the m_nonSelfBlocking array
static const uint8_t Y_INDEX = 3; //!< index of the Y value in the m_nonSelfBlocking array
static const uint8_t R_INDEX = 4; //!< index of the R value in the m_nonSelfBlocking array
/**
* The nested map containing the 3GPP value tables for the NTN Dense
* Urban LOS scenario.
* The outer key specifies the band (either "S" or "Ka"), while the
* inner key represents the quantized elevation angle.
* The inner vector collects the table3gpp values.
*/
const std::map<std::string, std::map<int, std::vector<float>>>* m_NTNDenseUrbanLOS;
/**
* The nested map containing the 3GPP value tables for the NTN Dense Urban NLOS scenario.
* The outer key specifies the band (either "S" or "Ka"), while the
* inner key represents the quantized elevation angle.
* The inner vector collects the table3gpp values.
*/
const std::map<std::string, std::map<int, std::vector<float>>>* m_NTNDenseUrbanNLOS;
/**
* The nested map containing the 3GPP value tables for the NTN Urban LOS scenario.
* The outer key specifies the band (either "S" or "Ka"), while the
* inner key represents the quantized elevation angle.
* The inner vector collects the table3gpp values.
*/
const std::map<std::string, std::map<int, std::vector<float>>>* m_NTNUrbanLOS;
/**
* The nested map containing the 3GPP value tables for the NTN Urban NLOS scenario.
* The outer key specifies the band (either "S" or "Ka"), while the
* inner key represents the quantized elevation angle.
* The inner vector collects the table3gpp values.
*/
const std::map<std::string, std::map<int, std::vector<float>>>* m_NTNUrbanNLOS;
/**
* The nested map containing the 3GPP value tables for the NTN Suburban LOS scenario.
* The outer key specifies the band (either "S" or "Ka"), while the
* inner key represents the quantized elevation angle.
* The inner vector collects the table3gpp values.
*/
const std::map<std::string, std::map<int, std::vector<float>>>* m_NTNSuburbanLOS;
/**
* The nested map containing the 3GPP value tables for the NTN Suburban NLOS scenario.
* The outer key specifies the band (either "S" or "Ka"), while the
* inner key represents the quantized elevation angle.
* The inner vector collects the table3gpp values.
*/
const std::map<std::string, std::map<int, std::vector<float>>>* m_NTNSuburbanNLOS;
/**
* The nested map containing the 3GPP value tables for the NTN Rural LOS scenario.
* The outer key specifies the band (either "S" or "Ka"), while the
* inner key represents the quantized elevation angle.
* The inner vector collects the table3gpp values.
*/
const std::map<std::string, std::map<int, std::vector<float>>>* m_NTNRuralLOS;
/**
* The nested map containing the 3GPP value tables for the NTN Rural NLOS scenario
* The outer key specifies the band (either "S" or "Ka"), while the
* inner key represents the quantized elevation angle.
* The inner vector collects the table3gpp values.
*/
const std::map<std::string, std::map<int, std::vector<float>>>* m_NTNRuralNLOS;
};
} // namespace ns3