A Discrete-Event Network Simulator
API
three-gpp-channel-example.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019 SIGNET Lab, Department of Information Engineering,
3  * University of Padova
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */
18 
30 #include "ns3/channel-condition-model.h"
31 #include "ns3/constant-position-mobility-model.h"
32 #include "ns3/core-module.h"
33 #include "ns3/lte-spectrum-value-helper.h"
34 #include "ns3/mobility-model.h"
35 #include "ns3/net-device.h"
36 #include "ns3/node-container.h"
37 #include "ns3/node.h"
38 #include "ns3/simple-net-device.h"
39 #include "ns3/spectrum-signal-parameters.h"
40 #include "ns3/three-gpp-channel-model.h"
41 #include "ns3/three-gpp-propagation-loss-model.h"
42 #include "ns3/three-gpp-spectrum-propagation-loss-model.h"
43 #include "ns3/uniform-planar-array.h"
44 
45 #include <fstream>
46 
47 NS_LOG_COMPONENT_DEFINE("ThreeGppChannelExample");
48 
49 using namespace ns3;
50 
55 
61 struct ComputeSnrParams
62 {
63  Ptr<MobilityModel> txMob;
64  Ptr<MobilityModel> rxMob;
65  double txPow;
66  double noiseFigure;
67  Ptr<PhasedArrayModel> txAntenna;
68  Ptr<PhasedArrayModel> rxAntenna;
69 };
70 
77 static void
79  Ptr<PhasedArrayModel> thisAntenna,
80  Ptr<NetDevice> otherDevice)
81 {
82  // retrieve the position of the two devices
83  Vector aPos = thisDevice->GetNode()->GetObject<MobilityModel>()->GetPosition();
84  Vector bPos = otherDevice->GetNode()->GetObject<MobilityModel>()->GetPosition();
85 
86  // compute the azimuth and the elevation angles
87  Angles completeAngle(bPos, aPos);
88  double hAngleRadian = completeAngle.GetAzimuth();
89 
90  double vAngleRadian = completeAngle.GetInclination(); // the elevation angle
91 
92  // retrieve the number of antenna elements and resize the vector
93  uint64_t totNoArrayElements = thisAntenna->GetNumElems();
94  PhasedArrayModel::ComplexVector antennaWeights(totNoArrayElements);
95 
96  // the total power is divided equally among the antenna elements
97  double power = 1.0 / sqrt(totNoArrayElements);
98 
99  // compute the antenna weights
100  const double sinVAngleRadian = sin(vAngleRadian);
101  const double cosVAngleRadian = cos(vAngleRadian);
102  const double sinHAngleRadian = sin(hAngleRadian);
103  const double cosHAngleRadian = cos(hAngleRadian);
104 
105  for (uint64_t ind = 0; ind < totNoArrayElements; ind++)
106  {
107  Vector loc = thisAntenna->GetElementLocation(ind);
108  double phase = -2 * M_PI *
109  (sinVAngleRadian * cosHAngleRadian * loc.x +
110  sinVAngleRadian * sinHAngleRadian * loc.y + cosVAngleRadian * loc.z);
111  antennaWeights[ind] = exp(std::complex<double>(0, phase)) * power;
112  }
113 
114  // store the antenna weights
115  thisAntenna->SetBeamformingVector(antennaWeights);
116 }
117 
123 static void
125 {
126  // Create the tx PSD using the LteSpectrumValueHelper
127  // 100 RBs corresponds to 18 MHz (1 RB = 180 kHz)
128  // EARFCN 100 corresponds to 2125.00 MHz
129  std::vector<int> activeRbs0(100);
130  for (int i = 0; i < 100; i++)
131  {
132  activeRbs0[i] = i;
133  }
134  auto txPsd =
135  LteSpectrumValueHelper::CreateTxPowerSpectralDensity(2100, 100, params.txPow, activeRbs0);
136  auto txParams = Create<SpectrumSignalParameters>();
137  txParams->psd = txPsd->Copy();
138  NS_LOG_DEBUG("Average tx power " << 10 * log10(Sum(*txPsd) * 180e3) << " dB");
139 
140  // create the noise PSD
141  auto noisePsd =
143  NS_LOG_DEBUG("Average noise power " << 10 * log10(Sum(*noisePsd) * 180e3) << " dB");
144 
145  // apply the pathloss
146  double propagationGainDb = m_propagationLossModel->CalcRxPower(0, params.txMob, params.rxMob);
147  NS_LOG_DEBUG("Pathloss " << -propagationGainDb << " dB");
148  double propagationGainLinear = std::pow(10.0, (propagationGainDb) / 10.0);
149  *(txParams->psd) *= propagationGainLinear;
150 
151  NS_ASSERT_MSG(params.txAntenna, "params.txAntenna is nullptr!");
152  NS_ASSERT_MSG(params.rxAntenna, "params.rxAntenna is nullptr!");
153 
154  // apply the fast fading and the beamforming gain
155  auto rxParams = m_spectrumLossModel->CalcRxPowerSpectralDensity(txParams,
156  params.txMob,
157  params.rxMob,
158  params.txAntenna,
159  params.rxAntenna);
160  auto rxPsd = rxParams->psd;
161  NS_LOG_DEBUG("Average rx power " << 10 * log10(Sum(*rxPsd) * 180e3) << " dB");
162 
163  // compute the SNR
164  NS_LOG_DEBUG("Average SNR " << 10 * log10(Sum(*rxPsd) / Sum(*noisePsd)) << " dB");
165 
166  // print the SNR and pathloss values in the snr-trace.txt file
167  std::ofstream f;
168  f.open("snr-trace.txt", std::ios::out | std::ios::app);
169  f << Simulator::Now().GetSeconds() << " " << 10 * log10(Sum(*rxPsd) / Sum(*noisePsd)) << " "
170  << propagationGainDb << std::endl;
171  f.close();
172 }
173 
174 int
175 main(int argc, char* argv[])
176 {
177  double frequency = 2125.0e6; // operating frequency in Hz (corresponds to EARFCN 2100)
178  double txPow = 49.0; // tx power in dBm
179  double noiseFigure = 9.0; // noise figure in dB
180  double distance = 10.0; // distance between tx and rx nodes in meters
181  uint32_t simTime = 1000; // simulation time in milliseconds
182  uint32_t timeRes = 10; // time resolution in milliseconds
183  std::string scenario = "UMa"; // 3GPP propagation scenario
184 
185  Config::SetDefault("ns3::ThreeGppChannelModel::UpdatePeriod",
186  TimeValue(MilliSeconds(1))); // update the channel at each iteration
187  Config::SetDefault("ns3::ThreeGppChannelConditionModel::UpdatePeriod",
188  TimeValue(MilliSeconds(0.0))); // do not update the channel condition
189 
192 
193  // create and configure the factories for the channel condition and propagation loss models
194  ObjectFactory propagationLossModelFactory;
195  ObjectFactory channelConditionModelFactory;
196  if (scenario == "RMa")
197  {
198  propagationLossModelFactory.SetTypeId(ThreeGppRmaPropagationLossModel::GetTypeId());
199  channelConditionModelFactory.SetTypeId(ThreeGppRmaChannelConditionModel::GetTypeId());
200  }
201  else if (scenario == "UMa")
202  {
203  propagationLossModelFactory.SetTypeId(ThreeGppUmaPropagationLossModel::GetTypeId());
204  channelConditionModelFactory.SetTypeId(ThreeGppUmaChannelConditionModel::GetTypeId());
205  }
206  else if (scenario == "UMi-StreetCanyon")
207  {
208  propagationLossModelFactory.SetTypeId(
210  channelConditionModelFactory.SetTypeId(
212  }
213  else if (scenario == "InH-OfficeOpen")
214  {
215  propagationLossModelFactory.SetTypeId(
217  channelConditionModelFactory.SetTypeId(
219  }
220  else if (scenario == "InH-OfficeMixed")
221  {
222  propagationLossModelFactory.SetTypeId(
224  channelConditionModelFactory.SetTypeId(
226  }
227  else
228  {
229  NS_FATAL_ERROR("Unknown scenario");
230  }
231 
232  // create the propagation loss model
233  m_propagationLossModel = propagationLossModelFactory.Create<ThreeGppPropagationLossModel>();
234  m_propagationLossModel->SetAttribute("Frequency", DoubleValue(frequency));
235  m_propagationLossModel->SetAttribute("ShadowingEnabled", BooleanValue(false));
236 
237  // create the spectrum propagation loss model
238  m_spectrumLossModel = CreateObject<ThreeGppSpectrumPropagationLossModel>();
239  m_spectrumLossModel->SetChannelModelAttribute("Frequency", DoubleValue(frequency));
241 
242  // create the channel condition model and associate it with the spectrum and
243  // propagation loss model
244  Ptr<ChannelConditionModel> condModel =
245  channelConditionModelFactory.Create<ThreeGppChannelConditionModel>();
246  m_spectrumLossModel->SetChannelModelAttribute("ChannelConditionModel", PointerValue(condModel));
248 
249  // create the tx and rx nodes
251  nodes.Create(2);
252 
253  // create the tx and rx devices
254  Ptr<SimpleNetDevice> txDev = CreateObject<SimpleNetDevice>();
255  Ptr<SimpleNetDevice> rxDev = CreateObject<SimpleNetDevice>();
256 
257  // associate the nodes and the devices
258  nodes.Get(0)->AddDevice(txDev);
259  txDev->SetNode(nodes.Get(0));
260  nodes.Get(1)->AddDevice(rxDev);
261  rxDev->SetNode(nodes.Get(1));
262 
263  // create the tx and rx mobility models, set the positions
264  Ptr<MobilityModel> txMob = CreateObject<ConstantPositionMobilityModel>();
265  txMob->SetPosition(Vector(0.0, 0.0, 10.0));
266  Ptr<MobilityModel> rxMob = CreateObject<ConstantPositionMobilityModel>();
267  rxMob->SetPosition(Vector(distance, 0.0, 1.6));
268 
269  // assign the mobility models to the nodes
270  nodes.Get(0)->AggregateObject(txMob);
271  nodes.Get(1)->AggregateObject(rxMob);
272 
273  // create the antenna objects and set their dimensions
274  Ptr<PhasedArrayModel> txAntenna =
275  CreateObjectWithAttributes<UniformPlanarArray>("NumColumns",
276  UintegerValue(2),
277  "NumRows",
278  UintegerValue(2));
279  Ptr<PhasedArrayModel> rxAntenna =
280  CreateObjectWithAttributes<UniformPlanarArray>("NumColumns",
281  UintegerValue(2),
282  "NumRows",
283  UintegerValue(2));
284 
285  // set the beamforming vectors
286  DoBeamforming(txDev, txAntenna, rxDev);
287  DoBeamforming(rxDev, rxAntenna, txDev);
288 
289  for (int i = 0; i < floor(simTime / timeRes); i++)
290  {
291  ComputeSnrParams params{txMob, rxMob, txPow, noiseFigure, txAntenna, rxAntenna};
293  }
294 
295  Simulator::Run();
297  return 0;
298 }
double f(double x, void *params)
Definition: 80211b.c:70
Class holding the azimuth and inclination angles of spherical coordinates.
Definition: angles.h:118
double GetInclination() const
Getter for inclination angle.
Definition: angles.cc:246
double GetAzimuth() const
Getter for azimuth angle.
Definition: angles.cc:240
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
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.
MatrixArray class inherits ValArray class and provides additional interfaces to ValArray which enable...
Definition: matrix-array.h:83
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 Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:138
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:204
Instantiate subclasses of ns3::Object.
Ptr< Object > Create() 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.
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:259
virtual Vector GetElementLocation(uint64_t index) const =0
Returns the location of the antenna element with the specified index, normalized with respect to the ...
void SetBeamformingVector(const ComplexVector &beamformingVector)
Sets the beamforming vector to be used.
virtual size_t GetNumElems() const =0
Returns the number of antenna elements.
Ptr< SpectrumSignalParameters > CalcRxPowerSpectralDensity(Ptr< const SpectrumSignalParameters > 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 EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
static void Run()
Run the simulation.
Definition: simulator.cc:178
Hold variables of type string.
Definition: string.h:56
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()
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()
Get the type ID.
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:403
Hold an unsigned integer type.
Definition: uinteger.h:45
#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:86
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:890
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
NodeContainer nodes
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double Sum(const SpectrumValue &x)
params
Fit Fluctuating Two Ray model to the 3GPP TR 38.901 using the Anderson-Darling goodness-of-fit ##.
A structure that holds the parameters for the ComputeSnr function.
double txPow
the tx power in dBm
Ptr< SpectrumValue > psd
The Power Spectral Density of the waveform, in linear units.
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(const ComputeSnrParams &params)
Compute the average SNR.
static Ptr< ThreeGppSpectrumPropagationLossModel > m_spectrumLossModel
the SpectrumPropagationLossModel object