5#include "ns3/antenna-module.h"
6#include "ns3/applications-module.h"
7#include "ns3/config-store-module.h"
8#include "ns3/core-module.h"
9#include "ns3/internet-module.h"
10#include "ns3/mobility-module.h"
11#include "ns3/nr-eps-bearer-tag.h"
12#include "ns3/nr-module.h"
13#include "ns3/point-to-point-helper.h"
69NS_LOG_COMPONENT_DEFINE(
"Nr3gppIndoorCalibration");
71struct DroppingParameters
73 bool ueAntennaPolarization;
74 bool gnbAntennaPolarization;
75 uint8_t numVPortsGnb = 1;
76 uint8_t numHPortsGnb = 1;
77 uint8_t numVPortsUe = 1;
78 uint8_t numHPortsUe = 1;
80 : ueAntennaPolarization(false),
81 gnbAntennaPolarization(false){};
82 DroppingParameters(
bool isUePolarized,
bool isGnbPolarized)
83 : ueAntennaPolarization(isUePolarized),
84 gnbAntennaPolarization(isGnbPolarized){};
85 DroppingParameters(
bool isUePolarized,
bool isGnbPolarized, uint8_t nVGnb, uint8_t nHGnb)
86 : ueAntennaPolarization(isUePolarized),
87 gnbAntennaPolarization(isGnbPolarized),
89 numHPortsGnb(nHGnb){};
90 DroppingParameters(
bool isUePolarized,
96 : ueAntennaPolarization(isUePolarized),
97 gnbAntennaPolarization(isGnbPolarized),
107class Nr3gppIndoorCalibration
125 void UeSnrPerProcessedChunk(
double snr);
131 void UeRssiPerProcessedChunk(
double rssidBm);
156 void Run(
double centralFrequencyBand,
157 double bandwidthBand,
161 double beamSearchAngleStep,
162 bool gNbAntennaModel,
164 std::string indoorScenario,
166 std::string resultsDirPath,
169 DroppingParameters dropParam = DroppingParameters());
174 ~Nr3gppIndoorCalibration();
185 NodeContainer SelectWellPlacedUes(
const NodeContainer ueNodes,
186 const NodeContainer gnbNodes,
187 double min3DDistance,
188 uint32_t numberOfUesToBeSelected);
191 std::ofstream m_outSinrFile;
192 std::ofstream m_outSnrFile;
193 std::ofstream m_outRssiFile;
194 std::ofstream m_outUePositionsFile;
195 std::ofstream m_outGnbPositionsFile;
196 std::ofstream m_outDistancesFile;
211 std::ostringstream oss;
212 oss << directoryName << filePrefix << tag;
227BuildTag(
bool gNbAntennaModel,
bool ueAntennaModel, std::string scenario,
double speed)
229 std::ostringstream oss;
253 oss <<
"-ao" << ao <<
"-amGnb" << gnbAm <<
"-amUE" << ueAm <<
"-sc" << scenario <<
"-sp"
254 << speed <<
"-gm" << gm;
267 scenario->UeReception(params);
278 scenario->UeSnrPerProcessedChunk(snr);
289 scenario->UeRssiPerProcessedChunk(rssidBm);
295 m_outSinrFile << params.m_cellId << params.m_rnti <<
"\t" << 10 * log10(params.m_sinr)
300Nr3gppIndoorCalibration::UeSnrPerProcessedChunk(
double snr)
302 m_outSnrFile << 10 * log10(snr) << std::endl;
306Nr3gppIndoorCalibration::UeRssiPerProcessedChunk(
double rssidBm)
308 m_outRssiFile << rssidBm << std::endl;
311Nr3gppIndoorCalibration::~Nr3gppIndoorCalibration()
313 m_outSinrFile.close();
314 m_outSnrFile.close();
315 m_outRssiFile.close();
319Nr3gppIndoorCalibration::SelectWellPlacedUes(
const NodeContainer ueNodes,
320 const NodeContainer gnbNodes,
322 uint32_t numberOfUesToBeSelected)
324 NodeContainer ueNodesFiltered;
325 bool correctDistance =
true;
327 for (NodeContainer::Iterator itUe = ueNodes.Begin(); itUe != ueNodes.End(); itUe++)
329 correctDistance =
true;
330 Ptr<MobilityModel> ueMm = (*itUe)->GetObject<MobilityModel>();
331 Vector uePos = ueMm->GetPosition();
333 for (NodeContainer::Iterator itGnb = gnbNodes.Begin(); itGnb != gnbNodes.End(); itGnb++)
335 Ptr<MobilityModel> gnbMm = (*itGnb)->GetObject<MobilityModel>();
336 Vector gnbPos = gnbMm->GetPosition();
337 double x = uePos.x - gnbPos.x;
338 double y = uePos.y - gnbPos.y;
339 double distance = sqrt(x * x + y * y);
341 if (distance < minDistance)
343 correctDistance =
false;
349 m_outDistancesFile << distance << std::endl;
355 ueNodesFiltered.Add(*itUe);
357 if (ueNodesFiltered.GetN() >= numberOfUesToBeSelected)
363 return ueNodesFiltered;
367Nr3gppIndoorCalibration::Run(
double centralFrequencyBand,
368 double bandwidthBand,
372 double beamSearchAngleStep,
373 bool gNbAntennaModel,
375 std::string indoorScenario,
377 std::string resultsDirPath,
380 DroppingParameters dropParam)
382 Time simTime = MilliSeconds(duration);
383 Time udpAppStartTimeDl = MilliSeconds(100);
384 Time udpAppStopTimeDl = MilliSeconds(duration);
385 uint32_t packetSize = 1000;
386 DataRate udpRate = DataRate(
"0.1kbps");
389 uint16_t ueCount = 240;
391 double minDistance = 0;
393 double gNbHeight = 3;
395 double ueHeight = 1.5;
397 NS_ABORT_MSG_UNLESS(indoorScenario ==
"InH-OfficeOpen" || indoorScenario ==
"InH-OfficeMixed",
398 "The scenario is not supported");
403 tag =
BuildTag(gNbAntennaModel, ueAntennaModel, indoorScenario, speed);
408 std::string filenameUePositions =
BuildFileNameString(resultsDirPath,
"ue-positions", tag);
409 std::string filenameGnbPositions =
BuildFileNameString(resultsDirPath,
"gnb-positions", tag);
412 m_outSinrFile.open(filenameSinr.c_str());
413 m_outSinrFile.setf(std::ios_base::fixed);
415 if (!m_outSinrFile.is_open())
417 NS_ABORT_MSG(
"Can't open file " << filenameSinr);
420 m_outSnrFile.open(filenameSnr.c_str());
421 m_outSnrFile.setf(std::ios_base::fixed);
423 if (!m_outSnrFile.is_open())
425 NS_ABORT_MSG(
"Can't open file " << filenameSnr);
428 m_outRssiFile.open(filenameRssi.c_str());
429 m_outRssiFile.setf(std::ios_base::fixed);
431 if (!m_outRssiFile.is_open())
433 NS_ABORT_MSG(
"Can't open file " << filenameRssi);
436 m_outUePositionsFile.open(filenameUePositions.c_str());
437 m_outUePositionsFile.setf(std::ios_base::fixed);
439 if (!m_outUePositionsFile.is_open())
441 NS_ABORT_MSG(
"Can't open file " << filenameUePositions);
444 m_outGnbPositionsFile.open(filenameGnbPositions.c_str());
445 m_outGnbPositionsFile.setf(std::ios_base::fixed);
447 if (!m_outGnbPositionsFile.is_open())
449 NS_ABORT_MSG(
"Can't open file " << filenameGnbPositions);
452 m_outDistancesFile.open(filenameDistances.c_str());
453 m_outDistancesFile.setf(std::ios_base::fixed);
455 if (!m_outDistancesFile.is_open())
457 NS_ABORT_MSG(
"Can't open file " << filenameDistances);
461 NodeContainer gNbNodes;
462 NodeContainer ueNodes;
463 MobilityHelper mobility;
466 ueNodes.Create(ueCount);
469 Ptr<ListPositionAllocator> gNbPositionAlloc = CreateObject<ListPositionAllocator>();
471 for (uint8_t j = 0; j < 2; j++)
473 for (uint8_t i = 0; i < 6; i++)
475 gNbPositionAlloc->Add(Vector(i * 20, j * 20, gNbHeight));
479 mobility.SetMobilityModel(
"ns3::ConstantPositionMobilityModel");
480 mobility.SetPositionAllocator(gNbPositionAlloc);
481 mobility.Install(gNbNodes);
483 double minBigBoxX = -10.0;
484 double minBigBoxY = -15.0;
485 double maxBigBoxX = 110.0;
486 double maxBigBoxY = 35.0;
491 NodeContainer selectedUeNodes;
492 for (uint8_t j = 0; j < 2; j++)
494 double minSmallBoxY = minBigBoxY + j * (maxBigBoxY - minBigBoxY) / 2;
496 for (uint8_t i = 0; i < 6; i++)
498 double minSmallBoxX = minBigBoxX + i * (maxBigBoxX - minBigBoxX) / 6;
499 Ptr<UniformRandomVariable> ueRandomVarX = CreateObject<UniformRandomVariable>();
501 double minX = minSmallBoxX;
502 double maxX = minSmallBoxX + (maxBigBoxX - minBigBoxX) / 6 - 0.0001;
503 double minY = minSmallBoxY;
504 double maxY = minSmallBoxY + (maxBigBoxY - minBigBoxY) / 2 - 0.0001;
506 Ptr<RandomBoxPositionAllocator> ueRandomRectPosAlloc =
507 CreateObject<RandomBoxPositionAllocator>();
508 ueRandomVarX->SetAttribute(
"Min", DoubleValue(minX));
509 ueRandomVarX->SetAttribute(
"Max", DoubleValue(maxX));
510 ueRandomRectPosAlloc->SetX(ueRandomVarX);
511 Ptr<UniformRandomVariable> ueRandomVarY = CreateObject<UniformRandomVariable>();
512 ueRandomVarY->SetAttribute(
"Min", DoubleValue(minY));
513 ueRandomVarY->SetAttribute(
"Max", DoubleValue(maxY));
514 ueRandomRectPosAlloc->SetY(ueRandomVarY);
515 Ptr<ConstantRandomVariable> ueRandomVarZ = CreateObject<ConstantRandomVariable>();
516 ueRandomVarZ->SetAttribute(
"Constant", DoubleValue(ueHeight));
517 ueRandomRectPosAlloc->SetZ(ueRandomVarZ);
519 uint8_t smallBoxIndex = j * 6 + i;
521 NodeContainer smallBoxCandidateNodes;
522 NodeContainer smallBoxGnbNode;
524 smallBoxGnbNode.Add(gNbNodes.Get(smallBoxIndex));
526 for (uint32_t n = smallBoxIndex * ueCount / 12;
527 n < smallBoxIndex * static_cast<uint32_t>(ueCount / 12) +
528 static_cast<uint32_t
>(ueCount / 12);
531 smallBoxCandidateNodes.Add(ueNodes.Get(n));
533 mobility.SetPositionAllocator(ueRandomRectPosAlloc);
534 mobility.Install(smallBoxCandidateNodes);
536 SelectWellPlacedUes(smallBoxCandidateNodes, smallBoxGnbNode, minDistance, 10);
537 selectedUeNodes.Add(sn);
541 for (uint32_t j = 0; j < selectedUeNodes.GetN(); j++)
543 Vector v = selectedUeNodes.Get(j)->GetObject<MobilityModel>()->GetPosition();
544 m_outUePositionsFile << j <<
"\t" << v.x <<
"\t" << v.y <<
"\t" << v.z <<
" " << std::endl;
547 for (uint32_t j = 0; j < gNbNodes.GetN(); j++)
549 Vector v = gNbNodes.Get(j)->GetObject<MobilityModel>()->GetPosition();
550 m_outGnbPositionsFile << j <<
"\t" << v.x <<
"\t" << v.y <<
"\t" << v.z <<
" " << std::endl;
553 m_outUePositionsFile.close();
554 m_outGnbPositionsFile.close();
555 m_outDistancesFile.close();
558 Ptr<NrHelper> nrHelper = CreateObject<NrHelper>();
559 Ptr<NrPointToPointEpcHelper> nrEpcHelper = CreateObject<NrPointToPointEpcHelper>();
560 Ptr<IdealBeamformingHelper> idealBeamformingHelper = CreateObject<IdealBeamformingHelper>();
561 Ptr<NrChannelHelper> channelHelper = CreateObject<NrChannelHelper>();
563 nrHelper->SetBeamformingHelper(idealBeamformingHelper);
564 nrHelper->SetEpcHelper(nrEpcHelper);
565 channelHelper->ConfigureFactories(indoorScenario,
"Default",
"ThreeGpp");
582 const uint8_t numCcPerBand = 1;
593 channelHelper->AssignChannelsToBands({band});
600 Config::SetDefault(
"ns3::NrGnbRrc::SrsPeriodicity", UintegerValue(320));
604 idealBeamformingHelper->SetAttribute(
"BeamformingMethod",
606 idealBeamformingHelper->SetBeamformingAlgorithmAttribute(
"BeamSearchAngleStep",
607 DoubleValue(beamSearchAngleStep));
611 idealBeamformingHelper->SetAttribute(
"BeamformingMethod",
615 nrHelper->SetSchedulerTypeId(TypeId::LookupByName(
"ns3::NrMacSchedulerTdmaPF"));
618 nrHelper->SetUeAntennaAttribute(
"NumRows", UintegerValue(2));
619 nrHelper->SetUeAntennaAttribute(
"NumColumns", UintegerValue(4));
623 nrHelper->SetUeAntennaAttribute(
"AntennaElement",
624 PointerValue(CreateObject<IsotropicAntennaModel>()));
628 nrHelper->SetUeAntennaAttribute(
"AntennaElement",
629 PointerValue(CreateObject<ThreeGppAntennaModel>()));
632 nrHelper->SetGnbAntennaAttribute(
"NumRows", UintegerValue(4));
633 nrHelper->SetGnbAntennaAttribute(
"NumColumns", UintegerValue(8));
637 nrHelper->SetGnbAntennaAttribute(
"AntennaElement",
638 PointerValue(CreateObject<IsotropicAntennaModel>()));
642 nrHelper->SetGnbAntennaAttribute(
"AntennaElement",
643 PointerValue(CreateObject<ThreeGppAntennaModel>()));
647 if (dropParam.gnbAntennaPolarization)
649 nrHelper->SetGnbAntennaAttribute(
"IsPolarized", BooleanValue(
true));
651 if (dropParam.ueAntennaPolarization)
653 nrHelper->SetUeAntennaAttribute(
"IsPolarized", BooleanValue(
true));
655 nrHelper->SetGnbAntennaAttribute(
"NumVerticalPorts", UintegerValue(dropParam.numVPortsGnb));
656 nrHelper->SetGnbAntennaAttribute(
"NumHorizontalPorts", UintegerValue(dropParam.numHPortsGnb));
657 nrHelper->SetUeAntennaAttribute(
"NumVerticalPorts", UintegerValue(dropParam.numVPortsUe));
658 nrHelper->SetUeAntennaAttribute(
"NumHorizontalPorts", UintegerValue(dropParam.numHPortsUe));
661 NetDeviceContainer gNbDevs = nrHelper->InstallGnbDevice(gNbNodes, allBwps);
662 NetDeviceContainer ueNetDevs = nrHelper->InstallUeDevice(selectedUeNodes, allBwps);
664 int64_t randomStream = 1;
665 randomStream += nrHelper->AssignStreams(gNbDevs, randomStream);
666 randomStream += nrHelper->AssignStreams(ueNetDevs, randomStream);
668 for (uint32_t i = 0; i < gNbDevs.GetN(); i++)
670 nrHelper->GetGnbPhy(gNbDevs.Get(i), 0)
671 ->SetAttribute(
"Numerology", UintegerValue(numerology));
673 nrHelper->GetGnbPhy(gNbDevs.Get(i), 0)->SetAttribute(
"TxPower", DoubleValue(totalTxPower));
675 nrHelper->GetGnbPhy(gNbDevs.Get(i), 0)->SetAttribute(
"NoiseFigure", DoubleValue(7));
677 for (uint32_t j = 0; j < ueNetDevs.GetN(); j++)
680 nrHelper->GetUePhy(ueNetDevs.Get(j), 0)->SetAttribute(
"NoiseFigure", DoubleValue(10));
685 auto [remoteHost, remoteHostIpv4Address] =
686 nrEpcHelper->SetupRemoteHost(
"100Gb/s", 2500, Seconds(0.000));
688 InternetStackHelper internet;
689 internet.Install(ueNodes);
690 Ipv4InterfaceContainer ueIpIface;
691 ueIpIface = nrEpcHelper->AssignUeIpv4Address(NetDeviceContainer(ueNetDevs));
694 nrHelper->AttachToClosestGnb(ueNetDevs, gNbDevs);
697 uint16_t dlPort = 1234;
698 ApplicationContainer clientAppsDl;
699 ApplicationContainer serverAppsDl;
702 Time::FromDouble((packetSize * 8) /
static_cast<double>(udpRate.GetBitRate()), Time::S);
704 UdpServerHelper dlPacketSinkHelper(dlPort);
705 serverAppsDl.Add(dlPacketSinkHelper.Install(ueNodes));
708 for (uint32_t i = 0; i < ueNetDevs.GetN(); i++)
710 UdpClientHelper dlClient(ueIpIface.GetAddress(i), dlPort);
711 dlClient.SetAttribute(
"MaxPackets", UintegerValue(0xFFFFFFFF));
712 dlClient.SetAttribute(
"PacketSize", UintegerValue(packetSize));
713 dlClient.SetAttribute(
715 TimeValue(udpInterval));
717 clientAppsDl.Add(dlClient.Install(remoteHost));
721 serverAppsDl.Start(udpAppStartTimeDl);
722 clientAppsDl.Start(udpAppStartTimeDl);
724 serverAppsDl.Stop(udpAppStopTimeDl);
725 clientAppsDl.Stop(udpAppStopTimeDl);
727 for (uint32_t i = 0; i < ueNetDevs.GetN(); i++)
729 Ptr<NrSpectrumPhy> ue1SpectrumPhy =
730 DynamicCast<NrUeNetDevice>(ueNetDevs.Get(i))->GetPhy(0)->GetSpectrumPhy();
731 ue1SpectrumPhy->TraceConnectWithoutContext(
"RxPacketTraceUe",
733 Ptr<NrInterference> ue1SpectrumPhyInterference = ue1SpectrumPhy->GetNrInterference();
734 NS_ABORT_IF(!ue1SpectrumPhyInterference);
735 ue1SpectrumPhyInterference->TraceConnectWithoutContext(
736 "SnrPerProcessedChunk",
738 ue1SpectrumPhyInterference->TraceConnectWithoutContext(
739 "RssiPerProcessedChunk",
743 Simulator::Stop(simTime);
745 Simulator::Destroy();
749main(
int argc,
char* argv[])
753 double centralFrequencyBand = 30e9;
754 double bandwidthBand = 40e6;
755 uint16_t numerology = 2;
756 double totalTxPower = 23;
758 uint32_t duration = 150;
759 bool cellScan =
false;
760 double beamSearchAngleStep = 10.0;
761 bool enableGnbIso =
true;
762 bool enableUeIso =
true;
763 std::string indoorScenario =
"InH-OfficeOpen";
765 bool polarizedAntennas =
false;
766 std::string outdir =
"./";
767 std::string simTag =
"";
768 uint8_t numVPortsGnb = 1;
769 uint8_t numHPortsGnb = 1;
770 uint8_t numVPortsUe = 1;
771 uint8_t numHPortsUe = 1;
773 CommandLine cmd(__FILE__);
775 cmd.AddValue(
"duration",
776 "Simulation duration in ms, should be greater than 100 ms to allow the collection "
779 cmd.AddValue(
"cellScan",
780 "Use beam search method to determine beamforming vector,"
781 "true to use cell scanning method",
783 cmd.AddValue(
"beamSearchAngleStep",
784 "Beam search angle step for beam search method",
785 beamSearchAngleStep);
786 cmd.AddValue(
"enableGnbIso",
"Enable Isotropic antenna for the gNB", enableGnbIso);
787 cmd.AddValue(
"enableGnbIso",
"Enable Isotropic antenna for the UE", enableUeIso);
788 cmd.AddValue(
"indoorScenario",
789 "The indoor scenario to be used can be: InH-OfficeMixed or InH-OfficeOpen",
791 cmd.AddValue(
"speed",
"UE speed in km/h", speed);
792 cmd.AddValue(
"outdir",
"directory where to store the simulation results", outdir);
793 cmd.AddValue(
"polarizedAntennas",
794 "Set true to to make UE and Gnb anetnna polarized",
796 cmd.AddValue(
"simTag",
797 "tag to be appended to output filenames to distinguish simulation campaigns",
799 cmd.AddValue(
"vportGnb",
"Set GNB Vertical Ports", numVPortsGnb);
800 cmd.AddValue(
"hportGnb",
"Set GNB Horizontal Ports", numHPortsGnb);
801 cmd.AddValue(
"vportUe",
"Set UE Vertical Ports", numVPortsUe);
802 cmd.AddValue(
"hportUE",
"Set UE Horizontal Ports", numHPortsUe);
804 cmd.Parse(argc, argv);
806 ConfigStore inputConfig;
807 inputConfig.ConfigureDefaults();
809 Nr3gppIndoorCalibration phase1CalibrationScenario;
811 DroppingParameters dropParam = {polarizedAntennas,
818 phase1CalibrationScenario.Run(centralFrequencyBand,
Manages the correct creation of operation bands, component carriers and bandwidth parts.
OperationBandInfo CreateOperationBandContiguousCc(const SimpleOperationBandConf &conf)
Create an operation band with the CC specified.
static BandwidthPartInfoPtrVector GetAllBwps(const std::vector< std::reference_wrapper< OperationBandInfo > > &operationBands)
Get all the BWP pointers from the specified vector of operation bands.
void UeRssiPerProcessedChunkTrace(Nr3gppIndoorCalibration *scenario, double rssidBm)
void UeSnrPerProcessedChunkTrace(Nr3gppIndoorCalibration *scenario, double snr)
std::string BuildFileNameString(std::string directoryName, std::string filePrefix, std::string tag)
std::string BuildTag(bool gNbAntennaModel, bool ueAntennaModel, std::string scenario, double speed)
void UeReceptionTrace(Nr3gppIndoorCalibration *scenario, RxPacketTraceParams params)
std::vector< std::reference_wrapper< BandwidthPartInfoPtr > > BandwidthPartInfoPtrVector
vector of unique_ptr of BandwidthPartInfo
Minimum configuration requirements for a OperationBand.
Operation band information structure.
The RxPacketTraceParams struct.