5G-LENA nr-v3.0-32-g83aee33
The 5G/NR module for the ns-3 simulator
Loading...
Searching...
No Matches
nr-spectrum-phy-test.cc
1/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2
3// Copyright (c) 2020 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
4//
5// SPDX-License-Identifier: GPL-2.0-only
6
7#include "nr-spectrum-phy-test.h"
8
9#include "ns3/beam-manager.h"
10#include "ns3/constant-position-mobility-model.h"
11#include "ns3/multi-model-spectrum-channel.h"
12#include "ns3/nr-gnb-phy.h"
13#include "ns3/nr-interference.h"
14#include "ns3/nr-spectrum-phy.h"
15#include "ns3/nr-spectrum-value-helper.h"
16
17namespace ns3
18{
19
20NoLossSpectrumPropagationLossModel::NoLossSpectrumPropagationLossModel()
21{
22}
23
24NoLossSpectrumPropagationLossModel::~NoLossSpectrumPropagationLossModel()
25{
26}
27
28TypeId
30{
31 static TypeId tid = TypeId("ns3::NoLossSpectrumPropagationLossModel")
32 .SetParent<SpectrumPropagationLossModel>()
33 .SetGroupName("Spectrum");
34 return tid;
35}
36
37Ptr<SpectrumValue>
38NoLossSpectrumPropagationLossModel::DoCalcRxPowerSpectralDensity(
39 Ptr<const SpectrumSignalParameters> params,
40 Ptr<const MobilityModel> a,
41 Ptr<const MobilityModel> b) const
42{
43 return Copy(params->psd);
44}
45
46int64_t
47NoLossSpectrumPropagationLossModel::DoAssignStreams(int64_t stream)
48{
49 return 0;
50}
51
53 double bandwidth,
54 double noiseFigureFirst,
55 double noiseFigureSecond,
56 double expectedSnrFirst,
57 double expectedSnrSecond,
58 uint8_t numerology)
59 : TestCase("NrSpectrumPhy configuration test case")
60{
61 m_txPower = txPower;
62 m_bandwidth = bandwidth;
63 m_noiseFigureFirst = noiseFigureFirst;
64 m_noiseFigureSecond = noiseFigureSecond;
65 m_expectedSnrFirst = expectedSnrFirst;
66 m_expectedSnrSecond = expectedSnrSecond;
67 m_numerology = numerology;
68}
69
73
74void
76{
77 m_snr.push_back(snr);
78}
79
80void
81TestSaveSnr(SetNoisePsdTestCase* test, double snr)
82{
83 test->SaveSnr(snr);
84}
85
86void
87SetNoisePsdTestCase::DoEvaluateTest()
88{
89 if (m_snr.size() != 2)
90 {
91 NS_TEST_ASSERT_MSG_EQ(true,
92 false,
93 "Test could not be evaluated, something wrong in test setup. Expects "
94 "to obtain two SNR values during the simulation.");
95 }
96 else
97 {
98 NS_TEST_ASSERT_MSG_NE(m_snr.at(0),
99 m_snr.at(1),
100 "SNR should not be equal because noise figure has been changed.");
101 NS_TEST_ASSERT_MSG_EQ_TOL(m_snr.at(0),
102 m_expectedSnrFirst,
103 m_expectedSnrFirst * 0.1,
104 "First SNR is not as expected.");
105 NS_TEST_ASSERT_MSG_EQ_TOL(m_snr.at(1),
106 m_expectedSnrSecond,
107 m_expectedSnrSecond * 0.1,
108 "Second SNR is not as expected.");
109 }
110}
111
112void
113SetNoisePsdTestCase::DoRun()
114{
115 double centerFrequency = 28e9;
116
117 Ptr<NrSpectrumPhy> rxPhy = CreateObject<NrSpectrumPhy>();
118 rxPhy->SetMobility(CreateObject<ConstantPositionMobilityModel>());
119 Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
120 spectrumChannel->AddSpectrumPropagationLossModel(
121 CreateObject<NoLossSpectrumPropagationLossModel>());
122 rxPhy->SetChannel(spectrumChannel);
123 Ptr<NrGnbPhy> phy = CreateObject<NrGnbPhy>();
124 Ptr<BeamManager> beamManager = CreateObject<BeamManager>();
125 phy->InstallSpectrumPhy(rxPhy);
126 rxPhy->InstallPhy(phy);
127 Ptr<UniformPlanarArray> antenna = CreateObject<UniformPlanarArray>();
128 rxPhy->SetAntenna(antenna);
129 beamManager->Configure(antenna);
130 phy->DoSetCellId(99);
131 rxPhy->InstallPhy(phy);
132 double subcarrierSpacing = 15000 * static_cast<uint32_t>(std::pow(2, m_numerology));
133 uint32_t rbNum = m_bandwidth / (12 * subcarrierSpacing);
134 Ptr<const SpectrumModel> sm =
135 NrSpectrumValueHelper::GetSpectrumModel(rbNum, centerFrequency, subcarrierSpacing);
136
137 std::vector<int> activeRbs;
138 for (size_t rbId = 0; rbId < sm->GetNumBands(); rbId++)
139 {
140 activeRbs.push_back(rbId);
141 }
142
143 Ptr<const SpectrumValue> txPsd = NrSpectrumValueHelper::CreateTxPowerSpectralDensity(
144 m_txPower,
145 activeRbs,
146 sm,
147 NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_BW);
148 Ptr<const SpectrumValue> nsv0first =
150 Ptr<const SpectrumValue> nsv0second =
152
153 Ptr<NrSpectrumSignalParametersDataFrame> params1 =
154 Create<NrSpectrumSignalParametersDataFrame>();
155 params1->duration = Time(MilliSeconds(1));
156 params1->psd = Copy(txPsd);
157 params1->cellId = 99;
158 Ptr<NrSpectrumPhy> txPhy = CreateObject<NrSpectrumPhy>();
159 txPhy->SetMobility(CreateObject<ConstantPositionMobilityModel>());
160 Ptr<UniformPlanarArray> ueAntenna = CreateObject<UniformPlanarArray>();
161 Ptr<NrGnbPhy> uePhy = CreateObject<NrGnbPhy>();
162 uePhy->InstallSpectrumPhy(txPhy);
163 txPhy->InstallPhy(uePhy);
164 txPhy->SetAntenna(ueAntenna);
165 Ptr<BeamManager> ueBeamManager = CreateObject<BeamManager>();
166 ueBeamManager->Configure(ueAntenna);
167 uePhy->DoSetCellId(99);
168
169 params1->txPhy = txPhy;
170
171 rxPhy->GetNrInterference()->TraceConnectWithoutContext("SnrPerProcessedChunk",
172 MakeBoundCallback(&TestSaveSnr, this));
173
174 Simulator::Schedule(MilliSeconds(0),
176 rxPhy,
177 nsv0first);
178 // spectrum phy can be attached to spectrum channel only once that the spectrum model of the
179 // spectrum phy is being set spectrum model is being set when noise power spectral density is
180 // set for the first time
181 Simulator::Schedule(MilliSeconds(0), &MultiModelSpectrumChannel::AddRx, spectrumChannel, rxPhy);
182 Simulator::Schedule(MilliSeconds(1),
183 &MultiModelSpectrumChannel::StartTx,
184 spectrumChannel,
185 params1);
186 Simulator::Schedule(MilliSeconds(3), &NrInterference::EndRx, rxPhy->GetNrInterference());
187
188 Simulator::Schedule(MilliSeconds(4),
190 rxPhy,
191 nsv0second);
192 Simulator::Schedule(MilliSeconds(5),
193 &MultiModelSpectrumChannel::StartTx,
194 spectrumChannel,
195 params1);
196 Simulator::Schedule(MilliSeconds(7), &NrInterference::EndRx, rxPhy->GetNrInterference());
197
198 Simulator::Schedule(MilliSeconds(9), &SetNoisePsdTestCase::DoEvaluateTest, this);
199
200 Simulator::Run();
201 Simulator::Destroy();
202}
203
205 : TestSuite("nr-spectrum-phy-test")
206{
207 struct TestInputValues
208 {
209 double bandwidth{100e6}; // Hz
210 double txPower{10}; // dBm
211 double noiseFigure1{5}; // dB
212 double noiseFigure2{6}; // dB
213 uint8_t numerology{0}; // integer value
214
215 TestInputValues(double b, double t, double n1, double n2, double u)
216 : bandwidth(b),
217 txPower(t),
218 noiseFigure1(n1),
219 noiseFigure2(n2),
220 numerology(u)
221 {
222 }
223 };
224
225 std::vector<TestInputValues> testInputValuesSet = {
226 {100e6, 10.0, 4, 6, 0},
227 {200e6, 5.0, 5, 6, 0},
228 {300e6, 20.0, 7, 5, 0},
229 {1e9, 30.0, 4, 5, 0},
230 {20e6, 4.0, 5, 6, 0},
231 {10e6, 1.0, 8, 9, 0},
232 {5e6, 1.0, 8, 9, 0},
233 {1.4e6, 0.5, 8, 9, 0},
234 {100e6, 10.0, 4, 6, 1},
235 {200e6, 5.0, 5, 6, 1},
236 {300e6, 20.0, 7, 5, 1},
237 {1e9, 30.0, 4, 5, 1},
238 {20e6, 4.0, 5, 6, 1},
239 {10e6, 1.0, 8, 9, 1},
240 {5e6, 1.0, 8, 9, 1},
241 {1.4e6, 0.5, 8, 9, 1},
242 {100e6, 10.0, 4, 6, 2},
243 {200e6, 5.0, 5, 6, 2},
244 {300e6, 20.0, 7, 5, 2},
245 {1e9, 30.0, 4, 5, 2},
246 {20e6, 4.0, 5, 6, 2},
247 {10e6, 1.0, 8, 9, 2},
248 {5e6, 1.0, 8, 9, 2},
249 {1.4e6, 0.5, 8, 9, 2},
250 {100e6, 10.0, 4, 6, 3},
251 {200e6, 5.0, 5, 6, 3},
252 {300e6, 20.0, 7, 5, 3},
253 {1e9, 30.0, 4, 5, 3},
254 {20e6, 4.0, 5, 6, 3},
255 {10e6, 1.0, 8, 9, 3},
256 {5e6, 1.0, 8, 9, 3},
257 //{ 1.4e6, 0.5, 8, 9, 3}, This test case will not work since 1.4MHz cannot s not enough
258 // width for numerology 3, because numerology 3 RB width is 1.44 MHz
259 {100e6, 10.0, 4, 6, 4},
260 {200e6, 5.0, 5, 6, 4},
261 {300e6, 20.0, 7, 5, 4},
262 {1e9, 30.0, 4, 5, 4},
263 {20e6, 4.0, 5, 6, 4},
264 {10e6, 1.0, 8, 9, 4},
265 {5e6, 1.0, 8, 9, 4},
266 //{ 1.4e6, 0.5, 8, 9, 4} This test case will not work since 1.4MHz cannot is not enough
267 // width for numerology 3, because numerology 3 RB width is 2.88 MHz
268 };
269
270 for (auto input : testInputValuesSet)
271 {
272 uint64_t effectiveBandwidth =
273 NrSpectrumValueHelper::GetEffectiveBandwidth(input.bandwidth, input.numerology);
274 double txPowerW = std::pow(10., (input.txPower - 30) / 10); // W
275 double txPowerWDensity = txPowerW / (double)effectiveBandwidth; // W/Hz
276 double kT_W_Hz = std::pow(10.0, (-174.0 - 30) / 10.0); // W/Hz
277
278 // calculate what should be SNR for noise figure 1
279 double noiseFigureLinear1 = std::pow(10.0, input.noiseFigure1 / 10.0);
280 double noisePowerSpectralDensity1 = kT_W_Hz * noiseFigureLinear1;
281 double expectedSnr1 = txPowerWDensity / noisePowerSpectralDensity1;
282
283 // calculate what should be SNR for noise figure 2
284 double noiseFigureLinear2 = std::pow(10.0, input.noiseFigure2 / 10.0);
285 double noisePowerSpectralDensity2 = kT_W_Hz * noiseFigureLinear2;
286 double expectedSnr2 = txPowerWDensity / noisePowerSpectralDensity2;
287
288 AddTestCase(new SetNoisePsdTestCase(input.txPower,
289 input.bandwidth,
290 input.noiseFigure1,
291 input.noiseFigure2,
292 expectedSnr1,
293 expectedSnr2,
294 input.numerology),
295 Duration::QUICK);
296 }
297}
298
299// Allocate an instance of this TestSuite
300static NrSpectrumPhyTestSuite g_nrSpectrumPhyTestSuite;
301
302} // namespace ns3
static TypeId GetTypeId()
Get the type ID.
void SetNoisePowerSpectralDensity(const Ptr< const SpectrumValue > &noisePsd)
Sets noise power spectral density to be used by this device.
static Ptr< const SpectrumModel > GetSpectrumModel(uint32_t numRbs, double centerFrequency, double subcarrierSpacing)
Creates or obtains from a global map a spectrum model with a given number of RBs, center frequency an...
static Ptr< SpectrumValue > CreateNoisePowerSpectralDensity(double noiseFigure, const Ptr< const SpectrumModel > &spectrumModel)
Create a SpectrumValue that models the power spectral density of AWGN.
static uint64_t GetEffectiveBandwidth(double bandwidth, uint8_t numerology)
Returns the effective bandwidth for the total system bandwidth.
static Ptr< SpectrumValue > CreateTxPowerSpectralDensity(double powerTx, const std::vector< int > &rbIndexVector, const Ptr< const SpectrumModel > &txSm, enum PowerAllocationType allocationType)
Create SpectrumValue that will represent transmit power spectral density, and assuming that all RBs a...
SetNoisePsdTestCase(double txPower, double bandwidth, double noiseFigureFirst, double noiseFigureSecond, double expectedSnrFirst, double expectedSnrSecond, uint8_t numerology)
void SaveSnr(double snr)
Save SNR value in the list of values.