A Discrete-Event Network Simulator
API
probabilistic-v2v-channel-condition-model-test.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2020 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
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 #include "ns3/abort.h"
20 #include "ns3/test.h"
21 #include "ns3/config.h"
22 #include "ns3/channel-condition-model.h"
23 #include "ns3/probabilistic-v2v-channel-condition-model.h"
24 #include "ns3/three-gpp-v2v-propagation-loss-model.h"
25 #include "ns3/constant-position-mobility-model.h"
26 #include "ns3/log.h"
27 #include "ns3/simulator.h"
28 #include "ns3/double.h"
29 #include "ns3/uinteger.h"
30 #include "ns3/boolean.h"
31 #include "ns3/core-module.h"
32 #include "ns3/node-container.h"
33 
34 using namespace ns3;
35 
36 NS_LOG_COMPONENT_DEFINE ("ProbabilisticV2vChannelConditionModelsTest");
37 
51 {
52 public:
57 
62 
63 private:
67  virtual void DoRun (void);
68 
76  void EvaluateChannelCondition (Ptr<MobilityModel> a, Ptr<MobilityModel> b);
77 
81  struct TestVector
82  {
83  Vector m_positionA;
84  Vector m_positionB;
85  double m_pLos {0.0};
86  double m_pNlosv {0.0};
87  std::string m_density;
89  };
90 
93  uint64_t m_numLos {0};
94  uint64_t m_numNlosv {0};
95  double m_tolerance;
96 };
97 
99  : TestCase ("Test case for the class ProbabilisticV2vUrbanChannelConditionModel"),
100  m_testVectors (),
101  m_tolerance (5e-3)
102 {}
103 
105 {}
106 
107 void
109 {
111  if (cond->GetLosCondition () == ChannelCondition::LosConditionValue::LOS)
112  {
113  m_numLos++;
114  }
115  else if (cond->GetLosCondition () == ChannelCondition::LosConditionValue::NLOSv)
116  {
117  m_numNlosv++;
118  }
119 }
120 
121 void
123 {
124  RngSeedManager::SetSeed (1);
125  RngSeedManager::SetRun (1);
126 
127  // create the test vector
128  TestVector testVector;
129 
130  // tests for the V2v Urban scenario
131  testVector.m_positionA = Vector (0, 0, 1.6);
132  testVector.m_positionB = Vector (10, 0, 1.6);
133  testVector.m_pLos = std::min (1.0, std::max (0.0, 0.8548 * exp (-0.0064 * 10.0)));
134  testVector.m_typeId = ProbabilisticV2vUrbanChannelConditionModel::GetTypeId ();
135  testVector.m_pNlosv = std::min (1.0, std::max (0.0, 1 / (0.0396 * 10.0) * exp (-(log (10.0) - 5.2718) * (log (10.0) - 5.2718) / 3.4827)));
136  testVector.m_density = "Low";
137  m_testVectors.Add (testVector);
138 
139  testVector.m_positionA = Vector (0, 0, 1.6);
140  testVector.m_positionB = Vector (100, 0, 1.6);
141  testVector.m_pLos = std::min (1.0, std::max (0.0, 0.8548 * exp (-0.0064 * 100.0)));
142  testVector.m_typeId = ProbabilisticV2vUrbanChannelConditionModel::GetTypeId ();
143  testVector.m_pNlosv = std::min (1.0, std::max (0.0, 1 / (0.0396 * 100.0) * exp (-(log (100.0) - 5.2718) * (log (100.0) - 5.2718) / 3.4827)));
144  testVector.m_density = "Low";
145  m_testVectors.Add (testVector);
146 
147  testVector.m_positionA = Vector (0, 0, 1.6);
148  testVector.m_positionB = Vector (10, 0, 1.6);
149  testVector.m_pLos = std::min (1.0, std::max (0.0, 0.8372 * exp (-0.0114 * 10.0)));
150  testVector.m_typeId = ProbabilisticV2vUrbanChannelConditionModel::GetTypeId ();
151  testVector.m_pNlosv = std::min (1.0, std::max (0.0, 1 / (0.0312 * 10.0) * exp (-(log (10.0) - 5.0063) * (log (10.0) - 5.0063) / 2.4544)));
152  testVector.m_density = "Medium";
153  m_testVectors.Add (testVector);
154 
155  testVector.m_positionA = Vector (0, 0, 1.6);
156  testVector.m_positionB = Vector (100, 0, 1.6);
157  testVector.m_pLos = std::min (1.0, std::max (0.0, 0.8372 * exp (-0.0114 * 100.0)));
158  testVector.m_typeId = ProbabilisticV2vUrbanChannelConditionModel::GetTypeId ();
159  testVector.m_pNlosv = std::min (1.0, std::max (0.0, 1 / (0.0312 * 100.0) * exp (-(log (100.0) - 5.0063) * (log (100.0) - 5.0063) / 2.4544)));
160  testVector.m_density = "Medium";
161  m_testVectors.Add (testVector);
162 
163  testVector.m_positionA = Vector (0, 0, 1.6);
164  testVector.m_positionB = Vector (10, 0, 1.6);
165  testVector.m_pLos = std::min (1.0, std::max (0.0, 0.8962 * exp (-0.017 * 10.0)));
166  testVector.m_typeId = ProbabilisticV2vUrbanChannelConditionModel::GetTypeId ();
167  testVector.m_pNlosv = std::min (1.0, std::max (0.0, 1 / (0.0242 * 10.0) * exp (-(log (10.0) - 5.0115) * (log (10.0) - 5.0115) / 2.2092)));
168  testVector.m_density = "High";
169  m_testVectors.Add (testVector);
170 
171  testVector.m_positionA = Vector (0, 0, 1.6);
172  testVector.m_positionB = Vector (100, 0, 1.6);
173  testVector.m_pLos = std::min (1.0, std::max (0.0, 0.8962 * exp (-0.017 * 100.0)));
174  testVector.m_typeId = ProbabilisticV2vUrbanChannelConditionModel::GetTypeId ();
175  testVector.m_pNlosv = std::min (1.0, std::max (0.0, 1 / (0.0242 * 100.0) * exp (-(log (100.0) - 5.0115) * (log (100.0) - 5.0115) / 2.2092)));
176  testVector.m_density = "High";
177  m_testVectors.Add (testVector);
178 
179  // create the factory for the channel condition models
180  ObjectFactory condModelFactory;
181 
182  // create the two nodes
184  nodes.Create (2);
185 
186  // create the mobility models
187  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
188  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
189 
190  // aggregate the nodes and the mobility models
191  nodes.Get (0)->AggregateObject (a);
192  nodes.Get (1)->AggregateObject (b);
193 
194  // Get the channel condition multiple times and compute the LOS probability
195  uint32_t numberOfReps = 500000;
196  for (uint32_t i = 0; i < m_testVectors.GetN (); ++i)
197  {
198  testVector = m_testVectors.Get (i);
199 
200  // set the distance between the two nodes
201  a->SetPosition (testVector.m_positionA);
202  b->SetPosition (testVector.m_positionB);
203 
204  // create the channel condition model
205  condModelFactory.SetTypeId (testVector.m_typeId);
207  m_condModel->SetAttribute ("UpdatePeriod", TimeValue (MilliSeconds (9)));
209  m_condModel->SetAttribute ("Density", StringValue (testVector.m_density));
210 
211  m_numLos = 0;
212  m_numNlosv = 0;
213  for (uint32_t j = 0; j < numberOfReps; j++)
214  {
215  Simulator::Schedule (MilliSeconds (10 * j), &V2vUrbanProbChCondModelTestCase::EvaluateChannelCondition, this, a, b);
216  }
217 
218  Simulator::Run ();
219  Simulator::Destroy ();
220 
221  double resultPlos = double (m_numLos) / double (numberOfReps);
222  double resultPnlosv = double (m_numNlosv) / double (numberOfReps);
223  NS_LOG_DEBUG (testVector.m_typeId << " a pos " << testVector.m_positionA << " b pos " << testVector.m_positionB << " numLos " << m_numLos << " numberOfReps " << numberOfReps << " resultPlos " << resultPlos << " ref " << testVector.m_pLos);
224  NS_TEST_EXPECT_MSG_EQ_TOL (resultPlos, testVector.m_pLos, m_tolerance, "Got unexpected LOS probability");
225  NS_LOG_DEBUG (testVector.m_typeId << " a pos " << testVector.m_positionA << " b pos " << testVector.m_positionB << " numNlosv " << m_numNlosv << " numberOfReps " << numberOfReps << " resultPnlosv " << resultPnlosv << " ref " << testVector.m_pNlosv);
226  NS_TEST_EXPECT_MSG_EQ_TOL (resultPnlosv, testVector.m_pNlosv, m_tolerance, "Got unexpected NLOSv probability");
227  }
228 }
229 
243 {
244 public:
249 
254 
255 private:
259  virtual void DoRun (void);
260 
269 
273  struct TestVector
274  {
275  Vector m_positionA;
276  Vector m_positionB;
277  double m_pLos {0.0};
278  double m_pNlos {0.0};
279  std::string m_density;
281  };
282 
285  uint64_t m_numLos {0};
286  uint64_t m_numNlos {0};
287  double m_tolerance;
288 };
289 
291  : TestCase ("Test case for the class ProbabilisticV2vHighwayChannelConditionModel"),
292  m_testVectors (),
293  m_tolerance (5e-3)
294 {}
295 
297 {}
298 
299 void
301 {
303  if (cond->GetLosCondition () == ChannelCondition::LosConditionValue::LOS)
304  {
305  m_numLos++;
306  }
307  else if (cond->GetLosCondition () == ChannelCondition::LosConditionValue::NLOS)
308  {
309  m_numNlos++;
310  }
311 }
312 
313 void
315 {
316  RngSeedManager::SetSeed (1);
317  RngSeedManager::SetRun (1);
318 
319  // create the test vector
320  TestVector testVector;
321 
322  // tests for the V2v Highway scenario
323  testVector.m_positionA = Vector (0, 0, 1.6);
324  testVector.m_positionB = Vector (10, 0, 1.6);
325  double aLos = 1.5e-6;
326  double bLos = -0.0015;
327  double cLos = 1.0;
328  testVector.m_pLos = std::min (1.0, std::max (0.0, aLos * 10.0 * 10.0 + bLos * 10.0 + cLos));
329  testVector.m_typeId = ProbabilisticV2vHighwayChannelConditionModel::GetTypeId ();
330  double aNlos = -2.9e-7;
331  double bNlos = 0.00059;
332  double cNlos = 0.0017;
333  testVector.m_pNlos = std::min (1.0, std::max (0.0, aNlos * 10.0 * 10.0 + bNlos * 10.0 + cNlos));
334  testVector.m_density = "Low";
335  m_testVectors.Add (testVector);
336 
337  testVector.m_positionA = Vector (0, 0, 1.6);
338  testVector.m_positionB = Vector (100, 0, 1.6);
339  testVector.m_pLos = std::min (1.0, std::max (0.0, aLos * 100.0 * 100.0 + bLos * 100.0 + cLos));
340  testVector.m_typeId = ProbabilisticV2vHighwayChannelConditionModel::GetTypeId ();
341  testVector.m_pNlos = std::min (1.0, std::max (0.0, aNlos * 100.0 * 100.0 + bNlos * 100.0 + cNlos));
342  testVector.m_density = "Low";
343  m_testVectors.Add (testVector);
344 
345  testVector.m_positionA = Vector (0, 0, 1.6);
346  testVector.m_positionB = Vector (10, 0, 1.6);
347  aLos = 2.7e-6;
348  bLos = -0.0025;
349  cLos = 1.0;
350  testVector.m_pLos = std::min (1.0, std::max (0.0, aLos * 10.0 * 10.0 + bLos * 10.0 + cLos));
351  testVector.m_typeId = ProbabilisticV2vHighwayChannelConditionModel::GetTypeId ();
352  aNlos = -3.7e-7;
353  bNlos = 0.00061;
354  cNlos = 0.015;
355  testVector.m_pNlos = std::min (1.0, std::max (0.0, aNlos * 10.0 * 10.0 + bNlos * 10.0 + cNlos));
356  testVector.m_density = "Medium";
357  m_testVectors.Add (testVector);
358 
359  testVector.m_positionA = Vector (0, 0, 1.6);
360  testVector.m_positionB = Vector (100, 0, 1.6);
361  testVector.m_pLos = std::min (1.0, std::max (0.0, aLos * 100.0 * 100.0 + bLos * 100.0 + cLos));
362  testVector.m_typeId = ProbabilisticV2vHighwayChannelConditionModel::GetTypeId ();
363  testVector.m_pNlos = std::min (1.0, std::max (0.0, aNlos * 100.0 * 100.0 + bNlos * 100.0 + cNlos));
364  testVector.m_density = "Medium";
365  m_testVectors.Add (testVector);
366 
367  testVector.m_positionA = Vector (0, 0, 1.6);
368  testVector.m_positionB = Vector (10, 0, 1.6);
369  aLos = 3.2e-6;
370  bLos = -0.003;
371  cLos = 1.0;
372  testVector.m_pLos = std::min (1.0, std::max (0.0, aLos * 10.0 * 10.0 + bLos * 10.0 + cLos));
373  testVector.m_typeId = ProbabilisticV2vHighwayChannelConditionModel::GetTypeId ();
374  aNlos = -4.1e-7;
375  bNlos = 0.00067;
376  cNlos = 0.0;
377  testVector.m_pNlos = std::min (1.0, std::max (0.0, aNlos * 10.0 * 10.0 + bNlos * 10.0 + cNlos));
378  testVector.m_density = "High";
379  m_testVectors.Add (testVector);
380 
381  testVector.m_positionA = Vector (0, 0, 1.6);
382  testVector.m_positionB = Vector (100, 0, 1.6);
383  testVector.m_pLos = std::min (1.0, std::max (0.0, aLos * 100.0 * 100.0 + bLos * 100.0 + cLos));
384  testVector.m_typeId = ProbabilisticV2vHighwayChannelConditionModel::GetTypeId ();
385  testVector.m_pNlos = std::min (1.0, std::max (0.0, aNlos * 100.0 * 100.0 + bNlos * 100.0 + cNlos));
386  testVector.m_density = "High";
387  m_testVectors.Add (testVector);
388 
389  // create the factory for the channel condition models
390  ObjectFactory condModelFactory;
391 
392  // create the two nodes
394  nodes.Create (2);
395 
396  // create the mobility models
397  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
398  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
399 
400  // aggregate the nodes and the mobility models
401  nodes.Get (0)->AggregateObject (a);
402  nodes.Get (1)->AggregateObject (b);
403 
404  // Get the channel condition multiple times and compute the LOS probability
405  uint32_t numberOfReps = 500000;
406  for (uint32_t i = 0; i < m_testVectors.GetN (); ++i)
407  {
408  testVector = m_testVectors.Get (i);
409 
410  // set the distance between the two nodes
411  a->SetPosition (testVector.m_positionA);
412  b->SetPosition (testVector.m_positionB);
413 
414  // create the channel condition model
415  condModelFactory.SetTypeId (testVector.m_typeId);
417  m_condModel->SetAttribute ("UpdatePeriod", TimeValue (MilliSeconds (9)));
419  m_condModel->SetAttribute ("Density", StringValue (testVector.m_density));
420 
421  m_numLos = 0;
422  m_numNlos = 0;
423  for (uint32_t j = 0; j < numberOfReps; j++)
424  {
425  Simulator::Schedule (MilliSeconds (10 * j), &V2vHighwayProbChCondModelTestCase::EvaluateChannelCondition, this, a, b);
426  }
427 
428  Simulator::Run ();
429  Simulator::Destroy ();
430 
431  double resultPlos = double (m_numLos) / double (numberOfReps);
432  double resultPnlos = double (m_numNlos) / double (numberOfReps);
433  NS_LOG_DEBUG (testVector.m_typeId << " a pos " << testVector.m_positionA << " b pos " << testVector.m_positionB << " numLos " << m_numLos << " numberOfReps " << numberOfReps << " resultPlos " << resultPlos << " ref " << testVector.m_pLos);
434  NS_TEST_EXPECT_MSG_EQ_TOL (resultPlos, testVector.m_pLos, m_tolerance, "Got unexpected LOS probability");
435  NS_LOG_DEBUG (testVector.m_typeId << " a pos " << testVector.m_positionA << " b pos " << testVector.m_positionB << " numNlos " << m_numNlos << " numberOfReps " << numberOfReps << " resultPnlos " << resultPnlos << " ref " << testVector.m_pNlos);
436  NS_TEST_EXPECT_MSG_EQ_TOL (resultPnlos, testVector.m_pNlos, m_tolerance, "Got unexpected NLOS probability");
437  }
438 }
439 
455 {
456 public:
458 };
459 
461  : TestSuite ("probabilistic-v2v-channel-condition-model", SYSTEM)
462 {
463  AddTestCase (new V2vUrbanProbChCondModelTestCase, TestCase::QUICK); // test for a fully probabilistic model (NLOS vs LOS vs NLOSv), in V2V urban scenario
464  AddTestCase (new V2vHighwayProbChCondModelTestCase, TestCase::QUICK); // test for a fully probabilistic model (NLOS vs LOS vs NLOSv), in V2V highway scenario*/
465 }
466 
#define min(a, b)
Definition: 80211b.c:42
#define max(a, b)
Definition: 80211b.c:43
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
TestVectors< TestVector > m_testVectors
array containing all the test vectors
virtual void DoRun(void)
Builds the simulation scenario and perform the tests.
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 EvaluateChannelCondition(Ptr< MobilityModel > a, Ptr< MobilityModel > b)
Evaluates the channel condition between two nodes by calling the method GetChannelCondition on m_cond...
virtual void DoRun(void)
Builds the simulation scenario and perform the tests.
Ptr< ProbabilisticV2vUrbanChannelConditionModel > m_condModel
the channel condition model
void SetPosition(const Vector &position)
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
Instantiate subclasses of ns3::Object.
Ptr< Object > Create(void) 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.
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:41
encapsulates test code
Definition: test.h:994
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
A suite of tests to run.
Definition: test.h:1188
A simple way to store test vectors (for stimulus or from responses)
Definition: test.h:1251
virtual int64_t AssignStreams(int64_t stream) override
If this model uses objects of type RandomVariableStream, set the stream numbers to the integers start...
virtual Ptr< ChannelCondition > GetChannelCondition(Ptr< const MobilityModel > a, Ptr< const MobilityModel > b) const override
Retrieve the condition of the channel between a and b.
AttributeValue implementation for Time.
Definition: nstime.h:1308
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:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#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:491
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.
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