A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
li-ion-energy-source.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2010 Andrea Sacco
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  * Author: Andrea Sacco <andrea.sacco85@gmail.com>
19  */
20 
21 #include "li-ion-energy-source.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 
28 #include <cmath>
29 
30 NS_LOG_COMPONENT_DEFINE ("LiIonEnergySource");
31 
32 namespace ns3 {
33 
34 NS_OBJECT_ENSURE_REGISTERED (LiIonEnergySource);
35 
36 TypeId
38 {
39  static TypeId tid = TypeId ("ns3::LiIonEnergySource")
41  .AddConstructor<LiIonEnergySource> ()
42  .AddAttribute ("LiIonEnergySourceInitialEnergyJ",
43  "Initial energy stored in basic energy source.",
44  DoubleValue (31752.0), // in Joules
45  MakeDoubleAccessor (&LiIonEnergySource::SetInitialEnergy,
47  MakeDoubleChecker<double> ())
48  .AddAttribute ("InitialCellVoltage",
49  "Initial (maximum) voltage of the cell (fully charged).",
50  DoubleValue (4.05), // in Volts
51  MakeDoubleAccessor (&LiIonEnergySource::SetInitialSupplyVoltage,
53  MakeDoubleChecker<double> ())
54  .AddAttribute ("NominalCellVoltage",
55  "Nominal voltage of the cell.",
56  DoubleValue (3.6), // in Volts
57  MakeDoubleAccessor (&LiIonEnergySource::m_eNom),
58  MakeDoubleChecker<double> ())
59  .AddAttribute ("ExpCellVoltage",
60  "Cell voltage at the end of the exponential zone.",
61  DoubleValue (3.6), // in Volts
62  MakeDoubleAccessor (&LiIonEnergySource::m_eExp),
63  MakeDoubleChecker<double> ())
64  .AddAttribute ("RatedCapacity",
65  "Rated capacity of the cell.",
66  DoubleValue (2.45), // in Ah
67  MakeDoubleAccessor (&LiIonEnergySource::m_qRated),
68  MakeDoubleChecker<double> ())
69  .AddAttribute ("NomCapacity",
70  "Cell capacity at the end of the nominal zone.",
71  DoubleValue (1.1), // in Ah
72  MakeDoubleAccessor (&LiIonEnergySource::m_qNom),
73  MakeDoubleChecker<double> ())
74  .AddAttribute ("ExpCapacity",
75  "Cell Capacity at the end of the exponential zone.",
76  DoubleValue (1.2), // in Ah
77  MakeDoubleAccessor (&LiIonEnergySource::m_qExp),
78  MakeDoubleChecker<double> ())
79  .AddAttribute ("InternalResistance",
80  "Internal resistance of the cell",
81  DoubleValue (0.083), // in Ohms
82  MakeDoubleAccessor (&LiIonEnergySource::m_internalResistance),
83  MakeDoubleChecker<double> ())
84  .AddAttribute ("TypCurrent",
85  "Typical discharge current used to fit the curves",
86  DoubleValue (2.33), // in A
87  MakeDoubleAccessor (&LiIonEnergySource::m_typCurrent),
88  MakeDoubleChecker<double> ())
89  .AddAttribute ("ThresholdVoltage",
90  "Minimum threshold voltage to consider the battery depleted.",
91  DoubleValue (3.3), // in Volts
92  MakeDoubleAccessor (&LiIonEnergySource::m_minVoltTh),
93  MakeDoubleChecker<double> ())
94  .AddAttribute ("PeriodicEnergyUpdateInterval",
95  "Time between two consecutive periodic energy updates.",
96  TimeValue (Seconds (1.0)),
99  MakeTimeChecker ())
100  .AddTraceSource ("RemainingEnergy",
101  "Remaining energy at BasicEnergySource.",
103  ;
104  return tid;
105 }
106 
108  : m_drainedCapacity (0.0),
109  m_lastUpdateTime (Seconds (0.0))
110 {
111 }
112 
114 {
115 }
116 
117 void
118 LiIonEnergySource::SetInitialEnergy (double initialEnergyJ)
119 {
120  NS_LOG_FUNCTION (this << initialEnergyJ);
121  NS_ASSERT (initialEnergyJ >= 0);
122  m_initialEnergyJ = initialEnergyJ;
123  // set remaining energy to be initial energy
125 }
126 
127 double
129 {
130  NS_LOG_FUNCTION (this);
131  return m_initialEnergyJ;
132 }
133 
134 void
136 {
137  m_eFull = supplyVoltageV;
138  m_supplyVoltageV = supplyVoltageV;
139 }
140 
141 double
143 {
144  NS_LOG_FUNCTION (this);
145  return m_supplyVoltageV;
146 }
147 
148 void
150 {
151  NS_LOG_FUNCTION (this);
152  m_energyUpdateInterval = interval;
153 }
154 
155 Time
157 {
158  NS_LOG_FUNCTION (this);
159  return m_energyUpdateInterval;
160 }
161 
162 double
164 {
165  NS_LOG_FUNCTION (this);
166  // update energy source to get the latest remaining energy.
168  return m_remainingEnergyJ;
169 }
170 
171 double
173 {
174  NS_LOG_FUNCTION (this);
175  // update energy source to get the latest remaining energy.
178 }
179 
180 void
182 {
183  NS_LOG_FUNCTION (this << energyJ);
184  NS_ASSERT (energyJ >= 0);
185  m_remainingEnergyJ -= energyJ;
186 
187  // check if remaining energy is 0
189  {
191  }
192 }
193 
194 void
196 {
197  NS_LOG_FUNCTION (this << energyJ);
198  NS_ASSERT (energyJ >= 0);
199  m_remainingEnergyJ += energyJ;
200 }
201 
202 void
204 {
205  NS_LOG_FUNCTION (this);
206  NS_LOG_DEBUG ("LiIonEnergySource:Updating remaining energy at node #" <<
207  GetNode ()->GetId ());
208 
209  // do not update if simulation has finished
210  if (Simulator::IsFinished ())
211  {
212  return;
213  }
214 
216 
218 
219  if (m_remainingEnergyJ <= 0)
220  {
222  return; // stop periodic update
223  }
224 
226 
229  this);
230 }
231 
232 /*
233  * Private functions start here.
234  */
235 void
237 {
238  NS_LOG_FUNCTION (this);
239  UpdateEnergySource (); // start periodic update
240 }
241 
242 void
244 {
245  NS_LOG_FUNCTION (this);
246  // calculate remaining energy at the end of simulation
248  BreakDeviceEnergyModelRefCycle (); // break reference cycle
249 }
250 
251 
252 void
254 {
255  NS_LOG_FUNCTION (this);
256  NS_LOG_DEBUG ("LiIonEnergySource:Energy depleted at node #" <<
257  GetNode ()->GetId ());
258  NotifyEnergyDrained (); // notify DeviceEnergyModel objects
259  m_remainingEnergyJ = 0; // energy never goes below 0
260 }
261 
262 
263 void
265 {
266  NS_LOG_FUNCTION (this);
267  double totalCurrentA = CalculateTotalCurrent ();
268  Time duration = Simulator::Now () - m_lastUpdateTime;
269  NS_ASSERT (duration.GetSeconds () >= 0);
270  // energy = current * voltage * time
271  double energyToDecreaseJ = totalCurrentA * m_supplyVoltageV * duration.GetSeconds ();
272  m_remainingEnergyJ -= energyToDecreaseJ;
273  m_drainedCapacity += (totalCurrentA * duration.GetSeconds () / 3600);
274  // update the supply voltage
275  m_supplyVoltageV = GetVoltage (totalCurrentA);
276  NS_LOG_DEBUG ("LiIonEnergySource:Remaining energy = " << m_remainingEnergyJ);
277 }
278 
279 double
281 {
282  NS_LOG_FUNCTION (this << i);
283 
284  // integral of i in dt, drained capacity in Ah
285  double it = m_drainedCapacity;
286 
287  // empirical factors
288  double A = m_eFull - m_eExp;
289  double B = 3 / m_qExp;
290 
291  // slope of the polarization curve
292  double K = std::abs ( (m_eFull - m_eNom + A * (std::exp (-B * m_qNom) - 1)) * (m_qRated - m_qNom) / m_qNom);
293 
294  // constant voltage
295  double E0 = m_eFull + K + m_internalResistance * m_typCurrent - A;
296 
297  double E = E0 - K * m_qRated / (m_qRated - it) + A * std::exp (-B * it);
298 
299  // cell voltage
300  double V = E - m_internalResistance * i;
301 
302  NS_LOG_DEBUG ("Voltage: " << V << " with E: " << E);
303 
304  return V;
305 }
306 
307 } // namespace ns3