#include "ns3/mmwave-helper.h" #include "ns3/core-module.h" #include "ns3/network-module.h" #include "ns3/mobility-module.h" #include "ns3/config-store.h" #include "ns3/mmwave-helper.h" #include "ns3/log.h" #include "ns3/nr-point-to-point-epc-helper.h" #include "ns3/network-module.h" #include "ns3/ipv4-global-routing-helper.h" #include "ns3/internet-module.h" #include "ns3/applications-module.h" #include "ns3/point-to-point-helper.h" #include "ns3/eps-bearer-tag.h" #include "ns3/abort.h" #include "ns3/object.h" #include "ns3/mmwave-mac-scheduler-ns3.h" #include "ns3/mmwave-mac-scheduler-ofdma.h" #include "ns3/mmwave-mac-scheduler-ofdma-rr.h" #include "ns3/mmwave-phy-mac-common.h" #include "ns3/basic-data-calculators.h" #include "ns3/antenna-array-3gpp-model.h" #include "ns3/netanim-module.h" #include #include using namespace ns3; using namespace std; enum AntennaModelEnum{ _ISO, _3GPP, }; NS_LOG_COMPONENT_DEFINE ("Nr3gppIndoorCalibration"); static ns3::GlobalValue g_duration ("duration", "simulation duration in milliseconds, should be greater than 100 ms to allow the collection of traces", ns3::UintegerValue (150), ns3::MakeUintegerChecker()); static ns3::GlobalValue g_shadowing ("shadowing", "if true, shadowing is enabled in 3gpp propagation loss model;" "if false, shadowing is disabled", ns3::BooleanValue (true), ns3::MakeBooleanChecker ()); static ns3::GlobalValue g_antennaOrientation ("antennaOrientation", "the orientation of the antenna on gNB and UE", ns3::EnumValue (AntennaArray3gppModel::Z0), ns3::MakeEnumChecker (AntennaArray3gppModel::Z0, "Z0", AntennaArray3gppModel::X0, "X0")); static ns3::GlobalValue g_antennaModelgNb ("antennaModelGnb", "the antenna model of gNb, can be ISO or 3GPP", ns3::EnumValue (_3GPP), ns3::MakeEnumChecker (_ISO, "ISO", _3GPP, "3GPP")); static ns3::GlobalValue g_antennaModelUe ("antennaModelUe", "the antenna model of Ue, can be ISO or 3GPP", ns3::EnumValue (_3GPP), ns3::MakeEnumChecker (_ISO, "ISO", _3GPP, "3GPP")); static ns3::GlobalValue g_resultsDir ("resultsDir", "directory where to store the simulation results", ns3::StringValue ("./"), ns3::MakeStringChecker ()); static ns3::GlobalValue g_simTag ("simTag", "tag to be appended to the output filenames to distinguish different simulation campaign output files", ns3::StringValue (""), ns3::MakeStringChecker ()); static ns3::GlobalValue g_indoorScenario ("indoorScenario", "the indoor scenario to be used can be: InH-OfficeMixed, InH-OfficeOpen or InH-ShoppingMall", ns3::StringValue ("InH-OfficeOpen"), ns3::MakeStringChecker ()); static ns3::GlobalValue g_speed ("speed", "UE speed in km/h", ns3::DoubleValue (3.00), ns3::MakeDoubleChecker (0.0, 10.0)); static ns3::GlobalValue g_isBeamSearchMethod ("isBeamSearchMethod", "if true, beam search method will be used;" "if false, long term covariance matrix will be used", ns3::BooleanValue (true), ns3::MakeBooleanChecker ()); static ns3::GlobalValue g_beamSearchMethodAngle ("beamSearchMethodAngle", "beam search method angle step", ns3::DoubleValue (30.00), ns3::MakeDoubleChecker (0.0, 360.0)); static ns3::GlobalValue g_gNbAntennaMount ("gnbAntennaMount", "gNb antenna mount type. Can be Wall mount or Sector mount. Doc: 38.802-e20. A.2.1-7", ns3::EnumValue (ns3::AntennaArray3gppModel::GnbWallMount), ns3::MakeEnumChecker (ns3::AntennaArray3gppModel::GnbWallMount, "WALL", ns3::AntennaArray3gppModel::GnbSingleSector, "SECT")); //######################################### Beginning of class class Nr3gppIndoorCalibration{ public: void UeRssiPerProcessedChunk (double rssidBm); void Run (bool shadowing, AntennaArrayModel::AntennaOrientation antOrientation, TypeId gNbAntennaModel, TypeId ueAntennaModel, std::string scenario, double speed, std::string resultsDirPath, std::string tag, bool isBeamSearchMethod, double beamSearchMethodAngle, AntennaArray3gppModel::GnbAntennaMount gNbAntennaMount, uint32_t duration); ~Nr3gppIndoorCalibration (); private: std::ofstream m_outRssiFile; //!< the output file stream for the RSSI file std::ofstream m_outUePositionsFile; //!< the output file stream for the UE positions file std::ofstream m_outGnbPositionsFile; //!< the output file stream for the gNB positions file std::ofstream m_outDistancesFile; //!< the output file stream for the distances file }; std::string BuildFileNameString (std::string directoryName, std::string filePrefix, std::string tag) { std::ostringstream oss; oss << directoryName << filePrefix<UeRssiPerProcessedChunk (rssidBm); } void Nr3gppIndoorCalibration::UeRssiPerProcessedChunk (double rssidBm) { m_outRssiFile< mmWaveHelper = CreateObject (); mmWaveHelper->SetAttribute ("PathlossModel", StringValue ("ns3::MmWave3gppPropagationLossModel")); mmWaveHelper->SetAttribute ("ChannelModel", StringValue ("ns3::MmWave3gppChannel")); Ptr epcHelper = CreateObject (); mmWaveHelper->SetEpcHelper (epcHelper); mmWaveHelper->Initialize(); // create base stations and mobile terminals NodeContainer gNbNodes; NodeContainer ueNodes; MobilityHelper gnmobility, uemobility; gNbNodes.Create (3); ueNodes.Create (1); // Creating positions of the gNB according to the 3gpp TR 38.900 Figure 7.2.-1 Ptr gNbPositionAlloc = CreateObject (); gNbPositionAlloc->Add(Vector( 76, 40, 3)); gNbPositionAlloc->Add(Vector( 45 , 12 , 3)); gNbPositionAlloc->Add(Vector( 20, 40, 3)); gnmobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); gnmobility.SetPositionAllocator (gNbPositionAlloc); gnmobility.Install (gNbNodes); Ptr uEPositionAlloc = CreateObject (); uEPositionAlloc->Add(Vector( 45, 40, 1.5)); uemobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); uemobility.SetPositionAllocator (uEPositionAlloc); uemobility.Install(ueNodes); Vector v = gNbNodes.Get(0)->GetObject()->GetPosition(); m_outGnbPositionsFile<<0<<"\t"<GetObject()->GetPosition(); m_outGnbPositionsFile<<0<<"\t"<GetObject()->GetPosition(); m_outGnbPositionsFile<<0<<"\t"<GetObject()->GetPosition(); m_outUePositionsFile<<0<<"\t"<InstallEnbDevice (gNbNodes); NetDeviceContainer ueNetDevs = mmWaveHelper->InstallUeDevice (ueNodes); // create the internet and install the IP stack on the UEs // get SGW/PGW and create a single RemoteHost Ptr pgw = epcHelper->GetPgwNode (); NodeContainer remoteHostContainer; remoteHostContainer.Create (1); Ptr remoteHost = remoteHostContainer.Get (0); InternetStackHelper internet; internet.Install (remoteHostContainer); // connect a remoteHost to pgw. Setup routing too PointToPointHelper p2ph; p2ph.SetDeviceAttribute ("DataRate", DataRateValue (DataRate ("100Gb/s"))); p2ph.SetDeviceAttribute ("Mtu", UintegerValue (2500)); p2ph.SetChannelAttribute ("Delay", TimeValue (Seconds (0.000))); NetDeviceContainer internetDevices = p2ph.Install (pgw, remoteHost); Ipv4AddressHelper ipv4h; ipv4h.SetBase ("1.0.0.0", "255.0.0.0"); Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign (internetDevices); // in this container, interface 0 is the pgw, 1 is the remoteHost //Ipv4Address remoteHostAddr = internetIpIfaces.GetAddress (1); Ipv4StaticRoutingHelper ipv4RoutingHelper; Ptr remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject ()); remoteHostStaticRouting->AddNetworkRouteTo (Ipv4Address ("7.0.0.0"), Ipv4Mask ("255.0.0.0"), 1); internet.Install (ueNodes); Ipv4InterfaceContainer ueIpIface; ueIpIface = epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueNetDevs)); // Set the default gateway for the UEs Ptr ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ueNodes.Get(0)->GetObject ()); ueStaticRouting->SetDefaultRoute (epcHelper->GetUeDefaultGatewayAddress (), 1); Ptr closestEnbDevice; for (NetDeviceContainer::Iterator i = gNbDevs.Begin (); i != gNbDevs.End (); ++i) { closestEnbDevice = *i; for (NetDeviceContainer::Iterator ue = ueNetDevs.Begin (); ue != ueNetDevs.End (); ue++) { mmWaveHelper->AttachToEnb (*ue, closestEnbDevice); uint16_t dlPort = 1234; ApplicationContainer clientAppsDl; ApplicationContainer serverAppsDl; Time udpInterval = Time::FromDouble((1000*8) / static_cast (udpRate.GetBitRate ()), Time::S); UdpServerHelper dlPacketSinkHelper (dlPort); serverAppsDl.Add (dlPacketSinkHelper.Install (ueNodes)); // configure UDP downlink traffic UdpClientHelper dlClient (ueIpIface.GetAddress (0), dlPort); //CHECK AFTER dlClient.SetAttribute ("MaxPackets", UintegerValue(0xFFFFFFFF)); dlClient.SetAttribute("PacketSize", UintegerValue(1000)); dlClient.SetAttribute ("Interval", TimeValue (udpInterval)); // we try to saturate, we just need to measure during a short time, how much traffic can handle each BWP clientAppsDl.Add (dlClient.Install (remoteHost)); // start UDP server and client apps serverAppsDl.Start(udpAppStartTimeDl); clientAppsDl.Start(udpAppStartTimeDl); serverAppsDl.Stop(udpAppStopTimeDl); clientAppsDl.Stop(udpAppStopTimeDl); Ptr ue1SpectrumPhy = DynamicCast (ueNetDevs.Get(0))->GetPhy(0)->GetSpectrumPhy(); Ptr ue1SpectrumPhyInterference = ue1SpectrumPhy->GetMmWaveInterference(); NS_ABORT_IF(!ue1SpectrumPhyInterference); ue1SpectrumPhyInterference->TraceConnectWithoutContext("RssiPerProcessedChunk", MakeBoundCallback (&UeRssiPerProcessedChunkTrace, this)); } } AnimationInterface anim("g.xml"); anim.SetConstantPosition(gNbNodes.Get(0), v.x,v.y,v.z); anim.SetConstantPosition(gNbNodes.Get(1), v1.x,v1.y,v1.z); anim.SetConstantPosition(gNbNodes.Get(2), v2.x,v2.y,v2.z); anim.SetConstantPosition(ueNodes.Get(0), ve.x,ve.y,ve.z); Simulator::Stop (simTime); Simulator::Run (); Simulator::Destroy (); } //########################################################################################## int main(int argc, char *argv[]) { CommandLine cmd; cmd.Parse (argc, argv); ConfigStore inputConfig; inputConfig.ConfigureDefaults (); // parse again so you can override input file default values via command line cmd.Parse (argc, argv); EnumValue enumValue; DoubleValue doubleValue; BooleanValue booleanValue; StringValue stringValue; TypeIdValue typeIdValue; UintegerValue uintValue; GlobalValue::GetValueByName ("duration", uintValue); uint32_t duration = uintValue.Get (); GlobalValue::GetValueByName ("shadowing", booleanValue); bool shadowing = booleanValue.Get (); GlobalValue::GetValueByName ("antennaOrientation", enumValue); enum AntennaArray3gppModel::AntennaOrientation antennaOrientation = (AntennaArray3gppModel::AntennaOrientation) enumValue.Get (); GlobalValue::GetValueByName ("antennaModelGnb", enumValue); enum AntennaModelEnum antennaGnb = (AntennaModelEnum) enumValue.Get (); TypeId antennaModelGnb; if (antennaGnb == _3GPP) { antennaModelGnb = AntennaArray3gppModel::GetTypeId(); } else { antennaModelGnb = AntennaArrayModel::GetTypeId(); } GlobalValue::GetValueByName ("antennaModelUe", enumValue); enum AntennaModelEnum antennaUe = (AntennaModelEnum) enumValue.Get (); TypeId antennaModelUe; if (antennaUe == _3GPP) { antennaModelUe = AntennaArray3gppModel::GetTypeId(); } else { antennaModelUe = AntennaArrayModel::GetTypeId(); } GlobalValue::GetValueByName ("indoorScenario", stringValue); std::string indoorScenario = stringValue.Get (); GlobalValue::GetValueByName ("speed", doubleValue); double speed = doubleValue.Get (); GlobalValue::GetValueByName ("resultsDir", stringValue); std::string resultsDir = stringValue.Get (); GlobalValue::GetValueByName ("simTag", stringValue); std::string tag = stringValue.Get (); GlobalValue::GetValueByName ("isBeamSearchMethod", booleanValue); bool isBeamSearchMethod = booleanValue.Get (); GlobalValue::GetValueByName ("beamSearchMethodAngle", doubleValue); double beamSearchMethodAngle = doubleValue.Get (); GlobalValue::GetValueByName ("gnbAntennaMount", enumValue); enum AntennaArray3gppModel::GnbAntennaMount gnbAntennaMount = (AntennaArray3gppModel::GnbAntennaMount) enumValue.Get (); Nr3gppIndoorCalibration phase1CalibrationScenario; phase1CalibrationScenario.Run(shadowing, antennaOrientation, antennaModelGnb, antennaModelUe, indoorScenario, speed, resultsDir, tag, isBeamSearchMethod, beamSearchMethodAngle, gnbAntennaMount, duration); return 0; }