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("EDDRAdaptation", "ns3::EndDeviceLorawanMac::EnableEDDataRateAdaptation");
89 cmd.AddValue("ChangeTransmissionPower", "ns3::AdrComponent::ChangeTransmissionPower");
90 cmd.AddValue("AdrEnabled", "Whether to enable Adaptive Data Rate (ADR)", adrEnabled);
91 cmd.AddValue("nDevices", "Number of devices to simulate", nDevices);
92 cmd.AddValue("PeriodsToSimulate", "Number of periods (20m) to simulate", nPeriodsOf20Minutes);
93 cmd.AddValue("MobileNodeProbability",
94 "Probability of a node being a mobile node",
95 mobileNodeProbability);
96 cmd.AddValue("sideLength",
97 "Length (m) of the side of the rectangle nodes will be placed in",
98 sideLengthMeters);
99 cmd.AddValue("maxRandomLoss",
100 "Maximum amount (dB) of the random loss component",
101 maxRandomLossDB);
102 cmd.AddValue("gatewayDistance", "Distance (m) between gateways", gatewayDistanceMeters);
103 cmd.AddValue("initializeSF", "Whether to initialize the SFs", initializeSF);
104 cmd.AddValue("MinSpeed", "Minimum speed (m/s) for mobile devices", minSpeedMetersPerSecond);
105 cmd.AddValue("MaxSpeed", "Maximum speed (m/s) for mobile devices", maxSpeedMetersPerSecond);
106 cmd.AddValue("MaxTransmissions", "ns3::EndDeviceLorawanMac::MaxTransmissions");
107 cmd.Parse(argc, argv);
108
109 int gatewayRings = 2 + (std::sqrt(2) * sideLengthMeters) / (gatewayDistanceMeters);
110 int nGateways = 3 * gatewayRings * gatewayRings - 3 * gatewayRings + 1;
111
112 // Logging
113 //////////
114
115 LogComponentEnable("AdrExample", LOG_LEVEL_ALL);
116 // LogComponentEnable ("LoraPacketTracker", LOG_LEVEL_ALL);
117 // LogComponentEnable ("NetworkServer", LOG_LEVEL_ALL);
118 // LogComponentEnable ("NetworkController", LOG_LEVEL_ALL);
119 // LogComponentEnable ("NetworkScheduler", LOG_LEVEL_ALL);
120 // LogComponentEnable ("NetworkStatus", LOG_LEVEL_ALL);
121 // LogComponentEnable ("EndDeviceStatus", LOG_LEVEL_ALL);
122 LogComponentEnable("AdrComponent", LOG_LEVEL_ALL);
123 // LogComponentEnable("ClassAEndDeviceLorawanMac", LOG_LEVEL_ALL);
124 // LogComponentEnable ("LogicalLoraChannelHelper", LOG_LEVEL_ALL);
125 // LogComponentEnable ("MacCommand", LOG_LEVEL_ALL);
126 // LogComponentEnable ("AdrExploraSf", LOG_LEVEL_ALL);
127 // LogComponentEnable ("AdrExploraAt", LOG_LEVEL_ALL);
128 // LogComponentEnable ("EndDeviceLorawanMac", LOG_LEVEL_ALL);
132
133 // Set the end devices to allow data rate control (i.e. adaptive data rate) from the network
134 // server
135 Config::SetDefault("ns3::EndDeviceLorawanMac::DRControl", BooleanValue(true));
136
137 // Create a simple wireless channel
138 ///////////////////////////////////
139
141 loss->SetPathLossExponent(3.76);
142 loss->SetReference(1, 7.7);
143
145 x->SetAttribute("Min", DoubleValue(0.0));
146 x->SetAttribute("Max", DoubleValue(maxRandomLossDB));
147
149 randomLoss->SetAttribute("Variable", PointerValue(x));
150
151 loss->SetNext(randomLoss);
152
154
156
157 // Helpers
158 //////////
159
160 // End device mobility
161 MobilityHelper mobilityEd;
162 MobilityHelper mobilityGw;
163 mobilityEd.SetPositionAllocator("ns3::RandomRectanglePositionAllocator",
164 "X",
166 "Min",
167 DoubleValue(-sideLengthMeters),
168 "Max",
169 DoubleValue(sideLengthMeters))),
170 "Y",
172 "Min",
173 DoubleValue(-sideLengthMeters),
174 "Max",
175 DoubleValue(sideLengthMeters))));
176
177 // // Gateway mobility
178 // Ptr<ListPositionAllocator> positionAllocGw = CreateObject<ListPositionAllocator> ();
179 // positionAllocGw->Add (Vector (0.0, 0.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 // positionAllocGw->Add (Vector (5000.0, 5000.0, 15.0));
184 // mobilityGw.SetPositionAllocator (positionAllocGw);
185 // mobilityGw.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
186 Ptr<HexGridPositionAllocator> hexAllocator =
187 CreateObject<HexGridPositionAllocator>(gatewayDistanceMeters / 2);
188 mobilityGw.SetPositionAllocator(hexAllocator);
189 mobilityGw.SetMobilityModel("ns3::ConstantPositionMobilityModel");
190
191 // Create the LoraPhyHelper
192 LoraPhyHelper phyHelper = LoraPhyHelper();
193 phyHelper.SetChannel(channel);
194
195 // Create the LorawanMacHelper
197
198 // Create the LoraHelper
199 LoraHelper helper = LoraHelper();
200 helper.EnablePacketTracking();
201
202 ////////////////
203 // Create gateways //
204 ////////////////
205
206 NodeContainer gateways;
207 gateways.Create(nGateways);
208 mobilityGw.Install(gateways);
209
210 // Create the LoraNetDevices of the gateways
213 helper.Install(phyHelper, macHelper, gateways);
214
215 // Create end devices
216 /////////////
217
218 NodeContainer endDevices;
219 endDevices.Create(nDevices);
220
221 // Install mobility model on fixed nodes
222 mobilityEd.SetMobilityModel("ns3::ConstantPositionMobilityModel");
223 int fixedPositionNodes = double(nDevices) * (1 - mobileNodeProbability);
224 for (int i = 0; i < fixedPositionNodes; ++i)
225 {
226 mobilityEd.Install(endDevices.Get(i));
227 }
228 // Install mobility model on mobile nodes
229 mobilityEd.SetMobilityModel(
230 "ns3::RandomWalk2dMobilityModel",
231 "Bounds",
233 Rectangle(-sideLengthMeters, sideLengthMeters, -sideLengthMeters, sideLengthMeters)),
234 "Distance",
235 DoubleValue(1000),
236 "Speed",
238 "Min",
239 DoubleValue(minSpeedMetersPerSecond),
240 "Max",
241 DoubleValue(maxSpeedMetersPerSecond))));
242 for (int i = fixedPositionNodes; i < (int)endDevices.GetN(); ++i)
243 {
244 mobilityEd.Install(endDevices.Get(i));
245 }
246
247 // Create a LoraDeviceAddressGenerator
248 uint8_t nwkId = 54;
249 uint32_t nwkAddr = 1864;
252
253 // Create the LoraNetDevices of the end devices
256 macHelper.SetAddressGenerator(addrGen);
258 helper.Install(phyHelper, macHelper, endDevices);
259
260 // Install applications in end devices
261 int appPeriodSeconds = 1200; // One packet every 20 minutes
264 ApplicationContainer appContainer = appHelper.Install(endDevices);
265
266 // Do not set spreading factors up: we will wait for the network server to do this
267 if (initializeSF)
268 {
269 LorawanMacHelper::SetSpreadingFactorsUp(endDevices, gateways, channel);
270 }
271
272 ////////////
273 // Create network server
274 ////////////
275
276 Ptr<Node> networkServer = CreateObject<Node>();
277
278 // PointToPoint links between gateways and server
280 p2p.SetDeviceAttribute("DataRate", StringValue("5Mbps"));
281 p2p.SetChannelAttribute("Delay", StringValue("2ms"));
282 // Store network server app registration details for later
283 P2PGwRegistration_t gwRegistration;
284 for (auto gw = gateways.Begin(); gw != gateways.End(); ++gw)
285 {
286 auto container = p2p.Install(networkServer, *gw);
287 auto serverP2PNetDev = DynamicCast<PointToPointNetDevice>(container.Get(0));
288 gwRegistration.emplace_back(serverP2PNetDev, *gw);
289 }
290
291 // Install the NetworkServer application on the network server
292 NetworkServerHelper networkServerHelper;
293 networkServerHelper.EnableAdr(adrEnabled);
294 networkServerHelper.SetAdr(adrType);
295 networkServerHelper.SetGatewaysP2P(gwRegistration);
296 networkServerHelper.SetEndDevices(endDevices);
297 networkServerHelper.Install(networkServer);
298
299 // Install the Forwarder application on the gateways
300 ForwarderHelper forwarderHelper;
301 forwarderHelper.Install(gateways);
302
303 // Connect our traces
305 "/NodeList/*/DeviceList/0/$ns3::LoraNetDevice/Mac/$ns3::EndDeviceLorawanMac/TxPower",
308 "/NodeList/*/DeviceList/0/$ns3::LoraNetDevice/Mac/$ns3::EndDeviceLorawanMac/DataRate",
310
311 // Activate printing of end device MAC parameters
312 Time stateSamplePeriod = Seconds(1200);
313 helper.EnablePeriodicDeviceStatusPrinting(endDevices,
314 gateways,
315 "nodeData.txt",
316 stateSamplePeriod);
317 helper.EnablePeriodicPhyPerformancePrinting(gateways, "phyPerformance.txt", stateSamplePeriod);
318 helper.EnablePeriodicGlobalPerformancePrinting("globalPerformance.txt", stateSamplePeriod);
319
320 LoraPacketTracker& tracker = helper.GetPacketTracker();
321
322 // Start simulation
323 Time simulationTime = Seconds(1200 * nPeriodsOf20Minutes);
324 Simulator::Stop(simulationTime);
327
328 std::cout << tracker.CountMacPacketsGlobally(Seconds(1200 * (nPeriodsOf20Minutes - 2)),
329 Seconds(1200 * (nPeriodsOf20Minutes - 1)))
330 << std::endl;
331
332 return 0;
333}
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.
Smart pointer class similar to boost::intrusive_ptr.
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:94
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...
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:883
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition config.cc:943
#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:1308
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
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:580
@ 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:309
channel
Definition third.py:77
bool verbose
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.