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