A Discrete-Event Network Simulator
API
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 
34 using namespace ns3;
35 
36 NS_LOG_COMPONENT_DEFINE("BuildingsPenetrationLossesTest");
37 
56 {
57  public:
62 
67 
68  private:
72  void DoRun() override;
73 
77  struct TestVector
78  {
79  Vector m_positionA;
80  Vector m_positionB;
81  double m_frequency;
82  bool m_isLos;
85  double m_pt;
86  double m_pr;
87  };
88 
91  double m_tolerance;
92 };
93 
95  : TestCase("Test case for BuildingsPenetrationLosses"),
96  m_testVectors(),
97  m_tolerance(2e-3)
98 {
99 }
100 
102 {
103 }
104 
105 void
107 {
108  // create the test vector
109  TestVector testVector;
110 
111  // tests for the RMa scenario
112  testVector.m_positionA = Vector(0, 0, 35.0); // O2I case
113  testVector.m_positionB = Vector(10, 0, 1.5);
114  testVector.m_frequency = 5.0e9;
115  testVector.m_propModel = ThreeGppRmaPropagationLossModel::GetTypeId();
116  testVector.m_pt = 0.0;
117  testVector.m_pr = -77.3784;
118  m_testVectors.Add(testVector);
119 
120  testVector.m_positionA = Vector(0, 0, 35.0); // O2I case
121  testVector.m_positionB = Vector(100, 0, 1.5);
122  testVector.m_frequency = 5.0e9;
123  testVector.m_propModel = ThreeGppRmaPropagationLossModel::GetTypeId();
124  testVector.m_pt = 0.0;
125  testVector.m_pr = -87.2965;
126  m_testVectors.Add(testVector);
127 
128  testVector.m_positionA = Vector(0, 0, 35.0); // O2O case
129  testVector.m_positionB = Vector(1000, 0, 1.5);
130  testVector.m_frequency = 5.0e9;
131  testVector.m_propModel = ThreeGppRmaPropagationLossModel::GetTypeId();
132  testVector.m_pt = 0.0;
133  testVector.m_pr = -108.5577;
134  m_testVectors.Add(testVector);
135 
136  // tests for the UMa scenario
137  testVector.m_positionA = Vector(0, 0, 25.0); // O2I case
138  testVector.m_positionB = Vector(10, 0, 1.5);
139  testVector.m_frequency = 5.0e9;
140  testVector.m_propModel = ThreeGppUmaPropagationLossModel::GetTypeId();
141  testVector.m_pt = 0.0;
142  testVector.m_pr = -72.9380;
143  m_testVectors.Add(testVector);
144 
145  testVector.m_positionA = Vector(0, 0, 25.0); // O2I case
146  testVector.m_positionB = Vector(100, 0, 1.5);
147  testVector.m_frequency = 5.0e9;
148  testVector.m_propModel = ThreeGppUmaPropagationLossModel::GetTypeId();
149  testVector.m_pt = 0.0;
150  testVector.m_pr = -86.2362;
151  m_testVectors.Add(testVector);
152 
153  testVector.m_positionA = Vector(0, 0, 25.0); // O2O case
154  testVector.m_positionB = Vector(1000, 0, 1.5);
155  testVector.m_frequency = 5.0e9;
156  testVector.m_propModel = ThreeGppUmaPropagationLossModel::GetTypeId();
157  testVector.m_pt = 0.0;
158  testVector.m_pr = -109.7252;
159  m_testVectors.Add(testVector);
160 
161  // tests for the UMi scenario
162  testVector.m_positionA = Vector(0, 0, 10.0); // O2I case
163  testVector.m_positionB = Vector(10, 0, 1.5);
164  testVector.m_frequency = 5.0e9;
165  testVector.m_propModel = ThreeGppUmiStreetCanyonPropagationLossModel::GetTypeId();
166  testVector.m_pt = 0.0;
167  testVector.m_pr = -69.8591;
168  m_testVectors.Add(testVector);
169 
170  testVector.m_positionA = Vector(0, 0, 10.0); // O2I case
171  testVector.m_positionB = Vector(100, 0, 1.5);
172  testVector.m_frequency = 5.0e9;
173  testVector.m_propModel = ThreeGppUmiStreetCanyonPropagationLossModel::GetTypeId();
174  testVector.m_pt = 0.0;
175  testVector.m_pr = -88.4122;
176  m_testVectors.Add(testVector);
177 
178  testVector.m_positionA = Vector(0, 0, 10.0); // O2O case
179  testVector.m_positionB = Vector(1000, 0, 1.5);
180  testVector.m_frequency = 5.0e9;
181  testVector.m_propModel = ThreeGppUmiStreetCanyonPropagationLossModel::GetTypeId();
182  testVector.m_pt = 0.0;
183  testVector.m_pr = -119.3114;
184  m_testVectors.Add(testVector);
185 
186  // create the factory for the propagation loss model
187  ObjectFactory propModelFactory;
188 
189  Ptr<Building> building = Create<Building>();
190  building->SetExtWallsType(Building::ExtWallsType_t::ConcreteWithWindows);
191  building->SetNRoomsX(1);
192  building->SetNRoomsY(1);
193  building->SetNFloors(2);
194  building->SetBoundaries(Box(0.0, 100.0, 0.0, 10.0, 0.0, 5.0));
195 
196  // create the two nodes
198  nodes.Create(2);
199 
200  // create the mobility models
201  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel>();
202  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel>();
203 
204  // aggregate the nodes and the mobility models
205  nodes.Get(0)->AggregateObject(a);
206  nodes.Get(1)->AggregateObject(b);
207 
208  Ptr<MobilityBuildingInfo> buildingInfoA = CreateObject<MobilityBuildingInfo>();
209  Ptr<MobilityBuildingInfo> buildingInfoB = CreateObject<MobilityBuildingInfo>();
210  a->AggregateObject(buildingInfoA); // operation usually done by BuildingsHelper::Install
211  buildingInfoA->MakeConsistent(a);
212 
213  b->AggregateObject(buildingInfoB); // operation usually done by BuildingsHelper::Install
214  buildingInfoB->MakeConsistent(b);
215 
216  Ptr<ChannelConditionModel> condModel = CreateObject<BuildingsChannelConditionModel>();
217 
218  for (std::size_t i = 0; i < m_testVectors.GetN(); i++)
219  {
220  TestVector testVector = m_testVectors.Get(i);
221  a->SetPosition(testVector.m_positionA);
222  b->SetPosition(testVector.m_positionB);
223 
224  Ptr<ChannelCondition> cond = condModel->GetChannelCondition(a, b);
225 
226  propModelFactory.SetTypeId(testVector.m_propModel);
227  m_propModel = propModelFactory.Create<ThreeGppPropagationLossModel>();
228  m_propModel->SetAttribute("Frequency", DoubleValue(testVector.m_frequency));
229  m_propModel->SetAttribute("ShadowingEnabled", BooleanValue(false));
231 
232  bool isAIndoor = buildingInfoA->IsIndoor();
233  bool isBIndoor = buildingInfoB->IsIndoor();
234 
235  if (!isAIndoor && !isBIndoor) // a and b are outdoor
236  {
237  cond->SetLosCondition(ChannelCondition::LosConditionValue::LOS);
238  cond->SetO2iCondition(ChannelCondition::O2iConditionValue::O2O);
239 
240  // check rcv power to be equal to the calculated value without losses
242  testVector.m_pr,
243  m_tolerance,
244  "rcv power is not equal expected value");
245  }
246  else
247  {
248  cond->SetLosCondition(ChannelCondition::LosConditionValue::LOS);
249  cond->SetO2iCondition(ChannelCondition::O2iConditionValue::O2I);
250  cond->SetO2iLowHighCondition(ChannelCondition::O2iLowHighConditionValue::LOW);
251 
252  // check rcv power to be lower than the calculated without losses
254  testVector.m_pr,
255  "rcv power is not less than calculated value");
256  }
257  m_propModel = nullptr;
258  }
259  Simulator::Destroy();
260 }
261 
268 {
269  public:
271 };
272 
274  : TestSuite("buildings-penetration-losses", UNIT)
275 {
276  AddTestCase(new BuildingsPenetrationLossesTestCase, TestCase::QUICK);
277 }
278 
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.
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
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:204
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
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.
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:301
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 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:790
#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
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