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 * 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 program creates a simple network which uses an Adaptive Data Rate (ADR) algorithm to set up
22 * the Spreading Factors of the devices in the Network.
23 */
24
25#include "ns3/command-line.h"
26#include "ns3/config.h"
27#include "ns3/core-module.h"
28#include "ns3/forwarder-helper.h"
29#include "ns3/gateway-lora-phy.h"
30#include "ns3/hex-grid-position-allocator.h"
31#include "ns3/log.h"
32#include "ns3/lora-channel.h"
33#include "ns3/lora-device-address-generator.h"
34#include "ns3/lora-helper.h"
35#include "ns3/lora-phy-helper.h"
36#include "ns3/lorawan-mac-helper.h"
37#include "ns3/mobility-helper.h"
38#include "ns3/network-module.h"
39#include "ns3/network-server-helper.h"
40#include "ns3/periodic-sender-helper.h"
41#include "ns3/periodic-sender.h"
42#include "ns3/point-to-point-module.h"
43#include "ns3/random-variable-stream.h"
44#include "ns3/rectangle.h"
45#include "ns3/string.h"
46
47using namespace ns3;
48using namespace lorawan;
49
50NS_LOG_COMPONENT_DEFINE("AdrExample");
51
52/**
53 * Record a change in the data rate setting on an end device.
54 *
55 * \param oldDr The previous data rate value.
56 * \param newDr The updated data rate value.
57 */
58void
59OnDataRateChange(uint8_t oldDr, uint8_t newDr)
60{
61 NS_LOG_DEBUG("DR" << unsigned(oldDr) << " -> DR" << unsigned(newDr));
62}
63
64/**
65 * Record a change in the transmission power setting on an end device.
66 *
67 * \param oldTxPower The previous transmission power value.
68 * \param newTxPower The updated transmission power value.
69 */
70void
71OnTxPowerChange(double oldTxPower, double newTxPower)
72{
73 NS_LOG_DEBUG(oldTxPower << " dBm -> " << newTxPower << " dBm");
74}
75
76int
77main(int argc, char* argv[])
78{
79 bool verbose = false;
80 bool adrEnabled = true;
81 bool initializeSF = false;
82 int nDevices = 400;
83 int nPeriodsOf20Minutes = 20;
84 double mobileNodeProbability = 0;
85 double sideLengthMeters = 10000;
86 int gatewayDistanceMeters = 5000;
87 double maxRandomLossDB = 10;
88 double minSpeedMetersPerSecond = 2;
89 double maxSpeedMetersPerSecond = 16;
90 std::string adrType = "ns3::AdrComponent";
91
92 CommandLine cmd(__FILE__);
93 cmd.AddValue("verbose", "Whether to print output or not", verbose);
94 cmd.AddValue("MultipleGwCombiningMethod", "ns3::AdrComponent::MultipleGwCombiningMethod");
95 cmd.AddValue("MultiplePacketsCombiningMethod",
96 "ns3::AdrComponent::MultiplePacketsCombiningMethod");
97 cmd.AddValue("HistoryRange", "ns3::AdrComponent::HistoryRange");
98 cmd.AddValue("MType", "ns3::EndDeviceLorawanMac::MType");
99 cmd.AddValue("EDDRAdaptation", "ns3::EndDeviceLorawanMac::EnableEDDataRateAdaptation");
100 cmd.AddValue("ChangeTransmissionPower", "ns3::AdrComponent::ChangeTransmissionPower");
101 cmd.AddValue("AdrEnabled", "Whether to enable Adaptive Data Rate (ADR)", adrEnabled);
102 cmd.AddValue("nDevices", "Number of devices to simulate", nDevices);
103 cmd.AddValue("PeriodsToSimulate", "Number of periods (20m) to simulate", nPeriodsOf20Minutes);
104 cmd.AddValue("MobileNodeProbability",
105 "Probability of a node being a mobile node",
106 mobileNodeProbability);
107 cmd.AddValue("sideLength",
108 "Length (m) of the side of the rectangle nodes will be placed in",
109 sideLengthMeters);
110 cmd.AddValue("maxRandomLoss",
111 "Maximum amount (dB) of the random loss component",
112 maxRandomLossDB);
113 cmd.AddValue("gatewayDistance", "Distance (m) between gateways", gatewayDistanceMeters);
114 cmd.AddValue("initializeSF", "Whether to initialize the SFs", initializeSF);
115 cmd.AddValue("MinSpeed", "Minimum speed (m/s) for mobile devices", minSpeedMetersPerSecond);
116 cmd.AddValue("MaxSpeed", "Maximum speed (m/s) for mobile devices", maxSpeedMetersPerSecond);
117 cmd.AddValue("MaxTransmissions", "ns3::EndDeviceLorawanMac::MaxTransmissions");
118 cmd.Parse(argc, argv);
119
120 int gatewayRings = 2 + (std::sqrt(2) * sideLengthMeters) / (gatewayDistanceMeters);
121 int nGateways = 3 * gatewayRings * gatewayRings - 3 * gatewayRings + 1;
122
123 // Logging
124 //////////
125
126 LogComponentEnable("AdrExample", LOG_LEVEL_ALL);
127 // LogComponentEnable ("LoraPacketTracker", LOG_LEVEL_ALL);
128 // LogComponentEnable ("NetworkServer", LOG_LEVEL_ALL);
129 // LogComponentEnable ("NetworkController", LOG_LEVEL_ALL);
130 // LogComponentEnable ("NetworkScheduler", LOG_LEVEL_ALL);
131 // LogComponentEnable ("NetworkStatus", LOG_LEVEL_ALL);
132 // LogComponentEnable ("EndDeviceStatus", LOG_LEVEL_ALL);
133 LogComponentEnable("AdrComponent", LOG_LEVEL_ALL);
134 // LogComponentEnable("ClassAEndDeviceLorawanMac", LOG_LEVEL_ALL);
135 // LogComponentEnable ("LogicalLoraChannelHelper", LOG_LEVEL_ALL);
136 // LogComponentEnable ("MacCommand", LOG_LEVEL_ALL);
137 // LogComponentEnable ("AdrExploraSf", LOG_LEVEL_ALL);
138 // LogComponentEnable ("AdrExploraAt", LOG_LEVEL_ALL);
139 // LogComponentEnable ("EndDeviceLorawanMac", LOG_LEVEL_ALL);
143
144 // Set the end devices to allow data rate control (i.e. adaptive data rate) from the network
145 // server
146 Config::SetDefault("ns3::EndDeviceLorawanMac::DRControl", BooleanValue(true));
147
148 // Create a simple wireless channel
149 ///////////////////////////////////
150
151 Ptr<LogDistancePropagationLossModel> loss = CreateObject<LogDistancePropagationLossModel>();
152 loss->SetPathLossExponent(3.76);
153 loss->SetReference(1, 7.7);
154
155 Ptr<UniformRandomVariable> x = CreateObject<UniformRandomVariable>();
156 x->SetAttribute("Min", DoubleValue(0.0));
157 x->SetAttribute("Max", DoubleValue(maxRandomLossDB));
158
159 Ptr<RandomPropagationLossModel> randomLoss = CreateObject<RandomPropagationLossModel>();
160 randomLoss->SetAttribute("Variable", PointerValue(x));
161
162 loss->SetNext(randomLoss);
163
164 Ptr<PropagationDelayModel> delay = CreateObject<ConstantSpeedPropagationDelayModel>();
165
166 Ptr<LoraChannel> channel = CreateObject<LoraChannel>(loss, delay);
167
168 // Helpers
169 //////////
170
171 // End device mobility
172 MobilityHelper mobilityEd;
173 MobilityHelper mobilityGw;
174 mobilityEd.SetPositionAllocator("ns3::RandomRectanglePositionAllocator",
175 "X",
176 PointerValue(CreateObjectWithAttributes<UniformRandomVariable>(
177 "Min",
178 DoubleValue(-sideLengthMeters),
179 "Max",
180 DoubleValue(sideLengthMeters))),
181 "Y",
182 PointerValue(CreateObjectWithAttributes<UniformRandomVariable>(
183 "Min",
184 DoubleValue(-sideLengthMeters),
185 "Max",
186 DoubleValue(sideLengthMeters))));
187
188 // // Gateway mobility
189 // Ptr<ListPositionAllocator> positionAllocGw = CreateObject<ListPositionAllocator> ();
190 // positionAllocGw->Add (Vector (0.0, 0.0, 15.0));
191 // positionAllocGw->Add (Vector (-5000.0, -5000.0, 15.0));
192 // positionAllocGw->Add (Vector (-5000.0, 5000.0, 15.0));
193 // positionAllocGw->Add (Vector (5000.0, -5000.0, 15.0));
194 // positionAllocGw->Add (Vector (5000.0, 5000.0, 15.0));
195 // mobilityGw.SetPositionAllocator (positionAllocGw);
196 // mobilityGw.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
197 Ptr<HexGridPositionAllocator> hexAllocator =
198 CreateObject<HexGridPositionAllocator>(gatewayDistanceMeters / 2);
199 mobilityGw.SetPositionAllocator(hexAllocator);
200 mobilityGw.SetMobilityModel("ns3::ConstantPositionMobilityModel");
201
202 // Create the LoraPhyHelper
203 LoraPhyHelper phyHelper = LoraPhyHelper();
204 phyHelper.SetChannel(channel);
205
206 // Create the LorawanMacHelper
208
209 // Create the LoraHelper
210 LoraHelper helper = LoraHelper();
211 helper.EnablePacketTracking();
212
213 ////////////////
214 // Create gateways //
215 ////////////////
216
217 NodeContainer gateways;
218 gateways.Create(nGateways);
219 mobilityGw.Install(gateways);
220
221 // Create the LoraNetDevices of the gateways
224 helper.Install(phyHelper, macHelper, gateways);
225
226 // Create end devices
227 /////////////
228
229 NodeContainer endDevices;
230 endDevices.Create(nDevices);
231
232 // Install mobility model on fixed nodes
233 mobilityEd.SetMobilityModel("ns3::ConstantPositionMobilityModel");
234 int fixedPositionNodes = double(nDevices) * (1 - mobileNodeProbability);
235 for (int i = 0; i < fixedPositionNodes; ++i)
236 {
237 mobilityEd.Install(endDevices.Get(i));
238 }
239 // Install mobility model on mobile nodes
240 mobilityEd.SetMobilityModel(
241 "ns3::RandomWalk2dMobilityModel",
242 "Bounds",
244 Rectangle(-sideLengthMeters, sideLengthMeters, -sideLengthMeters, sideLengthMeters)),
245 "Distance",
246 DoubleValue(1000),
247 "Speed",
248 PointerValue(CreateObjectWithAttributes<UniformRandomVariable>(
249 "Min",
250 DoubleValue(minSpeedMetersPerSecond),
251 "Max",
252 DoubleValue(maxSpeedMetersPerSecond))));
253 for (int i = fixedPositionNodes; i < (int)endDevices.GetN(); ++i)
254 {
255 mobilityEd.Install(endDevices.Get(i));
256 }
257
258 // Create a LoraDeviceAddressGenerator
259 uint8_t nwkId = 54;
260 uint32_t nwkAddr = 1864;
262 CreateObject<LoraDeviceAddressGenerator>(nwkId, nwkAddr);
263
264 // Create the LoraNetDevices of the end devices
267 macHelper.SetAddressGenerator(addrGen);
269 helper.Install(phyHelper, macHelper, endDevices);
270
271 // Install applications in end devices
272 int appPeriodSeconds = 1200; // One packet every 20 minutes
275 ApplicationContainer appContainer = appHelper.Install(endDevices);
276
277 // Do not set spreading factors up: we will wait for the network server to do this
278 if (initializeSF)
279 {
280 LorawanMacHelper::SetSpreadingFactorsUp(endDevices, gateways, channel);
281 }
282
283 ////////////
284 // Create network server
285 ////////////
286
287 Ptr<Node> networkServer = CreateObject<Node>();
288
289 // PointToPoint links between gateways and server
291 p2p.SetDeviceAttribute("DataRate", StringValue("5Mbps"));
292 p2p.SetChannelAttribute("Delay", StringValue("2ms"));
293 // Store network server app registration details for later
294 P2PGwRegistration_t gwRegistration;
295 for (auto gw = gateways.Begin(); gw != gateways.End(); ++gw)
296 {
297 auto container = p2p.Install(networkServer, *gw);
298 auto serverP2PNetDev = DynamicCast<PointToPointNetDevice>(container.Get(0));
299 gwRegistration.emplace_back(serverP2PNetDev, *gw);
300 }
301
302 // Install the NetworkServer application on the network server
303 NetworkServerHelper networkServerHelper;
304 networkServerHelper.EnableAdr(adrEnabled);
305 networkServerHelper.SetAdr(adrType);
306 networkServerHelper.SetGatewaysP2P(gwRegistration);
307 networkServerHelper.SetEndDevices(endDevices);
308 networkServerHelper.Install(networkServer);
309
310 // Install the Forwarder application on the gateways
311 ForwarderHelper forwarderHelper;
312 forwarderHelper.Install(gateways);
313
314 // Connect our traces
316 "/NodeList/*/DeviceList/0/$ns3::LoraNetDevice/Mac/$ns3::EndDeviceLorawanMac/TxPower",
319 "/NodeList/*/DeviceList/0/$ns3::LoraNetDevice/Mac/$ns3::EndDeviceLorawanMac/DataRate",
321
322 // Activate printing of end device MAC parameters
323 Time stateSamplePeriod = Seconds(1200);
324 helper.EnablePeriodicDeviceStatusPrinting(endDevices,
325 gateways,
326 "nodeData.txt",
327 stateSamplePeriod);
328 helper.EnablePeriodicPhyPerformancePrinting(gateways, "phyPerformance.txt", stateSamplePeriod);
329 helper.EnablePeriodicGlobalPerformancePrinting("globalPerformance.txt", stateSamplePeriod);
330
331 LoraPacketTracker& tracker = helper.GetPacketTracker();
332
333 // Start simulation
334 Time simulationTime = Seconds(1200 * nPeriodsOf20Minutes);
335 Simulator::Stop(simulationTime);
338
339 std::cout << tracker.CountMacPacketsGlobally(Seconds(1200 * (nPeriodsOf20Minutes - 2)),
340 Seconds(1200 * (nPeriodsOf20Minutes - 1)))
341 << std::endl;
342
343 return 0;
344}
holds a vector of ns3::Application pointers.
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.
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:48
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
a 2d rectangle
Definition: rectangle.h:35
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
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 EnablePeriodicDeviceStatusPrinting(NodeContainer endDevices, NodeContainer gateways, std::string filename, Time interval)
Periodically prints the status of devices in the network to a file.
Definition: lora-helper.cc:169
void EnablePeriodicPhyPerformancePrinting(NodeContainer gateways, std::string filename, Time interval)
Periodically prints PHY-level performance at every gateway in the container.
Definition: lora-helper.cc:236
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
void EnablePeriodicGlobalPerformancePrinting(std::string filename, Time interval)
Periodically print global performance as the total number of send and received packets.
Definition: lora-helper.cc:286
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.
Definition: adr-example.cc:59
void OnTxPowerChange(double oldTxPower, double newTxPower)
Record a change in the transmission power setting on an end device.
Definition: adr-example.cc:71
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:894
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition: config.cc:954
#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
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1319
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
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:700
@ LOG_LEVEL_ALL
Print everything.
Definition: log.h:116
@ LOG_PREFIX_FUNC
Prefix all trace prints with function.
Definition: log.h:118
@ LOG_PREFIX_TIME
Prefix all trace prints with simulation time.
Definition: log.h:119
@ LOG_PREFIX_NODE
Prefix all trace prints with simulation node.
Definition: log.h:120
void LogComponentEnableAll(LogLevel level)
Enable the logging output for all registered log components.
Definition: log.cc:320
ns cmd
Definition: second.py:40
ns channel
Definition: third.py:88
bool verbose