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 }
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
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
Hold variables of type string.
Definition: string.h:41
virtual uint64_t GetNumberOfElements(void) const =0
Returns the number of antenna elements.
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:380
static void DoBeamforming(Ptr< NetDevice > thisDevice, Ptr< PhasedArrayModel > thisAntenna, Ptr< NetDevice > otherDevice)
Perform the beamforming using the DFT beamforming method.
static void Run(void)
Run the simulation.
Definition: simulator.cc:172
virtual Ptr< Node > GetNode(void) const =0
Class holding the azimuth and inclination angles of spherical coordinates.
Definition: angles.h:118
#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:1297
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
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.
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:1353
Ptr< Object > Create(void) const
Create an Object instance of the configured TypeId.
double GetAzimuth(void) const
Getter for azimuth angle.
Definition: angles.cc:222
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.
virtual Vector GetElementLocation(uint64_t index) const =0
Returns the location of the antenna element with the specified index, normalized with respect to the ...
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.
std::vector< std::complex< double > > ComplexVector
type definition for complex vectors
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
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 GetInclination(void) const
Getter for inclination angle.
Definition: angles.cc:229
double Sum(const SpectrumValue &x)
Base class for the 3GPP propagation models.
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