A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
three-gpp-two-ray-channel-calibration.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022 SIGNET Lab, Department of Information Engineering,
3 * University of Padova
4 *
5 * SPDX-License-Identifier: GPL-2.0-only
6 *
7 */
8
9#include <ns3/command-line.h>
10#include <ns3/core-module.h>
11#include <ns3/double.h>
12#include <ns3/isotropic-antenna-model.h>
13#include <ns3/mobility-helper.h>
14#include <ns3/node-container.h>
15#include <ns3/object-factory.h>
16#include <ns3/pointer.h>
17#include <ns3/string.h>
18#include <ns3/three-gpp-channel-model.h>
19#include <ns3/three-gpp-propagation-loss-model.h>
20#include <ns3/three-gpp-spectrum-propagation-loss-model.h>
21#include <ns3/two-ray-spectrum-propagation-loss-model.h>
22#include <ns3/uinteger.h>
23#include <ns3/uniform-planar-array.h>
24
25NS_LOG_COMPONENT_DEFINE("ThreeGppTwoRayChannelCalibration");
26
27using namespace ns3;
28
29// Calibration results actually show a weak dependence with respect to the carrier frequency
30constexpr double FC_STEP = 5e9;
31
32// 500 MHz, as to provide a fit for the whole frequency range supported by the TR 38.901 model
33constexpr double MIN_FC = 500e6;
34
35// 100 GHz, as to provide a fit for the whole frequency range supported by the TR 38.901 model
36constexpr double MAX_FC = 100e9;
37
38// Results are independent from this
39constexpr double BW = 200e6;
40
41// Results are independent from this, it dictate sonly the resolution of the PSD.
42// This value corresponds to numerology index 2 of the 5G NR specifications
43constexpr double RB_WIDTH = 60e3;
44
45const std::vector<std::string> LOS_CONDITIONS{
46 "LOS",
47 "NLOS",
48};
49
50const std::vector<std::string> THREE_GPP_SCENARIOS{
51 "RMa",
52 "UMa",
53 "UMi-StreetCanyon",
54 "InH-OfficeOpen",
55 "InH-OfficeMixed",
56};
57
59 Create<OutputStreamWrapper>("two-ray-to-three-gpp-calibration.csv", std::ios::out);
60
61void
62LogEndToEndGain(std::string cond, std::string scen, double fc, long int seed, double gain)
63{
64 *g_outStream->GetStream() << cond << "\t" << scen << "\t" << fc << "\t" << seed << "\t" << gain
65 << "\n";
66}
67
68double
73
76{
77 uint32_t numRbs = std::floor(BW / RB_WIDTH);
78 double f = fc - (numRbs * RB_WIDTH / 2.0);
79 double powerTx = 0.0;
80
81 Bands rbs; // A vector representing each resource block
82 std::vector<int> rbsId; // A vector representing the resource block IDs
83 rbsId.reserve(numRbs);
84
85 for (uint32_t numrb = 0; numrb < numRbs; ++numrb)
86 {
87 BandInfo rb;
88 rb.fl = f;
89 f += RB_WIDTH / 2;
90 rb.fc = f;
91 f += RB_WIDTH / 2;
92 rb.fh = f;
93
94 rbs.push_back(rb);
95 rbsId.push_back(numrb);
96 }
99
100 double powerTxW = std::pow(10., (powerTx - 30) / 10);
101 double txPowerDensity = powerTxW / BW;
102
103 for (auto rbId : rbsId)
104 {
105 (*txPsd)[rbId] = txPowerDensity;
106 }
107
108 return txPsd;
109}
110
111double
112ComputeEndToEndGain(std::string cond,
113 std::string scen,
114 double fc,
115 Ptr<Node> a,
116 Ptr<Node> b,
119{
120 // Fix the LOS condition
121 Ptr<ChannelConditionModel> channelConditionModel;
122 if (cond == "LOS")
123 {
124 channelConditionModel = CreateObject<AlwaysLosChannelConditionModel>();
125 }
126 else if (cond == "NLOS")
127 {
128 channelConditionModel = CreateObject<NeverLosChannelConditionModel>();
129 }
130 else
131 {
132 NS_ABORT_MSG("Unsupported channel condition");
133 }
134
135 // Create the needed objects. These must be created anew each loop, otherwise the channel is
136 // stored and never re-computed.
137 Ptr<ThreeGppSpectrumPropagationLossModel> threeGppSpectrumLossModel =
140
141 // Pass the needed pointers between the various spectrum instances
142 threeGppSpectrumLossModel->SetAttribute("ChannelModel", PointerValue(threeGppChannelModel));
143 threeGppChannelModel->SetAttribute("ChannelConditionModel",
144 PointerValue(channelConditionModel));
145
146 // Create the TX PSD
148 double txPower = ComputePowerSpectralDensityOverallPower(txPsd);
149
150 // Create TX signal parameters
152 signalParams->psd = txPsd;
153
154 // Set the carrier frequency
155 threeGppChannelModel->SetAttribute("Frequency", DoubleValue(fc));
156
157 // Set the scenario
158 threeGppChannelModel->SetAttribute("Scenario", StringValue(scen));
159
160 // Disable all possible sources of variance apart from the multipath fading
161 threeGppChannelModel->SetAttribute("Blockage", BooleanValue(false));
162
163 // Retrieve the mobility models and the position of the TX and RX nodes
164 Ptr<MobilityModel> aMob = a->GetObject<MobilityModel>();
165 Ptr<MobilityModel> bMob = b->GetObject<MobilityModel>();
166 Vector aPos = aMob->GetPosition();
167 Vector bPos = bMob->GetPosition();
168
169 // Compute the relative azimuth and the elevation angles
170 Angles angleBtoA(bPos, aPos);
171 Angles angleAtoB(aPos, bPos);
172
173 // Create the BF vectors
174 aArray->SetBeamformingVector(aArray->GetBeamformingVector(angleBtoA));
175 bArray->SetBeamformingVector(bArray->GetBeamformingVector(angleAtoB));
176
177 // Compute the received power due to multipath fading
178 auto rxParams = threeGppSpectrumLossModel->DoCalcRxPowerSpectralDensity(signalParams,
179 aMob,
180 bMob,
181 aArray,
182 bArray);
183 double rxPower = ComputePowerSpectralDensityOverallPower(rxParams->psd);
184
185 return rxPower / txPower;
186}
187
188int
189main(int argc, char* argv[])
190{
191 uint32_t numRealizations = 5000; // The number of different channel realizations
192 bool enableOutput = false; // Whether to log the results of the example
193
194 CommandLine cmd(__FILE__);
195 cmd.AddValue("enableOutput", "Logs the results of the example", enableOutput);
196 cmd.AddValue("numRealizations", "The number of different realizations", numRealizations);
197 cmd.Parse(argc, argv);
198
199 // Log trace structure
200 if (enableOutput)
201 {
202 *g_outStream->GetStream() << "cond\tscen\tfc\tseed\tgain\n";
203 }
204
205 // Aggregate them to the corresponding nodes
207 nodes.Create(2);
208
209 // Create the mobility models for the TX and RX nodes
212 Vector aPos(0.0, 0.0, 0.0);
213 Vector bPos(10.0, 0.0, 0.0);
214 positionAlloc->Add(aPos);
215 positionAlloc->Add(bPos);
216 mobility.SetPositionAllocator(positionAlloc);
217 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
218 mobility.Install(nodes);
219
220 // Create the TX and RX phased arrays
221 Ptr<PhasedArrayModel> aPhasedArray =
223 UintegerValue(1),
224 "NumRows",
225 UintegerValue(1));
226 aPhasedArray->SetAntennaElement(PointerValue(CreateObject<IsotropicAntennaModel>()));
227 Ptr<PhasedArrayModel> bPhasedArray =
229 UintegerValue(1),
230 "NumRows",
231 UintegerValue(1));
232 bPhasedArray->SetAntennaElement(PointerValue(CreateObject<IsotropicAntennaModel>()));
233
234 // Loop over predetermined set of scenarios, LOS conditions and frequencies
235 for (const auto& cond : LOS_CONDITIONS)
236 {
237 for (const auto& scen : THREE_GPP_SCENARIOS)
238 {
239 for (double fc = MIN_FC; fc < MAX_FC; fc += FC_STEP)
240 {
241 for (uint32_t runIdx = 0; runIdx < numRealizations; runIdx++)
242 {
243 double gain = ComputeEndToEndGain(cond,
244 scen,
245 fc,
246 nodes.Get(0),
247 nodes.Get(1),
248 aPhasedArray,
249 bPhasedArray);
250 if (enableOutput)
251 {
252 LogEndToEndGain(cond, scen, fc, runIdx, gain);
253 }
254 }
255 }
256 }
257 }
258}
Class holding the azimuth and inclination angles of spherical coordinates.
Definition angles.h:107
Parse command-line arguments.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
Helper class used to assign positions and mobility models to nodes.
Keep track of the current position and velocity of an object.
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
AttributeValue implementation for Pointer.
Smart pointer class similar to boost::intrusive_ptr.
Hold variables of type string.
Definition string.h:45
Hold an unsigned integer type.
Definition uinteger.h:34
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Ptr< T > CreateObjectWithAttributes(Args... args)
Allocate an Object on the heap and initialize with a set of attributes.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
NodeContainer nodes
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double Integral(const SpectrumValue &arg)
std::vector< BandInfo > Bands
Container of BandInfo.
mobility
Definition third.py:92
The building block of a SpectrumModel.
double fc
center frequency
double fl
lower limit of subband
double fh
upper limit of subband
void LogEndToEndGain(std::string cond, std::string scen, double fc, long int seed, double gain)
const Ptr< OutputStreamWrapper > g_outStream
const std::vector< std::string > LOS_CONDITIONS
const std::vector< std::string > THREE_GPP_SCENARIOS
constexpr double MIN_FC
double ComputePowerSpectralDensityOverallPower(Ptr< const SpectrumValue > psd)
double ComputeEndToEndGain(std::string cond, std::string scen, double fc, Ptr< Node > a, Ptr< Node > b, Ptr< PhasedArrayModel > aArray, Ptr< PhasedArrayModel > bArray)
Ptr< SpectrumValue > CreateTxPowerSpectralDensity(double fc)
constexpr double BW
constexpr double RB_WIDTH
constexpr double MAX_FC
constexpr double FC_STEP