A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
lora-radio-energy-model.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017 University of Padova
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Romagnolo Stefano <romagnolostefano93@gmail.com>
7 */
8
10
12
13#include "ns3/energy-source.h"
14#include "ns3/pointer.h"
15#include "ns3/simulator.h"
16
17namespace ns3
18{
19namespace lorawan
20{
21
22NS_LOG_COMPONENT_DEFINE("LoraRadioEnergyModel");
23
25
32
37
38void
46
47void
54
55void
57{
58 NS_LOG_FUNCTION(this);
59 if (m_changeStateCallback.IsNull())
60 {
61 NS_FATAL_ERROR("LoraRadioEnergyModelPhyListener:Change state callback not set!");
62 }
64}
65
66void
68{
69 NS_LOG_FUNCTION(this);
70 if (m_changeStateCallback.IsNull())
71 {
72 NS_FATAL_ERROR("LoraRadioEnergyModelPhyListener:Change state callback not set!");
73 }
75}
76
77void
79{
80 NS_LOG_FUNCTION(this << txPowerDbm);
81 if (m_updateTxCurrentCallback.IsNull())
82 {
83 NS_FATAL_ERROR("LoraRadioEnergyModelPhyListener:Update tx current callback not set!");
84 }
85 m_updateTxCurrentCallback(txPowerDbm);
86 if (m_changeStateCallback.IsNull())
87 {
88 NS_FATAL_ERROR("LoraRadioEnergyModelPhyListener:Change state callback not set!");
89 }
91}
92
93void
95{
96 NS_LOG_FUNCTION(this);
97 if (m_changeStateCallback.IsNull())
98 {
99 NS_FATAL_ERROR("LoraRadioEnergyModelPhyListener:Change state callback not set!");
100 }
102}
103
104void
106{
107 NS_LOG_FUNCTION(this);
108 if (m_changeStateCallback.IsNull())
109 {
110 NS_FATAL_ERROR("LoraRadioEnergyModelPhyListener:Change state callback not set!");
111 }
113}
114
115TypeId
117{
118 static TypeId tid =
119 TypeId("ns3::LoraRadioEnergyModel")
121 .SetGroupName("Energy")
122 .AddConstructor<LoraRadioEnergyModel>()
123 .AddAttribute("SleepCurrentA",
124 "The radio Sleep current in Ampere.",
125 DoubleValue(0.1e-6), // sleep mode = 0.1uA
129 .AddAttribute("StandbyCurrentA",
130 "The default radio Standby current in Ampere.",
131 DoubleValue(1.4e-3), // standby mode = 1.4mA
135 .AddAttribute("TxCurrentA",
136 "The radio Tx current in Ampere.",
137 DoubleValue(28e-3), // transmit at 13dBm = 28mA
141 .AddAttribute("RxCurrentA",
142 "The radio Rx current in Ampere.",
143 DoubleValue(10.8e-3), // receive mode = 10.8mA
147 .AddAttribute("TxCurrentModel",
148 "A pointer to the attached tx current model.",
149 PointerValue(),
152 .AddTraceSource(
153 "TotalEnergyConsumption",
154 "Total energy consumption of the radio device.",
156 "ns3::TracedValueCallback::Double");
157 return tid;
158}
159
161 : m_source(nullptr),
162 m_currentState(EndDeviceLoraPhy::State::STANDBY),
165{
166 NS_LOG_FUNCTION(this);
168 // set callback for EndDeviceLoraPhy listener
169 m_listener = std::make_shared<LoraRadioEnergyModelPhyListener>();
170 m_listener->SetChangeStateCallback(MakeCallback(&DeviceEnergyModel::ChangeState, this));
171 // set callback for updating the tx current
172 m_listener->SetUpdateTxCurrentCallback(
174}
175
182
183void
185{
186 NS_LOG_FUNCTION(this << source);
187 NS_ASSERT(source);
188 m_source = source;
189}
190
191double
193{
194 NS_LOG_FUNCTION(this);
195
196 const auto duration = Simulator::Now() - m_lastUpdateTime;
197 NS_ASSERT(duration.IsPositive()); // check if duration is valid
198
199 // energy to decrease = current * voltage * time
200 const auto supplyVoltage = m_source->GetSupplyVoltage();
201 const auto energyToDecrease = duration.GetSeconds() * GetStateA(m_currentState) * supplyVoltage;
202
203 // notify energy source
204 m_source->UpdateEnergySource();
205
206 return m_totalEnergyConsumption + energyToDecrease;
207}
208
209double
215
216void
218{
219 NS_LOG_FUNCTION(this << standbyCurrentA);
220 m_standbyCurrentA = standbyCurrentA;
221}
222
223double
225{
226 NS_LOG_FUNCTION(this);
227 return m_txCurrentA;
228}
229
230void
232{
233 NS_LOG_FUNCTION(this << txCurrentA);
234 m_txCurrentA = txCurrentA;
235}
236
237double
239{
240 NS_LOG_FUNCTION(this);
241 return m_rxCurrentA;
242}
243
244void
246{
247 NS_LOG_FUNCTION(this << rxCurrentA);
248 m_rxCurrentA = rxCurrentA;
249}
250
251double
257
258void
260{
261 NS_LOG_FUNCTION(this << sleepCurrentA);
262 m_sleepCurrentA = sleepCurrentA;
263}
264
271
272void
274{
275 NS_LOG_FUNCTION(this);
276 if (callback.IsNull())
277 {
278 NS_LOG_DEBUG("LoraRadioEnergyModel:Setting NULL energy depletion callback!");
279 }
280 m_energyDepletionCallback = callback;
281}
282
283void
285{
286 NS_LOG_FUNCTION(this);
287 if (callback.IsNull())
288 {
289 NS_LOG_DEBUG("LoraRadioEnergyModel:Setting NULL energy recharged callback!");
290 }
291 m_energyRechargedCallback = callback;
292}
293
294void
299
300void
302{
304 {
305 m_txCurrentA = m_txCurrentModel->CalcTxCurrent(txPowerDbm);
306 }
307}
308
309void
311{
312 EndDeviceLoraPhy::State newPhyState{newState};
313 NS_LOG_FUNCTION(this << newPhyState);
314
316
317 const auto duration = Simulator::Now() - m_lastUpdateTime;
318 NS_ASSERT(duration.IsPositive()); // check if duration is valid
319
320 // energy to decrease = current * voltage * time
321 const auto supplyVoltage = m_source->GetSupplyVoltage();
322 const auto energyToDecrease = duration.GetSeconds() * GetStateA(m_currentState) * supplyVoltage;
323
324 // update total energy consumption
325 m_totalEnergyConsumption += energyToDecrease;
327
328 // update last update time stamp
330
331 // notify energy source
332 m_source->UpdateEnergySource();
333
334 // in case the energy source is found to be depleted during the last update, a callback might be
335 // invoked that might cause a change in the Lora PHY state (e.g., the PHY is put into SLEEP
336 // mode). This in turn causes a new call to this member function, with the consequence that the
337 // previous instance is resumed after the termination of the new instance. In particular, the
338 // state set by the previous instance is erroneously the final state stored in m_currentState.
339 // The check below ensures that previous instances do not change m_currentState.
340
341 if (m_nPendingChangeState <= 1)
342 {
343 // update current state & last update time stamp
344 SetLoraRadioState(newPhyState);
345
346 // some debug message
347 NS_LOG_DEBUG("LoraRadioEnergyModel:Total energy consumption is " << m_totalEnergyConsumption
348 << "J");
349 }
350
352}
353
354void
356{
357 NS_LOG_FUNCTION(this);
358 NS_LOG_DEBUG("LoraRadioEnergyModel:Energy is depleted!");
359 // invoke energy depletion callback, if set.
360 if (!m_energyDepletionCallback.IsNull())
361 {
363 }
364}
365
366void
368{
369 NS_LOG_FUNCTION(this);
370 NS_LOG_DEBUG("LoraRadioEnergyModel:Energy is recharged!");
371 // invoke energy recharged callback, if set.
372 if (!m_energyRechargedCallback.IsNull())
373 {
375 }
376}
377
378void
380{
381 NS_LOG_FUNCTION(this);
382 NS_LOG_DEBUG("LoraRadioEnergyModel:Energy changed!");
383}
384
385std::shared_ptr<LoraRadioEnergyModelPhyListener>
391
392/*
393 * Private functions start here.
394 */
395
396void
398{
399 NS_LOG_FUNCTION(this);
400 m_source = nullptr;
402}
403
404double
406{
407 switch (state)
408 {
410 return m_sleepCurrentA;
412 return m_standbyCurrentA;
414 return m_txCurrentA;
417 return m_rxCurrentA;
418 }
419 NS_FATAL_ERROR("LoraRadioEnergyModel: undefined radio state " << m_currentState);
420}
421
422double
427
428void
430{
431 NS_LOG_FUNCTION(this << state);
432 m_currentState = state;
433 NS_LOG_DEBUG("LoraRadioEnergyModel: Switching to state: " << state
434 << " at time = " << Simulator::Now());
435}
436
437} // namespace lorawan
438} // namespace ns3
bool IsNull() const
Check for null implementation.
Definition callback.h:561
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
AttributeValue implementation for Pointer.
Definition pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:191
a unique identifier for an interface.
Definition type-id.h:50
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:999
Callback< void, int > ChangeStateCallback
Callback type for ChangeState function.
Class representing a LoRa transceiver hardware state-machine of a SX1272 LoRa chip (see SX1272/73 Dat...
State
An enumeration of the possible internal states of an EndDeviceLoraPhy.
@ TX
The PHY layer is transmitting a packet.
@ RX_ACTIVE
The PHY layer is actively receiving a transmission after locking onto a preamble.
@ SLEEP
The PHY layer is in low-power sleep state.
@ RX_ENABLED
The PHY layer is listening to the channel for a valid transmission preamble.
@ STANDBY
The PHY layer is in standby mode.
void HandleEnergyChanged() override
Handles energy changed.
double GetStateA(EndDeviceLoraPhy::State state) const
Callback< void > LoraRadioEnergyDepletionCallback
Callback type for energy depletion handling.
uint8_t m_nPendingChangeState
pending state change
double GetTxCurrentA() const
Gets transmit current.
void ChangeState(int newState) override
Changes state of the LoraRadioEnergyModel.
double GetRxCurrentA() const
Gets receive current.
void SetTxCurrentFromModel(double txPowerDbm)
Calls the CalcTxCurrent method of the tx current model to compute the tx current based on such model.
LoraRadioEnergyDepletionCallback m_energyDepletionCallback
Energy depletion callback.
void DoDispose() override
Destructor implementation.
Ptr< energy::EnergySource > m_source
energy source
EndDeviceLoraPhy::State m_currentState
current state the radio is in
void HandleEnergyRecharged() override
Handles energy recharged.
std::shared_ptr< LoraRadioEnergyModelPhyListener > GetPhyListener()
void HandleEnergyDepletion() override
Handles energy depletion.
void SetEnergyRechargedCallback(LoraRadioEnergyRechargedCallback callback)
void SetLoraRadioState(const EndDeviceLoraPhy::State state)
Time m_lastUpdateTime
time stamp of previous energy update
double GetStandbyCurrentA() const
Gets standby current.
Ptr< LoraTxCurrentModel > m_txCurrentModel
current model
Callback< void > LoraRadioEnergyRechargedCallback
Callback type for energy recharged handling.
void SetEnergyDepletionCallback(LoraRadioEnergyDepletionCallback callback)
void SetStandbyCurrentA(double standbyCurrentA)
Sets standby current.
void SetSleepCurrentA(double sleepCurrentA)
Sets sleep current.
void SetRxCurrentA(double rxCurrentA)
Sets receive current.
void SetTxCurrentA(double txCurrentA)
Sets transmit current.
void SetEnergySource(Ptr< energy::EnergySource > source) override
Sets pointer to EnergySource installed on node.
std::shared_ptr< LoraRadioEnergyModelPhyListener > m_listener
EndDeviceLoraPhy listener.
double GetSleepCurrentA() const
Gets sleep current.
void SetTxCurrentModel(Ptr< LoraTxCurrentModel > model)
static TypeId GetTypeId()
Register this type.
EndDeviceLoraPhy::State GetCurrentState() const
LoraRadioEnergyRechargedCallback m_energyRechargedCallback
Energy recharged callback.
TracedValue< double > m_totalEnergyConsumption
This variable keeps track of the total energy consumed by this model.
void NotifyStandby() override
Notify listeners that the device entered STANDBY state.
void NotifySleep() override
Notify listeners that the device entered SLEEP state.
void SetChangeStateCallback(energy::DeviceEnergyModel::ChangeStateCallback callback)
Sets the change state callback.
energy::DeviceEnergyModel::ChangeStateCallback m_changeStateCallback
Change state callback used to notify the LoraRadioEnergyModel of a state change.
Callback< void, double > UpdateTxCurrentCallback
Callback type for updating the transmit current based on the nominal tx power.
void SetUpdateTxCurrentCallback(UpdateTxCurrentCallback callback)
Sets the update tx current callback.
void NotifyRxActive() override
Notify listeners that the device entered RX_ACTIVE state.
UpdateTxCurrentCallback m_updateTxCurrentCallback
Callback used to update the tx current stored in LoraRadioEnergyModel based on the nominal tx power u...
void NotifyRxEnabled() override
Notify listeners that the device entered RX_ENABLED state.
void NotifyTx(double txPowerDbm) override
Notify listeners that the device entered TX state.
#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:250
Ptr< AttributeChecker > MakePointerChecker()
Create a PointerChecker for a type.
Definition pointer.h:273
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:690
#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:194
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:260
#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
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 AttributeChecker > MakeDoubleChecker()
Definition double.h:82
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition double.h:32