A Discrete-Event Network Simulator
API
wifi-radio-energy-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  * Author: Sidharth Nabar <snabar@uw.edu>, He Wu <mdzz@u.washington.edu>
19  */
20 
21 #include "ns3/log.h"
22 #include "ns3/simulator.h"
23 #include "ns3/pointer.h"
24 #include "ns3/energy-source.h"
26 #include "wifi-tx-current-model.h"
27 
28 namespace ns3 {
29 
30 NS_LOG_COMPONENT_DEFINE ("WifiRadioEnergyModel");
31 
32 NS_OBJECT_ENSURE_REGISTERED (WifiRadioEnergyModel);
33 
34 TypeId
36 {
37  static TypeId tid = TypeId ("ns3::WifiRadioEnergyModel")
39  .SetGroupName ("Energy")
40  .AddConstructor<WifiRadioEnergyModel> ()
41  .AddAttribute ("IdleCurrentA",
42  "The default radio Idle current in Ampere.",
43  DoubleValue (0.273), // idle mode = 273mA
46  MakeDoubleChecker<double> ())
47  .AddAttribute ("CcaBusyCurrentA",
48  "The default radio CCA Busy State current in Ampere.",
49  DoubleValue (0.273), // default to be the same as idle mode
52  MakeDoubleChecker<double> ())
53  .AddAttribute ("TxCurrentA",
54  "The radio TX current in Ampere.",
55  DoubleValue (0.380), // transmit at 0dBm = 380mA
58  MakeDoubleChecker<double> ())
59  .AddAttribute ("RxCurrentA",
60  "The radio RX current in Ampere.",
61  DoubleValue (0.313), // receive mode = 313mA
64  MakeDoubleChecker<double> ())
65  .AddAttribute ("SwitchingCurrentA",
66  "The default radio Channel Switch current in Ampere.",
67  DoubleValue (0.273), // default to be the same as idle mode
70  MakeDoubleChecker<double> ())
71  .AddAttribute ("SleepCurrentA",
72  "The radio Sleep current in Ampere.",
73  DoubleValue (0.033), // sleep mode = 33mA
76  MakeDoubleChecker<double> ())
77  .AddAttribute ("TxCurrentModel", "A pointer to the attached TX current model.",
78  PointerValue (),
80  MakePointerChecker<WifiTxCurrentModel> ())
81  .AddTraceSource ("TotalEnergyConsumption",
82  "Total energy consumption of the radio device.",
84  "ns3::TracedValueCallback::Double")
85  ;
86  return tid;
87 }
88 
90  : m_source (0),
91  m_currentState (WifiPhyState::IDLE),
92  m_lastUpdateTime (Seconds (0.0)),
93  m_nPendingChangeState (0)
94 {
95  NS_LOG_FUNCTION (this);
97  // set callback for WifiPhy listener
100  // set callback for updating the TX current
102 }
103 
105 {
106  NS_LOG_FUNCTION (this);
107  m_txCurrentModel = 0;
108  delete m_listener;
109 }
110 
111 void
113 {
114  NS_LOG_FUNCTION (this << source);
115  NS_ASSERT (source != NULL);
116  m_source = source;
118  Time durationToOff = GetMaximumTimeInState (m_currentState);
120 }
121 
122 double
124 {
125  NS_LOG_FUNCTION (this);
126 
127  Time duration = Simulator::Now () - m_lastUpdateTime;
128  NS_ASSERT (duration.IsPositive ()); // check if duration is valid
129 
130  // energy to decrease = current * voltage * time
131  double supplyVoltage = m_source->GetSupplyVoltage ();
132  double energyToDecrease = duration.GetSeconds () * GetStateA (m_currentState) * supplyVoltage;
133 
134  // notify energy source
135  m_source->UpdateEnergySource ();
136 
137  return m_totalEnergyConsumption + energyToDecrease;
138 }
139 
140 double
142 {
143  NS_LOG_FUNCTION (this);
144  return m_idleCurrentA;
145 }
146 
147 void
149 {
150  NS_LOG_FUNCTION (this << idleCurrentA);
151  m_idleCurrentA = idleCurrentA;
152 }
153 
154 double
156 {
157  NS_LOG_FUNCTION (this);
158  return m_ccaBusyCurrentA;
159 }
160 
161 void
163 {
164  NS_LOG_FUNCTION (this << CcaBusyCurrentA);
165  m_ccaBusyCurrentA = CcaBusyCurrentA;
166 }
167 
168 double
170 {
171  NS_LOG_FUNCTION (this);
172  return m_txCurrentA;
173 }
174 
175 void
177 {
178  NS_LOG_FUNCTION (this << txCurrentA);
179  m_txCurrentA = txCurrentA;
180 }
181 
182 double
184 {
185  NS_LOG_FUNCTION (this);
186  return m_rxCurrentA;
187 }
188 
189 void
191 {
192  NS_LOG_FUNCTION (this << rxCurrentA);
193  m_rxCurrentA = rxCurrentA;
194 }
195 
196 double
198 {
199  NS_LOG_FUNCTION (this);
200  return m_switchingCurrentA;
201 }
202 
203 void
205 {
206  NS_LOG_FUNCTION (this << switchingCurrentA);
207  m_switchingCurrentA = switchingCurrentA;
208 }
209 
210 double
212 {
213  NS_LOG_FUNCTION (this);
214  return m_sleepCurrentA;
215 }
216 
217 void
219 {
220  NS_LOG_FUNCTION (this << sleepCurrentA);
221  m_sleepCurrentA = sleepCurrentA;
222 }
223 
226 {
227  NS_LOG_FUNCTION (this);
228  return m_currentState;
229 }
230 
231 void
234 {
235  NS_LOG_FUNCTION (this);
236  if (callback.IsNull ())
237  {
238  NS_LOG_DEBUG ("WifiRadioEnergyModel:Setting NULL energy depletion callback!");
239  }
240  m_energyDepletionCallback = callback;
241 }
242 
243 void
246 {
247  NS_LOG_FUNCTION (this);
248  if (callback.IsNull ())
249  {
250  NS_LOG_DEBUG ("WifiRadioEnergyModel:Setting NULL energy recharged callback!");
251  }
252  m_energyRechargedCallback = callback;
253 }
254 
255 void
257 {
258  m_txCurrentModel = model;
259 }
260 
261 void
263 {
264  if (m_txCurrentModel)
265  {
266  m_txCurrentA = m_txCurrentModel->CalcTxCurrent (txPowerDbm);
267  }
268 }
269 
270 Time
272 {
273  if (state == WifiPhyState::OFF)
274  {
275  NS_FATAL_ERROR ("Requested maximum remaining time for OFF state");
276  }
277  double remainingEnergy = m_source->GetRemainingEnergy ();
278  double supplyVoltage = m_source->GetSupplyVoltage ();
279  double current = GetStateA (state);
280  return Seconds (remainingEnergy / (current * supplyVoltage));
281 }
282 
283 void
285 {
286  NS_LOG_FUNCTION (this << newState);
287 
289 
290  if (m_nPendingChangeState > 1 && newState == WifiPhyState::OFF)
291  {
292  SetWifiRadioState ((WifiPhyState) newState);
294  return;
295  }
296 
297  if (newState != WifiPhyState::OFF)
298  {
300  Time durationToOff = GetMaximumTimeInState (newState);
302  }
303 
304  Time duration = Simulator::Now () - m_lastUpdateTime;
305  NS_ASSERT (duration.IsPositive ()); // check if duration is valid
306 
307  // energy to decrease = current * voltage * time
308  double supplyVoltage = m_source->GetSupplyVoltage ();
309  double energyToDecrease = duration.GetSeconds () * GetStateA (m_currentState) * supplyVoltage;
310 
311  // update total energy consumption
312  m_totalEnergyConsumption += energyToDecrease;
313  NS_ASSERT (m_totalEnergyConsumption <= m_source->GetInitialEnergy ());
314 
315  // update last update time stamp
317 
318  // notify energy source
319  m_source->UpdateEnergySource ();
320 
321  // in case the energy source is found to be depleted during the last update, a callback might be
322  // invoked that might cause a change in the Wifi PHY state (e.g., the PHY is put into SLEEP mode).
323  // This in turn causes a new call to this member function, with the consequence that the previous
324  // instance is resumed after the termination of the new instance. In particular, the state set
325  // by the previous instance is erroneously the final state stored in m_currentState. The check below
326  // ensures that previous instances do not change m_currentState.
327 
329  {
330  // update current state & last update time stamp
331  SetWifiRadioState ((WifiPhyState) newState);
332 
333  // some debug message
334  NS_LOG_DEBUG ("WifiRadioEnergyModel:Total energy consumption is " <<
335  m_totalEnergyConsumption << "J");
336  }
337 
339 }
340 
341 void
343 {
344  NS_LOG_FUNCTION (this);
345  NS_LOG_DEBUG ("WifiRadioEnergyModel:Energy is depleted!");
346  // invoke energy depletion callback, if set.
348  {
350  }
351 }
352 
353 void
355 {
356  NS_LOG_FUNCTION (this);
357  NS_LOG_DEBUG ("WifiRadioEnergyModel:Energy is recharged!");
358  // invoke energy recharged callback, if set.
360  {
362  }
363 }
364 
365 void
367 {
368  NS_LOG_FUNCTION (this);
369  NS_LOG_DEBUG ("WifiRadioEnergyModel:Energy is changed!");
371  {
373  Time durationToOff = GetMaximumTimeInState (m_currentState);
375  }
376 }
377 
380 {
381  NS_LOG_FUNCTION (this);
382  return m_listener;
383 }
384 
385 /*
386  * Private functions start here.
387  */
388 
389 void
391 {
392  NS_LOG_FUNCTION (this);
393  m_source = NULL;
395 }
396 
397 double
399 {
400  switch (state)
401  {
402  case WifiPhyState::IDLE:
403  return m_idleCurrentA;
405  return m_ccaBusyCurrentA;
406  case WifiPhyState::TX:
407  return m_txCurrentA;
408  case WifiPhyState::RX:
409  return m_rxCurrentA;
411  return m_switchingCurrentA;
412  case WifiPhyState::SLEEP:
413  return m_sleepCurrentA;
414  case WifiPhyState::OFF:
415  return 0.0;
416  }
417  NS_FATAL_ERROR ("WifiRadioEnergyModel: undefined radio state " << state);
418 }
419 
420 double
422 {
423  return GetStateA (m_currentState);
424 }
425 
426 void
428 {
429  NS_LOG_FUNCTION (this << state);
430  m_currentState = state;
431  std::string stateName;
432  switch (state)
433  {
434  case WifiPhyState::IDLE:
435  stateName = "IDLE";
436  break;
438  stateName = "CCA_BUSY";
439  break;
440  case WifiPhyState::TX:
441  stateName = "TX";
442  break;
443  case WifiPhyState::RX:
444  stateName = "RX";
445  break;
447  stateName = "SWITCHING";
448  break;
449  case WifiPhyState::SLEEP:
450  stateName = "SLEEP";
451  break;
452  case WifiPhyState::OFF:
453  stateName = "OFF";
454  break;
455  }
456  NS_LOG_DEBUG ("WifiRadioEnergyModel:Switching to state: " << stateName <<
457  " at time = " << Simulator::Now ());
458 }
459 
460 // -------------------------------------------------------------------------- //
461 
463 {
464  NS_LOG_FUNCTION (this);
467 }
468 
470 {
471  NS_LOG_FUNCTION (this);
472 }
473 
474 void
476 {
477  NS_LOG_FUNCTION (this << &callback);
478  NS_ASSERT (!callback.IsNull ());
479  m_changeStateCallback = callback;
480 }
481 
482 void
484 {
485  NS_LOG_FUNCTION (this << &callback);
486  NS_ASSERT (!callback.IsNull ());
487  m_updateTxCurrentCallback = callback;
488 }
489 
490 void
492 {
493  NS_LOG_FUNCTION (this << duration);
495  {
496  NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
497  }
500 }
501 
502 void
504 {
505  NS_LOG_FUNCTION (this);
507  {
508  NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
509  }
511 }
512 
513 void
515 {
516  NS_LOG_FUNCTION (this);
518  {
519  NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
520  }
522 }
523 
524 void
526 {
527  NS_LOG_FUNCTION (this << duration << txPowerDbm);
529  {
530  NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Update tx current callback not set!");
531  }
532  m_updateTxCurrentCallback (txPowerDbm);
534  {
535  NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
536  }
538  // schedule changing state back to IDLE after TX duration
541 }
542 
543 void
545 {
546  NS_LOG_FUNCTION (this << duration);
548  {
549  NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
550  }
552  // schedule changing state back to IDLE after CCA_BUSY duration
555 }
556 
557 void
559 {
560  NS_LOG_FUNCTION (this << duration);
562  {
563  NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
564  }
566  // schedule changing state back to IDLE after CCA_BUSY duration
569 }
570 
571 void
573 {
574  NS_LOG_FUNCTION (this);
576  {
577  NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
578  }
581 }
582 
583 void
585 {
586  NS_LOG_FUNCTION (this);
588  {
589  NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
590  }
592 }
593 
594 void
596 {
597  NS_LOG_FUNCTION (this);
599  {
600  NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
601  }
604 }
605 
606 void
608 {
609  NS_LOG_FUNCTION (this);
611  {
612  NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
613  }
615 }
616 
617 void
619 {
620  NS_LOG_FUNCTION (this);
622  {
623  NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
624  }
626 }
627 
628 } // namespace ns3
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
double GetRxCurrentA(void) const
Gets receive current in Amperes.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
static TypeId GetTypeId(void)
Get the type ID.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void HandleEnergyRecharged(void)
Handles energy recharged.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
TracedValue< double > m_totalEnergyConsumption
This variable keeps track of the total energy consumed by this model in watts.
Base class for device energy models.
double GetTxCurrentA(void) const
Gets transmit current in Amperes.
double m_rxCurrentA
receive current in Amperes
void SetWifiRadioState(const WifiPhyState state)
The PHY layer is sleeping.
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:380
UpdateTxCurrentCallback m_updateTxCurrentCallback
Callback used to update the TX current stored in WifiRadioEnergyModel based on the nominal TX power u...
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
Channel is IDLE, no packet is being transmitted.
Definition: csma-channel.h:75
double m_ccaBusyCurrentA
CCA busy current in Amperes.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
void ChangeState(int newState)
Changes state of the WifiRadioEnergyMode.
void NotifyOff(void) override
Defined in ns3::WifiPhyListener.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
WifiRadioEnergyModelPhyListener * m_listener
WifiPhy listener.
void SetSleepCurrentA(double sleepCurrentA)
Sets sleep current in Amperes.
WifiRadioEnergyModelPhyListener * GetPhyListener(void)
void SetUpdateTxCurrentCallback(UpdateTxCurrentCallback callback)
Sets the update TX current callback.
void SwitchToIdle(void)
A helper function that makes scheduling m_changeStateCallback possible.
void NotifyOn(void) override
Defined in ns3::WifiPhyListener.
void SetRxCurrentA(double rxCurrentA)
Sets receive current in Amperes.
void NotifySwitchingStart(Time duration) override
double m_idleCurrentA
idle current in Amperes
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
void SetCcaBusyCurrentA(double ccaBusyCurrentA)
Sets CCA busy current in Amperes.
Time GetMaximumTimeInState(int state) const
double GetTotalEnergyConsumption(void) const
void SetChangeStateCallback(DeviceEnergyModel::ChangeStateCallback callback)
Sets the change state callback.
Ptr< WifiTxCurrentModel > m_txCurrentModel
current model
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: pointer.h:227
double m_sleepCurrentA
sleep current in Amperes
WifiPhyState GetCurrentState(void) const
Ptr< EnergySource > m_source
energy source
void NotifyMaybeCcaBusyStart(Time duration) override
void NotifyTxStart(Time duration, double txPowerDbm) override
Switches the WifiRadioEnergyModel to TX state and switches back to IDLE after TX duration.
void SetTxCurrentFromModel(double txPowerDbm)
Calls the CalcTxCurrent method of the TX current model to compute the TX current based on such model...
void SetEnergyRechargedCallback(WifiRadioEnergyRechargedCallback callback)
The PHY layer has sense the medium busy through the CCA mechanism.
Time m_lastUpdateTime
time stamp of previous energy update
double GetSwitchingCurrentA(void) const
Gets switching current in Amperes.
DeviceEnergyModel::ChangeStateCallback m_changeStateCallback
Change state callback used to notify the WifiRadioEnergyModel of a state change.
EventId m_switchToOffEvent
switch to off event
EventId m_switchToIdleEvent
switch to idle event
void NotifyRxStart(Time duration) override
Switches the WifiRadioEnergyModel to RX state.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Hold objects of type Ptr<T>.
Definition: pointer.h:36
void NotifyWakeup(void) override
Defined in ns3::WifiPhyListener.
The PHY layer is IDLE.
WifiPhyState
The state of the PHY layer.
WifiPhyState m_currentState
current state the radio is in
double GetStateA(int state) const
A WifiPhy listener class for notifying the WifiRadioEnergyModel of Wifi radio state change...
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
void NotifyRxEndOk(void) override
Switches the WifiRadioEnergyModel back to IDLE state.
double GetCcaBusyCurrentA(void) const
Gets CCA busy current in Amperes.
void SetTxCurrentA(double txCurrentA)
Sets transmit current in Amperes.
A WiFi radio energy model.
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: double.h:42
void SetEnergyDepletionCallback(WifiRadioEnergyDepletionCallback callback)
The PHY layer is sending a packet.
void NotifySleep(void) override
Defined in ns3::WifiPhyListener.
void DoDispose(void)
Destructor implementation.
void HandleEnergyChanged(void)
Handles energy changed.
bool IsPositive(void) const
Exactly equivalent to t >= 0.
Definition: nstime.h:317
uint8_t m_nPendingChangeState
pending state change
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
WifiRadioEnergyDepletionCallback m_energyDepletionCallback
Energy depletion callback.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
The PHY layer is receiving a packet.
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
The PHY layer is switched off.
void Nullify(void)
Discard the implementation, set it to null.
Definition: callback.h:1391
virtual void ChangeState(int newState)=0
The PHY layer is switching to other channel.
void SetSwitchingCurrentA(double switchingCurrentA)
Sets switching current in Amperes.
void SetEnergySource(const Ptr< EnergySource > source)
Sets pointer to EnergySouce installed on node.
double m_switchingCurrentA
switching current in Amperes
void SetTxCurrentModel(const Ptr< WifiTxCurrentModel > model)
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1386
This class can be used to hold variables of floating point type such as &#39;double&#39; or &#39;float&#39;...
Definition: double.h:41
double GetSleepCurrentA(void) const
Gets sleep current in Amperes.
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
void SetIdleCurrentA(double idleCurrentA)
Sets idle current in Amperes.
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1642
WifiRadioEnergyRechargedCallback m_energyRechargedCallback
Energy recharged callback.
double GetIdleCurrentA(void) const
Gets idle current in Amperes.
void NotifyRxEndError(void) override
Switches the WifiRadioEnergyModel back to IDLE state.
void HandleEnergyDepletion(void)
Handles energy depletion.
double m_txCurrentA
transmit current in Amperes