A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
aloha-throughput.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#include "ns3/building-allocator.h"
21#include "ns3/building-penetration-loss.h"
22#include "ns3/buildings-helper.h"
23#include "ns3/callback.h"
24#include "ns3/command-line.h"
25#include "ns3/constant-position-mobility-model.h"
26#include "ns3/correlated-shadowing-propagation-loss-model.h"
27#include "ns3/double.h"
28#include "ns3/end-device-lora-phy.h"
29#include "ns3/end-device-lorawan-mac.h"
30#include "ns3/forwarder-helper.h"
31#include "ns3/gateway-lora-phy.h"
32#include "ns3/gateway-lorawan-mac.h"
33#include "ns3/log.h"
34#include "ns3/lora-device-address.h"
35#include "ns3/lora-frame-header.h"
36#include "ns3/lora-helper.h"
37#include "ns3/lora-net-device.h"
38#include "ns3/lora-phy.h"
39#include "ns3/lorawan-mac-header.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("AlohaThroughput");
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 = 1000; //!< Radius (m) of the deployment
61double simulationTimeSeconds = 100; //!< 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
67/** Record received pkts by Data Rate (DR) [index 0 -> DR5, index 5 -> DR0]. */
68auto packetsSent = std::vector<int>(6, 0);
69/** Record received pkts by Data Rate (DR) [index 0 -> DR5, index 5 -> DR0]. */
70auto packetsReceived = std::vector<int>(6, 0);
71
72/**
73 * Record the beginning of a transmission by an end device.
74 *
75 * \param packet A pointer to the packet sent.
76 * \param senderNodeId Node id of the sender end device.
77 */
78void
80{
81 NS_LOG_FUNCTION(packet << senderNodeId);
82 LoraTag tag;
83 packet->PeekPacketTag(tag);
84 packetsSent.at(tag.GetSpreadingFactor() - 7)++;
85}
86
87/**
88 * Record the correct reception of a packet by a gateway.
89 *
90 * \param packet A pointer to the packet received.
91 * \param receiverNodeId Node id of the receiver gateway.
92 */
93void
95{
96 NS_LOG_FUNCTION(packet << receiverNodeId);
97 LoraTag tag;
98 packet->PeekPacketTag(tag);
99 packetsReceived.at(tag.GetSpreadingFactor() - 7)++;
100}
101
102int
103main(int argc, char* argv[])
104{
105 std::string interferenceMatrix = "aloha";
106
107 CommandLine cmd(__FILE__);
108 cmd.AddValue("nDevices", "Number of end devices to include in the simulation", nDevices);
109 cmd.AddValue("simulationTime", "Simulation Time (s)", simulationTimeSeconds);
110 cmd.AddValue("interferenceMatrix",
111 "Interference matrix to use [aloha, goursaud]",
112 interferenceMatrix);
113 cmd.AddValue("radius", "Radius (m) of the deployment", radiusMeters);
114 cmd.Parse(argc, argv);
115
117
118 // Set up logging
119 LogComponentEnable("AlohaThroughput", LOG_LEVEL_ALL);
120
121 // Make all devices use SF7 (i.e., DR5)
122 // Config::SetDefault ("ns3::EndDeviceLorawanMac::DataRate", UintegerValue (5));
123
124 if (interferenceMatrix == "aloha")
125 {
127 }
128 else if (interferenceMatrix == "goursaud")
129 {
131 }
132
133 /***********
134 * Setup *
135 ***********/
136
137 // Mobility
139 mobility.SetPositionAllocator("ns3::UniformDiscPositionAllocator",
140 "rho",
142 "X",
143 DoubleValue(0.0),
144 "Y",
145 DoubleValue(0.0));
146 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
147
148 /************************
149 * Create the channel *
150 ************************/
151
152 // Create the lora channel object
153 Ptr<LogDistancePropagationLossModel> loss = CreateObject<LogDistancePropagationLossModel>();
154 loss->SetPathLossExponent(3.76);
155 loss->SetReference(1, 7.7);
156
158 {
159 // Create the correlated shadowing component
161 CreateObject<CorrelatedShadowingPropagationLossModel>();
162
163 // Aggregate shadowing to the logdistance loss
164 loss->SetNext(shadowing);
165
166 // Add the effect to the channel propagation loss
167 Ptr<BuildingPenetrationLoss> buildingLoss = CreateObject<BuildingPenetrationLoss>();
168
169 shadowing->SetNext(buildingLoss);
170 }
171
172 Ptr<PropagationDelayModel> delay = CreateObject<ConstantSpeedPropagationDelayModel>();
173
174 Ptr<LoraChannel> channel = CreateObject<LoraChannel>(loss, delay);
175
176 /************************
177 * Create the helpers *
178 ************************/
179
180 // Create the LoraPhyHelper
181 LoraPhyHelper phyHelper = LoraPhyHelper();
182 phyHelper.SetChannel(channel);
183
184 // Create the LorawanMacHelper
187
188 // Create the LoraHelper
189 LoraHelper helper = LoraHelper();
190 helper.EnablePacketTracking(); // Output filename
191
192 // Create the NetworkServerHelper
194
195 // Create the ForwarderHelper
196 ForwarderHelper forHelper = ForwarderHelper();
197
198 /************************
199 * Create End Devices *
200 ************************/
201
202 // Create a set of nodes
203 NodeContainer endDevices;
204 endDevices.Create(nDevices);
205
206 // Assign a mobility model to each node
207 mobility.Install(endDevices);
208
209 // Make it so that nodes are at a certain height > 0
210 for (auto j = endDevices.Begin(); j != endDevices.End(); ++j)
211 {
212 Ptr<MobilityModel> mobility = (*j)->GetObject<MobilityModel>();
213 Vector position = mobility->GetPosition();
214 position.z = 1.2;
215 mobility->SetPosition(position);
216 }
217
218 // Create the LoraNetDevices of the end devices
219 uint8_t nwkId = 54;
220 uint32_t nwkAddr = 1864;
222 CreateObject<LoraDeviceAddressGenerator>(nwkId, nwkAddr);
223
224 // Create the LoraNetDevices of the end devices
225 macHelper.SetAddressGenerator(addrGen);
228 helper.Install(phyHelper, macHelper, endDevices);
229
230 // Now end devices are connected to the channel
231
232 // Connect trace sources
233 for (auto j = endDevices.Begin(); j != endDevices.End(); ++j)
234 {
235 Ptr<Node> node = *j;
236 Ptr<LoraNetDevice> loraNetDevice = node->GetDevice(0)->GetObject<LoraNetDevice>();
237 Ptr<LoraPhy> phy = loraNetDevice->GetPhy();
238 }
239
240 /*********************
241 * Create Gateways *
242 *********************/
243
244 // Create the gateway nodes (allocate them uniformly on the disc)
245 NodeContainer gateways;
246 gateways.Create(nGateways);
247
248 Ptr<ListPositionAllocator> allocator = CreateObject<ListPositionAllocator>();
249 // Make it so that nodes are at a certain height > 0
250 allocator->Add(Vector(0.0, 0.0, 15.0));
251 mobility.SetPositionAllocator(allocator);
252 mobility.Install(gateways);
253
254 // Create a netdevice for each gateway
257 helper.Install(phyHelper, macHelper, gateways);
258
259 NS_LOG_DEBUG("Completed configuration");
260
261 /*********************************************
262 * Install applications on the end devices *
263 *********************************************/
264
265 Time appStopTime = Seconds(simulationTimeSeconds);
266 int packetSize = 50;
269 appHelper.SetPacketSize(packetSize);
270 ApplicationContainer appContainer = appHelper.Install(endDevices);
271
272 appContainer.Start(Seconds(0));
273 appContainer.Stop(appStopTime);
274
275 std::ofstream outputFile;
276 // Delete contents of the file as it is opened
277 outputFile.open("durations.txt", std::ofstream::out | std::ofstream::trunc);
278 for (uint8_t sf = 7; sf <= 12; sf++)
279 {
280 LoraTxParameters txParams;
281 txParams.sf = sf;
282 txParams.headerDisabled = false;
283 txParams.codingRate = 1;
284 txParams.bandwidthHz = 125000;
285 txParams.nPreamble = 8;
286 txParams.crcEnabled = true;
288 Ptr<Packet> pkt = Create<Packet>(packetSize);
289
290 LoraFrameHeader frameHdr = LoraFrameHeader();
291 frameHdr.SetAsUplink();
292 frameHdr.SetFPort(1);
293 frameHdr.SetAddress(LoraDeviceAddress());
294 frameHdr.SetAdr(false);
295 frameHdr.SetAdrAckReq(false);
296 frameHdr.SetFCnt(0);
297 pkt->AddHeader(frameHdr);
298
301 macHdr.SetMajor(1);
302 pkt->AddHeader(macHdr);
303
304 outputFile << LoraPhy::GetOnAirTime(pkt, txParams).GetMicroSeconds() << " ";
305 }
306 outputFile.close();
307
308 /**************************
309 * Create network server *
310 ***************************/
311
312 // Create the network server node
313 Ptr<Node> networkServer = CreateObject<Node>();
314
315 // PointToPoint links between gateways and server
317 p2p.SetDeviceAttribute("DataRate", StringValue("5Mbps"));
318 p2p.SetChannelAttribute("Delay", StringValue("2ms"));
319 // Store network server app registration details for later
320 P2PGwRegistration_t gwRegistration;
321 for (auto gw = gateways.Begin(); gw != gateways.End(); ++gw)
322 {
323 auto container = p2p.Install(networkServer, *gw);
324 auto serverP2PNetDev = DynamicCast<PointToPointNetDevice>(container.Get(0));
325 gwRegistration.emplace_back(serverP2PNetDev, *gw);
326 }
327
328 // Create a network server for the network
329 nsHelper.SetGatewaysP2P(gwRegistration);
330 nsHelper.SetEndDevices(endDevices);
331 nsHelper.Install(networkServer);
332
333 // Create a forwarder for each gateway
334 forHelper.Install(gateways);
335
336 // Install trace sources
337 for (auto node = gateways.Begin(); node != gateways.End(); node++)
338 {
339 (*node)->GetDevice(0)->GetObject<LoraNetDevice>()->GetPhy()->TraceConnectWithoutContext(
340 "ReceivedPacket",
342 }
343
344 // Install trace sources
345 for (auto node = endDevices.Begin(); node != endDevices.End(); node++)
346 {
347 (*node)->GetDevice(0)->GetObject<LoraNetDevice>()->GetPhy()->TraceConnectWithoutContext(
348 "StartSending",
350 }
351
352 LorawanMacHelper::SetSpreadingFactorsUp(endDevices, gateways, channel);
353
354 ////////////////
355 // Simulation //
356 ////////////////
357
358 Simulator::Stop(appStopTime + Hours(1));
359
360 NS_LOG_INFO("Running simulation...");
362
364
365 /////////////////////////////
366 // Print results to stdout //
367 /////////////////////////////
368 NS_LOG_INFO("Computing performance metrics...");
369
370 for (int i = 0; i < 6; i++)
371 {
372 std::cout << packetsSent.at(i) << " " << packetsReceived.at(i) << std::endl;
373 }
374
375 return 0;
376}
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.
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.
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:322
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
int64_t GetMicroSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:413
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...
This class represents the device address of a LoraWAN end device.
This class represents the Frame header (FHDR) used in a LoraWAN network.
void SetFCnt(uint16_t fCnt)
Set the FCnt value.
void SetAdr(bool adr)
Set the value of the ADR bit field.
void SetAddress(LoraDeviceAddress address)
Set the address.
void SetAsUplink()
State that this is an uplink message.
void SetAdrAckReq(bool adrAckReq)
Set the value of the ADRACKReq bit field.
void SetFPort(uint8_t fPort)
Set the FPort value.
Helps to create LoraNetDevice objects.
Definition: lora-helper.h:48
void EnablePacketTracking()
Enable tracking of packets via trace sources.
Definition: lora-helper.cc:145
virtual NetDeviceContainer Install(const LoraPhyHelper &phyHelper, const LorawanMacHelper &macHelper, NodeContainer c) const
Install LoraNetDevices on a list of nodes.
Definition: lora-helper.cc:44
static CollisionMatrix collisionMatrix
Collision matrix type set by the constructor.
Hold together all LoRa related objects.
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.
static Time GetOnAirTime(Ptr< Packet > packet, LoraTxParameters txParams)
Compute the time that a packet with certain characteristics will take to be transmitted.
Definition: lora-phy.cc:167
static Time GetTSym(LoraTxParameters txParams)
Compute the symbol time from spreading factor and bandwidth.
Definition: lora-phy.cc:161
Tag used to save various data about a packet, like its Spreading Factor and data about interference.
Definition: lora-tag.h:37
uint8_t GetSpreadingFactor() const
Read which Spreading Factor this packet was transmitted with.
Definition: lora-tag.cc:94
This class represents the Mac header of a LoRaWAN packet.
void SetMajor(uint8_t major)
Set the major version of this header.
void SetMType(enum MType mtype)
Set the message type.
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 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...
auto packetsReceived
Record received pkts by Data Rate (DR) [index 0 -> DR5, index 5 -> DR0].
void OnPacketReceptionCallback(Ptr< const Packet > packet, uint32_t receiverNodeId)
Record the correct reception of a packet by a gateway.
double simulationTimeSeconds
Scenario duration (s) in simulated time.
auto packetsSent
Record received pkts by Data Rate (DR) [index 0 -> DR5, index 5 -> DR0].
int nDevices
Number of end device nodes to create.
bool realisticChannelModel
Whether to use a more realistic channel model with buildings and correlated shadowing.
int nGateways
Number of gateway nodes to create.
double radiusMeters
Radius (m) of the deployment.
void OnTransmissionCallback(Ptr< const Packet > packet, uint32_t senderNodeId)
Record the beginning of a transmission by an end device.
int appPeriodSeconds
Duration (s) of the inter-transmission time of end devices.
#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_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#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
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1331
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
ns cmd
Definition: second.py:40
ns channel
Definition: third.py:88
ns mobility
Definition: third.py:103
ns phy
Definition: third.py:89
Structure to collect all parameters that are used to compute the duration of a packet (excluding payl...
Definition: lora-phy.h:49
uint8_t codingRate
Code rate (obtained as 4/(codingRate+4))
Definition: lora-phy.h:52
uint32_t nPreamble
Number of preamble symbols.
Definition: lora-phy.h:54
bool headerDisabled
Whether to use implicit header mode.
Definition: lora-phy.h:51
double bandwidthHz
Bandwidth in Hz.
Definition: lora-phy.h:53
bool lowDataRateOptimizationEnabled
Whether low data rate optimization is enabled.
Definition: lora-phy.h:56
bool crcEnabled
Whether Cyclic Redundancy Check (CRC) is enabled.
Definition: lora-phy.h:55
uint8_t sf
Spreading Factor.
Definition: lora-phy.h:50
static const uint32_t packetSize
Packet size generated at the AP.