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
47NS_LOG_COMPONENT_DEFINE("ThreeGppChannelExample");
48
49using namespace ns3;
50
55
62{
65 double txPow;
66 double noiseFigure;
69};
70
77static 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->GetNumberOfElements();
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
123static 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 Ptr<SpectrumValue> txPsd =
136 Ptr<SpectrumSignalParameters> 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 Ptr<SpectrumValue> noisePsd =
142 LteSpectrumValueHelper::CreateNoisePowerSpectralDensity(2100, 100, params.noiseFigure);
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
156 params.txMob,
157 params.rxMob,
158 params.txAntenna,
159 params.rxAntenna);
160 NS_LOG_DEBUG("Average rx power " << 10 * log10(Sum(*rxPsd) * 180e3) << " dB");
161
162 // compute the SNR
163 NS_LOG_DEBUG("Average SNR " << 10 * log10(Sum(*rxPsd) / Sum(*noisePsd)) << " dB");
164
165 // print the SNR and pathloss values in the snr-trace.txt file
166 std::ofstream f;
167 f.open("snr-trace.txt", std::ios::out | std::ios::app);
168 f << Simulator::Now().GetSeconds() << " " << 10 * log10(Sum(*rxPsd) / Sum(*noisePsd)) << " "
169 << propagationGainDb << std::endl;
170 f.close();
171}
172
173int
174main(int argc, char* argv[])
175{
176 double frequency = 2125.0e6; // operating frequency in Hz (corresponds to EARFCN 2100)
177 double txPow = 49.0; // tx power in dBm
178 double noiseFigure = 9.0; // noise figure in dB
179 double distance = 10.0; // distance between tx and rx nodes in meters
180 uint32_t simTime = 1000; // simulation time in milliseconds
181 uint32_t timeRes = 10; // time resolution in milliseconds
182 std::string scenario = "UMa"; // 3GPP propagation scenario
183
184 Config::SetDefault("ns3::ThreeGppChannelModel::UpdatePeriod",
185 TimeValue(MilliSeconds(1))); // update the channel at each iteration
186 Config::SetDefault("ns3::ThreeGppChannelConditionModel::UpdatePeriod",
187 TimeValue(MilliSeconds(0.0))); // do not update the channel condition
188
189 RngSeedManager::SetSeed(1);
190 RngSeedManager::SetRun(1);
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(
208 ThreeGppUmiStreetCanyonPropagationLossModel::GetTypeId());
209 channelConditionModelFactory.SetTypeId(
210 ThreeGppUmiStreetCanyonChannelConditionModel::GetTypeId());
211 }
212 else if (scenario == "InH-OfficeOpen")
213 {
214 propagationLossModelFactory.SetTypeId(
215 ThreeGppIndoorOfficePropagationLossModel::GetTypeId());
216 channelConditionModelFactory.SetTypeId(
217 ThreeGppIndoorOpenOfficeChannelConditionModel::GetTypeId());
218 }
219 else if (scenario == "InH-OfficeMixed")
220 {
221 propagationLossModelFactory.SetTypeId(
222 ThreeGppIndoorOfficePropagationLossModel::GetTypeId());
223 channelConditionModelFactory.SetTypeId(
224 ThreeGppIndoorMixedOfficeChannelConditionModel::GetTypeId());
225 }
226 else
227 {
228 NS_FATAL_ERROR("Unknown scenario");
229 }
230
231 // create the propagation loss model
232 m_propagationLossModel = propagationLossModelFactory.Create<ThreeGppPropagationLossModel>();
233 m_propagationLossModel->SetAttribute("Frequency", DoubleValue(frequency));
234 m_propagationLossModel->SetAttribute("ShadowingEnabled", BooleanValue(false));
235
236 // create the spectrum propagation loss model
237 m_spectrumLossModel = CreateObject<ThreeGppSpectrumPropagationLossModel>();
240
241 // create the channel condition model and associate it with the spectrum and
242 // propagation loss model
244 channelConditionModelFactory.Create<ThreeGppChannelConditionModel>();
245 m_spectrumLossModel->SetChannelModelAttribute("ChannelConditionModel", PointerValue(condModel));
247
248 // create the tx and rx nodes
250 nodes.Create(2);
251
252 // create the tx and rx devices
253 Ptr<SimpleNetDevice> txDev = CreateObject<SimpleNetDevice>();
254 Ptr<SimpleNetDevice> rxDev = CreateObject<SimpleNetDevice>();
255
256 // associate the nodes and the devices
257 nodes.Get(0)->AddDevice(txDev);
258 txDev->SetNode(nodes.Get(0));
259 nodes.Get(1)->AddDevice(rxDev);
260 rxDev->SetNode(nodes.Get(1));
261
262 // create the tx and rx mobility models, set the positions
263 Ptr<MobilityModel> txMob = CreateObject<ConstantPositionMobilityModel>();
264 txMob->SetPosition(Vector(0.0, 0.0, 10.0));
265 Ptr<MobilityModel> rxMob = CreateObject<ConstantPositionMobilityModel>();
266 rxMob->SetPosition(Vector(distance, 0.0, 1.6));
267
268 // assign the mobility models to the nodes
269 nodes.Get(0)->AggregateObject(txMob);
270 nodes.Get(1)->AggregateObject(rxMob);
271
272 // create the antenna objects and set their dimensions
273 Ptr<PhasedArrayModel> txAntenna =
274 CreateObjectWithAttributes<UniformPlanarArray>("NumColumns",
275 UintegerValue(2),
276 "NumRows",
277 UintegerValue(2));
278 Ptr<PhasedArrayModel> rxAntenna =
279 CreateObjectWithAttributes<UniformPlanarArray>("NumColumns",
280 UintegerValue(2),
281 "NumRows",
282 UintegerValue(2));
283
284 // set the beamforming vectors
285 DoBeamforming(txDev, txAntenna, rxDev);
286 DoBeamforming(rxDev, rxAntenna, txDev);
287
288 for (int i = 0; i < floor(simTime / timeRes); i++)
289 {
290 ComputeSnrParams params{txMob, rxMob, txPow, noiseFigure, txAntenna, rxAntenna};
291 Simulator::Schedule(MilliSeconds(timeRes * i), &ComputeSnr, params);
292 }
293
294 Simulator::Run();
295 Simulator::Destroy();
296 return 0;
297}
double f(double x, void *params)
Definition: 80211b.c:71
Class holding the azimuth and inclination angles of spherical coordinates.
Definition: angles.h:118
double GetInclination() const
Getter for inclination angle.
Definition: angles.cc:216
double GetAzimuth() const
Getter for azimuth angle.
Definition: angles.cc:210
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:42
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:200
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 ...
virtual size_t GetNumberOfElements() const =0
Returns the number of antenna elements.
void SetBeamformingVector(const ComplexVector &beamformingVector)
Sets the beamforming vector to be used.
Ptr< SpectrumValue > 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.
Ptr< SpectrumValue > Copy() const
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)
void SetChannelModelAttribute(const std::string &name, const AttributeValue &value)
Sets the value of an attribute belonging to the associated MatrixBasedChannelModel instance.
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:402
AttributeValue implementation for Time.
Definition: nstime.h:1423
Hold an unsigned integer type.
Definition: uinteger.h:45
Vector3D Vector
Vector alias typedef for compatibility with mobility models.
Definition: vector.h:324
#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:891
#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 Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:296
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1348
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.
Ptr< PhasedArrayModel > txAntenna
the tx antenna array
Ptr< MobilityModel > rxMob
the rx mobility model
double noiseFigure
the noise figure in dB
double txPow
the tx power in dBm
Ptr< PhasedArrayModel > rxAntenna
the rx antenna array
Ptr< MobilityModel > txMob
the tx mobility model
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
Ptr< SpectrumValue > CreateTxPowerSpectralDensity(double fc)