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 {
62  double txPow;
63  double noiseFigure;
66 
76  ComputeSnrParams (Ptr<MobilityModel> pTxMob, Ptr<MobilityModel> pRxMob, double pTxPow, double pNoiseFigure,
77  Ptr<PhasedArrayModel> pTxAntenna, Ptr<PhasedArrayModel> pRxAntenna)
78  {
79  txMob = pTxMob;
80  rxMob = pRxMob;
81  txPow = pTxPow;
82  noiseFigure = pNoiseFigure;
83  txAntenna = pTxAntenna;
84  rxAntenna = pRxAntenna;
85  }
86 };
87 
94 static void
95 DoBeamforming (Ptr<NetDevice> thisDevice, Ptr<PhasedArrayModel> thisAntenna, Ptr<NetDevice> otherDevice)
96 {
97  PhasedArrayModel::ComplexVector antennaWeights;
98 
99  // retrieve the position of the two devices
100  Vector aPos = thisDevice->GetNode ()->GetObject<MobilityModel> ()->GetPosition ();
101  Vector bPos = otherDevice->GetNode ()->GetObject<MobilityModel> ()->GetPosition ();
102 
103  // compute the azimuth and the elevation angles
104  Angles completeAngle (bPos,aPos);
105  double hAngleRadian = completeAngle.GetAzimuth ();
106 
107  double vAngleRadian = completeAngle.GetInclination (); // the elevation angle
108 
109  // retrieve the number of antenna elements
110  int totNoArrayElements = thisAntenna->GetNumberOfElements ();
111 
112  // the total power is divided equally among the antenna elements
113  double power = 1 / sqrt (totNoArrayElements);
114 
115  // compute the antenna weights
116  for (int ind = 0; ind < totNoArrayElements; ind++)
117  {
118  Vector loc = thisAntenna->GetElementLocation (ind);
119  double phase = -2 * M_PI * (sin (vAngleRadian) * cos (hAngleRadian) * loc.x
120  + sin (vAngleRadian) * sin (hAngleRadian) * loc.y
121  + cos (vAngleRadian) * loc.z);
122  antennaWeights.push_back (exp (std::complex<double> (0, phase)) * power);
123  }
124 
125  // store the antenna weights
126  thisAntenna->SetBeamformingVector (antennaWeights);
127 }
128 
133 static void
135 {
136  // Create the tx PSD using the LteSpectrumValueHelper
137  // 100 RBs corresponds to 18 MHz (1 RB = 180 kHz)
138  // EARFCN 100 corresponds to 2125.00 MHz
139  std::vector<int> activeRbs0 (100);
140  for (int i = 0; i < 100 ; i++)
141  {
142  activeRbs0[i] = i;
143  }
144  Ptr<SpectrumValue> txPsd = LteSpectrumValueHelper::CreateTxPowerSpectralDensity (2100, 100, params.txPow, activeRbs0);
145  Ptr<SpectrumValue> rxPsd = txPsd->Copy ();
146  NS_LOG_DEBUG ("Average tx power " << 10*log10(Sum (*txPsd) * 180e3) << " dB");
147 
148  // create the noise PSD
150  NS_LOG_DEBUG ("Average noise power " << 10*log10 (Sum (*noisePsd) * 180e3) << " dB");
151 
152  // apply the pathloss
153  double propagationGainDb = m_propagationLossModel->CalcRxPower (0, params.txMob, params.rxMob);
154  NS_LOG_DEBUG ("Pathloss " << -propagationGainDb << " dB");
155  double propagationGainLinear = std::pow (10.0, (propagationGainDb) / 10.0);
156  *(rxPsd) *= propagationGainLinear;
157 
158  NS_ASSERT_MSG (params.txAntenna, "params.txAntenna is nullptr!");
159  NS_ASSERT_MSG (params.rxAntenna, "params.rxAntenna is nullptr!");
160 
161  // apply the fast fading and the beamforming gain
162  rxPsd = m_spectrumLossModel->CalcRxPowerSpectralDensity (rxPsd, params.txMob, params.rxMob, params.txAntenna, params.rxAntenna);
163  NS_LOG_DEBUG ("Average rx power " << 10 * log10 (Sum (*rxPsd) * 180e3) << " dB");
164 
165  // compute the SNR
166  NS_LOG_DEBUG ("Average SNR " << 10 * log10 (Sum (*rxPsd) / Sum (*noisePsd)) << " dB");
167 
168  // print the SNR and pathloss values in the snr-trace.txt file
169  std::ofstream f;
170  f.open ("snr-trace.txt", std::ios::out | std::ios::app);
171  f << Simulator::Now ().GetSeconds () << " " << 10 * log10 (Sum (*rxPsd) / Sum (*noisePsd)) << " " << propagationGainDb << std::endl;
172  f.close ();
173 }
174 
175 int
176 main (int argc, char *argv[])
177 {
178  double frequency = 2125.0e6; // operating frequency in Hz (corresponds to EARFCN 2100)
179  double txPow = 49.0; // tx power in dBm
180  double noiseFigure = 9.0; // noise figure in dB
181  double distance = 10.0; // distance between tx and rx nodes in meters
182  uint32_t simTime = 10000; // simulation time in milliseconds
183  uint32_t timeRes = 10; // time resolution in milliseconds
184  std::string scenario = "UMa"; // 3GPP propagation scenario
185 
186  Config::SetDefault ("ns3::ThreeGppChannelModel::UpdatePeriod", TimeValue(MilliSeconds (1))); // update the channel at each iteration
187  Config::SetDefault ("ns3::ThreeGppChannelConditionModel::UpdatePeriod", TimeValue(MilliSeconds (0.0))); // do not update the channel condition
188 
191 
192  // create and configure the factories for the channel condition and propagation loss models
193  ObjectFactory propagationLossModelFactory;
194  ObjectFactory channelConditionModelFactory;
195  if (scenario == "RMa")
196  {
197  propagationLossModelFactory.SetTypeId (ThreeGppRmaPropagationLossModel::GetTypeId ());
198  channelConditionModelFactory.SetTypeId (ThreeGppRmaChannelConditionModel::GetTypeId ());
199  }
200  else if (scenario == "UMa")
201  {
202  propagationLossModelFactory.SetTypeId (ThreeGppUmaPropagationLossModel::GetTypeId ());
203  channelConditionModelFactory.SetTypeId (ThreeGppUmaChannelConditionModel::GetTypeId ());
204  }
205  else if (scenario == "UMi-StreetCanyon")
206  {
207  propagationLossModelFactory.SetTypeId (ThreeGppUmiStreetCanyonPropagationLossModel::GetTypeId ());
208  channelConditionModelFactory.SetTypeId (ThreeGppUmiStreetCanyonChannelConditionModel::GetTypeId ());
209  }
210  else if (scenario == "InH-OfficeOpen")
211  {
212  propagationLossModelFactory.SetTypeId (ThreeGppIndoorOfficePropagationLossModel::GetTypeId ());
214  }
215  else if (scenario == "InH-OfficeMixed")
216  {
217  propagationLossModelFactory.SetTypeId (ThreeGppIndoorOfficePropagationLossModel::GetTypeId ());
219  }
220  else
221  {
222  NS_FATAL_ERROR ("Unknown scenario");
223  }
224 
225  // create the propagation loss model
226  m_propagationLossModel = propagationLossModelFactory.Create<ThreeGppPropagationLossModel> ();
227  m_propagationLossModel->SetAttribute ("Frequency", DoubleValue (frequency));
228  m_propagationLossModel->SetAttribute ("ShadowingEnabled", BooleanValue (false));
229 
230  // create the spectrum propagation loss model
231  m_spectrumLossModel = CreateObject<ThreeGppSpectrumPropagationLossModel> ();
232  m_spectrumLossModel->SetChannelModelAttribute ("Frequency", DoubleValue (frequency));
233  m_spectrumLossModel->SetChannelModelAttribute ("Scenario", StringValue (scenario));
234 
235  // create the channel condition model and associate it with the spectrum and
236  // propagation loss model
237  Ptr<ChannelConditionModel> condModel = channelConditionModelFactory.Create<ThreeGppChannelConditionModel> ();
238  m_spectrumLossModel->SetChannelModelAttribute ("ChannelConditionModel", PointerValue (condModel));
240 
241  // create the tx and rx nodes
243  nodes.Create (2);
244 
245  // create the tx and rx devices
246  Ptr<SimpleNetDevice> txDev = CreateObject<SimpleNetDevice> ();
247  Ptr<SimpleNetDevice> rxDev = CreateObject<SimpleNetDevice> ();
248 
249  // associate the nodes and the devices
250  nodes.Get (0)->AddDevice (txDev);
251  txDev->SetNode (nodes.Get (0));
252  nodes.Get (1)->AddDevice (rxDev);
253  rxDev->SetNode (nodes.Get (1));
254 
255  // create the tx and rx mobility models, set the positions
256  Ptr<MobilityModel> txMob = CreateObject<ConstantPositionMobilityModel> ();
257  txMob->SetPosition (Vector (0.0,0.0,10.0));
258  Ptr<MobilityModel> rxMob = CreateObject<ConstantPositionMobilityModel> ();
259  rxMob->SetPosition (Vector (distance,0.0,1.6));
260 
261  // assign the mobility models to the nodes
262  nodes.Get (0)->AggregateObject (txMob);
263  nodes.Get (1)->AggregateObject (rxMob);
264 
265  // create the antenna objects and set their dimensions
266  Ptr<PhasedArrayModel> txAntenna = CreateObjectWithAttributes<UniformPlanarArray> ("NumColumns", UintegerValue (2), "NumRows", UintegerValue (2));
267  Ptr<PhasedArrayModel> rxAntenna = CreateObjectWithAttributes<UniformPlanarArray> ("NumColumns", UintegerValue (2), "NumRows", UintegerValue (2));
268 
269  // set the beamforming vectors
270  DoBeamforming (txDev, txAntenna, rxDev);
271  DoBeamforming (rxDev, rxAntenna, txDev);
272 
273  for (int i = 0; i < floor (simTime / timeRes); i++)
274  {
275  Simulator::Schedule (MilliSeconds (timeRes*i), &ComputeSnr, ComputeSnrParams (txMob, rxMob, txPow, noiseFigure, txAntenna, rxAntenna));
276  }
277 
278  Simulator::Run ();
280  return 0;
281 }
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:231
double GetAzimuth(void) const
Getter for azimuth angle.
Definition: angles.cc:224
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)
virtual Ptr< Node > GetNode(void) const =0
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:256
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.
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
virtual Vector GetElementLocation(uint64_t index) const =0
Returns the location of the antenna element with the specified index, normalized with respect to the ...
virtual uint64_t GetNumberOfElements(void) const =0
Returns the number of antenna elements.
void SetBeamformingVector(const ComplexVector &beamformingVector)
Sets the beamforming vector to be used.
std::vector< std::complex< double > > ComplexVector
type definition for complex vectors
Ptr< SpectrumValue > CalcRxPowerSpectralDensity(Ptr< const SpectrumValue > 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.
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:556
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.
void SetChannelModelAttribute(const std::string &name, const AttributeValue &value)
Sets the value of an attribute belonging to the associated MatrixBasedChannelModel instance.
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:379
AttributeValue implementation for Time.
Definition: nstime.h:1308
Hold an unsigned integer type.
Definition: uinteger.h:44
#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:88
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:1252
nodes
Definition: first.py:32
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double Sum(const SpectrumValue &x)
A structure that holds the parameters for the ComputeSnr function.
Ptr< MobilityModel > rxMob
the rx mobility model
ComputeSnrParams(Ptr< MobilityModel > pTxMob, Ptr< MobilityModel > pRxMob, double pTxPow, double pNoiseFigure, Ptr< PhasedArrayModel > pTxAntenna, Ptr< PhasedArrayModel > pRxAntenna)
Constructor.
Ptr< PhasedArrayModel > rxAntenna
the rx antenna array
double noiseFigure
the noise figure in dB
double txPow
the tx power in dBm
Ptr< PhasedArrayModel > txAntenna
the tx antenna array
Ptr< MobilityModel > txMob
the tx mobility model
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(ComputeSnrParams &params)
Compute the average SNR.
static Ptr< ThreeGppSpectrumPropagationLossModel > m_spectrumLossModel
the SpectrumPropagationLossModel object
static Vector GetPosition(Ptr< Node > node)
Definition: wifi-ap.cc:96