A Discrete-Event Network Simulator
API
channel-condition-model-test-suite.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2019 SIGNET Lab, Department of Information Engineering,
3 * University of Padova
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/channel-condition-model.h"
21#include "ns3/config.h"
22#include "ns3/constant-position-mobility-model.h"
23#include "ns3/double.h"
24#include "ns3/log.h"
25#include "ns3/node-container.h"
26#include "ns3/simulator.h"
27#include "ns3/test.h"
28
29using namespace ns3;
30
31NS_LOG_COMPONENT_DEFINE("ChannelConditionModelsTest");
32
42{
43 public:
48
53
54 private:
58 void DoRun() override;
59
68
72 typedef struct
73 {
74 Vector m_positionA;
75 Vector m_positionB;
76 double m_pLos;
78 } TestVector;
79
82 uint64_t m_numLos;
83 double m_tolerance;
84};
85
87 : TestCase("Test case for the child classes of ThreeGppChannelConditionModel"),
88 m_testVectors(),
89 m_tolerance(2e-3)
90{
91}
92
94{
95}
96
97void
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 =
149 (18.0 / 50.0 + exp(-50.0 / 63.0) * (1.0 - 18.0 / 50.0)) *
150 (1.0 + pow(2.0 / 10.0, 1.5) * 5.0 / 4.0 * pow(50.0 / 100.0, 3) * exp(-50.0 / 150.0));
151 testVector.m_typeId = ThreeGppUmaChannelConditionModel::GetTypeId();
152 m_testVectors.Add(testVector);
153
154 testVector.m_positionA = Vector(0, 0, 25.0);
155 testVector.m_positionB = Vector(100, 0, 1.5);
156 testVector.m_pLos = (18.0 / 100.0 + exp(-100.0 / 63.0) * (1.0 - 18.0 / 100.0)) * (1.0 + 0);
157 testVector.m_typeId = ThreeGppUmaChannelConditionModel::GetTypeId();
158 m_testVectors.Add(testVector);
159
160 testVector.m_positionA = Vector(0, 0, 25.0);
161 testVector.m_positionB = Vector(100, 0, 15);
162 testVector.m_pLos = (18.0 / 100.0 + exp(-100.0 / 63.0) * (1.0 - 18.0 / 100.0)) *
163 (1.0 + pow(2.0 / 10.0, 1.5) * 5.0 / 4.0 * 1.0 * exp(-100.0 / 150.0));
164 testVector.m_typeId = ThreeGppUmaChannelConditionModel::GetTypeId();
165 m_testVectors.Add(testVector);
166
167 // tests for the UMi-Street Canyon scenario
168 testVector.m_positionA = Vector(0, 0, 10.0);
169 testVector.m_positionB = Vector(18, 0, 1.5);
170 testVector.m_pLos = 1;
171 testVector.m_typeId = ThreeGppUmiStreetCanyonChannelConditionModel::GetTypeId();
172 m_testVectors.Add(testVector);
173
174 testVector.m_positionA = Vector(0, 0, 10.0);
175 testVector.m_positionB = Vector(50, 0, 1.5);
176 testVector.m_pLos = (18.0 / 50.0 + exp(-50.0 / 36.0) * (1.0 - 18.0 / 50.0));
177 testVector.m_typeId = ThreeGppUmiStreetCanyonChannelConditionModel::GetTypeId();
178 m_testVectors.Add(testVector);
179
180 m_testVectors.Add(testVector);
181 testVector.m_positionA = Vector(0, 0, 10.0);
182 testVector.m_positionB = Vector(100, 0, 15);
183 testVector.m_pLos = (18.0 / 100.0 + exp(-100.0 / 36.0) * (1.0 - 18.0 / 100.0));
184 testVector.m_typeId = ThreeGppUmiStreetCanyonChannelConditionModel::GetTypeId();
185 m_testVectors.Add(testVector);
186
187 // tests for the Indoor Mixed Office scenario
188 testVector.m_positionA = Vector(0, 0, 2.0);
189 testVector.m_positionB = Vector(1.2, 0, 1.5);
190 testVector.m_pLos = 1;
191 testVector.m_typeId = ThreeGppIndoorMixedOfficeChannelConditionModel::GetTypeId();
192 m_testVectors.Add(testVector);
193
194 testVector.m_positionA = Vector(0, 0, 2.0);
195 testVector.m_positionB = Vector(5, 0, 1.5);
196 testVector.m_pLos = exp(-(5.0 - 1.2) / 4.7);
197 testVector.m_typeId = ThreeGppIndoorMixedOfficeChannelConditionModel::GetTypeId();
198 m_testVectors.Add(testVector);
199
200 testVector.m_positionA = Vector(0, 0, 2.0);
201 testVector.m_positionB = Vector(10, 0, 1.5);
202 testVector.m_pLos = exp(-(10.0 - 6.5) / 32.6) * 0.32;
203 testVector.m_typeId = ThreeGppIndoorMixedOfficeChannelConditionModel::GetTypeId();
204 m_testVectors.Add(testVector);
205
206 // tests for the Indoor Open Office scenario
207 testVector.m_positionA = Vector(0, 0, 3.0);
208 testVector.m_positionB = Vector(5, 0, 1.5);
209 testVector.m_pLos = 1;
210 testVector.m_typeId = ThreeGppIndoorOpenOfficeChannelConditionModel::GetTypeId();
211 m_testVectors.Add(testVector);
212
213 testVector.m_positionA = Vector(0, 0, 3.0);
214 testVector.m_positionB = Vector(30, 0, 1.5);
215 testVector.m_pLos = exp(-(30.0 - 5.0) / 70.8);
216 testVector.m_typeId = ThreeGppIndoorOpenOfficeChannelConditionModel::GetTypeId();
217 m_testVectors.Add(testVector);
218
219 testVector.m_positionA = Vector(0, 0, 3.0);
220 testVector.m_positionB = Vector(100, 0, 1.5);
221 testVector.m_pLos = exp(-(100.0 - 49.0) / 211.7) * 0.54;
222 testVector.m_typeId = ThreeGppIndoorOpenOfficeChannelConditionModel::GetTypeId();
223 m_testVectors.Add(testVector);
224
225 // create the factory for the channel condition models
226 ObjectFactory condModelFactory;
227
228 // create the two nodes
230 nodes.Create(2);
231
232 // create the mobility models
233 Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
234 Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel>();
235
236 // aggregate the nodes and the mobility models
239
240 // Get the channel condition multiple times and compute the LOS probability
241 uint32_t numberOfReps = 500000;
242 for (uint32_t i = 0; i < m_testVectors.GetN(); ++i)
243 {
244 testVector = m_testVectors.Get(i);
245
246 // set the distance between the two nodes
247 a->SetPosition(testVector.m_positionA);
248 b->SetPosition(testVector.m_positionB);
249
250 // create the channel condition model
251 condModelFactory.SetTypeId(testVector.m_typeId);
253 m_condModel->SetAttribute("UpdatePeriod", TimeValue(MilliSeconds(9)));
254
255 m_numLos = 0;
256 for (uint32_t j = 0; j < numberOfReps; j++)
257 {
258 Simulator::Schedule(MilliSeconds(10 * j),
260 this,
261 a,
262 b);
263 }
264
265 Simulator::Run();
266 Simulator::Destroy();
267
268 double resultPlos = double(m_numLos) / double(numberOfReps);
269 NS_LOG_DEBUG(testVector.m_typeId << " a pos " << testVector.m_positionA << " b pos "
270 << testVector.m_positionB << " numLos " << m_numLos
271 << " numberOfReps " << numberOfReps << " resultPlos "
272 << resultPlos << " ref " << testVector.m_pLos);
273 NS_TEST_EXPECT_MSG_EQ_TOL(resultPlos,
274 testVector.m_pLos,
276 "Got unexpected LOS probability");
277 }
278}
279
286{
287 public:
289};
290
292 : TestSuite("propagation-channel-condition-model", UNIT)
293{
295}
296
static ChannelConditionModelsTestSuite g_channelConditionModelsTestSuite
Static variable for test initialization.
Test suite for the channel condition models.
Test case for the 3GPP channel condition models.
void DoRun() override
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:258
Instantiate subclasses of ns3::Object.
Ptr< Object > Create() 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:259
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:305
A suite of tests to run.
Definition: test.h:1256
A simple way to store test vectors (for stimulus or from responses)
Definition: test.h:1319
Base class for the 3GPP channel condition models.
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:1425
a unique identifier for an interface.
Definition: type-id.h:60
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#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:510
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1350
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