1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3 * Copyright (c) 2014 Wireless Communications and Networking Group (WCNG),
4 * University of Rochester, Rochester, NY, USA.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation;
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * Author: Cristiano Tapparello <cristiano.tapparello@rochester.edu>
20 */
21
22 /**
23 *
24 * This example extends the energy model example by connecting a basic energy
25 * harvester to the nodes.
26 *
27 * The example considers a simple communication link between a source and a
28 * destination node, where the source node sends a packet to the destination
29 * every 1 second. Each node is powered by a BasicEnergySource, which is recharged
30 * by a BasicEnergyHarvester, and the WiFi radio consumes energy for the transmission/
31 * reception of the packets.
32 *
33 * For the receiver node, the example prints the energy consumption of the WiFi radio,
34 * the power harvested by the energy harvester and the residual energy in the
35 * energy source.
36 *
37 * The nodes initial energy is set to 1.0 J, the transmission and reception entail a
38 * current consumption of 0.0174 A and 0.0197 A, respectively (default values in
39 * WifiRadioEnergyModel). The energy harvester provides an amount of power that varies
40 * according to a random variable uniformly distributed in [0 0.1] W, and is updated
41 * every 1 s. The energy source voltage is 3 V (default value in BasicEnergySource) and
42 * the residual energy level is updated every 1 second (default value).
43 *
44 * The simulation start at time 0 and it is hard stopped at time 10 seconds. Given the
45 * packet size and the distance between the nodes, each transmission lasts 0.0023s.
46 * As a result, the destination node receives 10 messages.
47 *
48 */
49
50 #include <iostream>
51 #include <fstream>
52 #include <vector>
53 #include <string>
54 #include "ns3/core-module.h"
55 #include "ns3/network-module.h"
56 #include "ns3/mobility-module.h"
57 #include "ns3/config-store-module.h"
58 #include "ns3/energy-module.h"
59 #include "ns3/internet-module.h"
60 #include "ns3/yans-wifi-helper.h"
61 #include "ns3/wifi-radio-energy-model-helper.h"
62
63 using namespace ns3;
64
65 NS_LOG_COMPONENT_DEFINE ("EnergyWithHarvestingExample");
66
67 static inline std::string
PrintReceivedPacket(Address & from)68 PrintReceivedPacket (Address& from)
69 {
70 InetSocketAddress iaddr = InetSocketAddress::ConvertFrom (from);
71
72 std::ostringstream oss;
73 oss << "--\nReceived one packet! Socket: " << iaddr.GetIpv4 ()
74 << " port: " << iaddr.GetPort ()
75 << " at time = " << Simulator::Now ().GetSeconds ()
76 << "\n--";
77
78 return oss.str ();
79 }
80
81 /**
82 * \param socket Pointer to socket.
83 *
84 * Packet receiving sink.
85 */
86 void
ReceivePacket(Ptr<Socket> socket)87 ReceivePacket (Ptr<Socket> socket)
88 {
89 Ptr<Packet> packet;
90 Address from;
91 while ((packet = socket->RecvFrom (from)))
92 {
93 if (packet->GetSize () > 0)
94 {
95 NS_LOG_UNCOND (PrintReceivedPacket (from));
96 }
97 }
98 }
99
100 /**
101 * \param socket Pointer to socket.
102 * \param pktSize Packet size.
103 * \param n Pointer to node.
104 * \param pktCount Number of packets to generate.
105 * \param pktInterval Packet sending interval.
106 *
107 * Traffic generator.
108 */
109 static void
GenerateTraffic(Ptr<Socket> socket,uint32_t pktSize,Ptr<Node> n,uint32_t pktCount,Time pktInterval)110 GenerateTraffic (Ptr<Socket> socket, uint32_t pktSize, Ptr<Node> n,
111 uint32_t pktCount, Time pktInterval)
112 {
113 if (pktCount > 0)
114 {
115 socket->Send (Create<Packet> (pktSize));
116 Simulator::Schedule (pktInterval, &GenerateTraffic, socket, pktSize, n,
117 pktCount - 1, pktInterval);
118 }
119 else
120 {
121 socket->Close ();
122 }
123 }
124
125 /// Trace function for remaining energy at node.
126 void
RemainingEnergy(double oldValue,double remainingEnergy)127 RemainingEnergy (double oldValue, double remainingEnergy)
128 {
129 NS_LOG_UNCOND (Simulator::Now ().GetSeconds ()
130 << "s Current remaining energy = " << remainingEnergy << "J");
131 }
132
133 /// Trace function for total energy consumption at node.
134 void
TotalEnergy(double oldValue,double totalEnergy)135 TotalEnergy (double oldValue, double totalEnergy)
136 {
137 NS_LOG_UNCOND (Simulator::Now ().GetSeconds ()
138 << "s Total energy consumed by radio = " << totalEnergy << "J");
139 }
140
141 /// Trace function for the power harvested by the energy harvester.
142 void
HarvestedPower(double oldValue,double harvestedPower)143 HarvestedPower (double oldValue, double harvestedPower)
144 {
145 NS_LOG_UNCOND (Simulator::Now ().GetSeconds ()
146 << "s Current harvested power = " << harvestedPower << " W");
147 }
148
149 /// Trace function for the total energy harvested by the node.
150 void
TotalEnergyHarvested(double oldValue,double TotalEnergyHarvested)151 TotalEnergyHarvested (double oldValue, double TotalEnergyHarvested)
152 {
153 NS_LOG_UNCOND (Simulator::Now ().GetSeconds ()
154 << "s Total energy harvested by harvester = "
155 << TotalEnergyHarvested << " J");
156 }
157
158
159 int
main(int argc,char * argv[])160 main (int argc, char *argv[])
161 {
162 std::string phyMode ("DsssRate1Mbps");
163 double Prss = -80; // dBm
164 uint32_t PacketSize = 200; // bytes
165 bool verbose = false;
166
167 // simulation parameters
168 uint32_t numPackets = 10000; // number of packets to send
169 double interval = 1; // seconds
170 double startTime = 0.0; // seconds
171 double distanceToRx = 100.0; // meters
172
173 // Energy Harvester variables
174 double harvestingUpdateInterval = 1; // seconds
175
176 CommandLine cmd (__FILE__);
177 cmd.AddValue ("phyMode", "Wifi Phy mode", phyMode);
178 cmd.AddValue ("Prss", "Intended primary RSS (dBm)", Prss);
179 cmd.AddValue ("PacketSize", "size of application packet sent", PacketSize);
180 cmd.AddValue ("numPackets", "Total number of packets to send", numPackets);
181 cmd.AddValue ("startTime", "Simulation start time", startTime);
182 cmd.AddValue ("distanceToRx", "X-Axis distance between nodes", distanceToRx);
183 cmd.AddValue ("verbose", "Turn on all device log components", verbose);
184 cmd.Parse (argc, argv);
185
186 // Convert to time object
187 Time interPacketInterval = Seconds (interval);
188
189 // disable fragmentation for frames below 2200 bytes
190 Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold",
191 StringValue ("2200"));
192 // turn off RTS/CTS for frames below 2200 bytes
193 Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold",
194 StringValue ("2200"));
195 // Fix non-unicast data rate to be the same as that of unicast
196 Config::SetDefault ("ns3::WifiRemoteStationManager::NonUnicastMode",
197 StringValue (phyMode));
198
199 NodeContainer c;
200 c.Create (2); // create 2 nodes
201 NodeContainer networkNodes;
202 networkNodes.Add (c.Get (0));
203 networkNodes.Add (c.Get (1));
204
205 // The below set of helpers will help us to put together the wifi NICs we want
206 WifiHelper wifi;
207 if (verbose)
208 {
209 wifi.EnableLogComponents ();
210 }
211 wifi.SetStandard (WIFI_STANDARD_80211b);
212
213 /** Wifi PHY **/
214 /***************************************************************************/
215 YansWifiPhyHelper wifiPhy;
216
217 /** wifi channel **/
218 YansWifiChannelHelper wifiChannel;
219 wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
220 wifiChannel.AddPropagationLoss ("ns3::FriisPropagationLossModel");
221
222 // create wifi channel
223 Ptr<YansWifiChannel> wifiChannelPtr = wifiChannel.Create ();
224 wifiPhy.SetChannel (wifiChannelPtr);
225
226 /** MAC layer **/
227 // Add a MAC and disable rate control
228 WifiMacHelper wifiMac;
229 wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode",
230 StringValue (phyMode), "ControlMode",
231 StringValue (phyMode));
232 // Set it to ad-hoc mode
233 wifiMac.SetType ("ns3::AdhocWifiMac");
234
235 /** install PHY + MAC **/
236 NetDeviceContainer devices = wifi.Install (wifiPhy, wifiMac, networkNodes);
237
238 /** mobility **/
239 MobilityHelper mobility;
240 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
241 positionAlloc->Add (Vector (0.0, 0.0, 0.0));
242 positionAlloc->Add (Vector (2 * distanceToRx, 0.0, 0.0));
243 mobility.SetPositionAllocator (positionAlloc);
244 mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
245 mobility.Install (c);
246
247 /** Energy Model **/
248 /***************************************************************************/
249 /* energy source */
250 BasicEnergySourceHelper basicSourceHelper;
251 // configure energy source
252 basicSourceHelper.Set ("BasicEnergySourceInitialEnergyJ", DoubleValue (1.0));
253 // install source
254 EnergySourceContainer sources = basicSourceHelper.Install (c);
255 /* device energy model */
256 WifiRadioEnergyModelHelper radioEnergyHelper;
257 // configure radio energy model
258 radioEnergyHelper.Set ("TxCurrentA", DoubleValue (0.0174));
259 radioEnergyHelper.Set ("RxCurrentA", DoubleValue (0.0197));
260 // install device model
261 DeviceEnergyModelContainer deviceModels = radioEnergyHelper.Install (devices, sources);
262
263 /* energy harvester */
264 BasicEnergyHarvesterHelper basicHarvesterHelper;
265 // configure energy harvester
266 basicHarvesterHelper.Set ("PeriodicHarvestedPowerUpdateInterval", TimeValue (Seconds (harvestingUpdateInterval)));
267 basicHarvesterHelper.Set ("HarvestablePower", StringValue ("ns3::UniformRandomVariable[Min=0.0|Max=0.1]"));
268 // install harvester on all energy sources
269 EnergyHarvesterContainer harvesters = basicHarvesterHelper.Install (sources);
270 /***************************************************************************/
271
272 /** Internet stack **/
273 InternetStackHelper internet;
274 internet.Install (networkNodes);
275
276 Ipv4AddressHelper ipv4;
277 NS_LOG_INFO ("Assign IP Addresses.");
278 ipv4.SetBase ("10.1.1.0", "255.255.255.0");
279 Ipv4InterfaceContainer i = ipv4.Assign (devices);
280
281 TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
282 Ptr<Socket> recvSink = Socket::CreateSocket (networkNodes.Get (1), tid); // node 1, Destination
283 InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), 80);
284 recvSink->Bind (local);
285 recvSink->SetRecvCallback (MakeCallback (&ReceivePacket));
286
287 Ptr<Socket> source = Socket::CreateSocket (networkNodes.Get (0), tid); // node 0, Source
288 InetSocketAddress remote = InetSocketAddress (Ipv4Address::GetBroadcast (), 80);
289 source->SetAllowBroadcast (true);
290 source->Connect (remote);
291
292 /** connect trace sources **/
293 /***************************************************************************/
294 // all traces are connected to node 1 (Destination)
295 // energy source
296 Ptr<BasicEnergySource> basicSourcePtr = DynamicCast<BasicEnergySource> (sources.Get (1));
297 basicSourcePtr->TraceConnectWithoutContext ("RemainingEnergy", MakeCallback (&RemainingEnergy));
298 // device energy model
299 Ptr<DeviceEnergyModel> basicRadioModelPtr =
300 basicSourcePtr->FindDeviceEnergyModels ("ns3::WifiRadioEnergyModel").Get (0);
301 NS_ASSERT (basicRadioModelPtr != 0);
302 basicRadioModelPtr->TraceConnectWithoutContext ("TotalEnergyConsumption", MakeCallback (&TotalEnergy));
303 // energy harvester
304 Ptr<BasicEnergyHarvester> basicHarvesterPtr = DynamicCast<BasicEnergyHarvester> (harvesters.Get (1));
305 basicHarvesterPtr->TraceConnectWithoutContext ("HarvestedPower", MakeCallback (&HarvestedPower));
306 basicHarvesterPtr->TraceConnectWithoutContext ("TotalEnergyHarvested", MakeCallback (&TotalEnergyHarvested));
307 /***************************************************************************/
308
309
310 /** simulation setup **/
311 // start traffic
312 Simulator::Schedule (Seconds (startTime), &GenerateTraffic, source, PacketSize,
313 networkNodes.Get (0), numPackets, interPacketInterval);
314
315 Simulator::Stop (Seconds (10.0));
316 Simulator::Run ();
317
318 for (DeviceEnergyModelContainer::Iterator iter = deviceModels.Begin (); iter != deviceModels.End (); iter ++)
319 {
320 double energyConsumed = (*iter)->GetTotalEnergyConsumption ();
321 NS_LOG_UNCOND ("End of simulation (" << Simulator::Now ().GetSeconds ()
322 << "s) Total energy consumed by radio = " << energyConsumed << "J");
323 NS_ASSERT (energyConsumed <= 1.0);
324 }
325
326 Simulator::Destroy ();
327
328 return 0;
329 }
330