A Discrete-Event Network Simulator
API
probabilistic-v2v-channel-condition-model-test.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
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 #include "ns3/abort.h"
19 #include "ns3/boolean.h"
20 #include "ns3/channel-condition-model.h"
21 #include "ns3/config.h"
22 #include "ns3/constant-position-mobility-model.h"
23 #include "ns3/core-module.h"
24 #include "ns3/double.h"
25 #include "ns3/log.h"
26 #include "ns3/node-container.h"
27 #include "ns3/probabilistic-v2v-channel-condition-model.h"
28 #include "ns3/simulator.h"
29 #include "ns3/test.h"
30 #include "ns3/three-gpp-v2v-propagation-loss-model.h"
31 #include "ns3/uinteger.h"
32 
33 using namespace ns3;
34 
35 NS_LOG_COMPONENT_DEFINE("ProbabilisticV2vChannelConditionModelsTest");
36 
50 {
51  public:
56 
61 
62  private:
66  void DoRun() override;
67 
75  void EvaluateChannelCondition(Ptr<MobilityModel> a, Ptr<MobilityModel> b);
76 
80  struct TestVector
81  {
82  Vector m_positionA;
83  Vector m_positionB;
84  double m_pLos{0.0};
85  double m_pNlosv{0.0};
86  std::string m_density;
88  };
89 
92  uint64_t m_numLos{0};
93  uint64_t m_numNlosv{0};
94  double m_tolerance;
95 };
96 
98  : TestCase("Test case for the class ProbabilisticV2vUrbanChannelConditionModel"),
99  m_testVectors(),
100  m_tolerance(5e-3)
101 {
102 }
103 
105 {
106 }
107 
108 void
111 {
113  if (cond->GetLosCondition() == ChannelCondition::LosConditionValue::LOS)
114  {
115  m_numLos++;
116  }
117  else if (cond->GetLosCondition() == ChannelCondition::LosConditionValue::NLOSv)
118  {
119  m_numNlosv++;
120  }
121 }
122 
123 void
125 {
126  RngSeedManager::SetSeed(1);
127  RngSeedManager::SetRun(1);
128 
129  // create the test vector
130  TestVector testVector;
131 
132  // tests for the V2v Urban scenario
133  testVector.m_positionA = Vector(0, 0, 1.6);
134  testVector.m_positionB = Vector(10, 0, 1.6);
135  testVector.m_pLos = std::min(1.0, std::max(0.0, 0.8548 * exp(-0.0064 * 10.0)));
136  testVector.m_typeId = ProbabilisticV2vUrbanChannelConditionModel::GetTypeId();
137  testVector.m_pNlosv = std::min(
138  1.0,
139  std::max(0.0,
140  1 / (0.0396 * 10.0) * exp(-(log(10.0) - 5.2718) * (log(10.0) - 5.2718) / 3.4827)));
141  testVector.m_density = "Low";
142  m_testVectors.Add(testVector);
143 
144  testVector.m_positionA = Vector(0, 0, 1.6);
145  testVector.m_positionB = Vector(100, 0, 1.6);
146  testVector.m_pLos = std::min(1.0, std::max(0.0, 0.8548 * exp(-0.0064 * 100.0)));
147  testVector.m_typeId = ProbabilisticV2vUrbanChannelConditionModel::GetTypeId();
148  testVector.m_pNlosv =
149  std::min(1.0,
150  std::max(0.0,
151  1 / (0.0396 * 100.0) *
152  exp(-(log(100.0) - 5.2718) * (log(100.0) - 5.2718) / 3.4827)));
153  testVector.m_density = "Low";
154  m_testVectors.Add(testVector);
155 
156  testVector.m_positionA = Vector(0, 0, 1.6);
157  testVector.m_positionB = Vector(10, 0, 1.6);
158  testVector.m_pLos = std::min(1.0, std::max(0.0, 0.8372 * exp(-0.0114 * 10.0)));
159  testVector.m_typeId = ProbabilisticV2vUrbanChannelConditionModel::GetTypeId();
160  testVector.m_pNlosv = std::min(
161  1.0,
162  std::max(0.0,
163  1 / (0.0312 * 10.0) * exp(-(log(10.0) - 5.0063) * (log(10.0) - 5.0063) / 2.4544)));
164  testVector.m_density = "Medium";
165  m_testVectors.Add(testVector);
166 
167  testVector.m_positionA = Vector(0, 0, 1.6);
168  testVector.m_positionB = Vector(100, 0, 1.6);
169  testVector.m_pLos = std::min(1.0, std::max(0.0, 0.8372 * exp(-0.0114 * 100.0)));
170  testVector.m_typeId = ProbabilisticV2vUrbanChannelConditionModel::GetTypeId();
171  testVector.m_pNlosv =
172  std::min(1.0,
173  std::max(0.0,
174  1 / (0.0312 * 100.0) *
175  exp(-(log(100.0) - 5.0063) * (log(100.0) - 5.0063) / 2.4544)));
176  testVector.m_density = "Medium";
177  m_testVectors.Add(testVector);
178 
179  testVector.m_positionA = Vector(0, 0, 1.6);
180  testVector.m_positionB = Vector(10, 0, 1.6);
181  testVector.m_pLos = std::min(1.0, std::max(0.0, 0.8962 * exp(-0.017 * 10.0)));
182  testVector.m_typeId = ProbabilisticV2vUrbanChannelConditionModel::GetTypeId();
183  testVector.m_pNlosv = std::min(
184  1.0,
185  std::max(0.0,
186  1 / (0.0242 * 10.0) * exp(-(log(10.0) - 5.0115) * (log(10.0) - 5.0115) / 2.2092)));
187  testVector.m_density = "High";
188  m_testVectors.Add(testVector);
189 
190  testVector.m_positionA = Vector(0, 0, 1.6);
191  testVector.m_positionB = Vector(100, 0, 1.6);
192  testVector.m_pLos = std::min(1.0, std::max(0.0, 0.8962 * exp(-0.017 * 100.0)));
193  testVector.m_typeId = ProbabilisticV2vUrbanChannelConditionModel::GetTypeId();
194  testVector.m_pNlosv =
195  std::min(1.0,
196  std::max(0.0,
197  1 / (0.0242 * 100.0) *
198  exp(-(log(100.0) - 5.0115) * (log(100.0) - 5.0115) / 2.2092)));
199  testVector.m_density = "High";
200  m_testVectors.Add(testVector);
201 
202  // create the factory for the channel condition models
203  ObjectFactory condModelFactory;
204 
205  // create the two nodes
207  nodes.Create(2);
208 
209  // create the mobility models
210  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
211  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel>();
212 
213  // aggregate the nodes and the mobility models
214  nodes.Get(0)->AggregateObject(a);
215  nodes.Get(1)->AggregateObject(b);
216 
217  // Get the channel condition multiple times and compute the LOS probability
218  uint32_t numberOfReps = 500000;
219  for (uint32_t i = 0; i < m_testVectors.GetN(); ++i)
220  {
221  testVector = m_testVectors.Get(i);
222 
223  // set the distance between the two nodes
224  a->SetPosition(testVector.m_positionA);
225  b->SetPosition(testVector.m_positionB);
226 
227  // create the channel condition model
228  condModelFactory.SetTypeId(testVector.m_typeId);
230  m_condModel->SetAttribute("UpdatePeriod", TimeValue(MilliSeconds(9)));
232  m_condModel->SetAttribute("Density", StringValue(testVector.m_density));
233 
234  m_numLos = 0;
235  m_numNlosv = 0;
236  for (uint32_t j = 0; j < numberOfReps; j++)
237  {
238  Simulator::Schedule(MilliSeconds(10 * j),
240  this,
241  a,
242  b);
243  }
244 
245  Simulator::Run();
246  Simulator::Destroy();
247 
248  double resultPlos = double(m_numLos) / double(numberOfReps);
249  double resultPnlosv = double(m_numNlosv) / double(numberOfReps);
250  NS_LOG_DEBUG(testVector.m_typeId << " a pos " << testVector.m_positionA << " b pos "
251  << testVector.m_positionB << " numLos " << m_numLos
252  << " numberOfReps " << numberOfReps << " resultPlos "
253  << resultPlos << " ref " << testVector.m_pLos);
254  NS_TEST_EXPECT_MSG_EQ_TOL(resultPlos,
255  testVector.m_pLos,
256  m_tolerance,
257  "Got unexpected LOS probability");
258  NS_LOG_DEBUG(testVector.m_typeId << " a pos " << testVector.m_positionA << " b pos "
259  << testVector.m_positionB << " numNlosv " << m_numNlosv
260  << " numberOfReps " << numberOfReps << " resultPnlosv "
261  << resultPnlosv << " ref " << testVector.m_pNlosv);
262  NS_TEST_EXPECT_MSG_EQ_TOL(resultPnlosv,
263  testVector.m_pNlosv,
264  m_tolerance,
265  "Got unexpected NLOSv probability");
266  }
267 }
268 
282 {
283  public:
288 
293 
294  private:
298  void DoRun() override;
299 
308 
312  struct TestVector
313  {
314  Vector m_positionA;
315  Vector m_positionB;
316  double m_pLos{0.0};
317  double m_pNlos{0.0};
318  std::string m_density;
320  };
321 
324  uint64_t m_numLos{0};
325  uint64_t m_numNlos{0};
326  double m_tolerance;
327 };
328 
330  : TestCase("Test case for the class ProbabilisticV2vHighwayChannelConditionModel"),
331  m_testVectors(),
332  m_tolerance(5e-3)
333 {
334 }
335 
337 {
338 }
339 
340 void
343 {
345  if (cond->GetLosCondition() == ChannelCondition::LosConditionValue::LOS)
346  {
347  m_numLos++;
348  }
349  else if (cond->GetLosCondition() == ChannelCondition::LosConditionValue::NLOS)
350  {
351  m_numNlos++;
352  }
353 }
354 
355 void
357 {
358  RngSeedManager::SetSeed(1);
359  RngSeedManager::SetRun(1);
360 
361  // create the test vector
362  TestVector testVector;
363 
364  // tests for the V2v Highway scenario
365  testVector.m_positionA = Vector(0, 0, 1.6);
366  testVector.m_positionB = Vector(10, 0, 1.6);
367  double aLos = 1.5e-6;
368  double bLos = -0.0015;
369  double cLos = 1.0;
370  testVector.m_pLos = std::min(1.0, std::max(0.0, aLos * 10.0 * 10.0 + bLos * 10.0 + cLos));
371  testVector.m_typeId = ProbabilisticV2vHighwayChannelConditionModel::GetTypeId();
372  double aNlos = -2.9e-7;
373  double bNlos = 0.00059;
374  double cNlos = 0.0017;
375  testVector.m_pNlos = std::min(1.0, std::max(0.0, aNlos * 10.0 * 10.0 + bNlos * 10.0 + cNlos));
376  testVector.m_density = "Low";
377  m_testVectors.Add(testVector);
378 
379  testVector.m_positionA = Vector(0, 0, 1.6);
380  testVector.m_positionB = Vector(100, 0, 1.6);
381  testVector.m_pLos = std::min(1.0, std::max(0.0, aLos * 100.0 * 100.0 + bLos * 100.0 + cLos));
382  testVector.m_typeId = ProbabilisticV2vHighwayChannelConditionModel::GetTypeId();
383  testVector.m_pNlos =
384  std::min(1.0, std::max(0.0, aNlos * 100.0 * 100.0 + bNlos * 100.0 + cNlos));
385  testVector.m_density = "Low";
386  m_testVectors.Add(testVector);
387 
388  testVector.m_positionA = Vector(0, 0, 1.6);
389  testVector.m_positionB = Vector(10, 0, 1.6);
390  aLos = 2.7e-6;
391  bLos = -0.0025;
392  cLos = 1.0;
393  testVector.m_pLos = std::min(1.0, std::max(0.0, aLos * 10.0 * 10.0 + bLos * 10.0 + cLos));
394  testVector.m_typeId = ProbabilisticV2vHighwayChannelConditionModel::GetTypeId();
395  aNlos = -3.7e-7;
396  bNlos = 0.00061;
397  cNlos = 0.015;
398  testVector.m_pNlos = std::min(1.0, std::max(0.0, aNlos * 10.0 * 10.0 + bNlos * 10.0 + cNlos));
399  testVector.m_density = "Medium";
400  m_testVectors.Add(testVector);
401 
402  testVector.m_positionA = Vector(0, 0, 1.6);
403  testVector.m_positionB = Vector(100, 0, 1.6);
404  testVector.m_pLos = std::min(1.0, std::max(0.0, aLos * 100.0 * 100.0 + bLos * 100.0 + cLos));
405  testVector.m_typeId = ProbabilisticV2vHighwayChannelConditionModel::GetTypeId();
406  testVector.m_pNlos =
407  std::min(1.0, std::max(0.0, aNlos * 100.0 * 100.0 + bNlos * 100.0 + cNlos));
408  testVector.m_density = "Medium";
409  m_testVectors.Add(testVector);
410 
411  testVector.m_positionA = Vector(0, 0, 1.6);
412  testVector.m_positionB = Vector(10, 0, 1.6);
413  aLos = 3.2e-6;
414  bLos = -0.003;
415  cLos = 1.0;
416  testVector.m_pLos = std::min(1.0, std::max(0.0, aLos * 10.0 * 10.0 + bLos * 10.0 + cLos));
417  testVector.m_typeId = ProbabilisticV2vHighwayChannelConditionModel::GetTypeId();
418  aNlos = -4.1e-7;
419  bNlos = 0.00067;
420  cNlos = 0.0;
421  testVector.m_pNlos = std::min(1.0, std::max(0.0, aNlos * 10.0 * 10.0 + bNlos * 10.0 + cNlos));
422  testVector.m_density = "High";
423  m_testVectors.Add(testVector);
424 
425  testVector.m_positionA = Vector(0, 0, 1.6);
426  testVector.m_positionB = Vector(100, 0, 1.6);
427  testVector.m_pLos = std::min(1.0, std::max(0.0, aLos * 100.0 * 100.0 + bLos * 100.0 + cLos));
428  testVector.m_typeId = ProbabilisticV2vHighwayChannelConditionModel::GetTypeId();
429  testVector.m_pNlos =
430  std::min(1.0, std::max(0.0, aNlos * 100.0 * 100.0 + bNlos * 100.0 + cNlos));
431  testVector.m_density = "High";
432  m_testVectors.Add(testVector);
433 
434  // create the factory for the channel condition models
435  ObjectFactory condModelFactory;
436 
437  // create the two nodes
439  nodes.Create(2);
440 
441  // create the mobility models
442  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
443  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel>();
444 
445  // aggregate the nodes and the mobility models
446  nodes.Get(0)->AggregateObject(a);
447  nodes.Get(1)->AggregateObject(b);
448 
449  // Get the channel condition multiple times and compute the LOS probability
450  uint32_t numberOfReps = 500000;
451  for (uint32_t i = 0; i < m_testVectors.GetN(); ++i)
452  {
453  testVector = m_testVectors.Get(i);
454 
455  // set the distance between the two nodes
456  a->SetPosition(testVector.m_positionA);
457  b->SetPosition(testVector.m_positionB);
458 
459  // create the channel condition model
460  condModelFactory.SetTypeId(testVector.m_typeId);
462  m_condModel->SetAttribute("UpdatePeriod", TimeValue(MilliSeconds(9)));
464  m_condModel->SetAttribute("Density", StringValue(testVector.m_density));
465 
466  m_numLos = 0;
467  m_numNlos = 0;
468  for (uint32_t j = 0; j < numberOfReps; j++)
469  {
470  Simulator::Schedule(MilliSeconds(10 * j),
472  this,
473  a,
474  b);
475  }
476 
477  Simulator::Run();
478  Simulator::Destroy();
479 
480  double resultPlos = double(m_numLos) / double(numberOfReps);
481  double resultPnlos = double(m_numNlos) / double(numberOfReps);
482  NS_LOG_DEBUG(testVector.m_typeId << " a pos " << testVector.m_positionA << " b pos "
483  << testVector.m_positionB << " numLos " << m_numLos
484  << " numberOfReps " << numberOfReps << " resultPlos "
485  << resultPlos << " ref " << testVector.m_pLos);
486  NS_TEST_EXPECT_MSG_EQ_TOL(resultPlos,
487  testVector.m_pLos,
488  m_tolerance,
489  "Got unexpected LOS probability");
490  NS_LOG_DEBUG(testVector.m_typeId << " a pos " << testVector.m_positionA << " b pos "
491  << testVector.m_positionB << " numNlos " << m_numNlos
492  << " numberOfReps " << numberOfReps << " resultPnlos "
493  << resultPnlos << " ref " << testVector.m_pNlos);
494  NS_TEST_EXPECT_MSG_EQ_TOL(resultPnlos,
495  testVector.m_pNlos,
496  m_tolerance,
497  "Got unexpected NLOS probability");
498  }
499 }
500 
516 {
517  public:
519 };
520 
522  : TestSuite("probabilistic-v2v-channel-condition-model", SYSTEM)
523 {
525  TestCase::QUICK); // test for a fully probabilistic model (NLOS vs LOS vs NLOSv), in
526  // V2V urban scenario
528  TestCase::QUICK); // test for a fully probabilistic model (NLOS vs LOS vs NLOSv), in
529  // V2V highway scenario*/
530 }
531 
#define min(a, b)
Definition: 80211b.c:41
#define max(a, b)
Definition: 80211b.c:42
Test suite for the probabilistic V2V channel condition model.
Test case for the V2V Highway channel condition models using a fully probabilistic model to determine...
void EvaluateChannelCondition(Ptr< MobilityModel > a, Ptr< MobilityModel > b)
Evaluates the channel condition between two nodes by calling the method GetChannelCondition on m_cond...
Ptr< ProbabilisticV2vHighwayChannelConditionModel > m_condModel
the channel condition model
void DoRun() override
Builds the simulation scenario and perform the tests.
TestVectors< TestVector > m_testVectors
array containing all the test vectors
Test case for the V2V Urban channel condition models using a fully probabilistic model to determine L...
TestVectors< TestVector > m_testVectors
array containing all the test vectors
void DoRun() override
Builds the simulation scenario and perform the tests.
void EvaluateChannelCondition(Ptr< MobilityModel > a, Ptr< MobilityModel > b)
Evaluates the channel condition between two nodes by calling the method GetChannelCondition on m_cond...
Ptr< ProbabilisticV2vUrbanChannelConditionModel > m_condModel
the channel condition model
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.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:204
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
Computes the channel condition for the V2V Highway scenario.
Computes the channel condition for the V2V Urban scenario.
Hold variables of type string.
Definition: string.h:56
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
A simple way to store test vectors (for stimulus or from responses)
Definition: test.h:1319
int64_t AssignStreams(int64_t stream) override
If this model uses objects of type RandomVariableStream, set the stream numbers to the integers start...
Ptr< ChannelCondition > GetChannelCondition(Ptr< const MobilityModel > a, Ptr< const MobilityModel > b) const override
Retrieve the condition of the channel between a and b.
a unique identifier for an interface.
Definition: type-id.h:59
#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
#define NS_TEST_EXPECT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report if ...
Definition: test.h:510
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
NodeContainer nodes
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static ProbabilisticV2vChCondModelsTestSuite g_probabilisticV2vChCondModelsTestSuite
Static variable for test initialization.
TypeId m_typeId
the type ID of the channel condition model to be used
TypeId m_typeId
the type ID of the channel condition model to be used