5G-LENA nr-v4.0
The 5G/NR module for the ns-3 simulator
Loading...
Searching...
No Matches
cttc-channel-randomness.cc
Go to the documentation of this file.
1// Copyright (c) 2020 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
2//
3// SPDX-License-Identifier: GPL-2.0-only
4
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"
26#include "ns3/log.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"
35
36using namespace ns3;
37
38NS_LOG_COMPONENT_DEFINE("CttcChannelRandomness");
39
46static void
47DoBeamforming(Ptr<NetDevice> thisDevice,
48 Ptr<UniformPlanarArray> thisAntenna,
49 Ptr<NetDevice> otherDevice)
50{
51 // retrieve the position of the two devices
52 Vector aPos = thisDevice->GetNode()->GetObject<MobilityModel>()->GetPosition();
53 Vector bPos = otherDevice->GetNode()->GetObject<MobilityModel>()->GetPosition();
54
55 // compute the azimuth and the elevation angles
56 Angles completeAngle(bPos, aPos);
57
58 double posX = bPos.x - aPos.x;
59 double phiAngle = atan((bPos.y - aPos.y) / posX);
60
61 if (posX < 0)
62 {
63 phiAngle = phiAngle + M_PI;
64 }
65 if (phiAngle < 0)
66 {
67 phiAngle = phiAngle + 2 * M_PI;
68 }
69
70 double hAngleRadian = fmod((phiAngle + M_PI), 2 * M_PI - M_PI); // the azimuth angle
71 double vAngleRadian = completeAngle.GetInclination(); // the elevation angle
72
73 // retrieve the number of antenna elements
74 size_t totNoArrayElements = thisAntenna->GetNumElems();
75
76 // the total power is divided equally among the antenna elements
77 double power = 1 / sqrt(totNoArrayElements);
78
79 UniformPlanarArray::ComplexVector antennaWeights(totNoArrayElements);
80 // compute the antenna weights
81 for (size_t ind = 0; ind < totNoArrayElements; ind++)
82 {
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;
88 }
89
90 // store the antenna weights
91 thisAntenna->SetBeamformingVector(antennaWeights);
92}
93
94int
95main(int argc, char* argv[])
96{
97 double frequency = 28.0e9;
98 uint32_t rbNum = 555; // bandwidth in number of RBs, for numerology 0 is equivalent to 555 RBs
99 double subcarrierSpacing = 15000; // subcarrier spacing for numerology 0
100
101 double txPower = 40;
102 double distance = 10.0;
103 std::string scenario = "UMa"; // 3GPP propagation scenario
104
105 uint32_t simTimeMs = 1000;
106 bool logging = false;
107
108 CommandLine cmd(__FILE__);
109 cmd.AddValue("frequency",
110 "The operating frequency in Hz (2125.0e6 corresponds to EARFCN 2100)",
111 frequency);
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'",
119 scenario);
120 cmd.AddValue("simTimeMs", "Simulation time in ms", simTimeMs);
121 cmd.AddValue("logging", "Enable logging", logging);
122 cmd.Parse(argc, argv);
123
124 Config::SetDefault("ns3::ThreeGppChannelModel::UpdatePeriod",
125 TimeValue(MilliSeconds(0))); // update the channel at each iteration
126 Config::SetDefault("ns3::ThreeGppChannelConditionModel::UpdatePeriod",
127 TimeValue(MilliSeconds(0.0))); // do not update the channel condition
128
129 // create the tx and rx nodes
130 NodeContainer nodes;
131 nodes.Create(2);
132
133 // create the tx and rx devices
134 Ptr<SimpleNetDevice> txDev = CreateObject<SimpleNetDevice>();
135 Ptr<SimpleNetDevice> rxDev = CreateObject<SimpleNetDevice>();
136
137 // associate the nodes and the devices
138 nodes.Get(0)->AddDevice(txDev);
139 txDev->SetNode(nodes.Get(0));
140 nodes.Get(1)->AddDevice(rxDev);
141 rxDev->SetNode(nodes.Get(1));
142
143 // create the tx and rx mobility models, set the positions
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));
148
149 // assign the mobility models to the nodes
150 nodes.Get(0)->AggregateObject(txMob);
151 nodes.Get(1)->AggregateObject(rxMob);
152
153 RngSeedManager::SetSeed(1);
154 RngSeedManager::SetRun(1);
155
156 int64_t stream = 1;
157
158 Ptr<ThreeGppPropagationLossModel> m_propagationLossModel;
159 Ptr<ThreeGppSpectrumPropagationLossModel>
160 m_spectrumLossModel;
161
162 // create and configure the factories for the channel condition and propagation loss models
163 ObjectFactory propagationLossModelFactory;
164 ObjectFactory channelConditionModelFactory;
165
166 if (scenario == "UMa")
167 {
168 propagationLossModelFactory.SetTypeId(ThreeGppUmaPropagationLossModel::GetTypeId());
169 channelConditionModelFactory.SetTypeId(AlwaysLosChannelConditionModel::GetTypeId());
170 }
171 else if (scenario == "UMi-StreetCanyon")
172 {
173 propagationLossModelFactory.SetTypeId(
174 ThreeGppUmiStreetCanyonPropagationLossModel::GetTypeId());
175 channelConditionModelFactory.SetTypeId(AlwaysLosChannelConditionModel::GetTypeId());
176 }
177 else
178 {
179 NS_FATAL_ERROR("The scenario can be 'UMa'or 'UMi-StreetCanyon'");
180 }
181
182 // create the propagation loss model
183 m_propagationLossModel = propagationLossModelFactory.Create<ThreeGppPropagationLossModel>();
184 m_propagationLossModel->SetAttribute("Frequency", DoubleValue(frequency));
185 m_propagationLossModel->SetAttribute("ShadowingEnabled", BooleanValue(false));
186
187 // create the spectrum propagation loss model
188 m_spectrumLossModel = CreateObject<ThreeGppSpectrumPropagationLossModel>();
189 m_spectrumLossModel->SetChannelModelAttribute("Frequency", DoubleValue(frequency));
190 m_spectrumLossModel->SetChannelModelAttribute("Scenario", StringValue(scenario));
191
192 // create the channel condition model and associate it with the spectrum and
193 // propagation loss model
194 Ptr<ChannelConditionModel> condModel =
195 channelConditionModelFactory.Create<ChannelConditionModel>();
196 m_spectrumLossModel->SetChannelModelAttribute("ChannelConditionModel", PointerValue(condModel));
197 m_propagationLossModel->SetChannelConditionModel(condModel);
198
199 // create the channel model
200 Ptr<ThreeGppChannelModel> channelModel = CreateObject<ThreeGppChannelModel>();
201 channelModel->SetAttribute("Frequency", DoubleValue(frequency));
202 channelModel->SetAttribute("Scenario", StringValue(scenario));
203 channelModel->SetAttribute("ChannelConditionModel", PointerValue(condModel));
204
205 // create the antenna objects and set their dimensions
206 Ptr<UniformPlanarArray> txAntenna =
207 CreateObjectWithAttributes<UniformPlanarArray>("NumColumns",
208 UintegerValue(2),
209 "NumRows",
210 UintegerValue(2));
211 Ptr<UniformPlanarArray> rxAntenna =
212 CreateObjectWithAttributes<UniformPlanarArray>("NumColumns",
213 UintegerValue(2),
214 "NumRows",
215 UintegerValue(2));
216
217 // set the beamforming vectors
218 DoBeamforming(txDev, txAntenna, rxDev);
219 DoBeamforming(rxDev, rxAntenna, txDev);
220
221 channelModel->AssignStreams(stream);
222
223 Ptr<const ThreeGppChannelModel::ChannelMatrix> channelMatrix1 =
224 channelModel->GetChannel(txMob, rxMob, txAntenna, rxAntenna);
225
226 /* for (uint32_t i = 0; i < channelMatrix1->m_channel.size (); i++)
227 {
228 for (uint32_t j = 0; j < channelMatrix1->m_channel.at (0).size (); j++)
229 {
230 std::cout << channelMatrix1->m_channel[i][j][0] << std::endl;
231 }
232 }*/
233
234 Ptr<const SpectrumModel> sm1 =
235 NrSpectrumValueHelper::GetSpectrumModel(rbNum, frequency, subcarrierSpacing);
236 std::vector<int> activeRbs;
237 for (size_t rbId = 0; rbId < sm1->GetNumBands(); rbId++)
238 {
239 activeRbs.push_back(rbId);
240 }
241 Ptr<const SpectrumValue> txPsd1 = NrSpectrumValueHelper::CreateTxPowerSpectralDensity(
242 txPower,
243 activeRbs,
244 sm1,
245 NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_BW);
246 Ptr<SpectrumSignalParameters> txParams1 = Create<SpectrumSignalParameters>();
247 txParams1->psd = txPsd1->Copy();
248 std::cout << "Average tx power 1: "
249 << 10 *
250 log10(Sum(*txParams1->psd) / txParams1->psd->GetSpectrumModel()->GetNumBands())
251 << " dBm" << std::endl;
252 Ptr<SpectrumSignalParameters> rxParams1 =
253 m_spectrumLossModel->DoCalcRxPowerSpectralDensity(txParams1,
254 txMob,
255 rxMob,
256 txAntenna,
257 rxAntenna);
258 std::cout << "Average rx power 1: "
259 << 10 * log10(Sum(*(rxParams1->psd)) /
260 rxParams1->psd->GetSpectrumModel()->GetNumBands())
261 << " dBm" << std::endl;
262
263 channelModel = CreateObject<ThreeGppChannelModel>();
264 channelModel->SetAttribute("Frequency", DoubleValue(frequency));
265 channelModel->SetAttribute("Scenario", StringValue(scenario));
266 channelModel->SetAttribute("ChannelConditionModel", PointerValue(condModel));
267
268 channelModel->AssignStreams(stream);
269
270 Ptr<const ThreeGppChannelModel::ChannelMatrix> channelMatrix2 =
271 channelModel->GetChannel(txMob, rxMob, txAntenna, rxAntenna);
272
273 /* for (uint32_t i = 0; i < channelMatrix2->m_channel.size (); i++)
274 {
275 for (uint32_t j = 0; j < channelMatrix2->m_channel.at (0).size (); j++)
276 {
277 std::cout << channelMatrix2->m_channel[i][j][0] << std::endl;
278 }
279 }*/
280
281 if (channelMatrix1->m_channel != channelMatrix2->m_channel)
282 {
283 std::cout << "matrices are different" << std::endl;
284 }
285 else
286 {
287 std::cout << "matrices are the same" << std::endl;
288 }
289
290 Ptr<const SpectrumModel> sm2 =
291 NrSpectrumValueHelper::GetSpectrumModel(rbNum, frequency, subcarrierSpacing);
292 std::vector<int> activeRbs2;
293 for (size_t rbId = 0; rbId < sm2->GetNumBands(); rbId++)
294 {
295 activeRbs2.push_back(rbId);
296 }
297 Ptr<const SpectrumValue> txPsd2 = NrSpectrumValueHelper::CreateTxPowerSpectralDensity(
298 txPower,
299 activeRbs2,
300 sm2,
301 NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_BW);
302 Ptr<SpectrumSignalParameters> txParams2 = Create<SpectrumSignalParameters>();
303 txParams2->psd = txPsd2->Copy();
304
305 std::cout << "Average tx power 1: "
306 << 10 *
307 log10(Sum(*txParams2->psd) / txParams2->psd->GetSpectrumModel()->GetNumBands())
308 << " dBm" << std::endl;
309 Ptr<SpectrumSignalParameters> rxParams2 =
310 m_spectrumLossModel->DoCalcRxPowerSpectralDensity(txParams2,
311 txMob,
312 rxMob,
313 txAntenna,
314 rxAntenna);
315 std::cout << "Average rx power 1: "
316 << 10 * log10(Sum(*(rxParams2->psd)) /
317 rxParams2->psd->GetSpectrumModel()->GetNumBands())
318 << " dBm" << std::endl;
319
320 Simulator::Stop(MilliSeconds(simTimeMs));
321 Simulator::Run();
322
323 Simulator::Destroy();
324 return 0;
325}
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)