A Discrete-Event Network Simulator
API
three-gpp-channel-example.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2019 SIGNET Lab, Department of Information Engineering,
4  * University of Padova
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */
19 
31 #include "ns3/core-module.h"
32 #include "ns3/three-gpp-channel-model.h"
33 #include "ns3/uniform-planar-array.h"
34 #include <fstream>
35 #include "ns3/three-gpp-spectrum-propagation-loss-model.h"
36 #include "ns3/net-device.h"
37 #include "ns3/simple-net-device.h"
38 #include "ns3/node.h"
39 #include "ns3/node-container.h"
40 #include "ns3/mobility-model.h"
41 #include "ns3/constant-position-mobility-model.h"
42 #include "ns3/lte-spectrum-value-helper.h"
43 #include "ns3/channel-condition-model.h"
44 #include "ns3/three-gpp-propagation-loss-model.h"
45 
46 NS_LOG_COMPONENT_DEFINE ("ThreeGppChannelExample");
47 
48 using namespace ns3;
49 
52 
59 static void
60 DoBeamforming (Ptr<NetDevice> thisDevice, Ptr<PhasedArrayModel> thisAntenna, Ptr<NetDevice> otherDevice)
61 {
62  PhasedArrayModel::ComplexVector antennaWeights;
63 
64  // retrieve the position of the two devices
65  Vector aPos = thisDevice->GetNode ()->GetObject<MobilityModel> ()->GetPosition ();
66  Vector bPos = otherDevice->GetNode ()->GetObject<MobilityModel> ()->GetPosition ();
67 
68  // compute the azimuth and the elevation angles
69  Angles completeAngle (bPos,aPos);
70  double hAngleRadian = completeAngle.GetAzimuth ();
71 
72  double vAngleRadian = completeAngle.GetInclination (); // the elevation angle
73 
74  // retrieve the number of antenna elements
75  int totNoArrayElements = thisAntenna->GetNumberOfElements ();
76 
77  // the total power is divided equally among the antenna elements
78  double power = 1 / sqrt (totNoArrayElements);
79 
80  // compute the antenna weights
81  for (int ind = 0; ind < totNoArrayElements; ind++)
82  {
83  Vector loc = thisAntenna->GetElementLocation (ind);
84  double phase = -2 * M_PI * (sin (vAngleRadian) * cos (hAngleRadian) * loc.x
85  + sin (vAngleRadian) * sin (hAngleRadian) * loc.y
86  + cos (vAngleRadian) * loc.z);
87  antennaWeights.push_back (exp (std::complex<double> (0, phase)) * power);
88  }
89 
90  // store the antenna weights
91  thisAntenna->SetBeamformingVector (antennaWeights);
92 }
93 
101 static void
102 ComputeSnr (Ptr<MobilityModel> txMob, Ptr<MobilityModel> rxMob, double txPow, double noiseFigure)
103 {
104  // Create the tx PSD using the LteSpectrumValueHelper
105  // 100 RBs corresponds to 18 MHz (1 RB = 180 kHz)
106  // EARFCN 100 corresponds to 2125.00 MHz
107  std::vector<int> activeRbs0 (100);
108  for (int i = 0; i < 100 ; i++)
109  {
110  activeRbs0[i] = i;
111  }
112  Ptr<SpectrumValue> txPsd = LteSpectrumValueHelper::CreateTxPowerSpectralDensity (2100, 100, txPow, activeRbs0);
113  Ptr<SpectrumValue> rxPsd = txPsd->Copy ();
114  NS_LOG_DEBUG ("Average tx power " << 10*log10(Sum (*txPsd) * 180e3) << " dB");
115 
116  // create the noise PSD
118  NS_LOG_DEBUG ("Average noise power " << 10*log10 (Sum (*noisePsd) * 180e3) << " dB");
119 
120  // apply the pathloss
121  double propagationGainDb = m_propagationLossModel->CalcRxPower (0, txMob, rxMob);
122  NS_LOG_DEBUG ("Pathloss " << -propagationGainDb << " dB");
123  double propagationGainLinear = std::pow (10.0, (propagationGainDb) / 10.0);
124  *(rxPsd) *= propagationGainLinear;
125 
126  // apply the fast fading and the beamforming gain
127  rxPsd = m_spectrumLossModel->CalcRxPowerSpectralDensity (rxPsd, txMob, rxMob);
128  NS_LOG_DEBUG ("Average rx power " << 10*log10 (Sum (*rxPsd) * 180e3) << " dB");
129 
130  // compute the SNR
131  NS_LOG_DEBUG ("Average SNR " << 10 * log10 (Sum (*rxPsd) / Sum (*noisePsd)) << " dB");
132 
133  // print the SNR and pathloss values in the snr-trace.txt file
134  std::ofstream f;
135  f.open ("snr-trace.txt", std::ios::out | std::ios::app);
136  f << Simulator::Now ().GetSeconds () << " " << 10 * log10 (Sum (*rxPsd) / Sum (*noisePsd)) << " " << propagationGainDb << std::endl;
137  f.close ();
138 }
139 
140 int
141 main (int argc, char *argv[])
142 {
143  double frequency = 2125.0e6; // operating frequency in Hz (corresponds to EARFCN 2100)
144  double txPow = 49.0; // tx power in dBm
145  double noiseFigure = 9.0; // noise figure in dB
146  double distance = 10.0; // distance between tx and rx nodes in meters
147  uint32_t simTime = 10000; // simulation time in milliseconds
148  uint32_t timeRes = 10; // time resolution in milliseconds
149  std::string scenario = "UMa"; // 3GPP propagation scenario
150 
151  Config::SetDefault ("ns3::ThreeGppChannelModel::UpdatePeriod", TimeValue(MilliSeconds (1))); // update the channel at each iteration
152  Config::SetDefault ("ns3::ThreeGppChannelConditionModel::UpdatePeriod", TimeValue(MilliSeconds (0.0))); // do not update the channel condition
153 
156 
157  // create and configure the factories for the channel condition and propagation loss models
158  ObjectFactory propagationLossModelFactory;
159  ObjectFactory channelConditionModelFactory;
160  if (scenario == "RMa")
161  {
162  propagationLossModelFactory.SetTypeId (ThreeGppRmaPropagationLossModel::GetTypeId ());
163  channelConditionModelFactory.SetTypeId (ThreeGppRmaChannelConditionModel::GetTypeId ());
164  }
165  else if (scenario == "UMa")
166  {
167  propagationLossModelFactory.SetTypeId (ThreeGppUmaPropagationLossModel::GetTypeId ());
168  channelConditionModelFactory.SetTypeId (ThreeGppUmaChannelConditionModel::GetTypeId ());
169  }
170  else if (scenario == "UMi-StreetCanyon")
171  {
172  propagationLossModelFactory.SetTypeId (ThreeGppUmiStreetCanyonPropagationLossModel::GetTypeId ());
173  channelConditionModelFactory.SetTypeId (ThreeGppUmiStreetCanyonChannelConditionModel::GetTypeId ());
174  }
175  else if (scenario == "InH-OfficeOpen")
176  {
177  propagationLossModelFactory.SetTypeId (ThreeGppIndoorOfficePropagationLossModel::GetTypeId ());
179  }
180  else if (scenario == "InH-OfficeMixed")
181  {
182  propagationLossModelFactory.SetTypeId (ThreeGppIndoorOfficePropagationLossModel::GetTypeId ());
184  }
185  else
186  {
187  NS_FATAL_ERROR ("Unknown scenario");
188  }
189 
190  // create the propagation loss model
191  m_propagationLossModel = propagationLossModelFactory.Create<ThreeGppPropagationLossModel> ();
192  m_propagationLossModel->SetAttribute ("Frequency", DoubleValue (frequency));
193  m_propagationLossModel->SetAttribute ("ShadowingEnabled", BooleanValue (false));
194 
195  // create the spectrum propagation loss model
196  m_spectrumLossModel = CreateObject<ThreeGppSpectrumPropagationLossModel> ();
197  m_spectrumLossModel->SetChannelModelAttribute ("Frequency", DoubleValue (frequency));
198  m_spectrumLossModel->SetChannelModelAttribute ("Scenario", StringValue (scenario));
199 
200  // create the channel condition model and associate it with the spectrum and
201  // propagation loss model
202  Ptr<ChannelConditionModel> condModel = channelConditionModelFactory.Create<ThreeGppChannelConditionModel> ();
203  m_spectrumLossModel->SetChannelModelAttribute ("ChannelConditionModel", PointerValue (condModel));
205 
206  // create the tx and rx nodes
208  nodes.Create (2);
209 
210  // create the tx and rx devices
211  Ptr<SimpleNetDevice> txDev = CreateObject<SimpleNetDevice> ();
212  Ptr<SimpleNetDevice> rxDev = CreateObject<SimpleNetDevice> ();
213 
214  // associate the nodes and the devices
215  nodes.Get (0)->AddDevice (txDev);
216  txDev->SetNode (nodes.Get (0));
217  nodes.Get (1)->AddDevice (rxDev);
218  rxDev->SetNode (nodes.Get (1));
219 
220  // create the tx and rx mobility models, set the positions
221  Ptr<MobilityModel> txMob = CreateObject<ConstantPositionMobilityModel> ();
222  txMob->SetPosition (Vector (0.0,0.0,10.0));
223  Ptr<MobilityModel> rxMob = CreateObject<ConstantPositionMobilityModel> ();
224  rxMob->SetPosition (Vector (distance,0.0,1.6));
225 
226  // assign the mobility models to the nodes
227  nodes.Get (0)->AggregateObject (txMob);
228  nodes.Get (1)->AggregateObject (rxMob);
229 
230  // create the antenna objects and set their dimensions
231  Ptr<PhasedArrayModel> txAntenna = CreateObjectWithAttributes<UniformPlanarArray> ("NumColumns", UintegerValue (2), "NumRows", UintegerValue (2));
232  Ptr<PhasedArrayModel> rxAntenna = CreateObjectWithAttributes<UniformPlanarArray> ("NumColumns", UintegerValue (2), "NumRows", UintegerValue (2));
233 
234  // initialize the devices in the ThreeGppSpectrumPropagationLossModel
235  m_spectrumLossModel->AddDevice (txDev, txAntenna);
236  m_spectrumLossModel->AddDevice (rxDev, rxAntenna);
237 
238  // set the beamforming vectors
239  DoBeamforming (txDev, txAntenna, rxDev);
240  DoBeamforming (rxDev, rxAntenna, txDev);
241 
242  for (int i = 0; i < floor (simTime / timeRes); i++)
243  {
244  Simulator::Schedule (MilliSeconds (timeRes*i), &ComputeSnr, txMob, rxMob, txPow, noiseFigure);
245  }
246 
247  Simulator::Run ();
249  return 0;
250 }
double f(double x, void *params)
Definition: 80211b.c:70
Class holding the azimuth and inclination angles of spherical coordinates.
Definition: angles.h:119
double GetInclination(void) const
Getter for inclination angle.
Definition: angles.cc:229
double GetAzimuth(void) const
Getter for azimuth angle.
Definition: angles.cc:222
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:41
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.
void SetPosition(const Vector &position)
keep track of a set of node pointers.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185
Instantiate subclasses of ns3::Object.
Ptr< Object > Create(void) 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.
std::vector< std::complex< double > > ComplexVector
type definition for complex vectors
Hold objects of type Ptr<T>.
Definition: pointer.h:37
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.
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:136
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
static void Run(void)
Run the simulation.
Definition: simulator.cc:172
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
Ptr< SpectrumValue > Copy() const
Hold variables of type string.
Definition: string.h:41
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(void)
Get the type ID.
static TypeId GetTypeId(void)
Get the type ID.
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:380
AttributeValue implementation for Time.
Definition: nstime.h:1353
Hold an unsigned integer type.
Definition: uinteger.h:44
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1297
nodes
Definition: first.py:32
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double Sum(const SpectrumValue &x)
static void ComputeSnr(Ptr< MobilityModel > txMob, Ptr< MobilityModel > rxMob, double txPow, double noiseFigure)
Compute the average SNR.
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 Ptr< ThreeGppSpectrumPropagationLossModel > m_spectrumLossModel
the SpectrumPropagationLossModel object
static Vector GetPosition(Ptr< Node > node)
Definition: wifi-ap.cc:96