5G-LENA nr-v3.1-69-g2dd513a7
The 5G/NR module for the ns-3 simulator
Loading...
Searching...
No Matches
ideal-beamforming-algorithm.cc
1// Copyright (c) 2020 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
2//
3// SPDX-License-Identifier: GPL-2.0-only
4
5#include "ideal-beamforming-algorithm.h"
6
7#include "nr-spectrum-phy.h"
8
9#include <ns3/double.h>
10#include <ns3/multi-model-spectrum-channel.h>
11#include <ns3/node.h>
12#include <ns3/nr-spectrum-value-helper.h>
13#include <ns3/uinteger.h>
14#include <ns3/uniform-planar-array.h>
15
16namespace ns3
17{
18
19NS_LOG_COMPONENT_DEFINE("IdealBeamformingAlgorithm");
20NS_OBJECT_ENSURE_REGISTERED(CellScanBeamforming);
21NS_OBJECT_ENSURE_REGISTERED(CellScanBeamformingAzimuthZenith);
22NS_OBJECT_ENSURE_REGISTERED(CellScanQuasiOmniBeamforming);
23NS_OBJECT_ENSURE_REGISTERED(DirectPathBeamforming);
24NS_OBJECT_ENSURE_REGISTERED(QuasiOmniDirectPathBeamforming);
25NS_OBJECT_ENSURE_REGISTERED(DirectPathQuasiOmniBeamforming);
26NS_OBJECT_ENSURE_REGISTERED(OptimalCovMatrixBeamforming);
27
28TypeId
30{
31 static TypeId tid = TypeId("ns3::IdealBeamformingAlgorithm").SetParent<Object>();
32 return tid;
33}
34
35TypeId
37{
38 static TypeId tid =
39 TypeId("ns3::CellScanBeamforming")
40 .SetParent<IdealBeamformingAlgorithm>()
41 .AddConstructor<CellScanBeamforming>()
42 .AddAttribute("BeamSearchAngleStep",
43 "Angle step when searching for the best beam",
44 DoubleValue(30),
47 MakeDoubleChecker<double>());
48
49 return tid;
50}
51
52void
54{
55 m_beamSearchAngleStep = beamSearchAngleStep;
56}
57
58double
60{
61 return m_beamSearchAngleStep;
62}
63
64BeamformingVectorPair
65CellScanBeamforming::GetBeamformingVectors(const Ptr<NrSpectrumPhy>& gnbSpectrumPhy,
66 const Ptr<NrSpectrumPhy>& ueSpectrumPhy) const
67{
68 NS_ABORT_MSG_IF(gnbSpectrumPhy == nullptr || ueSpectrumPhy == nullptr,
69 "Something went wrong, gnb or UE PHY layer not set.");
70 double distance = gnbSpectrumPhy->GetMobility()->GetDistanceFrom(ueSpectrumPhy->GetMobility());
71 NS_ABORT_MSG_IF(distance == 0,
72 "Beamforming method cannot be performed between two devices that are placed in "
73 "the same position.");
74
75 Ptr<SpectrumChannel> gnbSpectrumChannel =
76 gnbSpectrumPhy
77 ->GetSpectrumChannel(); // SpectrumChannel should be const.. but need to change ns-3-dev
78 Ptr<SpectrumChannel> ueSpectrumChannel = ueSpectrumPhy->GetSpectrumChannel();
79
80 Ptr<const PhasedArraySpectrumPropagationLossModel> gnbThreeGppSpectrumPropModel =
81 gnbSpectrumChannel->GetPhasedArraySpectrumPropagationLossModel();
82 Ptr<const PhasedArraySpectrumPropagationLossModel> ueThreeGppSpectrumPropModel =
83 ueSpectrumChannel->GetPhasedArraySpectrumPropagationLossModel();
84 NS_ASSERT_MSG(gnbThreeGppSpectrumPropModel == ueThreeGppSpectrumPropModel,
85 "Devices should be connected on the same spectrum channel");
86
87 std::vector<int> activeRbs;
88 for (size_t rbId = 0; rbId < gnbSpectrumPhy->GetRxSpectrumModel()->GetNumBands(); rbId++)
89 {
90 activeRbs.push_back(rbId);
91 }
92
93 Ptr<const SpectrumValue> fakePsd = NrSpectrumValueHelper::CreateTxPowerSpectralDensity(
94 0.0,
95 activeRbs,
96 gnbSpectrumPhy->GetRxSpectrumModel(),
97 NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_BW);
98 Ptr<SpectrumSignalParameters> fakeParams = Create<SpectrumSignalParameters>();
99 fakeParams->psd = fakePsd->Copy();
100
101 double max = 0;
102 double maxTxTheta = 0;
103 double maxRxTheta = 0;
104 uint16_t maxTxSector = 0;
105 uint16_t maxRxSector = 0;
106 PhasedArrayModel::ComplexVector maxTxW;
107 PhasedArrayModel::ComplexVector maxRxW;
108
109 UintegerValue uintValue;
110 gnbSpectrumPhy->GetAntenna()->GetAttribute("NumRows", uintValue);
111 uint32_t txNumRows = static_cast<uint32_t>(uintValue.Get());
112 ueSpectrumPhy->GetAntenna()->GetAttribute("NumRows", uintValue);
113 uint32_t rxNumRows = static_cast<uint32_t>(uintValue.Get());
114
115 NS_ASSERT(gnbSpectrumPhy->GetAntenna()->GetObject<PhasedArrayModel>()->GetNumElems() &&
116 ueSpectrumPhy->GetAntenna()->GetObject<PhasedArrayModel>()->GetNumElems());
117
118 uint16_t numRowsTx = static_cast<uint16_t>(txNumRows);
119 uint16_t numRowsRx = static_cast<uint16_t>(rxNumRows);
120 for (double txTheta = 60; txTheta < 121; txTheta = txTheta + m_beamSearchAngleStep)
121 {
122 for (uint16_t txSector = 0; txSector <= numRowsTx; txSector++)
123 {
124 NS_ASSERT(txSector < UINT16_MAX);
125
126 gnbSpectrumPhy->GetBeamManager()->SetSector(txSector, txTheta);
127 PhasedArrayModel::ComplexVector txW =
128 gnbSpectrumPhy->GetBeamManager()->GetCurrentBeamformingVector();
129
130 if (maxTxW.GetSize() == 0)
131 {
132 maxTxW = txW; // initialize maxTxW
133 }
134
135 for (double rxTheta = 60; rxTheta < 121;
136 rxTheta = static_cast<uint16_t>(rxTheta + m_beamSearchAngleStep))
137 {
138 for (uint16_t rxSector = 0; rxSector <= numRowsRx; rxSector++)
139 {
140 NS_ASSERT(rxSector < UINT16_MAX);
141
142 ueSpectrumPhy->GetBeamManager()->SetSector(rxSector, rxTheta);
143 PhasedArrayModel::ComplexVector rxW =
144 ueSpectrumPhy->GetBeamManager()->GetCurrentBeamformingVector();
145
146 if (maxRxW.GetSize() == 0)
147 {
148 maxRxW = rxW; // initialize maxRxW
149 }
150
151 NS_ABORT_MSG_IF(txW.GetSize() == 0 || rxW.GetSize() == 0,
152 "Beamforming vectors must be initialized in order to calculate "
153 "the long term matrix.");
154
155 Ptr<SpectrumSignalParameters> rxParams =
156 gnbThreeGppSpectrumPropModel->CalcRxPowerSpectralDensity(
157 fakeParams,
158 gnbSpectrumPhy->GetMobility(),
159 ueSpectrumPhy->GetMobility(),
160 gnbSpectrumPhy->GetAntenna()->GetObject<PhasedArrayModel>(),
161 ueSpectrumPhy->GetAntenna()->GetObject<PhasedArrayModel>());
162
163 size_t nbands = rxParams->psd->GetSpectrumModel()->GetNumBands();
164 double power = Sum(*(rxParams->psd)) / nbands;
165
166 NS_LOG_LOGIC(
167 " Rx power: "
168 << power << "txTheta " << txTheta << " rxTheta " << rxTheta << " tx sector "
169 << (M_PI * static_cast<double>(txSector) / static_cast<double>(txNumRows) -
170 0.5 * M_PI) /
171 M_PI * 180
172 << " rx sector "
173 << (M_PI * static_cast<double>(rxSector) / static_cast<double>(rxNumRows) -
174 0.5 * M_PI) /
175 M_PI * 180);
176
177 if (max < power)
178 {
179 max = power;
180 maxTxSector = txSector;
181 maxRxSector = rxSector;
182 maxTxTheta = txTheta;
183 maxRxTheta = rxTheta;
184 maxTxW = txW;
185 maxRxW = rxW;
186 }
187 }
188 }
189 }
190 }
191
192 BeamformingVector gnbBfv =
193 BeamformingVector(std::make_pair(maxTxW, BeamId(maxTxSector, maxTxTheta)));
194 BeamformingVector ueBfv =
195 BeamformingVector(std::make_pair(maxRxW, BeamId(maxRxSector, maxRxTheta)));
196
197 NS_LOG_DEBUG(
198 "Beamforming vectors for gNB with node id: "
199 << gnbSpectrumPhy->GetMobility()->GetObject<Node>()->GetId()
200 << " and UE with node id: " << ueSpectrumPhy->GetMobility()->GetObject<Node>()->GetId()
201 << " are txTheta " << maxTxTheta << " rxTheta " << maxRxTheta << " tx sector "
202 << (M_PI * static_cast<double>(maxTxSector) / static_cast<double>(txNumRows) - 0.5 * M_PI) /
203 M_PI * 180
204 << " rx sector "
205 << (M_PI * static_cast<double>(maxRxSector) / static_cast<double>(rxNumRows) - 0.5 * M_PI) /
206 M_PI * 180);
207
208 NS_ASSERT(maxTxW.GetSize() && maxRxW.GetSize());
209
210 return BeamformingVectorPair(std::make_pair(gnbBfv, ueBfv));
211}
212
213TypeId
215{
216 static TypeId tid = TypeId("ns3::CellScanBeamformingAzimuthZenith")
217 .SetParent<IdealBeamformingAlgorithm>()
218 .AddConstructor<CellScanBeamformingAzimuthZenith>();
219
220 return tid;
221}
222
223BeamformingVectorPair
225 const Ptr<NrSpectrumPhy>& gnbSpectrumPhy,
226 const Ptr<NrSpectrumPhy>& ueSpectrumPhy) const
227{
228 NS_ABORT_MSG_IF(gnbSpectrumPhy == nullptr || ueSpectrumPhy == nullptr,
229 "Something went wrong, gnb or UE PHY layer not set.");
230 double distance = gnbSpectrumPhy->GetMobility()->GetDistanceFrom(ueSpectrumPhy->GetMobility());
231 NS_ABORT_MSG_IF(distance == 0,
232 "Beamforming method cannot be performed between "
233 "two devices that are placed in the same position.");
234
235 Ptr<SpectrumChannel> gnbSpectrumChannel =
236 gnbSpectrumPhy
237 ->GetSpectrumChannel(); // SpectrumChannel should be const.. but need to change ns-3-dev
238 Ptr<SpectrumChannel> ueSpectrumChannel = ueSpectrumPhy->GetSpectrumChannel();
239
240 Ptr<const PhasedArraySpectrumPropagationLossModel> gnbThreeGppSpectrumPropModel =
241 gnbSpectrumChannel->GetPhasedArraySpectrumPropagationLossModel();
242 Ptr<const PhasedArraySpectrumPropagationLossModel> ueThreeGppSpectrumPropModel =
243 ueSpectrumChannel->GetPhasedArraySpectrumPropagationLossModel();
244 NS_ASSERT_MSG(gnbThreeGppSpectrumPropModel == ueThreeGppSpectrumPropModel,
245 "Devices should be connected on the same spectrum channel");
246
247 std::vector<int> activeRbs;
248 for (size_t rbId = 0; rbId < gnbSpectrumPhy->GetRxSpectrumModel()->GetNumBands(); rbId++)
249 {
250 activeRbs.push_back(rbId);
251 }
252
253 Ptr<const SpectrumValue> fakePsd = NrSpectrumValueHelper::CreateTxPowerSpectralDensity(
254 0.0,
255 activeRbs,
256 gnbSpectrumPhy->GetRxSpectrumModel(),
257 NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_BW);
258 Ptr<SpectrumSignalParameters> fakeParams = Create<SpectrumSignalParameters>();
259 fakeParams->psd = fakePsd->Copy();
260
261 double max = 0;
262 double maxTxAzimuth = 0;
263 double maxRxAzimuth = 0;
264 double maxTxZenith = 0;
265 double maxRxZenith = 0;
266 PhasedArrayModel::ComplexVector maxTxW;
267 PhasedArrayModel::ComplexVector maxRxW;
268
269 UintegerValue uintValue;
270 gnbSpectrumPhy->GetAntenna()->GetAttribute("NumRows", uintValue);
271 ueSpectrumPhy->GetAntenna()->GetAttribute("NumRows", uintValue);
272
273 NS_ASSERT(gnbSpectrumPhy->GetAntenna()->GetObject<PhasedArrayModel>()->GetNumElems() &&
274 ueSpectrumPhy->GetAntenna()->GetObject<PhasedArrayModel>()->GetNumElems());
275
276 for (double azimuthTx : m_azimuth)
277 {
278 for (double zenithTx : m_zenith)
279 {
280 gnbSpectrumPhy->GetBeamManager()->SetSectorAz(azimuthTx, zenithTx);
281 PhasedArrayModel::ComplexVector txW =
282 gnbSpectrumPhy->GetBeamManager()->GetCurrentBeamformingVector();
283
284 if (maxTxW.GetSize() == 0)
285 {
286 maxTxW = txW; // initialize maxTxW
287 }
288
289 for (double azimuthRx : m_azimuth)
290 {
291 for (double zenithRx : m_zenith)
292 {
293 ueSpectrumPhy->GetBeamManager()->SetSectorAz(azimuthRx, zenithRx);
294 PhasedArrayModel::ComplexVector rxW =
295 ueSpectrumPhy->GetBeamManager()->GetCurrentBeamformingVector();
296
297 if (maxRxW.GetSize() == 0)
298 {
299 maxRxW = rxW; // initialize maxRxW
300 }
301
302 NS_ABORT_MSG_IF(txW.GetSize() == 0 || rxW.GetSize() == 0,
303 "Beamforming vectors must be initialized in "
304 "order to calculate the long term matrix.");
305
306 Ptr<SpectrumSignalParameters> rxParams =
307 gnbThreeGppSpectrumPropModel->CalcRxPowerSpectralDensity(
308 fakeParams,
309 gnbSpectrumPhy->GetMobility(),
310 ueSpectrumPhy->GetMobility(),
311 gnbSpectrumPhy->GetAntenna()->GetObject<PhasedArrayModel>(),
312 ueSpectrumPhy->GetAntenna()->GetObject<PhasedArrayModel>());
313
314 size_t nbands = rxParams->psd->GetSpectrumModel()->GetNumBands();
315 double power = Sum(*rxParams->psd) / nbands;
316
317 NS_LOG_LOGIC(" Rx power: " << power << " azimuthTx " << azimuthTx
318 << " zenithTx " << zenithTx << " azimuthRx "
319 << azimuthRx << " zenithRx " << zenithRx);
320
321 if (max < power)
322 {
323 max = power;
324 maxTxAzimuth = azimuthTx;
325 maxRxAzimuth = azimuthRx;
326 maxTxZenith = zenithTx;
327 maxRxZenith = zenithRx;
328 maxTxW = txW;
329 maxRxW = rxW;
330 }
331 }
332 }
333 }
334 }
335
337 std::make_pair(maxTxW, BeamId(static_cast<uint16_t>(maxTxAzimuth), maxTxZenith)));
339 std::make_pair(maxRxW, BeamId(static_cast<uint16_t>(maxRxAzimuth), maxRxZenith)));
340
341 NS_LOG_DEBUG("Beamforming vectors for gNB with node id: "
342 << gnbSpectrumPhy->GetMobility()->GetObject<Node>()->GetId()
343 << " and UE with node id: "
344 << ueSpectrumPhy->GetMobility()->GetObject<Node>()->GetId() << " are azimuthTx "
345 << maxTxAzimuth << " zenithTx " << maxTxZenith << " azimuthRx " << maxRxAzimuth
346 << " zenithRx " << maxRxZenith);
347
348 NS_ASSERT(maxTxW.GetSize() && maxRxW.GetSize());
349
350 return BeamformingVectorPair(std::make_pair(gnbBfv, ueBfv));
351}
352
353TypeId
355{
356 static TypeId tid =
357 TypeId("ns3::CellScanQuasiOmniBeamforming")
358 .SetParent<IdealBeamformingAlgorithm>()
359 .AddConstructor<CellScanQuasiOmniBeamforming>()
360 .AddAttribute("BeamSearchAngleStep",
361 "Angle step when searching for the best beam",
362 DoubleValue(30),
365 MakeDoubleChecker<double>());
366
367 return tid;
368}
369
370void
372{
373 m_beamSearchAngleStep = beamSearchAngleStep;
374}
375
376double
378{
379 return m_beamSearchAngleStep;
380}
381
382BeamformingVectorPair
383CellScanQuasiOmniBeamforming::GetBeamformingVectors(const Ptr<NrSpectrumPhy>& gnbSpectrumPhy,
384 const Ptr<NrSpectrumPhy>& ueSpectrumPhy) const
385{
386 NS_ABORT_MSG_IF(gnbSpectrumPhy == nullptr || ueSpectrumPhy == nullptr,
387 "Something went wrong, gnb or UE PHY layer not set.");
388 double distance = gnbSpectrumPhy->GetMobility()->GetDistanceFrom(ueSpectrumPhy->GetMobility());
389 NS_ABORT_MSG_IF(distance == 0,
390 "Beamforming method cannot be performed between two devices that are placed in "
391 "the same position.");
392
393 Ptr<const PhasedArraySpectrumPropagationLossModel> txThreeGppSpectrumPropModel =
394 gnbSpectrumPhy->GetSpectrumChannel()->GetPhasedArraySpectrumPropagationLossModel();
395 Ptr<const PhasedArraySpectrumPropagationLossModel> rxThreeGppSpectrumPropModel =
396 ueSpectrumPhy->GetSpectrumChannel()->GetPhasedArraySpectrumPropagationLossModel();
397 NS_ASSERT_MSG(txThreeGppSpectrumPropModel == rxThreeGppSpectrumPropModel,
398 "Devices should be connected to the same spectrum channel");
399
400 std::vector<int> activeRbs;
401 for (size_t rbId = 0; rbId < gnbSpectrumPhy->GetRxSpectrumModel()->GetNumBands(); rbId++)
402 {
403 activeRbs.push_back(rbId);
404 }
405
406 Ptr<const SpectrumValue> fakePsd = NrSpectrumValueHelper::CreateTxPowerSpectralDensity(
407 0.0,
408 activeRbs,
409 gnbSpectrumPhy->GetRxSpectrumModel(),
410 NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_BW);
411 Ptr<SpectrumSignalParameters> fakeParams = Create<SpectrumSignalParameters>();
412 fakeParams->psd = fakePsd->Copy();
413
414 double max = 0;
415 double maxTxTheta = 0;
416 uint16_t maxTxSector = 0;
417 PhasedArrayModel::ComplexVector maxTxW;
418
419 UintegerValue uintValue;
420 gnbSpectrumPhy->GetAntenna()->GetAttribute("NumRows", uintValue);
421 uint32_t txNumRows = static_cast<uint32_t>(uintValue.Get());
422
423 ueSpectrumPhy->GetBeamManager()
424 ->ChangeToQuasiOmniBeamformingVector(); // we have to set it immediately to q-omni so that
425 // we can perform calculations when calling spectrum
426 // model above
427
428 PhasedArrayModel::ComplexVector rxW =
429 ueSpectrumPhy->GetBeamManager()->GetCurrentBeamformingVector();
430 BeamformingVector ueBfv = std::make_pair(rxW, OMNI_BEAM_ID);
431
432 uint16_t numRows = static_cast<uint16_t>(txNumRows);
433 for (double txTheta = 60; txTheta < 121; txTheta = txTheta + m_beamSearchAngleStep)
434 {
435 for (uint16_t txSector = 0; txSector <= numRows; txSector++)
436 {
437 NS_ASSERT(txSector < UINT16_MAX);
438
439 gnbSpectrumPhy->GetBeamManager()->SetSector(txSector, txTheta);
440 PhasedArrayModel::ComplexVector txW =
441 gnbSpectrumPhy->GetBeamManager()->GetCurrentBeamformingVector();
442
443 NS_ABORT_MSG_IF(txW.GetSize() == 0 || rxW.GetSize() == 0,
444 "Beamforming vectors must be initialized in order to calculate the "
445 "long term matrix.");
446 Ptr<SpectrumSignalParameters> rxParams =
447 txThreeGppSpectrumPropModel->CalcRxPowerSpectralDensity(
448 fakeParams,
449 gnbSpectrumPhy->GetMobility(),
450 ueSpectrumPhy->GetMobility(),
451 gnbSpectrumPhy->GetAntenna()->GetObject<PhasedArrayModel>(),
452 ueSpectrumPhy->GetAntenna()->GetObject<PhasedArrayModel>());
453
454 size_t nbands = rxParams->psd->GetSpectrumModel()->GetNumBands();
455 double power = Sum(*(rxParams->psd)) / nbands;
456
457 NS_LOG_LOGIC(" Rx power: "
458 << power << "txTheta " << txTheta << " tx sector "
459 << (M_PI * static_cast<double>(txSector) / static_cast<double>(txNumRows) -
460 0.5 * M_PI) /
461 M_PI * 180);
462
463 if (max < power)
464 {
465 max = power;
466 maxTxSector = txSector;
467 maxTxTheta = txTheta;
468 maxTxW = txW;
469 }
470 }
471 }
472
473 BeamformingVector gnbBfv =
474 BeamformingVector(std::make_pair(maxTxW, BeamId(maxTxSector, maxTxTheta)));
475
476 NS_LOG_DEBUG(
477 "Beamforming vectors for gNB with node id: "
478 << gnbSpectrumPhy->GetMobility()->GetObject<Node>()->GetId()
479 << " and UE with node id: " << ueSpectrumPhy->GetMobility()->GetObject<Node>()->GetId()
480 << " are txTheta " << maxTxTheta << " tx sector "
481 << (M_PI * static_cast<double>(maxTxSector) / static_cast<double>(txNumRows) - 0.5 * M_PI) /
482 M_PI * 180);
483
484 return BeamformingVectorPair(std::make_pair(gnbBfv, ueBfv));
485}
486
487TypeId
489{
490 static TypeId tid = TypeId("ns3::DirectPathBeamforming")
491 .SetParent<IdealBeamformingAlgorithm>()
492 .AddConstructor<DirectPathBeamforming>();
493 return tid;
494}
495
496BeamformingVectorPair
497DirectPathBeamforming::GetBeamformingVectors(const Ptr<NrSpectrumPhy>& gnbSpectrumPhy,
498 const Ptr<NrSpectrumPhy>& ueSpectrumPhy) const
499{
500 NS_LOG_FUNCTION(this);
501
502 Ptr<const UniformPlanarArray> gnbAntenna =
503 gnbSpectrumPhy->GetAntenna()->GetObject<UniformPlanarArray>();
504 Ptr<const UniformPlanarArray> ueAntenna =
505 ueSpectrumPhy->GetAntenna()->GetObject<UniformPlanarArray>();
506
507 PhasedArrayModel::ComplexVector gNbAntennaWeights =
508 CreateDirectPathBfv(gnbSpectrumPhy->GetMobility(),
509 ueSpectrumPhy->GetMobility(),
510 gnbAntenna);
511 // store the antenna weights
512 BeamformingVector gnbBfv =
513 BeamformingVector(std::make_pair(gNbAntennaWeights, BeamId::GetEmptyBeamId()));
514
515 PhasedArrayModel::ComplexVector ueAntennaWeights =
516 CreateDirectPathBfv(ueSpectrumPhy->GetMobility(), gnbSpectrumPhy->GetMobility(), ueAntenna);
517 // store the antenna weights
518 BeamformingVector ueBfv =
519 BeamformingVector(std::make_pair(ueAntennaWeights, BeamId::GetEmptyBeamId()));
520
521 return BeamformingVectorPair(std::make_pair(gnbBfv, ueBfv));
522}
523
524TypeId
526{
527 static TypeId tid = TypeId("ns3::QuasiOmniDirectPathBeamforming")
528 .SetParent<DirectPathBeamforming>()
529 .AddConstructor<QuasiOmniDirectPathBeamforming>();
530 return tid;
531}
532
533BeamformingVectorPair
534QuasiOmniDirectPathBeamforming::GetBeamformingVectors(const Ptr<NrSpectrumPhy>& gnbSpectrumPhy,
535 const Ptr<NrSpectrumPhy>& ueSpectrumPhy) const
536{
537 NS_LOG_FUNCTION(this);
538 Ptr<const UniformPlanarArray> gnbAntenna =
539 gnbSpectrumPhy->GetAntenna()->GetObject<UniformPlanarArray>();
540 Ptr<const UniformPlanarArray> ueAntenna =
541 ueSpectrumPhy->GetAntenna()->GetObject<UniformPlanarArray>();
542
543 // configure gNb beamforming vector to be quasi omni
544 UintegerValue numRows;
545 UintegerValue numColumns;
546 gnbAntenna->GetAttribute("NumRows", numRows);
547 gnbAntenna->GetAttribute("NumColumns", numColumns);
548 BeamformingVector gnbBfv = {CreateQuasiOmniBfv(gnbAntenna), OMNI_BEAM_ID};
549
550 // configure UE beamforming vector to be directed towards gNB
551 PhasedArrayModel::ComplexVector ueAntennaWeights =
552 CreateDirectPathBfv(ueSpectrumPhy->GetMobility(), gnbSpectrumPhy->GetMobility(), ueAntenna);
553 // store the antenna weights
554 BeamformingVector ueBfv = BeamformingVector({ueAntennaWeights, BeamId::GetEmptyBeamId()});
555 return BeamformingVectorPair(std::make_pair(gnbBfv, ueBfv));
556}
557
558TypeId
560{
561 static TypeId tid = TypeId("ns3::DirectPathQuasiOmniBeamforming")
562 .SetParent<DirectPathBeamforming>()
563 .AddConstructor<DirectPathQuasiOmniBeamforming>();
564 return tid;
565}
566
567BeamformingVectorPair
568DirectPathQuasiOmniBeamforming::GetBeamformingVectors(const Ptr<NrSpectrumPhy>& gnbSpectrumPhy,
569 const Ptr<NrSpectrumPhy>& ueSpectrumPhy) const
570{
571 NS_LOG_FUNCTION(this);
572 Ptr<const UniformPlanarArray> gnbAntenna =
573 gnbSpectrumPhy->GetAntenna()->GetObject<UniformPlanarArray>();
574 Ptr<const UniformPlanarArray> ueAntenna =
575 ueSpectrumPhy->GetAntenna()->GetObject<UniformPlanarArray>();
576
577 // configure ue beamforming vector to be quasi omni
578 UintegerValue numRows;
579 UintegerValue numColumns;
580 ueAntenna->GetAttribute("NumRows", numRows);
581 ueAntenna->GetAttribute("NumColumns", numColumns);
583
584 // configure gNB beamforming vector to be directed towards UE
585 PhasedArrayModel::ComplexVector gnbAntennaWeights =
586 CreateDirectPathBfv(gnbSpectrumPhy->GetMobility(),
587 ueSpectrumPhy->GetMobility(),
588 gnbAntenna);
589 // store the antenna weights
590 BeamformingVector gnbBfv = {gnbAntennaWeights, BeamId::GetEmptyBeamId()};
591
592 return BeamformingVectorPair(std::make_pair(gnbBfv, ueBfv));
593}
594
595TypeId
597{
598 static TypeId tid = TypeId("ns3::OptimalCovMatrixBeamforming")
599 .SetParent<IdealBeamformingAlgorithm>()
600 .AddConstructor<OptimalCovMatrixBeamforming>();
601
602 return tid;
603}
604
605BeamformingVectorPair
607 [[maybe_unused]] const Ptr<NrSpectrumPhy>& gnbSpectrumPhy,
608 [[maybe_unused]] const Ptr<NrSpectrumPhy>& ueSpectrumPhy) const
609{
610 NS_LOG_FUNCTION(this);
611 return BeamformingVectorPair();
612}
613
614} // namespace ns3
Representation of a beam id.
Definition beam-id.h:26
BeamformingVectorPair GetBeamformingVectors(const Ptr< NrSpectrumPhy > &gnbSpectrumPhy, const Ptr< NrSpectrumPhy > &ueSpectrumPhy) const override
Function that generates the beamforming vectors for a pair of communicating devices by using cell sca...
void SetBeamSearchAngleStep(double beamSearchAngleStep)
Sets the value of BeamSearchAngleStep attribute.
BeamformingVectorPair GetBeamformingVectors(const Ptr< NrSpectrumPhy > &gnbSpectrumPhy, const Ptr< NrSpectrumPhy > &ueSpectrumPhy) const override
Function that generates the beamforming vectors for a pair of communicating devices by using cell sca...
static TypeId GetTypeId()
Get the type id.
void SetBeamSearchAngleStep(double beamSearchAngleStep)
Sets the value of BeamSearchAngleStep attribute.
BeamformingVectorPair GetBeamformingVectors(const Ptr< NrSpectrumPhy > &gnbSpectrumPhy, const Ptr< NrSpectrumPhy > &ueSpectrumPhy) const override
Function that generates the beamforming vectors for a pair of communicating devices by using cell sca...
static TypeId GetTypeId()
Get the type id.
The DirectPathBeamforming class.
BeamformingVectorPair GetBeamformingVectors(const Ptr< NrSpectrumPhy > &gnbSpectrumPhy, const Ptr< NrSpectrumPhy > &ueSpectrumPhy) const override
Function that generates the beamforming vectors for a pair of communicating devices by using the dire...
static TypeId GetTypeId()
Get the type id.
BeamformingVectorPair GetBeamformingVectors(const Ptr< NrSpectrumPhy > &gnbSpectrumPhy, const Ptr< NrSpectrumPhy > &ueSpectrumPhy) const override
Function that generates the beamforming vectors for a pair of communicating devices by using the dire...
Generate "Ideal" beamforming vectors.
static TypeId GetTypeId()
Get the type id.
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...
static TypeId GetTypeId()
Get the type id.
BeamformingVectorPair GetBeamformingVectors(const Ptr< NrSpectrumPhy > &gnbSpectrumPhy, const Ptr< NrSpectrumPhy > &ueSpectrumPhy) const override
Function that generates the beamforming vectors for a pair of communicating devices by using the dire...
BeamformingVectorPair GetBeamformingVectors(const Ptr< NrSpectrumPhy > &gnbSpectrumPhy, const Ptr< NrSpectrumPhy > &ueSpectrumPhy) const override
Function that generates the beamforming vectors for a pair of communicating devices by using the quas...
std::pair< PhasedArrayModel::ComplexVector, BeamId > BeamformingVector
Physical representation of a beam.
const BeamId OMNI_BEAM_ID
Name of the OMNI beam.
Definition beam-id.cc:9
PhasedArrayModel::ComplexVector CreateQuasiOmniBfv(const Ptr< const UniformPlanarArray > &antenna)
Create a quasi omni beamforming vector.