# HG changeset patch
# User He Wu
# Date 1292888952 28800
# Node ID d8909a1fd0ff2de298e9e5090711f9cec203fd50
# Parent bc947fbfac8051a70745455b1deb33ce17f892cd
RV battery model and WiFi energy example
diff -r bc947fbfac80 -r d8909a1fd0ff CHANGES.html
--- a/CHANGES.html Mon Dec 20 15:19:11 2010 -0800
+++ b/CHANGES.html Mon Dec 20 15:49:12 2010 -0800
@@ -94,6 +94,10 @@
for example TCP sockets and not UDP sockets. A helper class exists to
facilitate creating BulkSendApplications. The API for the helper class
is similar to existing application helper classes, for example, OnOff.
+
+
+
Rakhmatov Vrudhula non-linear battery model
+
New class and helper for this battery model.
diff -r bc947fbfac80 -r d8909a1fd0ff RELEASE_NOTES
--- a/RELEASE_NOTES Mon Dec 20 15:19:11 2010 -0800
+++ b/RELEASE_NOTES Mon Dec 20 15:49:12 2010 -0800
@@ -71,6 +71,12 @@
application only works with SOCK_STREAM and SOCK_SEQPACKET
sockets, for example TCP sockets and not UDP sockets.
+ - Extensions to the energy models: 1) a new Rakhmatov Vrudhula
+ non-linear battery model, 2) additional support for modeling
+ energy consumption in WiFi devices, 3) an example for how to add
+ energy models to a WiFi-based simulation (in examples/energy/
+ directory).
+
Bugs fixed
----------
The following lists many of the bugs fixed or small feature additions
diff -r bc947fbfac80 -r d8909a1fd0ff examples/energy/energy-model-example.cc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/energy/energy-model-example.cc Mon Dec 20 15:49:12 2010 -0800
@@ -0,0 +1,262 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Network Security Lab, University of Washington, Seattle.
+ *
+ * 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: Sidharth Nabar , He Wu
+ */
+
+#include "ns3/core-module.h"
+#include "ns3/common-module.h"
+#include "ns3/node-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/mobility-module.h"
+#include "ns3/contrib-module.h"
+#include "ns3/wifi-module.h"
+#include "ns3/energy-module.h"
+
+#include
+#include
+#include
+#include
+
+NS_LOG_COMPONENT_DEFINE ("EnergyExample");
+
+using namespace ns3;
+
+/**
+ * \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)
+ {
+ InetSocketAddress iaddr = InetSocketAddress::ConvertFrom (from);
+ NS_LOG_UNCOND ("--\nReceived one packet! Socket: "<< iaddr.GetIpv4 ()
+ << " port: " << iaddr.GetPort () << " at time = " <<
+ Simulator::Now ().GetSeconds () << "\n--");
+ }
+ }
+}
+
+/**
+ * \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.
+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.
+void
+TotalEnergy (double oldValue, double totalEnergy)
+{
+ NS_LOG_UNCOND (Simulator::Now ().GetSeconds ()
+ << "s Total energy consumed by radio = " << totalEnergy << "J");
+}
+
+int
+main (int argc, char *argv[])
+{
+ /*
+ LogComponentEnable ("EnergySource", LOG_LEVEL_DEBUG);
+ LogComponentEnable ("BasicEnergySource", LOG_LEVEL_DEBUG);
+ LogComponentEnable ("DeviceEnergyModel", LOG_LEVEL_DEBUG);
+ LogComponentEnable ("WifiRadioEnergyModel", LOG_LEVEL_DEBUG);
+ */
+
+ std::string phyMode ("DsssRate1Mbps");
+ double Prss = -80; // dBm
+ uint32_t PpacketSize = 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
+ /*
+ * This is a magic number used to set the transmit power, based on other
+ * configuration.
+ */
+ double offset = 81;
+
+ CommandLine cmd;
+ cmd.AddValue ("phyMode", "Wifi Phy mode", phyMode);
+ cmd.AddValue ("Prss", "Intended primary RSS (dBm)", Prss);
+ cmd.AddValue ("PpacketSize", "size of application packet sent", PpacketSize);
+ 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_PHY_STANDARD_80211b);
+
+ /** Wifi PHY **/
+ /***************************************************************************/
+ YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
+ wifiPhy.Set ("RxGain", DoubleValue (-10));
+ wifiPhy.Set ("TxGain", DoubleValue (offset + Prss));
+ wifiPhy.Set ("CcaMode1Threshold", DoubleValue (0.0));
+ /***************************************************************************/
+
+ /** 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 non-QoS upper MAC, and disable rate control
+ NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
+ 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 (0.1));
+ // install source
+ EnergySourceContainer sources = basicSourceHelper.Install (c);
+ /* device energy model */
+ WifiRadioEnergyModelHelper radioEnergyHelper;
+ // configure radio energy model
+ radioEnergyHelper.Set ("TxCurrentA", DoubleValue (0.0174));
+ // install device model
+ DeviceEnergyModelContainer deviceModels = radioEnergyHelper.Install (devices, 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, receiver
+ InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), 80);
+ recvSink->Bind (local);
+ recvSink->SetRecvCallback (MakeCallback (&ReceivePacket));
+
+ Ptr source = Socket::CreateSocket (networkNodes.Get (0), tid); // node 0, sender
+ InetSocketAddress remote = InetSocketAddress (Ipv4Address::GetBroadcast (), 80);
+ source->SetAllowBroadcast (true);
+ source->Connect (remote);
+
+ /** connect trace sources **/
+ /***************************************************************************/
+ // all sources are connected to node 1
+ // 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 != NULL);
+ basicRadioModelPtr->TraceConnectWithoutContext ("TotalEnergyConsumption", MakeCallback (&TotalEnergy));
+ /***************************************************************************/
+
+
+ /** simulation setup **/
+ // start traffic
+ Simulator::Schedule (Seconds (startTime), &GenerateTraffic, source, PpacketSize,
+ networkNodes.Get (0), numPackets, interPacketInterval);
+
+ Simulator::Stop (Seconds (10.0));
+ Simulator::Run ();
+ Simulator::Destroy ();
+
+ return 0;
+}
diff -r bc947fbfac80 -r d8909a1fd0ff examples/energy/waf
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/energy/waf Mon Dec 20 15:49:12 2010 -0800
@@ -0,0 +1,1 @@
+exec "`dirname "$0"`"/../../waf "$@"
diff -r bc947fbfac80 -r d8909a1fd0ff examples/energy/wscript
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/energy/wscript Mon Dec 20 15:49:12 2010 -0800
@@ -0,0 +1,5 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def build(bld):
+ obj = bld.create_ns3_program('energy-model-example', ['core', 'simulator', 'mobility', 'wifi', 'energy', 'internet-stack'])
+ obj.source = 'energy-model-example.cc'
\ No newline at end of file
diff -r bc947fbfac80 -r d8909a1fd0ff src/contrib/energy/helper/energy-model-helper.cc
--- a/src/contrib/energy/helper/energy-model-helper.cc Mon Dec 20 15:19:11 2010 -0800
+++ b/src/contrib/energy/helper/energy-model-helper.cc Mon Dec 20 15:49:12 2010 -0800
@@ -93,6 +93,7 @@
{
NS_ASSERT (device != NULL);
NS_ASSERT (source != NULL);
+ // check to make sure source and net device are on the same node
NS_ASSERT (device->GetNode () == source->GetNode ());
DeviceEnergyModelContainer container (DoInstall (device, source));
return container;
@@ -108,6 +109,7 @@
EnergySourceContainer::Iterator src = sourceContainer.Begin ();
while (dev != deviceContainer.End ())
{
+ // check to make sure source and net device are on the same node
NS_ASSERT ((*dev)->GetNode () == (*src)->GetNode ());
Ptr model = DoInstall (*dev, *src);
container.Add (model);
diff -r bc947fbfac80 -r d8909a1fd0ff src/contrib/energy/helper/energy-source-container.cc
--- a/src/contrib/energy/helper/energy-source-container.cc Mon Dec 20 15:19:11 2010 -0800
+++ b/src/contrib/energy/helper/energy-source-container.cc Mon Dec 20 15:49:12 2010 -0800
@@ -118,6 +118,13 @@
void
EnergySourceContainer::DoDispose (void)
{
+ // call Object::Dispose for all EnergySource objects
+ for (std::vector< Ptr >::iterator i = m_sources.begin ();
+ i != m_sources.end (); i++)
+ {
+ (*i)->DisposeDeviceModels ();
+ (*i)->Dispose ();
+ }
m_sources.clear ();
}
@@ -126,9 +133,10 @@
{
// call Object::Start for all EnergySource objects
for (std::vector< Ptr >::iterator i = m_sources.begin ();
- i != m_sources.end (); i++)
+ i != m_sources.end (); i++)
{
(*i)->Start ();
+ (*i)->StartDeviceModels ();
}
}
diff -r bc947fbfac80 -r d8909a1fd0ff src/contrib/energy/helper/rv-battery-model-helper.cc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/energy/helper/rv-battery-model-helper.cc Mon Dec 20 15:49:12 2010 -0800
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Network Security Lab, University of Washington, Seattle.
+ *
+ * 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
+ *
+ * Authors: Sidharth Nabar , He Wu
+ */
+
+#include "rv-battery-model-helper.h"
+#include "ns3/energy-source.h"
+
+namespace ns3 {
+
+RvBatteryModelHelper::RvBatteryModelHelper ()
+{
+ m_rvBatteryModel.SetTypeId ("ns3::RvBatteryModel");
+}
+
+RvBatteryModelHelper::~RvBatteryModelHelper ()
+{
+}
+
+void
+RvBatteryModelHelper::Set (std::string name, const AttributeValue &v)
+{
+ m_rvBatteryModel.Set (name, v);
+}
+
+Ptr
+RvBatteryModelHelper::DoInstall (Ptr node) const
+{
+ NS_ASSERT (node != NULL);
+ // check if energy source already exists
+ Ptr source = node->GetObject ();
+ if (source != NULL)
+ {
+ NS_FATAL_ERROR ("Energy source already installed!");
+ }
+ source = m_rvBatteryModel.Create ();
+ NS_ASSERT (source != NULL);
+ source->SetNode (node);
+ return source;
+}
+
+} // namespace ns3
diff -r bc947fbfac80 -r d8909a1fd0ff src/contrib/energy/helper/rv-battery-model-helper.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/energy/helper/rv-battery-model-helper.h Mon Dec 20 15:49:12 2010 -0800
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Network Security Lab, University of Washington, Seattle.
+ *
+ * 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
+ *
+ * Authors: Sidharth Nabar , He Wu
+ */
+
+#ifndef RV_BATTERY_MODEL_HELPER_H
+#define RV_BATTERY_MODEL_HELPER_H
+
+#include "energy-model-helper.h"
+#include "ns3/node.h"
+
+namespace ns3 {
+
+/**
+ * \brief Creates a RvBatteryModel object.
+ */
+class RvBatteryModelHelper : public EnergySourceHelper
+{
+public:
+ RvBatteryModelHelper ();
+ ~RvBatteryModelHelper ();
+
+ void Set (std::string name, const AttributeValue &v);
+
+private:
+ virtual Ptr DoInstall (Ptr node) const;
+
+private:
+ ObjectFactory m_rvBatteryModel;
+
+};
+
+} // namespace ns3
+
+#endif /* RV_BATTERY_MODEL_HELPER_H */
diff -r bc947fbfac80 -r d8909a1fd0ff src/contrib/energy/helper/wifi-radio-energy-model-helper.cc
--- a/src/contrib/energy/helper/wifi-radio-energy-model-helper.cc Mon Dec 20 15:19:11 2010 -0800
+++ b/src/contrib/energy/helper/wifi-radio-energy-model-helper.cc Mon Dec 20 15:49:12 2010 -0800
@@ -67,23 +67,18 @@
NS_FATAL_ERROR ("NetDevice type is not WifiNetDevice!");
}
Ptr node = device->GetNode ();
- Ptr model = m_radioEnergy.Create ()->
- GetObject ();
+ Ptr model = m_radioEnergy.Create ()->GetObject ();
NS_ASSERT (model != NULL);
- // set node pointer
- model->SetNode (node);
// set energy source pointer
model->SetEnergySource (source);
// set energy depletion callback
model->SetEnergyDepletionCallback (m_depletionCallback);
// add model to device model list in energy source
source->AppendDeviceEnergyModel (model);
- // create and install energy model callback
+ // create and register energy model phy listener
Ptr wifiDevice = DynamicCast (device);
Ptr wifiPhy = wifiDevice->GetPhy ();
- DeviceEnergyModel::ChangeStateCallback callback;
- callback = MakeCallback (&DeviceEnergyModel::ChangeState, model);
- //wifiPhy->SetEnergyModelCallback (callback);
+ wifiPhy->RegisterListener (model->GetPhyListener ());
return model;
}
diff -r bc947fbfac80 -r d8909a1fd0ff src/contrib/energy/model/basic-energy-source.cc
--- a/src/contrib/energy/model/basic-energy-source.cc Mon Dec 20 15:19:11 2010 -0800
+++ b/src/contrib/energy/model/basic-energy-source.cc Mon Dec 20 15:49:12 2010 -0800
@@ -90,28 +90,25 @@
void
BasicEnergySource::SetEnergyUpdateInterval (Time interval)
{
- NS_LOG_FUNCTION (this);
+ NS_LOG_FUNCTION (this << interval);
m_energyUpdateInterval = interval;
}
Time
BasicEnergySource::GetEnergyUpdateInterval (void) const
{
- NS_LOG_FUNCTION (this);
return m_energyUpdateInterval;
}
double
BasicEnergySource::GetSupplyVoltage (void) const
{
- NS_LOG_FUNCTION (this);
return m_supplyVoltageV;
}
double
BasicEnergySource::GetInitialEnergy (void) const
{
- NS_LOG_FUNCTION (this);
return m_initialEnergyJ;
}
@@ -134,32 +131,10 @@
}
void
-BasicEnergySource::DecreaseRemainingEnergy (double energyJ)
-{
- NS_LOG_FUNCTION (this << energyJ);
- NS_ASSERT (energyJ >= 0);
- m_remainingEnergyJ -= energyJ;
- // check if remaining energy is 0
- if (m_remainingEnergyJ <= 0)
- {
- HandleEnergyDrainedEvent ();
- }
-}
-
-void
-BasicEnergySource::IncreaseRemainingEnergy (double energyJ)
-{
- NS_LOG_FUNCTION (this << energyJ);
- NS_ASSERT (energyJ >= 0);
- m_remainingEnergyJ += energyJ;
-}
-
-void
BasicEnergySource::UpdateEnergySource (void)
{
NS_LOG_FUNCTION (this);
- NS_LOG_DEBUG ("BasicEnergySource:Updating remaining energy at node #" <<
- GetNode ()->GetId ());
+ NS_LOG_DEBUG ("BasicEnergySource:Updating remaining energy.");
// do not update if simulation has finished
if (Simulator::IsFinished ())
@@ -208,8 +183,7 @@
BasicEnergySource::HandleEnergyDrainedEvent (void)
{
NS_LOG_FUNCTION (this);
- NS_LOG_DEBUG ("BasicEnergySource:Energy depleted at node #" <<
- GetNode ()->GetId ());
+ NS_LOG_DEBUG ("BasicEnergySource:Energy depleted!");
NotifyEnergyDrained (); // notify DeviceEnergyModel objects
m_remainingEnergyJ = 0; // energy never goes below 0
}
diff -r bc947fbfac80 -r d8909a1fd0ff src/contrib/energy/model/basic-energy-source.h
--- a/src/contrib/energy/model/basic-energy-source.h Mon Dec 20 15:19:11 2010 -0800
+++ b/src/contrib/energy/model/basic-energy-source.h Mon Dec 20 15:49:12 2010 -0800
@@ -68,20 +68,6 @@
virtual double GetEnergyFraction (void);
/**
- * \param energyJ Amount of energy (in Joules) to decrease from energy source.
- *
- * Implements DecreaseRemainingEnergy.
- */
- virtual void DecreaseRemainingEnergy (double energyJ);
-
- /**
- * \param energyJ Amount of energy (in Joules) to increase from energy source.
- *
- * Implements IncreaseRemainingEnergy.
- */
- virtual void IncreaseRemainingEnergy (double energyJ);
-
- /**
* Implements UpdateEnergySource.
*/
virtual void UpdateEnergySource (void);
@@ -116,7 +102,10 @@
private:
+ /// Defined in ns3::Object
void DoStart (void);
+
+ /// Defined in ns3::Object
void DoDispose (void);
/**
diff -r bc947fbfac80 -r d8909a1fd0ff src/contrib/energy/model/device-energy-model.h
--- a/src/contrib/energy/model/device-energy-model.h Mon Dec 20 15:19:11 2010 -0800
+++ b/src/contrib/energy/model/device-energy-model.h Mon Dec 20 15:49:12 2010 -0800
@@ -53,20 +53,6 @@
virtual ~DeviceEnergyModel ();
/**
- * \brief Sets pointer to node containing this EnergySource.
- *
- * \param node Pointer to node containing this EnergySource.
- */
- virtual void SetNode (Ptr node) = 0;
-
- /**
- * \brief Gets pointer to node containing this EnergySource.
- *
- * \returns Pointer to node containing this EnergySource.
- */
- virtual Ptr GetNode (void) const = 0;
-
- /**
* \param source Pointer to energy source installed on node.
*
* This function sets the pointer to energy source installed on node. Should
diff -r bc947fbfac80 -r d8909a1fd0ff src/contrib/energy/model/energy-source.cc
--- a/src/contrib/energy/model/energy-source.cc Mon Dec 20 15:19:11 2010 -0800
+++ b/src/contrib/energy/model/energy-source.cc Mon Dec 20 15:49:12 2010 -0800
@@ -47,7 +47,6 @@
void
EnergySource::SetNode (Ptr node)
{
- NS_LOG_FUNCTION (this << node);
NS_ASSERT (node != NULL);
m_node = node;
}
@@ -55,7 +54,6 @@
Ptr
EnergySource::GetNode (void) const
{
- NS_LOG_FUNCTION (this);
return m_node;
}
@@ -99,6 +97,34 @@
return container;
}
+void
+EnergySource::StartDeviceModels (void)
+{
+ /*
+ * Device models are not aggregated to the node, hence we have to manually
+ * call dispose method here.
+ */
+ DeviceEnergyModelContainer::Iterator i;
+ for (i = m_models.Begin (); i != m_models.End (); i++)
+ {
+ (*i)->Start ();
+ }
+}
+
+void
+EnergySource::DisposeDeviceModels (void)
+{
+ /*
+ * Device models are not aggregated to the node, hence we have to manually
+ * call dispose method here.
+ */
+ DeviceEnergyModelContainer::Iterator i;
+ for (i = m_models.Begin (); i != m_models.End (); i++)
+ {
+ (*i)->Dispose ();
+ }
+}
+
/*
* Private function starts here.
*/
@@ -107,7 +133,7 @@
EnergySource::DoDispose (void)
{
NS_LOG_FUNCTION (this);
- m_models.Clear ();
+ BreakDeviceEnergyModelRefCycle ();
}
/*
diff -r bc947fbfac80 -r d8909a1fd0ff src/contrib/energy/model/energy-source.h
--- a/src/contrib/energy/model/energy-source.h Mon Dec 20 15:19:11 2010 -0800
+++ b/src/contrib/energy/model/energy-source.h Mon Dec 20 15:49:12 2010 -0800
@@ -97,22 +97,6 @@
virtual double GetEnergyFraction (void) = 0;
/**
- * \param energyJ Amount of energy to decrease (in Joules)
- *
- * This function decreases the remaining energy in the energy source by the
- * specified amount. Provides linear interface for direct energy deduction.
- */
- virtual void DecreaseRemainingEnergy (double energyJ) = 0;
-
- /**
- * \param energyJ Amount of energy to increase (in Joules)
- *
- * This function increases the remaining energy in the energy source by the
- * specified amount. Provides linear interface for direct energy increase.
- */
- virtual void IncreaseRemainingEnergy (double energyJ) = 0;
-
- /**
* This function goes through the list of DeviceEnergyModels to obtain total
* current draw at the energy source and updates remaining energy. Called by
* DeviceEnergyModels to inform EnergySource of a state change.
@@ -154,11 +138,27 @@
*/
DeviceEnergyModelContainer FindDeviceEnergyModels (std::string name);
+ /**
+ * Calls Start () method of the device energy models. Device energy models are
+ * not aggregated to the node, therefore we need to manually start them here.
+ * Called by EnergySourceContainer, which is aggregated to the node.
+ */
+ void StartDeviceModels (void);
+
+ /**
+ * Calls Dispose () method of the device energy models. Device energy models
+ * are not aggregated to the node, therefore we need to manually start them
+ * here. Called by EnergySourceContainer, which is aggregated to the node.
+ */
+ void DisposeDeviceModels (void);
+
private:
/**
* All child's implementation must call BreakDeviceEnergyModelRefCycle to
* ensure reference cycles to DeviceEnergyModel objects are broken.
+ *
+ * Defined in ns3::Object
*/
virtual void DoDispose (void);
@@ -169,7 +169,8 @@
DeviceEnergyModelContainer m_models;
/**
- * Pointer to node containing this EnergySource.
+ * Pointer to node containing this EnergySource. Used by helper class to make
+ * sure device models are installed onto the corresponding node.
*/
Ptr m_node;
diff -r bc947fbfac80 -r d8909a1fd0ff src/contrib/energy/model/rv-battery-model.cc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/energy/model/rv-battery-model.cc Mon Dec 20 15:49:12 2010 -0800
@@ -0,0 +1,367 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Network Security Lab, University of Washington, Seattle.
+ *
+ * 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
+ *
+ * Authors: Sidharth Nabar , He Wu
+ */
+
+#include "rv-battery-model.h"
+#include "ns3/log.h"
+#include "ns3/assert.h"
+#include "ns3/double.h"
+#include "ns3/trace-source-accessor.h"
+#include "ns3/simulator.h"
+#include
+
+NS_LOG_COMPONENT_DEFINE ("RvBatteryModel");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (RvBatteryModel);
+
+TypeId
+RvBatteryModel::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::RvBatteryModel")
+ .SetParent ()
+ .AddConstructor ()
+ .AddAttribute ("RvBatteryModelPeriodicEnergyUpdateInterval",
+ "RV battery model sampling interval.",
+ TimeValue (Seconds (1.0)),
+ MakeTimeAccessor (&RvBatteryModel::SetSamplingInterval,
+ &RvBatteryModel::GetSamplingInterval),
+ MakeTimeChecker ())
+ .AddAttribute ("RvBatteryModelOpenCircuitVoltage",
+ "RV battery model open circuit voltage.",
+ DoubleValue (4.1),
+ MakeDoubleAccessor (&RvBatteryModel::SetOpenCircuitVoltage,
+ &RvBatteryModel::GetOpenCircuitVoltage),
+ MakeDoubleChecker ())
+ .AddAttribute ("RvBatteryModelCutoffVoltage",
+ "RV battery model cutoff voltage.",
+ DoubleValue (3.0),
+ MakeDoubleAccessor (&RvBatteryModel::SetCutoffVoltage,
+ &RvBatteryModel::GetCutoffVoltage),
+ MakeDoubleChecker ())
+ .AddAttribute ("RvBatteryModelAlphaValue",
+ "RV battery model alpha value.",
+ DoubleValue (35220.0),
+ MakeDoubleAccessor (&RvBatteryModel::SetAlpha,
+ &RvBatteryModel::GetAlpha),
+ MakeDoubleChecker ())
+ .AddAttribute ("RvBatteryModelBetaValue",
+ "RV battery model beta value.",
+ DoubleValue (0.637),
+ MakeDoubleAccessor (&RvBatteryModel::SetBeta,
+ &RvBatteryModel::GetBeta),
+ MakeDoubleChecker ())
+ .AddAttribute ("RvBatteryModelNumOfTerms",
+ "The number of terms of the infinite sum for estimating battery level.",
+ IntegerValue (10), // value used in paper
+ MakeIntegerAccessor (&RvBatteryModel::SetNumOfTerms,
+ &RvBatteryModel::GetNumOfTerms),
+ MakeIntegerChecker ())
+ .AddTraceSource ("RvBatteryModelBatteryLevel",
+ "RV battery model battery level.",
+ MakeTraceSourceAccessor (&RvBatteryModel::m_batteryLevel))
+ .AddTraceSource ("RvBatteryModelBatteryLifetime",
+ "RV battery model battery lifetime.",
+ MakeTraceSourceAccessor (&RvBatteryModel::m_lifetime))
+ ;
+ return tid;
+}
+
+RvBatteryModel::RvBatteryModel ()
+{
+ m_lastSampleTime = Seconds (0.0);
+ m_previousLoad = 0.0;
+ m_batteryLevel = 1; // fully charged
+ m_lifetime = Seconds (0.0);
+}
+
+RvBatteryModel::~RvBatteryModel ()
+{
+}
+
+double
+RvBatteryModel::GetInitialEnergy (void) const
+{
+ return m_alpha * GetSupplyVoltage ();
+}
+
+double
+RvBatteryModel::GetSupplyVoltage (void) const
+{
+ // average of Voc and Vcutoff
+ return (m_openCircuitVoltage - m_cutoffVoltage) / 2 + m_cutoffVoltage;
+}
+
+double
+RvBatteryModel::GetRemainingEnergy (void)
+{
+ NS_LOG_FUNCTION (this);
+ UpdateEnergySource ();
+ return m_alpha * GetSupplyVoltage () * m_batteryLevel;
+}
+
+double
+RvBatteryModel::GetEnergyFraction (void)
+{
+ return GetBatteryLevel ();
+}
+
+void
+RvBatteryModel::UpdateEnergySource (void)
+{
+ NS_LOG_FUNCTION (this);
+
+ // do not update if battery is already dead
+ if (m_batteryLevel <= 0)
+ {
+ NS_LOG_DEBUG ("RvBatteryModel:Battery is dead!");
+ return;
+ }
+
+ // do not update if simulation has finished
+ if (Simulator::IsFinished ())
+ {
+ return;
+ }
+
+ NS_LOG_DEBUG ("RvBatteryModel:Updating remaining energy!");
+
+ m_currentSampleEvent.Cancel ();
+
+ double currentLoad = CalculateTotalCurrent () * 1000; // must be in mA
+ double calculatedAlpha = Discharge (currentLoad, Simulator::Now ());
+
+ NS_LOG_DEBUG ("RvBatteryModel:Calculated alpha = " << calculatedAlpha <<
+ " time = " << Simulator::Now ().GetSeconds ());
+
+ // calculate battery level
+ m_batteryLevel = 1 - (calculatedAlpha / m_alpha);
+ if (m_batteryLevel < 0)
+ {
+ m_batteryLevel = 0;
+ }
+
+ // check if battery is dead.
+ if (calculatedAlpha >= m_alpha)
+ {
+ m_lifetime = Simulator::Now ();
+ NS_LOG_DEBUG ("RvBatteryModel:Battery is dead!");
+ HandleEnergyDrainedEvent ();
+ return; // stop periodic sampling
+ }
+
+ m_previousLoad = currentLoad;
+ m_lastSampleTime = Simulator::Now ();
+ m_currentSampleEvent = Simulator::Schedule (m_samplingInterval,
+ &RvBatteryModel::UpdateEnergySource,
+ this);
+}
+
+void
+RvBatteryModel::SetSamplingInterval (Time interval)
+{
+ NS_LOG_FUNCTION (this << interval);
+ m_samplingInterval = interval;
+}
+
+Time
+RvBatteryModel::GetSamplingInterval (void) const
+{
+ return m_samplingInterval;
+}
+
+void
+RvBatteryModel::SetOpenCircuitVoltage (double voltage)
+{
+ NS_LOG_FUNCTION (this << voltage);
+ NS_ASSERT (voltage >= 0);
+ m_openCircuitVoltage = voltage;
+}
+
+double
+RvBatteryModel::GetOpenCircuitVoltage (void) const
+{
+ return m_openCircuitVoltage;
+}
+
+void
+RvBatteryModel::SetCutoffVoltage (double voltage)
+{
+ NS_LOG_FUNCTION (this << voltage);
+ NS_ASSERT (voltage <= m_openCircuitVoltage);
+ m_cutoffVoltage = voltage;
+}
+
+double
+RvBatteryModel::GetCutoffVoltage (void) const
+{
+ return m_cutoffVoltage;
+}
+
+void
+RvBatteryModel::SetAlpha (double alpha)
+{
+ NS_LOG_FUNCTION (this << alpha);
+ NS_ASSERT (alpha >= 0);
+ m_alpha = alpha;
+}
+
+double
+RvBatteryModel::GetAlpha (void) const
+{
+ return m_alpha;
+}
+
+void
+RvBatteryModel::SetBeta (double beta)
+{
+ NS_LOG_FUNCTION (this << beta);
+ NS_ASSERT (beta >= 0);
+ m_beta = beta;
+}
+
+double
+RvBatteryModel::GetBeta (void) const
+{
+ return m_beta;
+}
+
+double
+RvBatteryModel::GetBatteryLevel (void)
+{
+ NS_LOG_FUNCTION (this);
+ UpdateEnergySource ();
+ return m_batteryLevel;
+}
+
+Time
+RvBatteryModel::GetLifetime (void) const
+{
+ return m_lifetime;
+}
+
+void
+RvBatteryModel::SetNumOfTerms (int num)
+{
+ NS_LOG_FUNCTION (this << num);
+ m_numOfTerms = num;
+}
+
+int
+RvBatteryModel::GetNumOfTerms (void) const
+{
+ return m_numOfTerms;
+}
+
+/*
+ * Private functions start here.
+ */
+
+void
+RvBatteryModel::DoStart (void)
+{
+ NS_LOG_DEBUG ("RvBatteryModel:Starting battery level update!");
+ UpdateEnergySource (); // start periodic sampling of load (total current)
+}
+
+void
+RvBatteryModel::DoDispose (void)
+{
+ BreakDeviceEnergyModelRefCycle (); // break reference cycle
+}
+
+void
+RvBatteryModel::HandleEnergyDrainedEvent (void)
+{
+ NS_LOG_FUNCTION (this);
+ NS_LOG_DEBUG ("RvBatteryModel:Energy depleted!");
+ NotifyEnergyDrained (); // notify DeviceEnergyModel objects
+}
+
+double
+RvBatteryModel::Discharge (double load, Time t)
+{
+ NS_LOG_FUNCTION (this << load << t);
+
+ // record only when load changes
+ if (load != m_previousLoad)
+ {
+ m_load.push_back (load);
+ m_previousLoad = load;
+ if (t != Seconds (0.0))
+ {
+ m_timeStamps[m_timeStamps.size () - 1] = m_lastSampleTime;
+ }
+ else
+ {
+ m_timeStamps.push_back (Seconds (0.0));
+ }
+ m_timeStamps.push_back (t);
+ }
+ else
+ {
+ m_timeStamps[m_timeStamps.size () - 1] = t;
+ }
+
+ m_lastSampleTime = t;
+
+ // calculate alpha for new t
+ NS_ASSERT (m_load.size () == m_timeStamps.size () - 1); // size must be equal
+ double calculatedAlpha = 0.0;
+ if (m_timeStamps.size () == 1)
+ {
+ // constant load
+ calculatedAlpha = m_load[0] * RvModelAFunction (t, t, Seconds(0.0),
+ m_beta);
+ }
+ else
+ {
+ // changing load
+ for (uint64_t i = 1; i < m_timeStamps.size (); i++)
+ {
+ calculatedAlpha += m_load[i - 1] * RvModelAFunction (t, m_timeStamps[i],
+ m_timeStamps[i - 1],
+ m_beta);
+ }
+ }
+
+ return calculatedAlpha;
+}
+
+double
+RvBatteryModel::RvModelAFunction (Time t, Time sk, Time sk_1, double beta)
+{
+ NS_LOG_FUNCTION (this << t << sk << sk_1 << beta);
+
+ // everything is in minutes
+ double firstDelta = (t.GetSeconds () - sk.GetSeconds ()) / 60;
+ double secondDelta = (t.GetSeconds () - sk_1.GetSeconds ()) / 60;
+ double delta = (sk.GetSeconds () - sk_1.GetSeconds ()) / 60;
+
+ double sum = 0.0;
+ for (int m = 1; m <= m_numOfTerms; m++)
+ {
+ double square = beta * beta * m * m;
+ sum += (exp (- square * (firstDelta)) - exp (- square * (secondDelta))) / square;
+ }
+ return delta + 2 * sum;
+}
+
+} // namespace ns3
diff -r bc947fbfac80 -r d8909a1fd0ff src/contrib/energy/model/rv-battery-model.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/energy/model/rv-battery-model.h Mon Dec 20 15:49:12 2010 -0800
@@ -0,0 +1,259 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Network Security Lab, University of Washington, Seattle.
+ *
+ * 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
+ *
+ * Authors: Sidharth Nabar , He Wu
+ */
+
+#ifndef RV_BATTERY_MODEL_H
+#define RV_BATTERY_MODEL_H
+
+#include "ns3/traced-value.h"
+#include "ns3/nstime.h"
+#include "ns3/event-id.h"
+#include "energy-source.h"
+
+namespace ns3 {
+
+/**
+ * \brief Rakhmatov Vrudhula non-linear battery model.
+ *
+ * This (energy source) model implements an analytical non-linear battery model.
+ * It is capable of capturing load capacity and recovery effects of batteries.
+ * Batteries are characterized by 2 parameters, alpha and beta, which can both
+ * be obtained from the discharge curve of the batteries.
+ *
+ * The model is developed by Daler Rakhmatov & Sarma Vrudhula in: "Battery
+ * Lifetime Prediction for Energy-Aware Computing" and "An Analytical High-Level
+ * Battery Model for Use in Energy Management of Portable Electronic Systems".
+ *
+ * The real-time algorithm is developed by Matthias Handy & Dirk Timmermann in:
+ * "Simulation of Mobile Wireless Networks with Accurate Modeling of non-linear
+ * battery effects". The real-time algorithm is modified by the authors of this
+ * code for improved accuracy and reduced computation (sampling) overhead.
+ */
+class RvBatteryModel : public EnergySource
+{
+public:
+ static TypeId GetTypeId (void);
+ RvBatteryModel ();
+ virtual ~RvBatteryModel ();
+
+ /**
+ * \return Initial energy stored (theoretical capacity) in the battery.
+ *
+ * Implements GetInitialEnergy.
+ */
+ virtual double GetInitialEnergy (void) const;
+
+ /**
+ * \returns Supply voltage at the energy source.
+ *
+ * Implements GetSupplyVoltage.
+ */
+ virtual double GetSupplyVoltage (void) const;
+
+ /**
+ * \return Remaining energy in energy source, in Joules
+ *
+ * Implements GetRemainingEnergy.
+ */
+ virtual double GetRemainingEnergy (void);
+
+ /**
+ * \returns Energy fraction.
+ *
+ * Implements GetEnergyFraction. For the RV battery model, energy fraction is
+ * equivalent to battery level.
+ */
+ virtual double GetEnergyFraction (void);
+
+ /**
+ * Implements UpdateEnergySource. This function samples the total load (total
+ * current) from all devices to discharge the battery.
+ */
+ virtual void UpdateEnergySource (void);
+
+ /**
+ * \param interval Energy update interval.
+ *
+ * This function sets the interval between each energy update.
+ */
+ void SetSamplingInterval (Time interval);
+
+ /**
+ * \returns The interval between each energy update.
+ */
+ Time GetSamplingInterval (void) const;
+
+ /**
+ * \brief Sets open circuit voltage of battery.
+ *
+ * \param voltage Open circuit voltage.
+ */
+ void SetOpenCircuitVoltage (double voltage);
+
+ /**
+ * \return Open circuit voltage of battery.
+ */
+ double GetOpenCircuitVoltage (void) const;
+
+ /**
+ * \brief Sets cutoff voltage of battery.
+ *
+ * \param voltage Cutoff voltage.
+ */
+ void SetCutoffVoltage (double voltage);
+
+ /**
+ * \returns Cutoff voltage of battery.
+ */
+ double GetCutoffVoltage (void) const;
+
+ /**
+ * \brief Sets the alpha value for the battery model.
+ *
+ * \param alpha Alpha.
+ */
+ void SetAlpha (double alpha);
+
+ /**
+ * \returns The alpha value used by the battery model.
+ */
+ double GetAlpha (void) const;
+
+ /**
+ * \brief Sets the beta value for the battery model.
+ *
+ * \param beta Beta.
+ */
+ void SetBeta (double beta);
+
+ /**
+ * \returns The beta value used by the battery model.
+ */
+ double GetBeta (void) const;
+
+ /**
+ * \returns Battery level [0, 1].
+ */
+ double GetBatteryLevel (void);
+
+ /**
+ * \returns Lifetime of the battery.
+ */
+ Time GetLifetime (void) const;
+
+ /**
+ * \brief Sets the number of terms of the infinite sum for estimating battery
+ * level.
+ *
+ * \param num Number of terms.
+ */
+ void SetNumOfTerms (int num);
+
+ /**
+ * \returns The number of terms of the infinite sum for estimating battery
+ * level.
+ */
+ int GetNumOfTerms (void) const;
+
+private:
+ /// Defined in ns3::Object
+ virtual void DoStart (void);
+
+ /// Defined in ns3::Object
+ virtual void DoDispose (void);
+
+ /**
+ * Handles the remaining energy going to zero event. This function notifies
+ * all the energy models aggregated to the node about the energy being
+ * depleted. Each energy model is then responsible for its own handler.
+ */
+ void HandleEnergyDrainedEvent (void);
+
+ /**
+ * \brief Discharges the battery.
+ *
+ * \param load Load value (total current form devices, in mA).
+ * \param t Time stamp of the load value.
+ * \returns Calculated alpha value.
+ *
+ * Discharge function calculates a value which is then compared to the alpha
+ * value to determine if the battery is dead. It will also update the battery
+ * level.
+ *
+ * Note that the load value passed to Discharge has to be in mA.
+ */
+ double Discharge (double load, Time t);
+
+ /**
+ * \brief RV model A function.
+ *
+ * \param t Current time.
+ * \param sk Time stamp in array position k
+ * \param sk_1 Time stamp in array position k-1
+ * \param beta Beta value used by the battery model.
+ * \returns Result of A function.
+ *
+ * This function computes alpha value using the recorded load profile.
+ */
+ double RvModelAFunction (Time t, Time sk, Time sk_1, double beta);
+
+private:
+ double m_openCircuitVoltage;
+ double m_cutoffVoltage;
+ double m_alpha; // alpha value of RV model, in Coulomb
+ double m_beta; // beta value of RV model, in second^-1
+
+ double m_previousLoad; // load value (total current) of previous sampling
+ std::vector m_load; // load profile
+ std::vector