66 const Ptr<NrSpectrumPhy>& ueSpectrumPhy)
const
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.");
75 Ptr<SpectrumChannel> gnbSpectrumChannel =
77 ->GetSpectrumChannel();
78 Ptr<SpectrumChannel> ueSpectrumChannel = ueSpectrumPhy->GetSpectrumChannel();
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");
87 std::vector<int> activeRbs;
88 for (
size_t rbId = 0; rbId < gnbSpectrumPhy->GetRxSpectrumModel()->GetNumBands(); rbId++)
90 activeRbs.push_back(rbId);
96 gnbSpectrumPhy->GetRxSpectrumModel(),
97 NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_BW);
98 Ptr<SpectrumSignalParameters> fakeParams = Create<SpectrumSignalParameters>();
99 fakeParams->psd = fakePsd->Copy();
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;
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());
115 NS_ASSERT(gnbSpectrumPhy->GetAntenna()->GetObject<PhasedArrayModel>()->GetNumElems() &&
116 ueSpectrumPhy->GetAntenna()->GetObject<PhasedArrayModel>()->GetNumElems());
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)
122 for (uint16_t txSector = 0; txSector <= numRowsTx; txSector++)
124 NS_ASSERT(txSector < UINT16_MAX);
126 gnbSpectrumPhy->GetBeamManager()->SetSector(txSector, txTheta);
127 PhasedArrayModel::ComplexVector txW =
128 gnbSpectrumPhy->GetBeamManager()->GetCurrentBeamformingVector();
130 if (maxTxW.GetSize() == 0)
135 for (
double rxTheta = 60; rxTheta < 121;
136 rxTheta =
static_cast<uint16_t
>(rxTheta + m_beamSearchAngleStep))
138 for (uint16_t rxSector = 0; rxSector <= numRowsRx; rxSector++)
140 NS_ASSERT(rxSector < UINT16_MAX);
142 ueSpectrumPhy->GetBeamManager()->SetSector(rxSector, rxTheta);
143 PhasedArrayModel::ComplexVector rxW =
144 ueSpectrumPhy->GetBeamManager()->GetCurrentBeamformingVector();
146 if (maxRxW.GetSize() == 0)
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.");
155 Ptr<SpectrumSignalParameters> rxParams =
156 gnbThreeGppSpectrumPropModel->CalcRxPowerSpectralDensity(
158 gnbSpectrumPhy->GetMobility(),
159 ueSpectrumPhy->GetMobility(),
160 gnbSpectrumPhy->GetAntenna()->GetObject<PhasedArrayModel>(),
161 ueSpectrumPhy->GetAntenna()->GetObject<PhasedArrayModel>());
163 size_t nbands = rxParams->psd->GetSpectrumModel()->GetNumBands();
164 double power = Sum(*(rxParams->psd)) / nbands;
168 << power <<
"txTheta " << txTheta <<
" rxTheta " << rxTheta <<
" tx sector "
169 << (M_PI *
static_cast<double>(txSector) /
static_cast<double>(txNumRows) -
173 << (M_PI *
static_cast<double>(rxSector) /
static_cast<double>(rxNumRows) -
180 maxTxSector = txSector;
181 maxRxSector = rxSector;
182 maxTxTheta = txTheta;
183 maxRxTheta = rxTheta;
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) /
205 << (M_PI *
static_cast<double>(maxRxSector) /
static_cast<double>(rxNumRows) - 0.5 * M_PI) /
208 NS_ASSERT(maxTxW.GetSize() && maxRxW.GetSize());
210 return BeamformingVectorPair(std::make_pair(gnbBfv, ueBfv));
225 const Ptr<NrSpectrumPhy>& gnbSpectrumPhy,
226 const Ptr<NrSpectrumPhy>& ueSpectrumPhy)
const
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.");
235 Ptr<SpectrumChannel> gnbSpectrumChannel =
237 ->GetSpectrumChannel();
238 Ptr<SpectrumChannel> ueSpectrumChannel = ueSpectrumPhy->GetSpectrumChannel();
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");
247 std::vector<int> activeRbs;
248 for (
size_t rbId = 0; rbId < gnbSpectrumPhy->GetRxSpectrumModel()->GetNumBands(); rbId++)
250 activeRbs.push_back(rbId);
256 gnbSpectrumPhy->GetRxSpectrumModel(),
257 NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_BW);
258 Ptr<SpectrumSignalParameters> fakeParams = Create<SpectrumSignalParameters>();
259 fakeParams->psd = fakePsd->Copy();
262 double maxTxAzimuth = 0;
263 double maxRxAzimuth = 0;
264 double maxTxZenith = 0;
265 double maxRxZenith = 0;
266 PhasedArrayModel::ComplexVector maxTxW;
267 PhasedArrayModel::ComplexVector maxRxW;
269 UintegerValue uintValue;
270 gnbSpectrumPhy->GetAntenna()->GetAttribute(
"NumRows", uintValue);
271 ueSpectrumPhy->GetAntenna()->GetAttribute(
"NumRows", uintValue);
273 NS_ASSERT(gnbSpectrumPhy->GetAntenna()->GetObject<PhasedArrayModel>()->GetNumElems() &&
274 ueSpectrumPhy->GetAntenna()->GetObject<PhasedArrayModel>()->GetNumElems());
276 for (
double azimuthTx : m_azimuth)
278 for (
double zenithTx : m_zenith)
280 gnbSpectrumPhy->GetBeamManager()->SetSectorAz(azimuthTx, zenithTx);
281 PhasedArrayModel::ComplexVector txW =
282 gnbSpectrumPhy->GetBeamManager()->GetCurrentBeamformingVector();
284 if (maxTxW.GetSize() == 0)
289 for (
double azimuthRx : m_azimuth)
291 for (
double zenithRx : m_zenith)
293 ueSpectrumPhy->GetBeamManager()->SetSectorAz(azimuthRx, zenithRx);
294 PhasedArrayModel::ComplexVector rxW =
295 ueSpectrumPhy->GetBeamManager()->GetCurrentBeamformingVector();
297 if (maxRxW.GetSize() == 0)
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.");
306 Ptr<SpectrumSignalParameters> rxParams =
307 gnbThreeGppSpectrumPropModel->CalcRxPowerSpectralDensity(
309 gnbSpectrumPhy->GetMobility(),
310 ueSpectrumPhy->GetMobility(),
311 gnbSpectrumPhy->GetAntenna()->GetObject<PhasedArrayModel>(),
312 ueSpectrumPhy->GetAntenna()->GetObject<PhasedArrayModel>());
314 size_t nbands = rxParams->psd->GetSpectrumModel()->GetNumBands();
315 double power = Sum(*rxParams->psd) / nbands;
317 NS_LOG_LOGIC(
" Rx power: " << power <<
" azimuthTx " << azimuthTx
318 <<
" zenithTx " << zenithTx <<
" azimuthRx "
319 << azimuthRx <<
" zenithRx " << zenithRx);
324 maxTxAzimuth = azimuthTx;
325 maxRxAzimuth = azimuthRx;
326 maxTxZenith = zenithTx;
327 maxRxZenith = zenithRx;
337 std::make_pair(maxTxW,
BeamId(
static_cast<uint16_t
>(maxTxAzimuth), maxTxZenith)));
339 std::make_pair(maxRxW,
BeamId(
static_cast<uint16_t
>(maxRxAzimuth), maxRxZenith)));
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);
348 NS_ASSERT(maxTxW.GetSize() && maxRxW.GetSize());
350 return BeamformingVectorPair(std::make_pair(gnbBfv, ueBfv));
384 const Ptr<NrSpectrumPhy>& ueSpectrumPhy)
const
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.");
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");
400 std::vector<int> activeRbs;
401 for (
size_t rbId = 0; rbId < gnbSpectrumPhy->GetRxSpectrumModel()->GetNumBands(); rbId++)
403 activeRbs.push_back(rbId);
409 gnbSpectrumPhy->GetRxSpectrumModel(),
410 NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_BW);
411 Ptr<SpectrumSignalParameters> fakeParams = Create<SpectrumSignalParameters>();
412 fakeParams->psd = fakePsd->Copy();
415 double maxTxTheta = 0;
416 uint16_t maxTxSector = 0;
417 PhasedArrayModel::ComplexVector maxTxW;
419 UintegerValue uintValue;
420 gnbSpectrumPhy->GetAntenna()->GetAttribute(
"NumRows", uintValue);
421 uint32_t txNumRows =
static_cast<uint32_t
>(uintValue.Get());
423 ueSpectrumPhy->GetBeamManager()
424 ->ChangeToQuasiOmniBeamformingVector();
428 PhasedArrayModel::ComplexVector rxW =
429 ueSpectrumPhy->GetBeamManager()->GetCurrentBeamformingVector();
432 uint16_t numRows =
static_cast<uint16_t
>(txNumRows);
433 for (
double txTheta = 60; txTheta < 121; txTheta = txTheta + m_beamSearchAngleStep)
435 for (uint16_t txSector = 0; txSector <= numRows; txSector++)
437 NS_ASSERT(txSector < UINT16_MAX);
439 gnbSpectrumPhy->GetBeamManager()->SetSector(txSector, txTheta);
440 PhasedArrayModel::ComplexVector txW =
441 gnbSpectrumPhy->GetBeamManager()->GetCurrentBeamformingVector();
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(
449 gnbSpectrumPhy->GetMobility(),
450 ueSpectrumPhy->GetMobility(),
451 gnbSpectrumPhy->GetAntenna()->GetObject<PhasedArrayModel>(),
452 ueSpectrumPhy->GetAntenna()->GetObject<PhasedArrayModel>());
454 size_t nbands = rxParams->psd->GetSpectrumModel()->GetNumBands();
455 double power = Sum(*(rxParams->psd)) / nbands;
457 NS_LOG_LOGIC(
" Rx power: "
458 << power <<
"txTheta " << txTheta <<
" tx sector "
459 << (M_PI *
static_cast<double>(txSector) /
static_cast<double>(txNumRows) -
466 maxTxSector = txSector;
467 maxTxTheta = txTheta;
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) /
484 return BeamformingVectorPair(std::make_pair(gnbBfv, ueBfv));
498 const Ptr<NrSpectrumPhy>& ueSpectrumPhy)
const
500 NS_LOG_FUNCTION(
this);
502 Ptr<const UniformPlanarArray> gnbAntenna =
503 gnbSpectrumPhy->GetAntenna()->GetObject<UniformPlanarArray>();
504 Ptr<const UniformPlanarArray> ueAntenna =
505 ueSpectrumPhy->GetAntenna()->GetObject<UniformPlanarArray>();
507 PhasedArrayModel::ComplexVector gNbAntennaWeights =
508 CreateDirectPathBfv(gnbSpectrumPhy->GetMobility(),
509 ueSpectrumPhy->GetMobility(),
515 PhasedArrayModel::ComplexVector ueAntennaWeights =
516 CreateDirectPathBfv(ueSpectrumPhy->GetMobility(), gnbSpectrumPhy->GetMobility(), ueAntenna);
521 return BeamformingVectorPair(std::make_pair(gnbBfv, ueBfv));
535 const Ptr<NrSpectrumPhy>& ueSpectrumPhy)
const
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>();
544 UintegerValue numRows;
545 UintegerValue numColumns;
546 gnbAntenna->GetAttribute(
"NumRows", numRows);
547 gnbAntenna->GetAttribute(
"NumColumns", numColumns);
551 PhasedArrayModel::ComplexVector ueAntennaWeights =
552 CreateDirectPathBfv(ueSpectrumPhy->GetMobility(), gnbSpectrumPhy->GetMobility(), ueAntenna);
555 return BeamformingVectorPair(std::make_pair(gnbBfv, ueBfv));
569 const Ptr<NrSpectrumPhy>& ueSpectrumPhy)
const
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>();
578 UintegerValue numRows;
579 UintegerValue numColumns;
580 ueAntenna->GetAttribute(
"NumRows", numRows);
581 ueAntenna->GetAttribute(
"NumColumns", numColumns);
585 PhasedArrayModel::ComplexVector gnbAntennaWeights =
586 CreateDirectPathBfv(gnbSpectrumPhy->GetMobility(),
587 ueSpectrumPhy->GetMobility(),
592 return BeamformingVectorPair(std::make_pair(gnbBfv, ueBfv));