A Discrete-Event Network Simulator
API
channel-condition-model-test-suite.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2019 SIGNET Lab, Department of Information Engineering,
4 * University of Padova
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/log.h"
21#include "ns3/abort.h"
22#include "ns3/test.h"
23#include "ns3/config.h"
24#include "ns3/double.h"
25#include "ns3/channel-condition-model.h"
26#include "ns3/constant-position-mobility-model.h"
27#include "ns3/simulator.h"
28#include "ns3/node-container.h"
29
30using namespace ns3;
31
32NS_LOG_COMPONENT_DEFINE ("ChannelConditionModelsTest");
33
43{
44public:
49
54
55private:
59 virtual void DoRun (void);
60
69
73 typedef struct
74 {
75 Vector m_positionA;
76 Vector m_positionB;
77 double m_pLos;
79 } TestVector;
80
83 uint64_t m_numLos;
84 double m_tolerance;
85};
86
88 : TestCase ("Test case for the child classes of ThreeGppChannelConditionModel"),
89 m_testVectors (),
90 m_tolerance (2e-3)
91{
92}
93
95{
96}
97
98void
100{
102 if (cond->GetLosCondition () == ChannelCondition::LosConditionValue::LOS)
103 {
104 m_numLos++;
105 }
106}
107
108void
110{
111 // create the test vector
112 TestVector testVector;
113
114 // tests for the RMa scenario
115 testVector.m_positionA = Vector (0, 0, 35.0);
116 testVector.m_positionB = Vector (10, 0, 1.5);
117 testVector.m_pLos = 1;
118 testVector.m_typeId = ThreeGppRmaChannelConditionModel::GetTypeId ();
119 m_testVectors.Add (testVector);
120
121 testVector.m_positionA = Vector (0, 0, 35.0);
122 testVector.m_positionB = Vector (100, 0, 1.5);
123 testVector.m_pLos = exp (-(100.0 - 10.0) / 1000.0);
124 testVector.m_typeId = ThreeGppRmaChannelConditionModel::GetTypeId ();
125 m_testVectors.Add (testVector);
126
127 testVector.m_positionA = Vector (0, 0, 35.0);
128 testVector.m_positionB = Vector (1000, 0, 1.5);
129 testVector.m_pLos = exp (-(1000.0 - 10.0) / 1000.0);
130 testVector.m_typeId = ThreeGppRmaChannelConditionModel::GetTypeId ();
131 m_testVectors.Add (testVector);
132
133 // tests for the UMa scenario
134 testVector.m_positionA = Vector (0, 0, 25.0);
135 testVector.m_positionB = Vector (18, 0, 1.5);
136 testVector.m_pLos = 1;
137 testVector.m_typeId = ThreeGppUmaChannelConditionModel::GetTypeId ();
138 m_testVectors.Add (testVector);
139
140 testVector.m_positionA = Vector (0, 0, 25.0);
141 testVector.m_positionB = Vector (50, 0, 1.5);
142 testVector.m_pLos = (18.0 / 50.0 + exp (-50.0 / 63.0) * (1.0 - 18.0 / 50.0)) * (1.0 + 0);
143 testVector.m_typeId = ThreeGppUmaChannelConditionModel::GetTypeId ();
144 m_testVectors.Add (testVector);
145
146 testVector.m_positionA = Vector (0, 0, 25.0);
147 testVector.m_positionB = Vector (50, 0, 15);
148 testVector.m_pLos = (18.0 / 50.0 + exp (-50.0 / 63.0) * (1.0 - 18.0 / 50.0)) * (1.0 + pow (2.0 / 10.0, 1.5) * 5.0 / 4.0 * pow (50.0 / 100.0, 3) * exp (-50.0 / 150.0));
149 testVector.m_typeId = ThreeGppUmaChannelConditionModel::GetTypeId ();
150 m_testVectors.Add (testVector);
151
152 testVector.m_positionA = Vector (0, 0, 25.0);
153 testVector.m_positionB = Vector (100, 0, 1.5);
154 testVector.m_pLos = (18.0 / 100.0 + exp (-100.0 / 63.0) * (1.0 - 18.0 / 100.0)) * (1.0 + 0);
155 testVector.m_typeId = ThreeGppUmaChannelConditionModel::GetTypeId ();
156 m_testVectors.Add (testVector);
157
158 testVector.m_positionA = Vector (0, 0, 25.0);
159 testVector.m_positionB = Vector (100, 0, 15);
160 testVector.m_pLos = (18.0 / 100.0 + exp (-100.0 / 63.0) * (1.0 - 18.0 / 100.0)) * (1.0 + pow (2.0 / 10.0, 1.5) * 5.0 / 4.0 * 1.0 * exp (-100.0 / 150.0));
161 testVector.m_typeId = ThreeGppUmaChannelConditionModel::GetTypeId ();
162 m_testVectors.Add (testVector);
163
164 // tests for the UMi-Street Canyon scenario
165 testVector.m_positionA = Vector (0, 0, 10.0);
166 testVector.m_positionB = Vector (18, 0, 1.5);
167 testVector.m_pLos = 1;
168 testVector.m_typeId = ThreeGppUmiStreetCanyonChannelConditionModel::GetTypeId ();
169 m_testVectors.Add (testVector);
170
171 testVector.m_positionA = Vector (0, 0, 10.0);
172 testVector.m_positionB = Vector (50, 0, 1.5);
173 testVector.m_pLos = (18.0 / 50.0 + exp (-50.0 / 36.0) * (1.0 - 18.0 / 50.0));
174 testVector.m_typeId = ThreeGppUmiStreetCanyonChannelConditionModel::GetTypeId ();
175 m_testVectors.Add (testVector);
176
177 m_testVectors.Add (testVector);
178 testVector.m_positionA = Vector (0, 0, 10.0);
179 testVector.m_positionB = Vector (100, 0, 15);
180 testVector.m_pLos = (18.0 / 100.0 + exp (-100.0 / 36.0) * (1.0 - 18.0 / 100.0));
181 testVector.m_typeId = ThreeGppUmiStreetCanyonChannelConditionModel::GetTypeId ();
182 m_testVectors.Add (testVector);
183
184 // tests for the Indoor Mixed Office scenario
185 testVector.m_positionA = Vector (0, 0, 2.0);
186 testVector.m_positionB = Vector (1.2, 0, 1.5);
187 testVector.m_pLos = 1;
188 testVector.m_typeId = ThreeGppIndoorMixedOfficeChannelConditionModel::GetTypeId ();
189 m_testVectors.Add (testVector);
190
191 testVector.m_positionA = Vector (0, 0, 2.0);
192 testVector.m_positionB = Vector (5, 0, 1.5);
193 testVector.m_pLos = exp (-(5.0 - 1.2) / 4.7);
194 testVector.m_typeId = ThreeGppIndoorMixedOfficeChannelConditionModel::GetTypeId ();
195 m_testVectors.Add (testVector);
196
197 testVector.m_positionA = Vector (0, 0, 2.0);
198 testVector.m_positionB = Vector (10, 0, 1.5);
199 testVector.m_pLos = exp (-(10.0 - 6.5) / 32.6) * 0.32;
200 testVector.m_typeId = ThreeGppIndoorMixedOfficeChannelConditionModel::GetTypeId ();
201 m_testVectors.Add (testVector);
202
203 // tests for the Indoor Open Office scenario
204 testVector.m_positionA = Vector (0, 0, 3.0);
205 testVector.m_positionB = Vector (5, 0, 1.5);
206 testVector.m_pLos = 1;
207 testVector.m_typeId = ThreeGppIndoorOpenOfficeChannelConditionModel::GetTypeId ();
208 m_testVectors.Add (testVector);
209
210 testVector.m_positionA = Vector (0, 0, 3.0);
211 testVector.m_positionB = Vector (30, 0, 1.5);
212 testVector.m_pLos = exp (-(30.0 - 5.0) / 70.8);
213 testVector.m_typeId = ThreeGppIndoorOpenOfficeChannelConditionModel::GetTypeId ();
214 m_testVectors.Add (testVector);
215
216 testVector.m_positionA = Vector (0, 0, 3.0);
217 testVector.m_positionB = Vector (100, 0, 1.5);
218 testVector.m_pLos = exp (-(100.0 - 49.0) / 211.7) * 0.54;
219 testVector.m_typeId = ThreeGppIndoorOpenOfficeChannelConditionModel::GetTypeId ();
220 m_testVectors.Add (testVector);
221
222 // create the factory for the channel condition models
223 ObjectFactory condModelFactory;
224
225 // create the two nodes
227 nodes.Create (2);
228
229 // create the mobility models
230 Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
231 Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
232
233 // aggregate the nodes and the mobility models
234 nodes.Get (0)->AggregateObject (a);
235 nodes.Get (1)->AggregateObject (b);
236
237 // Get the channel condition multiple times and compute the LOS probability
238 uint32_t numberOfReps = 500000;
239 for (uint32_t i = 0; i < m_testVectors.GetN (); ++i)
240 {
241 testVector = m_testVectors.Get (i);
242
243 // set the distance between the two nodes
244 a->SetPosition (testVector.m_positionA);
245 b->SetPosition (testVector.m_positionB);
246
247 // create the channel condition model
248 condModelFactory.SetTypeId (testVector.m_typeId);
249 m_condModel = condModelFactory.Create<ThreeGppChannelConditionModel> ();
250 m_condModel->SetAttribute ("UpdatePeriod", TimeValue (MilliSeconds (9)));
251
252 m_numLos = 0;
253 for (uint32_t j = 0; j < numberOfReps; j++)
254 {
255 Simulator::Schedule (MilliSeconds (10 * j), &ThreeGppChannelConditionModelTestCase::EvaluateChannelCondition, this, a, b);
256 }
257
259 Simulator::Destroy ();
260
261 double resultPlos = double (m_numLos) / double (numberOfReps);
262 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);
263 NS_TEST_EXPECT_MSG_EQ_TOL (resultPlos, testVector.m_pLos, m_tolerance, "Got unexpected LOS probability");
264 }
265}
266
273{
274public:
276};
277
279 : TestSuite ("propagation-channel-condition-model", UNIT)
280{
282}
283
void Run(ObjectFactory &factory, uint32_t pop, uint32_t total, uint32_t runs, Ptr< RandomVariableStream > eventStream, bool calRev)
Perform the runs for a single scheduler type.
static ChannelConditionModelsTestSuite g_channelConditionModelsTestSuite
Static variable for test initialization.
Test suite for the channel condition models.
Test case for the 3GPP channel condition models.
virtual void DoRun(void)
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< ThreeGppChannelConditionModel > m_condModel
the channel condition model
TestVectors< TestVector > m_testVectors
array containing all the test vectors
uint64_t m_numLos
the number of LOS occurrences
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: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.
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:252
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
Base class for the 3GPP channel condition models.
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:1309
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:206
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:274
#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:1253
NodeContainer nodes
Every class exported by the ns3 library is enclosed in the ns3 namespace.
TypeId m_typeId
the type ID of the channel condition model to be used