1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
|
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2009 The Boeing Company
* 2014 Universita' degli Studi di Napoli "Federico II"
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
//
// This script configures two nodes on an 802.11b physical layer, with
// 802.11b NICs in adhoc mode. One of the nodes generates on-off traffic
// destined to the other node.
//
// The purpose is to test the energy depletion on the nodes and the
// activation of the callback that puts a node in the sleep state when
// its energy is depleted. Furthermore, this script can be used to test
// the available policies for updating the transmit current based on
// the nominal tx power used to transmit each frame.
//
// There are a number of command-line options available to control
// the default behavior. The list of available command-line options
// can be listed with the following command:
// ./waf --run "wifi-sleep --help"
//
// Note that all ns-3 attributes (not just the ones exposed in the below
// script) can be changed at command line; see the documentation.
//
// This script can also be helpful to put the Wifi layer into verbose
// logging mode; this command will turn on all wifi logging:
//
// ./waf --run "wifi-sleep --verbose=1"
//
// When you are done, you will notice four trace files in your directory:
// two for the remaining energy on each node and two for the state transitions
// of each node.
//
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/mobility-module.h"
#include "ns3/config-store-module.h"
#include "ns3/wifi-module.h"
#include "ns3/internet-module.h"
#include "ns3/applications-module.h"
#include "ns3/energy-module.h"
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("WifiSleep");
template <int node>
void RemainingEnergyTrace (double oldValue, double newValue)
{
std::stringstream ss;
ss << "energy_" << node << ".log";
static std::fstream f (ss.str().c_str(), std::ios::out);
f << Simulator::Now().GetSeconds() << " remaining energy=" << newValue << std::endl;
}
template <int node>
void PhyStateTrace (std::string context, Time start, Time duration, enum WifiPhy::State state)
{
std::stringstream ss;
ss << "state_" << node << ".log";
static std::fstream f (ss.str().c_str(), std::ios::out);
f << Simulator::Now().GetSeconds() << " state=" << state << " start=" << start << " duration=" << duration << std::endl;
}
int main (int argc, char *argv[])
{
std::string dataRate = "1Mbps";
uint32_t packetSize = 1000; // bytes
double duration = 10.0; // seconds
double initialEnergy = 7.5; // joule
double voltage = 3.0; // volts
double txPowerStart = 0.0; // dbm
double txPowerEnd = 15.0; // dbm
uint32_t nTxPowerLevels = 16;
uint32_t txPowerLevel = 0;
double idleCurrent = 0.273; // Ampere
double txCurrent = 0.380; // Ampere
bool verbose = false;
CommandLine cmd;
cmd.AddValue ("dataRate", "Data rate", dataRate);
cmd.AddValue ("packetSize", "size of application packet sent", packetSize);
cmd.AddValue ("duration", "duration (seconds) of the experiment", duration);
cmd.AddValue ("initialEnergy", "Initial Energy (Joule) of each node", initialEnergy);
cmd.AddValue ("voltage", "Supply voltage (Joule)", voltage);
cmd.AddValue ("txPowerStart", "Minimum available transmission level (dbm)", txPowerStart);
cmd.AddValue ("txPowerEnd", "Maximum available transmission level (dbm)", txPowerEnd);
cmd.AddValue ("nTxPowerLevels", "Number of transmission power levels available between txPowerStart and txPowerEnd included", nTxPowerLevels);
cmd.AddValue ("txPowerLevel", "Transmission power level", txPowerLevel);
cmd.AddValue ("idleCurrent", "The radio Idle current in Ampere", idleCurrent);
cmd.AddValue ("txCurrent", "The radio Tx current in Ampere", txCurrent);
cmd.AddValue ("verbose", "turn on all WifiNetDevice log components", verbose);
cmd.Parse (argc, argv);
NodeContainer c;
c.Create (2);
// The below set of helpers will help us to put together the wifi NICs we want
WifiHelper wifi;
if (verbose)
{
wifi.EnableLogComponents (); // Turn on all Wifi logging
}
wifi.SetStandard (WIFI_PHY_STANDARD_80211b);
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
// ns-3 supports RadioTap and Prism tracing extensions for 802.11b
wifiPhy.SetPcapDataLinkType (YansWifiPhyHelper::DLT_IEEE802_11_RADIO);
wifiPhy.Set ("TxPowerStart", DoubleValue (txPowerStart));
wifiPhy.Set ("TxPowerEnd", DoubleValue (txPowerEnd));
wifiPhy.Set ("TxPowerLevels", UintegerValue (nTxPowerLevels));
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
wifiPhy.SetChannel (wifiChannel.Create ());
// Add a mac and set the selected tx power level
WifiMacHelper wifiMac;
wifi.SetRemoteStationManager ("ns3::ArfWifiManager", "DefaultTxPowerLevel", UintegerValue (txPowerLevel));
// Set it to adhoc mode
wifiMac.SetType ("ns3::AdhocWifiMac");
NetDeviceContainer devices = wifi.Install (wifiPhy, wifiMac, c);
MobilityHelper mobility;
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
positionAlloc->Add (Vector (0.0, 0.0, 0.0));
positionAlloc->Add (Vector (10.0, 0.0, 0.0));
mobility.SetPositionAllocator (positionAlloc);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (c);
InternetStackHelper internet;
internet.Install (c);
Ipv4AddressHelper ipv4;
NS_LOG_INFO ("Assign IP Addresses.");
ipv4.SetBase ("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer i = ipv4.Assign (devices);
ApplicationContainer apps;
std::string transportProto = std::string("ns3::UdpSocketFactory");
OnOffHelper onOff(transportProto, InetSocketAddress (Ipv4Address ("10.1.1.2"), 9000));
onOff.SetAttribute ("DataRate", DataRateValue (DataRate (dataRate)));
onOff.SetAttribute ("PacketSize", UintegerValue (packetSize));
onOff.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0.001]"));
apps = onOff.Install (c.Get (0));
apps.Start (Seconds (0.01));
apps.Stop (Seconds (duration));
// Create a packet sink to receive these packets
PacketSinkHelper sink (transportProto, InetSocketAddress (Ipv4Address::GetAny (), 9001));
apps = sink.Install (c.Get (1));
apps.Start (Seconds (0.01));
apps.Stop (Seconds (duration));
// Energy sources
EnergySourceContainer eSources;
BasicEnergySourceHelper basicSourceHelper;
WifiRadioEnergyModelHelper radioEnergyHelper;
basicSourceHelper.Set ("BasicEnergySourceInitialEnergyJ", DoubleValue (initialEnergy));
basicSourceHelper.Set ("BasicEnergySupplyVoltageV", DoubleValue (voltage));
radioEnergyHelper.Set ("IdleCurrentA", DoubleValue (idleCurrent));
radioEnergyHelper.Set ("TxCurrentA", DoubleValue (txCurrent));
// compute the efficiency of the power amplifier (eta) assuming that the provided value for tx current
// corresponds to the minimum tx power level
double eta = WifiTxCurrentModel::DbmToW (txPowerStart) / ((txCurrent - idleCurrent) * voltage);
radioEnergyHelper.SetTxCurrentModel ("ns3::LinearWifiTxCurrentModel",
"Voltage", DoubleValue (voltage),
"IdleCurrent", DoubleValue (idleCurrent),
"Eta", DoubleValue (eta));
// install an energy source on each node
for (NodeContainer::Iterator n = c.Begin(); n != c.End(); n++)
{
eSources.Add (basicSourceHelper.Install (*n));
Ptr<WifiNetDevice> wnd;
for (uint32_t i = 0; i < (*n)->GetNDevices (); ++i)
{
wnd = (*n)->GetDevice (i)->GetObject<WifiNetDevice> ();
// if it is a WifiNetDevice
if (wnd != 0)
{
// this device draws power from the last created energy source
radioEnergyHelper.Install (wnd, eSources.Get (eSources.GetN()-1));
}
}
}
// Tracing
eSources.Get (0)->TraceConnectWithoutContext ("RemainingEnergy", MakeCallback(&RemainingEnergyTrace<0>));
eSources.Get (1)->TraceConnectWithoutContext ("RemainingEnergy", MakeCallback(&RemainingEnergyTrace<1>));
Config::Connect ("/NodeList/0/DeviceList/*/Phy/State/State", MakeCallback (&PhyStateTrace<0>));
Config::Connect ("/NodeList/1/DeviceList/*/Phy/State/State", MakeCallback (&PhyStateTrace<1>));
// wifiPhy.EnablePcap ("wifi-sleep", devices);
Simulator::Stop (Seconds(duration+1));
Simulator::Run ();
Simulator::Destroy ();
return 0;
}
|