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 * 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 * Author: Davide Magrin <magrinda@dei.unipd.it>
18 */
19
20/*
21 * This script simulates a complex scenario with multiple gateways and end
22 * devices. The metric of interest for this script is the throughput of the
23 * network.
24 */
25
26#include "ns3/building-allocator.h"
27#include "ns3/building-penetration-loss.h"
28#include "ns3/buildings-helper.h"
29#include "ns3/class-a-end-device-lorawan-mac.h"
30#include "ns3/command-line.h"
31#include "ns3/constant-position-mobility-model.h"
32#include "ns3/correlated-shadowing-propagation-loss-model.h"
33#include "ns3/double.h"
34#include "ns3/end-device-lora-phy.h"
35#include "ns3/forwarder-helper.h"
36#include "ns3/gateway-lora-phy.h"
37#include "ns3/gateway-lorawan-mac.h"
38#include "ns3/log.h"
39#include "ns3/lora-helper.h"
40#include "ns3/mobility-helper.h"
41#include "ns3/network-server-helper.h"
42#include "ns3/node-container.h"
43#include "ns3/periodic-sender-helper.h"
44#include "ns3/pointer.h"
45#include "ns3/position-allocator.h"
46#include "ns3/random-variable-stream.h"
47#include "ns3/simulator.h"
48
49#include <algorithm>
50#include <ctime>
51
52using namespace ns3;
53using namespace lorawan;
54
55NS_LOG_COMPONENT_DEFINE("ComplexLorawanNetworkExample");
56
57// Network settings
58int nDevices = 200; //!< Number of end device nodes to create
59int nGateways = 1; //!< Number of gateway nodes to create
60double radiusMeters = 6400; //!< Radius (m) of the deployment
61double simulationTimeSeconds = 600; //!< Scenario duration (s) in simulated time
62
63// Channel model
64bool realisticChannelModel = false; //!< Whether to use a more realistic channel model with
65 //!< Buildings and correlated shadowing
66
67int appPeriodSeconds = 600; //!< Duration (s) of the inter-transmission time of end devices
68
69// Output control
70bool printBuildingInfo = true; //!< Whether to print building information
71
72int
73main(int argc, char* argv[])
74{
75 CommandLine cmd(__FILE__);
76 cmd.AddValue("nDevices", "Number of end devices to include in the simulation", nDevices);
77 cmd.AddValue("radius", "The radius (m) of the area to simulate", radiusMeters);
78 cmd.AddValue("simulationTime", "The time (s) for which to simulate", simulationTimeSeconds);
79 cmd.AddValue("appPeriod",
80 "The period in seconds to be used by periodically transmitting applications",
82 cmd.AddValue("print", "Whether or not to print building information", printBuildingInfo);
83 cmd.Parse(argc, argv);
84
85 // Set up logging
86 LogComponentEnable("ComplexLorawanNetworkExample", LOG_LEVEL_ALL);
87 // LogComponentEnable("LoraChannel", LOG_LEVEL_INFO);
88 // LogComponentEnable("LoraPhy", LOG_LEVEL_ALL);
89 // LogComponentEnable("EndDeviceLoraPhy", LOG_LEVEL_ALL);
90 // LogComponentEnable("GatewayLoraPhy", LOG_LEVEL_ALL);
91 // LogComponentEnable("LoraInterferenceHelper", LOG_LEVEL_ALL);
92 // LogComponentEnable("LorawanMac", LOG_LEVEL_ALL);
93 // LogComponentEnable("EndDeviceLorawanMac", LOG_LEVEL_ALL);
94 // LogComponentEnable("ClassAEndDeviceLorawanMac", LOG_LEVEL_ALL);
95 // LogComponentEnable("GatewayLorawanMac", LOG_LEVEL_ALL);
96 // LogComponentEnable("LogicalLoraChannelHelper", LOG_LEVEL_ALL);
97 // LogComponentEnable("LogicalLoraChannel", LOG_LEVEL_ALL);
98 // LogComponentEnable("LoraHelper", LOG_LEVEL_ALL);
99 // LogComponentEnable("LoraPhyHelper", LOG_LEVEL_ALL);
100 // LogComponentEnable("LorawanMacHelper", LOG_LEVEL_ALL);
101 // LogComponentEnable("PeriodicSenderHelper", LOG_LEVEL_ALL);
102 // LogComponentEnable("PeriodicSender", LOG_LEVEL_ALL);
103 // LogComponentEnable("LorawanMacHeader", LOG_LEVEL_ALL);
104 // LogComponentEnable("LoraFrameHeader", LOG_LEVEL_ALL);
105 // LogComponentEnable("NetworkScheduler", LOG_LEVEL_ALL);
106 // LogComponentEnable("NetworkServer", LOG_LEVEL_ALL);
107 // LogComponentEnable("NetworkStatus", LOG_LEVEL_ALL);
108 // LogComponentEnable("NetworkController", LOG_LEVEL_ALL);
109
110 /***********
111 * Setup *
112 ***********/
113
114 // Create the time value from the period
115 Time appPeriod = Seconds(appPeriodSeconds);
116
117 // Mobility
118 MobilityHelper mobility;
119 mobility.SetPositionAllocator("ns3::UniformDiscPositionAllocator",
120 "rho",
122 "X",
123 DoubleValue(0.0),
124 "Y",
125 DoubleValue(0.0));
126 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
127
128 /************************
129 * Create the channel *
130 ************************/
131
132 // Create the lora channel object
133 Ptr<LogDistancePropagationLossModel> loss = CreateObject<LogDistancePropagationLossModel>();
134 loss->SetPathLossExponent(3.76);
135 loss->SetReference(1, 7.7);
136
138 {
139 // Create the correlated shadowing component
141 CreateObject<CorrelatedShadowingPropagationLossModel>();
142
143 // Aggregate shadowing to the logdistance loss
144 loss->SetNext(shadowing);
145
146 // Add the effect to the channel propagation loss
147 Ptr<BuildingPenetrationLoss> buildingLoss = CreateObject<BuildingPenetrationLoss>();
148
149 shadowing->SetNext(buildingLoss);
150 }
151
152 Ptr<PropagationDelayModel> delay = CreateObject<ConstantSpeedPropagationDelayModel>();
153
154 Ptr<LoraChannel> channel = CreateObject<LoraChannel>(loss, delay);
155
156 /************************
157 * Create the helpers *
158 ************************/
159
160 // Create the LoraPhyHelper
161 LoraPhyHelper phyHelper = LoraPhyHelper();
162 phyHelper.SetChannel(channel);
163
164 // Create the LorawanMacHelper
166
167 // Create the LoraHelper
168 LoraHelper helper = LoraHelper();
169 helper.EnablePacketTracking(); // Output filename
170 // helper.EnableSimulationTimePrinting ();
171
172 // Create the NetworkServerHelper
174
175 // Create the ForwarderHelper
176 ForwarderHelper forHelper = ForwarderHelper();
177
178 /************************
179 * Create End Devices *
180 ************************/
181
182 // Create a set of nodes
183 NodeContainer endDevices;
184 endDevices.Create(nDevices);
185
186 // Assign a mobility model to each node
187 mobility.Install(endDevices);
188
189 // Make it so that nodes are at a certain height > 0
190 for (auto j = endDevices.Begin(); j != endDevices.End(); ++j)
191 {
192 Ptr<MobilityModel> mobility = (*j)->GetObject<MobilityModel>();
193 Vector position = mobility->GetPosition();
194 position.z = 1.2;
195 mobility->SetPosition(position);
196 }
197
198 // Create the LoraNetDevices of the end devices
199 uint8_t nwkId = 54;
200 uint32_t nwkAddr = 1864;
202 CreateObject<LoraDeviceAddressGenerator>(nwkId, nwkAddr);
203
204 // Create the LoraNetDevices of the end devices
205 macHelper.SetAddressGenerator(addrGen);
208 helper.Install(phyHelper, macHelper, endDevices);
209
210 // Now end devices are connected to the channel
211
212 // Connect trace sources
213 for (auto j = endDevices.Begin(); j != endDevices.End(); ++j)
214 {
215 Ptr<Node> node = *j;
216 Ptr<LoraNetDevice> loraNetDevice = node->GetDevice(0)->GetObject<LoraNetDevice>();
217 Ptr<LoraPhy> phy = loraNetDevice->GetPhy();
218 }
219
220 /*********************
221 * Create Gateways *
222 *********************/
223
224 // Create the gateway nodes (allocate them uniformly on the disc)
225 NodeContainer gateways;
226 gateways.Create(nGateways);
227
228 Ptr<ListPositionAllocator> allocator = CreateObject<ListPositionAllocator>();
229 // Make it so that nodes are at a certain height > 0
230 allocator->Add(Vector(0.0, 0.0, 15.0));
231 mobility.SetPositionAllocator(allocator);
232 mobility.Install(gateways);
233
234 // Create a netdevice for each gateway
237 helper.Install(phyHelper, macHelper, gateways);
238
239 /**********************
240 * Handle buildings *
241 **********************/
242
243 double xLength = 130;
244 double deltaX = 32;
245 double yLength = 64;
246 double deltaY = 17;
247 int gridWidth = 2 * radiusMeters / (xLength + deltaX);
248 int gridHeight = 2 * radiusMeters / (yLength + deltaY);
250 {
251 gridWidth = 0;
252 gridHeight = 0;
253 }
254 Ptr<GridBuildingAllocator> gridBuildingAllocator;
255 gridBuildingAllocator = CreateObject<GridBuildingAllocator>();
256 gridBuildingAllocator->SetAttribute("GridWidth", UintegerValue(gridWidth));
257 gridBuildingAllocator->SetAttribute("LengthX", DoubleValue(xLength));
258 gridBuildingAllocator->SetAttribute("LengthY", DoubleValue(yLength));
259 gridBuildingAllocator->SetAttribute("DeltaX", DoubleValue(deltaX));
260 gridBuildingAllocator->SetAttribute("DeltaY", DoubleValue(deltaY));
261 gridBuildingAllocator->SetAttribute("Height", DoubleValue(6));
262 gridBuildingAllocator->SetBuildingAttribute("NRoomsX", UintegerValue(2));
263 gridBuildingAllocator->SetBuildingAttribute("NRoomsY", UintegerValue(4));
264 gridBuildingAllocator->SetBuildingAttribute("NFloors", UintegerValue(2));
265 gridBuildingAllocator->SetAttribute(
266 "MinX",
267 DoubleValue(-gridWidth * (xLength + deltaX) / 2 + deltaX / 2));
268 gridBuildingAllocator->SetAttribute(
269 "MinY",
270 DoubleValue(-gridHeight * (yLength + deltaY) / 2 + deltaY / 2));
271 BuildingContainer bContainer = gridBuildingAllocator->Create(gridWidth * gridHeight);
272
273 BuildingsHelper::Install(endDevices);
274 BuildingsHelper::Install(gateways);
275
276 // Print the buildings
278 {
279 std::ofstream myfile;
280 myfile.open("buildings.txt");
281 std::vector<Ptr<Building>>::const_iterator it;
282 int j = 1;
283 for (it = bContainer.Begin(); it != bContainer.End(); ++it, ++j)
284 {
285 Box boundaries = (*it)->GetBoundaries();
286 myfile << "set object " << j << " rect from " << boundaries.xMin << ","
287 << boundaries.yMin << " to " << boundaries.xMax << "," << boundaries.yMax
288 << std::endl;
289 }
290 myfile.close();
291 }
292
293 /**********************************************
294 * Set up the end device's spreading factor *
295 **********************************************/
296
297 LorawanMacHelper::SetSpreadingFactorsUp(endDevices, gateways, channel);
298
299 NS_LOG_DEBUG("Completed configuration");
300
301 /*********************************************
302 * Install applications on the end devices *
303 *********************************************/
304
305 Time appStopTime = Seconds(simulationTimeSeconds);
308 appHelper.SetPacketSize(23);
310 CreateObjectWithAttributes<UniformRandomVariable>("Min",
311 DoubleValue(0),
312 "Max",
313 DoubleValue(10));
314 ApplicationContainer appContainer = appHelper.Install(endDevices);
315
316 appContainer.Start(Seconds(0));
317 appContainer.Stop(appStopTime);
318
319 /**************************
320 * Create network server *
321 ***************************/
322
323 // Create the network server node
324 Ptr<Node> networkServer = CreateObject<Node>();
325
326 // PointToPoint links between gateways and server
328 p2p.SetDeviceAttribute("DataRate", StringValue("5Mbps"));
329 p2p.SetChannelAttribute("Delay", StringValue("2ms"));
330 // Store network server app registration details for later
331 P2PGwRegistration_t gwRegistration;
332 for (auto gw = gateways.Begin(); gw != gateways.End(); ++gw)
333 {
334 auto container = p2p.Install(networkServer, *gw);
335 auto serverP2PNetDev = DynamicCast<PointToPointNetDevice>(container.Get(0));
336 gwRegistration.emplace_back(serverP2PNetDev, *gw);
337 }
338
339 // Create a network server for the network
340 nsHelper.SetGatewaysP2P(gwRegistration);
341 nsHelper.SetEndDevices(endDevices);
342 nsHelper.Install(networkServer);
343
344 // Create a forwarder for each gateway
345 forHelper.Install(gateways);
346
347 ////////////////
348 // Simulation //
349 ////////////////
350
351 Simulator::Stop(appStopTime + Hours(1));
352
353 NS_LOG_INFO("Running simulation...");
355
357
358 ///////////////////////////
359 // Print results to file //
360 ///////////////////////////
361 NS_LOG_INFO("Computing performance metrics...");
362
363 LoraPacketTracker& tracker = helper.GetPacketTracker();
364 std::cout << tracker.CountMacPacketsGlobally(Seconds(0), appStopTime + Hours(1)) << std::endl;
365
366 return 0;
367}
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:35
double yMax
The y coordinate of the top bound of the box.
Definition: box.h:116
double xMin
The x coordinate of the left bound of the box.
Definition: box.h:110
double yMin
The y coordinate of the bottom bound of the box.
Definition: box.h:114
double xMax
The x coordinate of the right bound of the box.
Definition: box.h:112
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.
Definition: command-line.h:232
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
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.
Definition: ptr.h:77
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static void Run()
Run the simulation.
Definition: simulator.cc:178
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:186
Hold variables of type string.
Definition: string.h:56
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
Hold an unsigned integer type.
Definition: uinteger.h:45
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:48
void EnablePacketTracking()
Enable tracking of packets via trace sources.
Definition: lora-helper.cc:145
LoraPacketTracker & GetPacketTracker()
Get a reference to the Packet Tracker object.
Definition: lora-helper.cc:154
virtual NetDeviceContainer Install(const LoraPhyHelper &phyHelper, const LorawanMacHelper &macHelper, NodeContainer c) const
Install LoraNetDevices on a list of nodes.
Definition: lora-helper.cc:44
Hold together all LoRa related objects.
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:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1319
Time Hours(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1295
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:302
@ LOG_LEVEL_ALL
Print everything.
Definition: log.h:116