A Discrete-Event Network Simulator
API
three-gpp-v2v-channel-example.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020, University of Padova, Dep. of Information Engineering, SIGNET lab
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  */
18 
38 #include "ns3/buildings-module.h"
39 #include "ns3/core-module.h"
40 #include "ns3/mobility-module.h"
41 #include "ns3/network-module.h"
42 #include "ns3/spectrum-signal-parameters.h"
43 #include "ns3/three-gpp-channel-model.h"
44 #include "ns3/three-gpp-spectrum-propagation-loss-model.h"
45 #include "ns3/three-gpp-v2v-propagation-loss-model.h"
46 #include "ns3/uniform-planar-array.h"
47 
48 #include <fstream>
49 
50 using namespace ns3;
51 
52 NS_LOG_COMPONENT_DEFINE("ThreeGppV2vChannelExample");
53 
59 
60 /*
61  * \brief A structure that holds the parameters for the ComputeSnr
62  * function. In this way the problem with the limited
63  * number of parameters of method Schedule is avoided.
64  */
66 {
70  double noiseFigure;
73 };
74 
81 static void
83  Ptr<PhasedArrayModel> thisAntenna,
84  Ptr<NetDevice> otherDevice)
85 {
86  PhasedArrayModel::ComplexVector antennaWeights;
87 
88  // retrieve the position of the two devices
89  Vector aPos = thisDevice->GetNode()->GetObject<MobilityModel>()->GetPosition();
90  Vector bPos = otherDevice->GetNode()->GetObject<MobilityModel>()->GetPosition();
91 
92  // compute the azimuth and the elevation angles
93  Angles completeAngle(bPos, aPos);
94 
95  PhasedArrayModel::ComplexVector bf = thisAntenna->GetBeamformingVector(completeAngle);
96  thisAntenna->SetBeamformingVector(bf);
97 }
98 
104 static void
106 {
107  // check the channel condition
108  Ptr<ChannelCondition> cond = m_condModel->GetChannelCondition(params.txMob, params.rxMob);
109 
110  // apply the pathloss
111  double propagationGainDb = m_propagationLossModel->CalcRxPower(0, params.txMob, params.rxMob);
112  NS_LOG_DEBUG("Pathloss " << -propagationGainDb << " dB");
113  double propagationGainLinear = std::pow(10.0, (propagationGainDb) / 10.0);
114  *(params.txParams->psd) *= propagationGainLinear;
115 
116  // apply the fast fading and the beamforming gain
118  params.txMob,
119  params.rxMob,
120  params.txAntenna,
121  params.rxAntenna);
122  NS_LOG_DEBUG("Average rx power " << 10 * log10(Sum(*rxPsd) * 180e3) << " dB");
123 
124  // create the noise psd
125  // taken from lte-spectrum-value-helper
126  const double kT_dBm_Hz = -174.0; // dBm/Hz
127  double kT_W_Hz = std::pow(10.0, (kT_dBm_Hz - 30) / 10.0);
128  double noiseFigureLinear = std::pow(10.0, params.noiseFigure / 10.0);
129  double noisePowerSpectralDensity = kT_W_Hz * noiseFigureLinear;
130  Ptr<SpectrumValue> noisePsd = Create<SpectrumValue>(params.txParams->psd->GetSpectrumModel());
131  (*noisePsd) = noisePowerSpectralDensity;
132 
133  // compute the SNR
134  NS_LOG_DEBUG("Average SNR " << 10 * log10(Sum(*rxPsd) / Sum(*noisePsd)) << " dB");
135 
136  // print the SNR and pathloss values in the snr-trace.txt file
137  std::ofstream f;
138  f.open("example-output.txt", std::ios::out | std::ios::app);
139  f << Simulator::Now().GetSeconds() << " " // time [s]
140  << params.txMob->GetPosition().x << " " << params.txMob->GetPosition().y << " "
141  << params.rxMob->GetPosition().x << " " << params.rxMob->GetPosition().y << " "
142  << cond->GetLosCondition() << " " // channel state
143  << 10 * log10(Sum(*rxPsd) / Sum(*noisePsd)) << " " // SNR [dB]
144  << -propagationGainDb << std::endl; // pathloss [dB]
145  f.close();
146 }
147 
153 void
155 {
156  std::ofstream outFile;
157  outFile.open(filename, std::ios_base::out | std::ios_base::trunc);
158  if (!outFile.is_open())
159  {
160  NS_LOG_ERROR("Can't open file " << filename);
161  return;
162  }
163  uint32_t index = 0;
165  {
166  ++index;
167  Box box = (*it)->GetBoundaries();
168  outFile << "set object " << index << " rect from " << box.xMin << "," << box.yMin << " to "
169  << box.xMax << "," << box.yMax << std::endl;
170  }
171 }
172 
173 int
174 main(int argc, char* argv[])
175 {
176  double frequency = 28.0e9; // operating frequency in Hz
177  double txPow_dbm = 30.0; // tx power in dBm
178  double noiseFigure = 9.0; // noise figure in dB
179  Time simTime = Seconds(40); // simulation time
180  Time timeRes = MilliSeconds(10); // time resolution
181  std::string scenario = "V2V-Urban"; // 3GPP propagation scenario, V2V-Urban or V2V-Highway
182  double vScatt = 0; // maximum speed of the vehicles in the scenario [m/s]
183  double subCarrierSpacing = 60e3; // subcarrier spacing in kHz
184  uint32_t numRb = 275; // number of resource blocks
185 
186  CommandLine cmd(__FILE__);
187  cmd.AddValue("frequency", "operating frequency in Hz", frequency);
188  cmd.AddValue("txPow", "tx power in dBm", txPow_dbm);
189  cmd.AddValue("noiseFigure", "noise figure in dB", noiseFigure);
190  cmd.AddValue("scenario", "3GPP propagation scenario, V2V-Urban or V2V-Highway", scenario);
191  cmd.Parse(argc, argv);
192 
193  // create the nodes
195  nodes.Create(2);
196 
197  // create the tx and rx devices
198  Ptr<SimpleNetDevice> txDev = CreateObject<SimpleNetDevice>();
199  Ptr<SimpleNetDevice> rxDev = CreateObject<SimpleNetDevice>();
200 
201  // associate the nodes and the devices
202  nodes.Get(0)->AddDevice(txDev);
203  txDev->SetNode(nodes.Get(0));
204  nodes.Get(1)->AddDevice(rxDev);
205  rxDev->SetNode(nodes.Get(1));
206 
207  // create the antenna objects and set their dimensions
208  Ptr<PhasedArrayModel> txAntenna =
209  CreateObjectWithAttributes<UniformPlanarArray>("NumColumns",
210  UintegerValue(2),
211  "NumRows",
212  UintegerValue(2),
213  "BearingAngle",
214  DoubleValue(-M_PI / 2));
215  Ptr<PhasedArrayModel> rxAntenna =
216  CreateObjectWithAttributes<UniformPlanarArray>("NumColumns",
217  UintegerValue(2),
218  "NumRows",
219  UintegerValue(2),
220  "BearingAngle",
221  DoubleValue(M_PI / 2));
222 
223  Ptr<MobilityModel> txMob;
224  Ptr<MobilityModel> rxMob;
225  if (scenario == "V2V-Urban")
226  {
227  // 3GPP defines that the maximum speed in urban scenario is 60 km/h
228  vScatt = 60 / 3.6;
229 
230  // create a grid of buildings
231  double buildingSizeX = 250 - 3.5 * 2 - 3; // m
232  double buildingSizeY = 433 - 3.5 * 2 - 3; // m
233  double streetWidth = 20; // m
234  double buildingHeight = 10; // m
235  uint32_t numBuildingsX = 2;
236  uint32_t numBuildingsY = 2;
237  double maxAxisX = (buildingSizeX + streetWidth) * numBuildingsX;
238  double maxAxisY = (buildingSizeY + streetWidth) * numBuildingsY;
239 
240  std::vector<Ptr<Building>> buildingVector;
241  for (uint32_t buildingIdX = 0; buildingIdX < numBuildingsX; ++buildingIdX)
242  {
243  for (uint32_t buildingIdY = 0; buildingIdY < numBuildingsY; ++buildingIdY)
244  {
245  Ptr<Building> building;
246  building = CreateObject<Building>();
247 
248  building->SetBoundaries(
249  Box(buildingIdX * (buildingSizeX + streetWidth),
250  buildingIdX * (buildingSizeX + streetWidth) + buildingSizeX,
251  buildingIdY * (buildingSizeY + streetWidth),
252  buildingIdY * (buildingSizeY + streetWidth) + buildingSizeY,
253  0.0,
254  buildingHeight));
255  building->SetNRoomsX(1);
256  building->SetNRoomsY(1);
257  building->SetNFloors(1);
258  buildingVector.push_back(building);
259  }
260  }
261 
262  // set the mobility model
263  double vTx = vScatt;
264  double vRx = vScatt / 2;
265  txMob = CreateObject<WaypointMobilityModel>();
266  rxMob = CreateObject<WaypointMobilityModel>();
267  Time nextWaypoint = Seconds(0.0);
268  txMob->GetObject<WaypointMobilityModel>()->AddWaypoint(
269  Waypoint(nextWaypoint, Vector(maxAxisX / 2 - streetWidth / 2, 1.0, 1.5)));
270  nextWaypoint += Seconds((maxAxisY - streetWidth) / 2 / vTx);
271  txMob->GetObject<WaypointMobilityModel>()->AddWaypoint(
272  Waypoint(nextWaypoint,
273  Vector(maxAxisX / 2 - streetWidth / 2, maxAxisY / 2 - streetWidth / 2, 1.5)));
274  nextWaypoint += Seconds((maxAxisX - streetWidth) / 2 / vTx);
275  txMob->GetObject<WaypointMobilityModel>()->AddWaypoint(
276  Waypoint(nextWaypoint, Vector(0.0, maxAxisY / 2 - streetWidth / 2, 1.5)));
277  nextWaypoint = Seconds(0.0);
278  rxMob->GetObject<WaypointMobilityModel>()->AddWaypoint(
279  Waypoint(nextWaypoint, Vector(maxAxisX / 2 - streetWidth / 2, 0.0, 1.5)));
280  nextWaypoint += Seconds(maxAxisY / vRx);
281  rxMob->GetObject<WaypointMobilityModel>()->AddWaypoint(
282  Waypoint(nextWaypoint, Vector(maxAxisX / 2 - streetWidth / 2, maxAxisY, 1.5)));
283 
284  nodes.Get(0)->AggregateObject(txMob);
285  nodes.Get(1)->AggregateObject(rxMob);
286 
287  // create the channel condition model
288  m_condModel = CreateObject<ThreeGppV2vUrbanChannelConditionModel>();
289 
290  // create the propagation loss model
291  m_propagationLossModel = CreateObject<ThreeGppV2vUrbanPropagationLossModel>();
292  }
293  else if (scenario == "V2V-Highway")
294  {
295  // Two vehicles are travelling one behid the other with constant velocity
296  // along the y axis. The distance between the two vehicles is 20 meters.
297 
298  // 3GPP defines that the maximum speed in urban scenario is 140 km/h
299  vScatt = 140 / 3.6;
300  double vTx = vScatt;
301  double vRx = vScatt / 2;
302 
303  txMob = CreateObject<ConstantVelocityMobilityModel>();
304  rxMob = CreateObject<ConstantVelocityMobilityModel>();
305  txMob->GetObject<ConstantVelocityMobilityModel>()->SetPosition(Vector(300.0, 20.0, 1.5));
306  txMob->GetObject<ConstantVelocityMobilityModel>()->SetVelocity(Vector(0.0, vTx, 0.0));
307  rxMob->GetObject<ConstantVelocityMobilityModel>()->SetPosition(Vector(300.0, 0.0, 1.5));
308  rxMob->GetObject<ConstantVelocityMobilityModel>()->SetVelocity(Vector(0.0, vRx, 0.0));
309 
310  nodes.Get(0)->AggregateObject(txMob);
311  nodes.Get(1)->AggregateObject(rxMob);
312 
313  // create the channel condition model
314  m_condModel = CreateObject<ThreeGppV2vHighwayChannelConditionModel>();
315 
316  // create the propagation loss model
317  m_propagationLossModel = CreateObject<ThreeGppV2vHighwayPropagationLossModel>();
318  }
319  else
320  {
321  NS_FATAL_ERROR("Unknown scenario");
322  }
323 
324  m_condModel->SetAttribute("UpdatePeriod", TimeValue(MilliSeconds(100)));
325 
326  m_propagationLossModel->SetAttribute("Frequency", DoubleValue(frequency));
327  m_propagationLossModel->SetAttribute("ShadowingEnabled", BooleanValue(false));
328  m_propagationLossModel->SetAttribute("ChannelConditionModel", PointerValue(m_condModel));
329 
330  // create the channel model
331  Ptr<ThreeGppChannelModel> channelModel = CreateObject<ThreeGppChannelModel>();
332  channelModel->SetAttribute("Scenario", StringValue(scenario));
333  channelModel->SetAttribute("Frequency", DoubleValue(frequency));
334  channelModel->SetAttribute("ChannelConditionModel", PointerValue(m_condModel));
335  channelModel->SetAttribute("vScatt", DoubleValue(vScatt));
336 
337  // create the spectrum propagation loss model
338  m_spectrumLossModel = CreateObjectWithAttributes<ThreeGppSpectrumPropagationLossModel>(
339  "ChannelModel",
340  PointerValue(channelModel));
341 
343 
344  // set the beamforming vectors
345  DoBeamforming(txDev, txAntenna, rxDev);
346  DoBeamforming(rxDev, rxAntenna, txDev);
347 
348  // create the tx power spectral density
349  Bands rbs;
350  double freqSubBand = frequency;
351  for (uint32_t n = 0; n < numRb; ++n)
352  {
353  BandInfo rb;
354  rb.fl = freqSubBand;
355  freqSubBand += subCarrierSpacing / 2;
356  rb.fc = freqSubBand;
357  freqSubBand += subCarrierSpacing / 2;
358  rb.fh = freqSubBand;
359  rbs.push_back(rb);
360  }
361  Ptr<SpectrumModel> spectrumModel = Create<SpectrumModel>(rbs);
362  Ptr<SpectrumValue> txPsd = Create<SpectrumValue>(spectrumModel);
363  Ptr<SpectrumSignalParameters> txParams = Create<SpectrumSignalParameters>();
364  double txPow_w = std::pow(10., (txPow_dbm - 30) / 10);
365  double txPowDens = (txPow_w / (numRb * subCarrierSpacing));
366  (*txPsd) = txPowDens;
367  txParams->psd = txPsd->Copy();
368 
369  for (int i = 0; i < simTime / timeRes; i++)
370  {
371  ComputeSnrParams params{txMob, rxMob, txParams, noiseFigure, txAntenna, rxAntenna};
372  Simulator::Schedule(timeRes * i, &ComputeSnr, params);
373  }
374 
375  // initialize the output file
376  std::ofstream f;
377  f.open("example-output.txt", std::ios::out);
378  f << "Time[s] TxPosX[m] TxPosY[m] RxPosX[m] RxPosY[m] ChannelState SNR[dB] Pathloss[dB]"
379  << std::endl;
380  f.close();
381 
382  // print the list of buildings to file
383  PrintGnuplottableBuildingListToFile("buildings.txt");
384 
385  Simulator::Run();
387  return 0;
388 }
double f(double x, void *params)
Definition: 80211b.c:71
Class holding the azimuth and inclination angles of spherical coordinates.
Definition: angles.h:118
AttributeValue implementation for Boolean.
Definition: boolean.h:37
a 3d box
Definition: box.h:35
double yMax
The y coordinate of the top bound of the box.
Definition: box.h:116
double xMin
The x coordinate of the left bound of the box.
Definition: box.h:110
double yMin
The y coordinate of the bottom bound of the box.
Definition: box.h:114
double xMax
The x coordinate of the right bound of the box.
Definition: box.h:112
std::vector< Ptr< Building > >::const_iterator Iterator
Const Iterator.
Definition: building-list.h:41
static Iterator End()
static Iterator Begin()
static void Install(Ptr< Node > node)
Install the MobilityBuildingInfo to a node.
Parse command-line arguments.
Definition: command-line.h:232
Mobility model for which the current speed does not change once it has been set and until it is set a...
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.
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
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:259
ComplexVector GetBeamformingVector() const
Returns the beamforming vector that is currently being used.
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.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:140
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
static void Run()
Run the simulation.
Definition: simulator.cc:176
Ptr< SpectrumValue > Copy() const
Hold variables of type string.
Definition: string.h:56
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
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
a (time, location) pair.
Definition: waypoint.h:36
Waypoint-based mobility model.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
#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 Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
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.
std::vector< BandInfo > Bands
Container of BandInfo.
double Sum(const SpectrumValue &x)
cmd
Definition: second.py:33
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
Ptr< SpectrumSignalParameters > txParams
the params of the tx signal
Ptr< PhasedArrayModel > rxAntenna
the rx antenna array
Ptr< MobilityModel > txMob
the tx mobility model
The building block of a SpectrumModel.
double fc
center frequency
double fl
lower limit of subband
double fh
upper limit of subband
Ptr< SpectrumValue > psd
The Power Spectral Density of the waveform, in linear units.
static Ptr< ChannelConditionModel > m_condModel
the ChannelConditionModel object
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.
void PrintGnuplottableBuildingListToFile(std::string filename)
Generates a GNU-plottable file representing the buildings deployed in the scenario.
static Ptr< ThreeGppSpectrumPropagationLossModel > m_spectrumLossModel
the SpectrumPropagationLossModel object