22#include "ns3/antenna-module.h"
23#include "ns3/config-store-module.h"
24#include "ns3/config-store.h"
25#include "ns3/core-module.h"
27#include "ns3/mobility-module.h"
28#include "ns3/nr-module.h"
29#include "ns3/nr-spectrum-value-helper.h"
30#include "ns3/simple-net-device.h"
31#include "ns3/spectrum-model.h"
32#include "ns3/three-gpp-channel-model.h"
33#include "ns3/three-gpp-propagation-loss-model.h"
34#include "ns3/three-gpp-spectrum-propagation-loss-model.h"
38NS_LOG_COMPONENT_DEFINE(
"CttcChannelRandomness");
48 Ptr<UniformPlanarArray> thisAntenna,
49 Ptr<NetDevice> otherDevice)
52 Vector aPos = thisDevice->GetNode()->GetObject<MobilityModel>()->GetPosition();
53 Vector bPos = otherDevice->GetNode()->GetObject<MobilityModel>()->GetPosition();
56 Angles completeAngle(bPos, aPos);
58 double posX = bPos.x - aPos.x;
59 double phiAngle = atan((bPos.y - aPos.y) / posX);
63 phiAngle = phiAngle + M_PI;
67 phiAngle = phiAngle + 2 * M_PI;
70 double hAngleRadian = fmod((phiAngle + M_PI), 2 * M_PI - M_PI);
71 double vAngleRadian = completeAngle.GetInclination();
74 size_t totNoArrayElements = thisAntenna->GetNumElems();
77 double power = 1 / sqrt(totNoArrayElements);
79 UniformPlanarArray::ComplexVector antennaWeights(totNoArrayElements);
81 for (
size_t ind = 0; ind < totNoArrayElements; ind++)
83 Vector loc = thisAntenna->GetElementLocation(ind);
84 double phase = -2 * M_PI *
85 (sin(vAngleRadian) * cos(hAngleRadian) * loc.x +
86 sin(vAngleRadian) * sin(hAngleRadian) * loc.y + cos(vAngleRadian) * loc.z);
87 antennaWeights[ind] = exp(std::complex<double>(0, phase)) * power;
91 thisAntenna->SetBeamformingVector(antennaWeights);
95main(
int argc,
char* argv[])
97 double frequency = 28.0e9;
99 double subcarrierSpacing = 15000;
102 double distance = 10.0;
103 std::string scenario =
"UMa";
105 uint32_t simTimeMs = 1000;
106 bool logging =
false;
108 CommandLine cmd(__FILE__);
109 cmd.AddValue(
"frequency",
110 "The operating frequency in Hz (2125.0e6 corresponds to EARFCN 2100)",
112 cmd.AddValue(
"rbNum",
"The system BW in number of resource blocks", rbNum);
113 cmd.AddValue(
"subcarrierSpacing",
"The subcarrier spacing", subcarrierSpacing);
114 cmd.AddValue(
"txPower",
"The transmission power in dBm", txPower);
115 cmd.AddValue(
"distance",
"The distance between tx and rx nodes in meters", distance);
116 cmd.AddValue(
"scenario",
117 "The 3GPP propagation scenario for the simulation."
118 "Choose among 'UMa'and 'UMi-StreetCanyon'",
120 cmd.AddValue(
"simTimeMs",
"Simulation time in ms", simTimeMs);
121 cmd.AddValue(
"logging",
"Enable logging", logging);
122 cmd.Parse(argc, argv);
124 Config::SetDefault(
"ns3::ThreeGppChannelModel::UpdatePeriod",
125 TimeValue(MilliSeconds(0)));
126 Config::SetDefault(
"ns3::ThreeGppChannelConditionModel::UpdatePeriod",
127 TimeValue(MilliSeconds(0.0)));
134 Ptr<SimpleNetDevice> txDev = CreateObject<SimpleNetDevice>();
135 Ptr<SimpleNetDevice> rxDev = CreateObject<SimpleNetDevice>();
138 nodes.Get(0)->AddDevice(txDev);
139 txDev->SetNode(nodes.Get(0));
140 nodes.Get(1)->AddDevice(rxDev);
141 rxDev->SetNode(nodes.Get(1));
144 Ptr<MobilityModel> txMob = CreateObject<ConstantPositionMobilityModel>();
145 txMob->SetPosition(Vector(0.0, 0.0, 10.0));
146 Ptr<MobilityModel> rxMob = CreateObject<ConstantPositionMobilityModel>();
147 rxMob->SetPosition(Vector(distance, 0.0, 1.6));
150 nodes.Get(0)->AggregateObject(txMob);
151 nodes.Get(1)->AggregateObject(rxMob);
153 RngSeedManager::SetSeed(1);
154 RngSeedManager::SetRun(1);
158 Ptr<ThreeGppPropagationLossModel> m_propagationLossModel;
159 Ptr<ThreeGppSpectrumPropagationLossModel>
163 ObjectFactory propagationLossModelFactory;
164 ObjectFactory channelConditionModelFactory;
166 if (scenario ==
"UMa")
168 propagationLossModelFactory.SetTypeId(ThreeGppUmaPropagationLossModel::GetTypeId());
169 channelConditionModelFactory.SetTypeId(AlwaysLosChannelConditionModel::GetTypeId());
171 else if (scenario ==
"UMi-StreetCanyon")
173 propagationLossModelFactory.SetTypeId(
174 ThreeGppUmiStreetCanyonPropagationLossModel::GetTypeId());
175 channelConditionModelFactory.SetTypeId(AlwaysLosChannelConditionModel::GetTypeId());
179 NS_FATAL_ERROR(
"The scenario can be 'UMa'or 'UMi-StreetCanyon'");
183 m_propagationLossModel = propagationLossModelFactory.Create<ThreeGppPropagationLossModel>();
184 m_propagationLossModel->SetAttribute(
"Frequency", DoubleValue(frequency));
185 m_propagationLossModel->SetAttribute(
"ShadowingEnabled", BooleanValue(
false));
188 m_spectrumLossModel = CreateObject<ThreeGppSpectrumPropagationLossModel>();
189 m_spectrumLossModel->SetChannelModelAttribute(
"Frequency", DoubleValue(frequency));
190 m_spectrumLossModel->SetChannelModelAttribute(
"Scenario", StringValue(scenario));
194 Ptr<ChannelConditionModel> condModel =
195 channelConditionModelFactory.Create<ChannelConditionModel>();
196 m_spectrumLossModel->SetChannelModelAttribute(
"ChannelConditionModel", PointerValue(condModel));
197 m_propagationLossModel->SetChannelConditionModel(condModel);
200 Ptr<ThreeGppChannelModel> channelModel = CreateObject<ThreeGppChannelModel>();
201 channelModel->SetAttribute(
"Frequency", DoubleValue(frequency));
202 channelModel->SetAttribute(
"Scenario", StringValue(scenario));
203 channelModel->SetAttribute(
"ChannelConditionModel", PointerValue(condModel));
206 Ptr<UniformPlanarArray> txAntenna =
207 CreateObjectWithAttributes<UniformPlanarArray>(
"NumColumns",
211 Ptr<UniformPlanarArray> rxAntenna =
212 CreateObjectWithAttributes<UniformPlanarArray>(
"NumColumns",
221 channelModel->AssignStreams(stream);
223 Ptr<const ThreeGppChannelModel::ChannelMatrix> channelMatrix1 =
224 channelModel->GetChannel(txMob, rxMob, txAntenna, rxAntenna);
234 Ptr<const SpectrumModel> sm1 =
236 std::vector<int> activeRbs;
237 for (
size_t rbId = 0; rbId < sm1->GetNumBands(); rbId++)
239 activeRbs.push_back(rbId);
245 NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_BW);
246 Ptr<SpectrumSignalParameters> txParams1 = Create<SpectrumSignalParameters>();
247 txParams1->psd = txPsd1->Copy();
248 std::cout <<
"Average tx power 1: "
250 log10(Sum(*txParams1->psd) / txParams1->psd->GetSpectrumModel()->GetNumBands())
251 <<
" dBm" << std::endl;
252 Ptr<SpectrumSignalParameters> rxParams1 =
253 m_spectrumLossModel->DoCalcRxPowerSpectralDensity(txParams1,
258 std::cout <<
"Average rx power 1: "
259 << 10 * log10(Sum(*(rxParams1->psd)) /
260 rxParams1->psd->GetSpectrumModel()->GetNumBands())
261 <<
" dBm" << std::endl;
263 channelModel = CreateObject<ThreeGppChannelModel>();
264 channelModel->SetAttribute(
"Frequency", DoubleValue(frequency));
265 channelModel->SetAttribute(
"Scenario", StringValue(scenario));
266 channelModel->SetAttribute(
"ChannelConditionModel", PointerValue(condModel));
268 channelModel->AssignStreams(stream);
270 Ptr<const ThreeGppChannelModel::ChannelMatrix> channelMatrix2 =
271 channelModel->GetChannel(txMob, rxMob, txAntenna, rxAntenna);
281 if (channelMatrix1->m_channel != channelMatrix2->m_channel)
283 std::cout <<
"matrices are different" << std::endl;
287 std::cout <<
"matrices are the same" << std::endl;
290 Ptr<const SpectrumModel> sm2 =
292 std::vector<int> activeRbs2;
293 for (
size_t rbId = 0; rbId < sm2->GetNumBands(); rbId++)
295 activeRbs2.push_back(rbId);
301 NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_BW);
302 Ptr<SpectrumSignalParameters> txParams2 = Create<SpectrumSignalParameters>();
303 txParams2->psd = txPsd2->Copy();
305 std::cout <<
"Average tx power 1: "
307 log10(Sum(*txParams2->psd) / txParams2->psd->GetSpectrumModel()->GetNumBands())
308 <<
" dBm" << std::endl;
309 Ptr<SpectrumSignalParameters> rxParams2 =
310 m_spectrumLossModel->DoCalcRxPowerSpectralDensity(txParams2,
315 std::cout <<
"Average rx power 1: "
316 << 10 * log10(Sum(*(rxParams2->psd)) /
317 rxParams2->psd->GetSpectrumModel()->GetNumBands())
318 <<
" dBm" << std::endl;
320 Simulator::Stop(MilliSeconds(simTimeMs));
323 Simulator::Destroy();
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 > 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 void DoBeamforming(Ptr< NetDevice > thisDevice, Ptr< UniformPlanarArray > thisAntenna, Ptr< NetDevice > otherDevice)