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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Sidharth Nabar <snabar@uw.edu>, He Wu <mdzz@u.washington.edu>
7 */
8
10
12
13#include "ns3/energy-source.h"
14#include "ns3/log.h"
15#include "ns3/pointer.h"
16#include "ns3/simulator.h"
17
18namespace ns3
19{
20
21NS_LOG_COMPONENT_DEFINE("WifiRadioEnergyModel");
22
23NS_OBJECT_ENSURE_REGISTERED(WifiRadioEnergyModel);
24
25TypeId
27{
28 static TypeId tid =
29 TypeId("ns3::WifiRadioEnergyModel")
31 .SetGroupName("Energy")
33 .AddAttribute("IdleCurrentA",
34 "The default radio Idle current in Ampere.",
35 DoubleValue(0.273), // idle mode = 273mA
39 .AddAttribute("CcaBusyCurrentA",
40 "The default radio CCA Busy State current in Ampere.",
41 DoubleValue(0.273), // default to be the same as idle mode
45 .AddAttribute("TxCurrentA",
46 "The radio TX current in Ampere.",
47 DoubleValue(0.380), // transmit at 0dBm = 380mA
51 .AddAttribute("RxCurrentA",
52 "The radio RX current in Ampere.",
53 DoubleValue(0.313), // receive mode = 313mA
57 .AddAttribute("SwitchingCurrentA",
58 "The default radio Channel Switch current in Ampere.",
59 DoubleValue(0.273), // default to be the same as idle mode
63 .AddAttribute("SleepCurrentA",
64 "The radio Sleep current in Ampere.",
65 DoubleValue(0.033), // sleep mode = 33mA
69 .AddAttribute("TxCurrentModel",
70 "A pointer to the attached TX current model.",
74 .AddTraceSource(
75 "TotalEnergyConsumption",
76 "Total energy consumption of the radio device.",
78 "ns3::TracedValueCallback::Double");
79 return tid;
80}
81
83 : m_source(nullptr),
84 m_currentState(WifiPhyState::IDLE),
85 m_lastUpdateTime(Seconds(0.0)),
86 m_nPendingChangeState(0)
87{
88 NS_LOG_FUNCTION(this);
90 // set callback for WifiPhy listener
91 m_listener = std::make_shared<WifiRadioEnergyModelPhyListener>();
92 m_listener->SetChangeStateCallback(MakeCallback(&DeviceEnergyModel::ChangeState, this));
93 // set callback for updating the TX current
94 m_listener->SetUpdateTxCurrentCallback(
96}
97
104
105void
107{
108 NS_LOG_FUNCTION(this << source);
109 NS_ASSERT(source);
110 m_source = source;
112 const auto durationToOff = GetMaximumTimeInState(m_currentState);
115 this,
116 static_cast<int>(WifiPhyState::OFF));
117}
118
119Watt_u
121{
122 NS_LOG_FUNCTION(this);
123
124 const auto duration = Simulator::Now() - m_lastUpdateTime;
125 NS_ASSERT(duration.IsPositive()); // check if duration is valid
126
127 // energy to decrease = current * voltage * time
128 const auto supplyVoltage = m_source->GetSupplyVoltage();
129 const auto energyToDecrease = duration.GetSeconds() * GetStateA(m_currentState) * supplyVoltage;
130
131 // notify energy source
132 m_source->UpdateEnergySource();
133
134 return m_totalEnergyConsumption + energyToDecrease;
135}
136
143
144void
146{
147 NS_LOG_FUNCTION(this << idleCurrent);
148 m_idleCurrent = idleCurrent;
149}
150
157
158void
160{
161 NS_LOG_FUNCTION(this << ccaBusyCurrent);
162 m_ccaBusyCurrent = ccaBusyCurrent;
163}
164
167{
168 NS_LOG_FUNCTION(this);
169 return m_txCurrent;
170}
171
172void
174{
175 NS_LOG_FUNCTION(this << txCurrent);
176 m_txCurrent = txCurrent;
177}
178
181{
182 NS_LOG_FUNCTION(this);
183 return m_rxCurrent;
184}
185
186void
188{
189 NS_LOG_FUNCTION(this << rxCurrent);
190 m_rxCurrent = rxCurrent;
191}
192
199
200void
202{
203 NS_LOG_FUNCTION(this << switchingCurrent);
204 m_switchingCurrent = switchingCurrent;
205}
206
213
214void
216{
217 NS_LOG_FUNCTION(this << sleepCurrent);
218 m_sleepCurrent = sleepCurrent;
219}
220
227
228void
230{
231 NS_LOG_FUNCTION(this);
232 if (callback.IsNull())
233 {
234 NS_LOG_DEBUG("WifiRadioEnergyModel:Setting NULL energy depletion callback!");
235 }
236 m_energyDepletionCallback = callback;
237}
238
239void
241{
242 NS_LOG_FUNCTION(this);
243 if (callback.IsNull())
244 {
245 NS_LOG_DEBUG("WifiRadioEnergyModel:Setting NULL energy recharged callback!");
246 }
247 m_energyRechargedCallback = callback;
248}
249
250void
255
256void
258{
260 {
261 m_txCurrent = m_txCurrentModel->CalcTxCurrent(txPower);
262 }
263}
264
265Time
267{
268 if (state == WifiPhyState::OFF)
269 {
270 NS_FATAL_ERROR("Requested maximum remaining time for OFF state");
271 }
272 const auto remainingEnergy = m_source->GetRemainingEnergy();
273 const auto supplyVoltage = m_source->GetSupplyVoltage();
274 const auto current = GetStateA(state);
275 return Seconds(remainingEnergy / (current * supplyVoltage));
276}
277
278void
280{
281 WifiPhyState newPhyState{newState};
282 NS_LOG_FUNCTION(this << newPhyState);
283
285
286 if (m_nPendingChangeState > 1 && newPhyState == WifiPhyState::OFF)
287 {
288 SetWifiRadioState(newPhyState);
290 return;
291 }
292
293 if (newPhyState != WifiPhyState::OFF)
294 {
296 const auto durationToOff = GetMaximumTimeInState(newPhyState);
299 this,
300 static_cast<int>(WifiPhyState::OFF));
301 }
302
303 const auto duration = Simulator::Now() - m_lastUpdateTime;
304 NS_ASSERT(duration.IsPositive()); // check if duration is valid
305
306 // energy to decrease = current * voltage * time
307 const auto supplyVoltage = m_source->GetSupplyVoltage();
308 const auto energyToDecrease = duration.GetSeconds() * GetStateA(m_currentState) * supplyVoltage;
309
310 // update total energy consumption
311 m_totalEnergyConsumption += energyToDecrease;
313
314 // update last update time stamp
316
317 // notify energy source
318 m_source->UpdateEnergySource();
319
320 // in case the energy source is found to be depleted during the last update, a callback might be
321 // invoked that might cause a change in the Wifi PHY state (e.g., the PHY is put into SLEEP
322 // mode). This in turn causes a new call to this member function, with the consequence that the
323 // previous instance is resumed after the termination of the new instance. In particular, the
324 // state set by the previous instance is erroneously the final state stored in m_currentState.
325 // The check below ensures that previous instances do not change m_currentState.
326
328 {
329 // update current state & last update time stamp
330 SetWifiRadioState(newPhyState);
331
332 // some debug message
333 NS_LOG_DEBUG("WifiRadioEnergyModel:Total energy consumption is " << m_totalEnergyConsumption
334 << "J");
335 }
336
338}
339
340void
342{
343 NS_LOG_FUNCTION(this);
344 NS_LOG_DEBUG("WifiRadioEnergyModel:Energy is depleted!");
345 // invoke energy depletion callback, if set.
347 {
349 }
350}
351
352void
354{
355 NS_LOG_FUNCTION(this);
356 NS_LOG_DEBUG("WifiRadioEnergyModel:Energy is recharged!");
357 // invoke energy recharged callback, if set.
359 {
361 }
362}
363
364void
366{
367 NS_LOG_FUNCTION(this);
368 NS_LOG_DEBUG("WifiRadioEnergyModel:Energy is changed!");
370 {
372 const auto durationToOff = GetMaximumTimeInState(m_currentState);
375 this,
376 static_cast<int>(WifiPhyState::OFF));
377 }
378}
379
380std::shared_ptr<WifiRadioEnergyModelPhyListener>
386
387/*
388 * Private functions start here.
389 */
390
391void
398
401{
402 switch (state)
403 {
405 return m_idleCurrent;
407 return m_ccaBusyCurrent;
408 case WifiPhyState::TX:
409 return m_txCurrent;
410 case WifiPhyState::RX:
411 return m_rxCurrent;
413 return m_switchingCurrent;
415 return m_sleepCurrent;
417 return 0.0;
418 }
419 NS_FATAL_ERROR("WifiRadioEnergyModel: undefined radio state " << state);
420}
421
427
428void
430{
431 NS_LOG_FUNCTION(this << state);
432 m_currentState = state;
433 std::string stateName;
434 switch (state)
435 {
437 stateName = "IDLE";
438 break;
440 stateName = "CCA_BUSY";
441 break;
442 case WifiPhyState::TX:
443 stateName = "TX";
444 break;
445 case WifiPhyState::RX:
446 stateName = "RX";
447 break;
449 stateName = "SWITCHING";
450 break;
452 stateName = "SLEEP";
453 break;
455 stateName = "OFF";
456 break;
457 }
458 NS_LOG_DEBUG("WifiRadioEnergyModel:Switching to state: " << stateName
459 << " at time = " << Simulator::Now());
460}
461
462// -------------------------------------------------------------------------- //
463
470
475
476void
484
485void
492
493void
495{
496 NS_LOG_FUNCTION(this << duration);
498 {
499 NS_FATAL_ERROR("WifiRadioEnergyModelPhyListener:Change state callback not set!");
500 }
501 m_changeStateCallback(static_cast<int>(WifiPhyState::RX));
503}
504
505void
507{
508 NS_LOG_FUNCTION(this);
510 {
511 NS_FATAL_ERROR("WifiRadioEnergyModelPhyListener:Change state callback not set!");
512 }
513 m_changeStateCallback(static_cast<int>(WifiPhyState::IDLE));
514}
515
516void
518{
519 NS_LOG_FUNCTION(this);
521 {
522 NS_FATAL_ERROR("WifiRadioEnergyModelPhyListener:Change state callback not set!");
523 }
524 m_changeStateCallback(static_cast<int>(WifiPhyState::IDLE));
525}
526
527void
529{
530 NS_LOG_FUNCTION(this << duration << txPower);
532 {
533 NS_FATAL_ERROR("WifiRadioEnergyModelPhyListener:Update tx current callback not set!");
534 }
537 {
538 NS_FATAL_ERROR("WifiRadioEnergyModelPhyListener:Change state callback not set!");
539 }
540 m_changeStateCallback(static_cast<int>(WifiPhyState::TX));
541 // schedule changing state back to IDLE after TX duration
545}
546
547void
549 WifiChannelListType channelType,
550 const std::vector<Time>& /*per20MhzDurations*/)
551{
552 NS_LOG_FUNCTION(this << duration << channelType);
554 {
555 NS_FATAL_ERROR("WifiRadioEnergyModelPhyListener:Change state callback not set!");
556 }
558 // schedule changing state back to IDLE after CCA_BUSY duration
562}
563
564void
566{
567 NS_LOG_FUNCTION(this << duration);
569 {
570 NS_FATAL_ERROR("WifiRadioEnergyModelPhyListener:Change state callback not set!");
571 }
573 // schedule changing state back to IDLE after CCA_BUSY duration
577}
578
579void
581{
582 NS_LOG_FUNCTION(this);
584 {
585 NS_FATAL_ERROR("WifiRadioEnergyModelPhyListener:Change state callback not set!");
586 }
589}
590
591void
593{
594 NS_LOG_FUNCTION(this);
596 {
597 NS_FATAL_ERROR("WifiRadioEnergyModelPhyListener:Change state callback not set!");
598 }
599 m_changeStateCallback(static_cast<int>(WifiPhyState::IDLE));
600}
601
602void
604{
605 NS_LOG_FUNCTION(this);
607 {
608 NS_FATAL_ERROR("WifiRadioEnergyModelPhyListener:Change state callback not set!");
609 }
610 m_changeStateCallback(static_cast<int>(WifiPhyState::OFF));
612}
613
614void
616{
617 NS_LOG_FUNCTION(this);
619 {
620 NS_FATAL_ERROR("WifiRadioEnergyModelPhyListener:Change state callback not set!");
621 }
622 m_changeStateCallback(static_cast<int>(WifiPhyState::IDLE));
623}
624
625void
627{
628 NS_LOG_FUNCTION(this);
630 {
631 NS_FATAL_ERROR("WifiRadioEnergyModelPhyListener:Change state callback not set!");
632 }
633 m_changeStateCallback(static_cast<int>(WifiPhyState::IDLE));
634}
635
636} // namespace ns3
void Nullify()
Discard the implementation, set it to null.
Definition callback.h:561
bool IsNull() const
Check for null implementation.
Definition callback.h:555
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition event-id.cc:44
AttributeValue implementation for Pointer.
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
a unique identifier for an interface.
Definition type-id.h:48
TypeId AddConstructor()
Record in this TypeId the fact that the default constructor is accessible.
Definition type-id.h:670
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
A WiFi radio energy model.
void HandleEnergyChanged() override
Handles energy changed.
WifiRadioEnergyDepletionCallback m_energyDepletionCallback
Energy depletion callback.
void SetSleepCurrentA(ampere_u sleepCurrentA)
Sets sleep current.
void SetRxCurrentA(ampere_u rxCurrentA)
Sets receive current.
Ptr< energy::EnergySource > m_source
energy source
void ChangeState(int newState) override
Changes state of the WifiRadioEnergyMode.
ampere_u GetSleepCurrentA() const
Gets sleep current.
WifiRadioEnergyRechargedCallback m_energyRechargedCallback
Energy recharged callback.
ampere_u GetCcaBusyCurrentA() const
Gets CCA busy current.
void SetIdleCurrentA(ampere_u idleCurrentA)
Sets idle current.
TracedValue< double > m_totalEnergyConsumption
This variable keeps track of the total energy consumed by this model in watts.
void SetTxCurrentModel(const Ptr< WifiTxCurrentModel > model)
void SetTxCurrentFromModel(dBm_u txPower)
Calls the CalcTxCurrent method of the TX current model to compute the TX current based on such model.
EventId m_switchToOffEvent
switch to off event
void DoDispose() override
Destructor implementation.
void HandleEnergyRecharged() override
Handles energy recharged.
Time m_lastUpdateTime
time stamp of previous energy update
ampere_u GetSwitchingCurrentA() const
Gets switching current.
ampere_u m_switchingCurrent
switching current
ampere_u m_txCurrent
transmit current
ampere_u GetStateA(WifiPhyState state) const
ampere_u GetTxCurrentA() const
Gets transmit current.
std::shared_ptr< WifiRadioEnergyModelPhyListener > m_listener
WifiPhy listener.
void HandleEnergyDepletion() override
Handles energy depletion.
static TypeId GetTypeId()
Get the type ID.
ampere_u DoGetCurrentA() const override
void SetCcaBusyCurrentA(ampere_u ccaBusyCurrentA)
Sets CCA busy current.
void SetEnergyDepletionCallback(WifiRadioEnergyDepletionCallback callback)
std::shared_ptr< WifiRadioEnergyModelPhyListener > GetPhyListener()
ampere_u m_rxCurrent
receive current
WifiPhyState m_currentState
current state the radio is in
ampere_u GetIdleCurrentA() const
Gets idle current.
void SetWifiRadioState(const WifiPhyState state)
ampere_u m_ccaBusyCurrent
CCA busy current.
Time GetMaximumTimeInState(WifiPhyState state) const
void SetTxCurrentA(ampere_u txCurrentA)
Sets transmit current.
Ptr< WifiTxCurrentModel > m_txCurrentModel
current model
void SetSwitchingCurrentA(ampere_u switchingCurrentA)
Sets switching current.
ampere_u GetRxCurrentA() const
Gets receive current.
ampere_u m_sleepCurrent
sleep current
Watt_u GetTotalEnergyConsumption() const override
void SetEnergySource(const Ptr< energy::EnergySource > source) override
Sets pointer to EnergySource installed on node.
void SetEnergyRechargedCallback(WifiRadioEnergyRechargedCallback callback)
uint8_t m_nPendingChangeState
pending state change
energy::DeviceEnergyModel::ChangeStateCallback m_changeStateCallback
Change state callback used to notify the WifiRadioEnergyModel of a state change.
void NotifySleep() override
Notify listeners that we went to sleep.
void NotifyOff() override
Notify listeners that we went to switch off.
void SetChangeStateCallback(energy::DeviceEnergyModel::ChangeStateCallback callback)
Sets the change state callback.
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 NotifyTxStart(Time duration, dBm_u txPower) override
void NotifySwitchingStart(Time duration) override
void SwitchToIdle()
A helper function that makes scheduling m_changeStateCallback possible.
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:55
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:248
Ptr< AttributeChecker > MakePointerChecker()
Create a PointerChecker for a type.
Definition pointer.h:269
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#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:35
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
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.
WifiPhyState
The state of the PHY layer.
@ SWITCHING
The PHY layer is switching to other channel.
@ TX
The PHY layer is sending a packet.
@ OFF
The PHY layer is switched off.
@ IDLE
The PHY layer is IDLE.
@ CCA_BUSY
The PHY layer has sense the medium busy through the CCA mechanism.
@ SLEEP
The PHY layer is sleeping.
@ RX
The PHY layer is receiving a packet.
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:684
Ptr< const AttributeChecker > MakeDoubleChecker()
Definition double.h:82
double ampere_u
ampere weak type
Definition wifi-units.h:33
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition double.h:32
double Watt_u
Watt weak type.
Definition wifi-units.h:25
@ IDLE
Channel is IDLE, no packet is being transmitted.