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
34using namespace ns3;
35
36NS_LOG_COMPONENT_DEFINE ("ProbabilisticV2vChannelConditionModelsTest");
37
51{
52public:
57
62
63private:
67 virtual void DoRun (void);
68
77
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
107void
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
121void
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{
244public:
249
254
255private:
259 virtual void DoRun (void);
260
269
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
299void
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
313void
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{
456public:
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