A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-radio-energy-model.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010 Network Security Lab, University of Washington, Seattle.
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: Sidharth Nabar <snabar@uw.edu>, He Wu <mdzz@u.washington.edu>
18 */
19
21
23
24#include "ns3/energy-source.h"
25#include "ns3/log.h"
26#include "ns3/pointer.h"
27#include "ns3/simulator.h"
28
29namespace ns3
30{
31
32NS_LOG_COMPONENT_DEFINE("WifiRadioEnergyModel");
33
34NS_OBJECT_ENSURE_REGISTERED(WifiRadioEnergyModel);
35
36TypeId
38{
39 static TypeId tid =
40 TypeId("ns3::WifiRadioEnergyModel")
42 .SetGroupName("Energy")
43 .AddConstructor<WifiRadioEnergyModel>()
44 .AddAttribute("IdleCurrentA",
45 "The default radio Idle current in Ampere.",
46 DoubleValue(0.273), // idle mode = 273mA
49 MakeDoubleChecker<double>())
50 .AddAttribute("CcaBusyCurrentA",
51 "The default radio CCA Busy State current in Ampere.",
52 DoubleValue(0.273), // default to be the same as idle mode
55 MakeDoubleChecker<double>())
56 .AddAttribute("TxCurrentA",
57 "The radio TX current in Ampere.",
58 DoubleValue(0.380), // transmit at 0dBm = 380mA
61 MakeDoubleChecker<double>())
62 .AddAttribute("RxCurrentA",
63 "The radio RX current in Ampere.",
64 DoubleValue(0.313), // receive mode = 313mA
67 MakeDoubleChecker<double>())
68 .AddAttribute("SwitchingCurrentA",
69 "The default radio Channel Switch current in Ampere.",
70 DoubleValue(0.273), // default to be the same as idle mode
73 MakeDoubleChecker<double>())
74 .AddAttribute("SleepCurrentA",
75 "The radio Sleep current in Ampere.",
76 DoubleValue(0.033), // sleep mode = 33mA
79 MakeDoubleChecker<double>())
80 .AddAttribute("TxCurrentModel",
81 "A pointer to the attached TX current model.",
84 MakePointerChecker<WifiTxCurrentModel>())
85 .AddTraceSource(
86 "TotalEnergyConsumption",
87 "Total energy consumption of the radio device.",
89 "ns3::TracedValueCallback::Double");
90 return tid;
91}
92
94 : m_source(nullptr),
95 m_currentState(WifiPhyState::IDLE),
96 m_lastUpdateTime(Seconds(0.0)),
97 m_nPendingChangeState(0)
98{
99 NS_LOG_FUNCTION(this);
101 // set callback for WifiPhy listener
104 // set callback for updating the TX current
107}
108
110{
111 NS_LOG_FUNCTION(this);
112 m_txCurrentModel = nullptr;
113 delete m_listener;
114}
115
116void
118{
119 NS_LOG_FUNCTION(this << source);
120 NS_ASSERT(source);
121 m_source = source;
126 this,
127 WifiPhyState::OFF);
128}
129
130double
132{
133 NS_LOG_FUNCTION(this);
134
135 Time duration = Simulator::Now() - m_lastUpdateTime;
136 NS_ASSERT(duration.IsPositive()); // check if duration is valid
137
138 // energy to decrease = current * voltage * time
139 double supplyVoltage = m_source->GetSupplyVoltage();
140 double energyToDecrease = duration.GetSeconds() * GetStateA(m_currentState) * supplyVoltage;
141
142 // notify energy source
143 m_source->UpdateEnergySource();
144
145 return m_totalEnergyConsumption + energyToDecrease;
146}
147
148double
150{
151 NS_LOG_FUNCTION(this);
152 return m_idleCurrentA;
153}
154
155void
157{
158 NS_LOG_FUNCTION(this << idleCurrentA);
159 m_idleCurrentA = idleCurrentA;
160}
161
162double
164{
165 NS_LOG_FUNCTION(this);
166 return m_ccaBusyCurrentA;
167}
168
169void
171{
172 NS_LOG_FUNCTION(this << CcaBusyCurrentA);
173 m_ccaBusyCurrentA = CcaBusyCurrentA;
174}
175
176double
178{
179 NS_LOG_FUNCTION(this);
180 return m_txCurrentA;
181}
182
183void
185{
186 NS_LOG_FUNCTION(this << txCurrentA);
187 m_txCurrentA = txCurrentA;
188}
189
190double
192{
193 NS_LOG_FUNCTION(this);
194 return m_rxCurrentA;
195}
196
197void
199{
200 NS_LOG_FUNCTION(this << rxCurrentA);
201 m_rxCurrentA = rxCurrentA;
202}
203
204double
206{
207 NS_LOG_FUNCTION(this);
208 return m_switchingCurrentA;
209}
210
211void
213{
214 NS_LOG_FUNCTION(this << switchingCurrentA);
215 m_switchingCurrentA = switchingCurrentA;
216}
217
218double
220{
221 NS_LOG_FUNCTION(this);
222 return m_sleepCurrentA;
223}
224
225void
227{
228 NS_LOG_FUNCTION(this << sleepCurrentA);
229 m_sleepCurrentA = sleepCurrentA;
230}
231
234{
235 NS_LOG_FUNCTION(this);
236 return m_currentState;
237}
238
239void
241{
242 NS_LOG_FUNCTION(this);
243 if (callback.IsNull())
244 {
245 NS_LOG_DEBUG("WifiRadioEnergyModel:Setting NULL energy depletion callback!");
246 }
247 m_energyDepletionCallback = callback;
248}
249
250void
252{
253 NS_LOG_FUNCTION(this);
254 if (callback.IsNull())
255 {
256 NS_LOG_DEBUG("WifiRadioEnergyModel:Setting NULL energy recharged callback!");
257 }
258 m_energyRechargedCallback = callback;
259}
260
261void
263{
264 m_txCurrentModel = model;
265}
266
267void
269{
271 {
272 m_txCurrentA = m_txCurrentModel->CalcTxCurrent(txPowerDbm);
273 }
274}
275
276Time
278{
279 if (state == WifiPhyState::OFF)
280 {
281 NS_FATAL_ERROR("Requested maximum remaining time for OFF state");
282 }
283 double remainingEnergy = m_source->GetRemainingEnergy();
284 double supplyVoltage = m_source->GetSupplyVoltage();
285 double current = GetStateA(state);
286 return Seconds(remainingEnergy / (current * supplyVoltage));
287}
288
289void
291{
292 NS_LOG_FUNCTION(this << newState);
293
295
296 if (m_nPendingChangeState > 1 && newState == WifiPhyState::OFF)
297 {
300 return;
301 }
302
303 if (newState != WifiPhyState::OFF)
304 {
306 Time durationToOff = GetMaximumTimeInState(newState);
309 this,
310 WifiPhyState::OFF);
311 }
312
313 Time duration = Simulator::Now() - m_lastUpdateTime;
314 NS_ASSERT(duration.IsPositive()); // check if duration is valid
315
316 // energy to decrease = current * voltage * time
317 double supplyVoltage = m_source->GetSupplyVoltage();
318 double energyToDecrease = duration.GetSeconds() * GetStateA(m_currentState) * supplyVoltage;
319
320 // update total energy consumption
321 m_totalEnergyConsumption += energyToDecrease;
322 NS_ASSERT(m_totalEnergyConsumption <= m_source->GetInitialEnergy());
323
324 // update last update time stamp
326
327 // notify energy source
328 m_source->UpdateEnergySource();
329
330 // in case the energy source is found to be depleted during the last update, a callback might be
331 // invoked that might cause a change in the Wifi PHY state (e.g., the PHY is put into SLEEP
332 // mode). This in turn causes a new call to this member function, with the consequence that the
333 // previous instance is resumed after the termination of the new instance. In particular, the
334 // state set by the previous instance is erroneously the final state stored in m_currentState.
335 // The check below ensures that previous instances do not change m_currentState.
336
337 if (m_nPendingChangeState <= 1 && m_currentState != WifiPhyState::OFF)
338 {
339 // update current state & last update time stamp
341
342 // some debug message
343 NS_LOG_DEBUG("WifiRadioEnergyModel:Total energy consumption is " << m_totalEnergyConsumption
344 << "J");
345 }
346
348}
349
350void
352{
353 NS_LOG_FUNCTION(this);
354 NS_LOG_DEBUG("WifiRadioEnergyModel:Energy is depleted!");
355 // invoke energy depletion callback, if set.
357 {
359 }
360}
361
362void
364{
365 NS_LOG_FUNCTION(this);
366 NS_LOG_DEBUG("WifiRadioEnergyModel:Energy is recharged!");
367 // invoke energy recharged callback, if set.
369 {
371 }
372}
373
374void
376{
377 NS_LOG_FUNCTION(this);
378 NS_LOG_DEBUG("WifiRadioEnergyModel:Energy is changed!");
379 if (m_currentState != WifiPhyState::OFF)
380 {
385 this,
386 WifiPhyState::OFF);
387 }
388}
389
392{
393 NS_LOG_FUNCTION(this);
394 return m_listener;
395}
396
397/*
398 * Private functions start here.
399 */
400
401void
403{
404 NS_LOG_FUNCTION(this);
405 m_source = nullptr;
407}
408
409double
411{
412 switch (state)
413 {
414 case WifiPhyState::IDLE:
415 return m_idleCurrentA;
416 case WifiPhyState::CCA_BUSY:
417 return m_ccaBusyCurrentA;
418 case WifiPhyState::TX:
419 return m_txCurrentA;
420 case WifiPhyState::RX:
421 return m_rxCurrentA;
422 case WifiPhyState::SWITCHING:
423 return m_switchingCurrentA;
424 case WifiPhyState::SLEEP:
425 return m_sleepCurrentA;
426 case WifiPhyState::OFF:
427 return 0.0;
428 }
429 NS_FATAL_ERROR("WifiRadioEnergyModel: undefined radio state " << state);
430}
431
432double
434{
436}
437
438void
440{
441 NS_LOG_FUNCTION(this << state);
442 m_currentState = state;
443 std::string stateName;
444 switch (state)
445 {
446 case WifiPhyState::IDLE:
447 stateName = "IDLE";
448 break;
449 case WifiPhyState::CCA_BUSY:
450 stateName = "CCA_BUSY";
451 break;
452 case WifiPhyState::TX:
453 stateName = "TX";
454 break;
455 case WifiPhyState::RX:
456 stateName = "RX";
457 break;
458 case WifiPhyState::SWITCHING:
459 stateName = "SWITCHING";
460 break;
461 case WifiPhyState::SLEEP:
462 stateName = "SLEEP";
463 break;
464 case WifiPhyState::OFF:
465 stateName = "OFF";
466 break;
467 }
468 NS_LOG_DEBUG("WifiRadioEnergyModel:Switching to state: " << stateName
469 << " at time = " << Simulator::Now());
470}
471
472// -------------------------------------------------------------------------- //
473
475{
476 NS_LOG_FUNCTION(this);
479}
480
482{
483 NS_LOG_FUNCTION(this);
484}
485
486void
489{
490 NS_LOG_FUNCTION(this << &callback);
491 NS_ASSERT(!callback.IsNull());
492 m_changeStateCallback = callback;
493}
494
495void
497{
498 NS_LOG_FUNCTION(this << &callback);
499 NS_ASSERT(!callback.IsNull());
500 m_updateTxCurrentCallback = callback;
501}
502
503void
505{
506 NS_LOG_FUNCTION(this << duration);
508 {
509 NS_FATAL_ERROR("WifiRadioEnergyModelPhyListener:Change state callback not set!");
510 }
511 m_changeStateCallback(WifiPhyState::RX);
513}
514
515void
517{
518 NS_LOG_FUNCTION(this);
520 {
521 NS_FATAL_ERROR("WifiRadioEnergyModelPhyListener:Change state callback not set!");
522 }
523 m_changeStateCallback(WifiPhyState::IDLE);
524}
525
526void
528{
529 NS_LOG_FUNCTION(this);
531 {
532 NS_FATAL_ERROR("WifiRadioEnergyModelPhyListener:Change state callback not set!");
533 }
534 m_changeStateCallback(WifiPhyState::IDLE);
535}
536
537void
539{
540 NS_LOG_FUNCTION(this << duration << txPowerDbm);
542 {
543 NS_FATAL_ERROR("WifiRadioEnergyModelPhyListener:Update tx current callback not set!");
544 }
545 m_updateTxCurrentCallback(txPowerDbm);
547 {
548 NS_FATAL_ERROR("WifiRadioEnergyModelPhyListener:Change state callback not set!");
549 }
550 m_changeStateCallback(WifiPhyState::TX);
551 // schedule changing state back to IDLE after TX duration
555}
556
557void
559 WifiChannelListType channelType,
560 const std::vector<Time>& /*per20MhzDurations*/)
561{
562 NS_LOG_FUNCTION(this << duration << channelType);
564 {
565 NS_FATAL_ERROR("WifiRadioEnergyModelPhyListener:Change state callback not set!");
566 }
567 m_changeStateCallback(WifiPhyState::CCA_BUSY);
568 // schedule changing state back to IDLE after CCA_BUSY duration
572}
573
574void
576{
577 NS_LOG_FUNCTION(this << duration);
579 {
580 NS_FATAL_ERROR("WifiRadioEnergyModelPhyListener:Change state callback not set!");
581 }
582 m_changeStateCallback(WifiPhyState::SWITCHING);
583 // schedule changing state back to IDLE after CCA_BUSY duration
587}
588
589void
591{
592 NS_LOG_FUNCTION(this);
594 {
595 NS_FATAL_ERROR("WifiRadioEnergyModelPhyListener:Change state callback not set!");
596 }
597 m_changeStateCallback(WifiPhyState::SLEEP);
599}
600
601void
603{
604 NS_LOG_FUNCTION(this);
606 {
607 NS_FATAL_ERROR("WifiRadioEnergyModelPhyListener:Change state callback not set!");
608 }
609 m_changeStateCallback(WifiPhyState::IDLE);
610}
611
612void
614{
615 NS_LOG_FUNCTION(this);
617 {
618 NS_FATAL_ERROR("WifiRadioEnergyModelPhyListener:Change state callback not set!");
619 }
620 m_changeStateCallback(WifiPhyState::OFF);
622}
623
624void
626{
627 NS_LOG_FUNCTION(this);
629 {
630 NS_FATAL_ERROR("WifiRadioEnergyModelPhyListener:Change state callback not set!");
631 }
632 m_changeStateCallback(WifiPhyState::IDLE);
633}
634
635void
637{
638 NS_LOG_FUNCTION(this);
640 {
641 NS_FATAL_ERROR("WifiRadioEnergyModelPhyListener:Change state callback not set!");
642 }
643 m_changeStateCallback(WifiPhyState::IDLE);
644}
645
646} // namespace ns3
void Nullify()
Discard the implementation, set it to null.
Definition: callback.h:573
bool IsNull() const
Check for null implementation.
Definition: callback.h:567
Base class for device energy models.
virtual void ChangeState(int newState)=0
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:55
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
bool IsPositive() const
Exactly equivalent to t >= 0.
Definition: nstime.h:332
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:402
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:936
A WiFi radio energy model.
double GetStateA(int state) const
void HandleEnergyChanged() override
Handles energy changed.
double GetCcaBusyCurrentA() const
Gets CCA busy current in Amperes.
WifiRadioEnergyDepletionCallback m_energyDepletionCallback
Energy depletion callback.
double m_idleCurrentA
idle current in Amperes
WifiPhyState GetCurrentState() const
double m_ccaBusyCurrentA
CCA busy current in Amperes.
void ChangeState(int newState) override
Changes state of the WifiRadioEnergyMode.
void SetCcaBusyCurrentA(double ccaBusyCurrentA)
Sets CCA busy current in Amperes.
Time GetMaximumTimeInState(int state) const
WifiRadioEnergyRechargedCallback m_energyRechargedCallback
Energy recharged callback.
double m_sleepCurrentA
sleep current in Amperes
WifiRadioEnergyModelPhyListener * m_listener
WifiPhy listener.
Ptr< EnergySource > m_source
energy source
TracedValue< double > m_totalEnergyConsumption
This variable keeps track of the total energy consumed by this model in watts.
void SetTxCurrentModel(const Ptr< WifiTxCurrentModel > model)
EventId m_switchToOffEvent
switch to off event
void DoDispose() override
Destructor implementation.
void SetRxCurrentA(double rxCurrentA)
Sets receive current in Amperes.
double GetTotalEnergyConsumption() const override
WifiRadioEnergyModelPhyListener * GetPhyListener()
double m_txCurrentA
transmit current in Amperes
void HandleEnergyRecharged() override
Handles energy recharged.
Time m_lastUpdateTime
time stamp of previous energy update
void SetTxCurrentA(double txCurrentA)
Sets transmit current in Amperes.
double GetRxCurrentA() const
Gets receive current in Amperes.
double GetTxCurrentA() const
Gets transmit current in Amperes.
void HandleEnergyDepletion() override
Handles energy depletion.
static TypeId GetTypeId()
Get the type ID.
double GetIdleCurrentA() const
Gets idle current in Amperes.
void SetSwitchingCurrentA(double switchingCurrentA)
Sets switching current in Amperes.
void SetTxCurrentFromModel(double txPowerDbm)
Calls the CalcTxCurrent method of the TX current model to compute the TX current based on such model.
void SetEnergyDepletionCallback(WifiRadioEnergyDepletionCallback callback)
void SetSleepCurrentA(double sleepCurrentA)
Sets sleep current in Amperes.
double m_rxCurrentA
receive current in Amperes
WifiPhyState m_currentState
current state the radio is in
void SetWifiRadioState(const WifiPhyState state)
double GetSleepCurrentA() const
Gets sleep current in Amperes.
Ptr< WifiTxCurrentModel > m_txCurrentModel
current model
double GetSwitchingCurrentA() const
Gets switching current in Amperes.
void SetIdleCurrentA(double idleCurrentA)
Sets idle current in Amperes.
double DoGetCurrentA() const override
void SetEnergySource(const Ptr< EnergySource > source) override
Sets pointer to EnergySource installed on node.
void SetEnergyRechargedCallback(WifiRadioEnergyRechargedCallback callback)
double m_switchingCurrentA
switching current in Amperes
uint8_t m_nPendingChangeState
pending state change
A WifiPhy listener class for notifying the WifiRadioEnergyModel of Wifi radio state change.
DeviceEnergyModel::ChangeStateCallback m_changeStateCallback
Change state callback used to notify the WifiRadioEnergyModel of a state change.
void NotifyTxStart(Time duration, double txPowerDbm) override
void NotifySleep() override
Notify listeners that we went to sleep.
void NotifyOff() override
Notify listeners that we went to switch off.
void NotifyRxStart(Time duration) override
void NotifyRxEndOk() override
We have received the last bit of a packet for which NotifyRxStart was invoked first and,...
UpdateTxCurrentCallback m_updateTxCurrentCallback
Callback used to update the TX current stored in WifiRadioEnergyModel based on the nominal TX power u...
void NotifyRxEndError() override
We have received the last bit of a packet for which NotifyRxStart was invoked first and,...
void SetUpdateTxCurrentCallback(UpdateTxCurrentCallback callback)
Sets the update TX current callback.
void NotifySwitchingStart(Time duration) override
void SwitchToIdle()
A helper function that makes scheduling m_changeStateCallback possible.
void SetChangeStateCallback(DeviceEnergyModel::ChangeStateCallback callback)
Sets the change state callback.
void NotifyWakeup() override
Notify listeners that we woke up.
EventId m_switchToIdleEvent
switch to idle event
void NotifyOn() override
Notify listeners that we went to switch on.
void NotifyCcaBusyStart(Time duration, WifiChannelListType channelType, const std::vector< Time > &per20MhzDurations) override
#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
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition: double.h:43
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:227
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#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:1336
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
WifiChannelListType
Enumeration of the possible channel-list parameter elements defined in Table 8-5 of IEEE 802....
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:702
@ IDLE
Channel is IDLE, no packet is being transmitted.
Definition: csma-channel.h:76
WifiPhyState
The state of the PHY layer.