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 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 */
19
20#include <ns3/command-line.h>
21#include <ns3/core-module.h>
22#include <ns3/double.h>
23#include <ns3/isotropic-antenna-model.h>
24#include <ns3/mobility-helper.h>
25#include <ns3/node-container.h>
26#include <ns3/object-factory.h>
27#include <ns3/pointer.h>
28#include <ns3/string.h>
29#include <ns3/three-gpp-channel-model.h>
30#include <ns3/three-gpp-propagation-loss-model.h>
31#include <ns3/three-gpp-spectrum-propagation-loss-model.h>
32#include <ns3/two-ray-spectrum-propagation-loss-model.h>
33#include <ns3/uinteger.h>
34#include <ns3/uniform-planar-array.h>
35
36NS_LOG_COMPONENT_DEFINE("ThreeGppTwoRayChannelCalibration");
37
38using namespace ns3;
39
40// Calibration results actually show a weak dependence with respect to the carrier frequency
41constexpr double FC_STEP = 5e9;
42
43// 500 MHz, as to provide a fit for the whole frequency range supported by the TR 38.901 model
44constexpr double MIN_FC = 500e6;
45
46// 100 GHz, as to provide a fit for the whole frequency range supported by the TR 38.901 model
47constexpr double MAX_FC = 100e9;
48
49// Results are independent from this
50constexpr double BW = 200e6;
51
52// Results are independent from this, it dictate sonly the resolution of the PSD.
53// This value corresponds to numerology index 2 of the 5G NR specifications
54constexpr double RB_WIDTH = 60e3;
55
56const std::vector<std::string> LOS_CONDITIONS{
57 "LOS",
58 "NLOS",
59};
60
61const std::vector<std::string> THREE_GPP_SCENARIOS{
62 "RMa",
63 "UMa",
64 "UMi-StreetCanyon",
65 "InH-OfficeOpen",
66 "InH-OfficeMixed",
67};
68
70 Create<OutputStreamWrapper>("two-ray-to-three-gpp-calibration.csv", std::ios::out);
71
72void
73LogEndToEndGain(std::string cond, std::string scen, double fc, long int seed, double gain)
74{
75 *g_outStream->GetStream() << cond << "\t" << scen << "\t" << fc << "\t" << seed << "\t" << gain
76 << "\n";
77}
78
79double
81{
82 return Integral(*psd);
83}
84
87{
88 uint32_t numRbs = std::floor(BW / RB_WIDTH);
89 double f = fc - (numRbs * RB_WIDTH / 2.0);
90 double powerTx = 0.0;
91
92 Bands rbs; // A vector representing each resource block
93 std::vector<int> rbsId; // A vector representing the resource block IDs
94 rbsId.reserve(numRbs);
95
96 for (uint32_t numrb = 0; numrb < numRbs; ++numrb)
97 {
98 BandInfo rb;
99 rb.fl = f;
100 f += RB_WIDTH / 2;
101 rb.fc = f;
102 f += RB_WIDTH / 2;
103 rb.fh = f;
104
105 rbs.push_back(rb);
106 rbsId.push_back(numrb);
107 }
108 Ptr<SpectrumModel> model = Create<SpectrumModel>(rbs);
109 Ptr<SpectrumValue> txPsd = Create<SpectrumValue>(model);
110
111 double powerTxW = std::pow(10., (powerTx - 30) / 10);
112 double txPowerDensity = powerTxW / BW;
113
114 for (auto rbId : rbsId)
115 {
116 (*txPsd)[rbId] = txPowerDensity;
117 }
118
119 return txPsd;
120}
121
122double
123ComputeEndToEndGain(std::string cond,
124 std::string scen,
125 double fc,
126 Ptr<Node> a,
127 Ptr<Node> b,
130{
131 // Fix the LOS condition
132 Ptr<ChannelConditionModel> channelConditionModel;
133 if (cond == "LOS")
134 {
135 channelConditionModel = CreateObject<AlwaysLosChannelConditionModel>();
136 }
137 else if (cond == "NLOS")
138 {
139 channelConditionModel = CreateObject<NeverLosChannelConditionModel>();
140 }
141 else
142 {
143 NS_ABORT_MSG("Unsupported channel condition");
144 }
145
146 // Create the needed objects. These must be created anew each loop, otherwise the channel is
147 // stored and never re-computed.
148 Ptr<ThreeGppSpectrumPropagationLossModel> threeGppSpectrumLossModel =
149 CreateObject<ThreeGppSpectrumPropagationLossModel>();
150 Ptr<ThreeGppChannelModel> threeGppChannelModel = CreateObject<ThreeGppChannelModel>();
151
152 // Pass the needed pointers between the various spectrum instances
153 threeGppSpectrumLossModel->SetAttribute("ChannelModel", PointerValue(threeGppChannelModel));
154 threeGppChannelModel->SetAttribute("ChannelConditionModel",
155 PointerValue(channelConditionModel));
156
157 // Create the TX PSD
159 double txPower = ComputePowerSpectralDensityOverallPower(txPsd);
160
161 // Create TX signal parameters
162 Ptr<SpectrumSignalParameters> signalParams = Create<SpectrumSignalParameters>();
163 signalParams->psd = txPsd;
164
165 // Set the carrier frequency
166 threeGppChannelModel->SetAttribute("Frequency", DoubleValue(fc));
167
168 // Set the scenario
169 threeGppChannelModel->SetAttribute("Scenario", StringValue(scen));
170
171 // Disable all possible sources of variance apart from the multipath fading
172 threeGppChannelModel->SetAttribute("Blockage", BooleanValue(false));
173
174 // Retrieve the mobility models and the position of the TX and RX nodes
175 Ptr<MobilityModel> aMob = a->GetObject<MobilityModel>();
176 Ptr<MobilityModel> bMob = b->GetObject<MobilityModel>();
177 Vector aPos = aMob->GetPosition();
178 Vector bPos = bMob->GetPosition();
179
180 // Compute the relative azimuth and the elevation angles
181 Angles angleBtoA(bPos, aPos);
182 Angles angleAtoB(aPos, bPos);
183
184 // Create the BF vectors
185 aArray->SetBeamformingVector(aArray->GetBeamformingVector(angleBtoA));
186 bArray->SetBeamformingVector(bArray->GetBeamformingVector(angleAtoB));
187
188 // Compute the received power due to multipath fading
189 auto rxParams = threeGppSpectrumLossModel->DoCalcRxPowerSpectralDensity(signalParams,
190 aMob,
191 bMob,
192 aArray,
193 bArray);
194 double rxPower = ComputePowerSpectralDensityOverallPower(rxParams->psd);
195
196 return rxPower / txPower;
197}
198
199int
200main(int argc, char* argv[])
201{
202 uint32_t numRealizations = 5000; // The number of different channel realizations
203 bool enableOutput = false; // Whether to log the results of the example
204
205 CommandLine cmd(__FILE__);
206 cmd.AddValue("enableOutput", "Logs the results of the example", enableOutput);
207 cmd.AddValue("numRealizations", "The number of different realizations", numRealizations);
208 cmd.Parse(argc, argv);
209
210 // Log trace structure
211 if (enableOutput)
212 {
213 *g_outStream->GetStream() << "cond\tscen\tfc\tseed\tgain\n";
214 }
215
216 // Aggregate them to the corresponding nodes
218 nodes.Create(2);
219
220 // Create the mobility models for the TX and RX nodes
222 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
223 Vector aPos(0.0, 0.0, 0.0);
224 Vector bPos(10.0, 0.0, 0.0);
225 positionAlloc->Add(aPos);
226 positionAlloc->Add(bPos);
227 mobility.SetPositionAllocator(positionAlloc);
228 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
229 mobility.Install(nodes);
230
231 // Create the TX and RX phased arrays
232 Ptr<PhasedArrayModel> aPhasedArray =
233 CreateObjectWithAttributes<UniformPlanarArray>("NumColumns",
234 UintegerValue(1),
235 "NumRows",
236 UintegerValue(1));
237 aPhasedArray->SetAntennaElement(PointerValue(CreateObject<IsotropicAntennaModel>()));
238 Ptr<PhasedArrayModel> bPhasedArray =
239 CreateObjectWithAttributes<UniformPlanarArray>("NumColumns",
240 UintegerValue(1),
241 "NumRows",
242 UintegerValue(1));
243 bPhasedArray->SetAntennaElement(PointerValue(CreateObject<IsotropicAntennaModel>()));
244
245 // Loop over predetermined set of scenarios, LOS conditions and frequencies
246 for (const auto& cond : LOS_CONDITIONS)
247 {
248 for (const auto& scen : THREE_GPP_SCENARIOS)
249 {
250 for (double fc = MIN_FC; fc < MAX_FC; fc += FC_STEP)
251 {
252 for (uint32_t runIdx = 0; runIdx < numRealizations; runIdx++)
253 {
254 double gain = ComputeEndToEndGain(cond,
255 scen,
256 fc,
257 nodes.Get(0),
258 nodes.Get(1),
259 aPhasedArray,
260 bPhasedArray);
261 if (enableOutput)
262 {
263 LogEndToEndGain(cond, scen, fc, runIdx, gain);
264 }
265 }
266 }
267 }
268 }
269}
Class holding the azimuth and inclination angles of spherical coordinates.
Definition: angles.h:118
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Parse command-line arguments.
Definition: command-line.h:232
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
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.
std::ostream * GetStream()
Return a pointer to an ostream previously set in the wrapper.
AttributeValue implementation for Pointer.
Definition: pointer.h:48
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
Hold variables of type string.
Definition: string.h:56
Hold an unsigned integer type.
Definition: uinteger.h:45
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
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.
ns cmd
Definition: second.py:40
ns mobility
Definition: third.py:105
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