A Discrete-Event Network Simulator
API
three-gpp-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  * Copyright (c) 2020 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */
19 
20 #include "ns3/abort.h"
21 #include "ns3/test.h"
22 #include "ns3/config.h"
23 #include "ns3/buildings-channel-condition-model.h"
24 #include "ns3/channel-condition-model.h"
25 #include "ns3/three-gpp-v2v-channel-condition-model.h"
26 #include "ns3/three-gpp-v2v-propagation-loss-model.h"
27 #include "ns3/constant-position-mobility-model.h"
28 #include "ns3/buildings-module.h"
29 #include "ns3/log.h"
30 #include "ns3/simulator.h"
31 #include "ns3/double.h"
32 #include "ns3/uinteger.h"
33 #include "ns3/boolean.h"
34 #include "ns3/core-module.h"
35 
36 using namespace ns3;
37 
38 NS_LOG_COMPONENT_DEFINE ("ThreeGppV2vChannelConditionModelsTest");
39 
48 {
49 public:
54 
59 
60 private:
64  virtual void DoRun (void);
65 
69  typedef struct
70  {
71  Vector m_positionA;
72  Vector m_positionB;
75  } TestVector;
76 
78 };
79 
81  : TestCase ("Test case for the ThreeGppV2vUrban and ThreeGppV2vHighway ChannelConditionModel with building"), m_testVectors ()
82 {}
83 
85 {}
86 
87 void
89 {
90  RngSeedManager::SetSeed (1);
91  RngSeedManager::SetRun (1);
92 
93  TestVector testVector;
94  //Add vectors for ThreeGppV2vUrbanChannelConditionModel
95  testVector.m_positionA = Vector (-5.0, 5.0, 1.5);
96  testVector.m_positionB = Vector (20.0, 5.0, 1.5);
97  testVector.m_losCond = ChannelCondition::LosConditionValue::NLOS;
98  testVector.m_typeId = ThreeGppV2vUrbanChannelConditionModel::GetTypeId ();
99  m_testVectors.Add (testVector);
100 
101  testVector.m_positionA = Vector (0.0, 11.0, 1.5);
102  testVector.m_positionB = Vector (4.0, 11.0, 1.5);
103  testVector.m_losCond = ChannelCondition::LosConditionValue::LOS;
104  testVector.m_typeId = ThreeGppV2vUrbanChannelConditionModel::GetTypeId ();
105  m_testVectors.Add (testVector);
106 
107  testVector.m_positionA = Vector (0.0, 11.0, 1.5);
108  testVector.m_positionB = Vector (1000.0, 11.0, 1.5);
109  testVector.m_losCond = ChannelCondition::LosConditionValue::NLOSv;
110  testVector.m_typeId = ThreeGppV2vUrbanChannelConditionModel::GetTypeId ();
111  m_testVectors.Add (testVector);
112 
113  //Now add same vectors for ThreeGppV2vHighwayChannelConditionModel
114  testVector.m_positionA = Vector (-5.0, 5.0, 1.5);
115  testVector.m_positionB = Vector (20.0, 5.0, 1.5);
116  testVector.m_losCond = ChannelCondition::LosConditionValue::NLOS;
117  testVector.m_typeId = ThreeGppV2vHighwayChannelConditionModel::GetTypeId ();
118  m_testVectors.Add (testVector);
119 
120  testVector.m_positionA = Vector (0.0, 11.0, 1.5);
121  testVector.m_positionB = Vector (4.0, 11.0, 1.5);
122  testVector.m_losCond = ChannelCondition::LosConditionValue::LOS;
123  testVector.m_typeId = ThreeGppV2vHighwayChannelConditionModel::GetTypeId ();
124  m_testVectors.Add (testVector);
125 
126  testVector.m_positionA = Vector (0.0, 11.0, 1.5);
127  testVector.m_positionB = Vector (1000.0, 11.0, 1.5);
128  testVector.m_losCond = ChannelCondition::LosConditionValue::NLOSv;
129  testVector.m_typeId = ThreeGppV2vHighwayChannelConditionModel::GetTypeId ();
130  m_testVectors.Add (testVector);
131 
132  // create the factory for the channel condition models
133  ObjectFactory condModelFactory;
134 
135  // Deploy nodes and building and get the channel condition
137  nodes.Create (2);
138 
139  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
140  nodes.Get (0)->AggregateObject (a);
141 
142  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
143  nodes.Get (1)->AggregateObject (b);
144 
145  Ptr<Building> building = Create<Building> ();
146  building->SetNRoomsX (1);
147  building->SetNRoomsY (1);
148  building->SetNFloors (1);
149  building->SetBoundaries (Box (0.0, 10.0, 0.0, 10.0, 0.0, 5.0));
150 
151  BuildingsHelper::Install (nodes);
152 
153  for (uint32_t i = 0; i < m_testVectors.GetN (); ++i)
154  {
155  testVector = m_testVectors.Get (i);
156  condModelFactory.SetTypeId (testVector.m_typeId);
157  Ptr<ChannelConditionModel> condModel = DynamicCast<ChannelConditionModel> (condModelFactory.Create ());
158  condModel->AssignStreams (1);
159 
160  a->SetPosition (testVector.m_positionA);
161  b->SetPosition (testVector.m_positionB);
163  buildingInfoA->MakeConsistent (a);
165  buildingInfoB->MakeConsistent (b);
167  cond = condModel->GetChannelCondition (a, b);
168 
169  NS_LOG_DEBUG ("Got " << cond->GetLosCondition () << " expected condition " << testVector.m_losCond);
170  NS_TEST_ASSERT_MSG_EQ (cond->GetLosCondition (), testVector.m_losCond, "Got unexpected channel condition");
171  }
172 
173  Simulator::Destroy ();
174 }
175 
184 {
185 public:
190 
195 
196 private:
200  virtual void DoRun (void);
201 
210 
214  typedef struct
215  {
216  Vector m_positionA;
217  Vector m_positionB;
218  double m_pLos;
220  } TestVector;
221 
224  uint64_t m_numLos {0};
225  double m_tolerance;
226 };
227 
229  : TestCase ("Test case for the class ThreeGppV2vUrbanChannelConditionModel"),
230  m_testVectors (),
231  m_tolerance (2e-3)
232 {}
233 
235 {}
236 
237 void
239 {
241  if (cond->GetLosCondition () == ChannelCondition::LosConditionValue::LOS)
242  {
243  m_numLos++;
244  }
245 }
246 
247 void
249 {
250  RngSeedManager::SetSeed (1);
251  RngSeedManager::SetRun (1);
252 
253  // create the test vector
254  TestVector testVector;
255 
256  // tests for the V2v Urban scenario
257  testVector.m_positionA = Vector (0, 0, 1.6);
258  testVector.m_positionB = Vector (10, 0, 1.6);
259  testVector.m_pLos = std::min (1.0, 1.05 * exp (-0.0114 * 10.0));
260  testVector.m_typeId = ThreeGppV2vUrbanChannelConditionModel::GetTypeId ();
261  m_testVectors.Add (testVector);
262 
263  testVector.m_positionA = Vector (0, 0, 1.6);
264  testVector.m_positionB = Vector (100, 0, 1.6);
265  testVector.m_pLos = std::min (1.0, 1.05 * exp (-0.0114 * 100.0));
266  testVector.m_typeId = ThreeGppV2vUrbanChannelConditionModel::GetTypeId ();
267  m_testVectors.Add (testVector);
268 
269  testVector.m_positionA = Vector (0, 0, 1.6);
270  testVector.m_positionB = Vector (1000, 0, 1.6);
271  testVector.m_pLos = std::min (1.0, 1.05 * exp (-0.0114 * 1000.0));
272  testVector.m_typeId = ThreeGppV2vUrbanChannelConditionModel::GetTypeId ();
273  m_testVectors.Add (testVector);
274 
275  // create the factory for the channel condition models
276  ObjectFactory condModelFactory;
277 
278  // create the two nodes
280  nodes.Create (2);
281 
282  // create the mobility models
283  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
284  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
285 
286  // aggregate the nodes and the mobility models
287  nodes.Get (0)->AggregateObject (a);
288  nodes.Get (1)->AggregateObject (b);
289 
290  BuildingsHelper::Install (nodes);
291 
292  // Get the channel condition multiple times and compute the LOS probability
293  uint32_t numberOfReps = 500000;
294  for (uint32_t i = 0; i < m_testVectors.GetN (); ++i)
295  {
296  testVector = m_testVectors.Get (i);
297 
298  // set the distance between the two nodes
299  a->SetPosition (testVector.m_positionA);
300  b->SetPosition (testVector.m_positionB);
302  buildingInfoA->MakeConsistent (a);
303  Ptr<MobilityBuildingInfo> buildingInfoB = b->GetObject<MobilityBuildingInfo> ();
304  buildingInfoB->MakeConsistent (b);
305 
306  // create the channel condition model
307  condModelFactory.SetTypeId (testVector.m_typeId);
309  m_condModel->SetAttribute ("UpdatePeriod", TimeValue (MilliSeconds (9)));
311 
312  m_numLos = 0;
313  for (uint32_t j = 0; j < numberOfReps; j++)
314  {
315  Simulator::Schedule (MilliSeconds (10 * j), &ThreeGppV2vUrbanLosNlosvChCondModelTestCase::EvaluateChannelCondition, this, a, b);
316  }
317 
318  Simulator::Run ();
319  Simulator::Destroy ();
320 
321  double resultPlos = double (m_numLos) / double (numberOfReps);
322  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);
323  NS_TEST_EXPECT_MSG_EQ_TOL (resultPlos, testVector.m_pLos, m_tolerance, "Got unexpected LOS probability");
324  }
325 }
326 
335 {
336 public:
341 
346 
347 private:
351  virtual void DoRun (void);
352 
361 
365  typedef struct
366  {
367  Vector m_positionA;
368  Vector m_positionB;
369  double m_pLos;
371  } TestVector;
372 
375  uint64_t m_numLos {0};
376  double m_tolerance;
377 };
378 
380  : TestCase ("Test case for the class ThreeGppV2vHighwayChannelConditionModel"),
381  m_testVectors (),
382  m_tolerance (2e-3)
383 {}
384 
386 {}
387 
388 void
390 {
392  if (cond->GetLosCondition () == ChannelCondition::LosConditionValue::LOS)
393  {
394  m_numLos++;
395  }
396 }
397 
398 void
400 {
401  RngSeedManager::SetSeed (1);
402  RngSeedManager::SetRun (1);
403 
404  // create the test vector
405  TestVector testVector;
406 
407  // tests for the V2v Highway scenario
408  testVector.m_positionA = Vector (0, 0, 1.6);
409  testVector.m_positionB = Vector (10, 0, 1.6);
410  testVector.m_pLos = std::min (1.0, 0.0000021013 * 10.0 * 10.0 - 0.002 * 10.0 + 1.0193);
411  testVector.m_typeId = ThreeGppV2vHighwayChannelConditionModel::GetTypeId ();
412  m_testVectors.Add (testVector);
413 
414  testVector.m_positionA = Vector (0, 0, 1.6);
415  testVector.m_positionB = Vector (100, 0, 1.6);
416  testVector.m_pLos = std::min (1.0, 0.0000021013 * 100.0 * 100.0 - 0.002 * 100.0 + 1.0193);
417  testVector.m_typeId = ThreeGppV2vHighwayChannelConditionModel::GetTypeId ();
418  m_testVectors.Add (testVector);
419 
420  testVector.m_positionA = Vector (0, 0, 1.6);
421  testVector.m_positionB = Vector (1000, 0, 1.6);
422  testVector.m_pLos = std::max (0.0, 0.54 - 0.001 * (1000.0 - 475));
423  testVector.m_typeId = ThreeGppV2vHighwayChannelConditionModel::GetTypeId ();
424  m_testVectors.Add (testVector);
425 
426  // create the factory for the channel condition models
427  ObjectFactory condModelFactory;
428 
429  // create the two nodes
431  nodes.Create (2);
432 
433  // create the mobility models
434  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
435  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
436 
437  // aggregate the nodes and the mobility models
438  nodes.Get (0)->AggregateObject (a);
439  nodes.Get (1)->AggregateObject (b);
440 
441  BuildingsHelper::Install (nodes);
442 
443  // Get the channel condition multiple times and compute the LOS probability
444  uint32_t numberOfReps = 500000;
445  for (uint32_t i = 0; i < m_testVectors.GetN (); ++i)
446  {
447  testVector = m_testVectors.Get (i);
448 
449  // set the distance between the two nodes
450  a->SetPosition (testVector.m_positionA);
451  b->SetPosition (testVector.m_positionB);
452 
453  // create the channel condition model
454  condModelFactory.SetTypeId (testVector.m_typeId);
456  m_condModel->SetAttribute ("UpdatePeriod", TimeValue (MilliSeconds (9)));
458 
459  m_numLos = 0;
460  for (uint32_t j = 0; j < numberOfReps; j++)
461  {
463  }
464 
465  Simulator::Run ();
466  Simulator::Destroy ();
467 
468  double resultPlos = static_cast<double> (m_numLos) / static_cast<double> (numberOfReps);
469  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);
470  NS_TEST_EXPECT_MSG_EQ_TOL (resultPlos, testVector.m_pLos, m_tolerance, "Got unexpected LOS probability");
471  }
472 }
473 
474 
496 {
497 public:
499 };
500 
502  : TestSuite ("three-gpp-v2v-channel-condition-model", SYSTEM)
503 {
504  AddTestCase (new ThreeGppV2vBuildingsChCondModelTestCase, TestCase::QUICK); // test for the deterministic procedure (NLOS vs LOS/NLOSv), based on buildings
505  AddTestCase (new ThreeGppV2vUrbanLosNlosvChCondModelTestCase, TestCase::QUICK); // test for the probabilistic procedure (LOS vs NLOSv), in V2V urban scenario
506  AddTestCase (new ThreeGppV2vHighwayLosNlosvChCondModelTestCase, TestCase::QUICK); // test for the probabilistic procedure (LOS vs NLOSv), in V2V highway scenario
507 }
508 
Ptr< ThreeGppV2vHighwayChannelConditionModel > m_condModel
the channel condition model
static ThreeGppV2vChCondModelsTestSuite ThreeGppV2vChCondModelsTestSuite
void SetNRoomsY(uint16_t nroomy)
Definition: building.cc:174
virtual void DoRun(void)
Builds the simulation scenario and perform the tests.
TypeId m_typeId
the type ID of the channel condition model to be used
#define min(a, b)
Definition: 80211b.c:42
A suite of tests to run.
Definition: test.h:1343
ChannelCondition::LosConditionValue m_losCond
the correct channel condition
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1297
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
encapsulates test code
Definition: test.h:1153
LosConditionValue GetLosCondition() const
Get the LosConditionValue contaning the information about the LOS/NLOS state of the channel...
TypeId m_typeId
the type ID of the channel condition model to be used
a 3d box
Definition: box.h:34
A simple way to store test vectors (for stimulus or from responses)
Definition: test.h:1406
void EvaluateChannelCondition(Ptr< MobilityModel > a, Ptr< MobilityModel > b)
Evaluates the channel condition between two nodes by calling the method GetChannelCondition on m_cond...
nodes
Definition: first.py:32
#define max(a, b)
Definition: 80211b.c:43
AttributeValue implementation for Time.
Definition: nstime.h:1353
Ptr< Object > Create(void) const
Create an Object instance of the configured TypeId.
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
Test case for the 3GPP V2V Highway channel condition models (probabilistic model for LOS/NLOSv states...
void SetNFloors(uint16_t nfloors)
Definition: building.cc:160
virtual int64_t AssignStreams(int64_t stream)=0
If this model uses objects of type RandomVariableStream, set the stream numbers to the integers start...
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:166
Test case for the 3GPP V2V Urban channel condition models (probabilistic model for LOS/NLOSv states)...
#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
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
TypeId m_typeId
the type ID of the channel condition model to be used
virtual Ptr< ChannelCondition > GetChannelCondition(Ptr< const MobilityModel > a, Ptr< const MobilityModel > b) const =0
Computes the condition of the channel between a and b.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
keep track of a set of node pointers.
Computes the channel condition for the V2V Highway scenario.
virtual Ptr< ChannelCondition > GetChannelCondition(Ptr< const MobilityModel > a, Ptr< const MobilityModel > b) const override
Retrieve the condition of the channel between a and b.
TestVectors< TestVector > m_testVectors
array containing all the test vectors
void SetPosition(const Vector &position)
void EvaluateChannelCondition(Ptr< MobilityModel > a, Ptr< MobilityModel > b)
Evaluates the channel condition between two nodes by calling the method GetChannelCondition on m_cond...
TestVectors< TestVector > m_testVectors
array containg all the test vectors
Ptr< ThreeGppV2vUrbanChannelConditionModel > m_condModel
the channel condition model
Instantiate subclasses of ns3::Object.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
mobility buildings information (to be used by mobility models)
TestVectors< TestVector > m_testVectors
array containing all the test vectors
virtual void DoRun(void)
Builds the simulation scenario and perform the tests.
void SetNRoomsX(uint16_t nroomx)
Definition: building.cc:167
virtual void DoRun(void)
Builds the simulation scenario and perform the tests.
void MakeConsistent(Ptr< MobilityModel > mm)
Make the given mobility model consistent, by determining whether its position falls inside any of the...
LosConditionValue
Possible values for Line-of-Sight condition.
Test suite for the 3GPP V2V channel condition model.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185
a unique identifier for an interface.
Definition: type-id.h:58
void SetBoundaries(Box box)
Set the boundaries of the building.
Definition: building.cc:139
virtual int64_t AssignStreams(int64_t stream) override
If this model uses objects of type RandomVariableStream, set the stream numbers to the integers start...
Computes the channel condition for the V2V Urban scenario.
Test case for the classes ThreeGppV2vUrbanChannelConditionModel, and ThreeGppV2vHighwayChannelConditi...