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 <math.h>
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  m_lastSampleTime = Seconds (0.0);
90  m_previousLoad = 0.0;
91  m_batteryLevel = 1; // fully charged
92  m_lifetime = Seconds (0.0);
93 }
94 
96 {
97 }
98 
99 double
101 {
102  return m_alpha * GetSupplyVoltage ();
103 }
104 
105 double
107 {
108  // average of Voc and Vcutoff
110 }
111 
112 double
114 {
115  NS_LOG_FUNCTION (this);
118 }
119 
120 double
122 {
123  return GetBatteryLevel ();
124 }
125 
126 void
128 {
129  NS_LOG_FUNCTION (this);
130 
131  // do not update if battery is already dead
132  if (m_batteryLevel <= 0)
133  {
134  NS_LOG_DEBUG ("RvBatteryModel:Battery is dead!");
135  return;
136  }
137 
138  // do not update if simulation has finished
139  if (Simulator::IsFinished ())
140  {
141  return;
142  }
143 
144  NS_LOG_DEBUG ("RvBatteryModel:Updating remaining energy!");
145 
147 
148  double currentLoad = CalculateTotalCurrent () * 1000; // must be in mA
149  double calculatedAlpha = Discharge (currentLoad, Simulator::Now ());
150 
151  NS_LOG_DEBUG ("RvBatteryModel:Calculated alpha = " << calculatedAlpha <<
152  " time = " << Simulator::Now ().GetSeconds ());
153 
154  // calculate battery level
155  m_batteryLevel = 1 - (calculatedAlpha / m_alpha);
156  if (m_batteryLevel < 0)
157  {
158  m_batteryLevel = 0;
159  }
160 
161  // check if battery is dead.
162  if (calculatedAlpha >= m_alpha)
163  {
165  NS_LOG_DEBUG ("RvBatteryModel:Battery is dead!");
167  return; // stop periodic sampling
168  }
169 
170  m_previousLoad = currentLoad;
174  this);
175 }
176 
177 void
179 {
180  NS_LOG_FUNCTION (this << interval);
181  m_samplingInterval = interval;
182 }
183 
184 Time
186 {
187  return m_samplingInterval;
188 }
189 
190 void
192 {
193  NS_LOG_FUNCTION (this << voltage);
194  NS_ASSERT (voltage >= 0);
195  m_openCircuitVoltage = voltage;
196 }
197 
198 double
200 {
201  return m_openCircuitVoltage;
202 }
203 
204 void
206 {
207  NS_LOG_FUNCTION (this << voltage);
208  NS_ASSERT (voltage <= m_openCircuitVoltage);
209  m_cutoffVoltage = voltage;
210 }
211 
212 double
214 {
215  return m_cutoffVoltage;
216 }
217 
218 void
220 {
221  NS_LOG_FUNCTION (this << alpha);
222  NS_ASSERT (alpha >= 0);
223  m_alpha = alpha;
224 }
225 
226 double
228 {
229  return m_alpha;
230 }
231 
232 void
234 {
235  NS_LOG_FUNCTION (this << beta);
236  NS_ASSERT (beta >= 0);
237  m_beta = beta;
238 }
239 
240 double
242 {
243  return m_beta;
244 }
245 
246 double
248 {
249  NS_LOG_FUNCTION (this);
251  return m_batteryLevel;
252 }
253 
254 Time
256 {
257  return m_lifetime;
258 }
259 
260 void
262 {
263  NS_LOG_FUNCTION (this << num);
264  m_numOfTerms = num;
265 }
266 
267 int
269 {
270  return m_numOfTerms;
271 }
272 
273 /*
274  * Private functions start here.
275  */
276 
277 void
279 {
280  NS_LOG_DEBUG ("RvBatteryModel:Starting battery level update!");
281  UpdateEnergySource (); // start periodic sampling of load (total current)
282 }
283 
284 void
286 {
287  BreakDeviceEnergyModelRefCycle (); // break reference cycle
288 }
289 
290 void
292 {
293  NS_LOG_FUNCTION (this);
294  NS_LOG_DEBUG ("RvBatteryModel:Energy depleted!");
295  NotifyEnergyDrained (); // notify DeviceEnergyModel objects
296 }
297 
298 double
300 {
301  NS_LOG_FUNCTION (this << load << t);
302 
303  // record only when load changes
304  if (load != m_previousLoad)
305  {
306  m_load.push_back (load);
307  m_previousLoad = load;
308  if (t != Seconds (0.0))
309  {
311  }
312  else
313  {
314  m_timeStamps.push_back (Seconds (0.0));
315  }
316  m_timeStamps.push_back (t);
317  }
318  else
319  {
320  m_timeStamps[m_timeStamps.size () - 1] = t;
321  }
322 
323  m_lastSampleTime = t;
324 
325  // calculate alpha for new t
326  NS_ASSERT (m_load.size () == m_timeStamps.size () - 1); // size must be equal
327  double calculatedAlpha = 0.0;
328  if (m_timeStamps.size () == 1)
329  {
330  // constant load
331  calculatedAlpha = m_load[0] * RvModelAFunction (t, t, Seconds (0.0),
332  m_beta);
333  }
334  else
335  {
336  // changing load
337  for (uint64_t i = 1; i < m_timeStamps.size (); i++)
338  {
339  calculatedAlpha += m_load[i - 1] * RvModelAFunction (t, m_timeStamps[i],
340  m_timeStamps[i - 1],
341  m_beta);
342  }
343  }
344 
345  return calculatedAlpha;
346 }
347 
348 double
349 RvBatteryModel::RvModelAFunction (Time t, Time sk, Time sk_1, double beta)
350 {
351  NS_LOG_FUNCTION (this << t << sk << sk_1 << beta);
352 
353  // everything is in minutes
354  double firstDelta = (t.GetSeconds () - sk.GetSeconds ()) / 60;
355  double secondDelta = (t.GetSeconds () - sk_1.GetSeconds ()) / 60;
356  double delta = (sk.GetSeconds () - sk_1.GetSeconds ()) / 60;
357 
358  double sum = 0.0;
359  for (int m = 1; m <= m_numOfTerms; m++)
360  {
361  double square = beta * beta * m * m;
362  sum += (exp (-square * (firstDelta)) - exp (-square * (secondDelta))) / square;
363  }
364  return delta + 2 * sum;
365 }
366 
367 } // namespace ns3