5G-LENA nr-v3.3-81-g75c7590d
The 5G/NR module for the ns-3 simulator
Loading...
Searching...
No Matches
nr-spectrum-phy-test.cc
1// Copyright (c) 2020 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
2//
3// SPDX-License-Identifier: GPL-2.0-only
4
5#include "nr-spectrum-phy-test.h"
6
7#include "ns3/beam-manager.h"
8#include "ns3/constant-position-mobility-model.h"
9#include "ns3/multi-model-spectrum-channel.h"
10#include "ns3/nr-gnb-phy.h"
11#include "ns3/nr-interference.h"
12#include "ns3/nr-spectrum-phy.h"
13#include "ns3/nr-spectrum-value-helper.h"
14
15namespace ns3
16{
17
18NoLossSpectrumPropagationLossModel::NoLossSpectrumPropagationLossModel()
19{
20}
21
22NoLossSpectrumPropagationLossModel::~NoLossSpectrumPropagationLossModel()
23{
24}
25
26TypeId
28{
29 static TypeId tid = TypeId("ns3::NoLossSpectrumPropagationLossModel")
30 .SetParent<SpectrumPropagationLossModel>()
31 .SetGroupName("Spectrum");
32 return tid;
33}
34
35Ptr<SpectrumValue>
36NoLossSpectrumPropagationLossModel::DoCalcRxPowerSpectralDensity(
37 Ptr<const SpectrumSignalParameters> params,
38 Ptr<const MobilityModel> a,
39 Ptr<const MobilityModel> b) const
40{
41 return Copy(params->psd);
42}
43
44int64_t
45NoLossSpectrumPropagationLossModel::DoAssignStreams(int64_t stream)
46{
47 return 0;
48}
49
51 double bandwidth,
52 double noiseFigureFirst,
53 double noiseFigureSecond,
54 double expectedSnrFirst,
55 double expectedSnrSecond,
56 uint8_t numerology)
57 : TestCase("NrSpectrumPhy configuration test case")
58{
59 m_txPower = txPower;
60 m_bandwidth = bandwidth;
61 m_noiseFigureFirst = noiseFigureFirst;
62 m_noiseFigureSecond = noiseFigureSecond;
63 m_expectedSnrFirst = expectedSnrFirst;
64 m_expectedSnrSecond = expectedSnrSecond;
65 m_numerology = numerology;
66}
67
71
72void
74{
75 m_snr.push_back(snr);
76}
77
78void
79TestSaveSnr(SetNoisePsdTestCase* test, double snr)
80{
81 test->SaveSnr(snr);
82}
83
84void
85SetNoisePsdTestCase::DoEvaluateTest()
86{
87 if (m_snr.size() != 2)
88 {
89 NS_TEST_ASSERT_MSG_EQ(true,
90 false,
91 "Test could not be evaluated, something wrong in test setup. Expects "
92 "to obtain two SNR values during the simulation.");
93 }
94 else
95 {
96 NS_TEST_ASSERT_MSG_NE(m_snr.at(0),
97 m_snr.at(1),
98 "SNR should not be equal because noise figure has been changed.");
99 NS_TEST_ASSERT_MSG_EQ_TOL(m_snr.at(0),
100 m_expectedSnrFirst,
101 m_expectedSnrFirst * 0.1,
102 "First SNR is not as expected.");
103 NS_TEST_ASSERT_MSG_EQ_TOL(m_snr.at(1),
104 m_expectedSnrSecond,
105 m_expectedSnrSecond * 0.1,
106 "Second SNR is not as expected.");
107 }
108}
109
110void
111SetNoisePsdTestCase::DoRun()
112{
113 double centerFrequency = 28e9;
114
115 Ptr<NrSpectrumPhy> rxPhy = CreateObject<NrSpectrumPhy>();
116 rxPhy->SetMobility(CreateObject<ConstantPositionMobilityModel>());
117 Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel>();
118 spectrumChannel->AddSpectrumPropagationLossModel(
119 CreateObject<NoLossSpectrumPropagationLossModel>());
120 rxPhy->SetChannel(spectrumChannel);
121 Ptr<NrGnbPhy> phy = CreateObject<NrGnbPhy>();
122 Ptr<BeamManager> beamManager = CreateObject<BeamManager>();
123 phy->InstallSpectrumPhy(rxPhy);
124 rxPhy->InstallPhy(phy);
125 Ptr<UniformPlanarArray> antenna = CreateObject<UniformPlanarArray>();
126 rxPhy->SetAntenna(antenna);
127 beamManager->Configure(antenna);
128 phy->DoSetCellId(99);
129 rxPhy->InstallPhy(phy);
130 double subcarrierSpacing = 15000 * static_cast<uint32_t>(std::pow(2, m_numerology));
131 uint32_t rbNum = m_bandwidth / (12 * subcarrierSpacing);
132 Ptr<const SpectrumModel> sm =
133 NrSpectrumValueHelper::GetSpectrumModel(rbNum, centerFrequency, subcarrierSpacing);
134
135 std::vector<int> activeRbs;
136 for (size_t rbId = 0; rbId < sm->GetNumBands(); rbId++)
137 {
138 activeRbs.push_back(rbId);
139 }
140
141 Ptr<const SpectrumValue> txPsd = NrSpectrumValueHelper::CreateTxPowerSpectralDensity(
142 m_txPower,
143 activeRbs,
144 sm,
145 NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_BW);
146 Ptr<const SpectrumValue> nsv0first =
148 Ptr<const SpectrumValue> nsv0second =
150
151 Ptr<NrSpectrumSignalParametersDataFrame> params1 =
152 Create<NrSpectrumSignalParametersDataFrame>();
153 params1->duration = Time(MilliSeconds(1));
154 params1->psd = Copy(txPsd);
155 params1->cellId = 99;
156 Ptr<NrSpectrumPhy> txPhy = CreateObject<NrSpectrumPhy>();
157 txPhy->SetMobility(CreateObject<ConstantPositionMobilityModel>());
158 Ptr<UniformPlanarArray> ueAntenna = CreateObject<UniformPlanarArray>();
159 Ptr<NrGnbPhy> gnbPhy = CreateObject<NrGnbPhy>();
160 gnbPhy->InstallSpectrumPhy(txPhy);
161 txPhy->InstallPhy(gnbPhy);
162 txPhy->SetAntenna(ueAntenna);
163 Ptr<BeamManager> ueBeamManager = CreateObject<BeamManager>();
164 ueBeamManager->Configure(ueAntenna);
165 gnbPhy->DoSetCellId(99);
166
167 params1->txPhy = txPhy;
168
169 rxPhy->GetNrInterference()->TraceConnectWithoutContext("SnrPerProcessedChunk",
170 MakeBoundCallback(&TestSaveSnr, this));
171
172 Simulator::Schedule(MilliSeconds(0),
174 rxPhy,
175 nsv0first);
176 // spectrum phy can be attached to spectrum channel only once that the spectrum model of the
177 // spectrum phy is being set spectrum model is being set when noise power spectral density is
178 // set for the first time
179 Simulator::Schedule(MilliSeconds(0), &MultiModelSpectrumChannel::AddRx, spectrumChannel, rxPhy);
180 Simulator::Schedule(MilliSeconds(1),
181 &MultiModelSpectrumChannel::StartTx,
182 spectrumChannel,
183 params1);
184 Simulator::Schedule(MilliSeconds(3), &NrInterference::EndRx, rxPhy->GetNrInterference());
185
186 Simulator::Schedule(MilliSeconds(4),
188 rxPhy,
189 nsv0second);
190 Simulator::Schedule(MilliSeconds(5),
191 &MultiModelSpectrumChannel::StartTx,
192 spectrumChannel,
193 params1);
194 Simulator::Schedule(MilliSeconds(7), &NrInterference::EndRx, rxPhy->GetNrInterference());
195
196 Simulator::Schedule(MilliSeconds(9), &SetNoisePsdTestCase::DoEvaluateTest, this);
197
198 Simulator::Run();
199 rxPhy->Dispose(); // Explicitly dispose NrSpectrumPhy since it is not aggregated to a Node
200 gnbPhy->Dispose(); // Explicitly dispose NrPhy since it is not aggregated to a Node
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 EndRx() override
virtual 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.