A Discrete-Event Network Simulator
API
three-gpp-v2v-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) 2020, University of Padova, Dep. of Information Engineering, SIGNET lab
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 */
19
39#include "ns3/buildings-module.h"
40#include "ns3/mobility-module.h"
41#include "ns3/core-module.h"
42#include "ns3/network-module.h"
43#include <fstream>
44#include "ns3/uniform-planar-array.h"
45#include "ns3/three-gpp-spectrum-propagation-loss-model.h"
46#include "ns3/three-gpp-v2v-propagation-loss-model.h"
47#include "ns3/three-gpp-channel-model.h"
48
49using namespace ns3;
50
51NS_LOG_COMPONENT_DEFINE ("ThreeGppV2vChannelExample");
52
56
57/*
58 * \brief A structure that holds the parameters for the ComputeSnr
59 * function. In this way the problem with the limited
60 * number of parameters of method Schedule is avoided.
61 */
63{
67 double noiseFigure;
70
81 Ptr<SpectrumValue> pTxPsd, double pNoiseFigure,
82 Ptr<PhasedArrayModel> pTxAntenna, Ptr<PhasedArrayModel> pRxAntenna)
83 {
84 txMob = pTxMob;
85 rxMob = pRxMob;
86 txPsd = pTxPsd;
87 noiseFigure = pNoiseFigure;
88 txAntenna = pTxAntenna;
89 rxAntenna = pRxAntenna;
90 }
91};
92
99static void
101{
102 PhasedArrayModel::ComplexVector antennaWeights;
103
104 // retrieve the position of the two devices
105 Vector aPos = thisDevice->GetNode ()->GetObject<MobilityModel> ()->GetPosition ();
106 Vector bPos = otherDevice->GetNode ()->GetObject<MobilityModel> ()->GetPosition ();
107
108 // compute the azimuth and the elevation angles
109 Angles completeAngle (bPos,aPos);
110
111 PhasedArrayModel::ComplexVector bf = thisAntenna->GetBeamformingVector (completeAngle);
112 thisAntenna->SetBeamformingVector (bf);
113}
114
119static void
121{
122 Ptr<SpectrumValue> rxPsd = params.txPsd->Copy ();
123
124 // check the channel condition
125 Ptr<ChannelCondition> cond = m_condModel->GetChannelCondition (params.txMob, params.rxMob);
126
127 // apply the pathloss
128 double propagationGainDb = m_propagationLossModel->CalcRxPower (0, params.txMob, params.rxMob);
129 NS_LOG_DEBUG ("Pathloss " << -propagationGainDb << " dB");
130 double propagationGainLinear = std::pow (10.0, (propagationGainDb) / 10.0);
131 *(rxPsd) *= propagationGainLinear;
132
133 // apply the fast fading and the beamforming gain
134 rxPsd = m_spectrumLossModel->CalcRxPowerSpectralDensity (rxPsd, params.txMob, params.rxMob, params.txAntenna, params.rxAntenna);
135 NS_LOG_DEBUG ("Average rx power " << 10 * log10 (Sum (*rxPsd) * 180e3) << " dB");
136
137 // create the noise psd
138 // taken from lte-spectrum-value-helper
139 const double kT_dBm_Hz = -174.0; // dBm/Hz
140 double kT_W_Hz = std::pow (10.0, (kT_dBm_Hz - 30) / 10.0);
141 double noiseFigureLinear = std::pow (10.0, params.noiseFigure / 10.0);
142 double noisePowerSpectralDensity = kT_W_Hz * noiseFigureLinear;
143 Ptr<SpectrumValue> noisePsd = Create <SpectrumValue> (params.txPsd->GetSpectrumModel ());
144 (*noisePsd) = noisePowerSpectralDensity;
145
146 // compute the SNR
147 NS_LOG_DEBUG ("Average SNR " << 10 * log10 (Sum (*rxPsd) / Sum (*noisePsd)) << " dB");
148
149 // print the SNR and pathloss values in the snr-trace.txt file
150 std::ofstream f;
151 f.open ("example-output.txt", std::ios::out | std::ios::app);
152 f << Simulator::Now ().GetSeconds () << " " // time [s]
153 << params.txMob->GetPosition ().x << " "
154 << params.txMob->GetPosition ().y << " "
155 << params.rxMob->GetPosition ().x << " "
156 << params.rxMob->GetPosition ().y << " "
157 << cond->GetLosCondition () << " " // channel state
158 << 10 * log10 (Sum (*rxPsd) / Sum (*noisePsd)) << " " // SNR [dB]
159 << -propagationGainDb << std::endl; // pathloss [dB]
160 f.close ();
161}
162
168void
170{
171 std::ofstream outFile;
172 outFile.open (filename.c_str (), std::ios_base::out | std::ios_base::trunc);
173 if (!outFile.is_open ())
174 {
175 NS_LOG_ERROR ("Can't open file " << filename);
176 return;
177 }
178 uint32_t index = 0;
179 for (BuildingList::Iterator it = BuildingList::Begin (); it != BuildingList::End (); ++it)
180 {
181 ++index;
182 Box box = (*it)->GetBoundaries ();
183 outFile << "set object " << index
184 << " rect from " << box.xMin << "," << box.yMin
185 << " to " << box.xMax << "," << box.yMax
186 << std::endl;
187 }
188}
189
190int
191main (int argc, char *argv[])
192{
193 double frequency = 28.0e9; // operating frequency in Hz
194 double txPow_dbm = 30.0; // tx power in dBm
195 double noiseFigure = 9.0; // noise figure in dB
196 Time simTime = Seconds (40); // simulation time
197 Time timeRes = MilliSeconds (10); // time resolution
198 std::string scenario = "V2V-Urban"; // 3GPP propagation scenario, V2V-Urban or V2V-Highway
199 double vScatt = 0; // maximum speed of the vehicles in the scenario [m/s]
200 double subCarrierSpacing = 60e3; // subcarrier spacing in kHz
201 uint32_t numRb = 275; // number of resource blocks
202
203 CommandLine cmd (__FILE__);
204 cmd.AddValue ("frequency", "operating frequency in Hz", frequency);
205 cmd.AddValue ("txPow", "tx power in dBm", txPow_dbm);
206 cmd.AddValue ("noiseFigure", "noise figure in dB", noiseFigure);
207 cmd.AddValue ("scenario", "3GPP propagation scenario, V2V-Urban or V2V-Highway", scenario);
208 cmd.Parse (argc, argv);
209
210 // create the nodes
212 nodes.Create (2);
213
214 // create the tx and rx devices
215 Ptr<SimpleNetDevice> txDev = CreateObject<SimpleNetDevice> ();
216 Ptr<SimpleNetDevice> rxDev = CreateObject<SimpleNetDevice> ();
217
218 // associate the nodes and the devices
219 nodes.Get (0)->AddDevice (txDev);
220 txDev->SetNode (nodes.Get (0));
221 nodes.Get (1)->AddDevice (rxDev);
222 rxDev->SetNode (nodes.Get (1));
223
224 // create the antenna objects and set their dimensions
225 Ptr<PhasedArrayModel> txAntenna = CreateObjectWithAttributes<UniformPlanarArray> ("NumColumns", UintegerValue (2), "NumRows", UintegerValue (2), "BearingAngle", DoubleValue (-M_PI / 2));
226 Ptr<PhasedArrayModel> rxAntenna = CreateObjectWithAttributes<UniformPlanarArray> ("NumColumns", UintegerValue (2), "NumRows", UintegerValue (2), "BearingAngle", DoubleValue (M_PI / 2));
227
228 Ptr<MobilityModel> txMob;
229 Ptr<MobilityModel> rxMob;
230 if (scenario == "V2V-Urban")
231 {
232 // 3GPP defines that the maximum speed in urban scenario is 60 km/h
233 vScatt = 60 / 3.6;
234
235 // create a grid of buildings
236 double buildingSizeX = 250 - 3.5 * 2 - 3; // m
237 double buildingSizeY = 433 - 3.5 * 2 - 3; // m
238 double streetWidth = 20; // m
239 double buildingHeight = 10; // m
240 uint32_t numBuildingsX = 2;
241 uint32_t numBuildingsY = 2;
242 double maxAxisX = (buildingSizeX + streetWidth) * numBuildingsX;
243 double maxAxisY = (buildingSizeY + streetWidth) * numBuildingsY;
244
245 std::vector<Ptr<Building> > buildingVector;
246 for (uint32_t buildingIdX = 0; buildingIdX < numBuildingsX; ++buildingIdX)
247 {
248 for (uint32_t buildingIdY = 0; buildingIdY < numBuildingsY; ++buildingIdY)
249 {
250 Ptr < Building > building;
251 building = CreateObject<Building> ();
252
253 building->SetBoundaries (Box (buildingIdX * (buildingSizeX + streetWidth),
254 buildingIdX * (buildingSizeX + streetWidth) + buildingSizeX,
255 buildingIdY * (buildingSizeY + streetWidth),
256 buildingIdY * (buildingSizeY + streetWidth) + buildingSizeY,
257 0.0, buildingHeight));
258 building->SetNRoomsX (1);
259 building->SetNRoomsY (1);
260 building->SetNFloors (1);
261 buildingVector.push_back (building);
262 }
263 }
264
265 // set the mobility model
266 double vTx = vScatt;
267 double vRx = vScatt / 2;
268 txMob = CreateObject<WaypointMobilityModel> ();
269 rxMob = CreateObject<WaypointMobilityModel> ();
270 Time nextWaypoint = Seconds (0.0);
271 txMob->GetObject<WaypointMobilityModel> ()->AddWaypoint (Waypoint (nextWaypoint, Vector (maxAxisX / 2 - streetWidth / 2, 1.0, 1.5)));
272 nextWaypoint += Seconds ((maxAxisY - streetWidth) / 2 / vTx);
273 txMob->GetObject<WaypointMobilityModel> ()->AddWaypoint (Waypoint (nextWaypoint, Vector (maxAxisX / 2 - streetWidth / 2, maxAxisY / 2 - streetWidth / 2, 1.5)));
274 nextWaypoint += Seconds ((maxAxisX - streetWidth) / 2 / vTx);
275 txMob->GetObject<WaypointMobilityModel> ()->AddWaypoint (Waypoint (nextWaypoint, Vector (0.0, maxAxisY / 2 - streetWidth / 2, 1.5)));
276 nextWaypoint = Seconds (0.0);
277 rxMob->GetObject<WaypointMobilityModel> ()->AddWaypoint (Waypoint (nextWaypoint, Vector (maxAxisX / 2 - streetWidth / 2, 0.0, 1.5)));
278 nextWaypoint += Seconds (maxAxisY / vRx);
279 rxMob->GetObject<WaypointMobilityModel> ()->AddWaypoint (Waypoint (nextWaypoint, Vector (maxAxisX / 2 - streetWidth / 2, maxAxisY, 1.5)));
280
281 nodes.Get (0)->AggregateObject (txMob);
282 nodes.Get (1)->AggregateObject (rxMob);
283
284 // create the channel condition model
285 m_condModel = CreateObject<ThreeGppV2vUrbanChannelConditionModel> ();
286
287 // create the propagation loss model
288 m_propagationLossModel = CreateObject<ThreeGppV2vUrbanPropagationLossModel> ();
289 }
290 else if (scenario == "V2V-Highway")
291 {
292 // Two vehicles are travelling one behid the other with constant velocity
293 // along the y axis. The distance between the two vehicles is 20 meters.
294
295 // 3GPP defines that the maximum speed in urban scenario is 140 km/h
296 vScatt = 140 / 3.6;
297 double vTx = vScatt;
298 double vRx = vScatt / 2;
299
300 txMob = CreateObject<ConstantVelocityMobilityModel> ();
301 rxMob = CreateObject<ConstantVelocityMobilityModel> ();
302 txMob->GetObject<ConstantVelocityMobilityModel> ()->SetPosition (Vector (300.0, 20.0, 1.5));
303 txMob->GetObject<ConstantVelocityMobilityModel> ()->SetVelocity (Vector (0.0, vTx, 0.0));
304 rxMob->GetObject<ConstantVelocityMobilityModel> ()->SetPosition (Vector (300.0, 0.0, 1.5));
305 rxMob->GetObject<ConstantVelocityMobilityModel> ()->SetVelocity (Vector (0.0, vRx, 0.0));
306
307 nodes.Get (0)->AggregateObject (txMob);
308 nodes.Get (1)->AggregateObject (rxMob);
309
310 // create the channel condition model
311 m_condModel = CreateObject<ThreeGppV2vHighwayChannelConditionModel> ();
312
313 // create the propagation loss model
314 m_propagationLossModel = CreateObject<ThreeGppV2vHighwayPropagationLossModel> ();
315 }
316 else
317 {
318 NS_FATAL_ERROR ("Unknown scenario");
319 }
320
321 m_condModel->SetAttribute ("UpdatePeriod", TimeValue (MilliSeconds (100)));
322
323 m_propagationLossModel->SetAttribute ("Frequency", DoubleValue (frequency));
324 m_propagationLossModel->SetAttribute ("ShadowingEnabled", BooleanValue (false));
325 m_propagationLossModel->SetAttribute ("ChannelConditionModel", PointerValue (m_condModel));
326
327 // create the channel model
328 Ptr<ThreeGppChannelModel> channelModel = CreateObject<ThreeGppChannelModel> ();
329 channelModel->SetAttribute ("Scenario", StringValue (scenario));
330 channelModel->SetAttribute ("Frequency", DoubleValue (frequency));
331 channelModel->SetAttribute ("ChannelConditionModel", PointerValue (m_condModel));
332 channelModel->SetAttribute ("vScatt", DoubleValue (vScatt));
333
334 // create the spectrum propagation loss model
335 m_spectrumLossModel = CreateObjectWithAttributes<ThreeGppSpectrumPropagationLossModel> ("ChannelModel", PointerValue (channelModel));
336
337 BuildingsHelper::Install (nodes);
338
339 // set the beamforming vectors
340 DoBeamforming (txDev, txAntenna, rxDev);
341 DoBeamforming (rxDev, rxAntenna, txDev);
342
343 // create the tx power spectral density
344 Bands rbs;
345 double freqSubBand = frequency;
346 for (uint16_t n = 0; n < numRb; ++n)
347 {
348 BandInfo rb;
349 rb.fl = freqSubBand;
350 freqSubBand += subCarrierSpacing / 2;
351 rb.fc = freqSubBand;
352 freqSubBand += subCarrierSpacing / 2;
353 rb.fh = freqSubBand;
354 rbs.push_back (rb);
355 }
356 Ptr<SpectrumModel> spectrumModel = Create<SpectrumModel> (rbs);
357 Ptr<SpectrumValue> txPsd = Create <SpectrumValue> (spectrumModel);
358 double txPow_w = std::pow (10., (txPow_dbm - 30) / 10);
359 double txPowDens = (txPow_w / (numRb * subCarrierSpacing));
360 (*txPsd) = txPowDens;
361
362 for (int i = 0; i < simTime / timeRes; i++)
363 {
364 Simulator::Schedule (timeRes * i, &ComputeSnr, ComputeSnrParams (txMob, rxMob, txPsd, noiseFigure, txAntenna, rxAntenna));
365 }
366
367 // initialize the output file
368 std::ofstream f;
369 f.open ("example-output.txt", std::ios::out);
370 f << "Time[s] TxPosX[m] TxPosY[m] RxPosX[m] RxPosY[m] ChannelState SNR[dB] Pathloss[dB]" << std::endl;
371 f.close ();
372
373 // print the list of buildings to file
374 PrintGnuplottableBuildingListToFile ("buildings.txt");
375
376 Simulator::Run ();
377 Simulator::Destroy ();
378 return 0;
379}
double f(double x, void *params)
Definition: 80211b.c:70
Class holding the azimuth and inclination angles of spherical coordinates.
Definition: angles.h:119
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:40
Parse command-line arguments.
Definition: command-line.h:229
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:41
Keep track of the current position and velocity of an object.
Vector GetPosition(void) const
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
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
ComplexVector GetBeamformingVector(void) const
Returns the beamforming vector that is currently being used.
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.
Ptr< SpectrumValue > Copy() const
Ptr< const SpectrumModel > GetSpectrumModel() const
Hold variables of type string.
Definition: string.h:41
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
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
Vector3D Vector
Vector alias typedef for compatibility with mobility models.
Definition: vector.h:324
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:165
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:257
#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 Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
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.
std::vector< BandInfo > Bands
Container of BandInfo.
double Sum(const SpectrumValue &x)
cmd
Definition: second.py:35
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< PhasedArrayModel > rxAntenna
the rx antenna array
ComputeSnrParams(Ptr< MobilityModel > pTxMob, Ptr< MobilityModel > pRxMob, Ptr< SpectrumValue > pTxPsd, double pNoiseFigure, Ptr< PhasedArrayModel > pTxAntenna, Ptr< PhasedArrayModel > pRxAntenna)
Constructor.
Ptr< SpectrumValue > txPsd
the PSD of the tx signal
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
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.
void PrintGnuplottableBuildingListToFile(std::string filename)
Generates a GNU-plottable file representig the buildings deployed in the scenario.
static void ComputeSnr(ComputeSnrParams &params)
Compute the average SNR.
static Ptr< ThreeGppSpectrumPropagationLossModel > m_spectrumLossModel
the SpectrumPropagationLossModel object
static void SetPosition(Ptr< Node > node, Vector position)
Definition: wifi-ap.cc:89
static Vector GetPosition(Ptr< Node > node)
Definition: wifi-ap.cc:96