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 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19/**
20 * This example shows how to configure the 3GPP channel model classes to
21 * compute the SNR between two nodes.
22 * The simulation involves two static nodes which are placed at a certain
23 * distance from each other and communicates through a wireless channel at
24 * 2 GHz with a bandwidth of 18 MHz. The default propagation environment is
25 * 3D-urban macro (UMa) and it can be configured changing the value of the
26 * string "scenario".
27 * Each node hosts a SimpleNetDevice and has an antenna array with 4 elements.
28 */
29
30#include "ns3/channel-condition-model.h"
31#include "ns3/constant-position-mobility-model.h"
32#include "ns3/core-module.h"
33#include "ns3/lte-spectrum-value-helper.h"
34#include "ns3/mobility-model.h"
35#include "ns3/net-device.h"
36#include "ns3/node-container.h"
37#include "ns3/node.h"
38#include "ns3/simple-net-device.h"
39#include "ns3/spectrum-signal-parameters.h"
40#include "ns3/three-gpp-channel-model.h"
41#include "ns3/three-gpp-propagation-loss-model.h"
42#include "ns3/three-gpp-spectrum-propagation-loss-model.h"
43#include "ns3/uniform-planar-array.h"
44
45#include <fstream>
46
47NS_LOG_COMPONENT_DEFINE("ThreeGppChannelExample");
48
49using namespace ns3;
50
52 m_propagationLossModel; //!< the PropagationLossModel object
54 m_spectrumLossModel; //!< the SpectrumPropagationLossModel object
55
56/**
57 * \brief A structure that holds the parameters for the
58 * ComputeSnr function. In this way the problem with the limited
59 * number of parameters of method Schedule is avoided.
60 */
62{
63 Ptr<MobilityModel> txMob; //!< the tx mobility model
64 Ptr<MobilityModel> rxMob; //!< the rx mobility model
65 double txPow; //!< the tx power in dBm
66 double noiseFigure; //!< the noise figure in dB
67 Ptr<PhasedArrayModel> txAntenna; //!< the tx antenna array
68 Ptr<PhasedArrayModel> rxAntenna; //!< the rx antenna array
69};
70
71/**
72 * Perform the beamforming using the DFT beamforming method
73 * \param thisDevice the device performing the beamforming
74 * \param thisAntenna the antenna object associated to thisDevice
75 * \param otherDevice the device towards which point the beam
76 */
77static void
79 Ptr<PhasedArrayModel> thisAntenna,
80 Ptr<NetDevice> otherDevice)
81{
82 // retrieve the position of the two devices
83 Vector aPos = thisDevice->GetNode()->GetObject<MobilityModel>()->GetPosition();
84 Vector bPos = otherDevice->GetNode()->GetObject<MobilityModel>()->GetPosition();
85
86 // compute the azimuth and the elevation angles
87 Angles completeAngle(bPos, aPos);
88 double hAngleRadian = completeAngle.GetAzimuth();
89
90 double vAngleRadian = completeAngle.GetInclination(); // the elevation angle
91
92 // retrieve the number of antenna elements and resize the vector
93 uint64_t totNoArrayElements = thisAntenna->GetNumElems();
94 PhasedArrayModel::ComplexVector antennaWeights(totNoArrayElements);
95
96 // the total power is divided equally among the antenna elements
97 double power = 1.0 / sqrt(totNoArrayElements);
98
99 // compute the antenna weights
100 const double sinVAngleRadian = sin(vAngleRadian);
101 const double cosVAngleRadian = cos(vAngleRadian);
102 const double sinHAngleRadian = sin(hAngleRadian);
103 const double cosHAngleRadian = cos(hAngleRadian);
104
105 for (uint64_t ind = 0; ind < totNoArrayElements; ind++)
106 {
107 Vector loc = thisAntenna->GetElementLocation(ind);
108 double phase = -2 * M_PI *
109 (sinVAngleRadian * cosHAngleRadian * loc.x +
110 sinVAngleRadian * sinHAngleRadian * loc.y + cosVAngleRadian * loc.z);
111 antennaWeights[ind] = exp(std::complex<double>(0, phase)) * power;
112 }
113
114 // store the antenna weights
115 thisAntenna->SetBeamformingVector(antennaWeights);
116}
117
118/**
119 * Compute the average SNR
120 * \param params A structure that holds the parameters that are needed to perform calculations in
121 * ComputeSnr
122 */
123static void
125{
126 // Create the tx PSD using the LteSpectrumValueHelper
127 // 100 RBs corresponds to 18 MHz (1 RB = 180 kHz)
128 // EARFCN 100 corresponds to 2125.00 MHz
129 std::vector<int> activeRbs0(100);
130 for (int i = 0; i < 100; i++)
131 {
132 activeRbs0[i] = i;
133 }
134 auto txPsd =
135 LteSpectrumValueHelper::CreateTxPowerSpectralDensity(2100, 100, params.txPow, activeRbs0);
136 auto txParams = Create<SpectrumSignalParameters>();
137 txParams->psd = txPsd->Copy();
138 NS_LOG_DEBUG("Average tx power " << 10 * log10(Sum(*txPsd) * 180e3) << " dB");
139
140 // create the noise PSD
141 auto noisePsd =
142 LteSpectrumValueHelper::CreateNoisePowerSpectralDensity(2100, 100, params.noiseFigure);
143 NS_LOG_DEBUG("Average noise power " << 10 * log10(Sum(*noisePsd) * 180e3) << " dB");
144
145 // apply the pathloss
146 double propagationGainDb = m_propagationLossModel->CalcRxPower(0, params.txMob, params.rxMob);
147 NS_LOG_DEBUG("Pathloss " << -propagationGainDb << " dB");
148 double propagationGainLinear = std::pow(10.0, (propagationGainDb) / 10.0);
149 *(txParams->psd) *= propagationGainLinear;
150
151 NS_ASSERT_MSG(params.txAntenna, "params.txAntenna is nullptr!");
152 NS_ASSERT_MSG(params.rxAntenna, "params.rxAntenna is nullptr!");
153
154 // apply the fast fading and the beamforming gain
155 auto rxParams = m_spectrumLossModel->CalcRxPowerSpectralDensity(txParams,
156 params.txMob,
157 params.rxMob,
158 params.txAntenna,
159 params.rxAntenna);
160 auto rxPsd = rxParams->psd;
161 NS_LOG_DEBUG("Average rx power " << 10 * log10(Sum(*rxPsd) * 180e3) << " dB");
162
163 // compute the SNR
164 NS_LOG_DEBUG("Average SNR " << 10 * log10(Sum(*rxPsd) / Sum(*noisePsd)) << " dB");
165
166 // print the SNR and pathloss values in the snr-trace.txt file
167 std::ofstream f;
168 f.open("snr-trace.txt", std::ios::out | std::ios::app);
169 f << Simulator::Now().GetSeconds() << " " << 10 * log10(Sum(*rxPsd) / Sum(*noisePsd)) << " "
170 << propagationGainDb << std::endl;
171 f.close();
172}
173
174int
175main(int argc, char* argv[])
176{
177 double frequency = 2125.0e6; // operating frequency in Hz (corresponds to EARFCN 2100)
178 double txPow = 49.0; // tx power in dBm
179 double noiseFigure = 9.0; // noise figure in dB
180 double distance = 10.0; // distance between tx and rx nodes in meters
181 uint32_t simTime = 1000; // simulation time in milliseconds
182 uint32_t timeRes = 10; // time resolution in milliseconds
183 std::string scenario = "UMa"; // 3GPP propagation scenario
184
185 Config::SetDefault("ns3::ThreeGppChannelModel::UpdatePeriod",
186 TimeValue(MilliSeconds(1))); // update the channel at each iteration
187 Config::SetDefault("ns3::ThreeGppChannelConditionModel::UpdatePeriod",
188 TimeValue(MilliSeconds(0.0))); // do not update the channel condition
189
192
193 // create and configure the factories for the channel condition and propagation loss models
194 ObjectFactory propagationLossModelFactory;
195 ObjectFactory channelConditionModelFactory;
196 if (scenario == "RMa")
197 {
198 propagationLossModelFactory.SetTypeId(ThreeGppRmaPropagationLossModel::GetTypeId());
199 channelConditionModelFactory.SetTypeId(ThreeGppRmaChannelConditionModel::GetTypeId());
200 }
201 else if (scenario == "UMa")
202 {
203 propagationLossModelFactory.SetTypeId(ThreeGppUmaPropagationLossModel::GetTypeId());
204 channelConditionModelFactory.SetTypeId(ThreeGppUmaChannelConditionModel::GetTypeId());
205 }
206 else if (scenario == "UMi-StreetCanyon")
207 {
208 propagationLossModelFactory.SetTypeId(
210 channelConditionModelFactory.SetTypeId(
212 }
213 else if (scenario == "InH-OfficeOpen")
214 {
215 propagationLossModelFactory.SetTypeId(
217 channelConditionModelFactory.SetTypeId(
219 }
220 else if (scenario == "InH-OfficeMixed")
221 {
222 propagationLossModelFactory.SetTypeId(
224 channelConditionModelFactory.SetTypeId(
226 }
227 else
228 {
229 NS_FATAL_ERROR("Unknown scenario");
230 }
231
232 // create the propagation loss model
233 m_propagationLossModel = propagationLossModelFactory.Create<ThreeGppPropagationLossModel>();
234 m_propagationLossModel->SetAttribute("Frequency", DoubleValue(frequency));
235 m_propagationLossModel->SetAttribute("ShadowingEnabled", BooleanValue(false));
236
237 // create the spectrum propagation loss model
238 m_spectrumLossModel = CreateObject<ThreeGppSpectrumPropagationLossModel>();
241
242 // create the channel condition model and associate it with the spectrum and
243 // propagation loss model
245 channelConditionModelFactory.Create<ThreeGppChannelConditionModel>();
246 m_spectrumLossModel->SetChannelModelAttribute("ChannelConditionModel", PointerValue(condModel));
248
249 // create the tx and rx nodes
251 nodes.Create(2);
252
253 // create the tx and rx devices
254 Ptr<SimpleNetDevice> txDev = CreateObject<SimpleNetDevice>();
255 Ptr<SimpleNetDevice> rxDev = CreateObject<SimpleNetDevice>();
256
257 // associate the nodes and the devices
258 nodes.Get(0)->AddDevice(txDev);
259 txDev->SetNode(nodes.Get(0));
260 nodes.Get(1)->AddDevice(rxDev);
261 rxDev->SetNode(nodes.Get(1));
262
263 // create the tx and rx mobility models, set the positions
264 Ptr<MobilityModel> txMob = CreateObject<ConstantPositionMobilityModel>();
265 txMob->SetPosition(Vector(0.0, 0.0, 10.0));
266 Ptr<MobilityModel> rxMob = CreateObject<ConstantPositionMobilityModel>();
267 rxMob->SetPosition(Vector(distance, 0.0, 1.6));
268
269 // assign the mobility models to the nodes
270 nodes.Get(0)->AggregateObject(txMob);
271 nodes.Get(1)->AggregateObject(rxMob);
272
273 // create the antenna objects and set their dimensions
274 Ptr<PhasedArrayModel> txAntenna =
275 CreateObjectWithAttributes<UniformPlanarArray>("NumColumns",
276 UintegerValue(2),
277 "NumRows",
278 UintegerValue(2));
279 Ptr<PhasedArrayModel> rxAntenna =
280 CreateObjectWithAttributes<UniformPlanarArray>("NumColumns",
281 UintegerValue(2),
282 "NumRows",
283 UintegerValue(2));
284
285 // set the beamforming vectors
286 DoBeamforming(txDev, txAntenna, rxDev);
287 DoBeamforming(rxDev, rxAntenna, txDev);
288
289 for (int i = 0; i < floor(simTime / timeRes); i++)
290 {
291 ComputeSnrParams params{txMob, rxMob, txPow, noiseFigure, txAntenna, rxAntenna};
292 Simulator::Schedule(MilliSeconds(timeRes * i), &ComputeSnr, params);
293 }
294
297 return 0;
298}
Class holding the azimuth and inclination angles of spherical coordinates.
Definition: angles.h:118
double GetInclination() const
Getter for inclination angle.
Definition: angles.cc:246
double GetAzimuth() const
Getter for azimuth angle.
Definition: angles.cc:240
AttributeValue implementation for Boolean.
Definition: boolean.h:37
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
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:135
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:211
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:309
Ptr< SpectrumSignalParameters > CalcRxPowerSpectralDensity(Ptr< const SpectrumSignalParameters > txPsd, Ptr< const MobilityModel > a, Ptr< const MobilityModel > b, Ptr< const PhasedArrayModel > aPhasedArrayModel, Ptr< const PhasedArrayModel > bPhasedArrayModel) const
This method is to be called to calculate.
AttributeValue implementation for Pointer.
Definition: pointer.h:48
double CalcRxPower(double txPowerDbm, Ptr< MobilityModel > a, Ptr< MobilityModel > b) const
Returns the Rx Power taking into account all the PropagationLossModel(s) chained to the current one.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
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:571
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
static void Run()
Run the simulation.
Definition: simulator.cc:178
Hold variables of type string.
Definition: string.h:56
Base class for the 3GPP channel condition models.
Base class for the 3GPP propagation models.
void SetChannelConditionModel(Ptr< ChannelConditionModel > model)
Set the channel condition model used to determine the channel state (e.g., the LOS/NLOS condition)
static TypeId GetTypeId()
Get the type ID.
void SetChannelModelAttribute(const std::string &name, const AttributeValue &value)
Sets the value of an attribute belonging to the associated MatrixBasedChannelModel instance.
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:403
AttributeValue implementation for Time.
Definition: nstime.h:1406
Hold an unsigned integer type.
Definition: uinteger.h:45
#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:86
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:894
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1331
NodeContainer nodes
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double Sum(const SpectrumValue &x)
FtrParams 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
Ptr< SpectrumValue > psd
The Power Spectral Density of the waveform, in linear units.
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