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/three-gpp-antenna-array-model.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
61 {
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 
71  double hAngleRadian = fmod (completeAngle.phi, 2.0 * M_PI); // the azimuth angle
72  if (hAngleRadian < 0)
73  {
74  hAngleRadian += 2.0 * M_PI;
75  }
76  double vAngleRadian = completeAngle.theta; // the elevation angle
77 
78  // retrieve the number of antenna elements
79  int totNoArrayElements = thisAntenna->GetNumberOfElements ();
80 
81  // the total power is divided equally among the antenna elements
82  double power = 1 / sqrt (totNoArrayElements);
83 
84  // compute the antenna weights
85  for (int ind = 0; ind < totNoArrayElements; ind++)
86  {
87  Vector loc = thisAntenna->GetElementLocation (ind);
88  double phase = -2 * M_PI * (sin (vAngleRadian) * cos (hAngleRadian) * loc.x
89  + sin (vAngleRadian) * sin (hAngleRadian) * loc.y
90  + cos (vAngleRadian) * loc.z);
91  antennaWeights.push_back (exp (std::complex<double> (0, phase)) * power);
92  }
93 
94  // store the antenna weights
95  thisAntenna->SetBeamformingVector (antennaWeights);
96 }
97 
105 static void
106 ComputeSnr (Ptr<MobilityModel> txMob, Ptr<MobilityModel> rxMob, double txPow, double noiseFigure)
107 {
108  // Create the tx PSD using the LteSpectrumValueHelper
109  // 100 RBs corresponds to 18 MHz (1 RB = 180 kHz)
110  // EARFCN 100 corresponds to 2125.00 MHz
111  std::vector<int> activeRbs0 (100);
112  for (int i = 0; i < 100 ; i++)
113  {
114  activeRbs0[i] = i;
115  }
116  Ptr<SpectrumValue> txPsd = LteSpectrumValueHelper::CreateTxPowerSpectralDensity (2100, 100, txPow, activeRbs0);
117  Ptr<SpectrumValue> rxPsd = txPsd->Copy ();
118  NS_LOG_DEBUG ("Average tx power " << 10*log10(Sum (*txPsd) * 180e3) << " dB");
119 
120  // create the noise PSD
122  NS_LOG_DEBUG ("Average noise power " << 10*log10 (Sum (*noisePsd) * 180e3) << " dB");
123 
124  // apply the pathloss
125  double propagationGainDb = m_propagationLossModel->CalcRxPower (0, txMob, rxMob);
126  NS_LOG_DEBUG ("Pathloss " << -propagationGainDb << " dB");
127  double propagationGainLinear = std::pow (10.0, (propagationGainDb) / 10.0);
128  *(rxPsd) *= propagationGainLinear;
129 
130  // apply the fast fading and the beamforming gain
131  rxPsd = m_spectrumLossModel->CalcRxPowerSpectralDensity (rxPsd, txMob, rxMob);
132  NS_LOG_DEBUG ("Average rx power " << 10*log10 (Sum (*rxPsd) * 180e3) << " dB");
133 
134  // compute the SNR
135  NS_LOG_DEBUG ("Average SNR " << 10 * log10 (Sum (*rxPsd) / Sum (*noisePsd)) << " dB");
136 
137  // print the SNR and pathloss values in the snr-trace.txt file
138  std::ofstream f;
139  f.open ("snr-trace.txt", std::ios::out | std::ios::app);
140  f << Simulator::Now ().GetSeconds () << " " << 10 * log10 (Sum (*rxPsd) / Sum (*noisePsd)) << " " << propagationGainDb << std::endl;
141  f.close ();
142 }
143 
144 int
145 main (int argc, char *argv[])
146 {
147  double frequency = 2125.0e6; // operating frequency in Hz (corresponds to EARFCN 2100)
148  double txPow = 49.0; // tx power in dBm
149  double noiseFigure = 9.0; // noise figure in dB
150  double distance = 10.0; // distance between tx and rx nodes in meters
151  uint32_t simTime = 10000; // simulation time in milliseconds
152  uint32_t timeRes = 10; // time resolution in milliseconds
153  std::string scenario = "UMa"; // 3GPP propagation scenario
154 
155  Config::SetDefault ("ns3::ThreeGppChannelModel::UpdatePeriod", TimeValue(MilliSeconds (1))); // update the channel at each iteration
156  Config::SetDefault ("ns3::ThreeGppChannelConditionModel::UpdatePeriod", TimeValue(MilliSeconds (0.0))); // do not update the channel condition
157 
160 
161  // create and configure the factories for the channel condition and propagation loss models
162  ObjectFactory propagationLossModelFactory;
163  ObjectFactory channelConditionModelFactory;
164  if (scenario == "RMa")
165  {
166  propagationLossModelFactory.SetTypeId (ThreeGppRmaPropagationLossModel::GetTypeId ());
167  channelConditionModelFactory.SetTypeId (ThreeGppRmaChannelConditionModel::GetTypeId ());
168  }
169  else if (scenario == "UMa")
170  {
171  propagationLossModelFactory.SetTypeId (ThreeGppUmaPropagationLossModel::GetTypeId ());
172  channelConditionModelFactory.SetTypeId (ThreeGppUmaChannelConditionModel::GetTypeId ());
173  }
174  else if (scenario == "UMi-StreetCanyon")
175  {
176  propagationLossModelFactory.SetTypeId (ThreeGppUmiStreetCanyonPropagationLossModel::GetTypeId ());
177  channelConditionModelFactory.SetTypeId (ThreeGppUmiStreetCanyonChannelConditionModel::GetTypeId ());
178  }
179  else if (scenario == "InH-OfficeOpen")
180  {
181  propagationLossModelFactory.SetTypeId (ThreeGppIndoorOfficePropagationLossModel::GetTypeId ());
183  }
184  else if (scenario == "InH-OfficeMixed")
185  {
186  propagationLossModelFactory.SetTypeId (ThreeGppIndoorOfficePropagationLossModel::GetTypeId ());
188  }
189  else
190  {
191  NS_FATAL_ERROR ("Unknown scenario");
192  }
193 
194  // create the propagation loss model
195  m_propagationLossModel = propagationLossModelFactory.Create<ThreeGppPropagationLossModel> ();
196  m_propagationLossModel->SetAttribute ("Frequency", DoubleValue (frequency));
197  m_propagationLossModel->SetAttribute ("ShadowingEnabled", BooleanValue (false));
198 
199  // create the spectrum propagation loss model
200  m_spectrumLossModel = CreateObject<ThreeGppSpectrumPropagationLossModel> ();
201  m_spectrumLossModel->SetChannelModelAttribute ("Frequency", DoubleValue (frequency));
202  m_spectrumLossModel->SetChannelModelAttribute ("Scenario", StringValue (scenario));
203 
204  // create the channel condition model and associate it with the spectrum and
205  // propagation loss model
206  Ptr<ChannelConditionModel> condModel = channelConditionModelFactory.Create<ThreeGppChannelConditionModel> ();
207  m_spectrumLossModel->SetChannelModelAttribute ("ChannelConditionModel", PointerValue (condModel));
209 
210  // create the tx and rx nodes
212  nodes.Create (2);
213 
214  // create the tx and rx devices
215  Ptr<SimpleNetDevice> txDev = CreateObject<SimpleNetDevice> ();
216  Ptr<SimpleNetDevice> rxDev = CreateObject<SimpleNetDevice> ();
217 
218  // associate the nodes and the devices
219  nodes.Get (0)->AddDevice (txDev);
220  txDev->SetNode (nodes.Get (0));
221  nodes.Get (1)->AddDevice (rxDev);
222  rxDev->SetNode (nodes.Get (1));
223 
224  // create the tx and rx mobility models, set the positions
225  Ptr<MobilityModel> txMob = CreateObject<ConstantPositionMobilityModel> ();
226  txMob->SetPosition (Vector (0.0,0.0,10.0));
227  Ptr<MobilityModel> rxMob = CreateObject<ConstantPositionMobilityModel> ();
228  rxMob->SetPosition (Vector (distance,0.0,1.6));
229 
230  // assign the mobility models to the nodes
231  nodes.Get (0)->AggregateObject (txMob);
232  nodes.Get (1)->AggregateObject (rxMob);
233 
234  // create the antenna objects and set their dimensions
235  Ptr<ThreeGppAntennaArrayModel> txAntenna = CreateObjectWithAttributes<ThreeGppAntennaArrayModel> ("NumColumns", UintegerValue (2), "NumRows", UintegerValue (2));
236  Ptr<ThreeGppAntennaArrayModel> rxAntenna = CreateObjectWithAttributes<ThreeGppAntennaArrayModel> ("NumColumns", UintegerValue (2), "NumRows", UintegerValue (2));
237 
238  // initialize the devices in the ThreeGppSpectrumPropagationLossModel
239  m_spectrumLossModel->AddDevice (txDev, txAntenna);
240  m_spectrumLossModel->AddDevice (rxDev, rxAntenna);
241 
242  // set the beamforming vectors
243  DoBeamforming (txDev, txAntenna, rxDev);
244  DoBeamforming (rxDev, rxAntenna, txDev);
245 
246  for (int i = 0; i < floor (simTime / timeRes); i++)
247  {
248  Simulator::Schedule (MilliSeconds (timeRes*i), &ComputeSnr, txMob, rxMob, txPow, noiseFigure);
249  }
250 
251  Simulator::Run ();
253  return 0;
254 }
static Ptr< ThreeGppPropagationLossModel > m_propagationLossModel
the PropagationLossModel object
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
virtual uint64_t GetNumberOfElements(void) const
Returns the number of antenna elements.
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...
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...
AttributeValue implementation for Boolean.
Definition: boolean.h:36
std::vector< std::complex< double > > ComplexVector
type definition for complex vectors
Hold variables of type string.
Definition: string.h:41
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:379
static void Run(void)
Run the simulation.
Definition: simulator.cc:172
virtual Ptr< Node > GetNode(void) const =0
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1286
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
double theta
the inclination angle in radians
Definition: angles.h:117
static TypeId GetTypeId(void)
Get the type ID.
static Vector GetPosition(Ptr< Node > node)
Definition: wifi-ap.cc:96
static void SetRun(uint64_t run)
Set the run number of simulation.
virtual Vector GetElementLocation(uint64_t index) const
Returns the location of the antenna element with the specified index assuming the left bottom corner ...
static void ComputeSnr(Ptr< MobilityModel > txMob, Ptr< MobilityModel > rxMob, double txPow, double noiseFigure)
Compute the average SNR.
static Ptr< ThreeGppSpectrumPropagationLossModel > m_spectrumLossModel
the SpectrumPropagationLossModel object
Keep track of the current position and velocity of an object.
virtual void SetNode(Ptr< Node > node)
nodes
Definition: first.py:32
AttributeValue implementation for Time.
Definition: nstime.h:1342
Ptr< Object > Create(void) const
Create an Object instance of the configured TypeId.
Hold an unsigned integer type.
Definition: uinteger.h:44
static TypeId GetTypeId(void)
Get the type ID.
Base class for the 3GPP channel condition models.
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:136
Ptr< SpectrumValue > Copy() const
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
void SetBeamformingVector(const ComplexVector &beamformingVector)
Sets the beamforming vector to be used.
double f(double x, void *params)
Definition: 80211b.c:70
Every class exported by the ns3 library is enclosed in the ns3 namespace.
keep track of a set of node pointers.
Hold objects of type Ptr<T>.
Definition: pointer.h:36
static Ptr< SpectrumValue > CreateNoisePowerSpectralDensity(uint32_t earfcn, uint16_t bandwidth, double noiseFigure)
create a SpectrumValue that models the power spectral density of AWGN
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
void SetPosition(const Vector &position)
static void SetSeed(uint32_t seed)
Set the seed.
static TypeId GetTypeId(void)
Get the type ID.
Instantiate subclasses of ns3::Object.
static TypeId GetTypeId(void)
Get the type ID.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
static void DoBeamforming(Ptr< NetDevice > thisDevice, Ptr< ThreeGppAntennaArrayModel > thisAntenna, Ptr< NetDevice > otherDevice)
Perform the beamforming using the DFT beamforming method.
void SetChannelConditionModel(Ptr< ChannelConditionModel > model)
Set the channel condition model used to determine the channel state (e.g., the LOS/NLOS condition) ...
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
double phi
the azimuth angle in radians
Definition: angles.h:111
double Sum(const SpectrumValue &x)
Base class for the 3GPP propagation models.
struct holding the azimuth and inclination angles of spherical coordinates.
Definition: angles.h:71
This class can be used to hold variables of floating point type such as &#39;double&#39; or &#39;float&#39;...
Definition: double.h:41
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185