From 2d87e8d3265f2d231280593bcdf7ce1d123fffc3 Mon Sep 17 00:00:00 2001 From: He Wu Date: Wed, 7 Jul 2010 21:54:32 -0700 Subject: [PATCH] Initial import of energy model --- AUTHORS | 2 + RELEASE_NOTES | 4 + .../helper/basic-energy-source-helper.cc | 67 ++++ .../helper/basic-energy-source-helper.h | 52 +++ .../helper/basic-radio-energy-model-helper.cc | 96 +++++ .../helper/basic-radio-energy-model-helper.h | 90 +++++ .../energy/helper/energy-model-helper.cc | 114 ++++++ .../energy/helper/energy-model-helper.h | 189 +++++++++ .../energy/model/basic-energy-source.cc | 133 +++++++ .../energy/model/basic-energy-source.h | 95 +++++ .../energy/model/basic-radio-energy-model.cc | 312 +++++++++++++++ .../energy/model/basic-radio-energy-model.h | 159 ++++++++ .../energy/model/device-energy-model.cc | 99 +++++ .../energy/model/device-energy-model.h | 96 +++++ src/contrib/energy/model/energy-source.cc | 157 ++++++++ src/contrib/energy/model/energy-source.h | 158 ++++++++ .../energy/model/radio-energy-model.cc | 100 +++++ src/contrib/energy/model/radio-energy-model.h | 186 +++++++++ .../energy/test/basic-energy-model-test.cc | 358 ++++++++++++++++++ src/contrib/energy/wscript | 28 ++ src/wscript | 1 + 21 files changed, 2496 insertions(+) create mode 100644 src/contrib/energy/helper/basic-energy-source-helper.cc create mode 100644 src/contrib/energy/helper/basic-energy-source-helper.h create mode 100644 src/contrib/energy/helper/basic-radio-energy-model-helper.cc create mode 100644 src/contrib/energy/helper/basic-radio-energy-model-helper.h create mode 100644 src/contrib/energy/helper/energy-model-helper.cc create mode 100644 src/contrib/energy/helper/energy-model-helper.h create mode 100644 src/contrib/energy/model/basic-energy-source.cc create mode 100644 src/contrib/energy/model/basic-energy-source.h create mode 100644 src/contrib/energy/model/basic-radio-energy-model.cc create mode 100644 src/contrib/energy/model/basic-radio-energy-model.h create mode 100644 src/contrib/energy/model/device-energy-model.cc create mode 100644 src/contrib/energy/model/device-energy-model.h create mode 100644 src/contrib/energy/model/energy-source.cc create mode 100644 src/contrib/energy/model/energy-source.h create mode 100644 src/contrib/energy/model/radio-energy-model.cc create mode 100644 src/contrib/energy/model/radio-energy-model.h create mode 100644 src/contrib/energy/test/basic-energy-model-test.cc create mode 100644 src/contrib/energy/wscript diff --git a/AUTHORS b/AUTHORS index a434214f9..720825a22 100644 --- a/AUTHORS +++ b/AUTHORS @@ -37,6 +37,7 @@ Francesco Malandrino (francesco.malandrino@gmail.com) Fabian Mauchle (f1mauchl@hsr.ch) Andrey Mazo (mazo@iitp.ru) Faker Moatamri (faker.moatamri@sophia.inria.fr) +Sidharth Nabar (snabar@uw.edu) Michael Nowatkowski (nowatkom@gmail.com) Duy Nguyen (duy@soe.ucsc.edu) Tommaso Pecorella (tommaso.pecorella@unifi.it) @@ -63,3 +64,4 @@ Guillaume Vu-Brugier (gvubrugier@gmail.com) Tom Wambold (tom5760@gmail.com) Danqi Wang (beyondwdq@gmail.com) Florian Westphal (fw@strlen.de) +He Wu (mdzz@u.washington.edu) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index ebad27363..260ff8993 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -45,6 +45,10 @@ New user-visible features - A brand new NS-2 mobility trace reader supports BonnMotion, SUMO, TraNS, etc. traces. + - An energy model for nodes and devices, including an energy source + model and device energy models allowing energy-aware devices + to notify the energy source about energy consumption. + Bugs fixed ---------- The following lists many of the bugs that were fixed since ns-3.7, in diff --git a/src/contrib/energy/helper/basic-energy-source-helper.cc b/src/contrib/energy/helper/basic-energy-source-helper.cc new file mode 100644 index 000000000..11db73791 --- /dev/null +++ b/src/contrib/energy/helper/basic-energy-source-helper.cc @@ -0,0 +1,67 @@ +/* -*- 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 "basic-energy-source-helper.h" +#include "ns3/energy-source.h" + +namespace ns3 { + +BasicEnergySourceHelper::BasicEnergySourceHelper () +{ + m_basicEnergySource.SetTypeId ("ns3::BasicEnergySource"); +} + +BasicEnergySourceHelper::~BasicEnergySourceHelper () +{ +} + +void +BasicEnergySourceHelper::Set (std::string name, const AttributeValue &v) +{ + m_basicEnergySource.Set (name, v); +} + +Ptr +BasicEnergySourceHelper::Create (void) const +{ + Ptr source = m_basicEnergySource.Create (); + NS_ASSERT (source != 0); + return source; +} + +void +BasicEnergySourceHelper::Install (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!"); + return; + } + // create energy source + source = Create (); + NS_ASSERT (source != NULL); + // aggregate source to node + node->AggregateObject (source); +} + +} // namespace ns3 diff --git a/src/contrib/energy/helper/basic-energy-source-helper.h b/src/contrib/energy/helper/basic-energy-source-helper.h new file mode 100644 index 000000000..6dcd144ff --- /dev/null +++ b/src/contrib/energy/helper/basic-energy-source-helper.h @@ -0,0 +1,52 @@ +/* -*- 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 BASIC_ENERGY_SOURCE_HELPER +#define BASIC_ENERGY_SOURCE_HELPER + +#include "energy-model-helper.h" + +namespace ns3 { + +class Node; + +/** + * \brief Creates a BasicEnergySource object. + */ +class BasicEnergySourceHelper : public EnergySourceHelper +{ +public: + BasicEnergySourceHelper (); + ~BasicEnergySourceHelper (); + + void Set (std::string name, const AttributeValue &v); + + Ptr Create (void) const; + + void Install (Ptr node) const; + +private: + ObjectFactory m_basicEnergySource; + +}; + +} // namespace ns3 + +#endif /* BASIC_ENERGY_SOURCE_HELPER */ diff --git a/src/contrib/energy/helper/basic-radio-energy-model-helper.cc b/src/contrib/energy/helper/basic-radio-energy-model-helper.cc new file mode 100644 index 000000000..f732d3d35 --- /dev/null +++ b/src/contrib/energy/helper/basic-radio-energy-model-helper.cc @@ -0,0 +1,96 @@ +/* -*- 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 "basic-radio-energy-model-helper.h" +#include "basic-energy-source-helper.h" +#include "ns3/radio-energy-model.h" +#include "ns3/config.h" +#include "ns3/names.h" +#include "ns3/log.h" + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("BasicRadioEnergyModelHelper"); + +BasicRadioEnergyModelHelper::BasicRadioEnergyModelHelper () +{ + m_radioEnergy.SetTypeId ("ns3::BasicRadioEnergyModel"); + m_depletionCallback.Nullify (); +} + +BasicRadioEnergyModelHelper::~BasicRadioEnergyModelHelper () +{ +} + +void +BasicRadioEnergyModelHelper::Set (std::string name, const AttributeValue &v) +{ + m_radioEnergy.Set (name, v); +} + +Ptr +BasicRadioEnergyModelHelper::Create (void) const +{ + return m_radioEnergy.Create (); +} + +void +BasicRadioEnergyModelHelper::SetDepletionCallback ( + BasicRadioEnergyModel::BasicEnergyDepletionCallback callback) +{ + m_depletionCallback = callback; +} + +/* + * Private function starts here. + */ + +void +BasicRadioEnergyModelHelper::DoInstall (Ptr node) const +{ + NS_LOG_FUNCTION (this << node); + // check if energy source is installed + Ptr source = node->GetObject (); + if (source != NULL) + { + Ptr model = m_radioEnergy.Create ()-> + GetObject (); + if (model == NULL) + { + NS_FATAL_ERROR ( "The requested radio energy model does not exist: " + << m_radioEnergy.GetTypeId ().GetName ()); + } + else + { + // 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); + } + } + else + { + NS_FATAL_ERROR ("Energy source NOT installed!"); + } +} + +} // namespace ns3 diff --git a/src/contrib/energy/helper/basic-radio-energy-model-helper.h b/src/contrib/energy/helper/basic-radio-energy-model-helper.h new file mode 100644 index 000000000..935ee7000 --- /dev/null +++ b/src/contrib/energy/helper/basic-radio-energy-model-helper.h @@ -0,0 +1,90 @@ +/* -*- 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 +*/ + +#ifndef BASIC_RADIO_ENERGY_MODEL_HELPER_H +#define BASIC_RADIO_ENERGY_MODEL_HELPER_H + +#include "energy-model-helper.h" +#include "ns3/device-energy-model.h" +#include "ns3/basic-radio-energy-model.h" + +namespace ns3 { + +/** + * \brief Assign energy model to nodes. + * + * This installer is used for BasicRadioEnergyModel. + */ +class BasicRadioEnergyModelHelper : public DeviceEnergyModelHelper +{ +public: + /** + * Construct a helper which is used to add a radio energy model to a node + */ + BasicRadioEnergyModelHelper (); + + /** + * Destroy a RadioEnergy Helper + */ + ~BasicRadioEnergyModelHelper (); + + /** + * \param name the name of the attribute to set + * \param v the value of the attribute + * + * Sets an attribute of the underlying PHY object. + */ + void Set (std::string name, const AttributeValue &v); + + /** + * \returns A newly created RadioEnergySource object. + */ + Ptr Create (void) const; + + /** + * \param callback Callback function for energy depletion handling. + * + * Sets the callback to be invoked when energy is depleted. + */ + void SetDepletionCallback ( + BasicRadioEnergyModel::BasicEnergyDepletionCallback callback); + + +private: + /** + * \brief Add an energy model to the specified node. + * + * \param node The node on which the energy model is to be installed. + * + * This method creates an instance of a ns3::BasicRadioEnergyModel and + * aggregates it to the given node. + */ + void DoInstall (Ptr node) const; + +private: + ObjectFactory m_radioEnergy; + /// Callback function for energy depletion. + BasicRadioEnergyModel::BasicEnergyDepletionCallback m_depletionCallback; + +}; + +} // namespace ns3 + +#endif /* BASIC_RADIO_ENERGY_MODEL_HELPER_H */ diff --git a/src/contrib/energy/helper/energy-model-helper.cc b/src/contrib/energy/helper/energy-model-helper.cc new file mode 100644 index 000000000..0b55a90db --- /dev/null +++ b/src/contrib/energy/helper/energy-model-helper.cc @@ -0,0 +1,114 @@ +/* -*- 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 "energy-model-helper.h" +#include "ns3/log.h" +#include "ns3/config.h" +#include "ns3/names.h" + +namespace ns3 { + +/* + * EnergySourceHelper + */ +EnergySourceHelper::~EnergySourceHelper () +{ +} + +/* + * DeviceEnergyModelHelper + */ +DeviceEnergyModelHelper::~DeviceEnergyModelHelper () +{ +} + +void +DeviceEnergyModelHelper::Install (Ptr node) const +{ + NS_ASSERT (node != NULL); + DoInstall (node); +} + +void +DeviceEnergyModelHelper::Install (NodeContainer c) const +{ + for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i) + { + Install (*i); + } +} + +void +DeviceEnergyModelHelper::Install (std::string nodeName) const +{ + Ptr node = Names::Find (nodeName); + Install (node); +} + +void +DeviceEnergyModelHelper::InstallAll (void) const +{ + Install (NodeContainer::GetGlobal ()); +} + +/* + * EnergyModelHelper + */ +EnergyModelHelper::EnergyModelHelper () +{ +} + +void +EnergyModelHelper::Install (const EnergySourceHelper &sourceHelper, + const DeviceEnergyModelHelper &modelHelper, Ptr node) const +{ + NS_ASSERT (node != NULL); + // install source. source must be installed before installing device model. + sourceHelper.Install (node); + // install device model + modelHelper.Install (node); +} + +void +EnergyModelHelper::Install (const EnergySourceHelper &sourceHelper, + const DeviceEnergyModelHelper &modelHelper, NodeContainer c) const +{ + for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i) + { + Install (sourceHelper, modelHelper, *i); + } +} + +void +EnergyModelHelper::Install (const EnergySourceHelper &sourceHelper, + const DeviceEnergyModelHelper &modelHelper, std::string nodeName) const +{ + Ptr node = Names::Find (nodeName); + Install (sourceHelper, modelHelper, node); +} + +void +EnergyModelHelper::InstallAll (const EnergySourceHelper &sourceHelper, + const DeviceEnergyModelHelper &modelHelper) const +{ + Install (sourceHelper, modelHelper, NodeContainer::GetGlobal ()); +} + +} // namespace ns3 diff --git a/src/contrib/energy/helper/energy-model-helper.h b/src/contrib/energy/helper/energy-model-helper.h new file mode 100644 index 000000000..47c66c982 --- /dev/null +++ b/src/contrib/energy/helper/energy-model-helper.h @@ -0,0 +1,189 @@ +/* -*- 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 ENERGY_MODEL_HELPER +#define ENERGY_MODEL_HELPER + +#include "ns3/attribute.h" +#include "ns3/object-factory.h" +#include "ns3/node-container.h" +#include "ns3/ptr.h" +#include "ns3/energy-source.h" +#include "ns3/device-energy-model.h" + +namespace ns3 { + +/** + * \brief Creates EnergySource objects. + * + * This class creates and installs an energy source onto network nodes. This + * base class must be implemented by new EnergySource implementation which wish + * to integrate with the \ref ns3::EnergyModelHelper class. + */ +class EnergySourceHelper +{ +public: + virtual ~EnergySourceHelper (); + + /** + * \returns A newly created EnergySource object. + * Subclasses must implement this methods to allow the ns3::EnergySource class + * to create DeviceEnergyModel object for installation. + */ + virtual Ptr Create (void) const = 0; + + /** + * \param node Pointer to the node where EnergySource will be installed on. + * + * This method installs an EnergySource onto a node. Must be implemented by + * subclasses. + */ + virtual void Install (Ptr node) const = 0; + +}; + + +/** + * \brief Creates DeviceEnergyModel objects + * + * This class can help to create and install an DeviceEnergyModel onto network + * nodes. It can be called separately to install extra DeviceEnergyModels onto + * the same nodes. This base class must be implemented by new DeviceEnergyModel + * which wishes to integrate with the \ref ns3::EnergyModelHelper class. + * + * Note that DeviceEnergyModel objects are *not* aggregated onto the node. They + * can be accessed through the EnergySource object, which *is* aggregated onto + * the node. + */ +class DeviceEnergyModelHelper +{ +public: + virtual ~DeviceEnergyModelHelper (); + + /** + * \returns A newly created DeviceEnergySource object. + * + * Subclasses must implement this method to allow the ns3::DeviceEnergyModel + * class to create DeviceEnergyModel object for installation. + */ + virtual Ptr Create (void) const = 0; + + /** + * \param name Name of attribute to set. + * \param v Value of the attribute. + * + * Sets one of the attributes of underlying DeviceEnergyModel. + */ + virtual void Set (std::string name, const AttributeValue &v) = 0; + + /** + * \param node The node on which a DeviceEnergyModel object must be created. + * + * Installs an DeviceEnergyModel onto a node. Subclasses must implement this + * method. + */ + void Install (Ptr node) const; + + /** + * \param c The set of nodes on which a jammer object must be created. + * + * Installs DeviceEnergyModel onto a list of nodes. Calls Install (Ptr + * node). + */ + void Install (NodeContainer c) const; + + /** + * \param nodeName The name of node. + * + * Calls Install (Ptr node). + */ + void Install (std::string nodeName) const; + + /** + * Install on *ALL* nodes exists in simulation. + */ + void InstallAll (void) const; + + +private: + /** + * \param node The node on which a DeviceEnergyModel object must be created. + * + * Implements Install (Ptr). Subclasses must implement this method. + */ + virtual void DoInstall (Ptr node) const = 0; + +}; + + +/** + * \brief Creates EnergySource and DeviceEnergyModel objects. + * + * This class helps to create EnergySource and DeviceEnergyModel objects. Note + * that only a single EnergySource can exist on the same node where multiple + * DeviceEnergyModel can coexist on the same node. Extra DeviceEnergyModels can + * be installed by DeviceEnergyModelHelper. + */ +class EnergyModelHelper +{ +public: + /** + * Create an EnergyModelHelper in an empty state: all its parameters must be + * set before calling ns3::EnergyModelHelper::Install. + */ + EnergyModelHelper (); + + /** + * \param source The EnergySourceHelper to create EnergySource. + * \param model The DeviceEnergyModelHelper to create DeviceEnergyModel. + * \param node The node on which the energy model will be installed on. + */ + void Install (const EnergySourceHelper &sourceHelper, + const DeviceEnergyModelHelper &modelHelper, Ptr node) const; + + /** + * \param source The EnergySourceHelper to create EnergySource. + * \param model The DeviceEnergyModelHelper to create DeviceEnergyModel. + * \param node List of node on which the energy model will be installed on. + */ + void Install (const EnergySourceHelper &sourceHelper, + const DeviceEnergyModelHelper &modelHelper, NodeContainer c) const; + + /** + * \param source The EnergySourceHelper to create EnergySource. + * \param model The DeviceEnergyModelHelper to create DeviceEnergyModel. + * \param node name of node on which the energy model will be installed on. + */ + void Install (const EnergySourceHelper &sourceHelper, + const DeviceEnergyModelHelper &modelHelper, std::string nodeName) const; + + /** + * \param source The EnergySourceHelper to create EnergySource. + * \param model The DeviceEnergyModelHelper to create DeviceEnergyModel. + * \param node name of node on which the energy model will be installed on. + */ + void InstallAll (const EnergySourceHelper &sourceHelper, + const DeviceEnergyModelHelper &modelHelper) const; + +}; + +} // namespace ns3 + +#endif /* ENERGY_MODEL_HELPER */ diff --git a/src/contrib/energy/model/basic-energy-source.cc b/src/contrib/energy/model/basic-energy-source.cc new file mode 100644 index 000000000..79377ccf5 --- /dev/null +++ b/src/contrib/energy/model/basic-energy-source.cc @@ -0,0 +1,133 @@ +/* -*- 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 "basic-energy-source.h" +#include "ns3/log.h" +#include "ns3/assert.h" +#include "ns3/double.h" +#include "ns3/trace-source-accessor.h" + +NS_LOG_COMPONENT_DEFINE ("BasicEnergySource"); + +namespace ns3 { + +NS_OBJECT_ENSURE_REGISTERED (BasicEnergySource); + +TypeId +BasicEnergySource::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::BasicEnergySource") + .SetParent () + .AddConstructor () + .AddAttribute ("BasicEnergySourceInitialEnergyJ", + "Initial energy stored in basic energy source.", + DoubleValue (10), // in Joules + MakeDoubleAccessor (&BasicEnergySource::SetInitialEnergy, + &BasicEnergySource::DoGetInitialEnergy), + MakeDoubleChecker ()) + .AddTraceSource ("RemainingEnergy", + "Remaining energy at BasicEnergySource.", + MakeTraceSourceAccessor (&BasicEnergySource::m_remainingEnergyJ)) + ; + return tid; +} + +BasicEnergySource::BasicEnergySource () +{ +} + +BasicEnergySource::~BasicEnergySource () +{ +} + +void +BasicEnergySource::SetInitialEnergy (double initialEnergyJ) +{ + NS_LOG_FUNCTION (this << initialEnergyJ); + NS_ASSERT (initialEnergyJ >= 0); + m_initialEnergyJ = initialEnergyJ; + // set remaining energy to be initial energy + m_remainingEnergyJ = m_initialEnergyJ; +} + +/* + * Private functions start here. + */ + +void +BasicEnergySource::DoDispose (void) +{ + NS_LOG_FUNCTION (this); + BreakDeviceEnergyModelRefCycle (); // break reference cycle +} + +double +BasicEnergySource::DoGetInitialEnergy (void) const +{ + NS_LOG_FUNCTION (this); + return m_initialEnergyJ; +} + +double +BasicEnergySource::DoGetRemainingEnergy (void) const +{ + NS_LOG_FUNCTION (this); + return m_remainingEnergyJ; +} + +void +BasicEnergySource::DoDecreaseRemainingEnergy (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::HandleEnergyDrainedEvent (void) +{ + NS_LOG_FUNCTION (this); + NS_LOG_DEBUG ("BasicEnergySource:Energy depleted!"); + NotifyEnergyDrained (); // notify DeviceEnergyModel objects + // energy never goes below 0 + m_remainingEnergyJ = 0; +} + +void +BasicEnergySource::DoIncreaseRemainingEnergy (double energyJ) +{ + NS_LOG_FUNCTION (this << energyJ); + NS_ASSERT (energyJ >= 0); + m_remainingEnergyJ += energyJ; +} + +double +BasicEnergySource::DoGetEnergyFraction (void) const +{ + NS_LOG_FUNCTION (this); + return m_remainingEnergyJ / m_initialEnergyJ; +} + +} // namespace ns3 diff --git a/src/contrib/energy/model/basic-energy-source.h b/src/contrib/energy/model/basic-energy-source.h new file mode 100644 index 000000000..8e007aca5 --- /dev/null +++ b/src/contrib/energy/model/basic-energy-source.h @@ -0,0 +1,95 @@ +/* -*- 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 BASIC_ENERGY_SOURCE +#define BASIC_ENERGY_SOURCE + +#include "ns3/traced-value.h" +#include "energy-source.h" + +namespace ns3 { + +class BasicEnergySource : public EnergySource +{ +public: + static TypeId GetTypeId (void); + BasicEnergySource (); + virtual ~BasicEnergySource (); + + + /** + * \param initialEnergy Initial energy, in Joules + * + * Implements SetInitialEnergy. Note that initial energy is assumed to be set + * before simulation starts and is set only once per simulation. + */ + void SetInitialEnergy (double initialEnergyJ); + + +private: + void DoDispose (void); + + /** + * \return Initial energy stored in energy source, in Joules. + * + * Implements GetInitialEnergy. + */ + double DoGetInitialEnergy (void) const; + + /** + * \return Remaining energy in energy source, in Joules + * + * Implements GetRemainingEnergy. + */ + double DoGetRemainingEnergy (void) const; + + /** + * \param energy Amount of energy (in Joules) to decrease from energy source. + * + * Implements DecreaseRemainingEnergy. + */ + void DoDecreaseRemainingEnergy (double energyJ); + + /** + * 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); + + /** + * \param energy Amount of energy (in Joules) to increase from energy source. + * + * Implements IncreaseRemainingEnergy. + */ + void DoIncreaseRemainingEnergy (double energyJ); + + /// Implements GetEnergyFraction. + double DoGetEnergyFraction (void) const; + +private: + double m_initialEnergyJ; // initial energy, in Joules + TracedValue m_remainingEnergyJ; // remaining energy, in Joules + +}; + +} // namespace ns3 + +#endif /* BASIC_ENERGY_SOURCE */ diff --git a/src/contrib/energy/model/basic-radio-energy-model.cc b/src/contrib/energy/model/basic-radio-energy-model.cc new file mode 100644 index 000000000..ee016926b --- /dev/null +++ b/src/contrib/energy/model/basic-radio-energy-model.cc @@ -0,0 +1,312 @@ +/* -*- 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/log.h" +#include "ns3/double.h" +#include "ns3/simulator.h" +#include "ns3/trace-source-accessor.h" +#include "basic-radio-energy-model.h" + +NS_LOG_COMPONENT_DEFINE ("BasicRadioEnergyModel"); + +namespace ns3 { + +NS_OBJECT_ENSURE_REGISTERED (BasicRadioEnergyModel); + +TypeId +BasicRadioEnergyModel::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::BasicRadioEnergyModel") + .SetParent () + .AddConstructor () + .AddAttribute ("TxPowerW", + "The radio Tx power in Watts.", + DoubleValue (0.0435), // typical CC2420 value + MakeDoubleAccessor (&BasicRadioEnergyModel::SetTxPowerW, + &BasicRadioEnergyModel::GetTxPowerW), + MakeDoubleChecker ()) + .AddAttribute ("RxPowerW", + "The radio Rx power in Watts.", + DoubleValue (0.047), // typical CC2420 value + MakeDoubleAccessor (&BasicRadioEnergyModel::SetRxPowerW, + &BasicRadioEnergyModel::GetRxPowerW), + MakeDoubleChecker ()) + .AddAttribute ("IdlePowerW", + "The default radio Idle power in Watts.", + DoubleValue (0.001065), // typical CC2420 value + MakeDoubleAccessor (&BasicRadioEnergyModel::SetIdlePowerW, + &BasicRadioEnergyModel::GetIdlePowerW), + MakeDoubleChecker ()) + .AddAttribute ("SleepPowerW", + "The default radio Sleep power in Watts.", + DoubleValue (0.00005), // typical CC2420 value + MakeDoubleAccessor (&BasicRadioEnergyModel::SetSleepPowerW, + &BasicRadioEnergyModel::GetSleepPowerW), + MakeDoubleChecker ()) + .AddAttribute ("PeriodicEnergyUpdateInterval", + "Time between two consecutive periodic energy updates.", + TimeValue (Seconds (1.0)), + MakeTimeAccessor (&BasicRadioEnergyModel::SetEnergyUpdateInterval, + &BasicRadioEnergyModel::GetEnergyUpdateInterval), + MakeTimeChecker ()) + .AddTraceSource ("TotalEnergyConsumption", + "Total energy consumption of the radio device.", + MakeTraceSourceAccessor (&BasicRadioEnergyModel::m_totalEnergyConsumption)) + ; + return tid; +} + +BasicRadioEnergyModel::BasicRadioEnergyModel () +{ + NS_LOG_FUNCTION (this); + m_currentState = IDLE; + m_lastUpdateTime = Seconds (0.0); + m_energyDepletionCallback.Nullify (); + /* + * Start scheduling the periodic energy update event. BasicRadioEnergyModel + * is *not* aggregated to the node. Hence we have to schedule this in the + * constructor instead of calling it in DoStart. + */ + m_periodicEnergyUpdateEvent = Simulator::Schedule (Seconds (0.0), + &BasicRadioEnergyModel::DoUpdateRemainingEnergy, this, m_currentState); +} + +BasicRadioEnergyModel::~BasicRadioEnergyModel () +{ +} + +BasicRadioEnergyModel::RadioState +BasicRadioEnergyModel::GetCurrentState (void) const +{ + NS_LOG_FUNCTION (this); + return m_currentState; +} + +void +BasicRadioEnergyModel::SetCurrentState (const RadioState currentState) +{ + NS_LOG_FUNCTION (this); + if (currentState != m_currentState) + { + m_currentState = currentState; + std::string stateName; + switch (currentState) + { + case TX: + stateName = "TX"; + break; + case RX: + stateName = "RX"; + break; + case IDLE: + stateName = "IDLE"; + break; + case SLEEP: + stateName = "SLEEP"; + break; + } + NS_LOG_DEBUG ("BasicRadioEnergyModel: Switching to state: " + << stateName << " at time = " << Simulator::Now ()); + } +} + +Time +BasicRadioEnergyModel::GetEnergyUpdateInterval (void) const +{ + NS_LOG_FUNCTION (this); + return m_energyUpdateInterval; +} + +void +BasicRadioEnergyModel::SetEnergyUpdateInterval (const Time interval) +{ + NS_LOG_FUNCTION (this); + NS_ASSERT (interval.GetSeconds () > 0); + m_energyUpdateInterval = interval; +} + +void +BasicRadioEnergyModel::SetEnergyDepletionCallback ( + BasicEnergyDepletionCallback callback) +{ + NS_LOG_FUNCTION (this); + if (callback.IsNull ()) + { + NS_LOG_DEBUG ("BasicRadioEnergyModel:Setting NULL energy depletion callback!"); + } + m_energyDepletionCallback = callback; +} + +bool +BasicRadioEnergyModel::IsStateTransitionValid (const RadioState destState) +{ + NS_LOG_FUNCTION (this << destState); + bool returnValue = true; + + /* + * This is a placeholder function to specify if some of the radio state + * transitions are prohibited. For example, if transition TX -> RX is not + * allowed, and must go through IDLE as TX -> IDLE -> RX, then this method + * can be used to raise an ns3 error. Initial state is m_currentState. + */ + + return returnValue; +} + +/* + * Private functions start here. + */ + +void +BasicRadioEnergyModel::DoDispose (void) +{ + NS_LOG_FUNCTION (this); + BreakSourceRefCycle (); // break reference cycle to energy source + m_energyDepletionCallback.Nullify (); +} + +void +BasicRadioEnergyModel::DoHandleEnergyDepletion (void) +{ + NS_LOG_FUNCTION (this); + NS_LOG_DEBUG ("BasicRadioEnergyModel:Energy is depleted!"); + // invoke energy depletion callback, if set. + if (!m_energyDepletionCallback.IsNull ()) + { + m_energyDepletionCallback (); + } +} + +double +BasicRadioEnergyModel::DoGetTotalEnergyConsumption (void) const +{ + NS_LOG_FUNCTION (this); + return m_totalEnergyConsumption; +} + +double +BasicRadioEnergyModel::DoGetTxPowerW (void) const +{ + NS_LOG_FUNCTION (this); + return m_txPower; +} + +void +BasicRadioEnergyModel::DoSetTxPowerW (double txPowerW) +{ + NS_LOG_FUNCTION (this << txPowerW); + m_txPower = txPowerW; +} + +double +BasicRadioEnergyModel::DoGetRxPowerW (void) const +{ + NS_LOG_FUNCTION (this); + return m_rxPower; +} + +void +BasicRadioEnergyModel::DoSetRxPowerW (double rxPowerW) +{ + NS_LOG_FUNCTION (this << rxPowerW); + m_rxPower = rxPowerW; +} + +double +BasicRadioEnergyModel::DoGetIdlePowerW (void) const +{ + NS_LOG_FUNCTION (this); + return m_idlePower; +} + +void +BasicRadioEnergyModel::DoSetIdlePowerW (double idlePowerW) +{ + NS_LOG_FUNCTION (this << idlePowerW); + m_idlePower = idlePowerW; +} + +double +BasicRadioEnergyModel::DoGetSleepPowerW (void) const +{ + NS_LOG_FUNCTION (this); + return m_sleepPower; +} + +void +BasicRadioEnergyModel::DoSetSleepPowerW (double sleepPowerW) +{ + NS_LOG_FUNCTION (this << sleepPowerW); + m_sleepPower = sleepPowerW; +} + +void +BasicRadioEnergyModel::DoUpdateRemainingEnergy (const RadioState destState) +{ + NS_LOG_FUNCTION (this << destState); + NS_ASSERT (IsStateTransitionValid (destState)); + + // Cancel the currently scheduled periodic event, if any + m_periodicEnergyUpdateEvent.Cancel (); + + Time duration = Simulator::Now () - m_lastUpdateTime; + NS_ASSERT (duration.GetNanoSeconds () >= 0); // check if duration is valid + + // update remaining energy accordingly + double energyToDecrease = 0.0; + switch (m_currentState) + { + case TX: + energyToDecrease = duration.GetSeconds () * m_txPower; + DecreaseRemainingEnergy (energyToDecrease); + break; + case RX: + energyToDecrease = duration.GetSeconds () * m_rxPower; + DecreaseRemainingEnergy (energyToDecrease); + break; + case IDLE: + energyToDecrease = duration.GetSeconds () * m_idlePower; + DecreaseRemainingEnergy (energyToDecrease); + break; + case SLEEP: + energyToDecrease = duration.GetSeconds () * m_sleepPower; + DecreaseRemainingEnergy (energyToDecrease); + break; + } + + // update total energy consumption + m_totalEnergyConsumption += energyToDecrease; + + // update last update time stamp + m_lastUpdateTime = Simulator::Now (); + + // update current state & last update time stamp + SetCurrentState (destState); + + // Schedule the next periodic energy update event + m_periodicEnergyUpdateEvent = Simulator::Schedule (m_energyUpdateInterval, + &BasicRadioEnergyModel::DoUpdateRemainingEnergy, this, m_currentState); + + // some debug message + NS_LOG_DEBUG ("BasicRadioEnergyModel:Total energy consumption is " + << m_totalEnergyConsumption << "J"); +} + +} // namespace ns3 diff --git a/src/contrib/energy/model/basic-radio-energy-model.h b/src/contrib/energy/model/basic-radio-energy-model.h new file mode 100644 index 000000000..9ef57527b --- /dev/null +++ b/src/contrib/energy/model/basic-radio-energy-model.h @@ -0,0 +1,159 @@ +/* -*- 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 BASIC_RADIO_ENERGY_MODEL_H +#define BASIC_RADIO_ENERGY_MODEL_H + +#include "radio-energy-model.h" +#include "ns3/nstime.h" +#include "ns3/event-id.h" +#include "ns3/traced-value.h" + +namespace ns3 { + +/** + * \brief a basic radio energy model + * + * This is a child class of the RadioEnergyModel class. + * + * 4 states are defined for the radio: TX, RX, IDLE, SLEEP. Default state is + * IDLE. + * The different types of transactions that are defined are: + * 1. Tx: State goes from IDLE to TX, radio is in TX state for TX_duration, + * then state goes from TX to IDLE. + * 2. Rx: State goes from IDLE to RX, radio is in RX state for RX_duration, + * then state goes from RX to IDLE. + * 3. Go_to_Sleep: State goes from IDLE to SLEEP. + * 4. End_of_Sleep: State goes from SLEEP to IDLE. + * The class keeps track of what state the radio is currently in. + * + * Energy calculation: For each transaction, we see how much time the radio + * spent in each state and calculate energy consumption accordingly. + * + * Energy update: Remaining energy = + * Previous remaining energy - Energy_transaction. + * + * Default values for power consumption are based on CC2420 radio chip, with + * supply voltage as 2.5V and currents as 17.4 mA (TX), 18.8 mA (RX), 20 uA + * (sleep) and 426 uA (idle). + * + * TODO change default values to wifi radio chip numbers. + */ +class BasicRadioEnergyModel : public RadioEnergyModel +{ +public: + /// Callback type for energy depletion handling. + typedef Callback BasicEnergyDepletionCallback; + +public: + static TypeId GetTypeId (void); + BasicRadioEnergyModel (); + virtual ~BasicRadioEnergyModel (); + + /** + * For current state, the getter is public, but the setter method should be + * private. + */ + RadioState GetCurrentState (void) const; + + /** + * \param interval Energy update interval. + * + * Setter for the energy update interval - time between two consecutive energy + * updates. + */ + void SetEnergyUpdateInterval (const Time interval); + + /** + * Getter for the energy update interval - time between two consecutive energy + * updates. + */ + Time GetEnergyUpdateInterval (void) const; + + /** + * \param callback Callback function. + * + * Sets callback for energy depletion handling. + */ + void SetEnergyDepletionCallback (BasicEnergyDepletionCallback callback); + + /** + * \param destState Radio state to switch to. + * \return True if the transition is allowed. + * + * This function checks if a given radio state transition is allowed. + */ + bool IsStateTransitionValid (const RadioState destState); + + +private: + void DoDispose (void); + + /// Handles energy depletion. + void DoHandleEnergyDepletion (void); + + /// Implements GetTotalEnergyConsumption. + double DoGetTotalEnergyConsumption (void) const; + + double DoGetTxPowerW (void) const; + void DoSetTxPowerW (double txPowerW); + double DoGetRxPowerW (void) const; + void DoSetRxPowerW (double rxPowerW); + double DoGetIdlePowerW (void) const; + void DoSetIdlePowerW (double idlePowerW); + double DoGetSleepPowerW (void) const; + void DoSetSleepPowerW (double sleepPowerW); + + void DoUpdateRemainingEnergy (const RadioState destState); + + /** + * \param currentState New state the radio device is currently in. + * + * Sets current state. This function is private so that only the energy model + * can change its own state. + */ + void SetCurrentState (const RadioState currentState); + +private: + /* + * Member variables for the power consumption in different radio modes. + * Power = (supply voltage * current draw) + */ + double m_txPower; + double m_rxPower; + double m_idlePower; + double m_sleepPower; + + // This variable keeps track of the total energy consumed by this particular model. + TracedValue m_totalEnergyConsumption; + + // State variables. + RadioState m_currentState; // current state the radio is in + Time m_lastUpdateTime; // time stamp of previous energy update + EventId m_periodicEnergyUpdateEvent; // scheduled event to update remaining energy periodically + Time m_energyUpdateInterval; // Time between consecutive periodic energy updates. + + // energy depletion callback + BasicEnergyDepletionCallback m_energyDepletionCallback; +}; + +} // namespace ns3 + +#endif /* BASIC_RADIO_ENERGY_MODEL_H */ diff --git a/src/contrib/energy/model/device-energy-model.cc b/src/contrib/energy/model/device-energy-model.cc new file mode 100644 index 000000000..75f6b27e9 --- /dev/null +++ b/src/contrib/energy/model/device-energy-model.cc @@ -0,0 +1,99 @@ +/* -*- 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 "device-energy-model.h" +#include "ns3/log.h" + +NS_LOG_COMPONENT_DEFINE ("DeviceEnergyModel"); + +namespace ns3 { + +NS_OBJECT_ENSURE_REGISTERED (DeviceEnergyModel); + +TypeId +DeviceEnergyModel::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::DeviceEnergyModel") + .SetParent () + ; + return tid; +} + +DeviceEnergyModel::DeviceEnergyModel () +{ +} + +DeviceEnergyModel::~DeviceEnergyModel () +{ +} + +void +DeviceEnergyModel::HandleEnergyDepletion (void) +{ + DoHandleEnergyDepletion (); +} + +void +DeviceEnergyModel::SetEnergySource (Ptr source) +{ + NS_LOG_FUNCTION (this << source); + NS_ASSERT (source != NULL); // energy source must exist + m_energySourcePtr = source; +} + +/* + * Private function starts here. + */ + +void +DeviceEnergyModel::DoDispose (void) +{ + NS_LOG_FUNCTION (this); + m_energySourcePtr = NULL; +} + +/* + * Protected functions start here. + */ + +void +DeviceEnergyModel::DecreaseRemainingEnergy (double energyJ) +{ + NS_LOG_FUNCTION (this << energyJ); + NS_ASSERT (m_energySourcePtr != NULL); // energy source must exist + m_energySourcePtr->DecreaseRemainingEnergy (energyJ); +} + +void +DeviceEnergyModel::IncreaseRemainingEnergy (double energyJ) +{ + NS_LOG_FUNCTION (this << energyJ); + NS_ASSERT (m_energySourcePtr != NULL); // energy source must exist + m_energySourcePtr->IncreaseRemainingEnergy (energyJ); +} + +void +DeviceEnergyModel::BreakSourceRefCycle (void) +{ + NS_LOG_FUNCTION (this); + m_energySourcePtr = NULL; +} + +} // namespace ns3 diff --git a/src/contrib/energy/model/device-energy-model.h b/src/contrib/energy/model/device-energy-model.h new file mode 100644 index 000000000..f2790d607 --- /dev/null +++ b/src/contrib/energy/model/device-energy-model.h @@ -0,0 +1,96 @@ +/* -*- 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 DEVICE_ENERGY_MODEL +#define DEVICE_ENERGY_MODEL + +#include "ns3/object.h" +#include "energy-source.h" + +namespace ns3 { + +class EnergySource; + +/** + * \brief Base class for device energy models. + * + * A device energy model should represent the energy consumption behavior of a + * specific device. It will update remaining energy stored in the EnergySource + * object installed on node. When energy is depleted, each DeviceEnergyModel + * object installed on the same node will be informed by the EnergySource. + */ +class DeviceEnergyModel : public Object +{ +public: + static TypeId GetTypeId (void); + DeviceEnergyModel (); + virtual ~DeviceEnergyModel (); + + /** + * This function is called by the EnergySource object when energy stored in + * the energy source is depleted. Should be implemented by child classes. + */ + void HandleEnergyDepletion (void); + + /// Sets the pointer to node energy source. + void SetEnergySource (Ptr source); + +private: + /* + * Do not include DoStart in any child of this base class. DeviceEnergyModel + * is *not* aggregated to the node hence DoStart will *not* be called. + */ + + /** + * All child's implementation must call BreakSourceRefCycle to ensure + * reference cycle to EnergySource object is broken. + */ + void DoDispose (void); + + /// Implements HandleEnergyDepletion. + virtual void DoHandleEnergyDepletion (void) = 0; + +private: + /// Pointer to EnergySource object + Ptr m_energySourcePtr; + +protected: + /// This function is used to access the private energy source pointer. + void DecreaseRemainingEnergy (double energyJ); + + /// This function is used to access the private energy source pointer. + void IncreaseRemainingEnergy (double energyJ); + + /** + * This function is called to break reference cycle between DeviceEnergyModel + * and EnergySource. Child of the DeviceEnergyModel base class must call this + * function in their implementation of DoDispose to make sure the reference + * cycle is broken. + * + * Normally this work will be completed by the DoDispose function. However it + * will be overridden in the child class. Hence we introduced this function. + */ + void BreakSourceRefCycle (void); + +}; + +} + +#endif /* DEVICE_ENERGY_MODEL */ diff --git a/src/contrib/energy/model/energy-source.cc b/src/contrib/energy/model/energy-source.cc new file mode 100644 index 000000000..84e313b72 --- /dev/null +++ b/src/contrib/energy/model/energy-source.cc @@ -0,0 +1,157 @@ +/* -*- 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 "energy-source.h" +#include "ns3/log.h" + +NS_LOG_COMPONENT_DEFINE ("EnergySource"); + +namespace ns3 { + +NS_OBJECT_ENSURE_REGISTERED (EnergySource); + +TypeId +EnergySource::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::EnergySource") + .SetParent () + ; + return tid; +} + +EnergySource::EnergySource () +{ +} + +EnergySource::~EnergySource () +{ +} + +double +EnergySource::GetInitialEnergy (void) const +{ + return DoGetInitialEnergy (); +} + +double +EnergySource::GetRemainingEnergy (void) const +{ + return DoGetRemainingEnergy (); +} + +void +EnergySource::DecreaseRemainingEnergy (double energyJ) +{ + DoDecreaseRemainingEnergy (energyJ); +} + +void +EnergySource::IncreaseRemainingEnergy (double energyJ) +{ + DoIncreaseRemainingEnergy (energyJ); +} + +double +EnergySource::GetEnergyFraction (void) const +{ + return DoGetEnergyFraction (); +} + +void +EnergySource::AppendDeviceEnergyModel ( + Ptr deviceEnergyModelPtr) +{ + NS_LOG_FUNCTION (this << deviceEnergyModelPtr); + NS_ASSERT (deviceEnergyModelPtr != NULL); // model must exist + m_deviceEnergyModelList.push_back (deviceEnergyModelPtr); +} + +EnergySource::DeviceEnergyModelList +EnergySource::FindDeviceEnergyModels (TypeId tid) +{ + NS_LOG_FUNCTION (this << tid); + DeviceEnergyModelList list; + DeviceEnergyModelList::iterator listItr; + for (listItr = m_deviceEnergyModelList.begin (); + listItr != m_deviceEnergyModelList.end (); listItr++) + { + if ((*listItr)->GetInstanceTypeId () == tid) + { + list.push_back (*listItr); + } + } + return list; +} + +EnergySource::DeviceEnergyModelList +EnergySource::FindDeviceEnergyModels (std::string name) +{ + NS_LOG_FUNCTION (this << name); + DeviceEnergyModelList list; + DeviceEnergyModelList::iterator listItr; + for (listItr = m_deviceEnergyModelList.begin (); + listItr != m_deviceEnergyModelList.end (); listItr++) + { + if ((*listItr)->GetInstanceTypeId ().GetName ().compare (name) == 0) + { + list.push_back (*listItr); + } + } + return list; +} + +/* + * Private function starts here. + */ + +void +EnergySource::DoDispose (void) +{ + NS_LOG_FUNCTION (this); + m_deviceEnergyModelList.clear (); // break reference cycle +} + +/* + * Protected functions start here. + */ + +void +EnergySource::NotifyEnergyDrained (void) +{ + NS_LOG_FUNCTION (this); + // notify all device energy models installed on node + DeviceEnergyModelList::iterator listItr; + for (listItr = m_deviceEnergyModelList.begin (); + listItr != m_deviceEnergyModelList.end (); listItr++) + { + NS_LOG_DEBUG ("BasicEnergySource:Notifying device energy model: " + << (*listItr)->GetInstanceTypeId ()); + (*listItr)->HandleEnergyDepletion (); + } +} + +void +EnergySource::BreakDeviceEnergyModelRefCycle (void) +{ + NS_LOG_FUNCTION (this); + m_deviceEnergyModelList.clear (); // break reference cycle +} + +} // namespace ns3 diff --git a/src/contrib/energy/model/energy-source.h b/src/contrib/energy/model/energy-source.h new file mode 100644 index 000000000..58e93bfec --- /dev/null +++ b/src/contrib/energy/model/energy-source.h @@ -0,0 +1,158 @@ +/* -*- 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 ENERGY_SOURCE_H +#define ENERGY_SOURCE_H + +#include "ns3/object.h" +#include "ns3/ptr.h" +#include "ns3/type-id.h" +#include "device-energy-model.h" + +namespace ns3 { + +class DeviceEnergyModel; + +/** + * \brief Energy source base class. + * + * This is the base class for energy sources. Energy sources keep track of + * remaining energy. Device energy models will be updating the remaining energy + * in the energy source. The energy source itself does not update the remaining + * energy. Energy source also keeps a list of device energy models installed on + * the same node. When the remaining energy level reaches 0, the energy source + * will notify all device energy models stored in the list. + * + * Unit of energy is chosen as Joules since energy models typically calculate + * energy as (time in seconds * power in Watts). If the energy source stores + * energy in different units (eg. kWh), a simple converter function should + * suffice. + */ +class EnergySource : public Object +{ +public: + /// List of pointers to DeviceEnergyModel objects. + typedef std::vector< Ptr > DeviceEnergyModelList; + +public: + static TypeId GetTypeId (void); + EnergySource (); + virtual ~EnergySource (); + + /// This function returns initial energy stored in energy source. + double GetInitialEnergy (void) const; + + /// This function returns the remaining energy stored in the energy source. + double GetRemainingEnergy (void) const; + + /** + * \param energy Amount of energy to decrease (in Joules) + * + * This function decreases the remaining energy in the energy source by the + * specified amount. + */ + void DecreaseRemainingEnergy (double energyJ); + + /** + * \param energy Amount of energy to increase (in Joules) + * + * This function increases the remaining energy in the energy source by the + * specified amount. Provided for supporting re-charging or scavenging. + */ + void IncreaseRemainingEnergy (double energyJ); + + /** + * \return Energy fraction = remaining energy / initial energy [0, 1] + * + * This function returns the percentage of energy left in the energy source. + */ + double GetEnergyFraction (void) const; + + /** + * \param deviceEnergyModelPtr Pointer to device energy model. + * \param tid TypeId of the specific device energy model. + * + * This function appends a device energy model to the end of a list of + * DeviceEnergyModelInfo structs. + */ + void AppendDeviceEnergyModel (Ptr deviceEnergyModelPtr); + + /** + * \param tid TypeId of the DeviceEnergyModel we are searching for. + * \returns List of pointers to DeviceEnergyModel objects installed on node. + */ + DeviceEnergyModelList FindDeviceEnergyModels (TypeId tid); + /** + * \param name name of the DeviceEnergyModel we are searching for. + * \returns List of pointers to DeviceEnergyModel objects installed on node. + */ + DeviceEnergyModelList FindDeviceEnergyModels (std::string name); + + +private: + /** + * All child's implementation must call BreakDeviceEnergyModelRefCycle to + * ensure reference cycles to DeviceEnergyModel objects are broken. + */ + void DoDispose (void); + + /// Implements GetInitialEnergy. + virtual double DoGetInitialEnergy (void) const = 0; + + /// Implements GetRemainingEnergy. + virtual double DoGetRemainingEnergy (void) const = 0; + + /// Implements DecreaseRemainingEnergy. + virtual void DoDecreaseRemainingEnergy (double energyJ) = 0; + + /// Implements IncreaseRemainingEnergy. + virtual void DoIncreaseRemainingEnergy (double energyJ) = 0; + + /// Implements GetEnergyFraction. + virtual double DoGetEnergyFraction (void) const = 0; + +private: + /// List of device energy models installed on the same node. + DeviceEnergyModelList m_deviceEnergyModelList; + + +protected: + /** + * This function notifies all DeviceEnergyModel of energy depletion event. It + * is called by the child EnergySource class when energy depletion happens. + */ + void NotifyEnergyDrained (void); + + /** + * This function is called to break reference cycle between EnergySource and + * DeviceEnergyModel. Child of the EnergySource base class must call this + * function in their implementation of DoDispose to make sure the reference + * cycle is broken. + * + * Normally this work will be completed by the DoDispose function. However it + * will be overridden in the child class. Hence we introduced this function. + */ + void BreakDeviceEnergyModelRefCycle (void); + +}; + +} // namespace ns3 + +#endif /* ENERGY_SOURCE_H */ diff --git a/src/contrib/energy/model/radio-energy-model.cc b/src/contrib/energy/model/radio-energy-model.cc new file mode 100644 index 000000000..1d863a61c --- /dev/null +++ b/src/contrib/energy/model/radio-energy-model.cc @@ -0,0 +1,100 @@ +/* -*- 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 "radio-energy-model.h" +#include "ns3/log.h" + +NS_LOG_COMPONENT_DEFINE ("RadioEnergyModel"); + +namespace ns3 { + +NS_OBJECT_ENSURE_REGISTERED (RadioEnergyModel); + +TypeId +RadioEnergyModel::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::RadioEnergyModel") + .SetParent () + ; + return tid; +} + +RadioEnergyModel::RadioEnergyModel () +{ +} + +RadioEnergyModel::~RadioEnergyModel () +{ +} + +double +RadioEnergyModel::GetTxPowerW (void) const +{ + return DoGetTxPowerW (); +} +double +RadioEnergyModel::GetRxPowerW (void) const +{ + return DoGetRxPowerW (); +} + +double +RadioEnergyModel::GetIdlePowerW (void) const +{ + return DoGetIdlePowerW (); +} + +double +RadioEnergyModel::GetSleepPowerW (void) const +{ + return DoGetSleepPowerW (); +} + +void +RadioEnergyModel::SetTxPowerW (double txPowerW) +{ + DoSetTxPowerW (txPowerW); +} + +void +RadioEnergyModel::SetRxPowerW (double rxPowerW) +{ + DoSetRxPowerW (rxPowerW); +} + +void +RadioEnergyModel::SetIdlePowerW (double idlePowerW) +{ + DoSetIdlePowerW (idlePowerW); +} + +void +RadioEnergyModel::SetSleepPowerW (double sleepPowerW) +{ + DoSetSleepPowerW (sleepPowerW); +} + +void +RadioEnergyModel::UpdateRemainingEnergy (const RadioState destState) +{ + DoUpdateRemainingEnergy (destState); +} + +} // namespace ns3 diff --git a/src/contrib/energy/model/radio-energy-model.h b/src/contrib/energy/model/radio-energy-model.h new file mode 100644 index 000000000..67ed84c91 --- /dev/null +++ b/src/contrib/energy/model/radio-energy-model.h @@ -0,0 +1,186 @@ +/* -*- 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 + */ + +#ifndef RADIO_ENERGY_MODEL_H +#define RADIO_ENERGY_MODEL_H + +#include "device-energy-model.h" + +namespace ns3 { + +/** + * \brief Keep track of energy consumption at a radio of a node. + * + * Assumption is that the radio is responsible for a significantly higher + * percentage of energy consumption than the computation at the node. + * + * The units used are: Joules (J) for energy, Watts (W) for power. + * + * This is a base class, which should be inherited and implemented by children + * classes. + */ +class RadioEnergyModel : public DeviceEnergyModel +{ +public: + /** + * The states of the PHY layer. + */ + enum RadioState + { + /** + * The radio is transmitting. + */ + TX = 0, + /** + * The radio is receiving. + */ + RX, + /** + * The radio is idle. + */ + IDLE, + /** + * The radio is in sleep mode. + */ + SLEEP + }; + +public: + static TypeId GetTypeId (void); + RadioEnergyModel (); + virtual ~RadioEnergyModel (); + + /** + * \returns the radio TX power in W. + */ + double GetTxPowerW (void) const; + + /** + * \param txPowerW the radio TX power in W + */ + void SetTxPowerW (double txPowerW); + + /** + * \returns the radio Rx power in W + */ + double GetRxPowerW (void) const; + + /** + * \param rxPowerW the radio RX power in W + */ + void SetRxPowerW (double rxPowerW); + + /** + * \returns the radio IDLE power in W + */ + double GetIdlePowerW (void) const; + + /** + * \param idlePowerW the radio IDLE power in W + */ + void SetIdlePowerW (double idlePowerW); + + /** + * \returns the radio SLEEP power in W + */ + double GetSleepPowerW (void) const; + + /** + * \param sleepPowerW the radio SLEEP power in W. + */ + void SetSleepPowerW (double sleepPowerW); + + /** + * \param destState Radio state to switch to. + * + * This function will update the remaining energy. Its implementation will be + * completed in child classes. + */ + void UpdateRemainingEnergy (const RadioState destState); + + +private: + /** + * \returns the radio TX power in W. + * + * Concrete subclasses of this base class must implement this method. + */ + virtual double DoGetTxPowerW (void) const = 0; + + /** + * \param the radio TX power in W + * + * Concrete subclasses of this base class must implement this method. + */ + virtual void DoSetTxPowerW (double txPowerW) = 0; + + /** + * \returns the radio RX power in W + * + * Concrete subclasses of this base class must implement this method. + */ + virtual double DoGetRxPowerW (void) const = 0; + + /** + * \param the radio RX power in W + * + * Concrete subclasses of this base class must implement this method. + */ + virtual void DoSetRxPowerW (double rxPowerW) = 0; + + /** + * \returns the radio IDLE power in W + * + * Concrete subclasses of this base class must implement this method. + */ + virtual double DoGetIdlePowerW (void) const = 0; + + /** + * \param idlePowerW the radio IDLE power in W + * + * Concrete subclasses of this base class must implement this method. + */ + virtual void DoSetIdlePowerW (double idlePowerW) = 0; + + /** + * \returns the radio SLEEP power in W + * + * Concrete subclasses of this base class must implement this method. + */ + virtual double DoGetSleepPowerW (void) const = 0; + + /** + * \param sleepPowerW the radio SLEEP power in W + * + * Concrete subclasses of this base class must implement this method. + */ + virtual void DoSetSleepPowerW (double sleepPowerW) = 0; + + /** + * \param destState Radio state to switch to. + * + * Concrete subclasses of this base class must implement this method. + */ + virtual void DoUpdateRemainingEnergy (const RadioState destState) = 0; +}; + +}; // namespace ns3 + +#endif /* RADIO_ENERGY_MODEL_H */ diff --git a/src/contrib/energy/test/basic-energy-model-test.cc b/src/contrib/energy/test/basic-energy-model-test.cc new file mode 100644 index 000000000..a248e82df --- /dev/null +++ b/src/contrib/energy/test/basic-energy-model-test.cc @@ -0,0 +1,358 @@ +/* -*- 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: He Wu + */ + +#include "ns3/basic-energy-source.h" +#include "ns3/basic-radio-energy-model.h" +#include "ns3/basic-energy-source-helper.h" +#include "ns3/basic-radio-energy-model-helper.h" +#include "ns3/log.h" +#include "ns3/test.h" +#include "ns3/node.h" +#include "ns3/simulator.h" +#include "ns3/double.h" +#include + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("BasicEnergyModelTestSuite"); + +/** + * Test case of update remaining energy for BasicEnergySource and + * BasicRadioEnergyModel. + */ +class BasicEnergyUpdateTest : public TestCase +{ +public: + BasicEnergyUpdateTest (); + virtual ~BasicEnergyUpdateTest (); + +private: + bool DoRun (void); + + /** + * \param state Radio state to switch to. + * \return False if no error occurs. + * + * Runs simulation for a while, check if final state & remaining energy is + * correctly updated. + */ + bool StateSwitchTest (RadioEnergyModel::RadioState state); + +private: + double m_timeS; // in seconds + double m_tolerance; // tolerance for power estimation + + ObjectFactory m_energySource; + ObjectFactory m_deviceEnergyModel; +}; + +BasicEnergyUpdateTest::BasicEnergyUpdateTest () + : TestCase ("Basic energy model update remaining energy test case") +{ + m_timeS = 15.5; // idle for 15 seconds before changing state + m_tolerance = 1.0e-13; // +} + +BasicEnergyUpdateTest::~BasicEnergyUpdateTest () +{ +} + +bool +BasicEnergyUpdateTest::DoRun (void) +{ + // set types + m_energySource.SetTypeId ("ns3::BasicEnergySource"); + m_deviceEnergyModel.SetTypeId ("ns3::BasicRadioEnergyModel"); + + // run state switch tests + if (StateSwitchTest (RadioEnergyModel::TX)) + { + return true; + } + if (StateSwitchTest (RadioEnergyModel::RX)) + { + return true; + } + if (StateSwitchTest (RadioEnergyModel::IDLE)) + { + return true; + } + if (StateSwitchTest (RadioEnergyModel::SLEEP)) + { + return true; + } + + // error free + return false; +} + +bool +BasicEnergyUpdateTest::StateSwitchTest ( + RadioEnergyModel::RadioState state) +{ + // create node + Ptr node = CreateObject (); + + // create energy source + Ptr source = m_energySource.Create (); + // aggregate energy source to node + node->AggregateObject (source); + + // create device energy model + Ptr model = + m_deviceEnergyModel.Create (); + // set energy source pointer + model->SetEnergySource (source); + // add device energy model to model list in energy source + source->AppendDeviceEnergyModel (model); + + // retrieve device energy model from energy source + EnergySource::DeviceEnergyModelList modelList = + source->FindDeviceEnergyModels ("ns3::BasicRadioEnergyModel"); + // check list + NS_TEST_ASSERT_MSG_EQ (false, modelList.empty (), "Model list is empty!"); + // get pointer + Ptr devModel = + DynamicCast (modelList[0]); + // check pointer + NS_TEST_ASSERT_MSG_NE (NULL, devModel, "NULL pointer to device model!"); + + // schedule change of state + Simulator::Schedule (Seconds (m_timeS), + &BasicRadioEnergyModel::UpdateRemainingEnergy, devModel, state); + + // run simulation + Simulator::Stop (Seconds (m_timeS * 2)); // run twice as long + Simulator::Run (); + Simulator::Destroy (); + + // calculate estimated remaining energy + double estRemainingEnergy = source->GetInitialEnergy (); + estRemainingEnergy -= devModel->GetIdlePowerW () * m_timeS; + /* + * Energy is updated periodically, hence we have to take into account of the + * update interval. + */ + double actualTime = m_timeS; + actualTime /= devModel->GetEnergyUpdateInterval ().GetSeconds (); + actualTime = floor (actualTime); // rounding for update interval + actualTime *= devModel->GetEnergyUpdateInterval ().GetSeconds (); + switch (state) + { + case RadioEnergyModel::TX: + estRemainingEnergy -= devModel->GetTxPowerW () * actualTime; + break; + case RadioEnergyModel::RX: + estRemainingEnergy -= devModel->GetRxPowerW () * actualTime; + break; + case RadioEnergyModel::IDLE: + estRemainingEnergy -= devModel->GetIdlePowerW () * actualTime; + break; + case RadioEnergyModel::SLEEP: + estRemainingEnergy -= devModel->GetSleepPowerW () * actualTime; + break; + default: + break; + } + // obtain remaining energy + double remainingEnergy = source->GetRemainingEnergy (); + NS_LOG_UNCOND ("Remaining energy is " << remainingEnergy << "\n" + << "Estimated remaining energy is " << estRemainingEnergy << "\n" + << "Difference is " << estRemainingEnergy - remainingEnergy); + // check remaining energy + NS_TEST_ASSERT_MSG_EQ_TOL (remainingEnergy, estRemainingEnergy, m_tolerance, + "Incorrect remaining energy!"); + + + // obtain radio state + RadioEnergyModel::RadioState endState = devModel->GetCurrentState (); + NS_LOG_UNCOND ("Radio state is " << endState); + // check end state + NS_TEST_ASSERT_MSG_EQ (endState, state, "Incorrect end state!"); + + return false; // no error +} + +// ----------------------------------------------------------------------------// + +/** + * Test case of energy depletion handling for BasicEnergySource and + * BasicRadioEnergyModel. + */ +class BasicEnergyDepletionTest : public TestCase +{ +public: + BasicEnergyDepletionTest (); + virtual ~BasicEnergyDepletionTest (); + +private: + bool DoRun (void); + + // / Callback invoked when energy is drained from source. + void DepletionHandler (void); + + /** + * \param simTimeS Simulation time, in seconds. + * \param updateIntervalS Device model update interval, in seconds. + * \return False if all is good. + * + * Runs simulation with specified simulation time and update interval. + */ + bool DepletionTestCase (double simTimeS, double updateIntervalS); + +private: + int m_numOfModels; // number of BasicRadioEnergyModel to install + int m_callbackCount; // counter for # of callbacks invoked + double m_simTimeS; // maximum simulation time, in seconds + double m_timeStepS; // simulation time step size, in seconds + double m_updateIntervalS; // update interval of each device model + +}; + +BasicEnergyDepletionTest::BasicEnergyDepletionTest () + : TestCase ("Basic energy model energy depletion test case") +{ + m_numOfModels = 10; + m_callbackCount = 0; + m_simTimeS = 4.5; + m_timeStepS = 0.5; + m_updateIntervalS = 1.5; +} + +BasicEnergyDepletionTest::~BasicEnergyDepletionTest () +{ +} + +bool +BasicEnergyDepletionTest::DoRun (void) +{ + /* + * Run simulation with different simulation time and update interval. + */ + for (double simTimeS = 0.0; simTimeS <= m_simTimeS; simTimeS += m_timeStepS) + { + for (double updateIntervalS = 0.5; updateIntervalS <= m_updateIntervalS; + updateIntervalS += m_timeStepS) + { + if (DepletionTestCase (simTimeS, updateIntervalS)) + { + return true; + } + // reset callback count + m_callbackCount = 0; + } + } + // error free + return false; +} + +void +BasicEnergyDepletionTest::DepletionHandler (void) +{ + m_callbackCount++; +} + +bool +BasicEnergyDepletionTest::DepletionTestCase (double simTimeS, + double updateIntervalS) +{ + // create node + Ptr node = CreateObject (); + + /* + * Create and install energy source and a single basic radio energy model on + * the node using helpers. + */ + // source helper + BasicEnergySourceHelper basicSourceHelper; + // set energy to 0 so that we deplete energy at the beginning of simulation + basicSourceHelper.Set ("BasicEnergySourceInitialEnergyJ", DoubleValue (0.0)); + // device energy model helper + BasicRadioEnergyModelHelper radioEnergyHelper; + // set update interval + Time updateInterval = Seconds (1.0); + radioEnergyHelper.Set ("PeriodicEnergyUpdateInterval", + TimeValue (Seconds (updateIntervalS))); + // set energy depletion callback + BasicRadioEnergyModel::BasicEnergyDepletionCallback callback = + MakeCallback (&BasicEnergyDepletionTest::DepletionHandler, this); + radioEnergyHelper.SetDepletionCallback (callback); + // energy model helper + EnergyModelHelper energyHelper; + // install on node + energyHelper.Install (basicSourceHelper, radioEnergyHelper, node); + + // Install more basic radio energy models onto the same node, using helper + for (int i = 1; i < m_numOfModels; i++) + { + radioEnergyHelper.Install (node); + } + + // run simulation + Simulator::Stop (Seconds (simTimeS)); + Simulator::Run (); + Simulator::Destroy (); + + /* + * Calculate total number of callbacks invoked. Taking the ceiling instead of + * the floor here because initial update is at time = 0. + */ + double tmp = ceil (simTimeS / updateIntervalS); + int numOfUpdates = (tmp == 0) ? 1 : tmp; + /* + * Every update will trigger *all* DeviceEnergyModels to react, therefore the + * total count should be numOfUpdates * m_numOfModels ^ 2 + */ + int totalCallbackCount = numOfUpdates * m_numOfModels * m_numOfModels; + + NS_LOG_UNCOND ("Simulation time = " << simTimeS << "s\n" + << "Update interval = " << updateIntervalS << "s\n" + << "Calculated callback count is " << totalCallbackCount << "\n" + << "Actual callback count is " << m_callbackCount); + + // check result + NS_TEST_ASSERT_MSG_EQ (totalCallbackCount, m_callbackCount, + "Not all callbacks are invoked!"); + + return false; +} + +// ----------------------------------------------------------------------------// + +/** + * Unit test suite for energy model. Although the test suite involves 2 modules + * it is still considered a unit test. Because a DeviceEnergyModel cannot live + * without an EnergySource. + */ +class BasicEnergyModelTestSuite : public TestSuite +{ +public: + BasicEnergyModelTestSuite (); +}; + +BasicEnergyModelTestSuite::BasicEnergyModelTestSuite () + : TestSuite ("devices-basic-energy-model", UNIT) +{ + AddTestCase (new BasicEnergyUpdateTest); + AddTestCase (new BasicEnergyDepletionTest); +} + +// create an instance of the test suite +BasicEnergyModelTestSuite g_energyModelTestSuite; diff --git a/src/contrib/energy/wscript b/src/contrib/energy/wscript new file mode 100644 index 000000000..800b036da --- /dev/null +++ b/src/contrib/energy/wscript @@ -0,0 +1,28 @@ +## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- + +def build(bld): + obj = bld.create_ns3_module('energy', ['node']) + obj.source = [ + 'model/radio-energy-model.cc', + 'model/basic-radio-energy-model.cc', + 'model/energy-source.cc', + 'model/basic-energy-source.cc', + 'model/device-energy-model.cc', + 'helper/energy-model-helper.cc', + 'helper/basic-energy-source-helper.cc', + 'helper/basic-radio-energy-model-helper.cc', + 'test/basic-energy-model-test.cc', + ] + headers = bld.new_task_gen('ns3header') + headers.module = 'energy' + headers.source = [ + 'model/radio-energy-model.h', + 'model/basic-radio-energy-model.h', + 'model/energy-source.h', + 'model/basic-energy-source.h', + 'model/device-energy-model.h', + 'helper/energy-model-helper.h', + 'helper/basic-energy-source-helper.h', + 'helper/basic-radio-energy-model-helper.h', + ] + diff --git a/src/wscript b/src/wscript index e5a6780e4..b833636c7 100644 --- a/src/wscript +++ b/src/wscript @@ -60,6 +60,7 @@ all_modules = ( 'devices/wimax', 'mpi', 'contrib/topology-read', + 'contrib/energy', ) def set_options(opt):