5#include "nr-spectrum-phy-test.h"
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"
18NoLossSpectrumPropagationLossModel::NoLossSpectrumPropagationLossModel()
22NoLossSpectrumPropagationLossModel::~NoLossSpectrumPropagationLossModel()
29 static TypeId tid = TypeId(
"ns3::NoLossSpectrumPropagationLossModel")
30 .SetParent<SpectrumPropagationLossModel>()
31 .SetGroupName(
"Spectrum");
36NoLossSpectrumPropagationLossModel::DoCalcRxPowerSpectralDensity(
37 Ptr<const SpectrumSignalParameters> params,
38 Ptr<const MobilityModel> a,
39 Ptr<const MobilityModel> b)
const
41 return Copy(params->psd);
45NoLossSpectrumPropagationLossModel::DoAssignStreams(int64_t stream)
52 double noiseFigureFirst,
53 double noiseFigureSecond,
54 double expectedSnrFirst,
55 double expectedSnrSecond,
57 : TestCase(
"NrSpectrumPhy configuration test case")
60 m_bandwidth = bandwidth;
61 m_noiseFigureFirst = noiseFigureFirst;
62 m_noiseFigureSecond = noiseFigureSecond;
63 m_expectedSnrFirst = expectedSnrFirst;
64 m_expectedSnrSecond = expectedSnrSecond;
65 m_numerology = numerology;
85SetNoisePsdTestCase::DoEvaluateTest()
87 if (m_snr.size() != 2)
89 NS_TEST_ASSERT_MSG_EQ(
true,
91 "Test could not be evaluated, something wrong in test setup. Expects "
92 "to obtain two SNR values during the simulation.");
96 NS_TEST_ASSERT_MSG_NE(m_snr.at(0),
98 "SNR should not be equal because noise figure has been changed.");
99 NS_TEST_ASSERT_MSG_EQ_TOL(m_snr.at(0),
101 m_expectedSnrFirst * 0.1,
102 "First SNR is not as expected.");
103 NS_TEST_ASSERT_MSG_EQ_TOL(m_snr.at(1),
105 m_expectedSnrSecond * 0.1,
106 "Second SNR is not as expected.");
111SetNoisePsdTestCase::DoRun()
113 double centerFrequency = 28e9;
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 =
135 std::vector<int> activeRbs;
136 for (
size_t rbId = 0; rbId < sm->GetNumBands(); rbId++)
138 activeRbs.push_back(rbId);
145 NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_BW);
146 Ptr<const SpectrumValue> nsv0first =
148 Ptr<const SpectrumValue> nsv0second =
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);
167 params1->txPhy = txPhy;
169 rxPhy->GetNrInterference()->TraceConnectWithoutContext(
"SnrPerProcessedChunk",
170 MakeBoundCallback(&TestSaveSnr,
this));
172 Simulator::Schedule(MilliSeconds(0),
179 Simulator::Schedule(MilliSeconds(0), &MultiModelSpectrumChannel::AddRx, spectrumChannel, rxPhy);
180 Simulator::Schedule(MilliSeconds(1),
181 &MultiModelSpectrumChannel::StartTx,
186 Simulator::Schedule(MilliSeconds(4),
190 Simulator::Schedule(MilliSeconds(5),
191 &MultiModelSpectrumChannel::StartTx,
196 Simulator::Schedule(MilliSeconds(9), &SetNoisePsdTestCase::DoEvaluateTest,
this);
201 Simulator::Destroy();
205 : TestSuite(
"nr-spectrum-phy-test")
207 struct TestInputValues
209 double bandwidth{100e6};
211 double noiseFigure1{5};
212 double noiseFigure2{6};
213 uint8_t numerology{0};
215 TestInputValues(
double b,
double t,
double n1,
double n2,
double u)
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},
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},
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},
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},
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},
270 for (
auto input : testInputValuesSet)
272 uint64_t effectiveBandwidth =
274 double txPowerW = std::pow(10., (input.txPower - 30) / 10);
275 double txPowerWDensity = txPowerW / (double)effectiveBandwidth;
276 double kT_W_Hz = std::pow(10.0, (-174.0 - 30) / 10.0);
279 double noiseFigureLinear1 = std::pow(10.0, input.noiseFigure1 / 10.0);
280 double noisePowerSpectralDensity1 = kT_W_Hz * noiseFigureLinear1;
281 double expectedSnr1 = txPowerWDensity / noisePowerSpectralDensity1;
284 double noiseFigureLinear2 = std::pow(10.0, input.noiseFigure2 / 10.0);
285 double noisePowerSpectralDensity2 = kT_W_Hz * noiseFigureLinear2;
286 double expectedSnr2 = txPowerWDensity / noisePowerSpectralDensity2;
static TypeId GetTypeId()
Get the type ID.
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)
~SetNoisePsdTestCase() override
void SaveSnr(double snr)
Save SNR value in the list of values.