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 
49 {
50 public:
55 
60 
61 private:
65  virtual void DoRun (void);
66 
74  void EvaluateChannelCondition (Ptr<MobilityModel> a, Ptr<MobilityModel> b);
75 
79  struct TestVector
80  {
81  Vector m_positionA;
82  Vector m_positionB;
83  double m_pLos {0.0};
84  double m_pNlosv {0.0};
85  std::string m_density;
87  };
88 
91  uint64_t m_numLos {0};
92  uint64_t m_numNlosv {0};
93  double m_tolerance;
94 };
95 
97  : TestCase ("Test case for the class ProbabilisticV2vUrbanChannelConditionModel"),
98  m_testVectors (),
99  m_tolerance (5e-3)
100 {}
101 
103 {}
104 
105 void
107 {
109  if (cond->GetLosCondition () == ChannelCondition::LosConditionValue::LOS)
110  {
111  m_numLos++;
112  }
113  else if (cond->GetLosCondition () == ChannelCondition::LosConditionValue::NLOSv)
114  {
115  m_numNlosv++;
116  }
117 }
118 
119 void
121 {
122  RngSeedManager::SetSeed (1);
123  RngSeedManager::SetRun (1);
124 
125  // create the test vector
126  TestVector testVector;
127 
128  // tests for the V2v Urban scenario
129  testVector.m_positionA = Vector (0, 0, 1.6);
130  testVector.m_positionB = Vector (10, 0, 1.6);
131  testVector.m_pLos = std::min (1.0, std::max (0.0, 0.8548 * exp (-0.0064 * 10.0)));
132  testVector.m_typeId = ProbabilisticV2vUrbanChannelConditionModel::GetTypeId ();
133  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)));
134  testVector.m_density = "Low";
135  m_testVectors.Add (testVector);
136 
137  testVector.m_positionA = Vector (0, 0, 1.6);
138  testVector.m_positionB = Vector (100, 0, 1.6);
139  testVector.m_pLos = std::min (1.0, std::max (0.0, 0.8548 * exp (-0.0064 * 100.0)));
140  testVector.m_typeId = ProbabilisticV2vUrbanChannelConditionModel::GetTypeId ();
141  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)));
142  testVector.m_density = "Low";
143  m_testVectors.Add (testVector);
144 
145  testVector.m_positionA = Vector (0, 0, 1.6);
146  testVector.m_positionB = Vector (10, 0, 1.6);
147  testVector.m_pLos = std::min (1.0, std::max (0.0, 0.8372 * exp (-0.0114 * 10.0)));
148  testVector.m_typeId = ProbabilisticV2vUrbanChannelConditionModel::GetTypeId ();
149  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)));
150  testVector.m_density = "Medium";
151  m_testVectors.Add (testVector);
152 
153  testVector.m_positionA = Vector (0, 0, 1.6);
154  testVector.m_positionB = Vector (100, 0, 1.6);
155  testVector.m_pLos = std::min (1.0, std::max (0.0, 0.8372 * exp (-0.0114 * 100.0)));
156  testVector.m_typeId = ProbabilisticV2vUrbanChannelConditionModel::GetTypeId ();
157  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)));
158  testVector.m_density = "Medium";
159  m_testVectors.Add (testVector);
160 
161  testVector.m_positionA = Vector (0, 0, 1.6);
162  testVector.m_positionB = Vector (10, 0, 1.6);
163  testVector.m_pLos = std::min (1.0, std::max (0.0, 0.8962 * exp (-0.017 * 10.0)));
164  testVector.m_typeId = ProbabilisticV2vUrbanChannelConditionModel::GetTypeId ();
165  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)));
166  testVector.m_density = "High";
167  m_testVectors.Add (testVector);
168 
169  testVector.m_positionA = Vector (0, 0, 1.6);
170  testVector.m_positionB = Vector (100, 0, 1.6);
171  testVector.m_pLos = std::min (1.0, std::max (0.0, 0.8962 * exp (-0.017 * 100.0)));
172  testVector.m_typeId = ProbabilisticV2vUrbanChannelConditionModel::GetTypeId ();
173  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)));
174  testVector.m_density = "High";
175  m_testVectors.Add (testVector);
176 
177  // create the factory for the channel condition models
178  ObjectFactory condModelFactory;
179 
180  // create the two nodes
182  nodes.Create (2);
183 
184  // create the mobility models
185  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
186  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
187 
188  // aggregate the nodes and the mobility models
189  nodes.Get (0)->AggregateObject (a);
190  nodes.Get (1)->AggregateObject (b);
191 
192  // Get the channel condition multiple times and compute the LOS probability
193  uint32_t numberOfReps = 500000;
194  for (uint32_t i = 0; i < m_testVectors.GetN (); ++i)
195  {
196  testVector = m_testVectors.Get (i);
197 
198  // set the distance between the two nodes
199  a->SetPosition (testVector.m_positionA);
200  b->SetPosition (testVector.m_positionB);
201 
202  // create the channel condition model
203  condModelFactory.SetTypeId (testVector.m_typeId);
205  m_condModel->SetAttribute ("UpdatePeriod", TimeValue (MilliSeconds (9)));
207  m_condModel->SetAttribute ("Density", StringValue (testVector.m_density));
208 
209  m_numLos = 0;
210  m_numNlosv = 0;
211  for (uint32_t j = 0; j < numberOfReps; j++)
212  {
213  Simulator::Schedule (MilliSeconds (10 * j), &V2vUrbanProbChCondModelTestCase::EvaluateChannelCondition, this, a, b);
214  }
215 
216  Simulator::Run ();
217  Simulator::Destroy ();
218 
219  double resultPlos = double (m_numLos) / double (numberOfReps);
220  double resultPnlosv = double (m_numNlosv) / double (numberOfReps);
221  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);
222  NS_TEST_EXPECT_MSG_EQ_TOL (resultPlos, testVector.m_pLos, m_tolerance, "Got unexpected LOS probability");
223  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);
224  NS_TEST_EXPECT_MSG_EQ_TOL (resultPnlosv, testVector.m_pNlosv, m_tolerance, "Got unexpected NLOSv probability");
225  }
226 }
227 
239 {
240 public:
245 
250 
251 private:
255  virtual void DoRun (void);
256 
265 
269  struct TestVector
270  {
271  Vector m_positionA;
272  Vector m_positionB;
273  double m_pLos {0.0};
274  double m_pNlos {0.0};
275  std::string m_density;
277  };
278 
281  uint64_t m_numLos {0};
282  uint64_t m_numNlos {0};
283  double m_tolerance;
284 };
285 
287  : TestCase ("Test case for the class ProbabilisticV2vHighwayChannelConditionModel"),
288  m_testVectors (),
289  m_tolerance (5e-3)
290 {}
291 
293 {}
294 
295 void
297 {
299  if (cond->GetLosCondition () == ChannelCondition::LosConditionValue::LOS)
300  {
301  m_numLos++;
302  }
303  else if (cond->GetLosCondition () == ChannelCondition::LosConditionValue::NLOS)
304  {
305  m_numNlos++;
306  }
307 }
308 
309 void
311 {
312  RngSeedManager::SetSeed (1);
313  RngSeedManager::SetRun (1);
314 
315  // create the test vector
316  TestVector testVector;
317 
318  // tests for the V2v Highway scenario
319  testVector.m_positionA = Vector (0, 0, 1.6);
320  testVector.m_positionB = Vector (10, 0, 1.6);
321  double aLos = 1.5e-6;
322  double bLos = -0.0015;
323  double cLos = 1.0;
324  testVector.m_pLos = std::min (1.0, std::max (0.0, aLos * 10.0 * 10.0 + bLos * 10.0 + cLos));
325  testVector.m_typeId = ProbabilisticV2vHighwayChannelConditionModel::GetTypeId ();
326  double aNlos = -2.9e-7;
327  double bNlos = 0.00059;
328  double cNlos = 0.0017;
329  testVector.m_pNlos = std::min (1.0, std::max (0.0, aNlos * 10.0 * 10.0 + bNlos * 10.0 + cNlos));
330  testVector.m_density = "Low";
331  m_testVectors.Add (testVector);
332 
333  testVector.m_positionA = Vector (0, 0, 1.6);
334  testVector.m_positionB = Vector (100, 0, 1.6);
335  testVector.m_pLos = std::min (1.0, std::max (0.0, aLos * 100.0 * 100.0 + bLos * 100.0 + cLos));
336  testVector.m_typeId = ProbabilisticV2vHighwayChannelConditionModel::GetTypeId ();
337  testVector.m_pNlos = std::min (1.0, std::max (0.0, aNlos * 100.0 * 100.0 + bNlos * 100.0 + cNlos));
338  testVector.m_density = "Low";
339  m_testVectors.Add (testVector);
340 
341  testVector.m_positionA = Vector (0, 0, 1.6);
342  testVector.m_positionB = Vector (10, 0, 1.6);
343  aLos = 2.7e-6;
344  bLos = -0.0025;
345  cLos = 1.0;
346  testVector.m_pLos = std::min (1.0, std::max (0.0, aLos * 10.0 * 10.0 + bLos * 10.0 + cLos));
347  testVector.m_typeId = ProbabilisticV2vHighwayChannelConditionModel::GetTypeId ();
348  aNlos = -3.7e-7;
349  bNlos = 0.00061;
350  cNlos = 0.015;
351  testVector.m_pNlos = std::min (1.0, std::max (0.0, aNlos * 10.0 * 10.0 + bNlos * 10.0 + cNlos));
352  testVector.m_density = "Medium";
353  m_testVectors.Add (testVector);
354 
355  testVector.m_positionA = Vector (0, 0, 1.6);
356  testVector.m_positionB = Vector (100, 0, 1.6);
357  testVector.m_pLos = std::min (1.0, std::max (0.0, aLos * 100.0 * 100.0 + bLos * 100.0 + cLos));
358  testVector.m_typeId = ProbabilisticV2vHighwayChannelConditionModel::GetTypeId ();
359  testVector.m_pNlos = std::min (1.0, std::max (0.0, aNlos * 100.0 * 100.0 + bNlos * 100.0 + cNlos));
360  testVector.m_density = "Medium";
361  m_testVectors.Add (testVector);
362 
363  testVector.m_positionA = Vector (0, 0, 1.6);
364  testVector.m_positionB = Vector (10, 0, 1.6);
365  aLos = 3.2e-6;
366  bLos = -0.003;
367  cLos = 1.0;
368  testVector.m_pLos = std::min (1.0, std::max (0.0, aLos * 10.0 * 10.0 + bLos * 10.0 + cLos));
369  testVector.m_typeId = ProbabilisticV2vHighwayChannelConditionModel::GetTypeId ();
370  aNlos = -4.1e-7;
371  bNlos = 0.00067;
372  cNlos = 0.0;
373  testVector.m_pNlos = std::min (1.0, std::max (0.0, aNlos * 10.0 * 10.0 + bNlos * 10.0 + cNlos));
374  testVector.m_density = "High";
375  m_testVectors.Add (testVector);
376 
377  testVector.m_positionA = Vector (0, 0, 1.6);
378  testVector.m_positionB = Vector (100, 0, 1.6);
379  testVector.m_pLos = std::min (1.0, std::max (0.0, aLos * 100.0 * 100.0 + bLos * 100.0 + cLos));
380  testVector.m_typeId = ProbabilisticV2vHighwayChannelConditionModel::GetTypeId ();
381  testVector.m_pNlos = std::min (1.0, std::max (0.0, aNlos * 100.0 * 100.0 + bNlos * 100.0 + cNlos));
382  testVector.m_density = "High";
383  m_testVectors.Add (testVector);
384 
385  // create the factory for the channel condition models
386  ObjectFactory condModelFactory;
387 
388  // create the two nodes
390  nodes.Create (2);
391 
392  // create the mobility models
393  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
394  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
395 
396  // aggregate the nodes and the mobility models
397  nodes.Get (0)->AggregateObject (a);
398  nodes.Get (1)->AggregateObject (b);
399 
400  // Get the channel condition multiple times and compute the LOS probability
401  uint32_t numberOfReps = 500000;
402  for (uint32_t i = 0; i < m_testVectors.GetN (); ++i)
403  {
404  testVector = m_testVectors.Get (i);
405 
406  // set the distance between the two nodes
407  a->SetPosition (testVector.m_positionA);
408  b->SetPosition (testVector.m_positionB);
409 
410  // create the channel condition model
411  condModelFactory.SetTypeId (testVector.m_typeId);
413  m_condModel->SetAttribute ("UpdatePeriod", TimeValue (MilliSeconds (9)));
415  m_condModel->SetAttribute ("Density", StringValue (testVector.m_density));
416 
417  m_numLos = 0;
418  m_numNlos = 0;
419  for (uint32_t j = 0; j < numberOfReps; j++)
420  {
421  Simulator::Schedule (MilliSeconds (10 * j), &V2vHighwayProbChCondModelTestCase::EvaluateChannelCondition, this, a, b);
422  }
423 
424  Simulator::Run ();
425  Simulator::Destroy ();
426 
427  double resultPlos = double (m_numLos) / double (numberOfReps);
428  double resultPnlos = double (m_numNlos) / double (numberOfReps);
429  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);
430  NS_TEST_EXPECT_MSG_EQ_TOL (resultPlos, testVector.m_pLos, m_tolerance, "Got unexpected LOS probability");
431  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);
432  NS_TEST_EXPECT_MSG_EQ_TOL (resultPnlos, testVector.m_pNlos, m_tolerance, "Got unexpected NLOS probability");
433  }
434 }
435 
449 {
450 public:
452 };
453 
455  : TestSuite ("probabilistic-v2v-channel-condition-model", SYSTEM)
456 {
457  AddTestCase (new V2vUrbanProbChCondModelTestCase, TestCase::QUICK); // test for a fully probabilistic model (NLOS vs LOS vs NLOSv), in V2V urban scenario
458  AddTestCase (new V2vHighwayProbChCondModelTestCase, TestCase::QUICK); // test for a fully probabilistic model (NLOS vs LOS vs NLOSv), in V2V highway scenario*/
459 }
460 
#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:185
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:1154
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:1344
A simple way to store test vectors (for stimulus or from responses)
Definition: test.h:1407
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:1353
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:563
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1297
nodes
Definition: first.py:32
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static ProbabilisticV2vChCondModelsTestSuite probabilisticV2vChCondModelsTestSuite
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