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{
83
84 // retrieve the position of the two devices
85 Vector aPos = thisDevice->GetNode()->GetObject<MobilityModel>()->GetPosition();
86 Vector bPos = otherDevice->GetNode()->GetObject<MobilityModel>()->GetPosition();
87
88 // compute the azimuth and the elevation angles
89 Angles completeAngle(bPos, aPos);
90 double hAngleRadian = completeAngle.GetAzimuth();
91
92 double vAngleRadian = completeAngle.GetInclination(); // the elevation angle
93
94 // retrieve the number of antenna elements
95 int totNoArrayElements = thisAntenna->GetNumberOfElements();
96
97 // the total power is divided equally among the antenna elements
98 double power = 1 / sqrt(totNoArrayElements);
99
100 // compute the antenna weights
101 for (int ind = 0; ind < totNoArrayElements; ind++)
102 {
103 Vector loc = thisAntenna->GetElementLocation(ind);
104 double phase = -2 * M_PI *
105 (sin(vAngleRadian) * cos(hAngleRadian) * loc.x +
106 sin(vAngleRadian) * sin(hAngleRadian) * loc.y + cos(vAngleRadian) * loc.z);
107 antennaWeights.push_back(exp(std::complex<double>(0, phase)) * power);
108 }
109
110 // store the antenna weights
111 thisAntenna->SetBeamformingVector(antennaWeights);
112}
113
119static void
121{
122 // Create the tx PSD using the LteSpectrumValueHelper
123 // 100 RBs corresponds to 18 MHz (1 RB = 180 kHz)
124 // EARFCN 100 corresponds to 2125.00 MHz
125 std::vector<int> activeRbs0(100);
126 for (int i = 0; i < 100; i++)
127 {
128 activeRbs0[i] = i;
129 }
130 Ptr<SpectrumValue> txPsd =
131 LteSpectrumValueHelper::CreateTxPowerSpectralDensity(2100, 100, params.txPow, activeRbs0);
132 Ptr<SpectrumSignalParameters> txParams = Create<SpectrumSignalParameters>();
133 txParams->psd = txPsd->Copy();
134 NS_LOG_DEBUG("Average tx power " << 10 * log10(Sum(*txPsd) * 180e3) << " dB");
135
136 // create the noise PSD
137 Ptr<SpectrumValue> noisePsd =
138 LteSpectrumValueHelper::CreateNoisePowerSpectralDensity(2100, 100, params.noiseFigure);
139 NS_LOG_DEBUG("Average noise power " << 10 * log10(Sum(*noisePsd) * 180e3) << " dB");
140
141 // apply the pathloss
142 double propagationGainDb = m_propagationLossModel->CalcRxPower(0, params.txMob, params.rxMob);
143 NS_LOG_DEBUG("Pathloss " << -propagationGainDb << " dB");
144 double propagationGainLinear = std::pow(10.0, (propagationGainDb) / 10.0);
145 *(txParams->psd) *= propagationGainLinear;
146
147 NS_ASSERT_MSG(params.txAntenna, "params.txAntenna is nullptr!");
148 NS_ASSERT_MSG(params.rxAntenna, "params.rxAntenna is nullptr!");
149
150 // apply the fast fading and the beamforming gain
152 params.txMob,
153 params.rxMob,
154 params.txAntenna,
155 params.rxAntenna);
156 NS_LOG_DEBUG("Average rx power " << 10 * log10(Sum(*rxPsd) * 180e3) << " dB");
157
158 // compute the SNR
159 NS_LOG_DEBUG("Average SNR " << 10 * log10(Sum(*rxPsd) / Sum(*noisePsd)) << " dB");
160
161 // print the SNR and pathloss values in the snr-trace.txt file
162 std::ofstream f;
163 f.open("snr-trace.txt", std::ios::out | std::ios::app);
164 f << Simulator::Now().GetSeconds() << " " << 10 * log10(Sum(*rxPsd) / Sum(*noisePsd)) << " "
165 << propagationGainDb << std::endl;
166 f.close();
167}
168
169int
170main(int argc, char* argv[])
171{
172 double frequency = 2125.0e6; // operating frequency in Hz (corresponds to EARFCN 2100)
173 double txPow = 49.0; // tx power in dBm
174 double noiseFigure = 9.0; // noise figure in dB
175 double distance = 10.0; // distance between tx and rx nodes in meters
176 uint32_t simTime = 10000; // simulation time in milliseconds
177 uint32_t timeRes = 10; // time resolution in milliseconds
178 std::string scenario = "UMa"; // 3GPP propagation scenario
179
180 Config::SetDefault("ns3::ThreeGppChannelModel::UpdatePeriod",
181 TimeValue(MilliSeconds(1))); // update the channel at each iteration
182 Config::SetDefault("ns3::ThreeGppChannelConditionModel::UpdatePeriod",
183 TimeValue(MilliSeconds(0.0))); // do not update the channel condition
184
185 RngSeedManager::SetSeed(1);
186 RngSeedManager::SetRun(1);
187
188 // create and configure the factories for the channel condition and propagation loss models
189 ObjectFactory propagationLossModelFactory;
190 ObjectFactory channelConditionModelFactory;
191 if (scenario == "RMa")
192 {
193 propagationLossModelFactory.SetTypeId(ThreeGppRmaPropagationLossModel::GetTypeId());
194 channelConditionModelFactory.SetTypeId(ThreeGppRmaChannelConditionModel::GetTypeId());
195 }
196 else if (scenario == "UMa")
197 {
198 propagationLossModelFactory.SetTypeId(ThreeGppUmaPropagationLossModel::GetTypeId());
199 channelConditionModelFactory.SetTypeId(ThreeGppUmaChannelConditionModel::GetTypeId());
200 }
201 else if (scenario == "UMi-StreetCanyon")
202 {
203 propagationLossModelFactory.SetTypeId(
204 ThreeGppUmiStreetCanyonPropagationLossModel::GetTypeId());
205 channelConditionModelFactory.SetTypeId(
206 ThreeGppUmiStreetCanyonChannelConditionModel::GetTypeId());
207 }
208 else if (scenario == "InH-OfficeOpen")
209 {
210 propagationLossModelFactory.SetTypeId(
211 ThreeGppIndoorOfficePropagationLossModel::GetTypeId());
212 channelConditionModelFactory.SetTypeId(
213 ThreeGppIndoorOpenOfficeChannelConditionModel::GetTypeId());
214 }
215 else if (scenario == "InH-OfficeMixed")
216 {
217 propagationLossModelFactory.SetTypeId(
218 ThreeGppIndoorOfficePropagationLossModel::GetTypeId());
219 channelConditionModelFactory.SetTypeId(
220 ThreeGppIndoorMixedOfficeChannelConditionModel::GetTypeId());
221 }
222 else
223 {
224 NS_FATAL_ERROR("Unknown scenario");
225 }
226
227 // create the propagation loss model
228 m_propagationLossModel = propagationLossModelFactory.Create<ThreeGppPropagationLossModel>();
229 m_propagationLossModel->SetAttribute("Frequency", DoubleValue(frequency));
230 m_propagationLossModel->SetAttribute("ShadowingEnabled", BooleanValue(false));
231
232 // create the spectrum propagation loss model
233 m_spectrumLossModel = CreateObject<ThreeGppSpectrumPropagationLossModel>();
236
237 // create the channel condition model and associate it with the spectrum and
238 // propagation loss model
240 channelConditionModelFactory.Create<ThreeGppChannelConditionModel>();
241 m_spectrumLossModel->SetChannelModelAttribute("ChannelConditionModel", PointerValue(condModel));
243
244 // create the tx and rx nodes
246 nodes.Create(2);
247
248 // create the tx and rx devices
249 Ptr<SimpleNetDevice> txDev = CreateObject<SimpleNetDevice>();
250 Ptr<SimpleNetDevice> rxDev = CreateObject<SimpleNetDevice>();
251
252 // associate the nodes and the devices
253 nodes.Get(0)->AddDevice(txDev);
254 txDev->SetNode(nodes.Get(0));
255 nodes.Get(1)->AddDevice(rxDev);
256 rxDev->SetNode(nodes.Get(1));
257
258 // create the tx and rx mobility models, set the positions
259 Ptr<MobilityModel> txMob = CreateObject<ConstantPositionMobilityModel>();
260 txMob->SetPosition(Vector(0.0, 0.0, 10.0));
261 Ptr<MobilityModel> rxMob = CreateObject<ConstantPositionMobilityModel>();
262 rxMob->SetPosition(Vector(distance, 0.0, 1.6));
263
264 // assign the mobility models to the nodes
265 nodes.Get(0)->AggregateObject(txMob);
266 nodes.Get(1)->AggregateObject(rxMob);
267
268 // create the antenna objects and set their dimensions
269 Ptr<PhasedArrayModel> txAntenna =
270 CreateObjectWithAttributes<UniformPlanarArray>("NumColumns",
271 UintegerValue(2),
272 "NumRows",
273 UintegerValue(2));
274 Ptr<PhasedArrayModel> rxAntenna =
275 CreateObjectWithAttributes<UniformPlanarArray>("NumColumns",
276 UintegerValue(2),
277 "NumRows",
278 UintegerValue(2));
279
280 // set the beamforming vectors
281 DoBeamforming(txDev, txAntenna, rxDev);
282 DoBeamforming(rxDev, rxAntenna, txDev);
283
284 for (int i = 0; i < floor(simTime / timeRes); i++)
285 {
286 ComputeSnrParams params{txMob, rxMob, txPow, noiseFigure, txAntenna, rxAntenna};
287 Simulator::Schedule(MilliSeconds(timeRes * i), &ComputeSnr, params);
288 }
289
290 Simulator::Run();
291 Simulator::Destroy();
292 return 0;
293}
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
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:258
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 uint64_t GetNumberOfElements() 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 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:42
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:1425
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:160
#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:1350
NodeContainer nodes
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< 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