A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
adr-example.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018 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 program creates a simple network which uses an Adaptive Data Rate (ADR) algorithm to set up
11 * the Spreading Factors of the devices in the Network.
12 */
13
14#include "ns3/command-line.h"
15#include "ns3/config.h"
16#include "ns3/core-module.h"
17#include "ns3/forwarder-helper.h"
18#include "ns3/gateway-lora-phy.h"
19#include "ns3/hex-grid-position-allocator.h"
20#include "ns3/log.h"
21#include "ns3/lora-channel.h"
22#include "ns3/lora-device-address-generator.h"
23#include "ns3/lora-helper.h"
24#include "ns3/lora-phy-helper.h"
25#include "ns3/lorawan-mac-helper.h"
26#include "ns3/mobility-helper.h"
27#include "ns3/network-module.h"
28#include "ns3/network-server-helper.h"
29#include "ns3/periodic-sender-helper.h"
30#include "ns3/periodic-sender.h"
31#include "ns3/point-to-point-module.h"
32#include "ns3/random-variable-stream.h"
33#include "ns3/rectangle.h"
34#include "ns3/string.h"
35
36using namespace ns3;
37using namespace lorawan;
38
39NS_LOG_COMPONENT_DEFINE("AdrExample");
40
41/**
42 * Record a change in the data rate setting on an end device.
43 *
44 * @param oldDr The previous data rate value.
45 * @param newDr The updated data rate value.
46 */
47void
48OnDataRateChange(uint8_t oldDr, uint8_t newDr)
49{
50 NS_LOG_DEBUG("DR" << unsigned(oldDr) << " -> DR" << unsigned(newDr));
51}
52
53/**
54 * Record a change in the transmission power setting on an end device.
55 *
56 * @param oldTxPower The previous transmission power value.
57 * @param newTxPower The updated transmission power value.
58 */
59void
60OnTxPowerChange(double oldTxPower, double newTxPower)
61{
62 NS_LOG_DEBUG(oldTxPower << " dBm -> " << newTxPower << " dBm");
63}
64
65int
66main(int argc, char* argv[])
67{
68 bool verbose = false;
69 bool adrEnabled = true;
70 bool initializeSF = false;
71 int nDevices = 400;
72 int nPeriodsOf20Minutes = 20;
73 double mobileNodeProbability = 0;
74 double sideLengthMeters = 10000;
75 int gatewayDistanceMeters = 5000;
76 double maxRandomLossDb = 10;
77 double minSpeedMetersPerSecond = 2;
78 double maxSpeedMetersPerSecond = 16;
79 std::string adrType = "ns3::AdrComponent";
80
81 CommandLine cmd(__FILE__);
82 cmd.AddValue("verbose", "Whether to print output or not", verbose);
83 cmd.AddValue("MultipleGwCombiningMethod", "ns3::AdrComponent::MultipleGwCombiningMethod");
84 cmd.AddValue("MultiplePacketsCombiningMethod",
85 "ns3::AdrComponent::MultiplePacketsCombiningMethod");
86 cmd.AddValue("HistoryRange", "ns3::AdrComponent::HistoryRange");
87 cmd.AddValue("MType", "ns3::EndDeviceLorawanMac::MType");
88 cmd.AddValue("ChangeTransmissionPower", "ns3::AdrComponent::ChangeTransmissionPower");
89 cmd.AddValue("AdrEnabled", "Whether to enable Adaptive Data Rate (ADR)", adrEnabled);
90 cmd.AddValue("nDevices", "Number of devices to simulate", nDevices);
91 cmd.AddValue("PeriodsToSimulate", "Number of periods (20m) to simulate", nPeriodsOf20Minutes);
92 cmd.AddValue("MobileNodeProbability",
93 "Probability of a node being a mobile node",
94 mobileNodeProbability);
95 cmd.AddValue("sideLength",
96 "Length (m) of the side of the rectangle nodes will be placed in",
97 sideLengthMeters);
98 cmd.AddValue("maxRandomLoss",
99 "Maximum amount (dB) of the random loss component",
100 maxRandomLossDb);
101 cmd.AddValue("gatewayDistance", "Distance (m) between gateways", gatewayDistanceMeters);
102 cmd.AddValue("initializeSF", "Whether to initialize the SFs", initializeSF);
103 cmd.AddValue("MinSpeed", "Minimum speed (m/s) for mobile devices", minSpeedMetersPerSecond);
104 cmd.AddValue("MaxSpeed", "Maximum speed (m/s) for mobile devices", maxSpeedMetersPerSecond);
105 cmd.AddValue("MaxTransmissions", "ns3::EndDeviceLorawanMac::MaxTransmissions");
106 cmd.Parse(argc, argv);
107
108 int gatewayRings = 2 + (std::sqrt(2) * sideLengthMeters) / (gatewayDistanceMeters);
109 int nGateways = 3 * gatewayRings * gatewayRings - 3 * gatewayRings + 1;
110
111 // Logging
112 //////////
113
114 LogComponentEnable("AdrExample", LOG_LEVEL_ALL);
115 // LogComponentEnable ("LoraPacketTracker", LOG_LEVEL_ALL);
116 // LogComponentEnable ("NetworkServer", LOG_LEVEL_ALL);
117 // LogComponentEnable ("NetworkController", LOG_LEVEL_ALL);
118 // LogComponentEnable ("NetworkScheduler", LOG_LEVEL_ALL);
119 // LogComponentEnable ("NetworkStatus", LOG_LEVEL_ALL);
120 // LogComponentEnable ("EndDeviceStatus", LOG_LEVEL_ALL);
121 LogComponentEnable("AdrComponent", LOG_LEVEL_ALL);
122 // LogComponentEnable("ClassAEndDeviceLorawanMac", LOG_LEVEL_ALL);
123 // LogComponentEnable ("LogicalLoraChannelHelper", LOG_LEVEL_ALL);
124 // LogComponentEnable ("MacCommand", LOG_LEVEL_ALL);
125 // LogComponentEnable ("AdrExploraSf", LOG_LEVEL_ALL);
126 // LogComponentEnable ("AdrExploraAt", LOG_LEVEL_ALL);
127 // LogComponentEnable ("EndDeviceLorawanMac", LOG_LEVEL_ALL);
131
132 // Set the end devices to allow data rate control (i.e. adaptive data rate) from the network
133 // server
134 Config::SetDefault("ns3::EndDeviceLorawanMac::ADR", BooleanValue(true));
135
136 // Create a simple wireless channel
137 ///////////////////////////////////
138
140 loss->SetPathLossExponent(3.76);
141 loss->SetReference(1, 7.7);
142
144 x->SetAttribute("Min", DoubleValue(0.0));
145 x->SetAttribute("Max", DoubleValue(maxRandomLossDb));
146
148 randomLoss->SetAttribute("Variable", PointerValue(x));
149
150 loss->SetNext(randomLoss);
151
153
155
156 // Helpers
157 //////////
158
159 // End device mobility
160 MobilityHelper mobilityEd;
161 MobilityHelper mobilityGw;
162 mobilityEd.SetPositionAllocator("ns3::RandomRectanglePositionAllocator",
163 "X",
165 "Min",
166 DoubleValue(-sideLengthMeters),
167 "Max",
168 DoubleValue(sideLengthMeters))),
169 "Y",
171 "Min",
172 DoubleValue(-sideLengthMeters),
173 "Max",
174 DoubleValue(sideLengthMeters))));
175
176 // // Gateway mobility
177 // Ptr<ListPositionAllocator> positionAllocGw = CreateObject<ListPositionAllocator> ();
178 // positionAllocGw->Add (Vector (0.0, 0.0, 15.0));
179 // positionAllocGw->Add (Vector (-5000.0, -5000.0, 15.0));
180 // positionAllocGw->Add (Vector (-5000.0, 5000.0, 15.0));
181 // positionAllocGw->Add (Vector (5000.0, -5000.0, 15.0));
182 // positionAllocGw->Add (Vector (5000.0, 5000.0, 15.0));
183 // mobilityGw.SetPositionAllocator (positionAllocGw);
184 // mobilityGw.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
185 Ptr<HexGridPositionAllocator> hexAllocator =
186 CreateObject<HexGridPositionAllocator>(gatewayDistanceMeters / 2);
187 mobilityGw.SetPositionAllocator(hexAllocator);
188 mobilityGw.SetMobilityModel("ns3::ConstantPositionMobilityModel");
189
190 // Create the LoraPhyHelper
191 LoraPhyHelper phyHelper = LoraPhyHelper();
192 phyHelper.SetChannel(channel);
193
194 // Create the LorawanMacHelper
196
197 // Create the LoraHelper
198 LoraHelper helper = LoraHelper();
199 helper.EnablePacketTracking();
200
201 ////////////////
202 // Create gateways //
203 ////////////////
204
205 NodeContainer gateways;
206 gateways.Create(nGateways);
207 mobilityGw.Install(gateways);
208
209 // Create the LoraNetDevices of the gateways
212 helper.Install(phyHelper, macHelper, gateways);
213
214 // Create end devices
215 /////////////
216
217 NodeContainer endDevices;
218 endDevices.Create(nDevices);
219
220 // Install mobility model on fixed nodes
221 mobilityEd.SetMobilityModel("ns3::ConstantPositionMobilityModel");
222 int fixedPositionNodes = double(nDevices) * (1 - mobileNodeProbability);
223 for (int i = 0; i < fixedPositionNodes; ++i)
224 {
225 mobilityEd.Install(endDevices.Get(i));
226 }
227 // Install mobility model on mobile nodes
228 mobilityEd.SetMobilityModel(
229 "ns3::RandomWalk2dMobilityModel",
230 "Bounds",
232 Rectangle(-sideLengthMeters, sideLengthMeters, -sideLengthMeters, sideLengthMeters)),
233 "Distance",
234 DoubleValue(1000),
235 "Speed",
237 "Min",
238 DoubleValue(minSpeedMetersPerSecond),
239 "Max",
240 DoubleValue(maxSpeedMetersPerSecond))));
241 for (int i = fixedPositionNodes; i < (int)endDevices.GetN(); ++i)
242 {
243 mobilityEd.Install(endDevices.Get(i));
244 }
245
246 // Create a LoraDeviceAddressGenerator
247 uint8_t nwkId = 54;
248 uint32_t nwkAddr = 1864;
251
252 // Create the LoraNetDevices of the end devices
255 macHelper.SetAddressGenerator(addrGen);
257 helper.Install(phyHelper, macHelper, endDevices);
258
259 // Install applications in end devices
260 int appPeriodSeconds = 1200; // One packet every 20 minutes
263 ApplicationContainer appContainer = appHelper.Install(endDevices);
264
265 // Do not set spreading factors up: we will wait for the network server to do this
266 if (initializeSF)
267 {
268 LorawanMacHelper::SetSpreadingFactorsUp(endDevices, gateways, channel);
269 }
270
271 ////////////
272 // Create network server
273 ////////////
274
275 Ptr<Node> networkServer = CreateObject<Node>();
276
277 // PointToPoint links between gateways and server
279 p2p.SetDeviceAttribute("DataRate", StringValue("5Mbps"));
280 p2p.SetChannelAttribute("Delay", StringValue("2ms"));
281 // Store network server app registration details for later
282 P2PGwRegistration_t gwRegistration;
283 for (auto gw = gateways.Begin(); gw != gateways.End(); ++gw)
284 {
285 auto container = p2p.Install(networkServer, *gw);
286 auto serverP2PNetDev = DynamicCast<PointToPointNetDevice>(container.Get(0));
287 gwRegistration.emplace_back(serverP2PNetDev, *gw);
288 }
289
290 // Install the NetworkServer application on the network server
291 NetworkServerHelper networkServerHelper;
292 networkServerHelper.EnableAdr(adrEnabled);
293 networkServerHelper.SetAdr(adrType);
294 networkServerHelper.SetGatewaysP2P(gwRegistration);
295 networkServerHelper.SetEndDevices(endDevices);
296 networkServerHelper.Install(networkServer);
297
298 // Install the Forwarder application on the gateways
299 ForwarderHelper forwarderHelper;
300 forwarderHelper.Install(gateways);
301
302 // Connect our traces
304 "/NodeList/*/DeviceList/0/$ns3::LoraNetDevice/Mac/$ns3::EndDeviceLorawanMac/TxPower",
307 "/NodeList/*/DeviceList/0/$ns3::LoraNetDevice/Mac/$ns3::EndDeviceLorawanMac/DataRate",
309
310 // Activate printing of end device MAC parameters
311 Time stateSamplePeriod = Seconds(1200);
312 helper.EnablePeriodicDeviceStatusPrinting(endDevices,
313 gateways,
314 "nodeData.txt",
315 stateSamplePeriod);
316 helper.EnablePeriodicPhyPerformancePrinting(gateways, "phyPerformance.txt", stateSamplePeriod);
317 helper.EnablePeriodicGlobalPerformancePrinting("globalPerformance.txt", stateSamplePeriod);
318
319 LoraPacketTracker& tracker = helper.GetPacketTracker();
320
321 // Start simulation
322 Time simulationTime = Seconds(1200 * nPeriodsOf20Minutes);
323 Simulator::Stop(simulationTime);
326
327 std::cout << tracker.CountMacPacketsGlobally(Seconds(1200 * (nPeriodsOf20Minutes - 2)),
328 Seconds(1200 * (nPeriodsOf20Minutes - 1)))
329 << std::endl;
330
331 return 0;
332}
cairo_uint64_t x
_cairo_uint_96by64_32x64_divrem:
holds a vector of ns3::Application pointers.
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.
void Install(Ptr< Node > node) const
"Layout" a single node according to the current position allocator type.
void SetMobilityModel(std::string type, Ts &&... args)
void SetPositionAllocator(Ptr< PositionAllocator > allocator)
Set the position allocator which will be used to allocate the initial position of every node initiali...
keep track of a set of node pointers.
Iterator End() const
Get an iterator which indicates past-the-last Node in the container.
uint32_t GetN() const
Get the number of Ptr<Node> stored in this 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.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
Build a set of PointToPointNetDevice objects.
AttributeValue implementation for Pointer.
Definition pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:67
a 2d rectangle
Definition rectangle.h:24
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:96
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 EnablePeriodicDeviceStatusPrinting(NodeContainer endDevices, NodeContainer gateways, std::string filename, Time interval)
Periodically prints the status of devices in the network to a file.
void EnablePeriodicPhyPerformancePrinting(NodeContainer gateways, std::string filename, Time interval)
Periodically prints PHY-level performance at every gateway in the container.
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.
void EnablePeriodicGlobalPerformancePrinting(std::string filename, Time interval)
Periodically print global performance as the total number of send and received packets.
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.
void SetRegion(enum Regions region)
Set the region in which the device is to operate.
This class can install a NetworkServer application on a node.
void EnableAdr(bool enableAdr)
Enable (true) or disable (false) the Adaptive Data Rate (ADR) component in the Network Server created...
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.
void SetAdr(std::string type)
Set the Adaptive Data Rate (ADR) implementation to use in the network server created by this helper.
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.
ApplicationContainer Install(NodeContainer c) const
Install a PeriodicSender application on each node of the input container configured with all the attr...
void OnDataRateChange(uint8_t oldDr, uint8_t newDr)
Record a change in the data rate setting on an end device.
void OnTxPowerChange(double oldTxPower, double newTxPower)
Record a change in the transmission power setting on an end device.
int nDevices
Number of end device nodes to create.
int nGateways
Number of gateway nodes to create.
int appPeriodSeconds
Duration (s) of the inter-transmission time of end devices.
void SetDefault(std::string name, const AttributeValue &value)
Definition config.cc:886
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition config.cc:946
#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
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:1369
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:284
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition callback.h:684
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:585
@ LOG_LEVEL_ALL
Print everything.
Definition log.h:105
@ LOG_PREFIX_FUNC
Prefix all trace prints with function.
Definition log.h:107
@ LOG_PREFIX_TIME
Prefix all trace prints with simulation time.
Definition log.h:108
@ LOG_PREFIX_NODE
Prefix all trace prints with simulation node.
Definition log.h:109
void LogComponentEnableAll(LogLevel level)
Enable the logging output for all registered log components.
Definition log.cc:302
channel
Definition third.py:77
bool verbose