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 }
GetPosition
static Vector GetPosition(Ptr< Node > node)
Definition: wifi-ap.cc:96
NS_LOG_COMPONENT_DEFINE
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
ns3::SpectrumValue::Copy
Ptr< SpectrumValue > Copy() const
Definition: spectrum-value.cc:409
ns3::BooleanValue
AttributeValue implementation for Boolean.
Definition: boolean.h:37
ns3::Angles::GetInclination
double GetInclination(void) const
Getter for inclination angle.
Definition: angles.cc:229
m_spectrumLossModel
static Ptr< ThreeGppSpectrumPropagationLossModel > m_spectrumLossModel
the SpectrumPropagationLossModel object
Definition: three-gpp-channel-example.cc:51
ns3::Simulator::Now
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
ns3
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ns3::Sum
double Sum(const SpectrumValue &x)
Definition: spectrum-value.cc:362
ns3::PhasedArrayModel::SetBeamformingVector
void SetBeamformingVector(const ComplexVector &beamformingVector)
Sets the beamforming vector to be used.
Definition: phased-array-model.cc:83
ns3::Object::GetObject
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
ns3::MobilityModel::SetPosition
void SetPosition(const Vector &position)
Definition: mobility-model.cc:88
ns3::PropagationLossModel::CalcRxPower
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.
Definition: propagation-loss-model.cc:73
m_propagationLossModel
static Ptr< ThreeGppPropagationLossModel > m_propagationLossModel
the PropagationLossModel object
Definition: three-gpp-channel-example.cc:50
ns3::PointerValue
Hold objects of type Ptr<T>.
Definition: pointer.h:37
ns3::ObjectBase::SetAttribute
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185
ns3::ThreeGppIndoorOfficePropagationLossModel::GetTypeId
static TypeId GetTypeId(void)
Get the type ID.
Definition: three-gpp-propagation-loss-model.cc:922
ns3::LteSpectrumValueHelper::CreateNoisePowerSpectralDensity
static Ptr< SpectrumValue > CreateNoisePowerSpectralDensity(uint32_t earfcn, uint16_t bandwidth, double noiseFigure)
create a SpectrumValue that models the power spectral density of AWGN
Definition: lte-spectrum-value-helper.cc:360
ns3::Simulator::Schedule
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:556
ns3::DoubleValue
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:41
ns3::ThreeGppUmaChannelConditionModel::GetTypeId
static TypeId GetTypeId(void)
Get the type ID.
Definition: channel-condition-model.cc:488
ns3::RngSeedManager::SetRun
static void SetRun(uint64_t run)
Set the run number of simulation.
Definition: rng-seed-manager.cc:87
first.nodes
nodes
Definition: first.py:32
ComputeSnr
static void ComputeSnr(Ptr< MobilityModel > txMob, Ptr< MobilityModel > rxMob, double txPow, double noiseFigure)
Compute the average SNR.
Definition: three-gpp-channel-example.cc:102
ns3::Ptr< ThreeGppPropagationLossModel >
ns3::ThreeGppRmaPropagationLossModel::GetTypeId
static TypeId GetTypeId(void)
Get the type ID.
Definition: three-gpp-propagation-loss-model.cc:301
NS_FATAL_ERROR
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
ns3::ThreeGppIndoorOpenOfficeChannelConditionModel::GetTypeId
static TypeId GetTypeId(void)
Get the type ID.
Definition: channel-condition-model.cc:666
ns3::ThreeGppRmaChannelConditionModel::GetTypeId
static TypeId GetTypeId(void)
Get the type ID.
Definition: channel-condition-model.cc:442
ns3::NetDevice::GetNode
virtual Ptr< Node > GetNode(void) const =0
ns3::MilliSeconds
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1297
ns3::ObjectFactory
Instantiate subclasses of ns3::Object.
Definition: object-factory.h:48
DoBeamforming
static void DoBeamforming(Ptr< NetDevice > thisDevice, Ptr< PhasedArrayModel > thisAntenna, Ptr< NetDevice > otherDevice)
Perform the beamforming using the DFT beamforming method.
Definition: three-gpp-channel-example.cc:60
ns3::ThreeGppUmiStreetCanyonChannelConditionModel::GetTypeId
static TypeId GetTypeId(void)
Get the type ID.
Definition: channel-condition-model.cc:556
ns3::RngSeedManager::SetSeed
static void SetSeed(uint32_t seed)
Set the seed.
Definition: rng-seed-manager.cc:81
ns3::Simulator::Run
static void Run(void)
Run the simulation.
Definition: simulator.cc:172
ns3::StringValue
Hold variables of type string.
Definition: string.h:41
ns3::SimpleNetDevice::SetNode
virtual void SetNode(Ptr< Node > node)
Definition: simple-net-device.cc:513
ns3::ThreeGppUmiStreetCanyonPropagationLossModel::GetTypeId
static TypeId GetTypeId(void)
Get the type ID.
Definition: three-gpp-propagation-loss-model.cc:715
ns3::Angles
Class holding the azimuth and inclination angles of spherical coordinates.
Definition: angles.h:119
NS_LOG_DEBUG
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
ns3::Angles::GetAzimuth
double GetAzimuth(void) const
Getter for azimuth angle.
Definition: angles.cc:222
ns3::ThreeGppIndoorMixedOfficeChannelConditionModel::GetTypeId
static TypeId GetTypeId(void)
Get the type ID.
Definition: channel-condition-model.cc:609
ns3::Simulator::Destroy
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:136
f
double f(double x, void *params)
Definition: 80211b.c:70
ns3::ThreeGppUmaPropagationLossModel::GetTypeId
static TypeId GetTypeId(void)
Get the type ID.
Definition: three-gpp-propagation-loss-model.cc:502
ns3::TimeValue
AttributeValue implementation for Time.
Definition: nstime.h:1353
ns3::MobilityModel
Keep track of the current position and velocity of an object.
Definition: mobility-model.h:40
ns3::NodeContainer
keep track of a set of node pointers.
Definition: node-container.h:39
ns3::PhasedArrayModel::GetElementLocation
virtual Vector GetElementLocation(uint64_t index) const =0
Returns the location of the antenna element with the specified index, normalized with respect to the ...
ns3::ThreeGppPropagationLossModel
Base class for the 3GPP propagation models.
Definition: three-gpp-propagation-loss-model.h:32
ns3::ObjectFactory::SetTypeId
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
Definition: object-factory.cc:40
ns3::UintegerValue
Hold an unsigned integer type.
Definition: uinteger.h:44
ns3::ObjectFactory::Create
Ptr< Object > Create(void) const
Create an Object instance of the configured TypeId.
Definition: object-factory.cc:98
ns3::Config::SetDefault
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
ns3::PhasedArrayModel::GetNumberOfElements
virtual uint64_t GetNumberOfElements(void) const =0
Returns the number of antenna elements.
ns3::LteSpectrumValueHelper::CreateTxPowerSpectralDensity
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.
Definition: lte-spectrum-value-helper.cc:274
ns3::PhasedArrayModel::ComplexVector
std::vector< std::complex< double > > ComplexVector
type definition for complex vectors
Definition: phased-array-model.h:54
ns3::ThreeGppPropagationLossModel::SetChannelConditionModel
void SetChannelConditionModel(Ptr< ChannelConditionModel > model)
Set the channel condition model used to determine the channel state (e.g., the LOS/NLOS condition)
Definition: three-gpp-propagation-loss-model.cc:90
ns3::ThreeGppChannelConditionModel
Base class for the 3GPP channel condition models.
Definition: channel-condition-model.h:447
ns3::Time::GetSeconds
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:380