A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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
50using namespace ns3;
51
52NS_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
81static void
83 Ptr<PhasedArrayModel> thisAntenna,
84 Ptr<NetDevice> otherDevice)
85{
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
104static 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
153void
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
173int
174main(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));
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
384
387 return 0;
388}
double f(double x, void *params)
Definition: 80211b.c:70
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
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:259
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.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
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
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)
ns cmd
Definition: second.py:33
FtrParams 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
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