A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
rv-battery-model.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2010 Network Security Lab, University of Washington, Seattle.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Authors: Sidharth Nabar <snabar@uw.edu>, He Wu <mdzz@u.washington.edu>
19  */
20 
21 #include "rv-battery-model.h"
22 #include "ns3/log.h"
23 #include "ns3/assert.h"
24 #include "ns3/double.h"
25 #include "ns3/trace-source-accessor.h"
26 #include "ns3/simulator.h"
27 #include <cmath>
28 
29 NS_LOG_COMPONENT_DEFINE ("RvBatteryModel");
30 
31 namespace ns3 {
32 
33 NS_OBJECT_ENSURE_REGISTERED (RvBatteryModel);
34 
35 TypeId
37 {
38  static TypeId tid = TypeId ("ns3::RvBatteryModel")
40  .AddConstructor<RvBatteryModel> ()
41  .AddAttribute ("RvBatteryModelPeriodicEnergyUpdateInterval",
42  "RV battery model sampling interval.",
43  TimeValue (Seconds (1.0)),
44  MakeTimeAccessor (&RvBatteryModel::SetSamplingInterval,
46  MakeTimeChecker ())
47  .AddAttribute ("RvBatteryModelOpenCircuitVoltage",
48  "RV battery model open circuit voltage.",
49  DoubleValue (4.1),
50  MakeDoubleAccessor (&RvBatteryModel::SetOpenCircuitVoltage,
52  MakeDoubleChecker<double> ())
53  .AddAttribute ("RvBatteryModelCutoffVoltage",
54  "RV battery model cutoff voltage.",
55  DoubleValue (3.0),
56  MakeDoubleAccessor (&RvBatteryModel::SetCutoffVoltage,
58  MakeDoubleChecker<double> ())
59  .AddAttribute ("RvBatteryModelAlphaValue",
60  "RV battery model alpha value.",
61  DoubleValue (35220.0),
62  MakeDoubleAccessor (&RvBatteryModel::SetAlpha,
64  MakeDoubleChecker<double> ())
65  .AddAttribute ("RvBatteryModelBetaValue",
66  "RV battery model beta value.",
67  DoubleValue (0.637),
68  MakeDoubleAccessor (&RvBatteryModel::SetBeta,
70  MakeDoubleChecker<double> ())
71  .AddAttribute ("RvBatteryModelNumOfTerms",
72  "The number of terms of the infinite sum for estimating battery level.",
73  IntegerValue (10), // value used in paper
74  MakeIntegerAccessor (&RvBatteryModel::SetNumOfTerms,
76  MakeIntegerChecker<int> ())
77  .AddTraceSource ("RvBatteryModelBatteryLevel",
78  "RV battery model battery level.",
80  .AddTraceSource ("RvBatteryModelBatteryLifetime",
81  "RV battery model battery lifetime.",
83  ;
84  return tid;
85 }
86 
88 {
89  NS_LOG_FUNCTION (this);
90  m_lastSampleTime = Seconds (0.0);
91  m_previousLoad = 0.0;
92  m_batteryLevel = 1; // fully charged
93  m_lifetime = Seconds (0.0);
94 }
95 
97 {
98  NS_LOG_FUNCTION (this);
99 }
100 
101 double
103 {
104  NS_LOG_FUNCTION (this);
105  return m_alpha * GetSupplyVoltage ();
106 }
107 
108 double
110 {
111  NS_LOG_FUNCTION (this);
112  // average of Voc and Vcutoff
114 }
115 
116 double
118 {
119  NS_LOG_FUNCTION (this);
122 }
123 
124 double
126 {
127  NS_LOG_FUNCTION (this);
128  return GetBatteryLevel ();
129 }
130 
131 void
133 {
134  NS_LOG_FUNCTION (this);
135 
136  // do not update if battery is already dead
137  if (m_batteryLevel <= 0)
138  {
139  NS_LOG_DEBUG ("RvBatteryModel:Battery is dead!");
140  return;
141  }
142 
143  // do not update if simulation has finished
144  if (Simulator::IsFinished ())
145  {
146  return;
147  }
148 
149  NS_LOG_DEBUG ("RvBatteryModel:Updating remaining energy!");
150 
152 
153  double currentLoad = CalculateTotalCurrent () * 1000; // must be in mA
154  double calculatedAlpha = Discharge (currentLoad, Simulator::Now ());
155 
156  NS_LOG_DEBUG ("RvBatteryModel:Calculated alpha = " << calculatedAlpha <<
157  " time = " << Simulator::Now ().GetSeconds ());
158 
159  // calculate battery level
160  m_batteryLevel = 1 - (calculatedAlpha / m_alpha);
161  if (m_batteryLevel < 0)
162  {
163  m_batteryLevel = 0;
164  }
165 
166  // check if battery is dead.
167  if (calculatedAlpha >= m_alpha)
168  {
170  NS_LOG_DEBUG ("RvBatteryModel:Battery is dead!");
172  return; // stop periodic sampling
173  }
174 
175  m_previousLoad = currentLoad;
179  this);
180 }
181 
182 void
184 {
185  NS_LOG_FUNCTION (this << interval);
186  m_samplingInterval = interval;
187 }
188 
189 Time
191 {
192  NS_LOG_FUNCTION (this);
193  return m_samplingInterval;
194 }
195 
196 void
198 {
199  NS_LOG_FUNCTION (this << voltage);
200  NS_ASSERT (voltage >= 0);
201  m_openCircuitVoltage = voltage;
202 }
203 
204 double
206 {
207  NS_LOG_FUNCTION (this);
208  return m_openCircuitVoltage;
209 }
210 
211 void
213 {
214  NS_LOG_FUNCTION (this << voltage);
215  NS_ASSERT (voltage <= m_openCircuitVoltage);
216  m_cutoffVoltage = voltage;
217 }
218 
219 double
221 {
222  NS_LOG_FUNCTION (this);
223  return m_cutoffVoltage;
224 }
225 
226 void
228 {
229  NS_LOG_FUNCTION (this << alpha);
230  NS_ASSERT (alpha >= 0);
231  m_alpha = alpha;
232 }
233 
234 double
236 {
237  NS_LOG_FUNCTION (this);
238  return m_alpha;
239 }
240 
241 void
243 {
244  NS_LOG_FUNCTION (this << beta);
245  NS_ASSERT (beta >= 0);
246  m_beta = beta;
247 }
248 
249 double
251 {
252  NS_LOG_FUNCTION (this);
253  return m_beta;
254 }
255 
256 double
258 {
259  NS_LOG_FUNCTION (this);
261  return m_batteryLevel;
262 }
263 
264 Time
266 {
267  NS_LOG_FUNCTION (this);
268  return m_lifetime;
269 }
270 
271 void
273 {
274  NS_LOG_FUNCTION (this << num);
275  m_numOfTerms = num;
276 }
277 
278 int
280 {
281  NS_LOG_FUNCTION (this);
282  return m_numOfTerms;
283 }
284 
285 /*
286  * Private functions start here.
287  */
288 
289 void
291 {
292  NS_LOG_FUNCTION (this);
293  NS_LOG_DEBUG ("RvBatteryModel:Starting battery level update!");
294  UpdateEnergySource (); // start periodic sampling of load (total current)
295 }
296 
297 void
299 {
300  NS_LOG_FUNCTION (this);
301  BreakDeviceEnergyModelRefCycle (); // break reference cycle
302 }
303 
304 void
306 {
307  NS_LOG_FUNCTION (this);
308  NS_LOG_DEBUG ("RvBatteryModel:Energy depleted!");
309  NotifyEnergyDrained (); // notify DeviceEnergyModel objects
310 }
311 
312 double
314 {
315  NS_LOG_FUNCTION (this << load << t);
316 
317  // record only when load changes
318  if (load != m_previousLoad)
319  {
320  m_load.push_back (load);
321  m_previousLoad = load;
322  if (t != Seconds (0.0))
323  {
325  }
326  else
327  {
328  m_timeStamps.push_back (Seconds (0.0));
329  }
330  m_timeStamps.push_back (t);
331  }
332  else
333  {
334  m_timeStamps[m_timeStamps.size () - 1] = t;
335  }
336 
337  m_lastSampleTime = t;
338 
339  // calculate alpha for new t
340  NS_ASSERT (m_load.size () == m_timeStamps.size () - 1); // size must be equal
341  double calculatedAlpha = 0.0;
342  if (m_timeStamps.size () == 1)
343  {
344  // constant load
345  calculatedAlpha = m_load[0] * RvModelAFunction (t, t, Seconds (0.0),
346  m_beta);
347  }
348  else
349  {
350  // changing load
351  for (uint64_t i = 1; i < m_timeStamps.size (); i++)
352  {
353  calculatedAlpha += m_load[i - 1] * RvModelAFunction (t, m_timeStamps[i],
354  m_timeStamps[i - 1],
355  m_beta);
356  }
357  }
358 
359  return calculatedAlpha;
360 }
361 
362 double
363 RvBatteryModel::RvModelAFunction (Time t, Time sk, Time sk_1, double beta)
364 {
365  NS_LOG_FUNCTION (this << t << sk << sk_1 << beta);
366 
367  // everything is in minutes
368  double firstDelta = (t.GetSeconds () - sk.GetSeconds ()) / 60;
369  double secondDelta = (t.GetSeconds () - sk_1.GetSeconds ()) / 60;
370  double delta = (sk.GetSeconds () - sk_1.GetSeconds ()) / 60;
371 
372  double sum = 0.0;
373  for (int m = 1; m <= m_numOfTerms; m++)
374  {
375  double square = beta * beta * m * m;
376  sum += (std::exp (-square * (firstDelta)) - std::exp (-square * (secondDelta))) / square;
377  }
378  return delta + 2 * sum;
379 }
380 
381 } // namespace ns3
double Discharge(double load, Time t)
Discharges the battery.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:79
void SetOpenCircuitVoltage(double voltage)
Sets open circuit voltage of battery.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register the class in the ns-3 factory.
Definition: object-base.h:38
Time m_samplingInterval
(1 / sampling interval) = sampling frequency
Time GetSamplingInterval(void) const
virtual double GetSupplyVoltage(void) const
Energy source base class.
Definition: energy-source.h:71
double GetBeta(void) const
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:61
Hold a signed integer type.
Definition: integer.h:45
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
void SetBeta(double beta)
Sets the beta value for the battery model.
virtual double GetInitialEnergy(void) const
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
Definition: simulator.h:825
void HandleEnergyDrainedEvent(void)
Handles the remaining energy going to zero event.
void SetNumOfTerms(int num)
Sets the number of terms of the infinite sum for estimating battery level.
void SetCutoffVoltage(double voltage)
Sets cutoff voltage of battery.
double GetAlpha(void) const
virtual void DoInitialize(void)
Defined in ns3::Object.
void BreakDeviceEnergyModelRefCycle(void)
This function is called to break reference cycle between EnergySource and DeviceEnergyModel.
double GetSeconds(void) const
Definition: nstime.h:272
Time GetLifetime(void) const
hold objects of type ns3::Time
Definition: nstime.h:1008
void SetSamplingInterval(Time interval)
std::vector< Time > m_timeStamps
virtual void DoDispose(void)
Defined in ns3::Object.
double CalculateTotalCurrent(void)
double RvModelAFunction(Time t, Time sk, Time sk_1, double beta)
RV model A function.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
static Time Now(void)
Return the "current simulation time".
Definition: simulator.cc:180
TracedValue< Time > m_lifetime
static TypeId GetTypeId(void)
void NotifyEnergyDrained(void)
This function notifies all DeviceEnergyModel of energy depletion event.
TracedValue< double > m_batteryLevel
Battery level is defined as: output of Discharge function / alpha value.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:213
virtual double GetRemainingEnergy(void)
virtual void UpdateEnergySource(void)
Implements UpdateEnergySource.
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::cancel method.
Definition: event-id.cc:47
double GetOpenCircuitVoltage(void) const
static bool IsFinished(void)
If there are no more events lefts to be scheduled, or if simulation time has already reached the "sto...
Definition: simulator.cc:150
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:441
int GetNumOfTerms(void) const
std::vector< double > m_load
Hold a floating point type.
Definition: double.h:41
a unique identifier for an interface.
Definition: type-id.h:49
double GetCutoffVoltage(void) const
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
void SetAlpha(double alpha)
Sets the alpha value for the battery model.
virtual double GetEnergyFraction(void)
double GetBatteryLevel(void)