A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
buildings-penetration-loss-pathloss-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2023 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
17
18#include "ns3/abort.h"
19#include "ns3/boolean.h"
20#include "ns3/building.h"
21#include "ns3/buildings-channel-condition-model.h"
22#include "ns3/channel-condition-model.h"
23#include "ns3/config.h"
24#include "ns3/constant-position-mobility-model.h"
25#include "ns3/constant-velocity-mobility-model.h"
26#include "ns3/double.h"
27#include "ns3/log.h"
28#include "ns3/mobility-building-info.h"
29#include "ns3/mobility-helper.h"
30#include "ns3/simulator.h"
31#include "ns3/test.h"
32#include "ns3/three-gpp-propagation-loss-model.h"
33
34using namespace ns3;
35
36NS_LOG_COMPONENT_DEFINE("BuildingsPenetrationLossesTest");
37
38/**
39 * \ingroup propagation-tests
40 *
41 * Test case for the 3GPP channel O2I building penetration losses.
42 * It considers pre-determined scenarios and based on the outdoor/indoor
43 * condition (O2O/O2I) checks whether the calculated received power
44 * is aligned with the calculation in 3GPP TR 38.901.
45 *
46 * For O2O condition the calculation is done according to Table 7.4.1-1
47 * and we check if the calculated received power is equal to the expected
48 * value.
49 * For the O2I condition, the calculation is done considering the building
50 * penetration losses based on the material of the building walls.
51 * In this case, we check if the calculated received power is less than the
52 * received value (thus ensure that losses have been included).
53 */
54
56{
57 public:
58 /**
59 * Constructor
60 */
62
63 /**
64 * Destructor
65 */
67
68 private:
69 /**
70 * Builds the simulation scenario and perform the tests
71 */
72 void DoRun() override;
73
74 /**
75 * Struct containing the parameters for each test
76 */
78 {
79 Vector m_positionA; //!< the position of the first node
80 Vector m_positionB; //!< the position of the second node
81 double m_frequency; //!< carrier frequency in Hz
82 TypeId m_condModel; //!< the type ID of the channel condition model to be used
83 TypeId m_propModel; //!< the type ID of the propagation loss model to be used
84 double m_pt; //!< transmitted power in dBm
85 double m_pr; //!< received power in dBm
86 };
87
88 TestVectors<TestVector> m_testVectors; //!< array containing all the test vectors
89 Ptr<ThreeGppPropagationLossModel> m_propModel; //!< the propagation loss model
90 double m_tolerance; //!< tolerance
91};
92
94 : TestCase("Test case for BuildingsPenetrationLosses"),
95 m_testVectors(),
96 m_tolerance(2e-3)
97{
98}
99
101{
102}
103
104void
106{
107 // create the test vector
108 TestVector testVector;
109
110 // tests for the RMa scenario
111 testVector.m_positionA = Vector(0, 0, 35.0); // O2I case
112 testVector.m_positionB = Vector(10, 0, 1.5);
113 testVector.m_frequency = 5.0e9;
115 testVector.m_pt = 0.0;
116 testVector.m_pr = -77.3784;
117 m_testVectors.Add(testVector);
118
119 testVector.m_positionA = Vector(0, 0, 35.0); // O2I case
120 testVector.m_positionB = Vector(100, 0, 1.5);
121 testVector.m_frequency = 5.0e9;
123 testVector.m_pt = 0.0;
124 testVector.m_pr = -87.2965;
125 m_testVectors.Add(testVector);
126
127 testVector.m_positionA = Vector(0, 0, 35.0); // O2O case
128 testVector.m_positionB = Vector(1000, 0, 1.5);
129 testVector.m_frequency = 5.0e9;
131 testVector.m_pt = 0.0;
132 testVector.m_pr = -108.5577;
133 m_testVectors.Add(testVector);
134
135 // tests for the UMa scenario
136 testVector.m_positionA = Vector(0, 0, 25.0); // O2I case
137 testVector.m_positionB = Vector(10, 0, 1.5);
138 testVector.m_frequency = 5.0e9;
140 testVector.m_pt = 0.0;
141 testVector.m_pr = -72.9380;
142 m_testVectors.Add(testVector);
143
144 testVector.m_positionA = Vector(0, 0, 25.0); // O2I case
145 testVector.m_positionB = Vector(100, 0, 1.5);
146 testVector.m_frequency = 5.0e9;
148 testVector.m_pt = 0.0;
149 testVector.m_pr = -86.2362;
150 m_testVectors.Add(testVector);
151
152 testVector.m_positionA = Vector(0, 0, 25.0); // O2O case
153 testVector.m_positionB = Vector(1000, 0, 1.5);
154 testVector.m_frequency = 5.0e9;
156 testVector.m_pt = 0.0;
157 testVector.m_pr = -109.7252;
158 m_testVectors.Add(testVector);
159
160 // tests for the UMi scenario
161 testVector.m_positionA = Vector(0, 0, 10.0); // O2I case
162 testVector.m_positionB = Vector(10, 0, 1.5);
163 testVector.m_frequency = 5.0e9;
165 testVector.m_pt = 0.0;
166 testVector.m_pr = -69.8591;
167 m_testVectors.Add(testVector);
168
169 testVector.m_positionA = Vector(0, 0, 10.0); // O2I case
170 testVector.m_positionB = Vector(100, 0, 1.5);
171 testVector.m_frequency = 5.0e9;
173 testVector.m_pt = 0.0;
174 testVector.m_pr = -88.4122;
175 m_testVectors.Add(testVector);
176
177 testVector.m_positionA = Vector(0, 0, 10.0); // O2O case
178 testVector.m_positionB = Vector(1000, 0, 1.5);
179 testVector.m_frequency = 5.0e9;
181 testVector.m_pt = 0.0;
182 testVector.m_pr = -119.3114;
183 m_testVectors.Add(testVector);
184
185 // create the factory for the propagation loss model
186 ObjectFactory propModelFactory;
187
188 Ptr<Building> building = Create<Building>();
189 building->SetExtWallsType(Building::ExtWallsType_t::ConcreteWithWindows);
190 building->SetNRoomsX(1);
191 building->SetNRoomsY(1);
192 building->SetNFloors(2);
193 building->SetBoundaries(Box(0.0, 100.0, 0.0, 10.0, 0.0, 5.0));
194
195 // create the two nodes
197 nodes.Create(2);
198
199 // create the mobility models
200 Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
201 Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel>();
202
203 // aggregate the nodes and the mobility models
206
207 Ptr<MobilityBuildingInfo> buildingInfoA = CreateObject<MobilityBuildingInfo>();
208 Ptr<MobilityBuildingInfo> buildingInfoB = CreateObject<MobilityBuildingInfo>();
209 a->AggregateObject(buildingInfoA); // operation usually done by BuildingsHelper::Install
210 buildingInfoA->MakeConsistent(a);
211
212 b->AggregateObject(buildingInfoB); // operation usually done by BuildingsHelper::Install
213 buildingInfoB->MakeConsistent(b);
214
215 Ptr<ChannelConditionModel> condModel = CreateObject<BuildingsChannelConditionModel>();
216
217 for (std::size_t i = 0; i < m_testVectors.GetN(); i++)
218 {
219 TestVector testVector = m_testVectors.Get(i);
220 a->SetPosition(testVector.m_positionA);
221 b->SetPosition(testVector.m_positionB);
222
223 Ptr<ChannelCondition> cond = condModel->GetChannelCondition(a, b);
224
225 propModelFactory.SetTypeId(testVector.m_propModel);
226 m_propModel = propModelFactory.Create<ThreeGppPropagationLossModel>();
227 m_propModel->SetAttribute("Frequency", DoubleValue(testVector.m_frequency));
228 m_propModel->SetAttribute("ShadowingEnabled", BooleanValue(false));
230
231 bool isAIndoor = buildingInfoA->IsIndoor();
232 bool isBIndoor = buildingInfoB->IsIndoor();
233
234 if (!isAIndoor && !isBIndoor) // a and b are outdoor
235 {
236 cond->SetLosCondition(ChannelCondition::LosConditionValue::LOS);
237 cond->SetO2iCondition(ChannelCondition::O2iConditionValue::O2O);
238
239 // check rcv power to be equal to the calculated value without losses
241 testVector.m_pr,
243 "rcv power is not equal expected value");
244 }
245 else
246 {
247 cond->SetLosCondition(ChannelCondition::LosConditionValue::LOS);
248 cond->SetO2iCondition(ChannelCondition::O2iConditionValue::O2I);
249 cond->SetO2iLowHighCondition(ChannelCondition::O2iLowHighConditionValue::LOW);
250
251 // check rcv power to be lower than the calculated without losses
253 testVector.m_pr,
254 "rcv power is not less than calculated value");
255 }
256 m_propModel = nullptr;
257 }
259}
260
261/**
262 * \ingroup propagation-tests
263 *
264 * Test suite for the buildings penetration losses
265 */
267{
268 public:
270};
271
273 : TestSuite("buildings-penetration-losses", Type::UNIT)
274{
275 AddTestCase(new BuildingsPenetrationLossesTestCase, TestCase::Duration::QUICK);
276}
277
278/// Static variable for test initialization
static BuildingsPenetrationLossesTestSuite g_buildingsPenetrationLossesTestSuite
Static variable for test initialization.
Test case for the 3GPP channel O2I building penetration losses.
TestVectors< TestVector > m_testVectors
array containing all the test vectors
Ptr< ThreeGppPropagationLossModel > m_propModel
the propagation loss model
void DoRun() override
Builds the simulation scenario and perform the tests.
Test suite for the buildings penetration losses.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
a 3d box
Definition: box.h:35
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
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:211
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:309
double CalcRxPower(double txPowerDbm, Ptr< MobilityModel > a, Ptr< MobilityModel > b) const
Returns the Rx Power taking into account all the PropagationLossModel(s) chained to the current one.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
encapsulates test code
Definition: test.h:1061
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1268
Type
Type of test.
Definition: test.h:1275
A simple way to store test vectors (for stimulus or from responses)
Definition: test.h:1342
Base class for the 3GPP propagation models.
void SetChannelConditionModel(Ptr< ChannelConditionModel > model)
Set the channel condition model used to determine the channel state (e.g., the LOS/NLOS condition)
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:202
#define NS_TEST_EXPECT_MSG_LT(actual, limit, msg)
Test that an actual value is less than a limit and report if not.
Definition: test.h:791
#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:511
NodeContainer nodes
Every class exported by the ns3 library is enclosed in the ns3 namespace.
TypeId m_propModel
the type ID of the propagation loss model to be used
TypeId m_condModel
the type ID of the channel condition model to be used