/* * Copyright (c) 2014 Wireless Communications and Networking Group (WCNG), * University of Rochester, Rochester, NY, USA. * * 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 * * Author: Cristiano Tapparello */ /** * * This example extends the energy model example by connecting a basic energy * harvester to the nodes. * * The example considers a simple communication link between a source and a * destination node, where the source node sends a packet to the destination * every 1 second. Each node is powered by a BasicEnergySource, which is recharged * by a BasicEnergyHarvester, and the WiFi radio consumes energy for the transmission/ * reception of the packets. * * For the receiver node, the example prints the energy consumption of the WiFi radio, * the power harvested by the energy harvester and the residual energy in the * energy source. * * The nodes initial energy is set to 1.0 J, the transmission and reception entail a * current consumption of 0.0174 A and 0.0197 A, respectively (default values in * WifiRadioEnergyModel). The energy harvester provides an amount of power that varies * according to a random variable uniformly distributed in [0 0.1] W, and is updated * every 1 s. The energy source voltage is 3 V (default value in BasicEnergySource) and * the residual energy level is updated every 1 second (default value). * * The simulation start at time 0 and it is hard stopped at time 10 seconds. Given the * packet size and the distance between the nodes, each transmission lasts 0.0023s. * As a result, the destination node receives 10 messages. * */ #include "ns3/config-store-module.h" #include "ns3/core-module.h" #include "ns3/energy-module.h" #include "ns3/internet-module.h" #include "ns3/mobility-module.h" #include "ns3/network-module.h" #include "ns3/wifi-radio-energy-model-helper.h" #include "ns3/yans-wifi-helper.h" #include #include #include #include using namespace ns3; NS_LOG_COMPONENT_DEFINE("EnergyWithHarvestingExample"); /** * Print a received packet * * \param from sender address * \return a sting with the details of the packet: dst {IP, port}, time. */ static inline std::string PrintReceivedPacket(Address& from) { InetSocketAddress iaddr = InetSocketAddress::ConvertFrom(from); std::ostringstream oss; oss << "--\nReceived one packet! Socket: " << iaddr.GetIpv4() << " port: " << iaddr.GetPort() << " at time = " << Simulator::Now().GetSeconds() << "\n--"; return oss.str(); } /** * \param socket Pointer to socket. * * Packet receiving sink. */ void ReceivePacket(Ptr socket) { Ptr packet; Address from; while ((packet = socket->RecvFrom(from))) { if (packet->GetSize() > 0) { NS_LOG_UNCOND(PrintReceivedPacket(from)); } } } /** * \param socket Pointer to socket. * \param pktSize Packet size. * \param n Pointer to node. * \param pktCount Number of packets to generate. * \param pktInterval Packet sending interval. * * Traffic generator. */ static void GenerateTraffic(Ptr socket, uint32_t pktSize, Ptr n, uint32_t pktCount, Time pktInterval) { if (pktCount > 0) { socket->Send(Create(pktSize)); Simulator::Schedule(pktInterval, &GenerateTraffic, socket, pktSize, n, pktCount - 1, pktInterval); } else { socket->Close(); } } /** * Trace function for remaining energy at node. * * \param oldValue Old value * \param remainingEnergy New value */ void RemainingEnergy(double oldValue, double remainingEnergy) { NS_LOG_UNCOND(Simulator::Now().GetSeconds() << "s Current remaining energy = " << remainingEnergy << "J"); } /** * Trace function for total energy consumption at node. * * \param oldValue Old value * \param totalEnergy New value */ void TotalEnergy(double oldValue, double totalEnergy) { NS_LOG_UNCOND(Simulator::Now().GetSeconds() << "s Total energy consumed by radio = " << totalEnergy << "J"); } /** * Trace function for the power harvested by the energy harvester. * * \param oldValue Old value * \param harvestedPower New value */ void HarvestedPower(double oldValue, double harvestedPower) { NS_LOG_UNCOND(Simulator::Now().GetSeconds() << "s Current harvested power = " << harvestedPower << " W"); } /** * Trace function for the total energy harvested by the node. * * \param oldValue Old value * \param totalEnergyHarvested New value */ void TotalEnergyHarvested(double oldValue, double totalEnergyHarvested) { NS_LOG_UNCOND(Simulator::Now().GetSeconds() << "s Total energy harvested by harvester = " << totalEnergyHarvested << " J"); } int main(int argc, char* argv[]) { std::string phyMode("DsssRate1Mbps"); double Prss = -80; // dBm uint32_t PacketSize = 200; // bytes bool verbose = false; // simulation parameters uint32_t numPackets = 10000; // number of packets to send double interval = 1; // seconds double startTime = 0.0; // seconds double distanceToRx = 100.0; // meters // Energy Harvester variables double harvestingUpdateInterval = 1; // seconds CommandLine cmd(__FILE__); cmd.AddValue("phyMode", "Wifi Phy mode", phyMode); cmd.AddValue("Prss", "Intended primary RSS (dBm)", Prss); cmd.AddValue("PacketSize", "size of application packet sent", PacketSize); cmd.AddValue("numPackets", "Total number of packets to send", numPackets); cmd.AddValue("startTime", "Simulation start time", startTime); cmd.AddValue("distanceToRx", "X-Axis distance between nodes", distanceToRx); cmd.AddValue("verbose", "Turn on all device log components", verbose); cmd.Parse(argc, argv); // Convert to time object Time interPacketInterval = Seconds(interval); // disable fragmentation for frames below 2200 bytes Config::SetDefault("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue("2200")); // turn off RTS/CTS for frames below 2200 bytes Config::SetDefault("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue("2200")); // Fix non-unicast data rate to be the same as that of unicast Config::SetDefault("ns3::WifiRemoteStationManager::NonUnicastMode", StringValue(phyMode)); NodeContainer c; c.Create(2); // create 2 nodes NodeContainer networkNodes; networkNodes.Add(c.Get(0)); networkNodes.Add(c.Get(1)); // The below set of helpers will help us to put together the wifi NICs we want WifiHelper wifi; if (verbose) { wifi.EnableLogComponents(); } wifi.SetStandard(WIFI_STANDARD_80211b); /** Wifi PHY **/ /***************************************************************************/ YansWifiPhyHelper wifiPhy; /** wifi channel **/ YansWifiChannelHelper wifiChannel; wifiChannel.SetPropagationDelay("ns3::ConstantSpeedPropagationDelayModel"); wifiChannel.AddPropagationLoss("ns3::FriisPropagationLossModel"); // create wifi channel Ptr wifiChannelPtr = wifiChannel.Create(); wifiPhy.SetChannel(wifiChannelPtr); /** MAC layer **/ // Add a MAC and disable rate control WifiMacHelper wifiMac; wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager", "DataMode", StringValue(phyMode), "ControlMode", StringValue(phyMode)); // Set it to ad-hoc mode wifiMac.SetType("ns3::AdhocWifiMac"); /** install PHY + MAC **/ NetDeviceContainer devices = wifi.Install(wifiPhy, wifiMac, networkNodes); /** mobility **/ MobilityHelper mobility; Ptr positionAlloc = CreateObject(); positionAlloc->Add(Vector(0.0, 0.0, 0.0)); positionAlloc->Add(Vector(2 * distanceToRx, 0.0, 0.0)); mobility.SetPositionAllocator(positionAlloc); mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel"); mobility.Install(c); /** Energy Model **/ /***************************************************************************/ /* energy source */ BasicEnergySourceHelper basicSourceHelper; // configure energy source basicSourceHelper.Set("BasicEnergySourceInitialEnergyJ", DoubleValue(1.0)); // install source EnergySourceContainer sources = basicSourceHelper.Install(c); /* device energy model */ WifiRadioEnergyModelHelper radioEnergyHelper; // configure radio energy model radioEnergyHelper.Set("TxCurrentA", DoubleValue(0.0174)); radioEnergyHelper.Set("RxCurrentA", DoubleValue(0.0197)); // install device model DeviceEnergyModelContainer deviceModels = radioEnergyHelper.Install(devices, sources); /* energy harvester */ BasicEnergyHarvesterHelper basicHarvesterHelper; // configure energy harvester basicHarvesterHelper.Set("PeriodicHarvestedPowerUpdateInterval", TimeValue(Seconds(harvestingUpdateInterval))); basicHarvesterHelper.Set("HarvestablePower", StringValue("ns3::UniformRandomVariable[Min=0.0|Max=0.1]")); // install harvester on all energy sources EnergyHarvesterContainer harvesters = basicHarvesterHelper.Install(sources); /***************************************************************************/ /** Internet stack **/ InternetStackHelper internet; internet.Install(networkNodes); Ipv4AddressHelper ipv4; NS_LOG_INFO("Assign IP Addresses."); ipv4.SetBase("10.1.1.0", "255.255.255.0"); Ipv4InterfaceContainer i = ipv4.Assign(devices); TypeId tid = TypeId::LookupByName("ns3::UdpSocketFactory"); Ptr recvSink = Socket::CreateSocket(networkNodes.Get(1), tid); // node 1, Destination InetSocketAddress local = InetSocketAddress(Ipv4Address::GetAny(), 80); recvSink->Bind(local); recvSink->SetRecvCallback(MakeCallback(&ReceivePacket)); Ptr source = Socket::CreateSocket(networkNodes.Get(0), tid); // node 0, Source InetSocketAddress remote = InetSocketAddress(Ipv4Address::GetBroadcast(), 80); source->SetAllowBroadcast(true); source->Connect(remote); /** connect trace sources **/ /***************************************************************************/ // all traces are connected to node 1 (Destination) // energy source Ptr basicSourcePtr = DynamicCast(sources.Get(1)); basicSourcePtr->TraceConnectWithoutContext("RemainingEnergy", MakeCallback(&RemainingEnergy)); // device energy model Ptr basicRadioModelPtr = basicSourcePtr->FindDeviceEnergyModels("ns3::WifiRadioEnergyModel").Get(0); NS_ASSERT(basicRadioModelPtr); basicRadioModelPtr->TraceConnectWithoutContext("TotalEnergyConsumption", MakeCallback(&TotalEnergy)); // energy harvester Ptr basicHarvesterPtr = DynamicCast(harvesters.Get(1)); basicHarvesterPtr->TraceConnectWithoutContext("HarvestedPower", MakeCallback(&HarvestedPower)); basicHarvesterPtr->TraceConnectWithoutContext("TotalEnergyHarvested", MakeCallback(&TotalEnergyHarvested)); /***************************************************************************/ /** simulation setup **/ // start traffic Simulator::Schedule(Seconds(startTime), &GenerateTraffic, source, PacketSize, networkNodes.Get(0), numPackets, interPacketInterval); Simulator::Stop(Seconds(10.0)); Simulator::Run(); for (DeviceEnergyModelContainer::Iterator iter = deviceModels.Begin(); iter != deviceModels.End(); iter++) { double energyConsumed = (*iter)->GetTotalEnergyConsumption(); NS_LOG_UNCOND("End of simulation (" << Simulator::Now().GetSeconds() << "s) Total energy consumed by radio = " << energyConsumed << "J"); NS_ASSERT(energyConsumed <= 1.0); } Simulator::Destroy(); return 0; }