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/core-module.h"
15#include "ns3/lorawan-module.h"
16#include "ns3/mobility-helper.h"
17#include "ns3/point-to-point-helper.h"
18#include "ns3/rectangle.h"
19
20using namespace ns3;
21using namespace lorawan;
22
23NS_LOG_COMPONENT_DEFINE("AdrExample");
24
25/**
26 * Record a change in the data rate setting on an end device.
27 *
28 * @param oldDr The previous data rate value.
29 * @param newDr The updated data rate value.
30 */
31void
32OnDataRateChange(uint8_t oldDr, uint8_t newDr)
33{
34 NS_LOG_DEBUG("DR" << unsigned(oldDr) << " -> DR" << unsigned(newDr));
35}
36
37/**
38 * Record a change in the transmission power setting on an end device.
39 *
40 * @param oldTxPower The previous transmission power value.
41 * @param newTxPower The updated transmission power value.
42 */
43void
44OnTxPowerChange(double oldTxPower, double newTxPower)
45{
46 NS_LOG_DEBUG(oldTxPower << " dBm -> " << newTxPower << " dBm");
47}
48
49int
50main(int argc, char* argv[])
51{
52 bool verbose = false;
53 bool adrEnabled = true;
54 bool initializeSF = false;
55 int nDevices = 400;
56 int nPeriodsOf20Minutes = 20;
57 double mobileNodeProbability = 0;
58 double sideLengthMeters = 10000;
59 int gatewayDistanceMeters = 5000;
60 double maxRandomLossDb = 10;
61 double minSpeedMetersPerSecond = 2;
62 double maxSpeedMetersPerSecond = 16;
63 std::string adrType = "ns3::AdrComponent";
64
65 CommandLine cmd(__FILE__);
66 cmd.AddValue("verbose", "Whether to print output or not", verbose);
67 cmd.AddValue("MultipleGwCombiningMethod", "ns3::AdrComponent::MultipleGwCombiningMethod");
68 cmd.AddValue("MultiplePacketsCombiningMethod",
69 "ns3::AdrComponent::MultiplePacketsCombiningMethod");
70 cmd.AddValue("HistoryRange", "ns3::AdrComponent::HistoryRange");
71 cmd.AddValue("MType", "ns3::EndDeviceLorawanMac::MType");
72 cmd.AddValue("ChangeTransmissionPower", "ns3::AdrComponent::ChangeTransmissionPower");
73 cmd.AddValue("AdrEnabled", "Whether to enable Adaptive Data Rate (ADR)", adrEnabled);
74 cmd.AddValue("nDevices", "Number of devices to simulate", nDevices);
75 cmd.AddValue("PeriodsToSimulate", "Number of periods (20m) to simulate", nPeriodsOf20Minutes);
76 cmd.AddValue("MobileNodeProbability",
77 "Probability of a node being a mobile node",
78 mobileNodeProbability);
79 cmd.AddValue("sideLength",
80 "Length (m) of the side of the rectangle nodes will be placed in",
81 sideLengthMeters);
82 cmd.AddValue("maxRandomLoss",
83 "Maximum amount (dB) of the random loss component",
84 maxRandomLossDb);
85 cmd.AddValue("gatewayDistance", "Distance (m) between gateways", gatewayDistanceMeters);
86 cmd.AddValue("initializeSF", "Whether to initialize the SFs", initializeSF);
87 cmd.AddValue("MinSpeed", "Minimum speed (m/s) for mobile devices", minSpeedMetersPerSecond);
88 cmd.AddValue("MaxSpeed", "Maximum speed (m/s) for mobile devices", maxSpeedMetersPerSecond);
89 cmd.AddValue("MaxTransmissions", "ns3::EndDeviceLorawanMac::MaxTransmissions");
90 cmd.Parse(argc, argv);
91
92 int gatewayRings = 2 + (std::sqrt(2) * sideLengthMeters) / (gatewayDistanceMeters);
93 int nGateways = 3 * gatewayRings * gatewayRings - 3 * gatewayRings + 1;
94
95 // Logging
96 //////////
97
98 LogComponentEnable("AdrExample", LOG_LEVEL_ALL);
99 // LogComponentEnable ("LoraPacketTracker", LOG_LEVEL_ALL);
100 // LogComponentEnable ("NetworkServer", LOG_LEVEL_ALL);
101 // LogComponentEnable ("NetworkController", LOG_LEVEL_ALL);
102 // LogComponentEnable ("NetworkScheduler", LOG_LEVEL_ALL);
103 // LogComponentEnable ("NetworkStatus", LOG_LEVEL_ALL);
104 // LogComponentEnable ("EndDeviceStatus", LOG_LEVEL_ALL);
105 LogComponentEnable("AdrComponent", LOG_LEVEL_ALL);
106 // LogComponentEnable("ClassAEndDeviceLorawanMac", LOG_LEVEL_ALL);
107 // LogComponentEnable ("LogicalLoraChannelHelper", LOG_LEVEL_ALL);
108 // LogComponentEnable ("MacCommand", LOG_LEVEL_ALL);
109 // LogComponentEnable ("AdrExploraSf", LOG_LEVEL_ALL);
110 // LogComponentEnable ("AdrExploraAt", LOG_LEVEL_ALL);
111 // LogComponentEnable ("EndDeviceLorawanMac", LOG_LEVEL_ALL);
115
116 // Set the end devices to allow data rate control (i.e. adaptive data rate) from the network
117 // server
118 Config::SetDefault("ns3::EndDeviceLorawanMac::ADR", BooleanValue(true));
119
120 // Create a simple wireless channel
121 ///////////////////////////////////
122
124 loss->SetPathLossExponent(3.76);
125 loss->SetReference(1, 7.7);
126
128 x->SetAttribute("Min", DoubleValue(0.0));
129 x->SetAttribute("Max", DoubleValue(maxRandomLossDb));
130
132 randomLoss->SetAttribute("Variable", PointerValue(x));
133
134 loss->SetNext(randomLoss);
135
137
139
140 // Helpers
141 //////////
142
143 // End device mobility
144 MobilityHelper mobilityEd;
145 MobilityHelper mobilityGw;
146 mobilityEd.SetPositionAllocator("ns3::RandomRectanglePositionAllocator",
147 "X",
149 "Min",
150 DoubleValue(-sideLengthMeters),
151 "Max",
152 DoubleValue(sideLengthMeters))),
153 "Y",
155 "Min",
156 DoubleValue(-sideLengthMeters),
157 "Max",
158 DoubleValue(sideLengthMeters))));
159
160 // // Gateway mobility
161 // Ptr<ListPositionAllocator> positionAllocGw = CreateObject<ListPositionAllocator> ();
162 // positionAllocGw->Add (Vector (0.0, 0.0, 15.0));
163 // positionAllocGw->Add (Vector (-5000.0, -5000.0, 15.0));
164 // positionAllocGw->Add (Vector (-5000.0, 5000.0, 15.0));
165 // positionAllocGw->Add (Vector (5000.0, -5000.0, 15.0));
166 // positionAllocGw->Add (Vector (5000.0, 5000.0, 15.0));
167 // mobilityGw.SetPositionAllocator (positionAllocGw);
168 // mobilityGw.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
169 Ptr<HexGridPositionAllocator> hexAllocator =
170 CreateObject<HexGridPositionAllocator>(gatewayDistanceMeters / 2);
171 mobilityGw.SetPositionAllocator(hexAllocator);
172 mobilityGw.SetMobilityModel("ns3::ConstantPositionMobilityModel");
173
174 // Create the LoraPhyHelper
175 LoraPhyHelper phyHelper = LoraPhyHelper();
176 phyHelper.SetChannel(channel);
177
178 // Create the LorawanMacHelper
180
181 // Create the LoraHelper
182 LoraHelper helper = LoraHelper();
183 helper.EnablePacketTracking();
184
185 ////////////////
186 // Create gateways //
187 ////////////////
188
189 NodeContainer gateways;
190 gateways.Create(nGateways);
191 mobilityGw.Install(gateways);
192
193 // Create the LoraNetDevices of the gateways
196 helper.Install(phyHelper, macHelper, gateways);
197
198 // Create end devices
199 /////////////
200
201 NodeContainer endDevices;
202 endDevices.Create(nDevices);
203
204 // Install mobility model on fixed nodes
205 mobilityEd.SetMobilityModel("ns3::ConstantPositionMobilityModel");
206 int fixedPositionNodes = double(nDevices) * (1 - mobileNodeProbability);
207 for (int i = 0; i < fixedPositionNodes; ++i)
208 {
209 mobilityEd.Install(endDevices.Get(i));
210 }
211 // Install mobility model on mobile nodes
212 mobilityEd.SetMobilityModel(
213 "ns3::RandomWalk2dMobilityModel",
214 "Bounds",
216 Rectangle(-sideLengthMeters, sideLengthMeters, -sideLengthMeters, sideLengthMeters)),
217 "Distance",
218 DoubleValue(1000),
219 "Speed",
221 "Min",
222 DoubleValue(minSpeedMetersPerSecond),
223 "Max",
224 DoubleValue(maxSpeedMetersPerSecond))));
225 for (int i = fixedPositionNodes; i < (int)endDevices.GetN(); ++i)
226 {
227 mobilityEd.Install(endDevices.Get(i));
228 }
229
230 // Create a LoraDeviceAddressGenerator
231 uint8_t nwkId = 54;
232 uint32_t nwkAddr = 1864;
235
236 // Create the LoraNetDevices of the end devices
239 macHelper.SetAddressGenerator(addrGen);
241 helper.Install(phyHelper, macHelper, endDevices);
242
243 // Install applications in end devices
244 int appPeriodSeconds = 1200; // One packet every 20 minutes
247 ApplicationContainer appContainer = appHelper.Install(endDevices);
248
249 // Do not set spreading factors up: we will wait for the network server to do this
250 if (initializeSF)
251 {
252 LorawanMacHelper::SetSpreadingFactorsUp(endDevices, gateways, channel);
253 }
254
255 ////////////
256 // Create network server
257 ////////////
258
259 Ptr<Node> networkServer = CreateObject<Node>();
260
261 // PointToPoint links between gateways and server
263 p2p.SetDeviceAttribute("DataRate", StringValue("5Mbps"));
264 p2p.SetChannelAttribute("Delay", StringValue("2ms"));
265 // Store network server app registration details for later
266 P2PGwRegistration_t gwRegistration;
267 for (auto gw = gateways.Begin(); gw != gateways.End(); ++gw)
268 {
269 auto container = p2p.Install(networkServer, *gw);
270 auto serverP2PNetDev = DynamicCast<PointToPointNetDevice>(container.Get(0));
271 gwRegistration.emplace_back(serverP2PNetDev, *gw);
272 }
273
274 // Install the NetworkServer application on the network server
275 NetworkServerHelper networkServerHelper;
276 networkServerHelper.EnableAdr(adrEnabled);
277 networkServerHelper.SetAdr(adrType);
278 networkServerHelper.SetGatewaysP2P(gwRegistration);
279 networkServerHelper.SetEndDevices(endDevices);
280 networkServerHelper.Install(networkServer);
281
282 // Install the Forwarder application on the gateways
283 ForwarderHelper forwarderHelper;
284 forwarderHelper.Install(gateways);
285
286 // Connect our traces
288 "/NodeList/*/DeviceList/0/$ns3::LoraNetDevice/Mac/$ns3::EndDeviceLorawanMac/TxPower",
291 "/NodeList/*/DeviceList/0/$ns3::LoraNetDevice/Mac/$ns3::EndDeviceLorawanMac/DataRate",
293
294 // Activate printing of end device MAC parameters
295 Time stateSamplePeriod = Seconds(1200);
296 helper.EnablePeriodicDeviceStatusPrinting(endDevices,
297 gateways,
298 "nodeData.txt",
299 stateSamplePeriod);
300 helper.EnablePeriodicPhyPerformancePrinting(gateways, "phyPerformance.txt", stateSamplePeriod);
301 helper.EnablePeriodicGlobalPerformancePrinting("globalPerformance.txt", stateSamplePeriod);
302
303 LoraPacketTracker& tracker = helper.GetPacketTracker();
304
305 // Start simulation
306 Time simulationTime = Seconds(1200 * nPeriodsOf20Minutes);
307 Simulator::Stop(simulationTime);
310
311 std::cout << tracker.CountMacPacketsGlobally(Seconds(1200 * (nPeriodsOf20Minutes - 2)),
312 Seconds(1200 * (nPeriodsOf20Minutes - 1)))
313 << std::endl;
314
315 return 0;
316}
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:70
a 2d rectangle
Definition rectangle.h:24
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:125
static void Run()
Run the simulation.
Definition simulator.cc:161
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:169
Hold variables of type string.
Definition string.h:45
Simulation virtual time values and global simulation resolution.
Definition nstime.h:95
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:34
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.
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:690
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:194
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:260
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:627
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:1273
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:279
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:605
@ LOG_LEVEL_ALL
Print everything.
Definition log.h:108
@ LOG_PREFIX_FUNC
Prefix all trace prints with function.
Definition log.h:110
@ LOG_PREFIX_TIME
Prefix all trace prints with simulation time.
Definition log.h:111
@ LOG_PREFIX_NODE
Prefix all trace prints with simulation node.
Definition log.h:112
void LogComponentEnableAll(LogLevel level)
Enable the logging output for all registered log components.
Definition log.cc:297
channel
Definition third.py:77
bool verbose