A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
complete-network-example.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017 University of Padova
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Davide Magrin <magrinda@dei.unipd.it>
7 */
8
9/*
10 * This script simulates a complex scenario with multiple gateways and end
11 * devices. The metric of interest for this script is the throughput of the
12 * network.
13 */
14
15#include "ns3/building-allocator.h"
16#include "ns3/building-penetration-loss.h"
17#include "ns3/buildings-helper.h"
18#include "ns3/class-a-end-device-lorawan-mac.h"
19#include "ns3/command-line.h"
20#include "ns3/constant-position-mobility-model.h"
21#include "ns3/correlated-shadowing-propagation-loss-model.h"
22#include "ns3/double.h"
23#include "ns3/end-device-lora-phy.h"
24#include "ns3/forwarder-helper.h"
25#include "ns3/gateway-lora-phy.h"
26#include "ns3/gateway-lorawan-mac.h"
27#include "ns3/log.h"
28#include "ns3/lora-helper.h"
29#include "ns3/mobility-helper.h"
30#include "ns3/network-server-helper.h"
31#include "ns3/node-container.h"
32#include "ns3/periodic-sender-helper.h"
33#include "ns3/pointer.h"
34#include "ns3/position-allocator.h"
35#include "ns3/random-variable-stream.h"
36#include "ns3/simulator.h"
37
38#include <algorithm>
39#include <ctime>
40
41using namespace ns3;
42using namespace lorawan;
43
44NS_LOG_COMPONENT_DEFINE("ComplexLorawanNetworkExample");
45
46// Network settings
47int nDevices = 200; //!< Number of end device nodes to create
48int nGateways = 1; //!< Number of gateway nodes to create
49double radiusMeters = 6400; //!< Radius (m) of the deployment
50double simulationTimeSeconds = 600; //!< Scenario duration (s) in simulated time
51
52// Channel model
53bool realisticChannelModel = false; //!< Whether to use a more realistic channel model with
54 //!< Buildings and correlated shadowing
55
56int appPeriodSeconds = 600; //!< Duration (s) of the inter-transmission time of end devices
57
58// Output control
59bool printBuildingInfo = true; //!< Whether to print building information
60
61int
62main(int argc, char* argv[])
63{
64 CommandLine cmd(__FILE__);
65 cmd.AddValue("nDevices", "Number of end devices to include in the simulation", nDevices);
66 cmd.AddValue("radius", "The radius (m) of the area to simulate", radiusMeters);
67 cmd.AddValue("realisticChannel",
68 "Whether to use a more realistic channel model",
70 cmd.AddValue("simulationTime", "The time (s) for which to simulate", simulationTimeSeconds);
71 cmd.AddValue("appPeriod",
72 "The period in seconds to be used by periodically transmitting applications",
74 cmd.AddValue("print", "Whether or not to print building information", printBuildingInfo);
75 cmd.Parse(argc, argv);
76
77 // Set up logging
78 LogComponentEnable("ComplexLorawanNetworkExample", LOG_LEVEL_ALL);
79 // LogComponentEnable("LoraChannel", LOG_LEVEL_INFO);
80 // LogComponentEnable("LoraPhy", LOG_LEVEL_ALL);
81 // LogComponentEnable("EndDeviceLoraPhy", LOG_LEVEL_ALL);
82 // LogComponentEnable("GatewayLoraPhy", LOG_LEVEL_ALL);
83 // LogComponentEnable("LoraInterferenceHelper", LOG_LEVEL_ALL);
84 // LogComponentEnable("LorawanMac", LOG_LEVEL_ALL);
85 // LogComponentEnable("EndDeviceLorawanMac", LOG_LEVEL_ALL);
86 // LogComponentEnable("ClassAEndDeviceLorawanMac", LOG_LEVEL_ALL);
87 // LogComponentEnable("GatewayLorawanMac", LOG_LEVEL_ALL);
88 // LogComponentEnable("LogicalLoraChannelHelper", LOG_LEVEL_ALL);
89 // LogComponentEnable("LogicalLoraChannel", LOG_LEVEL_ALL);
90 // LogComponentEnable("LoraHelper", LOG_LEVEL_ALL);
91 // LogComponentEnable("LoraPhyHelper", LOG_LEVEL_ALL);
92 // LogComponentEnable("LorawanMacHelper", LOG_LEVEL_ALL);
93 // LogComponentEnable("PeriodicSenderHelper", LOG_LEVEL_ALL);
94 // LogComponentEnable("PeriodicSender", LOG_LEVEL_ALL);
95 // LogComponentEnable("LorawanMacHeader", LOG_LEVEL_ALL);
96 // LogComponentEnable("LoraFrameHeader", LOG_LEVEL_ALL);
97 // LogComponentEnable("NetworkScheduler", LOG_LEVEL_ALL);
98 // LogComponentEnable("NetworkServer", LOG_LEVEL_ALL);
99 // LogComponentEnable("NetworkStatus", LOG_LEVEL_ALL);
100 // LogComponentEnable("NetworkController", LOG_LEVEL_ALL);
101
102 /***********
103 * Setup *
104 ***********/
105
106 // Create the time value from the period
107 Time appPeriod = Seconds(appPeriodSeconds);
108
109 // Mobility
110 MobilityHelper mobility;
111 mobility.SetPositionAllocator("ns3::UniformDiscPositionAllocator",
112 "rho",
114 "X",
115 DoubleValue(0.0),
116 "Y",
117 DoubleValue(0.0));
118 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
119
120 /************************
121 * Create the channel *
122 ************************/
123
124 // Create the lora channel object
126 loss->SetPathLossExponent(3.76);
127 loss->SetReference(1, 7.7);
128
130 {
131 // Create the correlated shadowing component
134
135 // Aggregate shadowing to the logdistance loss
136 loss->SetNext(shadowing);
137
138 // Add the effect to the channel propagation loss
140
141 shadowing->SetNext(buildingLoss);
142 }
143
145
146 Ptr<LoraChannel> channel = CreateObject<LoraChannel>(loss, delay);
147
148 /************************
149 * Create the helpers *
150 ************************/
151
152 // Create the LoraPhyHelper
153 LoraPhyHelper phyHelper = LoraPhyHelper();
154 phyHelper.SetChannel(channel);
155
156 // Create the LorawanMacHelper
158
159 // Create the LoraHelper
160 LoraHelper helper = LoraHelper();
161 helper.EnablePacketTracking(); // Output filename
162 // helper.EnableSimulationTimePrinting ();
163
164 // Create the NetworkServerHelper
166
167 // Create the ForwarderHelper
168 ForwarderHelper forHelper = ForwarderHelper();
169
170 /************************
171 * Create End Devices *
172 ************************/
173
174 // Create a set of nodes
175 NodeContainer endDevices;
176 endDevices.Create(nDevices);
177
178 // Assign a mobility model to each node
179 mobility.Install(endDevices);
180
181 // Make it so that nodes are at a certain height > 0
182 for (auto j = endDevices.Begin(); j != endDevices.End(); ++j)
183 {
184 Ptr<MobilityModel> mobility = (*j)->GetObject<MobilityModel>();
185 Vector position = mobility->GetPosition();
186 position.z = 1.2;
187 mobility->SetPosition(position);
188 }
189
190 // Create the LoraNetDevices of the end devices
191 uint8_t nwkId = 54;
192 uint32_t nwkAddr = 1864;
195
196 // Create the LoraNetDevices of the end devices
197 macHelper.SetAddressGenerator(addrGen);
200 helper.Install(phyHelper, macHelper, endDevices);
201
202 // Now end devices are connected to the channel
203
204 // Connect trace sources
205 for (auto j = endDevices.Begin(); j != endDevices.End(); ++j)
206 {
207 Ptr<Node> node = *j;
208 Ptr<LoraNetDevice> loraNetDevice = DynamicCast<LoraNetDevice>(node->GetDevice(0));
209 Ptr<LoraPhy> phy = loraNetDevice->GetPhy();
210 }
211
212 /*********************
213 * Create Gateways *
214 *********************/
215
216 // Create the gateway nodes (allocate them uniformly on the disc)
217 NodeContainer gateways;
218 gateways.Create(nGateways);
219
221 // Make it so that nodes are at a certain height > 0
222 allocator->Add(Vector(0.0, 0.0, 15.0));
223 mobility.SetPositionAllocator(allocator);
224 mobility.Install(gateways);
225
226 // Create a netdevice for each gateway
229 helper.Install(phyHelper, macHelper, gateways);
230
231 /**********************
232 * Handle buildings *
233 **********************/
234
235 double xLength = 130;
236 double deltaX = 32;
237 double yLength = 64;
238 double deltaY = 17;
239 int gridWidth = 2 * radiusMeters / (xLength + deltaX);
240 int gridHeight = 2 * radiusMeters / (yLength + deltaY);
242 {
243 gridWidth = 0;
244 gridHeight = 0;
245 }
246 Ptr<GridBuildingAllocator> gridBuildingAllocator;
247 gridBuildingAllocator = CreateObject<GridBuildingAllocator>();
248 gridBuildingAllocator->SetAttribute("GridWidth", UintegerValue(gridWidth));
249 gridBuildingAllocator->SetAttribute("LengthX", DoubleValue(xLength));
250 gridBuildingAllocator->SetAttribute("LengthY", DoubleValue(yLength));
251 gridBuildingAllocator->SetAttribute("DeltaX", DoubleValue(deltaX));
252 gridBuildingAllocator->SetAttribute("DeltaY", DoubleValue(deltaY));
253 gridBuildingAllocator->SetAttribute("Height", DoubleValue(6));
254 gridBuildingAllocator->SetBuildingAttribute("NRoomsX", UintegerValue(2));
255 gridBuildingAllocator->SetBuildingAttribute("NRoomsY", UintegerValue(4));
256 gridBuildingAllocator->SetBuildingAttribute("NFloors", UintegerValue(2));
257 gridBuildingAllocator->SetAttribute(
258 "MinX",
259 DoubleValue(-gridWidth * (xLength + deltaX) / 2 + deltaX / 2));
260 gridBuildingAllocator->SetAttribute(
261 "MinY",
262 DoubleValue(-gridHeight * (yLength + deltaY) / 2 + deltaY / 2));
263 BuildingContainer bContainer = gridBuildingAllocator->Create(gridWidth * gridHeight);
264
265 BuildingsHelper::Install(endDevices);
266 BuildingsHelper::Install(gateways);
267
268 // Print the buildings
270 {
271 std::ofstream myfile;
272 myfile.open("buildings.txt");
273 std::vector<Ptr<Building>>::const_iterator it;
274 int j = 1;
275 for (it = bContainer.Begin(); it != bContainer.End(); ++it, ++j)
276 {
277 Box boundaries = (*it)->GetBoundaries();
278 myfile << "set object " << j << " rect from " << boundaries.xMin << ","
279 << boundaries.yMin << " to " << boundaries.xMax << "," << boundaries.yMax
280 << std::endl;
281 }
282 myfile.close();
283 }
284
285 /**********************************************
286 * Set up the end device's spreading factor *
287 **********************************************/
288
289 LorawanMacHelper::SetSpreadingFactorsUp(endDevices, gateways, channel);
290
291 NS_LOG_DEBUG("Completed configuration");
292
293 /*********************************************
294 * Install applications on the end devices *
295 *********************************************/
296
297 Time appStopTime = Seconds(simulationTimeSeconds);
300 appHelper.SetPacketSize(23);
303 DoubleValue(0),
304 "Max",
305 DoubleValue(10));
306 ApplicationContainer appContainer = appHelper.Install(endDevices);
307
308 appContainer.Start(Seconds(0));
309 appContainer.Stop(appStopTime);
310
311 /**************************
312 * Create network server *
313 ***************************/
314
315 // Create the network server node
316 Ptr<Node> networkServer = CreateObject<Node>();
317
318 // PointToPoint links between gateways and server
320 p2p.SetDeviceAttribute("DataRate", StringValue("5Mbps"));
321 p2p.SetChannelAttribute("Delay", StringValue("2ms"));
322 // Store network server app registration details for later
323 P2PGwRegistration_t gwRegistration;
324 for (auto gw = gateways.Begin(); gw != gateways.End(); ++gw)
325 {
326 auto container = p2p.Install(networkServer, *gw);
327 auto serverP2PNetDev = DynamicCast<PointToPointNetDevice>(container.Get(0));
328 gwRegistration.emplace_back(serverP2PNetDev, *gw);
329 }
330
331 // Create a network server for the network
332 nsHelper.SetGatewaysP2P(gwRegistration);
333 nsHelper.SetEndDevices(endDevices);
334 nsHelper.Install(networkServer);
335
336 // Create a forwarder for each gateway
337 forHelper.Install(gateways);
338
339 ////////////////
340 // Simulation //
341 ////////////////
342
343 Simulator::Stop(appStopTime + Hours(1));
344
345 NS_LOG_INFO("Running simulation...");
347
349
350 ///////////////////////////
351 // Print results to file //
352 ///////////////////////////
353 NS_LOG_INFO("Computing performance metrics...");
354
355 LoraPacketTracker& tracker = helper.GetPacketTracker();
356 std::cout << tracker.CountMacPacketsGlobally(Seconds(0), appStopTime + Hours(1)) << std::endl;
357
358 return 0;
359}
holds a vector of ns3::Application pointers.
void Start(Time start) const
Start all of the Applications in this container at the start time given as a parameter.
void Stop(Time stop) const
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
a 3d box
Definition box.h:24
double yMax
The y coordinate of the top bound of the box.
Definition box.h:105
double xMin
The x coordinate of the left bound of the box.
Definition box.h:99
double yMin
The y coordinate of the bottom bound of the box.
Definition box.h:103
double xMax
The x coordinate of the right bound of the box.
Definition box.h:101
keep track of a set of building pointers.
Iterator End() const
Get an iterator which indicates past-the-last Building in the container.
Iterator Begin() const
Get an iterator which refers to the first Building in the container.
static void Install(Ptr< Node > node)
Install the MobilityBuildingInfo to a node.
Parse command-line arguments.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
Helper class used to assign positions and mobility models to nodes.
Keep track of the current position and velocity of an object.
keep track of a set of node pointers.
Iterator End() const
Get an iterator which indicates past-the-last Node in the container.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Iterator Begin() const
Get an iterator which refers to the first Node in the container.
Build a set of PointToPointNetDevice objects.
Smart pointer class similar to boost::intrusive_ptr.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static void Run()
Run the simulation.
Definition simulator.cc:167
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:175
Hold variables of type string.
Definition string.h:45
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
Hold an unsigned integer type.
Definition uinteger.h:34
This class can be used to install Forwarder applications on a set of gateways.
ApplicationContainer Install(NodeContainer c) const
Install a Forwarder application on each node of the input container configured with all the attribute...
Helps to create LoraNetDevice objects.
Definition lora-helper.h:37
void EnablePacketTracking()
Enable tracking of packets via trace sources.
LoraPacketTracker & GetPacketTracker()
Get a reference to the Packet Tracker object.
virtual NetDeviceContainer Install(const LoraPhyHelper &phyHelper, const LorawanMacHelper &macHelper, NodeContainer c) const
Install LoraNetDevices on a list of nodes.
Tracks and stores packets sent in the simulation and provides aggregation functionality.
std::string CountMacPacketsGlobally(Time startTime, Time stopTime)
In a time interval, count packets to evaluate the global performance at MAC level of the whole networ...
Helper to install LoraPhy instances on multiple Nodes.
void SetDeviceType(enum DeviceType dt)
Set the kind of PHY this helper will create.
void SetChannel(Ptr< LoraChannel > channel)
Set the LoraChannel to connect the PHYs to.
Helper class for configuring and installing the LorawanMac class on devices and gateways.
void SetDeviceType(enum DeviceType dt)
Set the kind of MAC this helper will create.
void SetAddressGenerator(Ptr< LoraDeviceAddressGenerator > addrGen)
Set the address generator to use for creation of these nodes.
static std::vector< int > SetSpreadingFactorsUp(NodeContainer endDevices, NodeContainer gateways, Ptr< LoraChannel > channel)
Initialize the end devices' data rate parameter.
This class can install a NetworkServer application on a node.
void SetGatewaysP2P(const P2PGwRegistration_t &registration)
Register gateways connected with point-to-point to this network server.
void SetEndDevices(NodeContainer endDevices)
Set which end devices will be managed by this network server.
ApplicationContainer Install(Ptr< Node > node)
Create one lorawan network server application on the Node.
This class can be used to install PeriodicSender applications on a wide range of nodes.
void SetPeriod(Time period)
Set the period to be used by the applications created by this helper.
void SetPacketSize(uint8_t size)
Set the base value for applications packet size in bytes.
ApplicationContainer Install(NodeContainer c) const
Install a PeriodicSender application on each node of the input container configured with all the attr...
double simulationTimeSeconds
Scenario duration (s) in simulated time.
int nDevices
Number of end device nodes to create.
bool printBuildingInfo
Whether to print building information.
bool realisticChannelModel
Whether to use a more realistic channel model with Buildings and correlated shadowing.
int nGateways
Number of gateway nodes to create.
int appPeriodSeconds
Duration (s) of the inter-transmission time of end devices.
double radiusMeters
Radius (m) of the deployment.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Ptr< T > CreateObjectWithAttributes(Args... args)
Allocate an Object on the heap and initialize with a set of attributes.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
Time Hours(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1284
std::list< std::pair< Ptr< PointToPointNetDevice >, Ptr< Node > > > P2PGwRegistration_t
Store network server app registration details for gateway nodes having a P2P link with the network se...
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void LogComponentEnable(const std::string &name, LogLevel level)
Enable the logging output associated with that log component.
Definition log.cc:291
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580
@ LOG_LEVEL_ALL
Print everything.
Definition log.h:105