A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
three-gpp-channel-example.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2019 SIGNET Lab, Department of Information Engineering,
3 * University of Padova
4 *
5 * SPDX-License-Identifier: GPL-2.0-only
6 */
7
8/**
9 * This example shows how to configure the 3GPP channel model classes to
10 * compute the SNR between two nodes.
11 * The simulation involves two static nodes which are placed at a certain
12 * distance from each other and communicates through a wireless channel at
13 * 2 GHz with a bandwidth of 18 MHz. The default propagation environment is
14 * 3D-urban macro (UMa) and it can be configured changing the value of the
15 * string "scenario".
16 * Each node hosts a SimpleNetDevice and has an antenna array with 4 elements.
17 */
18
19#include "ns3/channel-condition-model.h"
20#include "ns3/constant-position-mobility-model.h"
21#include "ns3/core-module.h"
22#include "ns3/lte-spectrum-value-helper.h"
23#include "ns3/mobility-model.h"
24#include "ns3/net-device.h"
25#include "ns3/node-container.h"
26#include "ns3/node.h"
27#include "ns3/simple-net-device.h"
28#include "ns3/spectrum-signal-parameters.h"
29#include "ns3/three-gpp-channel-model.h"
30#include "ns3/three-gpp-propagation-loss-model.h"
31#include "ns3/three-gpp-spectrum-propagation-loss-model.h"
32#include "ns3/uniform-planar-array.h"
33
34#include <fstream>
35
36NS_LOG_COMPONENT_DEFINE("ThreeGppChannelExample");
37
38using namespace ns3;
39
41 m_propagationLossModel; //!< the PropagationLossModel object
43 m_spectrumLossModel; //!< the SpectrumPropagationLossModel object
44
45/**
46 * \brief A structure that holds the parameters for the
47 * ComputeSnr function. In this way the problem with the limited
48 * number of parameters of method Schedule is avoided.
49 */
51{
52 Ptr<MobilityModel> txMob; //!< the tx mobility model
53 Ptr<MobilityModel> rxMob; //!< the rx mobility model
54 double txPow; //!< the tx power in dBm
55 double noiseFigure; //!< the noise figure in dB
56 Ptr<PhasedArrayModel> txAntenna; //!< the tx antenna array
57 Ptr<PhasedArrayModel> rxAntenna; //!< the rx antenna array
58};
59
60/**
61 * Perform the beamforming using the DFT beamforming method
62 * \param thisDevice the device performing the beamforming
63 * \param thisAntenna the antenna object associated to thisDevice
64 * \param otherDevice the device towards which point the beam
65 */
66static void
68 Ptr<PhasedArrayModel> thisAntenna,
69 Ptr<NetDevice> otherDevice)
70{
71 // retrieve the position of the two devices
72 Vector aPos = thisDevice->GetNode()->GetObject<MobilityModel>()->GetPosition();
73 Vector bPos = otherDevice->GetNode()->GetObject<MobilityModel>()->GetPosition();
74
75 // compute the azimuth and the elevation angles
76 Angles completeAngle(bPos, aPos);
77 double hAngleRadian = completeAngle.GetAzimuth();
78
79 double vAngleRadian = completeAngle.GetInclination(); // the elevation angle
80
81 // retrieve the number of antenna elements and resize the vector
82 uint64_t totNoArrayElements = thisAntenna->GetNumElems();
83 PhasedArrayModel::ComplexVector antennaWeights(totNoArrayElements);
84
85 // the total power is divided equally among the antenna elements
86 double power = 1.0 / sqrt(totNoArrayElements);
87
88 // compute the antenna weights
89 const double sinVAngleRadian = sin(vAngleRadian);
90 const double cosVAngleRadian = cos(vAngleRadian);
91 const double sinHAngleRadian = sin(hAngleRadian);
92 const double cosHAngleRadian = cos(hAngleRadian);
93
94 for (uint64_t ind = 0; ind < totNoArrayElements; ind++)
95 {
96 Vector loc = thisAntenna->GetElementLocation(ind);
97 double phase = -2 * M_PI *
98 (sinVAngleRadian * cosHAngleRadian * loc.x +
99 sinVAngleRadian * sinHAngleRadian * loc.y + cosVAngleRadian * loc.z);
100 antennaWeights[ind] = exp(std::complex<double>(0, phase)) * power;
101 }
102
103 // store the antenna weights
104 thisAntenna->SetBeamformingVector(antennaWeights);
105}
106
107/**
108 * Compute the average SNR
109 * \param params A structure that holds the parameters that are needed to perform calculations in
110 * ComputeSnr
111 */
112static void
114{
115 // Create the tx PSD using the LteSpectrumValueHelper
116 // 100 RBs corresponds to 18 MHz (1 RB = 180 kHz)
117 // EARFCN 100 corresponds to 2125.00 MHz
118 std::vector<int> activeRbs0(100);
119 for (int i = 0; i < 100; i++)
120 {
121 activeRbs0[i] = i;
122 }
123 auto txPsd =
124 LteSpectrumValueHelper::CreateTxPowerSpectralDensity(2100, 100, params.txPow, activeRbs0);
125 auto txParams = Create<SpectrumSignalParameters>();
126 txParams->psd = txPsd->Copy();
127 NS_LOG_DEBUG("Average tx power " << 10 * log10(Sum(*txPsd) * 180e3) << " dB");
128
129 // create the noise PSD
130 auto noisePsd =
131 LteSpectrumValueHelper::CreateNoisePowerSpectralDensity(2100, 100, params.noiseFigure);
132 NS_LOG_DEBUG("Average noise power " << 10 * log10(Sum(*noisePsd) * 180e3) << " dB");
133
134 // apply the pathloss
135 double propagationGainDb = m_propagationLossModel->CalcRxPower(0, params.txMob, params.rxMob);
136 NS_LOG_DEBUG("Pathloss " << -propagationGainDb << " dB");
137 double propagationGainLinear = std::pow(10.0, (propagationGainDb) / 10.0);
138 *(txParams->psd) *= propagationGainLinear;
139
140 NS_ASSERT_MSG(params.txAntenna, "params.txAntenna is nullptr!");
141 NS_ASSERT_MSG(params.rxAntenna, "params.rxAntenna is nullptr!");
142
143 // apply the fast fading and the beamforming gain
144 auto rxParams = m_spectrumLossModel->CalcRxPowerSpectralDensity(txParams,
145 params.txMob,
146 params.rxMob,
147 params.txAntenna,
148 params.rxAntenna);
149 auto rxPsd = rxParams->psd;
150 NS_LOG_DEBUG("Average rx power " << 10 * log10(Sum(*rxPsd) * 180e3) << " dB");
151
152 // compute the SNR
153 NS_LOG_DEBUG("Average SNR " << 10 * log10(Sum(*rxPsd) / Sum(*noisePsd)) << " dB");
154
155 // print the SNR and pathloss values in the snr-trace.txt file
156 std::ofstream f;
157 f.open("snr-trace.txt", std::ios::out | std::ios::app);
158 f << Simulator::Now().GetSeconds() << " " << 10 * log10(Sum(*rxPsd) / Sum(*noisePsd)) << " "
159 << propagationGainDb << std::endl;
160 f.close();
161}
162
163int
164main(int argc, char* argv[])
165{
166 double frequency = 2125.0e6; // operating frequency in Hz (corresponds to EARFCN 2100)
167 double txPow = 49.0; // tx power in dBm
168 double noiseFigure = 9.0; // noise figure in dB
169 double distance = 10.0; // distance between tx and rx nodes in meters
170 uint32_t simTime = 1000; // simulation time in milliseconds
171 uint32_t timeRes = 10; // time resolution in milliseconds
172 std::string scenario = "UMa"; // 3GPP propagation scenario
173
174 Config::SetDefault("ns3::ThreeGppChannelModel::UpdatePeriod",
175 TimeValue(MilliSeconds(1))); // update the channel at each iteration
176 Config::SetDefault("ns3::ThreeGppChannelConditionModel::UpdatePeriod",
177 TimeValue(MilliSeconds(0.0))); // do not update the channel condition
178
181
182 // create and configure the factories for the channel condition and propagation loss models
183 ObjectFactory propagationLossModelFactory;
184 ObjectFactory channelConditionModelFactory;
185 if (scenario == "RMa")
186 {
187 propagationLossModelFactory.SetTypeId(ThreeGppRmaPropagationLossModel::GetTypeId());
188 channelConditionModelFactory.SetTypeId(ThreeGppRmaChannelConditionModel::GetTypeId());
189 }
190 else if (scenario == "UMa")
191 {
192 propagationLossModelFactory.SetTypeId(ThreeGppUmaPropagationLossModel::GetTypeId());
193 channelConditionModelFactory.SetTypeId(ThreeGppUmaChannelConditionModel::GetTypeId());
194 }
195 else if (scenario == "UMi-StreetCanyon")
196 {
197 propagationLossModelFactory.SetTypeId(
199 channelConditionModelFactory.SetTypeId(
201 }
202 else if (scenario == "InH-OfficeOpen")
203 {
204 propagationLossModelFactory.SetTypeId(
206 channelConditionModelFactory.SetTypeId(
208 }
209 else if (scenario == "InH-OfficeMixed")
210 {
211 propagationLossModelFactory.SetTypeId(
213 channelConditionModelFactory.SetTypeId(
215 }
216 else
217 {
218 NS_FATAL_ERROR("Unknown scenario");
219 }
220
221 // create the propagation loss model
222 m_propagationLossModel = propagationLossModelFactory.Create<ThreeGppPropagationLossModel>();
223 m_propagationLossModel->SetAttribute("Frequency", DoubleValue(frequency));
224 m_propagationLossModel->SetAttribute("ShadowingEnabled", BooleanValue(false));
225
226 // create the spectrum propagation loss model
228 m_spectrumLossModel->SetChannelModelAttribute("Frequency", DoubleValue(frequency));
229 m_spectrumLossModel->SetChannelModelAttribute("Scenario", StringValue(scenario));
230
231 // create the channel condition model and associate it with the spectrum and
232 // propagation loss model
234 channelConditionModelFactory.Create<ThreeGppChannelConditionModel>();
235 m_spectrumLossModel->SetChannelModelAttribute("ChannelConditionModel", PointerValue(condModel));
236 m_propagationLossModel->SetChannelConditionModel(condModel);
237
238 // create the tx and rx nodes
240 nodes.Create(2);
241
242 // create the tx and rx devices
245
246 // associate the nodes and the devices
247 nodes.Get(0)->AddDevice(txDev);
248 txDev->SetNode(nodes.Get(0));
249 nodes.Get(1)->AddDevice(rxDev);
250 rxDev->SetNode(nodes.Get(1));
251
252 // create the tx and rx mobility models, set the positions
254 txMob->SetPosition(Vector(0.0, 0.0, 10.0));
256 rxMob->SetPosition(Vector(distance, 0.0, 1.6));
257
258 // assign the mobility models to the nodes
259 nodes.Get(0)->AggregateObject(txMob);
260 nodes.Get(1)->AggregateObject(rxMob);
261
262 // create the antenna objects and set their dimensions
263 Ptr<PhasedArrayModel> txAntenna =
265 UintegerValue(2),
266 "NumRows",
267 UintegerValue(2));
268 Ptr<PhasedArrayModel> rxAntenna =
270 UintegerValue(2),
271 "NumRows",
272 UintegerValue(2));
273
274 // set the beamforming vectors
275 DoBeamforming(txDev, txAntenna, rxDev);
276 DoBeamforming(rxDev, rxAntenna, txDev);
277
278 for (int i = 0; i < floor(simTime / timeRes); i++)
279 {
280 ComputeSnrParams params{txMob, rxMob, txPow, noiseFigure, txAntenna, rxAntenna};
281 Simulator::Schedule(MilliSeconds(timeRes * i), &ComputeSnr, params);
282 }
283
286 return 0;
287}
Class holding the azimuth and inclination angles of spherical coordinates.
Definition angles.h:107
double GetInclination() const
Getter for inclination angle.
Definition angles.cc:236
double GetAzimuth() const
Getter for azimuth angle.
Definition angles.cc:230
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
static Ptr< SpectrumValue > CreateNoisePowerSpectralDensity(uint32_t earfcn, uint16_t bandwidth, double noiseFigure)
create a SpectrumValue that models the power spectral density of AWGN
static Ptr< SpectrumValue > CreateTxPowerSpectralDensity(uint32_t earfcn, uint16_t bandwidth, double powerTx, std::vector< int > activeRbs)
create a spectrum value representing the power spectral density of a signal to be transmitted.
Keep track of the current position and velocity of an object.
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition node.cc:124
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Instantiate subclasses of ns3::Object.
Ptr< Object > Create() const
Create an Object instance of the configured TypeId.
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition object.cc:298
AttributeValue implementation for Pointer.
Smart pointer class similar to boost::intrusive_ptr.
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
static void Run()
Run the simulation.
Definition simulator.cc:167
Hold variables of type string.
Definition string.h:45
Base class for the 3GPP channel condition models.
Base class for the 3GPP propagation models.
static TypeId GetTypeId()
Get the type ID.
static TypeId GetTypeId()
Get the type ID.
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:392
Hold an unsigned integer type.
Definition uinteger.h:34
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition assert.h:75
void SetDefault(std::string name, const AttributeValue &value)
Definition config.cc:883
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Ptr< T > CreateObjectWithAttributes(Args... args)
Allocate an Object on the heap and initialize with a set of attributes.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1320
NodeContainer nodes
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double Sum(const SpectrumValue &x)
params
Fit Fluctuating Two Ray model to the 3GPP TR 38.901 using the Anderson-Darling goodness-of-fit ##.
A structure that holds the parameters for the ComputeSnr function.
Ptr< PhasedArrayModel > txAntenna
the tx antenna array
Ptr< MobilityModel > rxMob
the rx mobility model
double noiseFigure
the noise figure in dB
double txPow
the tx power in dBm
Ptr< PhasedArrayModel > rxAntenna
the rx antenna array
Ptr< MobilityModel > txMob
the tx mobility model
static Ptr< ThreeGppPropagationLossModel > m_propagationLossModel
the PropagationLossModel object
static void DoBeamforming(Ptr< NetDevice > thisDevice, Ptr< PhasedArrayModel > thisAntenna, Ptr< NetDevice > otherDevice)
Perform the beamforming using the DFT beamforming method.
static void ComputeSnr(const ComputeSnrParams &params)
Compute the average SNR.
static Ptr< ThreeGppSpectrumPropagationLossModel > m_spectrumLossModel
the SpectrumPropagationLossModel object