A Discrete-Event Network Simulator
API
li-ion-energy-source.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010 Andrea Sacco
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Andrea Sacco <andrea.sacco85@gmail.com>
18  */
19 
20 #include "li-ion-energy-source.h"
21 
22 #include "ns3/assert.h"
23 #include "ns3/double.h"
24 #include "ns3/log.h"
25 #include "ns3/simulator.h"
26 #include "ns3/trace-source-accessor.h"
27 
28 #include <cmath>
29 
30 namespace ns3
31 {
32 
33 NS_LOG_COMPONENT_DEFINE("LiIonEnergySource");
34 
35 NS_OBJECT_ENSURE_REGISTERED(LiIonEnergySource);
36 
37 TypeId
39 {
40  static TypeId tid =
41  TypeId("ns3::LiIonEnergySource")
43  .SetGroupName("Energy")
44  .AddConstructor<LiIonEnergySource>()
45  .AddAttribute("LiIonEnergySourceInitialEnergyJ",
46  "Initial energy stored in basic energy source.",
47  DoubleValue(31752.0), // in Joules
50  MakeDoubleChecker<double>())
51  .AddAttribute("LiIonEnergyLowBatteryThreshold",
52  "Low battery threshold for LiIon energy source.",
53  DoubleValue(0.10), // as a fraction of the initial energy
55  MakeDoubleChecker<double>())
56  .AddAttribute("InitialCellVoltage",
57  "Initial (maximum) voltage of the cell (fully charged).",
58  DoubleValue(4.05), // in Volts
61  MakeDoubleChecker<double>())
62  .AddAttribute("NominalCellVoltage",
63  "Nominal voltage of the cell.",
64  DoubleValue(3.6), // in Volts
66  MakeDoubleChecker<double>())
67  .AddAttribute("ExpCellVoltage",
68  "Cell voltage at the end of the exponential zone.",
69  DoubleValue(3.6), // in Volts
71  MakeDoubleChecker<double>())
72  .AddAttribute("RatedCapacity",
73  "Rated capacity of the cell.",
74  DoubleValue(2.45), // in Ah
76  MakeDoubleChecker<double>())
77  .AddAttribute("NomCapacity",
78  "Cell capacity at the end of the nominal zone.",
79  DoubleValue(1.1), // in Ah
81  MakeDoubleChecker<double>())
82  .AddAttribute("ExpCapacity",
83  "Cell Capacity at the end of the exponential zone.",
84  DoubleValue(1.2), // in Ah
86  MakeDoubleChecker<double>())
87  .AddAttribute("InternalResistance",
88  "Internal resistance of the cell",
89  DoubleValue(0.083), // in Ohms
91  MakeDoubleChecker<double>())
92  .AddAttribute("TypCurrent",
93  "Typical discharge current used to fit the curves",
94  DoubleValue(2.33), // in A
96  MakeDoubleChecker<double>())
97  .AddAttribute("ThresholdVoltage",
98  "Minimum threshold voltage to consider the battery depleted.",
99  DoubleValue(3.3), // in Volts
101  MakeDoubleChecker<double>())
102  .AddAttribute("PeriodicEnergyUpdateInterval",
103  "Time between two consecutive periodic energy updates.",
104  TimeValue(Seconds(1.0)),
107  MakeTimeChecker())
108  .AddTraceSource("RemainingEnergy",
109  "Remaining energy at BasicEnergySource.",
111  "ns3::TracedValueCallback::Double");
112  return tid;
113 }
114 
116  : m_drainedCapacity(0.0),
117  m_lastUpdateTime(Seconds(0.0))
118 {
119  NS_LOG_FUNCTION(this);
120 }
121 
123 {
124  NS_LOG_FUNCTION(this);
125 }
126 
127 void
129 {
130  NS_LOG_FUNCTION(this << initialEnergyJ);
131  NS_ASSERT(initialEnergyJ >= 0);
132  m_initialEnergyJ = initialEnergyJ;
133  // set remaining energy to be initial energy
135 }
136 
137 double
139 {
140  NS_LOG_FUNCTION(this);
141  return m_initialEnergyJ;
142 }
143 
144 void
146 {
147  NS_LOG_FUNCTION(this << supplyVoltageV);
148  m_eFull = supplyVoltageV;
149  m_supplyVoltageV = supplyVoltageV;
150 }
151 
152 double
154 {
155  NS_LOG_FUNCTION(this);
156  return m_supplyVoltageV;
157 }
158 
159 void
161 {
162  NS_LOG_FUNCTION(this << interval);
163  m_energyUpdateInterval = interval;
164 }
165 
166 Time
168 {
169  NS_LOG_FUNCTION(this);
170  return m_energyUpdateInterval;
171 }
172 
173 double
175 {
176  NS_LOG_FUNCTION(this);
177  // update energy source to get the latest remaining energy.
179  return m_remainingEnergyJ;
180 }
181 
182 double
184 {
185  NS_LOG_FUNCTION(this);
186  // update energy source to get the latest remaining energy.
189 }
190 
191 void
193 {
194  NS_LOG_FUNCTION(this << energyJ);
195  NS_ASSERT(energyJ >= 0);
196  m_remainingEnergyJ -= energyJ;
197 
198  // check if remaining energy is 0
200  {
202  }
203 }
204 
205 void
207 {
208  NS_LOG_FUNCTION(this << energyJ);
209  NS_ASSERT(energyJ >= 0);
210  m_remainingEnergyJ += energyJ;
211 }
212 
213 void
215 {
216  NS_LOG_FUNCTION(this);
217  NS_LOG_DEBUG("LiIonEnergySource:Updating remaining energy at node #" << GetNode()->GetId());
218 
219  // do not update if simulation has finished
220  if (Simulator::IsFinished())
221  {
222  return;
223  }
224 
226 
228 
230 
232  {
234  return; // stop periodic update
235  }
236 
239 }
240 
241 /*
242  * Private functions start here.
243  */
244 void
246 {
247  NS_LOG_FUNCTION(this);
248  UpdateEnergySource(); // start periodic update
249 }
250 
251 void
253 {
254  NS_LOG_FUNCTION(this);
255  BreakDeviceEnergyModelRefCycle(); // break reference cycle
256 }
257 
258 void
260 {
261  NS_LOG_FUNCTION(this);
262  NS_LOG_DEBUG("LiIonEnergySource:Energy depleted at node #" << GetNode()->GetId());
263  NotifyEnergyDrained(); // notify DeviceEnergyModel objects
264 }
265 
266 void
268 {
269  NS_LOG_FUNCTION(this);
270  double totalCurrentA = CalculateTotalCurrent();
271  Time duration = Simulator::Now() - m_lastUpdateTime;
272  NS_ASSERT(duration.GetSeconds() >= 0);
273  // energy = current * voltage * time
274  double energyToDecreaseJ = totalCurrentA * m_supplyVoltageV * duration.GetSeconds();
275 
276  if (m_remainingEnergyJ < energyToDecreaseJ)
277  {
278  m_remainingEnergyJ = 0; // energy never goes below 0
279  }
280  else
281  {
282  m_remainingEnergyJ -= energyToDecreaseJ;
283  }
284 
285  m_drainedCapacity += (totalCurrentA * duration).GetHours();
286  // update the supply voltage
287  m_supplyVoltageV = GetVoltage(totalCurrentA);
288  NS_LOG_DEBUG("LiIonEnergySource:Remaining energy = " << m_remainingEnergyJ);
289 }
290 
291 double
293 {
294  NS_LOG_FUNCTION(this << i);
295 
296  // integral of i in dt, drained capacity in Ah
297  double it = m_drainedCapacity;
298 
299  // empirical factors
300  double A = m_eFull - m_eExp;
301  double B = 3 / m_qExp;
302 
303  // slope of the polarization curve
304  double K = std::abs((m_eFull - m_eNom + A * (std::exp(-B * m_qNom) - 1)) * (m_qRated - m_qNom) /
305  m_qNom);
306 
307  // constant voltage
308  double E0 = m_eFull + K + m_internalResistance * m_typCurrent - A;
309 
310  double E = E0 - K * m_qRated / (m_qRated - it) + A * std::exp(-B * it);
311 
312  // cell voltage
313  double V = E - m_internalResistance * i;
314 
315  NS_LOG_DEBUG("Voltage: " << V << " with E: " << E);
316 
317  return V;
318 }
319 
320 } // namespace ns3
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
double CalculateTotalCurrent()
void BreakDeviceEnergyModelRefCycle()
This function is called to break reference cycle between EnergySource and DeviceEnergyModel.
void NotifyEnergyDrained()
This function notifies all DeviceEnergyModel of energy depletion event.
Ptr< Node > GetNode() const
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:55
Model a generic Lithium Ion Battery basing on [1][2].
void DoDispose() override
All child's implementation must call BreakDeviceEnergyModelRefCycle to ensure reference cycles to Dev...
void UpdateEnergySource() override
Implements UpdateEnergySource.
double m_drainedCapacity
capacity drained from the cell, in Ah
void SetInitialEnergy(double initialEnergyJ)
double m_minVoltTh
minimum threshold voltage to consider the battery depleted
virtual void IncreaseRemainingEnergy(double energyJ)
void DoInitialize() override
Initialize() implementation.
double m_supplyVoltageV
actual voltage of the cell
TracedValue< double > m_remainingEnergyJ
remaining energy, in Joules
double m_initialEnergyJ
initial energy, in Joules
double GetRemainingEnergy() override
double m_eFull
initial voltage of the cell, in Volts
void SetEnergyUpdateInterval(Time interval)
double m_internalResistance
internal resistance of the cell, in Ohms
Time m_energyUpdateInterval
energy update interval
void SetInitialSupplyVoltage(double supplyVoltageV)
double m_eNom
nominal voltage of the cell, in Volts
double m_lowBatteryTh
low battery threshold, as a fraction of the initial energy
double m_eExp
cell voltage at the end of the exponential zone, in Volts
EventId m_energyUpdateEvent
energy update event
double GetEnergyFraction() override
void CalculateRemainingEnergy()
Calculates remaining energy.
double GetInitialEnergy() const override
static TypeId GetTypeId()
Get the type ID.
double m_qNom
cell capacity at the end of the nominal zone, in Ah
double m_qExp
capacity value at the end of the exponential zone, in Ah
double GetVoltage(double current) const
Get the cell voltage in function of the discharge current.
double m_qRated
rated capacity of the cell, in Ah
double GetSupplyVoltage() const override
virtual void DecreaseRemainingEnergy(double energyJ)
double m_typCurrent
typical discharge current used to fit the curves
void HandleEnergyDrainedEvent()
Handles the remaining energy going to zero event.
Time m_lastUpdateTime
last update time
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static bool IsFinished()
Check if the simulation should finish.
Definition: simulator.cc:171
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:403
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#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 an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1414
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:533
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition: double.h:43
#define E(name, start, end)